You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
front/src/app/components/timeline/timeline.component.html

121 lines
5.1 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<!-- Spinner pendant le chargement -->
<div *ngIf="loading" class="flex justify-center items-center h-64">
<div class="animate-spin rounded-full h-16 w-16 border-4 border-blue-500 border-t-transparent"></div>
</div>
<!-- Timeline principale -->
<div *ngIf="!loading && pins.length > 0" class="relative mx-auto max-w-7xl py-20 px-6">
<!-- Barre centrale -->
<div class="absolute left-1/2 transform -translate-x-1/2 h-full bg-blue-500 w-6 rounded-full z-0"></div>
<!-- Groupement par années -->
<ng-container *ngFor="let year of sortedYears">
<!-- Marqueur d'année -->
<div class="relative mb-24 flex justify-center items-center">
<div class="absolute left-1/2 transform -translate-x-1/2 h-16 w-8 bg-blue-500 z-0"></div>
<div class="bg-blue-600 text-white text-4xl font-bold px-10 py-5 rounded-full shadow-2xl z-10 border-4 border-white">
{{ year }}
</div>
</div>
<!-- Pins de l'année -->
<ng-container *ngFor="let pin of groupedPins[year]; let i = index">
<div class="mb-32 flex flex-col sm:flex-row justify-between items-center w-full relative z-10">
<!-- Espace vide -->
<div class="w-full sm:w-5/12" [ngClass]="{ 'order-1': i % 2 === 0, 'order-2': i % 2 !== 0 }"></div>
<!-- Bulle centrale avec la date -->
<div
class="z-20 flex items-center justify-center bg-white border-[6px] border-blue-600 text-blue-700 font-bold text-lg shadow-2xl w-32 h-32 rounded-full text-center px-4 leading-tight"
[ngClass]="{ 'order-2': i % 2 === 0, 'order-1': i % 2 !== 0 }"
>
<span>{{ pin.date | date: 'dd/MM/yyyy' }}</span>
</div>
<!-- Carte de contenu -->
<div
class="bg-white dark:bg-gray-800 rounded-3xl shadow-2xl px-10 py-8 w-full sm:w-5/12 transition-all duration-300 hover:scale-[1.02]"
[ngClass]="{
'order-3 text-center sm:text-left': i % 2 === 0,
'order-0 text-center sm:text-right': i % 2 !== 0
}"
>
<!-- Titre centré -->
<h3 class="text-3xl font-extrabold text-gray-900 dark:text-white mb-4 text-center">
{{ pin.title || 'Titre inconnu' }}
</h3>
<!-- Description justifiée tronquée -->
<div
class="text-lg text-gray-700 dark:text-gray-300 mb-4 text-justify transition-all duration-300"
[ngClass]="{
'line-clamp-5 overflow-hidden': !expandedDescriptions[pins.indexOf(pin)]
}"
>
{{ pin.description || 'Aucune description' }}
</div>
<!-- Bouton "voir plus / moins" -->
<div *ngIf="pin.description.length > 200" class="text-right mb-6">
<button
class="text-blue-600 font-semibold hover:underline"
(click)="toggleDescription(pins.indexOf(pin))"
>
{{ expandedDescriptions[pins.indexOf(pin)] ? 'Voir moins' : 'Voir plus' }}
</button>
</div>
<!-- Carrousel d'images -->
<ng-container *ngIf="imageUrls[pins.indexOf(pin)].length > 0">
<div class="relative flex items-center justify-center">
<button
*ngIf="imageUrls[pins.indexOf(pin)].length > 1"
(click)="prevImage(pins.indexOf(pin))"
class="absolute left-0 bg-white border border-blue-500 text-blue-500 rounded-full w-10 h-10 shadow-md hover:bg-blue-100 z-10"
>
</button>
<img
[src]="imageUrls[pins.indexOf(pin)][carouselIndexes[pins.indexOf(pin)]]"
alt="image"
class="rounded-xl mx-auto w-full h-64 object-cover shadow-lg"
/>
<button
*ngIf="imageUrls[pins.indexOf(pin)].length > 1"
(click)="nextImage(pins.indexOf(pin))"
class="absolute right-0 bg-white border border-blue-500 text-blue-500 rounded-full w-10 h-10 shadow-md hover:bg-blue-100 z-10"
>
</button>
</div>
<!-- Indicateur de position -->
<div *ngIf="imageUrls[pins.indexOf(pin)].length > 1" class="flex justify-center mt-2 space-x-2">
<div
*ngFor="let img of imageUrls[pins.indexOf(pin)]; let j = index"
class="w-3 h-3 rounded-full"
[ngClass]="{
'bg-blue-600': j === carouselIndexes[pins.indexOf(pin)],
'bg-blue-200': j !== carouselIndexes[pins.indexOf(pin)]
}"
></div>
</div>
</ng-container>
<!-- Fallback sil ny a pas dimage -->
<ng-container *ngIf="!imageUrls[pins.indexOf(pin)] || imageUrls[pins.indexOf(pin)].length === 0">
<div class="text-gray-400 italic text-center">Aucune image</div>
</ng-container>
</div>
</div>
</ng-container>
</ng-container>
</div>
<!-- Message si vide -->
<div *ngIf="!loading && pins.length === 0" class="text-center text-gray-500 py-12 text-xl">
Aucun souvenir à afficher pour le moment.
</div>