PORTFOLIO/src/frontend/src/app/presentation/features/featured-projects/project-detail/project-detail.component.html

119 lines
4.5 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

@if (project) {
<section class="project-detail-panel" [style.--prj-accent]="project.accentColor" aria-live="polite">
<div class="project-detail-header">
<div>
<span class="detail-kicker">
{{ project.code }}
@if (project.inDevelopment) {
<span class="detail-dev-tag">● {{ i18n.t().fpInDevelopment }}</span>
}
</span>
<h3>{{ project.title }}</h3>
</div>
<button type="button" class="close-button" (click)="onClose()" [attr.aria-label]="i18n.t().projectDetailCloseAria">
×
</button>
</div>
<div class="project-detail-layout">
<div class="project-detail-visual">
@if (project.images && project.images.length > 0) {
<div class="main-image-viewport">
@if (getCurrentImage(); as currentImg) {
@if (!imageErrors()[currentImg]) {
<img
[src]="currentImg"
[alt]="project.title + ' vista ' + (activeImageIndex() + 1)"
(error)="onImageError(currentImg)"
loading="lazy"
/>
} @else {
<div class="detail-placeholder">
<span class="placeholder-icon">◧</span>
<span class="placeholder-code">{{ project.code }}</span>
</div>
}
} @else {
<div class="detail-placeholder">
<span class="placeholder-icon">◧</span>
<span class="placeholder-code">{{ project.code }}</span>
</div>
}
</div>
@if (project.images.length > 1) {
<div class="gallery-thumbs" role="tablist" aria-label="Miniaturas de capturas">
@for (img of project.images; track img; let i = $index) {
<button
type="button"
class="thumb-btn"
[class.is-active]="activeImageIndex() === i"
[attr.aria-selected]="activeImageIndex() === i"
(click)="selectImage(i)"
>
@if (!imageErrors()[img]) {
<img [src]="img" [alt]="project.title + ' miniatura ' + (i + 1)" (error)="onImageError(img)" loading="lazy" />
} @else {
<span class="thumb-label">{{ i + 1 }}</span>
}
</button>
}
</div>
}
} @else {
<!-- Ficha de Arquitectura Técnica para proyectos sin imágenes (SIPLECE) -->
<div class="technical-blueprint-panel">
<div class="blueprint-circuit-bg" aria-hidden="true"></div>
<div class="blueprint-panel-content">
<span class="blueprint-panel-icon">◧</span>
<span class="blueprint-panel-code">{{ project.code }}</span>
<h4 class="blueprint-panel-title">{{ project.title }}</h4>
<p class="blueprint-panel-subtitle">{{ i18n.t().fpNoImagesTechnical }}</p>
<div class="blueprint-specs-list">
<span class="spec-item">🏛 {{ project.institution }}</span>
<span class="spec-item">🔒 Autenticación JWT & RBAC</span>
<span class="spec-item">⚡ Clean Architecture (.NET + Angular)</span>
<span class="spec-item">📊 Trazabilidad & Auditoría CACES</span>
</div>
</div>
</div>
}
</div>
<div class="project-detail-body">
<div class="project-detail-meta">
<span class="meta-pill">{{ project.institution }}</span>
<span class="meta-pill subtle">{{ project.subtitle }}</span>
</div>
<p class="project-detail-summary">{{ project.description }}</p>
<div class="detail-block">
<h4>{{ i18n.t().projectDetailChallenge }}</h4>
<p>{{ project.challenge }}</p>
</div>
<div class="detail-block">
<h4>{{ i18n.t().projectDetailSolution }}</h4>
<p>{{ project.solution }}</p>
</div>
<div class="detail-block results-block">
<h4>{{ i18n.t().projectDetailResults }}</h4>
<ul>
@for (result of project.results; track result) {
<li>{{ result }}</li>
}
</ul>
</div>
<div class="detail-tags">
@for (tag of project.tags; track tag) {
<span>{{ tag }}</span>
}
</div>
</div>
</div>
</section>
}