mirror of
https://github.com/4gray/iptvnator.git
synced 2026-10-16 14:16:16 -08:00
feat: implement content card component with dynamic features and styles
This commit is contained in:
1 parent
d64283e33d
commit
e6923d3fff
4 files changed
+260
No files matched your search
@@ -0,0 +1,48 @@
|
||||
<div class="content-card" (click)="onCardClick()">
|
||||
<div class="thumbnail-wrapper">
|
||||
@if (showRemoveButton()) {
|
||||
<button
|
||||
mat-icon-button
|
||||
class="remove-button"
|
||||
[matTooltip]="removeTooltip()"
|
||||
(click)="onRemoveClick($event)"
|
||||
>
|
||||
<mat-icon>close</mat-icon>
|
||||
</button>
|
||||
}
|
||||
|
||||
@if (posterUrl()) {
|
||||
<img
|
||||
[src]="posterUrl()"
|
||||
[alt]="title()"
|
||||
(error)="onImageError($event)"
|
||||
class="poster"
|
||||
/>
|
||||
} @else if (showPlaceholder()) {
|
||||
<div class="poster-placeholder">
|
||||
<mat-icon>{{ getPlaceholderIcon() }}</mat-icon>
|
||||
</div>
|
||||
} @else {
|
||||
<img
|
||||
src="./assets/images/default-poster.png"
|
||||
[alt]="title()"
|
||||
class="poster"
|
||||
/>
|
||||
}
|
||||
|
||||
@if (type()) {
|
||||
<span class="type-badge" [class]="type()">
|
||||
{{ type() }}
|
||||
</span>
|
||||
}
|
||||
</div>
|
||||
|
||||
<div class="card-info">
|
||||
<h3>{{ title() }}</h3>
|
||||
@if (date()) {
|
||||
<p class="date-info">
|
||||
{{ date() | date: 'd MMM, HH:mm' }}
|
||||
</p>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,21 @@
|
||||
@use '../../styles/content-grid' as grid;
|
||||
|
||||
.content-card {
|
||||
@include grid.content-card;
|
||||
|
||||
.thumbnail-wrapper {
|
||||
@include grid.thumbnail-wrapper;
|
||||
|
||||
.remove-button {
|
||||
@include grid.remove-button;
|
||||
}
|
||||
|
||||
.type-badge {
|
||||
@include grid.type-badge;
|
||||
}
|
||||
}
|
||||
|
||||
.card-info {
|
||||
@include grid.card-info;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
import { DatePipe } from '@angular/common';
|
||||
import {
|
||||
ChangeDetectionStrategy,
|
||||
Component,
|
||||
input,
|
||||
output,
|
||||
} from '@angular/core';
|
||||
import { MatIconButton } from '@angular/material/button';
|
||||
import { MatIcon } from '@angular/material/icon';
|
||||
import { MatTooltip } from '@angular/material/tooltip';
|
||||
|
||||
@Component({
|
||||
selector: 'app-content-card',
|
||||
standalone: true,
|
||||
imports: [DatePipe, MatIcon, MatIconButton, MatTooltip],
|
||||
templateUrl: './content-card.component.html',
|
||||
styleUrl: './content-card.component.scss',
|
||||
changeDetection: ChangeDetectionStrategy.OnPush,
|
||||
})
|
||||
export class ContentCardComponent {
|
||||
/** URL of the poster image */
|
||||
readonly posterUrl = input<string>();
|
||||
|
||||
/** Title to display */
|
||||
readonly title = input.required<string>();
|
||||
|
||||
/** Content type (live, movie, series) */
|
||||
readonly type = input<string>();
|
||||
|
||||
/** Optional date to display */
|
||||
readonly date = input<Date | string>();
|
||||
|
||||
/** Whether to show the remove button */
|
||||
readonly showRemoveButton = input<boolean>(false);
|
||||
|
||||
/** Tooltip text for the remove button */
|
||||
readonly removeTooltip = input<string>('Remove');
|
||||
|
||||
/** Whether to show placeholder when no poster */
|
||||
readonly showPlaceholder = input<boolean>(true);
|
||||
|
||||
/** Emitted when the card is clicked */
|
||||
readonly cardClick = output<void>();
|
||||
|
||||
/** Emitted when the remove button is clicked */
|
||||
readonly remove = output<void>();
|
||||
|
||||
/** Get the icon for the placeholder based on type */
|
||||
getPlaceholderIcon(): string {
|
||||
switch (this.type()) {
|
||||
case 'live':
|
||||
return 'live_tv';
|
||||
case 'series':
|
||||
return 'tv';
|
||||
default:
|
||||
return 'movie';
|
||||
}
|
||||
}
|
||||
|
||||
onCardClick(): void {
|
||||
this.cardClick.emit();
|
||||
}
|
||||
|
||||
onRemoveClick(event: Event): void {
|
||||
event.stopPropagation();
|
||||
this.remove.emit();
|
||||
}
|
||||
|
||||
onImageError(event: Event): void {
|
||||
(event.target as HTMLImageElement).src =
|
||||
'./assets/images/default-poster.png';
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user