fix bug #10 , responsive accueil et page de recherche

This commit is contained in:
styve Lioumba
2025-11-24 22:33:35 +01:00
parent 0325f0eba8
commit a791b32f69
13 changed files with 544 additions and 222 deletions

View File

@@ -1,86 +1,128 @@
<footer class="py-4 w-full min-h-full bg-white dark:bg-gray-900">
<div class="max-w-[80rem] mx-auto space-y-6 px-2 md:px-4 lg:px-6 pt-4">
<div class="h-px w-full bg-gray-900/10 bg-gray-800 dark:bg-white"></div>
<div
class="flex flex-col sm:flex-row justify-between items-center text-sm text-gray-600 space-y-4 sm:space-y-0"
>
<a [routerLink]="['/']" class="inline-flex items-center gap-1">
<span class="inline-block text-xl text-gray-800 dark:text-white">TrouveTonProfile</span>
</a>
<footer class="sm:py-12 w-full bg-white dark:bg-gray-900 border-gray-200 dark:border-gray-800">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="space-y-8">
<!-- Séparateur décoratif (optionnel sur petit écran) -->
<div
class="sm:block h-px w-full bg-gradient-to-r from-transparent via-gray-300 dark:via-gray-700 to-transparent"
></div>
<ul class="flex items-center gap-4">
<li>
<a [routerLink]="['/conditions']" class="inline-block text-gray-800 dark:text-white"
>Conditions</a
<!-- Contenu principal du footer -->
<div class="flex flex-col lg:flex-row justify-between items-center gap-6 lg:gap-8">
<!-- Logo/Brand -->
<a
[routerLink]="['/']"
class="flex items-center gap-2 group order-1 lg:order-none"
aria-label="Accueil TrouveTonProfile"
>
<span
class="text-xl sm:text-2xl font-semibold text-gray-900 dark:text-white group-hover:text-indigo-600 dark:group-hover:text-indigo-400 transition-colors"
>
</li>
<li>
<a [routerLink]="['/terms']" class="inline-block text-gray-800 dark:text-white">Terms</a>
</li>
<li>
<a [routerLink]="['/politiques']" class="inline-block text-gray-800 dark:text-white"
>Politiques</a
>
</li>
</ul>
TrouveTonProfile
</span>
</a>
<ul class="flex items-center gap-4">
<li>
<a
target="_blank"
href="#"
class="inline-block rounded-full h-8 w-8 p-2 border text-gray-800 dark:text-white"
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="w-full h-full fill-current"
viewBox="0 0 448 512"
>
<path
d="M100.28 448H7.4V148.9h92.88zM53.79 108.1C24.09 108.1 0 83.5 0 53.8a53.79 53.79 0 0 1 107.58 0c0 29.7-24.1 54.3-53.79 54.3zM447.9 448h-92.68V302.4c0-34.7-.7-79.2-48.29-79.2-48.29 0-55.69 37.7-55.69 76.7V448h-92.78V148.9h89.08v40.8h1.3c12.4-23.5 42.69-48.3 87.88-48.3 94 0 111.28 61.9 111.28 142.3V448z"
/>
</svg>
</a>
</li>
<li>
<a
target="_blank"
href="#"
class="inline-block rounded-full h-8 w-8 p-2 border text-gray-800 dark:text-white"
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="w-full h-full fill-current"
viewBox="0 0 24 24"
>
<g fill="none" stroke-linecap="round" stroke-linejoin="round" stroke-width="2">
<path d="M0 0h24v24H0z" />
<path
fill="currentColor"
d="M18 2a1 1 0 0 1 .993.883L19 3v4a1 1 0 0 1-.883.993L18 8h-3v1h3a1 1 0 0 1 .991 1.131l-.02.112l-1 4a1 1 0 0 1-.858.75L17 15h-2v6a1 1 0 0 1-.883.993L14 22h-4a1 1 0 0 1-.993-.883L9 21v-6H7a1 1 0 0 1-.993-.883L6 14v-4a1 1 0 0 1 .883-.993L7 9h2V8a6 6 0 0 1 5.775-5.996L15 2z"
/>
</g>
</svg>
</a>
</li>
<li>
<a
target="_blank"
href="#"
class="inline-block rounded-full h-8 w-8 p-2 border text-gray-800 dark:text-white"
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="w-full h-full fill-current"
viewBox="0 0 512 512"
>
<path
d="M389.2 48h70.6L305.6 224.2 487 464H345L233.7 318.6 106.5 464H35.8L200.7 275.5 26.8 48H172.4L272.9 180.9 389.2 48zM364.4 421.8h39.1L151.1 88h-42L364.4 421.8z"
/>
</svg>
</a>
</li>
</ul>
<!-- Liens légaux -->
<nav class="order-2 lg:order-none" aria-label="Liens légaux">
<ul class="flex flex-wrap justify-center items-center gap-4 sm:gap-6">
<li>
<a
[routerLink]="['/conditions']"
class="text-sm sm:text-base text-gray-600 dark:text-gray-400 hover:text-indigo-600 dark:hover:text-indigo-400 transition-colors"
>
Conditions
</a>
</li>
<li class="hidden sm:block text-gray-300 dark:text-gray-700">|</li>
<li>
<a
[routerLink]="['/terms']"
class="text-sm sm:text-base text-gray-600 dark:text-gray-400 hover:text-indigo-600 dark:hover:text-indigo-400 transition-colors"
>
Termes
</a>
</li>
<li class="hidden sm:block text-gray-300 dark:text-gray-700">|</li>
<li>
<a
[routerLink]="['/politiques']"
class="text-sm sm:text-base text-gray-600 dark:text-gray-400 hover:text-indigo-600 dark:hover:text-indigo-400 transition-colors"
>
Politiques
</a>
</li>
</ul>
</nav>
<!-- Réseaux sociaux -->
<nav class="order-3 lg:order-none" aria-label="Réseaux sociaux">
<ul class="flex items-center gap-3 sm:gap-4">
<li>
<a
href="https://linkedin.com"
target="_blank"
rel="noopener noreferrer"
class="inline-flex items-center justify-center w-9 h-9 sm:w-10 sm:h-10 rounded-full border border-gray-300 dark:border-gray-700 text-gray-600 dark:text-gray-400 hover:border-indigo-500 dark:hover:border-indigo-400 hover:text-indigo-600 dark:hover:text-indigo-400 hover:scale-110 transition-all duration-200"
aria-label="LinkedIn"
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="w-4 h-4 sm:w-5 sm:h-5 fill-current"
viewBox="0 0 448 512"
>
<path
d="M100.28 448H7.4V148.9h92.88zM53.79 108.1C24.09 108.1 0 83.5 0 53.8a53.79 53.79 0 0 1 107.58 0c0 29.7-24.1 54.3-53.79 54.3zM447.9 448h-92.68V302.4c0-34.7-.7-79.2-48.29-79.2-48.29 0-55.69 37.7-55.69 76.7V448h-92.78V148.9h89.08v40.8h1.3c12.4-23.5 42.69-48.3 87.88-48.3 94 0 111.28 61.9 111.28 142.3V448z"
/>
</svg>
</a>
</li>
<li>
<a
href="https://facebook.com"
target="_blank"
rel="noopener noreferrer"
class="inline-flex items-center justify-center w-9 h-9 sm:w-10 sm:h-10 rounded-full border border-gray-300 dark:border-gray-700 text-gray-600 dark:text-gray-400 hover:border-indigo-500 dark:hover:border-indigo-400 hover:text-indigo-600 dark:hover:text-indigo-400 hover:scale-110 transition-all duration-200"
aria-label="Facebook"
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="w-4 h-4 sm:w-5 sm:h-5 fill-current"
viewBox="0 0 24 24"
>
<path
d="M18 2a1 1 0 0 1 .993.883L19 3v4a1 1 0 0 1-.883.993L18 8h-3v1h3a1 1 0 0 1 .991 1.131l-.02.112l-1 4a1 1 0 0 1-.858.75L17 15h-2v6a1 1 0 0 1-.883.993L14 22h-4a1 1 0 0 1-.993-.883L9 21v-6H7a1 1 0 0 1-.993-.883L6 14v-4a1 1 0 0 1 .883-.993L7 9h2V8a6 6 0 0 1 5.775-5.996L15 2z"
/>
</svg>
</a>
</li>
<li>
<a
href="https://x.com"
target="_blank"
rel="noopener noreferrer"
class="inline-flex items-center justify-center w-9 h-9 sm:w-10 sm:h-10 rounded-full border border-gray-300 dark:border-gray-700 text-gray-600 dark:text-gray-400 hover:border-indigo-500 dark:hover:border-indigo-400 hover:text-indigo-600 dark:hover:text-indigo-400 hover:scale-110 transition-all duration-200"
aria-label="X (Twitter)"
>
<svg
xmlns="http://www.w3.org/2000/svg"
class="w-4 h-4 sm:w-5 sm:h-5 fill-current"
viewBox="0 0 512 512"
>
<path
d="M389.2 48h70.6L305.6 224.2 487 464H345L233.7 318.6 106.5 464H35.8L200.7 275.5 26.8 48H172.4L272.9 180.9 389.2 48zM364.4 421.8h39.1L151.1 88h-42L364.4 421.8z"
/>
</svg>
</a>
</li>
</ul>
</nav>
</div>
<!-- Copyright (optionnel) -->
<div class="pt-6 border-t border-gray-200 dark:border-gray-800">
<p class="text-center text-xs sm:text-sm text-gray-500 dark:text-gray-500">
© {{ currentYear }} TrouveTonProfile. Tous droits réservés.
</p>
</div>
</div>
</div>
</footer>

View File

@@ -8,4 +8,6 @@ import { RouterLink } from '@angular/router';
templateUrl: './footer.component.html',
styleUrl: './footer.component.scss',
})
export class FooterComponent {}
export class FooterComponent {
readonly currentYear = new Date().getFullYear();
}

View File

@@ -1,132 +1,136 @@
<header class="w-screen bg-white dark:bg-gray-900 min-h-12">
<div class="w-full">
<nav
class="fixed w-full z-20 top-0 start-1/2 max-w-6xl -translate-x-1/2 bg-white dark:bg-gray-900"
>
<div class="max-w-screen-xl flex flex-nowrap items-center justify-between mx-auto p-4">
<a [routerLink]="['/']" class="flex items-center space-x-3 rtl:space-x-reverse">
<div class="flex flex-row items-center gap-1 mr-3">
<span class="text-xl select-none text-black dark:text-white">TrouveTonProfile</span>
</div>
</a>
<div class="flex md:order-2 space-x-1 items-center">
@if (isAuthenticated() && isEmailVerified()) {
@if (user(); as user) {
<a
[routerLink]="['my-profile']"
[state]="{ user }"
class="w-10 h-10 dark:border-white dark:border rounded-full inline-flex items-center justify-center bg-gray-200 text-gray-400"
>
@if (user.avatar) {
<img
alt="{{ user.username }}"
class="object-cover object-center h-full w-full rounded-full"
src="{{ environment.baseUrl }}/api/files/users/{{ user.id }}/{{ user.avatar }}"
loading="lazy"
/>
} @else {
<img
alt="{{ user.username }}"
class="object-cover object-center h-full w-full rounded-full"
src="https://api.dicebear.com/9.x/adventurer/svg?seed={{ user.username }}"
loading="lazy"
/>
}
</a>
<header class="w-full bg-white dark:bg-gray-900 shadow-sm">
<nav
class="fixed w-full z-20 top-0 left-1/2 -translate-x-1/2 max-w-6xl bg-white dark:bg-gray-900 border-b border-gray-200 dark:border-gray-800"
>
<div class="flex items-center justify-between px-4 py-3 sm:px-6">
<!-- Logo -->
<a
[routerLink]="['/']"
class="flex items-center space-x-2 group"
aria-label="Accueil TrouveTonProfile"
>
<span
class="text-lg sm:text-xl font-semibold text-gray-900 dark:text-white group-hover:text-indigo-600 dark:group-hover:text-indigo-400 transition-colors"
>
TrouveTonProfile
</span>
</a>
<!-- Actions utilisateur -->
<div class="flex items-center gap-2 sm:gap-3">
<!-- Avatar utilisateur (si connecté) -->
@if (isAuthenticated() && isEmailVerified() && user(); as user) {
<a
[routerLink]="['my-profile']"
[state]="{ user }"
class="w-9 h-9 sm:w-10 sm:h-10 rounded-full overflow-hidden bg-gray-200 border-2 border-transparent hover:border-indigo-500 dark:hover:border-indigo-400 transition-all ring-2 ring-transparent hover:ring-2 hover:ring-indigo-200 dark:hover:ring-indigo-900"
aria-label="Mon profil"
>
@if (user.avatar) {
<img
[alt]="user.username"
class="object-cover w-full h-full"
[src]="environment.baseUrl + '/api/files/users/' + user.id + '/' + user.avatar"
loading="lazy"
/>
} @else {
<img
[alt]="user.username"
class="object-cover w-full h-full"
[src]="'https://api.dicebear.com/9.x/adventurer/svg?seed=' + user.username"
loading="lazy"
/>
}
}
</a>
}
<!-- Toggle thème -->
<button
type="button"
(click)="toggleDarkMode()"
class="p-2 rounded-lg text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors"
[attr.aria-label]="
themeService.darkModeSignal() === 'dark'
? 'Passer en mode clair'
: 'Passer en mode sombre'
"
>
@if (themeService.darkModeSignal() === 'dark') {
<button
type="button"
(click)="toggleDarkMode()"
class="text-black dark:text-white font-medium rounded-lg text-sm px-4 py-2 text-center flex items-center justify-center gap-1"
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="w-5 h-5"
>
<span class="inline-block h-4 w-4">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="size-6"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M12 3v2.25m6.364.386-1.591 1.591M21 12h-2.25m-.386 6.364-1.591-1.591M12 18.75V21m-4.773-4.227-1.591 1.591M5.25 12H3m4.227-4.773L5.636 5.636M15.75 12a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0Z"
/>
</svg>
</span>
</button>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M12 3v2.25m6.364.386-1.591 1.591M21 12h-2.25m-.386 6.364-1.591-1.591M12 18.75V21m-4.773-4.227-1.591 1.591M5.25 12H3m4.227-4.773L5.636 5.636M15.75 12a3.75 3.75 0 1 1-7.5 0 3.75 3.75 0 0 1 7.5 0Z"
/>
</svg>
} @else {
<button
type="button"
(click)="toggleDarkMode()"
class="text-black dark:text-white font-medium rounded-lg text-sm px-4 py-2 text-center flex items-center justify-center gap-1"
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 -960 960 960"
fill="currentColor"
class="w-5 h-5"
>
<span class="inline-block h-4 w-4">
<svg
xmlns="http://www.w3.org/2000/svg"
class="w-full h-full fill-current"
viewBox="0 -960 960 960"
>
<path
d="M480-120q-150 0-255-105T120-480q0-150 105-255t255-105q14 0 27.5 1t26.5 3q-41 29-65.5 75.5T444-660q0 90 63 153t153 63q55 0 101-24.5t75-65.5q2 13 3 26.5t1 27.5q0 150-105 255T480-120Zm0-80q88 0 158-48.5T740-375q-20 5-40 8t-40 3q-123 0-209.5-86.5T364-660q0-20 3-40t8-40q-78 32-126.5 102T200-480q0 116 82 198t198 82Zm-10-270Z"
/>
</svg>
</span>
</button>
<path
d="M480-120q-150 0-255-105T120-480q0-150 105-255t255-105q14 0 27.5 1t26.5 3q-41 29-65.5 75.5T444-660q0 90 63 153t153 63q55 0 101-24.5t75-65.5q2 13 3 26.5t1 27.5q0 150-105 255T480-120Zm0-80q88 0 158-48.5T740-375q-20 5-40 8t-40 3q-123 0-209.5-86.5T364-660q0-20 3-40t8-40q-78 32-126.5 102T200-480q0 116 82 198t198 82Zm-10-270Z"
/>
</svg>
}
<span class="text-black dark:text-white"> | </span>
</button>
@if (isAuthenticated() && isEmailVerified()) {
<a
[routerLink]="['/auth']"
(click)="authFacade.logout()"
class="text-black dark:text-white font-medium rounded-lg text-sm px-4 py-2 text-center flex items-center justify-center space-x-4"
<!-- Séparateur -->
<div class="h-6 w-px bg-gray-300 dark:bg-gray-700"></div>
<!-- Bouton de connexion/déconnexion -->
@if (isAuthenticated() && isEmailVerified()) {
<a
[routerLink]="['/auth']"
(click)="authFacade.logout()"
class="flex items-center gap-2 px-3 py-2 rounded-lg text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors"
aria-label="Se déconnecter"
>
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="w-5 h-5"
>
<span class="h-4 w-4">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke-width="1.5"
stroke="currentColor"
class="size-6"
>
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M15.75 9V5.25A2.25 2.25 0 0 0 13.5 3h-6a2.25 2.25 0 0 0-2.25 2.25v13.5A2.25 2.25 0 0 0 7.5 21h6a2.25 2.25 0 0 0 2.25-2.25V15M12 9l-3 3m0 0 3 3m-3-3h12.75"
/>
</svg>
</span>
<span class="hidden sm:block text-black text-center dark:text-white"
>Se deconnecter</span
>
</a>
} @else {
<a
[routerLink]="['/auth']"
class="text-black dark:text-white font-medium rounded-lg text-sm px-4 py-2 text-center flex items-center justify-center gap-1"
<path
stroke-linecap="round"
stroke-linejoin="round"
d="M15.75 9V5.25A2.25 2.25 0 0 0 13.5 3h-6a2.25 2.25 0 0 0-2.25 2.25v13.5A2.25 2.25 0 0 0 7.5 21h6a2.25 2.25 0 0 0 2.25-2.25V15M12 9l-3 3m0 0 3 3m-3-3h12.75"
/>
</svg>
<span class="hidden sm:inline text-sm font-medium">Déconnexion</span>
</a>
} @else {
<a
[routerLink]="['/auth']"
class="flex items-center gap-2 px-3 py-2 rounded-lg text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors"
aria-label="Se connecter"
>
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 -960 960 960"
fill="currentColor"
class="w-5 h-5"
>
<span class="inline-block h-4 w-4">
<svg
xmlns="http://www.w3.org/2000/svg"
class="w-full h-full fill-current"
viewBox="0 -960 960 960"
>
<path
d="M234-276q51-39 114-61.5T480-360q69 0 132 22.5T726-276q35-41 54.5-93T800-480q0-133-93.5-226.5T480-800q-133 0-226.5 93.5T160-480q0 59 19.5 111t54.5 93Zm246-164q-59 0-99.5-40.5T340-580q0-59 40.5-99.5T480-720q59 0 99.5 40.5T620-580q0 59-40.5 99.5T480-440Zm0 360q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q53 0 100-15.5t86-44.5q-39-29-86-44.5T480-280q-53 0-100 15.5T294-220q39 29 86 44.5T480-160Zm0-360q26 0 43-17t17-43q0-26-17-43t-43-17q-26 0-43 17t-17 43q0 26 17 43t43 17Zm0-60Zm0 360Z"
/>
</svg>
</span>
<span class="hidden sm:block text-black dark:text-white">Se connecter</span>
</a>
}
</div>
<path
d="M234-276q51-39 114-61.5T480-360q69 0 132 22.5T726-276q35-41 54.5-93T800-480q0-133-93.5-226.5T480-800q-133 0-226.5 93.5T160-480q0 59 19.5 111t54.5 93Zm246-164q-59 0-99.5-40.5T340-580q0-59 40.5-99.5T480-720q59 0 99.5 40.5T620-580q0 59-40.5 99.5T480-440Zm0 360q-83 0-156-31.5T197-197q-54-54-85.5-127T80-480q0-83 31.5-156T197-763q54-54 127-85.5T480-880q83 0 156 31.5T763-763q54 54 85.5 127T880-480q0 83-31.5 156T763-197q-54 54-127 85.5T480-80Zm0-80q53 0 100-15.5t86-44.5q-39-29-86-44.5T480-280q-53 0-100 15.5T294-220q39 29 86 44.5T480-160Zm0-360q26 0 43-17t17-43q0-26-17-43t-43-17q-26 0-43 17t-17 43q0 26 17 43t43 17Zm0-60Zm0 360Z"
/>
</svg>
<span class="hidden sm:inline text-sm font-medium">Connexion</span>
</a>
}
</div>
</nav>
</div>
</div>
</nav>
</header>

View File

@@ -0,0 +1,36 @@
<!-- Pagination responsive -->
<nav class="flex justify-center mt-8 sm:mt-12" aria-label="Pagination">
<ul class="flex flex-wrap gap-2 items-center justify-center">
<li>
<button
class="px-3 py-2 rounded-lg border border-gray-300 dark:border-gray-700 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors"
>
Précédent
</button>
</li>
<li>
<button class="px-4 py-2 rounded-lg bg-indigo-600 text-white font-medium">1</button>
</li>
<li>
<button
class="px-4 py-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors"
>
2
</button>
</li>
<li>
<button
class="px-4 py-2 rounded-lg hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors"
>
3
</button>
</li>
<li>
<button
class="px-3 py-2 rounded-lg border border-gray-300 dark:border-gray-700 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors"
>
Suivant
</button>
</li>
</ul>
</nav>

View File

@@ -0,0 +1,22 @@
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { PaginationComponent } from './pagination.component';
describe('PaginationComponent', () => {
let component: PaginationComponent;
let fixture: ComponentFixture<PaginationComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
imports: [PaginationComponent],
}).compileComponents();
fixture = TestBed.createComponent(PaginationComponent);
component = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
});

View File

@@ -0,0 +1,10 @@
import { Component } from '@angular/core';
@Component({
selector: 'app-pagination',
standalone: true,
imports: [],
templateUrl: './pagination.component.html',
styleUrl: './pagination.component.scss',
})
export class PaginationComponent {}