Proyecto App Windows
This commit is contained in:
@@ -0,0 +1,193 @@
|
||||
<!-- 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>
|
||||
Reference in New Issue
Block a user