Files
KiraTV---Aplicacion-para-Wi…/libs/ui/components/src/lib/content-hero/content-hero.component.html
T
2026-05-03 23:36:48 +02:00

194 lines
6.8 KiB
HTML

<!-- Hero Section with Backdrop -->
<section class="hero">
<!-- Back Button -->
<button class="hero__back-button" (click)="onBack()">
<mat-icon>arrow_back</mat-icon>
</button>
@if (errorMessage()) {
<div class="hero__content hero__error">
<mat-icon class="error-icon">cloud_off</mat-icon>
<h2 class="error-title">{{ errorMessage() }}</h2>
<ng-content select="[hero-error-actions]"></ng-content>
</div>
} @else if (isLoading()) {
<div class="hero__content">
<!-- Skeleton Poster -->
<div class="poster">
<ngx-skeleton-loader
count="1"
[theme]="{
height: '100%',
width: '100%',
'border-radius': '8px',
'aspect-ratio': '2/3',
display: 'block',
}"
/>
</div>
<!-- Skeleton Details -->
<div class="details">
<!-- Title -->
<ngx-skeleton-loader
count="1"
[theme]="{
height: '40px',
width: '60%',
'margin-bottom': '16px',
display: 'block',
}"
/>
<!-- Tags -->
<div style="display: flex; gap: 8px; margin-bottom: 16px">
<ngx-skeleton-loader
count="3"
[theme]="{
height: '24px',
width: '60px',
display: 'block',
}"
/>
</div>
<!-- Description -->
<ngx-skeleton-loader
count="3"
[theme]="{
height: '16px',
'margin-bottom': '8px',
width: '100%',
display: 'block',
}"
/>
<!-- Meta -->
<div style="margin-top: 20px; display: flex; gap: 32px">
<ngx-skeleton-loader
count="2"
[theme]="{
height: '40px',
width: '100px',
display: 'block',
}"
/>
</div>
<!-- Buttons -->
<div style="margin-top: 24px; display: flex; gap: 12px">
<ngx-skeleton-loader
count="2"
[theme]="{
height: '48px',
width: '140px',
display: 'block',
}"
/>
</div>
</div>
</div>
} @else {
<!-- Backdrop Image -->
<div
class="hero__backdrop"
[class.hero__backdrop--blurred]="
!backdropUrl() && posterUrl() && !posterError()
"
[style.backgroundImage]="
backdropUrl() && !posterError()
? 'url(' + backdropUrl() + ')'
: posterUrl() && !posterError()
? 'url(' + posterUrl() + ')'
: fallbackBackdropBackground()
"
></div>
<!-- Gradient Vignette Overlay -->
<div class="hero__vignette"></div>
<!-- Hero Content -->
<div class="hero__content">
<!-- Poster Card -->
<div class="poster">
@if (posterUrl() && !posterError()) {
<img
class="poster__image"
[src]="posterUrl()"
(error)="onPosterError()"
alt="Poster"
/>
} @else {
<div
class="poster__placeholder"
[style.backgroundImage]="fallbackPosterBackground()"
>
<mat-icon class="poster__placeholder-icon"
>movie</mat-icon
>
<span class="poster__placeholder-text">{{
formattedTitle()
}}</span>
</div>
}
</div>
<div class="details">
<h1 class="details__title">{{ formattedTitle() }}</h1>
<!-- Tags Slot -->
<div class="details__tags">
<ng-content select="[hero-tags]"></ng-content>
</div>
<!-- Description -->
@if (description()) {
<p
#descriptionEl
class="details__description"
[class.details__description--expanded]="
isDescriptionExpanded()
"
>
{{ description() }}
</p>
@if (hasDescriptionOverflow() || isDescriptionExpanded()) {
<button
type="button"
class="details__description-toggle"
(click)="toggleDescription()"
[attr.aria-expanded]="isDescriptionExpanded()"
>
<span>{{
(isDescriptionExpanded()
? 'SHOW_LESS'
: 'SHOW_MORE'
) | translate
}}</span>
<mat-icon aria-hidden="true">
{{
isDescriptionExpanded()
? 'expand_less'
: 'expand_more'
}}
</mat-icon>
</button>
}
}
<!-- Metadata Grid Slot -->
<div class="details__meta">
<ng-content select="[hero-meta]"></ng-content>
</div>
<!-- Action Buttons Slot -->
<div class="action-buttons">
<ng-content select="[hero-actions]"></ng-content>
</div>
<!-- Additional Content (Seasons, Trailers, etc.) -->
<ng-content></ng-content>
</div>
</div>
}
</section>