Première grosse version fonctionnel
This commit is contained in:
@@ -0,0 +1,11 @@
|
||||
@import 'tailwindcss';
|
||||
|
||||
@source '../../vendor/laravel/framework/src/Illuminate/Pagination/resources/views/*.blade.php';
|
||||
@source '../../storage/framework/views/*.php';
|
||||
@source '../**/*.blade.php';
|
||||
@source '../**/*.js';
|
||||
|
||||
@theme {
|
||||
--font-sans: 'Instrument Sans', ui-sans-serif, system-ui, sans-serif, 'Apple Color Emoji', 'Segoe UI Emoji',
|
||||
'Segoe UI Symbol', 'Noto Color Emoji';
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
import './bootstrap';
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
import axios from 'axios';
|
||||
window.axios = axios;
|
||||
|
||||
window.axios.defaults.headers.common['X-Requested-With'] = 'XMLHttpRequest';
|
||||
@@ -0,0 +1,75 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Connexion | CESIZen - Ministère de la Santé</title>
|
||||
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
||||
<style>
|
||||
:root { --fr-blue: #000091; }
|
||||
.fr-input-group { margin-bottom: 1.5rem; }
|
||||
.fr-label { display: block; font-size: 0.875rem; font-weight: 700; margin-bottom: 0.5rem; color: #161616; }
|
||||
.fr-input { width: 100%; padding: 0.75rem; border: 2px solid #3a3a3a; border-radius: 0; background-color: #eee; transition: border-color 0.2s; }
|
||||
.fr-input:focus { border-color: var(--fr-blue); outline: 3px solid var(--fr-blue); outline-offset: 2px; }
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-[#F6F6F6] min-h-screen flex flex-col font-sans">
|
||||
@include('layouts.header')
|
||||
|
||||
<main id="main-content" class="flex-1 flex items-center justify-center p-8">
|
||||
<div class="w-full max-w-lg bg-white border border-slate-200 shadow-xl p-12">
|
||||
<div class="mb-10 text-left border-l-4 border-[#000091] pl-6">
|
||||
<h1 class="text-3xl font-black text-slate-900 mb-2">Se connecter</h1>
|
||||
<p class="text-slate-600 font-medium">Espace sécurisé pour les étudiants du CESI</p>
|
||||
</div>
|
||||
|
||||
@if ($errors->any())
|
||||
<div class="bg-[#FAEFEF] border-l-4 border-[#E1000F] p-4 mb-8" role="alert">
|
||||
<p class="text-[#E1000F] text-sm font-bold">Erreur : {{ $errors->first() }}</p>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<form action="{{ route('login') }}" method="POST" class="space-y-8">
|
||||
@csrf
|
||||
<div class="fr-input-group">
|
||||
<label for="email" class="fr-label">Adresse électronique (email)</label>
|
||||
<input type="email" id="email" name="email" required
|
||||
class="fr-input"
|
||||
value="{{ old('email') }}"
|
||||
aria-required="true"
|
||||
autocomplete="email">
|
||||
</div>
|
||||
|
||||
<div class="fr-input-group">
|
||||
<label for="password" class="fr-label">Mot de passe</label>
|
||||
<input type="password" id="password" name="password" required
|
||||
class="fr-input"
|
||||
aria-required="true"
|
||||
autocomplete="current-password">
|
||||
</div>
|
||||
|
||||
<div class="flex items-center justify-between">
|
||||
<label class="flex items-center gap-3 cursor-pointer group">
|
||||
<input type="checkbox" name="remember" class="w-5 h-5 border-2 border-slate-400 text-[#000091] focus:ring-[#000091]">
|
||||
<span class="text-sm font-bold text-slate-700 group-hover:text-[#000091]">Rester connecté</span>
|
||||
</label>
|
||||
<a href="#" class="text-sm font-bold text-[#000091] hover:underline">Mot de passe oublié ?</a>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="w-full py-4 bg-[#000091] text-white font-bold text-lg hover:bg-blue-800 shadow-md transition-all uppercase tracking-widest">
|
||||
Valider la connexion
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div class="mt-12 pt-8 border-t border-slate-100">
|
||||
<h2 class="text-lg font-bold text-slate-900 mb-4">Pas encore de compte ?</h2>
|
||||
<a href="{{ route('register') }}" class="inline-flex items-center gap-2 px-6 py-3 border-2 border-[#000091] text-[#000091] font-bold hover:bg-blue-50 transition-all">
|
||||
Créer mon espace personnel
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
@include('layouts.footer')
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,94 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>Créer un compte | CESIZen - Ministère de la Santé</title>
|
||||
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
||||
<style>
|
||||
:root { --fr-blue: #000091; }
|
||||
.fr-input-group { margin-bottom: 1.5rem; }
|
||||
.fr-label { display: block; font-size: 0.875rem; font-weight: 700; margin-bottom: 0.5rem; color: #161616; }
|
||||
.fr-input { width: 100%; padding: 0.75rem; border: 2px solid #3a3a3a; border-radius: 0; background-color: #eee; transition: border-color 0.2s; }
|
||||
.fr-input:focus { border-color: var(--fr-blue); outline: 3px solid var(--fr-blue); outline-offset: 2px; }
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-[#F6F6F6] min-h-screen flex flex-col font-sans">
|
||||
@include('layouts.header')
|
||||
|
||||
<main id="main-content" class="flex-1 flex items-center justify-center p-8">
|
||||
<div class="w-full max-w-lg bg-white border border-slate-200 shadow-xl p-12">
|
||||
<div class="mb-10 text-left border-l-4 border-[#000091] pl-6">
|
||||
<h1 class="text-3xl font-black text-slate-900 mb-2">Créer mon espace</h1>
|
||||
<p class="text-slate-600 font-medium">Rejoignez la plateforme de santé étudiante du CESI</p>
|
||||
</div>
|
||||
|
||||
@if ($errors->any())
|
||||
<div class="bg-[#FAEFEF] border-l-4 border-[#E1000F] p-4 mb-8" role="alert">
|
||||
<ul class="list-disc list-inside text-[#E1000F] text-sm font-bold">
|
||||
@foreach ($errors->all() as $error)
|
||||
<li>{{ $error }}</li>
|
||||
@endforeach
|
||||
</ul>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<form action="{{ route('register') }}" method="POST" class="space-y-6">
|
||||
@csrf
|
||||
|
||||
<div class="fr-input-group">
|
||||
<label for="name" class="fr-label">Nom complet</label>
|
||||
<input type="text" id="name" name="name" required
|
||||
class="fr-input"
|
||||
value="{{ old('name') }}"
|
||||
aria-required="true"
|
||||
autocomplete="name">
|
||||
</div>
|
||||
|
||||
<div class="fr-input-group">
|
||||
<label for="email" class="fr-label">Adresse électronique (email académique)</label>
|
||||
<input type="email" id="email" name="email" required
|
||||
class="fr-input"
|
||||
value="{{ old('email') }}"
|
||||
aria-required="true"
|
||||
autocomplete="email">
|
||||
</div>
|
||||
|
||||
<div class="fr-input-group">
|
||||
<label for="password" class="fr-label">Mot de passe</label>
|
||||
<input type="password" id="password" name="password" required
|
||||
class="fr-input"
|
||||
aria-required="true"
|
||||
autocomplete="new-password">
|
||||
<p class="text-[10px] text-slate-500 mt-1 uppercase font-bold tracking-tight">8 caractères minimum, incluant chiffres et symboles</p>
|
||||
</div>
|
||||
|
||||
<div class="fr-input-group">
|
||||
<label for="password_confirmation" class="fr-label">Confirmer le mot de passe</label>
|
||||
<input type="password" id="password_confirmation" name="password_confirmation" required
|
||||
class="fr-input"
|
||||
aria-required="true"
|
||||
autocomplete="new-password">
|
||||
</div>
|
||||
|
||||
<div class="bg-slate-50 p-4 border border-slate-200 text-[11px] text-slate-600 mb-6">
|
||||
En cliquant sur "Créer mon compte", vous acceptez nos <a href="#" class="underline hover:text-[#000091]">Conditions Générales d'Utilisation</a> et confirmez avoir lu notre <a href="#" class="underline hover:text-[#000091]">Politique de Confidentialité</a> (RGPD).
|
||||
</div>
|
||||
|
||||
<button type="submit" class="w-full py-4 bg-[#000091] text-white font-bold text-lg hover:bg-blue-800 shadow-md transition-all uppercase tracking-widest">
|
||||
Créer mon compte
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div class="mt-12 pt-8 border-t border-slate-100 text-center">
|
||||
<p class="text-slate-600 mb-4 font-medium">Vous avez déjà un compte ?</p>
|
||||
<a href="{{ route('login') }}" class="inline-flex items-center gap-2 px-8 py-3 border-2 border-[#000091] text-[#000091] font-bold hover:bg-blue-50 transition-all uppercase tracking-widest text-sm">
|
||||
Se connecter
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
|
||||
@include('layouts.footer')
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,54 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Bilan de Stress')
|
||||
@section('header_title', 'Évaluation de Stress (Holmes & Rahe)')
|
||||
|
||||
@section('content')
|
||||
<div class="max-w-4xl mx-auto space-y-10">
|
||||
|
||||
@if(session('score'))
|
||||
<div class="bg-white p-8 border-l-8 border-[--fr-blue] shadow-lg">
|
||||
<h2 class="text-2xl font-black mb-4">Votre Résultat : <span class="text-[--fr-blue]">{{ session('score') }} points</span></h2>
|
||||
<div class="p-6 bg-slate-50 rounded-lg">
|
||||
@if(session('score') >= 300)
|
||||
<p class="font-bold text-red-700 uppercase mb-2">Risque élevé de maladie</p>
|
||||
<p class="text-slate-600">Votre score indique un niveau de stress très important. Nous vous conseillons vivement de consulter un professionnel de santé.</p>
|
||||
@elseif(session('score') >= 150)
|
||||
<p class="font-bold text-orange-700 uppercase mb-2">Risque modéré</p>
|
||||
<p class="text-slate-600">Vous avez traversé beaucoup de changements récemment. Prenez du temps pour vous reposer.</p>
|
||||
@else
|
||||
<p class="font-bold text-teal-700 uppercase mb-2">Risque faible</p>
|
||||
<p class="text-slate-600">Votre niveau de stress lié aux changements de vie semble stable.</p>
|
||||
@endif
|
||||
</div>
|
||||
<a href="{{ route('diagnostics.index') }}" class="mt-6 inline-block text-[--fr-blue] font-bold hover:underline">Recommencer le test</a>
|
||||
</div>
|
||||
@else
|
||||
<div class="bg-white p-8 border border-slate-200 shadow-sm">
|
||||
<div class="mb-8">
|
||||
<h2 class="text-xl font-bold mb-2">Quels événements avez-vous vécus ces 12 derniers mois ?</h2>
|
||||
<p class="text-sm text-slate-500 italic">Cochez toutes les cases qui correspondent à votre situation actuelle.</p>
|
||||
</div>
|
||||
|
||||
<form action="{{ route('diagnostics.store') }}" method="POST" class="space-y-4">
|
||||
@csrf
|
||||
<div class="grid grid-cols-1 gap-3 max-h-[500px] overflow-y-auto pr-4 border-b border-t border-slate-100 py-6">
|
||||
@foreach($events as $event)
|
||||
<label class="flex items-center gap-4 p-4 hover:bg-slate-50 rounded-lg cursor-pointer transition-colors border border-transparent hover:border-slate-200 group">
|
||||
<input type="checkbox" name="events[]" value="{{ $event->id }}" class="w-5 h-5 text-[--fr-blue] border-slate-300 rounded focus:ring-[--fr-blue]">
|
||||
<span class="flex-1 text-sm font-medium text-slate-700 group-hover:text-slate-900">{{ $event->event_name }}</span>
|
||||
<span class="text-xs font-bold text-slate-400">{{ $event->points }} pts</span>
|
||||
</label>
|
||||
@endforeach
|
||||
</div>
|
||||
|
||||
<div class="pt-6">
|
||||
<button type="submit" class="w-full py-4 bg-[#000091] text-white font-bold rounded-sm hover:bg-blue-800 shadow-md transition-all uppercase tracking-widest">
|
||||
Calculer mon score de stress
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
@endsection
|
||||
@@ -0,0 +1,84 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Journal Émotionnel')
|
||||
|
||||
@section('content')
|
||||
<div class="max-w-4xl mx-auto space-y-10">
|
||||
|
||||
<!-- Nouveau Record -->
|
||||
<div class="bg-white p-8 border border-slate-200 shadow-sm">
|
||||
<h2 class="text-xl font-bold mb-6">Comment vous sentez-vous aujourd'hui ?</h2>
|
||||
<form action="{{ route('emotions.store') }}" method="POST" class="space-y-6">
|
||||
@csrf
|
||||
<div>
|
||||
<label class="block text-sm font-bold text-slate-700 mb-3">Votre émotion dominante</label>
|
||||
<div class="grid grid-cols-3 md:grid-cols-5 gap-4">
|
||||
@foreach(['Très bien' => '😊', 'Bien' => '🙂', 'Neutre' => '😐', 'Pas top' => '🙁', 'Stressé' => '😫'] as $label => $emoji)
|
||||
<label class="cursor-pointer group">
|
||||
<input type="radio" name="emotion" value="{{ $label }}" class="peer hidden" required>
|
||||
<div class="p-4 border-2 border-slate-100 rounded-xl text-center peer-checked:border-[--fr-blue] peer-checked:bg-blue-50 transition-all">
|
||||
<span class="block text-2xl mb-1">{{ $emoji }}</span>
|
||||
<span class="text-[10px] font-bold uppercase tracking-widest text-slate-500 group-hover:text-slate-900">{{ $label }}</span>
|
||||
</div>
|
||||
</label>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="block text-sm font-bold text-slate-700 mb-3">Intensité (1 à 5)</label>
|
||||
<input type="range" name="intensity" min="1" max="5" step="1" class="w-full h-2 bg-slate-200 rounded-lg appearance-none cursor-pointer accent-[--fr-blue]">
|
||||
<div class="flex justify-between text-[10px] font-bold text-slate-400 mt-2 px-1">
|
||||
<span>FAIBLE</span>
|
||||
<span>MODÉRÉE</span>
|
||||
<span>TRÈS FORTE</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label class="block text-sm font-bold text-slate-700 mb-3">Notes (Optionnel)</label>
|
||||
<textarea name="note" rows="3" class="w-full border-slate-200 rounded-lg focus:ring-[--fr-blue] focus:border-[--fr-blue]" placeholder="Décrivez votre état..."></textarea>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="w-full py-4 bg-[--fr-blue] text-white font-bold rounded-sm hover:bg-blue-800 shadow-md transition-all">
|
||||
Enregistrer dans mon journal
|
||||
</button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Historique -->
|
||||
<div class="space-y-4">
|
||||
<h2 class="text-xl font-bold">Historique récent</h2>
|
||||
@forelse($records as $record)
|
||||
<div class="bg-white p-6 border border-slate-100 shadow-sm flex items-center justify-between">
|
||||
<div class="flex items-center gap-6">
|
||||
<div class="text-3xl">
|
||||
@switch($record->emotion)
|
||||
@case('Très bien') 😊 @break
|
||||
@case('Bien') 🙂 @break
|
||||
@case('Neutre') 😐 @break
|
||||
@case('Pas top') 🙁 @break
|
||||
@case('Stressé') 😫 @break
|
||||
@default 😐
|
||||
@endswitch
|
||||
</div>
|
||||
<div>
|
||||
<p class="font-bold text-slate-900 capitalize">{{ $record->emotion }}</p>
|
||||
<p class="text-xs text-slate-500">{{ $record->created_at->diffForHumans() }}</p>
|
||||
@if($record->note)
|
||||
<p class="text-sm text-slate-600 mt-1 italic">"{{ $record->note }}"</p>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex gap-1">
|
||||
@for($i=1; $i<=5; $i++)
|
||||
<div class="w-2 h-6 rounded-full {{ $i <= $record->intensity ? 'bg-[--cz-jade-bg]' : 'bg-slate-100' }}"></div>
|
||||
@endfor
|
||||
</div>
|
||||
</div>
|
||||
@empty
|
||||
<p class="text-center text-slate-400 py-10">Aucun enregistrement pour le moment.</p>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@@ -0,0 +1,37 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>@yield('title', 'CESIZen') | Ministère de la Santé</title>
|
||||
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
||||
<style>
|
||||
:root {
|
||||
--fr-blue: #000091;
|
||||
--cz-navy: #000074;
|
||||
--cz-mustard: #715200;
|
||||
--cz-mustard-bg: #F8B803;
|
||||
--cz-jade: #00635B;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
@include('layouts.header')
|
||||
<body class="bg-[#F6F6F6] text-[#161616] min-h-screen font-sans">
|
||||
<div class="flex min-h-screen">
|
||||
<!-- Sidebar Simplifiée pour les sous-pages -->
|
||||
@include('layouts.sidebar')
|
||||
|
||||
<main class="flex-1">
|
||||
<!-- <header class="bg-white border-b border-slate-200 px-8 py-4 flex items-center justify-between">
|
||||
<h1 class="text-xl font-bold">@yield('header_title')</h1>
|
||||
@auth
|
||||
<span class="text-sm font-bold text-slate-600">{{ Auth::user()->name }}</span>
|
||||
@endauth
|
||||
</header> -->
|
||||
<div class="p-8">
|
||||
@yield('content')
|
||||
</div>
|
||||
</main>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
@@ -0,0 +1,21 @@
|
||||
<footer class="mt-auto bg-white border-t border-slate-200 pt-12 pb-8" role="contentinfo">
|
||||
<div class="container mx-auto px-8">
|
||||
<div class="flex flex-col lg:flex-row justify-between gap-10 mb-10 border-b border-slate-100 pb-10">
|
||||
<div class="flex items-center gap-6">
|
||||
<img src="img/ministere.png" alt="Logo du Ministère de la Santé et de la Prévention" class="w-24 h-auto">
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-6 text-xs font-bold text-slate-600">
|
||||
<a href="#" class="hover:text-[--fr-blue] underline">legifrance.gouv.fr</a>
|
||||
<a href="#" class="hover:text-[--fr-blue] underline">service-public.fr</a>
|
||||
<a href="#" class="hover:text-[--fr-blue] underline">data.gouv.fr</a>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-6 text-[11px] font-bold text-slate-500 uppercase tracking-wider">
|
||||
<a href="#" class="hover:underline">Mentions légales</a>
|
||||
<a href="#" class="hover:underline">Accessibilité : partiellement conforme</a>
|
||||
<a href="#" class="hover:underline">Données personnelles</a>
|
||||
<a href="#" class="hover:underline">Cookies</a>
|
||||
<span class="ml-auto text-slate-400 font-normal">© {{ date('Y') }} Ministère de la Santé - CESIZen</span>
|
||||
</div>
|
||||
</div>
|
||||
</footer>
|
||||
@@ -0,0 +1,41 @@
|
||||
<header role="banner" class="bg-white border-b-2 border-[--fr-blue] sticky top-0 z-50 shadow-sm">
|
||||
<div class="container mx-auto px-4 lg:px-8 py-3 flex items-center justify-between">
|
||||
<div class="flex items-start justify-start gap-8">
|
||||
<div class="flex flex-col border-r-2 border-slate-200 pr-8" aria-hidden="true">
|
||||
<img src="img/ministere.png" alt="Logo du Ministère de la Santé et de la Prévention" class="w-24 h-auto">
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col">
|
||||
<h1 class="text-2xl font-black text-[--fr-blue] tracking-tight">
|
||||
<a href="{{ route('home') }}"><img src="img/CesiZen.png" alt="Logo CesiZen" class="w-32 h-auto"></a>
|
||||
</h1>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<nav class="flex items-center gap-6" role="navigation" aria-label="Menu utilisateur">
|
||||
@auth
|
||||
<a href="{{ route('profile.index') }}" class="flex items-center gap-3 px-4 py-1.5 bg-slate-50 rounded-lg border border-slate-200 shadow-sm hover:border-[#000091] transition-all group">
|
||||
<div class="text-right">
|
||||
<p class="text-sm font-bold leading-none text-slate-900 group-hover:text-[#000091]">{{ Auth::user()->name }}</p>
|
||||
<p class="text-[10px] text-slate-500 font-bold uppercase tracking-tighter">Mon Profil</p>
|
||||
</div>
|
||||
<img src="https://ui-avatars.com/api/?name={{ urlencode(Auth::user()->name) }}&background=000091&color=fff" class="w-9 h-9 rounded-lg border border-slate-200" alt="Avatar de {{ Auth::user()->name }}">
|
||||
</a>
|
||||
<form action="{{ route('logout') }}" method="POST" class="inline">
|
||||
@csrf
|
||||
<button type="submit" class="text-xs font-bold text-slate-500 hover:text-[#E1000F] uppercase tracking-tighter flex items-center gap-1">
|
||||
<x-heroicon-o-arrow-left-on-rectangle class="h-4 w-4" />
|
||||
Quitter
|
||||
</button>
|
||||
</form>
|
||||
@else
|
||||
<div class="flex items-center gap-4">
|
||||
<a href="/login" class="text-sm font-bold text-[#000091] hover:underline px-2 py-2">Se connecter</a>
|
||||
<a href="/register" class="px-6 py-2.5 bg-[#000091] text-white text-sm font-bold rounded-sm shadow-md hover:bg-blue-800 transition-all">
|
||||
Créer un compte
|
||||
</a>
|
||||
</div>
|
||||
@endauth
|
||||
</nav>
|
||||
</div>
|
||||
</header>
|
||||
@@ -0,0 +1,67 @@
|
||||
<aside class="hidden lg:flex w-80 flex-col bg-white border-r border-slate-200 overflow-y-auto" role="navigation" aria-label="Menu latéral">
|
||||
<nav class="flex-1 px-6 py-10 space-y-1">
|
||||
<p class="text-[10px] font-bold text-slate-500 uppercase tracking-[0.2em] mb-4 px-4">Navigation</p>
|
||||
|
||||
<!-- Tableau de bord -->
|
||||
<a href="{{ route('home') }}"
|
||||
class="flex items-center gap-4 px-4 py-3 rounded-sm transition-all {{ request()->routeIs('home') ? 'text-white bg-[#000091] font-bold shadow-md' : 'text-slate-700 hover:bg-slate-50 font-medium' }}"
|
||||
{!! request()->routeIs('home') ? 'aria-current="page"' : '' !!}>
|
||||
<x-heroicon-o-home class="h-5 w-5" aria-hidden="true" />
|
||||
Tableau de bord
|
||||
</a>
|
||||
|
||||
<!-- Mon Journal Émotionnel -->
|
||||
<a href="{{ route('emotions.index') }}"
|
||||
class="flex items-center gap-4 px-4 py-3 rounded-sm transition-all group {{ request()->routeIs('emotions.*') ? 'text-white bg-[#000091] font-bold shadow-md' : 'text-slate-700 hover:bg-slate-50 font-medium border-b border-slate-100/50' }}"
|
||||
{!! request()->routeIs('emotions.*') ? 'aria-current="page"' : '' !!}>
|
||||
<div class="w-8 h-8 rounded-sm flex items-center justify-center transition-colors {{ request()->routeIs('emotions.*') ? 'bg-white/20 text-white' : 'bg-teal-50 text-[--cz-jade]' }}" aria-hidden="true">
|
||||
<x-heroicon-o-clock class="h-4 w-4" />
|
||||
</div>
|
||||
Mon Journal Émotionnel
|
||||
</a>
|
||||
|
||||
<!-- Diagnostics Stress -->
|
||||
<a href="{{ route('diagnostics.index') }}"
|
||||
class="flex items-center gap-4 px-4 py-3 rounded-sm transition-all group {{ request()->routeIs('diagnostics.*') ? 'text-white bg-[#000091] font-bold shadow-md' : 'text-slate-700 hover:bg-slate-50 font-medium border-b border-slate-100/50' }}"
|
||||
{!! request()->routeIs('diagnostics.*') ? 'aria-current="page"' : '' !!}>
|
||||
<div class="w-8 h-8 rounded-sm flex items-center justify-center transition-colors {{ request()->routeIs('diagnostics.*') ? 'bg-white/20 text-white' : 'bg-orange-50 text-[--cz-mustard]' }}" aria-hidden="true">
|
||||
<x-heroicon-o-chart-bar class="h-4 w-4" />
|
||||
</div>
|
||||
Diagnostics Stress
|
||||
</a>
|
||||
|
||||
<!-- Exercices de Respiration -->
|
||||
<a href="{{ route('relaxation.index') }}"
|
||||
class="flex items-center gap-4 px-4 py-3 rounded-sm transition-all group {{ request()->routeIs('relaxation.*') ? 'text-white bg-[#000091] font-bold shadow-md' : 'text-slate-700 hover:bg-slate-50 font-medium border-b border-slate-100/50' }}"
|
||||
{!! request()->routeIs('relaxation.*') ? 'aria-current="page"' : '' !!}>
|
||||
<div class="w-8 h-8 rounded-sm flex items-center justify-center transition-colors {{ request()->routeIs('relaxation.*') ? 'bg-white/20 text-white' : 'bg-indigo-50 text-indigo-700' }}" aria-hidden="true">
|
||||
<x-heroicon-o-heart class="h-4 w-4" />
|
||||
</div>
|
||||
Exercices de Respiration
|
||||
</a>
|
||||
|
||||
<div class="pt-10 space-y-1">
|
||||
<p class="text-[10px] font-bold text-slate-500 uppercase tracking-[0.2em] mb-4 px-4">Services de l'État</p>
|
||||
<a href="#" class="flex items-center justify-between px-4 py-2 text-sm text-slate-600 hover:text-[--fr-blue] font-medium transition-colors">
|
||||
<span>Guide Santé Étudiante</span>
|
||||
<x-heroicon-o-document-text class="h-4 w-4" aria-hidden="true" />
|
||||
</a>
|
||||
<a href="#" class="flex items-center justify-between px-4 py-2 text-sm text-slate-600 hover:text-[--fr-blue] font-medium transition-colors">
|
||||
<span>Ligne d'Urgence</span>
|
||||
<x-heroicon-o-phone class="h-4 w-4" aria-hidden="true" />
|
||||
</a>
|
||||
</div>
|
||||
</nav>
|
||||
|
||||
<!-- Alert Block -->
|
||||
<div class="p-6">
|
||||
<div class="bg-slate-900 rounded-sm p-6 text-white relative overflow-hidden">
|
||||
<p class="text-[10px] font-bold uppercase tracking-widest text-slate-400 mb-2">Besoin d'aide ?</p>
|
||||
<p class="text-xs font-medium leading-relaxed mb-4">Une ligne d'écoute gratuite est disponible pour tous les étudiants.</p>
|
||||
<a href="tel:0800130000" class="flex items-center justify-center gap-2 w-full py-2.5 bg-white text-slate-900 text-sm font-bold rounded-sm hover:bg-slate-100 transition-colors">
|
||||
<x-heroicon-o-phone class="h-4 w-4" aria-hidden="true" />
|
||||
0 800 130 000
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</aside>
|
||||
@@ -0,0 +1,121 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Mon Profil')
|
||||
@section('header_title', 'Gestion du compte')
|
||||
|
||||
@section('content')
|
||||
<div class="max-w-4xl mx-auto space-y-8">
|
||||
|
||||
<!-- Informations Personnelles -->
|
||||
<div class="bg-white p-8 border border-slate-200 shadow-sm">
|
||||
<div class="flex items-center gap-4 mb-8 border-l-4 border-[#000091] pl-6">
|
||||
<h2 class="text-2xl font-black text-slate-900">Informations personnelles</h2>
|
||||
</div>
|
||||
|
||||
@if (session('status') === 'profile-updated')
|
||||
<div class="bg-teal-50 border-l-4 border-[#00635B] p-4 mb-8" role="alert">
|
||||
<p class="text-[#00635B] text-sm font-bold">Vos informations ont été mises à jour avec succès.</p>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<form method="post" action="{{ route('profile.update') }}" class="space-y-6">
|
||||
@csrf
|
||||
@method('patch')
|
||||
|
||||
<div class="space-y-2">
|
||||
<label for="name" class="block text-sm font-bold text-slate-700">Nom complet</label>
|
||||
<input id="name" name="name" type="text" class="w-full border-2 border-slate-300 p-3 focus:border-[#000091] focus:ring-0 bg-slate-50" value="{{ old('name', $user->name) }}" required autocomplete="name">
|
||||
@error('name') <p class="text-red-600 text-xs mt-1">{{ $message }}</p> @enderror
|
||||
</div>
|
||||
|
||||
<div class="space-y-2">
|
||||
<label for="email" class="block text-sm font-bold text-slate-700">Adresse électronique</label>
|
||||
<input id="email" name="email" type="email" class="w-full border-2 border-slate-300 p-3 focus:border-[#000091] focus:ring-0 bg-slate-50" value="{{ old('email', $user->email) }}" required autocomplete="username">
|
||||
@error('email') <p class="text-red-600 text-xs mt-1">{{ $message }}</p> @enderror
|
||||
</div>
|
||||
|
||||
<div class="pt-4">
|
||||
<button type="submit" class="px-8 py-3 bg-[#000091] text-white font-bold rounded-sm hover:bg-blue-800 transition-all shadow-md uppercase tracking-wider text-sm">
|
||||
Enregistrer les modifications
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Changement de Mot de Passe -->
|
||||
<div class="bg-white p-8 border border-slate-200 shadow-sm">
|
||||
<div class="flex items-center gap-4 mb-8 border-l-4 border-[#000091] pl-6">
|
||||
<h2 class="text-2xl font-black text-slate-900">Sécurité du compte</h2>
|
||||
</div>
|
||||
|
||||
@if (session('status') === 'password-updated')
|
||||
<div class="bg-teal-50 border-l-4 border-[#00635B] p-4 mb-8" role="alert">
|
||||
<p class="text-[#00635B] text-sm font-bold">Votre mot de passe a été modifié.</p>
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<form method="post" action="{{ route('profile.password') }}" class="space-y-6">
|
||||
@csrf
|
||||
@method('put')
|
||||
|
||||
<div class="space-y-2">
|
||||
<label for="current_password" class="block text-sm font-bold text-slate-700">Mot de passe actuel</label>
|
||||
<input id="current_password" name="current_password" type="password" class="w-full border-2 border-slate-300 p-3 focus:border-[#000091] focus:ring-0 bg-slate-50" autocomplete="current-password">
|
||||
@error('current_password', 'updatePassword') <p class="text-red-600 text-xs mt-1">{{ $message }}</p> @enderror
|
||||
</div>
|
||||
|
||||
<div class="space-y-2">
|
||||
<label for="password" class="block text-sm font-bold text-slate-700">Nouveau mot de passe</label>
|
||||
<input id="password" name="password" type="password" class="w-full border-2 border-slate-300 p-3 focus:border-[#000091] focus:ring-0 bg-slate-50" autocomplete="new-password">
|
||||
@error('password', 'updatePassword') <p class="text-red-600 text-xs mt-1">{{ $message }}</p> @enderror
|
||||
</div>
|
||||
|
||||
<div class="space-y-2">
|
||||
<label for="password_confirmation" class="block text-sm font-bold text-slate-700">Confirmer le mot de passe</label>
|
||||
<input id="password_confirmation" name="password_confirmation" type="password" class="w-full border-2 border-slate-300 p-3 focus:border-[#000091] focus:ring-0 bg-slate-50" autocomplete="new-password">
|
||||
</div>
|
||||
|
||||
<div class="pt-4">
|
||||
<button type="submit" class="px-8 py-3 bg-[#000091] text-white font-bold rounded-sm hover:bg-blue-800 transition-all shadow-md uppercase tracking-wider text-sm">
|
||||
Mettre à jour le mot de passe
|
||||
</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
<!-- Zone de Danger -->
|
||||
<div class="bg-[#FAEFEF] p-8 border border-red-200 shadow-sm">
|
||||
<div class="flex items-center gap-4 mb-6 border-l-4 border-[#E1000F] pl-6">
|
||||
<h2 class="text-2xl font-black text-[#E1000F]">Suppression du compte</h2>
|
||||
</div>
|
||||
|
||||
<p class="text-sm text-slate-700 mb-8 leading-relaxed">
|
||||
Une fois votre compte supprimé, toutes vos données de santé, votre journal émotionnel et vos favoris seront définitivement effacés de nos serveurs sécurisés. Cette action est irréversible.
|
||||
</p>
|
||||
|
||||
<button onclick="document.getElementById('delete-modal').classList.remove('hidden')" class="px-8 py-3 bg-[#E1000F] text-white font-bold rounded-sm hover:bg-red-800 transition-all shadow-md uppercase tracking-wider text-sm">
|
||||
Supprimer mon compte définitivement
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Modal de suppression (Simplifié pour l'exemple) -->
|
||||
<div id="delete-modal" class="hidden fixed inset-0 bg-slate-900/50 backdrop-blur-sm z-[100] flex items-center justify-center p-4">
|
||||
<div class="bg-white max-w-md w-full p-8 shadow-2xl border-t-8 border-[#E1000F]">
|
||||
<h3 class="text-xl font-black mb-4">Êtes-vous absolument sûr ?</h3>
|
||||
<p class="text-sm text-slate-600 mb-8">Veuillez saisir votre mot de passe pour confirmer la suppression définitive de votre compte.</p>
|
||||
|
||||
<form method="post" action="{{ route('profile.destroy') }}" class="space-y-6">
|
||||
@csrf
|
||||
@method('delete')
|
||||
|
||||
<input type="password" name="password" placeholder="Mot de passe" class="w-full border-2 border-slate-300 p-3 focus:border-[#E1000F] focus:ring-0 bg-slate-50" required>
|
||||
|
||||
<div class="flex gap-4">
|
||||
<button type="button" onclick="document.getElementById('delete-modal').classList.add('hidden')" class="flex-1 py-3 bg-slate-100 text-slate-700 font-bold hover:bg-slate-200 transition-all">Annuler</button>
|
||||
<button type="submit" class="flex-1 py-3 bg-[#E1000F] text-white font-bold hover:bg-red-800 transition-all shadow-md">Confirmer</button>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@endsection
|
||||
@@ -0,0 +1,214 @@
|
||||
@extends('layouts.app')
|
||||
|
||||
@section('title', 'Détente & Respiration')
|
||||
|
||||
@section('content')
|
||||
<div class="max-w-6xl mx-auto space-y-12">
|
||||
|
||||
<!-- Module de Respiration Guidée -->
|
||||
<div x-data="breathingApp()" class="bg-white p-8 border border-slate-300 shadow-sm relative overflow-hidden">
|
||||
<div class="flex flex-col lg:flex-row gap-12 items-center">
|
||||
|
||||
<!-- Contrôles et Choix du mode -->
|
||||
<div class="flex-1 space-y-6 w-full">
|
||||
<div>
|
||||
<h2 class="text-2xl font-bold text-slate-900 mb-2 uppercase tracking-tight">Respiration Guidée</h2>
|
||||
<p class="text-slate-500 text-sm">Sélectionnez un programme pour stabiliser votre rythme cardiaque.</p>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 gap-4" x-show="!isStarted">
|
||||
<template x-for="mode in modes" :key="mode.name">
|
||||
<button
|
||||
@click="selectedMode = mode"
|
||||
:class="selectedMode.name === mode.name ? 'border-[--fr-blue] bg-blue-50 ring-2 ring-[--fr-blue] ring-opacity-20' : 'border-slate-300 bg-white'"
|
||||
class="flex items-center gap-4 p-5 border-2 rounded-xl transition-all text-left group shadow-sm hover:border-slate-400"
|
||||
>
|
||||
<div :class="mode.colorClass" class="w-12 h-12 rounded-full flex items-center justify-center text-white shadow-sm">
|
||||
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" class="w-6 h-6">
|
||||
<path stroke-linecap="round" stroke-linejoin="round" d="M12 3v17.25m0 0c-1.472 0-2.882.265-4.185.75M12 20.25c1.472 0 2.882.265 4.185.75M18.75 4.905c-.921-.154-1.862-.23-2.812-.23H9.25c-.95 0-1.891.076-2.812.23m12.324 3.248c.334.334.613.725.828 1.154M6.75 8.153a6.001 6.001 0 0 0-4.02 5.492m18.77 0c.115.624.175 1.266.175 1.921v2.684m-19.17 0v-2.684c0-.655.06-1.297.175-1.921M18 21V9a6 6 0 0 0-6-6h0a6 6 0 0 0-6 6v12" />
|
||||
</svg>
|
||||
</div>
|
||||
<div class="flex-1">
|
||||
<p class="font-bold text-slate-900 text-base" x-text="mode.name"></p>
|
||||
<p class="text-xs text-slate-500 leading-tight mt-1" x-text="mode.desc"></p>
|
||||
</div>
|
||||
</button>
|
||||
</template>
|
||||
|
||||
<button @click="startExercise()" class="w-full py-5 bg-[--fr-blue] text-white font-bold rounded-sm shadow-lg hover:bg-blue-800 transition-all mt-4 uppercase tracking-[0.2em] text-sm">
|
||||
Lancer la session (5 min)
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Affichage pendant l'exercice -->
|
||||
<div class="space-y-8 py-10 text-center lg:text-left" x-show="isStarted" x-cloak>
|
||||
<div>
|
||||
<p class="text-6xl font-light tracking-tighter text-slate-400" x-text="formatTime(totalSeconds)"></p>
|
||||
<p class="text-xs font-bold text-[--fr-blue] uppercase tracking-[0.3em] mt-3" x-text="selectedMode.name"></p>
|
||||
</div>
|
||||
|
||||
<button @click="stopExercise()" class="px-10 py-4 border-2 border-red-200 text-red-600 font-bold rounded-sm hover:bg-red-50 transition-all uppercase text-xs tracking-widest">
|
||||
Interrompre
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Animation du Cercle -->
|
||||
<div class="flex-1 flex flex-col items-center justify-center min-h-[450px] w-full bg-slate-50 border border-slate-200 rounded-sm relative">
|
||||
<div
|
||||
class="rounded-full flex items-center justify-center transition-all duration-1000 ease-in-out border-8 relative shadow-2xl"
|
||||
:class="selectedMode.borderClass"
|
||||
:style="'width: ' + circleSize + 'px; height: ' + circleSize + 'px; background-color: ' + selectedMode.bgOpacity"
|
||||
>
|
||||
<img src="{{ asset('img/CesiZen logo.png') }}" class="absolute w-2/3 opacity-10 pointer-events-none" alt="">
|
||||
|
||||
<div class="text-center z-10">
|
||||
<p class="text-2xl font-black tracking-widest uppercase mb-1" :class="selectedMode.textClass" x-text="phaseText"></p>
|
||||
<p class="text-5xl font-light" :class="selectedMode.textClass" x-show="isStarted" x-text="phaseTimer"></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Section Activités -->
|
||||
<div class="space-y-8">
|
||||
<div class="flex items-center gap-4">
|
||||
<h2 class="text-xl font-bold text-slate-900 uppercase tracking-widest whitespace-nowrap">Bibliothèque Méditation</h2>
|
||||
<div class="h-1 flex-1 bg-slate-100"></div>
|
||||
</div>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8">
|
||||
@forelse($activities as $activity)
|
||||
<div class="bg-white rounded-sm border-2 border-slate-200 overflow-hidden flex flex-col shadow-sm group hover:border-[--fr-blue] transition-all">
|
||||
<div class="h-48 bg-slate-100 flex items-center justify-center relative">
|
||||
@if($activity->type == 'audio')
|
||||
<x-heroicon-o-musical-note class="w-16 h-16 text-slate-300 group-hover:text-blue-200 transition-colors" />
|
||||
@elseif($activity->type == 'video')
|
||||
<x-heroicon-o-play-circle class="w-16 h-16 text-slate-300 group-hover:text-blue-200 transition-colors" />
|
||||
@else
|
||||
<x-heroicon-o-document-text class="w-16 h-16 text-slate-300 group-hover:text-blue-200 transition-colors" />
|
||||
@endif
|
||||
|
||||
<button
|
||||
onclick="toggleFavorite({{ $activity->id }}, this)"
|
||||
class="absolute top-4 right-4 p-2.5 rounded-full bg-white shadow-md border border-slate-200 transition-all hover:scale-110 {{ in_array($activity->id, $favorites) ? 'text-red-500 border-red-100' : 'text-slate-400' }}"
|
||||
>
|
||||
<x-heroicon-s-heart class="w-6 h-6" />
|
||||
</button>
|
||||
</div>
|
||||
<div class="p-8 flex-1 flex flex-col">
|
||||
<div class="flex items-center gap-2 mb-4">
|
||||
<span class="px-3 py-1 bg-blue-50 text-[--fr-blue] text-[10px] font-bold uppercase rounded-sm">{{ $activity->type }}</span>
|
||||
</div>
|
||||
<h3 class="text-xl font-bold text-slate-900 mb-3 group-hover:text-[--fr-blue] transition-colors leading-tight">{{ $activity->title }}</h3>
|
||||
<p class="text-sm text-slate-500 mb-8 flex-1 leading-relaxed">{{ $activity->description }}</p>
|
||||
|
||||
<a href="{{ $activity->url ?? '#' }}" target="_blank" class="w-full py-4 bg-[--fr-blue] text-white text-center text-xs font-bold rounded-sm shadow-md hover:bg-blue-800 transition-all uppercase tracking-widest">
|
||||
DÉCOUVRIR L'ACTIVITÉ
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
@empty
|
||||
<p class="text-slate-400 italic">Aucune activité disponible.</p>
|
||||
@endforelse
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<script>
|
||||
async function toggleFavorite(activityId, btn) {
|
||||
try {
|
||||
const response = await fetch(`/relaxation/${activityId}/favorite`, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'X-CSRF-TOKEN': '{{ csrf_token() }}',
|
||||
'Content-Type': 'application/json'
|
||||
}
|
||||
});
|
||||
const data = await response.json();
|
||||
|
||||
if (data.status === 'added') {
|
||||
btn.classList.remove('text-slate-400');
|
||||
btn.classList.add('text-red-500', 'border-red-100');
|
||||
} else {
|
||||
btn.classList.remove('text-red-500', 'border-red-100');
|
||||
btn.classList.add('text-slate-400');
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Erreur favoris');
|
||||
}
|
||||
}
|
||||
|
||||
function breathingApp() {
|
||||
return {
|
||||
isStarted: false,
|
||||
totalSeconds: 300,
|
||||
circleSize: 220,
|
||||
phaseText: 'Prêt ?',
|
||||
phaseTimer: 0,
|
||||
interval: null,
|
||||
|
||||
modes: [
|
||||
{ name: '7-4-8', desc: 'Favorise l\'endormissement et la détente musculaire profonde.', inhale: 7, hold: 4, exhale: 8, colorClass: 'bg-indigo-600', borderClass: 'border-indigo-200', textClass: 'text-indigo-600', bgClass: 'bg-indigo-600', bgOpacity: 'rgba(79, 70, 229, 0.05)' },
|
||||
{ name: '5-5', desc: 'Cohérence cardiaque pour équilibrer le système nerveux.', inhale: 5, hold: 0, exhale: 5, colorClass: 'bg-teal-600', borderClass: 'border-teal-200', textClass: 'text-teal-600', bgClass: 'bg-teal-600', bgOpacity: 'rgba(13, 148, 136, 0.05)' },
|
||||
{ name: '4-6', desc: 'Réduction rapide de l\'anxiété par l\'expiration prolongée.', inhale: 4, hold: 0, exhale: 6, colorClass: 'bg-orange-600', borderClass: 'border-orange-200', textClass: 'text-orange-600', bgClass: 'bg-orange-600', bgOpacity: 'rgba(234, 88, 12, 0.05)' }
|
||||
],
|
||||
selectedMode: null,
|
||||
|
||||
init() {
|
||||
this.selectedMode = this.modes[1];
|
||||
},
|
||||
|
||||
async startExercise() {
|
||||
this.isStarted = true;
|
||||
this.totalSeconds = 300;
|
||||
|
||||
this.interval = setInterval(() => {
|
||||
if (this.totalSeconds > 0) this.totalSeconds--;
|
||||
else this.stopExercise();
|
||||
}, 1000);
|
||||
|
||||
while (this.isStarted) {
|
||||
await this.runPhase('Inspirez', this.selectedMode.inhale, 350);
|
||||
if (!this.isStarted) break;
|
||||
if (this.selectedMode.hold > 0) {
|
||||
await this.runPhase('Bloquez', this.selectedMode.hold, 350);
|
||||
if (!this.isStarted) break;
|
||||
}
|
||||
await this.runPhase('Expirez', this.selectedMode.exhale, 220);
|
||||
}
|
||||
},
|
||||
|
||||
async runPhase(text, seconds, targetSize) {
|
||||
this.phaseText = text;
|
||||
this.phaseTimer = seconds;
|
||||
this.circleSize = targetSize;
|
||||
for (let i = 0; i < seconds; i++) {
|
||||
if (!this.isStarted) return;
|
||||
await new Promise(resolve => setTimeout(resolve, 1000));
|
||||
this.phaseTimer--;
|
||||
}
|
||||
},
|
||||
|
||||
stopExercise() {
|
||||
this.isStarted = false;
|
||||
this.phaseText = 'Prêt ?';
|
||||
this.circleSize = 220;
|
||||
clearInterval(this.interval);
|
||||
},
|
||||
|
||||
formatTime(sec) {
|
||||
let m = Math.floor(sec / 60);
|
||||
let s = sec % 60;
|
||||
return `${m}:${s < 10 ? '0' : ''}${s}`;
|
||||
}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
[x-cloak] { display: none !important; }
|
||||
</style>
|
||||
@endsection
|
||||
@@ -0,0 +1,169 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<title>CESIZen | Ministère de la Santé et de la Prévention</title>
|
||||
|
||||
<!-- Fonts -->
|
||||
<link rel="preconnect" href="https://fonts.bunny.net">
|
||||
<link href="https://fonts.bunny.net/css?family=instrument-sans:400,500,600,700" rel="stylesheet" />
|
||||
|
||||
<!-- Scripts -->
|
||||
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
||||
|
||||
<style>
|
||||
:root {
|
||||
/* Official French Government Colors (DSFR) */
|
||||
--fr-blue: #000091;
|
||||
--fr-blue-hover: #1212ff;
|
||||
--fr-red: #E1000F;
|
||||
--fr-text: #161616;
|
||||
--fr-background: #F6F6F6;
|
||||
|
||||
/* CESIZen Adapted for RGAA (High Contrast) */
|
||||
--cz-navy: #000074; /* Darker than 000080 for better contrast */
|
||||
--cz-mustard: #715200; /* Darkened mustard for text on white (Contrast > 7:1) */
|
||||
--cz-mustard-bg: #F8B803; /* Original mustard for backgrounds only */
|
||||
--cz-jade: #00635B; /* Darkened jade for text (Contrast > 4.5:1) */
|
||||
--cz-jade-bg: #26A69A; /* Original jade for backgrounds */
|
||||
--cz-indigo: #303F9F;
|
||||
--cz-coral: #C62828;
|
||||
}
|
||||
|
||||
/* Focus state for RGAA */
|
||||
:focus-visible {
|
||||
outline: 3px solid var(--fr-blue);
|
||||
outline-offset: 2px;
|
||||
}
|
||||
|
||||
.skip-link {
|
||||
position: absolute;
|
||||
top: -40px;
|
||||
left: 0;
|
||||
background: var(--fr-blue);
|
||||
color: white;
|
||||
padding: 8px;
|
||||
z-index: 100;
|
||||
transition: top 0.2s;
|
||||
}
|
||||
.skip-link:focus {
|
||||
top: 0;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body class="bg-[#F6F6F6] text-[#161616] min-h-screen font-sans antialiased overflow-x-hidden">
|
||||
|
||||
<a href="#main-content" class="skip-link">Aller au contenu principal</a>
|
||||
|
||||
<!-- Government Official Header -->
|
||||
@include('layouts.header')
|
||||
|
||||
<div class="flex min-h-[calc(100vh-80px)]">
|
||||
|
||||
<!-- Institutional Sidebar -->
|
||||
@include('layouts.sidebar')
|
||||
|
||||
<!-- Main Workspace -->
|
||||
<main id="main-content" class="flex-1 flex flex-col bg-[#F6F6F6] overflow-y-auto">
|
||||
|
||||
<div class="p-6 lg:p-10 max-w-7xl mx-auto w-full space-y-10">
|
||||
|
||||
<!-- Hero Section: Accessible and Structured -->
|
||||
<section class="bg-white border border-slate-200 p-8 lg:p-12 shadow-sm flex flex-col md:flex-row items-center gap-10 relative overflow-hidden">
|
||||
<div class="absolute top-0 left-0 w-2 h-full bg-[--cz-mustard-bg]"></div>
|
||||
|
||||
<div class="flex-1 space-y-6">
|
||||
<h2 class="text-4xl font-black text-slate-900 leading-tight">
|
||||
Bonjour <span class="text-[--fr-blue]">{{ Auth::user()->name ?? 'Cher étudiant' }}</span>
|
||||
</h2>
|
||||
<p class="text-slate-700 text-lg leading-relaxed max-w-2xl">
|
||||
Le <span class="font-bold">Ministère de la Santé</span> vous propose cet espace sécurisé pour suivre votre bien-être au quotidien. Retrouvez vos outils de prévention et vos diagnostics.
|
||||
</p>
|
||||
<div class="flex flex-wrap gap-4 pt-2">
|
||||
<a href="{{ route('diagnostics.index') }}" class="px-8 py-3.5 bg-[#000091] text-white font-bold rounded-sm hover:bg-blue-800 transition-all shadow-md">
|
||||
Faire mon bilan de santé
|
||||
</a>
|
||||
<a href="{{ route('relaxation.index') }}" class="px-8 py-3.5 bg-white border-2 border-[#000091] text-[#000091] font-bold rounded-sm hover:bg-slate-50 transition-all">
|
||||
Voir mes favoris
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- Grid of Modules -->
|
||||
<section aria-labelledby="modules-title">
|
||||
<h3 id="modules-title" class="text-xl font-bold text-slate-900 mb-6 flex items-center gap-2">
|
||||
Vos outils de suivi
|
||||
<span class="w-8 h-1 bg-[--cz-mustard-bg] rounded-full"></span>
|
||||
</h3>
|
||||
|
||||
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
|
||||
|
||||
<!-- Tracker (Jade) -->
|
||||
<div class="bg-white p-8 border border-slate-200 shadow-sm transition-colors relative group">
|
||||
<div class="w-12 h-12 rounded-sm bg-teal-50 flex items-center justify-center mb-6 text-[--cz-jade]" aria-hidden="true">
|
||||
<x-heroicon-o-clock class="h-7 w-7" />
|
||||
</div>
|
||||
<h4 class="text-xl font-bold text-slate-900 mb-2">Journal Émotionnel</h4>
|
||||
<p class="text-slate-600 text-sm leading-relaxed mb-6">Suivez l'évolution de votre état émotionnel avec l'outil d'auto-évaluation.</p>
|
||||
<a href="{{ route('emotions.index') }}" class="inline-flex items-center gap-2 text-sm font-bold text-[--cz-jade] hover:underline underline-offset-4 decoration-2">
|
||||
Accéder au journal
|
||||
<x-heroicon-o-arrow-right class="h-4 w-4" aria-hidden="true" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Diagnostics (Mustard) -->
|
||||
<div class="bg-white p-8 border border-slate-200 shadow-sm transition-colors relative group">
|
||||
<div class="w-12 h-12 rounded-sm bg-orange-50 flex items-center justify-center mb-6 text-[--cz-mustard]" aria-hidden="true">
|
||||
<x-heroicon-o-chart-bar class="h-7 w-7" />
|
||||
</div>
|
||||
<h4 class="text-xl font-bold text-slate-900 mb-2">Tests de Stress</h4>
|
||||
<p class="text-slate-600 text-sm leading-relaxed mb-6">Réalisez des diagnostics validés scientifiquement par nos experts.</p>
|
||||
<a href="{{ route('diagnostics.index') }}" class="inline-flex items-center gap-2 text-sm font-bold text-[--cz-mustard] hover:underline underline-offset-4 decoration-2">
|
||||
Commencer un test
|
||||
<x-heroicon-o-arrow-right class="h-4 w-4" aria-hidden="true" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
<!-- Info -->
|
||||
<div class="bg-white p-8 border border-slate-200 shadow-sm transition-colors relative group">
|
||||
<div class="w-12 h-12 rounded-sm bg-blue-50 flex items-center justify-center mb-6 text-[--fr-blue]" aria-hidden="true">
|
||||
<x-heroicon-o-document-text class="h-7 w-7" />
|
||||
</div>
|
||||
<h4 class="text-xl font-bold text-slate-900 mb-2">Guides Pratiques</h4>
|
||||
<p class="text-slate-600 text-sm leading-relaxed mb-6">Consultez les fiches de prévention sur le sommeil et la nutrition.</p>
|
||||
<a href="#" class="inline-flex items-center gap-2 text-sm font-bold text-[--fr-blue] hover:underline underline-offset-4 decoration-2">
|
||||
Lire les guides
|
||||
<x-heroicon-o-arrow-right class="h-4 w-4" aria-hidden="true" />
|
||||
</a>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- RGPD / Information Footer -->
|
||||
<section class="bg-slate-100 p-8 border border-slate-200 rounded-sm">
|
||||
<div class="flex flex-col md:flex-row gap-8 items-start">
|
||||
<div class="w-12 h-12 bg-white rounded-sm flex items-center justify-center text-[--fr-blue] border border-slate-200 shadow-sm flex-shrink-0" aria-hidden="true">
|
||||
<x-heroicon-o-shield-check class="w-6 h-6" />
|
||||
</div>
|
||||
<div>
|
||||
<h4 class="text-lg font-bold text-slate-900 mb-2">Vos données sont protégées</h4>
|
||||
<p class="text-slate-600 text-sm leading-relaxed">
|
||||
Conformément au RGPD et aux recommandations de la CNIL, vos données de santé sont strictement confidentielles.
|
||||
Elles sont hébergées sur des infrastructures sécurisées de l'État et ne sont jamais partagées sans votre accord.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
</div>
|
||||
|
||||
<!-- Global Footer Gov -->
|
||||
|
||||
</main>
|
||||
</div>
|
||||
@include('layouts.footer')
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user