Compare commits

..

25 Commits

Author SHA1 Message Date
681d5da4d1 Amélioration qualité images avec rendu CSS optimisé
- Amélioration rendu CSS des images dans PlaceCard
- Ajout propriétés imageRendering pour meilleure qualité
- Ajout loading='lazy' et fetchPriority='high'
- Script Node.js pour télécharger images haute résolution
- Guide README pour télécharger images Google Maps en HD
- APK rebuild
2025-11-24 13:17:54 +01:00
65ccd2daaf Météo dynamique pour Fakarava avec heure locale
- Intégration API Open-Meteo pour météo en temps réel
- Coordonnées Fakarava (Rotoava): -16.3167, -145.6167
- Affichage heure locale (fuseau horaire Pacific/Tahiti)
- Rafraîchissement automatique toutes les heures
- Gestion des erreurs avec valeurs par défaut
- Icônes dynamiques selon conditions météo
- APK rebuild
2025-11-24 13:10:08 +01:00
7e6b670847 Photo Google Maps pour Tumoana Markets
- Remplacement image temporaire par photo Google Maps
- Image authentique de Tumoana Markets
- APK rebuild
2025-11-23 20:26:40 +01:00
14b7405961 Mise à jour: Tumoana Markets et Snack Elda avec photos Google Maps
- Remplacement Magasin Rotoava → Tumoana Markets
- Photo Google Maps pour Snack Elda
- Mise à jour des coordonnées GPS
- Mise à jour des liens Google Maps
- APK rebuild
2025-11-23 20:22:31 +01:00
980a3dbe0c Intégration des photos réelles Google Maps pour 4 établissements
- Photos Google Maps téléchargées:
   restaurant-requin-dormeur.jpg → Snack du Requin Dormeur
   restaurant-kori-kori.jpg → Snack Kori Kori
   plage-cocotier-pk9.jpg → Plage PK 9 (Cocotier Couché)
   phare-topaka.jpg → Ancien Phare de Topaka

- Images temporaires Unsplash pour les autres lieux
- APK rebuild avec nouvelles photos authentiques
2025-11-23 20:14:48 +01:00
e693713267 Mise à jour des images avec correspondance spécifique aux activités
- Images renommées pour correspondre aux lieux spécifiques
- restaurant-requin-dormeur.jpg → Snack du Requin Dormeur
- restaurant-kori-kori.jpg → Snack Kori Kori
- plage-cocotier-pk9.jpg → Plage PK 9 (Cocotier Couché)
- phare-topaka.jpg → Ancien Phare de Topaka
- passe-nord-snorkeling.jpg → Passe Nord (Garuae)
- sables-roses.jpg → Sables Roses (Passe Sud)
- plage-pension.jpg → Plage de la Pension
- epicerie-rotoava.jpg → Magasin Rotoava
- snack-chez-elda.jpg → Snack Chez Elda
- epicerie-locale.jpg → Autres Petites Épiceries
- APK rebuild avec nouvelles images
2025-11-23 20:04:25 +01:00
3ff1b82b85 Permettre le commit de l'APK pour téléchargement distant 2025-11-23 19:56:01 +01:00
f42b09ebab Build APK avec images incluses (6.3M)
- APK généré avec toutes les images
- Restaurants, plages et épiceries avec photos
- Prêt pour test beta
2025-11-23 19:55:47 +01:00
908bf5f0c2 Ajout d'images pour les cartes de lieux (restaurants, plages, épiceries)
- Téléchargement d'images depuis Unsplash
- Images stockées dans public/images/
- Mise à jour de places.json avec chemins locaux
- Composant PlaceCard affiche maintenant les images dans l'en-tête
- Fallback automatique vers placeholder si image manquante
2025-11-23 19:52:37 +01:00
fa4ef6320a Fix: Logo visible en mode sombre avec dark:invert 2025-11-23 19:40:02 +01:00
45a96f618b Suppression de l'APK admin obsolète 2025-11-23 19:29:09 +01:00
bbfddefc76 Build APK simplifié réussi - Version finale sans admin/WiFi/bungalow 2025-11-23 19:27:15 +01:00
b10d9c515b Simplification complète de l'app - Suppression admin/WiFi/bungalow
- Suppression de toute la partie admin (routes, composants, API)
- Suppression du WiFi et du numéro de bungalow
- Simplification de l'accueil (logo, météo, message statique)
- App 100% statique maintenant
- Redirection simple vers /accueil
- Nettoyage des hooks et types inutilisés
2025-11-23 19:22:34 +01:00
29d6ab3d80 Rebuild APK client avec la logique de détection corrigée 2025-11-23 17:23:36 +01:00
429eb07291 Amélioration de la détection APK client vs admin
- Détection basée sur Capacitor Android + adminPassword
- APK client (sans adminPassword) → redirige vers /accueil
- APK admin (avec adminPassword) → redirige vers /admin/login
- Web avec /admin → admin
- Sinon → client
2025-11-23 17:21:22 +01:00
092d537180 Ajout du script build-apk-admin.sh pour générer l'APK admin
- Script dédié pour l'APK admin (compagnon-admin-debug.apk)
- Configuration Capacitor pour com.pensionmarama.admin
- Exclusion temporaire des routes API pendant le build
- Génération de l'APK admin avec les corrections pour /admin/login
2025-11-23 17:18:34 +01:00
61c1f47409 Corrections pour le build APK admin
- Ajout de updatedAt manquant dans la création de client
- Correction de l'import ThemeProvider (next-themes)
- Correction du size icon dans ThemeToggle
- Exclusion temporaire des routes API pendant le build
- Build APK admin réussi
2025-11-23 17:13:47 +01:00
0247f6ed9d Ajout du message informatif pour le mode hors ligne dans ClientList 2025-11-23 17:01:52 +01:00
ba1433b192 Correction de l'accès à /admin/login dans l'APK admin
- Détection automatique de l'app admin (Capacitor)
- Redirection automatique vers /admin/login si non connecté
- Gestion gracieuse des erreurs API en mode statique
- Message informatif si API non disponible
- Support du mode statique pour l'APK admin
2025-11-23 17:01:31 +01:00
0e485aacee Ajout du mode clair/sombre (dark mode)
- Installation de next-themes
- Création du composant ThemeToggle avec icônes soleil/lune
- Intégration du ThemeProvider dans le layout
- Ajout du toggle dans la navigation mobile et le header admin
- Adaptation des couleurs pour le dark mode (tropical chic)
- Mise à jour des composants UI (Card, Button) pour le dark mode
- Adaptation des composants principaux (Layout, WifiCard, etc.)
2025-11-23 16:53:27 +01:00
106f15205c Amélioration du composant QRCodeDisplay avec zone de texte
- Zone de texte sélectionnable pour le lien
- Boutons Copier et Sélectionner
- Alerte de confirmation
- Instructions claires pour l'utilisateur
2025-11-23 11:33:08 +01:00
dd41da5b0a Solution simplifiée pour copie du lien - zone de texte sélectionnable
- Zone de texte en lecture seule avec le lien
- Sélection automatique au clic
- Bouton 'Sélectionner' explicite
- Instructions claires pour l'utilisateur
- Plus simple et plus fiable que l'alerte
2025-11-23 11:12:30 +01:00
8b0ba77b63 Ajout d'une alerte de confirmation après copie du lien
- Alerte explicite avec le lien copié
- Feedback clair pour l'utilisateur
- Meilleur fallback pour anciens navigateurs
- Durée du feedback augmentée à 3 secondes
2025-11-23 11:07:06 +01:00
83c209117e Amélioration du bouton de copie du lien unique
- Ajout d'un feedback visuel (bouton devient vert + 'Copié !')
- Icônes Copy et Check pour plus de clarté
- Fallback pour navigateurs anciens (document.execCommand)
- Meilleur affichage du lien (plus grand, en monospace)
- Message explicatif pour l'utilisateur
2025-11-23 11:03:22 +01:00
ea2d620c7a Ajout interface admin déployable sur serveur
- API routes pour gestion clients (CRUD complet)
- Système de stockage JSON persistant (data/clients.json)
- Configuration Next.js serveur (next.config.server.js)
- Script de build pour déploiement (scripts/build-server.sh)
- Documentation complète de déploiement (ADMIN_DEPLOY.md)

Fonctionnalités admin:
- Création/modification/suppression de clients
- Génération automatique de tokens uniques
- QR codes pour configuration clients
- Authentification par mot de passe
- Backend Node.js avec API REST

Déploiement prévu: marama.syoul.fr
2025-11-23 10:57:01 +01:00
231 changed files with 10873 additions and 1058 deletions

16
.gitignore vendored
View File

@ -35,3 +35,19 @@ yarn-error.log*
*.tsbuildinfo
next-env.d.ts
# android
/android/.gradle
/android/build
/android/app/build
/android/local.properties
/android/.idea
# capacitor
/ios
/android/.cxx
# data storage (ne pas commit les données clients)
/data/clients.json
# APK (commenté pour permettre le téléchargement depuis le dépôt)
# /dist/*.apk

437
ADMIN_DEPLOY.md Normal file
View File

@ -0,0 +1,437 @@
# 🖥️ Guide de déploiement de l'interface Admin
Ce guide explique comment déployer l'interface d'administration sur votre serveur **marama.syoul.fr**.
---
## 📋 Vue d'ensemble
```
┌─────────────────────┐ ┌──────────────────────────┐
│ APK Client │ │ Admin Web │
│ (Statique) │ │ marama.syoul.fr │
│ │ │ │
│ • Accueil │ │ • Login admin │
│ • Explorer │ ←────│ • Gestion clients │
│ • Mana Tracker │ │ • Génération tokens │
│ • Infos │ │ • QR codes │
└─────────────────────┘ └──────────────────────────┘
Voyageurs Gérant (vous)
```
---
## 🚀 Déploiement en 5 étapes
### Étape 1 : Build de l'application admin
```bash
cd "/home/syoul/Ccompagnon Marama"
./scripts/build-server.sh
```
Ce script va :
- ✅ Configurer Next.js en mode serveur (avec API routes)
- ✅ Build l'application
- ✅ Préparer les fichiers dans `deploy/`
- ✅ Créer les scripts de lancement
**⏱️ Durée :** 2-3 minutes
---
### Étape 2 : Transférer sur votre serveur
```bash
# Depuis votre machine locale
rsync -avz --delete deploy/ user@marama.syoul.fr:/var/www/pension-admin/
# Remplacez 'user' par votre nom d'utilisateur SSH
```
**Alternative avec SCP :**
```bash
scp -r deploy/* user@marama.syoul.fr:/var/www/pension-admin/
```
---
### Étape 3 : Configuration sur le serveur
```bash
# Se connecter au serveur
ssh user@marama.syoul.fr
# Aller dans le dossier
cd /var/www/pension-admin
# Configurer le mot de passe admin
cp .env.example .env
nano .env
```
**Contenu de `.env` :**
```bash
# ⚠️ IMPORTANT : Changez ce mot de passe !
ADMIN_PASSWORD=votre_mot_de_passe_tres_securise
# Port (optionnel)
PORT=3000
```
---
### Étape 4 : Installer et démarrer
#### Option A : Lancement simple (test)
```bash
chmod +x start.sh
./start.sh
```
L'admin sera accessible sur `http://marama.syoul.fr:3000`
#### Option B : Avec PM2 (production, recommandé ⭐)
```bash
# Installer PM2 (si pas déjà fait)
npm install -g pm2
# Démarrer l'application
pm2 start npm --name "pension-admin" -- start
# Sauvegarder la config PM2
pm2 save
# Configurer le démarrage auto
pm2 startup
# Suivre les instructions affichées
# Commandes utiles PM2
pm2 status # Voir le statut
pm2 logs pension-admin # Voir les logs
pm2 restart pension-admin # Redémarrer
pm2 stop pension-admin # Arrêter
```
---
### Étape 5 : Configuration Nginx (reverse proxy)
#### A. Créer la configuration Nginx
```bash
sudo nano /etc/nginx/sites-available/pension-admin
```
**Contenu du fichier :**
```nginx
server {
listen 80;
server_name admin.marama.syoul.fr;
# Logs
access_log /var/log/nginx/pension-admin-access.log;
error_log /var/log/nginx/pension-admin-error.log;
location / {
proxy_pass http://localhost:3000;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection 'upgrade';
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
proxy_cache_bypass $http_upgrade;
}
}
```
#### B. Activer la configuration
```bash
# Créer le lien symbolique
sudo ln -s /etc/nginx/sites-available/pension-admin /etc/nginx/sites-enabled/
# Tester la configuration
sudo nginx -t
# Recharger Nginx
sudo systemctl reload nginx
```
#### C. Configurer SSL (HTTPS) avec Let's Encrypt
```bash
# Installer Certbot (si pas déjà fait)
sudo apt install certbot python3-certbot-nginx
# Obtenir le certificat SSL
sudo certbot --nginx -d admin.marama.syoul.fr
# Le renouvellement est automatique !
```
---
## 🔐 Configuration DNS
Ajoutez un enregistrement A ou CNAME dans votre DNS :
```
Type: A
Nom: admin.marama.syoul.fr (ou juste "admin")
Valeur: [IP de votre serveur]
TTL: 3600
```
---
## 🎯 Utilisation de l'interface admin
### 1. Se connecter
```
URL: https://admin.marama.syoul.fr
Mot de passe: celui défini dans .env
```
### 2. Ajouter un client
1. Cliquer sur **"Nouveau client"**
2. Remplir le formulaire :
- **Email** : email du voyageur
- **N° Bungalow** : 1, 2, 3, etc.
- **WiFi** : nom et mot de passe
- **Message du gérant** : message personnalisé
3. Cliquer sur **"Créer"**
4. Un **QR code** et un **lien unique** sont générés automatiquement
### 3. Partager avec le client
**Option A : QR Code** (recommandé)
- Afficher le QR code
- Le voyageur scan avec son téléphone
- L'app se configure automatiquement
**Option B : Lien**
- Copier le lien unique
- L'envoyer par email/SMS au client
---
## 🔄 Mise à jour de l'application
Quand vous modifiez le code :
```bash
# Sur votre machine locale
cd "/home/syoul/Ccompagnon Marama"
./scripts/build-server.sh
# Transférer
rsync -avz --delete deploy/ user@marama.syoul.fr:/var/www/pension-admin/
# Sur le serveur
ssh user@marama.syoul.fr
cd /var/www/pension-admin
pm2 restart pension-admin
```
---
## 📂 Structure des fichiers sur le serveur
```
/var/www/pension-admin/
├── .next/ # Application Next.js compilée
├── public/ # Assets statiques
├── data/
│ └── clients.json # Base de données des clients (créé auto)
├── package.json # Dépendances
├── next.config.js # Config Next.js
├── .env # Variables d'environnement (mot de passe)
├── start.sh # Script de lancement
└── DEPLOY.md # Documentation
```
---
## 🔒 Sécurité
### Recommandations importantes
1. **Mot de passe fort**
```bash
# Générer un mot de passe sécurisé
openssl rand -base64 32
```
2. **Permissions fichiers**
```bash
chmod 600 /var/www/pension-admin/.env
chmod 600 /var/www/pension-admin/data/clients.json
```
3. **Firewall**
```bash
# Autoriser uniquement HTTP/HTTPS
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
```
4. **Sauvegarde des données**
```bash
# Créer un cron job pour sauvegarder clients.json
0 2 * * * cp /var/www/pension-admin/data/clients.json /backup/clients-$(date +\%Y\%m\%d).json
```
---
## 🐛 Dépannage
### L'application ne démarre pas
```bash
# Vérifier les logs
pm2 logs pension-admin
# Vérifier que Node.js est installé
node --version # doit être >= 18
# Réinstaller les dépendances
cd /var/www/pension-admin
rm -rf node_modules
npm ci --production
pm2 restart pension-admin
```
### Erreur 502 Bad Gateway
```bash
# Vérifier que l'app tourne
pm2 status
# Vérifier les logs Nginx
sudo tail -f /var/log/nginx/pension-admin-error.log
# Redémarrer Nginx
sudo systemctl restart nginx
```
### Les clients ne peuvent pas se connecter
```bash
# Vérifier les permissions du fichier data
ls -la /var/www/pension-admin/data/
# Vérifier le contenu
cat /var/www/pension-admin/data/clients.json
# Si le fichier n'existe pas, l'app le créera automatiquement
```
### Changer le mot de passe admin
```bash
# Sur le serveur
cd /var/www/pension-admin
nano .env
# Modifier ADMIN_PASSWORD
# Redémarrer
pm2 restart pension-admin
```
---
## 📊 Monitoring
### Voir les statistiques avec PM2
```bash
pm2 monit # Monitoring en temps réel
pm2 logs # Voir tous les logs
pm2 status # Statut de toutes les apps
```
### Logs Nginx
```bash
# Logs d'accès
sudo tail -f /var/log/nginx/pension-admin-access.log
# Logs d'erreurs
sudo tail -f /var/log/nginx/pension-admin-error.log
```
---
## 🎓 Commandes utiles
```bash
# Redémarrer l'application
pm2 restart pension-admin
# Voir les logs en direct
pm2 logs pension-admin --lines 100
# Recharger l'app (sans downtime)
pm2 reload pension-admin
# Arrêter l'application
pm2 stop pension-admin
# Démarrer l'application
pm2 start pension-admin
# Supprimer de PM2
pm2 delete pension-admin
# Sauvegarder la config PM2
pm2 save
```
---
## 💡 Conseils
1. **Tester localement d'abord**
```bash
# Sur votre machine
npm run dev
# Ouvrir http://localhost:3000/admin
```
2. **Utiliser un sous-domaine dédié**
- `admin.marama.syoul.fr` (recommandé)
- Plutôt que `marama.syoul.fr/admin`
3. **Configurer les sauvegardes automatiques**
- Le fichier `data/clients.json` contient toutes vos données
- Sauvegardez-le régulièrement
4. **Monitoring avec Uptime Robot**
- Gratuit
- Vous alerte si le site est down
---
## 📞 Support
Si vous rencontrez des problèmes :
1. Vérifier les logs : `pm2 logs pension-admin`
2. Vérifier Nginx : `sudo nginx -t`
3. Vérifier les permissions : `ls -la data/`
---
**Version** : 1.0.0 - Novembre 2025
**Serveur** : marama.syoul.fr
**URL Admin** : https://admin.marama.syoul.fr

View File

@ -1,53 +1,37 @@
"use client";
import { Suspense } from "react";
import dynamic from "next/dynamic";
import Layout from "@/components/layout/Layout";
import WifiCard from "@/components/accueil/WifiCard";
import Logo from "@/components/Logo";
import { useClientData } from "@/lib/hooks/useClientData";
import { config } from "@/lib/config";
const WeatherWidget = dynamic(() => import("@/components/accueil/WeatherWidget"), {
loading: () => <div className="h-32 bg-gray-100 rounded-2xl animate-pulse" />,
loading: () => <div className="h-32 bg-gray-100 dark:bg-gray-800 rounded-2xl animate-pulse" />,
ssr: false,
});
function AccueilContent() {
const { bungalowNumber, gerantMessage, loading } = useClientData();
if (loading) {
return (
<Layout>
<div className="px-4 py-6 space-y-6">
<div className="h-32 bg-gray-100 rounded-2xl animate-pulse" />
</div>
</Layout>
);
}
export default function AccueilPage() {
return (
<Layout>
<div className="px-4 py-6 space-y-6">
<header className="text-center py-4">
<Logo size={140} className="mb-4" />
<h1 className="text-2xl font-bold text-primary mb-2">
<h1 className="text-2xl font-bold text-primary dark:text-primary mb-2">
Ia Ora Na
</h1>
<p className="text-lg text-gray-700">
Bienvenue au Bungalow {bungalowNumber}
<p className="text-lg text-gray-700 dark:text-gray-300">
Bienvenue à la Pension Marama
</p>
</header>
<WifiCard />
<WeatherWidget />
<section className="bg-secondary rounded-2xl p-6">
<h2 className="text-xl font-semibold text-primary mb-3">
<section className="bg-secondary dark:bg-primary/20 rounded-2xl p-6">
<h2 className="text-xl font-semibold text-primary dark:text-primary mb-3">
Le mot du gérant
</h2>
<p className="text-gray-700 leading-relaxed">
{gerantMessage}
<p className="text-gray-700 dark:text-gray-300 leading-relaxed">
{config.gerantMessage}
</p>
</section>
</div>
@ -55,17 +39,3 @@ function AccueilContent() {
);
}
export default function AccueilPage() {
return (
<Suspense fallback={
<Layout>
<div className="px-4 py-6 space-y-6">
<div className="h-32 bg-gray-100 rounded-2xl animate-pulse" />
</div>
</Layout>
}>
<AccueilContent />
</Suspense>
);
}

View File

@ -1,85 +0,0 @@
"use client";
import { useState } from "react";
import { useRouter } from "next/navigation";
import { Button } from "@/components/ui/button";
import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card";
import Logo from "@/components/Logo";
export default function AdminLoginPage() {
const [password, setPassword] = useState("");
const [error, setError] = useState("");
const [loading, setLoading] = useState(false);
const router = useRouter();
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setError("");
setLoading(true);
// Vérification simple côté client (la vraie vérification se fait côté serveur)
// Pour l'instant, on stocke le mot de passe dans localStorage
localStorage.setItem("adminPassword", password);
// Test avec une requête API
try {
const response = await fetch("/api/admin/clients", {
headers: {
Authorization: `Bearer ${password}`,
},
});
if (response.ok) {
router.push("/admin");
} else {
setError("Mot de passe incorrect");
localStorage.removeItem("adminPassword");
}
} catch (err) {
setError("Erreur de connexion");
localStorage.removeItem("adminPassword");
} finally {
setLoading(false);
}
};
return (
<div className="min-h-screen bg-background flex items-center justify-center px-4">
<Card className="w-full max-w-md">
<CardHeader className="text-center">
<div className="flex justify-center mb-4">
<Logo size={100} />
</div>
<CardTitle>Administration</CardTitle>
</CardHeader>
<CardContent>
<form onSubmit={handleSubmit} className="space-y-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Mot de passe
</label>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
className="w-full px-4 py-2 border border-gray-300 rounded-xl focus:ring-2 focus:ring-primary focus:border-transparent"
required
/>
</div>
{error && (
<div className="bg-red-50 border border-red-200 text-red-700 px-4 py-3 rounded-xl text-sm">
{error}
</div>
)}
<Button type="submit" disabled={loading} className="w-full">
{loading ? "Connexion..." : "Se connecter"}
</Button>
</form>
</CardContent>
</Card>
</div>
);
}

View File

@ -1,73 +0,0 @@
"use client";
import { useState, useEffect } from "react";
import { useRouter } from "next/navigation";
import AdminLayout from "@/components/admin/AdminLayout";
import ClientForm from "@/components/admin/ClientForm";
import ClientList from "@/components/admin/ClientList";
import { Button } from "@/components/ui/button";
import { Plus } from "lucide-react";
import { Client } from "@/lib/types/client";
export default function AdminPage() {
const [showForm, setShowForm] = useState(false);
const [editingClient, setEditingClient] = useState<Client | undefined>();
const [refreshKey, setRefreshKey] = useState(0);
const router = useRouter();
useEffect(() => {
// Vérifier si l'admin est connecté
const adminPassword = localStorage.getItem("adminPassword");
if (!adminPassword) {
router.push("/admin/login");
}
}, [router]);
const handleNewClient = () => {
setEditingClient(undefined);
setShowForm(true);
};
const handleEdit = (client: Client) => {
setEditingClient(client);
setShowForm(true);
};
const handleSuccess = () => {
setShowForm(false);
setEditingClient(undefined);
setRefreshKey((k) => k + 1);
};
const handleCancel = () => {
setShowForm(false);
setEditingClient(undefined);
};
return (
<AdminLayout>
<div className="space-y-6">
<div className="flex items-center justify-between">
<h2 className="text-2xl font-bold text-primary">Gestion des clients</h2>
{!showForm && (
<Button onClick={handleNewClient}>
<Plus className="h-4 w-4 mr-2" />
Nouveau client
</Button>
)}
</div>
{showForm ? (
<ClientForm
client={editingClient}
onSuccess={handleSuccess}
onCancel={handleCancel}
/>
) : (
<ClientList onEdit={handleEdit} onRefresh={() => setRefreshKey((k) => k + 1)} />
)}
</div>
</AdminLayout>
);
}

View File

@ -4,10 +4,10 @@
@layer base {
body {
@apply bg-background;
@apply bg-background dark:bg-background-dark;
font-size: 16px;
min-height: 100vh;
color: #1f2937;
@apply text-foreground dark:text-foreground-dark;
}
}

View File

@ -2,6 +2,7 @@ import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
import PWARegister from "@/components/PWARegister";
import { ThemeProvider } from "@/components/ThemeProvider";
const inter = Inter({ subsets: ["latin"] });
@ -29,14 +30,21 @@ export default function RootLayout({
children: React.ReactNode;
}>) {
return (
<html lang="fr">
<html lang="fr" suppressHydrationWarning>
<head>
<link rel="icon" href="/logo-relais-marama.svg" type="image/svg+xml" />
<link rel="apple-touch-icon" href="/logo-relais-marama.svg" />
</head>
<body className={inter.className}>
<ThemeProvider
attribute="class"
defaultTheme="light"
enableSystem={true}
disableTransitionOnChange={false}
>
{children}
<PWARegister />
</ThemeProvider>
</body>
</html>
);

View File

@ -11,11 +11,10 @@ export default function Home() {
}, [router]);
return (
<div className="flex items-center justify-center min-h-screen">
<div className="flex items-center justify-center min-h-screen bg-background dark:bg-background-dark">
<div className="text-center">
<p className="text-gray-600">Redirection...</p>
<p className="text-gray-600 dark:text-gray-400">Redirection...</p>
</div>
</div>
);
}

View File

@ -44,7 +44,7 @@ export default function Logo({ size = 120, className = "" }: LogoProps) {
alt="Relais Marama - Fakarava"
width={size}
height={size}
className="object-contain"
className="object-contain dark:invert"
style={{ maxWidth: `${size}px`, maxHeight: `${size}px` }}
/>
<p className="text-primary font-semibold mt-2" style={{ fontSize: `${size * 0.15}px` }}>

View File

@ -0,0 +1,12 @@
"use client";
import { ThemeProvider as NextThemesProvider } from "next-themes";
import { type ComponentProps } from "react";
export function ThemeProvider({
children,
...props
}: ComponentProps<typeof NextThemesProvider>) {
return <NextThemesProvider {...props}>{children}</NextThemesProvider>;
}

View File

@ -0,0 +1,45 @@
"use client";
import { useTheme } from "next-themes";
import { Moon, Sun } from "lucide-react";
import { Button } from "@/components/ui/button";
import { useEffect, useState } from "react";
export function ThemeToggle() {
const { theme, setTheme } = useTheme();
const [mounted, setMounted] = useState(false);
useEffect(() => {
setMounted(true);
}, []);
if (!mounted) {
return (
<Button
variant="ghost"
size="sm"
className="h-9 w-9 rounded-full p-0"
aria-label="Changer de thème"
>
<Sun className="h-5 w-5" />
</Button>
);
}
return (
<Button
variant="ghost"
size="sm"
onClick={() => setTheme(theme === "dark" ? "light" : "dark")}
className="h-10 w-10 rounded-full hover:bg-secondary dark:hover:bg-gray-800 p-0"
aria-label="Changer de thème"
>
{theme === "dark" ? (
<Sun className="h-5 w-5 text-primary dark:text-yellow-400" />
) : (
<Moon className="h-5 w-5 text-primary dark:text-blue-300" />
)}
</Button>
);
}

View File

@ -1,35 +1,177 @@
import { Cloud, Sun } from "lucide-react";
"use client";
import { useEffect, useState } from "react";
import { Cloud, Sun, CloudRain, Wind, Droplets, Loader2, Clock } from "lucide-react";
import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card";
interface WeatherData {
temperature: number;
condition: string;
windSpeed: number;
humidity: number;
weatherCode: number;
}
// Coordonnées de Fakarava (Rotoava)
const FAKARAVA_LAT = -16.3167;
const FAKARAVA_LON = -145.6167;
// Codes météo Open-Meteo vers descriptions
const getWeatherCondition = (code: number): { text: string; icon: React.ReactNode } => {
// Codes Open-Meteo WMO Weather interpretation codes
if (code === 0) {
return { text: "Ciel dégagé", icon: <Sun className="h-16 w-16 text-yellow-400" /> };
} else if (code <= 3) {
return { text: "Partiellement nuageux", icon: <Cloud className="h-16 w-16 text-gray-400" /> };
} else if (code <= 48) {
return { text: "Nuageux", icon: <Cloud className="h-16 w-16 text-gray-500" /> };
} else if (code <= 55) {
return { text: "Brouillard", icon: <Cloud className="h-16 w-16 text-gray-400" /> };
} else if (code <= 67) {
return { text: "Pluie", icon: <CloudRain className="h-16 w-16 text-blue-400" /> };
} else if (code <= 77) {
return { text: "Neige", icon: <CloudRain className="h-16 w-16 text-gray-300" /> };
} else if (code <= 82) {
return { text: "Averses", icon: <CloudRain className="h-16 w-16 text-blue-500" /> };
} else if (code <= 86) {
return { text: "Averses de neige", icon: <CloudRain className="h-16 w-16 text-gray-300" /> };
} else {
return { text: "Orage", icon: <CloudRain className="h-16 w-16 text-purple-500" /> };
}
};
export default function WeatherWidget() {
const [weather, setWeather] = useState<WeatherData | null>(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState<string | null>(null);
const [localTime, setLocalTime] = useState<string>("");
// Mise à jour de l'heure locale chaque seconde
useEffect(() => {
const updateTime = () => {
const now = new Date();
// Fuseau horaire de Tahiti (UTC-10)
const tahitiTime = new Date(now.toLocaleString("en-US", { timeZone: "Pacific/Tahiti" }));
const hours = tahitiTime.getHours().toString().padStart(2, "0");
const minutes = tahitiTime.getMinutes().toString().padStart(2, "0");
setLocalTime(`${hours}:${minutes}`);
};
updateTime();
const timeInterval = setInterval(updateTime, 1000);
return () => clearInterval(timeInterval);
}, []);
useEffect(() => {
const fetchWeather = async () => {
try {
setLoading(true);
setError(null);
// API Open-Meteo (gratuit, pas de clé API nécessaire)
const response = await fetch(
`https://api.open-meteo.com/v1/forecast?latitude=${FAKARAVA_LAT}&longitude=${FAKARAVA_LON}&current=temperature_2m,relative_humidity_2m,weather_code,wind_speed_10m&wind_speed_unit=kmh&timezone=Pacific/Tahiti`
);
if (!response.ok) {
throw new Error("Erreur lors de la récupération de la météo");
}
const data = await response.json();
const current = data.current;
setWeather({
temperature: Math.round(current.temperature_2m),
condition: getWeatherCondition(current.weather_code).text,
windSpeed: Math.round(current.wind_speed_10m),
humidity: current.relative_humidity_2m,
weatherCode: current.weather_code,
});
} catch (err) {
console.error("Erreur météo:", err);
setError("Impossible de charger la météo");
// Valeurs par défaut en cas d'erreur
setWeather({
temperature: 28,
condition: "Ensoleillé",
windSpeed: 15,
humidity: 75,
weatherCode: 0,
});
} finally {
setLoading(false);
}
};
fetchWeather();
// Rafraîchir toutes les heures
const interval = setInterval(fetchWeather, 3600000);
return () => clearInterval(interval);
}, []);
if (loading) {
return (
<Card className="bg-gradient-to-br from-primary/10 to-secondary">
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Sun className="h-6 w-6 text-primary" />
Météo
Météo - Fakarava
</CardTitle>
</CardHeader>
<CardContent>
<div className="flex items-center justify-between">
<div>
<p className="text-3xl font-bold text-primary">28°C</p>
<p className="text-gray-600 mt-1">Ensoleillé</p>
</div>
<div className="text-6xl">
<Sun className="h-16 w-16 text-yellow-400" />
</div>
</div>
<div className="mt-4 flex gap-4 text-sm text-gray-600">
<div>
<span className="font-semibold">Vent:</span> 15 km/h
</div>
<div>
<span className="font-semibold">Humidité:</span> 75%
</div>
<div className="flex items-center justify-center py-8">
<Loader2 className="h-8 w-8 animate-spin text-primary" />
</div>
</CardContent>
</Card>
);
}
if (!weather) {
return null;
}
const weatherInfo = getWeatherCondition(weather.weatherCode);
return (
<Card className="bg-gradient-to-br from-primary/10 to-secondary">
<CardHeader>
<CardTitle className="flex items-center justify-between">
<div className="flex items-center gap-2">
<Sun className="h-6 w-6 text-primary" />
Météo - Fakarava
</div>
{localTime && (
<div className="flex items-center gap-1 text-sm font-normal text-gray-600 dark:text-gray-400">
<Clock className="h-4 w-4" />
{localTime}
</div>
)}
</CardTitle>
</CardHeader>
<CardContent>
<div className="flex items-center justify-between">
<div>
<p className="text-3xl font-bold text-primary">{weather.temperature}°C</p>
<p className="text-gray-600 dark:text-gray-300 mt-1">{weather.condition}</p>
{error && (
<p className="text-xs text-orange-500 mt-1">Données en cache</p>
)}
</div>
<div className="text-6xl">{weatherInfo.icon}</div>
</div>
<div className="mt-4 flex gap-4 text-sm text-gray-600 dark:text-gray-400">
<div className="flex items-center gap-1">
<Wind className="h-4 w-4" />
<span className="font-semibold">Vent:</span> {weather.windSpeed} km/h
</div>
<div className="flex items-center gap-1">
<Droplets className="h-4 w-4" />
<span className="font-semibold">Humidité:</span> {weather.humidity}%
</div>
</div>
</CardContent>
</Card>
);
}

View File

@ -1,129 +0,0 @@
"use client";
import { useState, useEffect } from "react";
import { Wifi, Copy, Check, AlertCircle } from "lucide-react";
import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { useClientData } from "@/lib/hooks/useClientData";
export default function WifiCard() {
const { wifiName, wifiPassword, loading } = useClientData();
const [copied, setCopied] = useState(false);
const [error, setError] = useState<string | null>(null);
// Fonction de copie avec fallback pour les navigateurs qui ne supportent pas l'API Clipboard
const copyToClipboard = async (text: string): Promise<boolean> => {
// Méthode moderne (nécessite HTTPS ou localhost)
if (navigator.clipboard && window.isSecureContext) {
try {
await navigator.clipboard.writeText(text);
return true;
} catch (err) {
console.error("Erreur avec l'API Clipboard:", err);
}
}
// Fallback pour les navigateurs plus anciens ou contextes non sécurisés
try {
const textArea = document.createElement("textarea");
textArea.value = text;
textArea.style.position = "fixed";
textArea.style.left = "-999999px";
textArea.style.top = "-999999px";
document.body.appendChild(textArea);
textArea.focus();
textArea.select();
const successful = document.execCommand("copy");
document.body.removeChild(textArea);
if (successful) {
return true;
} else {
throw new Error("La commande copy a échoué");
}
} catch (err) {
console.error("Erreur avec la méthode fallback:", err);
return false;
}
};
const handleCopyPassword = async () => {
if (!wifiPassword || wifiPassword.trim() === "") {
setError("Le mot de passe WiFi n'est pas disponible");
setTimeout(() => setError(null), 3000);
return;
}
setError(null);
const success = await copyToClipboard(wifiPassword);
if (success) {
setCopied(true);
setTimeout(() => setCopied(false), 2000);
} else {
setError("Impossible de copier. Veuillez sélectionner manuellement le mot de passe ci-dessous.");
setTimeout(() => setError(null), 5000);
}
};
// Afficher le mot de passe en cas d'échec de la copie
const showPasswordFallback = error && error.includes("sélectionner manuellement");
return (
<Card className="bg-white">
<CardHeader>
<CardTitle className="flex items-center gap-2">
<Wifi className="h-6 w-6 text-primary" />
Connexion WiFi
</CardTitle>
</CardHeader>
<CardContent className="space-y-4">
<div>
<p className="text-sm text-gray-600 mb-1">Nom du réseau</p>
<p className="text-lg font-semibold text-primary">{wifiName || "Chargement..."}</p>
</div>
{showPasswordFallback && wifiPassword && (
<div className="bg-yellow-50 border border-yellow-200 rounded-xl p-3">
<p className="text-sm text-yellow-800 font-mono select-all">
{wifiPassword}
</p>
</div>
)}
{error && !showPasswordFallback && (
<div className="bg-red-50 border border-red-200 rounded-xl p-3 flex items-start gap-2">
<AlertCircle className="h-5 w-5 text-red-600 flex-shrink-0 mt-0.5" />
<p className="text-sm text-red-800">{error}</p>
</div>
)}
<Button
onClick={handleCopyPassword}
disabled={loading || !wifiPassword}
className="w-full h-14 text-lg"
size="lg"
>
{loading ? (
<>
<Copy className="mr-2 h-5 w-5" />
Chargement...
</>
) : copied ? (
<>
<Check className="mr-2 h-5 w-5" />
Mot de passe copié !
</>
) : (
<>
<Copy className="mr-2 h-5 w-5" />
Copier le mot de passe
</>
)}
</Button>
</CardContent>
</Card>
);
}

View File

@ -1,30 +0,0 @@
"use client";
import { LogOut } from "lucide-react";
import { Button } from "@/components/ui/button";
import { useRouter } from "next/navigation";
export default function AdminLayout({ children }: { children: React.ReactNode }) {
const router = useRouter();
const handleLogout = () => {
localStorage.removeItem("adminPassword");
router.push("/admin/login");
};
return (
<div className="min-h-screen bg-background">
<header className="bg-white border-b border-gray-200 shadow-sm">
<div className="max-w-4xl mx-auto px-4 py-4 flex items-center justify-between">
<h1 className="text-xl font-bold text-primary">Administration</h1>
<Button variant="outline" size="sm" onClick={handleLogout}>
<LogOut className="h-4 w-4 mr-2" />
Déconnexion
</Button>
</div>
</header>
<main className="max-w-4xl mx-auto px-4 py-6">{children}</main>
</div>
);
}

View File

@ -1,195 +0,0 @@
"use client";
import { useState } from "react";
import { Button } from "@/components/ui/button";
import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card";
import { Client, ClientInput } from "@/lib/types/client";
import QRCodeDisplay from "./QRCodeDisplay";
interface ClientFormProps {
client?: Client;
onSuccess: () => void;
onCancel: () => void;
}
export default function ClientForm({ client, onSuccess, onCancel }: ClientFormProps) {
const [formData, setFormData] = useState<ClientInput>({
email: client?.email || "",
bungalowNumber: client?.bungalowNumber || "",
wifiName: client?.wifiName || "Lagon-WiFi",
wifiPassword: client?.wifiPassword || "",
gerantMessage: client?.gerantMessage || "Bienvenue dans notre pension de famille !",
});
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const [createdClient, setCreatedClient] = useState<Client | null>(client || null);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setLoading(true);
setError(null);
try {
const adminPassword = localStorage.getItem("adminPassword") || "";
const url = client
? `/api/admin/clients/${client.id}`
: "/api/admin/clients";
const method = client ? "PUT" : "POST";
const response = await fetch(url, {
method,
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${adminPassword}`,
},
body: JSON.stringify(formData),
});
if (!response.ok) {
const data = await response.json();
throw new Error(data.error || "Erreur lors de la sauvegarde");
}
const data = await response.json();
setCreatedClient(data);
onSuccess();
} catch (err: any) {
setError(err.message);
} finally {
setLoading(false);
}
};
const getClientUrl = () => {
if (!createdClient) return "";
const baseUrl = typeof window !== "undefined" ? window.location.origin : "";
return `${baseUrl}/accueil?token=${createdClient.token}`;
};
return (
<Card>
<CardHeader>
<CardTitle>{client ? "Modifier le client" : "Nouveau client"}</CardTitle>
</CardHeader>
<CardContent>
<form onSubmit={handleSubmit} className="space-y-4">
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Email *
</label>
<input
type="email"
required
value={formData.email}
onChange={(e) => setFormData({ ...formData, email: e.target.value })}
disabled={!!client}
className="w-full px-4 py-2 border border-gray-300 rounded-xl focus:ring-2 focus:ring-primary focus:border-transparent disabled:bg-gray-100"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Numéro de bungalow *
</label>
<input
type="text"
required
value={formData.bungalowNumber}
onChange={(e) =>
setFormData({ ...formData, bungalowNumber: e.target.value })
}
className="w-full px-4 py-2 border border-gray-300 rounded-xl focus:ring-2 focus:ring-primary focus:border-transparent"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Nom du WiFi
</label>
<input
type="text"
value={formData.wifiName}
onChange={(e) =>
setFormData({ ...formData, wifiName: e.target.value })
}
className="w-full px-4 py-2 border border-gray-300 rounded-xl focus:ring-2 focus:ring-primary focus:border-transparent"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Mot de passe WiFi
</label>
<input
type="text"
value={formData.wifiPassword}
onChange={(e) =>
setFormData({ ...formData, wifiPassword: e.target.value })
}
className="w-full px-4 py-2 border border-gray-300 rounded-xl focus:ring-2 focus:ring-primary focus:border-transparent"
/>
</div>
<div>
<label className="block text-sm font-medium text-gray-700 mb-1">
Message du gérant
</label>
<textarea
value={formData.gerantMessage}
onChange={(e) =>
setFormData({ ...formData, gerantMessage: e.target.value })
}
rows={3}
className="w-full px-4 py-2 border border-gray-300 rounded-xl focus:ring-2 focus:ring-primary focus:border-transparent"
/>
</div>
{error && (
<div className="bg-red-50 border border-red-200 text-red-700 px-4 py-3 rounded-xl text-sm">
{error}
</div>
)}
<div className="flex gap-3">
<Button type="button" variant="outline" onClick={onCancel} className="flex-1">
Annuler
</Button>
<Button type="submit" disabled={loading} className="flex-1">
{loading ? "Enregistrement..." : client ? "Modifier" : "Créer"}
</Button>
</div>
</form>
{createdClient && !client && (
<div className="mt-6 pt-6 border-t border-gray-200">
<h3 className="font-semibold text-primary mb-3">Client créé avec succès !</h3>
<div className="space-y-4">
<div>
<p className="text-sm text-gray-600 mb-2">Lien unique :</p>
<div className="bg-secondary rounded-xl p-3 flex items-center justify-between gap-2">
<code className="text-xs break-all flex-1">{getClientUrl()}</code>
<Button
size="sm"
variant="outline"
onClick={() => {
navigator.clipboard.writeText(getClientUrl());
}}
>
Copier
</Button>
</div>
</div>
<div>
<p className="text-sm text-gray-600 mb-2">QR Code :</p>
<QRCodeDisplay url={getClientUrl()} />
</div>
</div>
</div>
)}
</CardContent>
</Card>
);
}

View File

@ -1,165 +0,0 @@
"use client";
import { useState, useEffect } from "react";
import { Trash2, Edit, Copy, QrCode } from "lucide-react";
import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
import { Client } from "@/lib/types/client";
import QRCodeDisplay from "./QRCodeDisplay";
interface ClientListProps {
onEdit: (client: Client) => void;
onRefresh: () => void;
}
export default function ClientList({ onEdit, onRefresh }: ClientListProps) {
const [clients, setClients] = useState<Client[]>([]);
const [loading, setLoading] = useState(true);
const [selectedClient, setSelectedClient] = useState<Client | null>(null);
const [showQR, setShowQR] = useState<string | null>(null);
useEffect(() => {
fetchClients();
}, []);
const fetchClients = async () => {
try {
const adminPassword = localStorage.getItem("adminPassword") || "";
const response = await fetch("/api/admin/clients", {
headers: {
Authorization: `Bearer ${adminPassword}`,
},
});
if (response.ok) {
const data = await response.json();
setClients(data);
}
} catch (error) {
console.error("Erreur lors du chargement des clients:", error);
} finally {
setLoading(false);
}
};
const handleDelete = async (id: string) => {
if (!confirm("Êtes-vous sûr de vouloir supprimer ce client ?")) {
return;
}
try {
const adminPassword = localStorage.getItem("adminPassword") || "";
const response = await fetch(`/api/admin/clients/${id}`, {
method: "DELETE",
headers: {
Authorization: `Bearer ${adminPassword}`,
},
});
if (response.ok) {
fetchClients();
onRefresh();
}
} catch (error) {
console.error("Erreur lors de la suppression:", error);
}
};
const getClientUrl = (token: string) => {
const baseUrl = typeof window !== "undefined" ? window.location.origin : "";
return `${baseUrl}/accueil?token=${token}`;
};
if (loading) {
return (
<div className="flex items-center justify-center py-8">
<p className="text-gray-600">Chargement...</p>
</div>
);
}
if (clients.length === 0) {
return (
<Card>
<CardContent className="py-8 text-center">
<p className="text-gray-600">Aucun client pour le moment.</p>
</CardContent>
</Card>
);
}
return (
<div className="space-y-4">
{clients.map((client) => (
<Card key={client.id}>
<CardHeader>
<div className="flex items-start justify-between">
<div className="flex-1">
<CardTitle className="text-lg">{client.email}</CardTitle>
<p className="text-sm text-gray-600 mt-1">
Bungalow {client.bungalowNumber}
</p>
</div>
<div className="flex gap-2">
<Button
size="sm"
variant="outline"
onClick={() => {
const url = getClientUrl(client.token);
navigator.clipboard.writeText(url);
}}
>
<Copy className="h-4 w-4" />
</Button>
<Button
size="sm"
variant="outline"
onClick={() =>
setShowQR(showQR === client.id ? null : client.id)
}
>
<QrCode className="h-4 w-4" />
</Button>
<Button
size="sm"
variant="outline"
onClick={() => onEdit(client)}
>
<Edit className="h-4 w-4" />
</Button>
<Button
size="sm"
variant="outline"
onClick={() => handleDelete(client.id)}
>
<Trash2 className="h-4 w-4" />
</Button>
</div>
</div>
</CardHeader>
<CardContent>
<div className="space-y-2 text-sm">
<div>
<span className="font-medium">WiFi:</span> {client.wifiName}
</div>
<div>
<span className="font-medium">Message:</span>{" "}
{client.gerantMessage.substring(0, 50)}
{client.gerantMessage.length > 50 ? "..." : ""}
</div>
<div className="text-xs text-gray-500">
Créé le {new Date(client.createdAt).toLocaleDateString("fr-FR")}
</div>
</div>
{showQR === client.id && (
<div className="mt-4 pt-4 border-t border-gray-200">
<QRCodeDisplay url={getClientUrl(client.token)} size={150} />
</div>
)}
</CardContent>
</Card>
))}
</div>
);
}

View File

@ -1,20 +0,0 @@
"use client";
import { QRCodeSVG } from "qrcode.react";
interface QRCodeDisplayProps {
url: string;
size?: number;
}
export default function QRCodeDisplay({ url, size = 200 }: QRCodeDisplayProps) {
return (
<div className="flex flex-col items-center gap-4 p-4 bg-white rounded-2xl border border-gray-200">
<QRCodeSVG value={url} size={size} level="H" />
<p className="text-xs text-gray-600 text-center break-all max-w-xs">
{url}
</p>
</div>
);
}

View File

@ -1,5 +1,6 @@
"use client";
import { useState } from "react";
import { MapPin, ExternalLink } from "lucide-react";
import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card";
import { Button } from "@/components/ui/button";
@ -10,6 +11,9 @@ interface PlaceCardProps {
}
export default function PlaceCard({ place }: PlaceCardProps) {
const [imageError, setImageError] = useState(false);
const hasValidImage = place.image && place.image !== "";
const handleOpenMaps = () => {
let url: string;
if (place.gmapLink && place.gmapLink !== "LIEN_GOOGLE_MAPS_A_INSERER") {
@ -22,10 +26,24 @@ export default function PlaceCard({ place }: PlaceCardProps) {
return (
<Card className="overflow-hidden">
<div className="relative h-48 bg-gradient-to-br from-primary/20 to-secondary">
<div className="relative h-48 bg-gradient-to-br from-primary/20 to-secondary overflow-hidden">
{hasValidImage && !imageError ? (
<img
src={place.image}
alt={place.name}
className="w-full h-full object-cover"
style={{
imageRendering: 'auto',
} as React.CSSProperties}
loading="lazy"
fetchPriority="high"
onError={() => setImageError(true)}
/>
) : (
<div className="absolute inset-0 flex items-center justify-center">
<MapPin className="h-16 w-16 text-primary/30" />
</div>
)}
</div>
<CardHeader>
<div className="flex items-start justify-between gap-2">

View File

@ -2,7 +2,7 @@ import TabNavigation from "./TabNavigation";
export default function Layout({ children }: { children: React.ReactNode }) {
return (
<div className="min-h-screen bg-background pb-16">
<div className="min-h-screen bg-background dark:bg-background-dark pb-16">
{children}
<TabNavigation />
</div>

View File

@ -4,6 +4,7 @@ import Link from "next/link";
import { usePathname } from "next/navigation";
import { Home, MapPin, Info, Waves } from "lucide-react";
import { cn } from "@/lib/utils";
import { ThemeToggle } from "@/components/ThemeToggle";
const tabs = [
{
@ -32,7 +33,7 @@ export default function TabNavigation() {
const pathname = usePathname();
return (
<nav className="fixed bottom-0 left-0 right-0 z-50 bg-white border-t border-gray-200 shadow-lg">
<nav className="fixed bottom-0 left-0 right-0 z-50 bg-white dark:bg-gray-900 border-t border-gray-200 dark:border-gray-800 shadow-lg">
<div className="flex items-center justify-around h-16 px-2">
{tabs.map((tab) => {
const Icon = tab.icon;
@ -44,8 +45,8 @@ export default function TabNavigation() {
className={cn(
"flex flex-col items-center justify-center gap-1 flex-1 h-full rounded-xl transition-colors",
isActive
? "text-primary bg-secondary"
: "text-gray-500 hover:text-primary hover:bg-gray-50"
? "text-primary bg-secondary dark:bg-primary/20"
: "text-gray-500 dark:text-gray-400 hover:text-primary dark:hover:text-primary hover:bg-gray-50 dark:hover:bg-gray-800"
)}
>
<Icon className="h-6 w-6" />
@ -53,6 +54,9 @@ export default function TabNavigation() {
</Link>
);
})}
<div className="flex items-center justify-center h-full px-2">
<ThemeToggle />
</div>
</div>
</nav>
);

View File

@ -7,10 +7,10 @@ const buttonVariants = cva(
{
variants: {
variant: {
default: "bg-primary text-primary-foreground hover:bg-primary/90",
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80",
outline: "border-2 border-primary text-primary hover:bg-primary hover:text-white",
ghost: "hover:bg-secondary hover:text-secondary-foreground",
default: "bg-primary text-primary-foreground hover:bg-primary/90 dark:bg-primary dark:hover:bg-primary/80",
secondary: "bg-secondary text-secondary-foreground hover:bg-secondary/80 dark:bg-primary/20 dark:text-primary dark:hover:bg-primary/30",
outline: "border-2 border-primary text-primary hover:bg-primary hover:text-white dark:border-primary dark:text-primary dark:hover:bg-primary dark:hover:text-white",
ghost: "hover:bg-secondary hover:text-secondary-foreground dark:hover:bg-gray-800 dark:hover:text-gray-200",
},
size: {
default: "h-12 px-6 py-3",

View File

@ -8,7 +8,7 @@ const Card = React.forwardRef<
<div
ref={ref}
className={cn(
"rounded-2xl border border-gray-200 bg-white shadow-sm",
"rounded-2xl border border-gray-200 dark:border-gray-800 bg-white dark:bg-gray-900 shadow-sm",
className
)}
{...props}
@ -46,7 +46,7 @@ const CardDescription = React.forwardRef<
>(({ className, ...props }, ref) => (
<p
ref={ref}
className={cn("text-sm text-gray-600", className)}
className={cn("text-sm text-gray-600 dark:text-gray-400", className)}
{...props}
/>
));

2
data/.gitkeep Normal file
View File

@ -0,0 +1,2 @@
# Ce dossier contiendra clients.json (ignoré par git)

5
deploy/.env.example Normal file
View File

@ -0,0 +1,5 @@
# Mot de passe admin
ADMIN_PASSWORD=votre_mot_de_passe_securise
# Port (optionnel, par défaut 3000)
PORT=3000

1
deploy/.next/BUILD_ID Normal file
View File

@ -0,0 +1 @@
3c87ZLiEKCTo7fN65B1s7

View File

@ -0,0 +1,88 @@
{
"pages": {
"/_not-found/page": [
"static/chunks/webpack-272d92e0b8f870de.js",
"static/chunks/fd9d1056-f29a34e8cb4f1ac5.js",
"static/chunks/117-81b684a50b4e5a2c.js",
"static/chunks/main-app-be78d15d42f0ba33.js",
"static/chunks/app/_not-found/page-93c891698b4decca.js"
],
"/layout": [
"static/chunks/webpack-272d92e0b8f870de.js",
"static/chunks/fd9d1056-f29a34e8cb4f1ac5.js",
"static/chunks/117-81b684a50b4e5a2c.js",
"static/chunks/main-app-be78d15d42f0ba33.js",
"static/css/37740839d02c8860.css",
"static/chunks/app/layout-012feff5f2309838.js"
],
"/accueil/page": [
"static/chunks/webpack-272d92e0b8f870de.js",
"static/chunks/fd9d1056-f29a34e8cb4f1ac5.js",
"static/chunks/117-81b684a50b4e5a2c.js",
"static/chunks/main-app-be78d15d42f0ba33.js",
"static/chunks/130-fbdba5ec657d70e2.js",
"static/chunks/876-74e3127f7295a7cc.js",
"static/chunks/app/accueil/page-eeceff806dc9e963.js"
],
"/admin/login/page": [
"static/chunks/webpack-272d92e0b8f870de.js",
"static/chunks/fd9d1056-f29a34e8cb4f1ac5.js",
"static/chunks/117-81b684a50b4e5a2c.js",
"static/chunks/main-app-be78d15d42f0ba33.js",
"static/chunks/130-fbdba5ec657d70e2.js",
"static/chunks/app/admin/login/page-64d4a547eaf512e7.js"
],
"/admin/page": [
"static/chunks/webpack-272d92e0b8f870de.js",
"static/chunks/fd9d1056-f29a34e8cb4f1ac5.js",
"static/chunks/117-81b684a50b4e5a2c.js",
"static/chunks/main-app-be78d15d42f0ba33.js",
"static/chunks/130-fbdba5ec657d70e2.js",
"static/chunks/659-547b5910f7777d12.js",
"static/chunks/app/admin/page-be00d3b5e7fb599b.js"
],
"/explorer/page": [
"static/chunks/webpack-272d92e0b8f870de.js",
"static/chunks/fd9d1056-f29a34e8cb4f1ac5.js",
"static/chunks/117-81b684a50b4e5a2c.js",
"static/chunks/main-app-be78d15d42f0ba33.js",
"static/chunks/130-fbdba5ec657d70e2.js",
"static/chunks/876-74e3127f7295a7cc.js",
"static/chunks/app/explorer/page-94fbb37299b728f0.js"
],
"/infos/page": [
"static/chunks/webpack-272d92e0b8f870de.js",
"static/chunks/fd9d1056-f29a34e8cb4f1ac5.js",
"static/chunks/117-81b684a50b4e5a2c.js",
"static/chunks/main-app-be78d15d42f0ba33.js",
"static/chunks/130-fbdba5ec657d70e2.js",
"static/chunks/876-74e3127f7295a7cc.js",
"static/chunks/app/infos/page-9c23965cb3e698cb.js"
],
"/mana-tracker/page": [
"static/chunks/webpack-272d92e0b8f870de.js",
"static/chunks/fd9d1056-f29a34e8cb4f1ac5.js",
"static/chunks/117-81b684a50b4e5a2c.js",
"static/chunks/main-app-be78d15d42f0ba33.js",
"static/chunks/130-fbdba5ec657d70e2.js",
"static/chunks/876-74e3127f7295a7cc.js",
"static/chunks/app/mana-tracker/page-190454f13d1cd3f9.js"
],
"/offline/page": [
"static/chunks/webpack-272d92e0b8f870de.js",
"static/chunks/fd9d1056-f29a34e8cb4f1ac5.js",
"static/chunks/117-81b684a50b4e5a2c.js",
"static/chunks/main-app-be78d15d42f0ba33.js",
"static/chunks/130-fbdba5ec657d70e2.js",
"static/chunks/876-74e3127f7295a7cc.js",
"static/chunks/app/offline/page-c706c75d3862967d.js"
],
"/page": [
"static/chunks/webpack-272d92e0b8f870de.js",
"static/chunks/fd9d1056-f29a34e8cb4f1ac5.js",
"static/chunks/117-81b684a50b4e5a2c.js",
"static/chunks/main-app-be78d15d42f0ba33.js",
"static/chunks/app/page-66582cb216c486f4.js"
]
}
}

View File

@ -0,0 +1 @@
{"/_not-found/page":"/_not-found","/accueil/page":"/accueil","/admin/login/page":"/admin/login","/admin/page":"/admin","/api/admin/clients/route":"/api/admin/clients","/explorer/page":"/explorer","/infos/page":"/infos","/mana-tracker/page":"/mana-tracker","/offline/page":"/offline","/page":"/"}

View File

@ -0,0 +1,32 @@
{
"polyfillFiles": [
"static/chunks/polyfills-42372ed130431b0a.js"
],
"devFiles": [],
"ampDevFiles": [],
"lowPriorityFiles": [
"static/3c87ZLiEKCTo7fN65B1s7/_buildManifest.js",
"static/3c87ZLiEKCTo7fN65B1s7/_ssgManifest.js"
],
"rootMainFiles": [
"static/chunks/webpack-272d92e0b8f870de.js",
"static/chunks/fd9d1056-f29a34e8cb4f1ac5.js",
"static/chunks/117-81b684a50b4e5a2c.js",
"static/chunks/main-app-be78d15d42f0ba33.js"
],
"pages": {
"/_app": [
"static/chunks/webpack-272d92e0b8f870de.js",
"static/chunks/framework-f66176bb897dc684.js",
"static/chunks/main-98da237dfd0126ae.js",
"static/chunks/pages/_app-72b849fbd24ac258.js"
],
"/_error": [
"static/chunks/webpack-272d92e0b8f870de.js",
"static/chunks/framework-f66176bb897dc684.js",
"static/chunks/main-98da237dfd0126ae.js",
"static/chunks/pages/_error-7ba65e1336b92748.js"
]
},
"ampFirstPages": []
}

File diff suppressed because one or more lines are too long

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -0,0 +1 @@
{"version":1,"hasExportPathMap":false,"exportTrailingSlash":false,"isNextImageImported":false}

View File

@ -0,0 +1 @@
{"version":1,"images":{"deviceSizes":[640,750,828,1080,1200,1920,2048,3840],"imageSizes":[16,32,48,64,96,128,256,384],"path":"/_next/image","loader":"default","loaderFile":"","domains":[],"disableStaticImages":false,"minimumCacheTTL":60,"formats":["image/avif","image/webp"],"dangerouslyAllowSVG":false,"contentSecurityPolicy":"script-src 'none'; frame-src 'none'; sandbox;","contentDispositionType":"inline","remotePatterns":[],"unoptimized":false,"sizes":[640,750,828,1080,1200,1920,2048,3840,16,32,48,64,96,128,256,384]}}

View File

@ -0,0 +1 @@
{"version":1,"files":["../node_modules/styled-jsx/index.js","../node_modules/styled-jsx/package.json","../node_modules/styled-jsx/dist/index/index.js","../node_modules/react/package.json","../node_modules/react/index.js","../node_modules/client-only/package.json","../node_modules/react/cjs/react.production.min.js","../node_modules/client-only/index.js","../node_modules/styled-jsx/style.js","../node_modules/next/dist/compiled/next-server/server.runtime.prod.js","../node_modules/next/package.json","../node_modules/next/dist/server/body-streams.js","../node_modules/next/dist/lib/constants.js","../node_modules/next/dist/lib/picocolors.js","../node_modules/next/dist/shared/lib/constants.js","../node_modules/next/dist/server/web/utils.js","../node_modules/next/dist/client/components/app-router-headers.js","../node_modules/next/dist/server/lib/trace/tracer.js","../node_modules/next/dist/server/lib/trace/constants.js","../node_modules/next/dist/client/components/static-generation-async-storage.external.js","../node_modules/next/dist/shared/lib/modern-browserslist-target.js","../node_modules/next/dist/client/components/static-generation-async-storage-instance.js","../node_modules/next/dist/shared/lib/runtime-config.external.js","../node_modules/next/dist/compiled/ws/package.json","../node_modules/next/dist/compiled/node-html-parser/package.json","../node_modules/next/dist/compiled/lru-cache/package.json","../node_modules/@swc/helpers/_/_interop_require_default/package.json","../node_modules/next/dist/client/components/async-local-storage.js","../node_modules/next/dist/compiled/ws/index.js","../node_modules/next/dist/compiled/node-html-parser/index.js","../node_modules/next/dist/compiled/lru-cache/index.js","../node_modules/next/dist/compiled/@opentelemetry/api/package.json","../node_modules/@swc/helpers/package.json","../node_modules/next/dist/compiled/jsonwebtoken/package.json","../node_modules/next/dist/shared/lib/error-source.js","../node_modules/@swc/helpers/cjs/_interop_require_default.cjs","../node_modules/next/dist/compiled/@opentelemetry/api/index.js","../node_modules/next/dist/compiled/jsonwebtoken/index.js","../node_modules/next/dist/compiled/debug/package.json","../node_modules/next/dist/lib/semver-noop.js","../node_modules/next/dist/compiled/debug/index.js","../node_modules/next/dist/server/future/route-modules/app-page/vendored/contexts/amp-context.js","../node_modules/next/dist/server/future/route-modules/app-page/vendored/contexts/app-router-context.js","../node_modules/next/dist/server/future/route-modules/app-page/vendored/contexts/entrypoints.js","../node_modules/next/dist/server/future/route-modules/app-page/vendored/contexts/head-manager-context.js","../node_modules/next/dist/server/future/route-modules/app-page/vendored/contexts/hooks-client-context.js","../node_modules/next/dist/server/future/route-modules/app-page/vendored/contexts/html-context.js","../node_modules/next/dist/server/future/route-modules/app-page/vendored/contexts/image-config-context.js","../node_modules/next/dist/server/future/route-modules/app-page/vendored/contexts/loadable-context.js","../node_modules/next/dist/server/future/route-modules/app-page/vendored/contexts/loadable.js","../node_modules/next/dist/server/future/route-modules/app-page/vendored/contexts/router-context.js","../node_modules/next/dist/server/future/route-modules/app-page/vendored/contexts/server-inserted-html.js","../node_modules/next/dist/server/future/route-modules/app-page/module.compiled.js","../node_modules/next/dist/server/future/route-modules/pages/vendored/contexts/amp-context.js","../node_modules/next/dist/server/future/route-modules/pages/vendored/contexts/app-router-context.js","../node_modules/next/dist/server/future/route-modules/pages/vendored/contexts/entrypoints.js","../node_modules/next/dist/server/future/route-modules/pages/vendored/contexts/head-manager-context.js","../node_modules/next/dist/server/future/route-modules/pages/vendored/contexts/hooks-client-context.js","../node_modules/next/dist/server/future/route-modules/pages/vendored/contexts/html-context.js","../node_modules/next/dist/server/future/route-modules/pages/vendored/contexts/image-config-context.js","../node_modules/next/dist/server/future/route-modules/pages/vendored/contexts/loadable-context.js","../node_modules/next/dist/server/future/route-modules/pages/vendored/contexts/loadable.js","../node_modules/next/dist/server/future/route-modules/pages/vendored/contexts/router-context.js","../node_modules/next/dist/server/future/route-modules/pages/vendored/contexts/server-inserted-html.js","../node_modules/next/dist/server/future/route-modules/pages/module.compiled.js"]}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"type": "commonjs"}

View File

@ -0,0 +1 @@
{"version":4,"routes":{"/infos":{"experimentalBypassFor":[{"type":"header","key":"Next-Action"},{"type":"header","key":"content-type","value":"multipart/form-data;.*"}],"initialRevalidateSeconds":false,"srcRoute":"/infos","dataRoute":"/infos.rsc"},"/mana-tracker":{"experimentalBypassFor":[{"type":"header","key":"Next-Action"},{"type":"header","key":"content-type","value":"multipart/form-data;.*"}],"initialRevalidateSeconds":false,"srcRoute":"/mana-tracker","dataRoute":"/mana-tracker.rsc"},"/offline":{"experimentalBypassFor":[{"type":"header","key":"Next-Action"},{"type":"header","key":"content-type","value":"multipart/form-data;.*"}],"initialRevalidateSeconds":false,"srcRoute":"/offline","dataRoute":"/offline.rsc"},"/":{"experimentalBypassFor":[{"type":"header","key":"Next-Action"},{"type":"header","key":"content-type","value":"multipart/form-data;.*"}],"initialRevalidateSeconds":false,"srcRoute":"/","dataRoute":"/index.rsc"},"/accueil":{"experimentalBypassFor":[{"type":"header","key":"Next-Action"},{"type":"header","key":"content-type","value":"multipart/form-data;.*"}],"initialRevalidateSeconds":false,"srcRoute":"/accueil","dataRoute":"/accueil.rsc"},"/admin":{"experimentalBypassFor":[{"type":"header","key":"Next-Action"},{"type":"header","key":"content-type","value":"multipart/form-data;.*"}],"initialRevalidateSeconds":false,"srcRoute":"/admin","dataRoute":"/admin.rsc"},"/explorer":{"experimentalBypassFor":[{"type":"header","key":"Next-Action"},{"type":"header","key":"content-type","value":"multipart/form-data;.*"}],"initialRevalidateSeconds":false,"srcRoute":"/explorer","dataRoute":"/explorer.rsc"},"/admin/login":{"experimentalBypassFor":[{"type":"header","key":"Next-Action"},{"type":"header","key":"content-type","value":"multipart/form-data;.*"}],"initialRevalidateSeconds":false,"srcRoute":"/admin/login","dataRoute":"/admin/login.rsc"}},"dynamicRoutes":{},"notFoundRoutes":[],"preview":{"previewModeId":"72798059332883bb836619ead11f265d","previewModeSigningKey":"c91fe6a8fb8a6afd08166f7488f47956827aa8492d588a1be69527dd7453feda","previewModeEncryptionKey":"b90ebc3c46fd8e2c88f96f242898610916379d8d4dc5cc0f98f6d0bb8b887095"}}

View File

@ -0,0 +1,14 @@
{
"app/accueil/page.tsx -> @/components/accueil/WeatherWidget": {
"id": 5147,
"files": [
"static/chunks/147.f0c63fadc263cdbf.js"
]
},
"app/explorer/page.tsx -> @/components/explorer/PlaceList": {
"id": 3293,
"files": [
"static/chunks/80.c30ab4050c6d10af.js"
]
}
}

View File

@ -0,0 +1 @@
{"version":1,"config":{"env":{},"webpack":null,"eslint":{"ignoreDuringBuilds":false},"typescript":{"ignoreBuildErrors":false,"tsconfigPath":"tsconfig.json"},"distDir":".next","cleanDistDir":true,"assetPrefix":"","cacheMaxMemorySize":52428800,"configOrigin":"next.config.js","useFileSystemPublicRoutes":true,"generateEtags":true,"pageExtensions":["tsx","ts","jsx","js"],"poweredByHeader":false,"compress":true,"analyticsId":"","images":{"deviceSizes":[640,750,828,1080,1200,1920,2048,3840],"imageSizes":[16,32,48,64,96,128,256,384],"path":"/_next/image","loader":"default","loaderFile":"","domains":[],"disableStaticImages":false,"minimumCacheTTL":60,"formats":["image/avif","image/webp"],"dangerouslyAllowSVG":false,"contentSecurityPolicy":"script-src 'none'; frame-src 'none'; sandbox;","contentDispositionType":"inline","remotePatterns":[],"unoptimized":false},"devIndicators":{"buildActivity":true,"buildActivityPosition":"bottom-right"},"onDemandEntries":{"maxInactiveAge":60000,"pagesBufferLength":5},"amp":{"canonicalBase":""},"basePath":"","sassOptions":{},"trailingSlash":false,"i18n":null,"productionBrowserSourceMaps":false,"optimizeFonts":true,"excludeDefaultMomentLocales":true,"serverRuntimeConfig":{},"publicRuntimeConfig":{},"reactProductionProfiling":false,"reactStrictMode":true,"httpAgentOptions":{"keepAlive":true},"outputFileTracing":true,"staticPageGenerationTimeout":60,"swcMinify":true,"modularizeImports":{"@mui/icons-material":{"transform":"@mui/icons-material/{{member}}"},"lodash":{"transform":"lodash/{{member}}"}},"experimental":{"multiZoneDraftMode":false,"prerenderEarlyExit":false,"serverMinification":true,"serverSourceMaps":false,"linkNoTouchStart":false,"caseSensitiveRoutes":false,"clientRouterFilter":true,"clientRouterFilterRedirects":false,"fetchCacheKeyPrefix":"","middlewarePrefetch":"flexible","optimisticClientCache":true,"manualClientBasePath":false,"cpus":7,"memoryBasedWorkersCount":false,"isrFlushToDisk":true,"workerThreads":false,"optimizeCss":false,"nextScriptWorkers":false,"scrollRestoration":false,"externalDir":false,"disableOptimizedLoading":false,"gzipSize":true,"craCompat":false,"esmExternals":true,"fullySpecified":false,"outputFileTracingRoot":"/home/syoul/Ccompagnon Marama","swcTraceProfiling":false,"forceSwcTransforms":false,"largePageDataBytes":128000,"adjustFontFallbacks":false,"adjustFontFallbacksWithSizeAdjust":false,"typedRoutes":false,"instrumentationHook":false,"bundlePagesExternals":false,"parallelServerCompiles":false,"parallelServerBuildTraces":false,"ppr":false,"missingSuspenseWithCSRBailout":true,"optimizeServerReact":true,"useEarlyImport":false,"staleTimes":{"dynamic":30,"static":300},"optimizePackageImports":["lucide-react","date-fns","lodash-es","ramda","antd","react-bootstrap","ahooks","@ant-design/icons","@headlessui/react","@headlessui-float/react","@heroicons/react/20/solid","@heroicons/react/24/solid","@heroicons/react/24/outline","@visx/visx","@tremor/react","rxjs","@mui/material","@mui/icons-material","recharts","react-use","@material-ui/core","@material-ui/icons","@tabler/icons-react","mui-core","react-icons/ai","react-icons/bi","react-icons/bs","react-icons/cg","react-icons/ci","react-icons/di","react-icons/fa","react-icons/fa6","react-icons/fc","react-icons/fi","react-icons/gi","react-icons/go","react-icons/gr","react-icons/hi","react-icons/hi2","react-icons/im","react-icons/io","react-icons/io5","react-icons/lia","react-icons/lib","react-icons/lu","react-icons/md","react-icons/pi","react-icons/ri","react-icons/rx","react-icons/si","react-icons/sl","react-icons/tb","react-icons/tfi","react-icons/ti","react-icons/vsc","react-icons/wi"],"trustHostHeader":false,"isExperimentalCompile":false},"configFileName":"next.config.js"},"appDir":"/home/syoul/Ccompagnon Marama","relativeAppDir":"","files":[".next/routes-manifest.json",".next/server/pages-manifest.json",".next/build-manifest.json",".next/prerender-manifest.json",".next/server/middleware-manifest.json",".next/server/middleware-build-manifest.js",".next/server/middleware-react-loadable-manifest.js",".next/server/app-paths-manifest.json",".next/app-path-routes-manifest.json",".next/app-build-manifest.json",".next/server/server-reference-manifest.js",".next/server/server-reference-manifest.json",".next/react-loadable-manifest.json",".next/server/font-manifest.json",".next/BUILD_ID",".next/server/next-font-manifest.js",".next/server/next-font-manifest.json"],"ignore":["node_modules/next/dist/compiled/@ampproject/toolbox-optimizer/**/*"]}

View File

@ -0,0 +1,12 @@
{
"/_not-found/page": "app/_not-found/page.js",
"/accueil/page": "app/accueil/page.js",
"/admin/login/page": "app/admin/login/page.js",
"/admin/page": "app/admin/page.js",
"/api/admin/clients/route": "app/api/admin/clients/route.js",
"/explorer/page": "app/explorer/page.js",
"/infos/page": "app/infos/page.js",
"/mana-tracker/page": "app/mana-tracker/page.js",
"/offline/page": "app/offline/page.js",
"/page": "app/page.js"
}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,6 @@
{
"status": 404,
"headers": {
"x-next-cache-tags": "_N_T_/layout,_N_T_/_not-found/layout,_N_T_/_not-found/page,_N_T_/_not-found"
}
}

View File

@ -0,0 +1,11 @@
2:I[4707,[],""]
3:I[6423,[],""]
4:I[5495,["185","static/chunks/app/layout-012feff5f2309838.js"],"ThemeProvider"]
9:I[1454,["185","static/chunks/app/layout-012feff5f2309838.js"],"default"]
5:{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"}
6:{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"}
7:{"display":"inline-block"}
8:{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0}
0:["3c87ZLiEKCTo7fN65B1s7",[[["",{"children":["/_not-found",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["/_not-found",{"children":["__PAGE__",{},[["$L1",[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],null],null],null]},[null,["$","$L2",null,{"parallelRouterKey":"children","segmentPath":["children","/_not-found","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/37740839d02c8860.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"fr","suppressHydrationWarning":true,"children":[["$","head",null,{"children":[["$","link",null,{"rel":"icon","href":"/logo-relais-marama.svg","type":"image/svg+xml"}],["$","link",null,{"rel":"apple-touch-icon","href":"/logo-relais-marama.svg"}]]}],["$","body",null,{"className":"__className_f367f3","children":["$","$L4",null,{"attribute":"class","defaultTheme":"light","enableSystem":true,"disableTransitionOnChange":false,"children":[["$","$L2",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":"$5","children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":"$6","children":"404"}],["$","div",null,{"style":"$7","children":["$","h2",null,{"style":"$8","children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}],["$","$L9",null,{}]]}]}]]}]],null],null],["$La",["$","meta",null,{"name":"robots","content":"noindex"}]]]]]
a:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Compagnon du lagon - Pension Marama"}],["$","meta","3",{"name":"description","content":"Votre guide numérique pour votre séjour à Fakarava"}],["$","link","4",{"rel":"manifest","href":"/manifest.json","crossOrigin":"use-credentials"}],["$","meta","5",{"name":"apple-mobile-web-app-capable","content":"yes"}],["$","meta","6",{"name":"apple-mobile-web-app-title","content":"Compagnon du lagon - Pension Marama"}],["$","meta","7",{"name":"apple-mobile-web-app-status-bar-style","content":"default"}],["$","meta","8",{"name":"next-size-adjust"}]]
1:null

View File

@ -0,0 +1 @@
(()=>{var e={};e.id=409,e.ids=[409],e.modules={2934:e=>{"use strict";e.exports=require("next/dist/client/components/action-async-storage.external.js")},4580:e=>{"use strict";e.exports=require("next/dist/client/components/request-async-storage.external.js")},5869:e=>{"use strict";e.exports=require("next/dist/client/components/static-generation-async-storage.external.js")},399:e=>{"use strict";e.exports=require("next/dist/compiled/next-server/app-page.runtime.prod.js")},4390:(e,t,n)=>{"use strict";n.r(t),n.d(t,{GlobalError:()=>i.a,__next_app__:()=>p,originalPathname:()=>c,pages:()=>d,routeModule:()=>f,tree:()=>u}),n(7352),n(5866),n(5481);var r=n(3191),o=n(8716),a=n(7922),i=n.n(a),s=n(5231),l={};for(let e in s)0>["default","tree","pages","GlobalError","originalPathname","__next_app__","routeModule"].indexOf(e)&&(l[e]=()=>s[e]);n.d(t,l);let u=["",{children:["/_not-found",{children:["__PAGE__",{},{page:[()=>Promise.resolve().then(n.t.bind(n,5866,23)),"next/dist/client/components/not-found-error"]}]},{}]},{layout:[()=>Promise.resolve().then(n.bind(n,5481)),"/home/syoul/Ccompagnon Marama/app/layout.tsx"],"not-found":[()=>Promise.resolve().then(n.t.bind(n,5866,23)),"next/dist/client/components/not-found-error"]}],d=[],c="/_not-found/page",p={require:n,loadChunk:()=>Promise.resolve()},f=new r.AppPageRouteModule({definition:{kind:o.x.APP_PAGE,page:"/_not-found/page",pathname:"/_not-found",bundlePath:"",filename:"",appPaths:[]},userland:{loaderTree:u}})},7274:(e,t,n)=>{Promise.resolve().then(n.bind(n,7904)),Promise.resolve().then(n.bind(n,7459))},9401:(e,t,n)=>{Promise.resolve().then(n.t.bind(n,2994,23)),Promise.resolve().then(n.t.bind(n,6114,23)),Promise.resolve().then(n.t.bind(n,9727,23)),Promise.resolve().then(n.t.bind(n,9671,23)),Promise.resolve().then(n.t.bind(n,1868,23)),Promise.resolve().then(n.t.bind(n,4759,23))},7904:(e,t,n)=>{"use strict";function r(){return null}n.d(t,{default:()=>r}),n(7577)},7459:(e,t,n)=>{"use strict";n.d(t,{ThemeProvider:()=>a});var r=n(326),o=n(4831);function a({children:e,...t}){return r.jsx(o.f,{...t,children:e})}},5481:(e,t,n)=>{"use strict";n.r(t),n.d(t,{default:()=>d,metadata:()=>u});var r=n(9510),o=n(5384),a=n.n(o);n(7272);var i=n(8570);let s=(0,i.createProxy)(String.raw`/home/syoul/Ccompagnon Marama/components/PWARegister.tsx#default`),l=(0,i.createProxy)(String.raw`/home/syoul/Ccompagnon Marama/components/ThemeProvider.tsx#ThemeProvider`),u={title:"Compagnon du lagon - Pension Marama",description:"Votre guide num\xe9rique pour votre s\xe9jour \xe0 Fakarava",manifest:"/manifest.json",themeColor:"#0E7490",appleWebApp:{capable:!0,statusBarStyle:"default",title:"Compagnon du lagon - Pension Marama"},viewport:{width:"device-width",initialScale:1,maximumScale:1,userScalable:!1}};function d({children:e}){return(0,r.jsxs)("html",{lang:"fr",suppressHydrationWarning:!0,children:[(0,r.jsxs)("head",{children:[r.jsx("link",{rel:"icon",href:"/logo-relais-marama.svg",type:"image/svg+xml"}),r.jsx("link",{rel:"apple-touch-icon",href:"/logo-relais-marama.svg"})]}),r.jsx("body",{className:a().className,children:(0,r.jsxs)(l,{attribute:"class",defaultTheme:"light",enableSystem:!0,disableTransitionOnChange:!1,children:[e,r.jsx(s,{})]})})]})}},6399:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var n in t)Object.defineProperty(e,n,{enumerable:!0,get:t[n]})}(t,{isNotFoundError:function(){return o},notFound:function(){return r}});let n="NEXT_NOT_FOUND";function r(){let e=Error(n);throw e.digest=n,e}function o(e){return"object"==typeof e&&null!==e&&"digest"in e&&e.digest===n}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},7352:(e,t,n)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),function(e,t){for(var n in t)Object.defineProperty(e,n,{enumerable:!0,get:t[n]})}(t,{PARALLEL_ROUTE_DEFAULT_PATH:function(){return o},default:function(){return a}});let r=n(6399),o="next/dist/client/components/parallel-route-default.js";function a(){(0,r.notFound)()}("function"==typeof t.default||"object"==typeof t.default&&null!==t.default)&&void 0===t.default.__esModule&&(Object.defineProperty(t.default,"__esModule",{value:!0}),Object.assign(t.default,t),e.exports=t.default)},7272:()=>{}};var t=require("../../webpack-runtime.js");t.C(e);var n=e=>t(t.s=e),r=t.X(0,[276,740],()=>n(4390));module.exports=r})();

View File

@ -0,0 +1 @@
{"version":1,"files":["../../../../node_modules/next/dist/client/components/action-async-storage-instance.js","../../../../node_modules/next/dist/client/components/action-async-storage.external.js","../../../../node_modules/next/dist/client/components/async-local-storage.js","../../../../node_modules/next/dist/client/components/request-async-storage-instance.js","../../../../node_modules/next/dist/client/components/request-async-storage.external.js","../../../../node_modules/next/dist/client/components/static-generation-async-storage-instance.js","../../../../node_modules/next/dist/client/components/static-generation-async-storage.external.js","../../../../node_modules/next/dist/compiled/@opentelemetry/api/index.js","../../../../node_modules/next/dist/compiled/@opentelemetry/api/package.json","../../../../node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js","../../../../node_modules/next/dist/server/lib/trace/constants.js","../../../../node_modules/next/dist/server/lib/trace/tracer.js","../../../../node_modules/next/package.json","../../../package.json","../../chunks/276.js","../../chunks/740.js","../../webpack-runtime.js","page_client-reference-manifest.js"]}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,5 @@
{
"headers": {
"x-next-cache-tags": "_N_T_/layout,_N_T_/accueil/layout,_N_T_/accueil/page,_N_T_/accueil"
}
}

View File

@ -0,0 +1,9 @@
2:I[9107,[],"ClientPageRoot"]
3:I[8666,["130","static/chunks/130-fbdba5ec657d70e2.js","876","static/chunks/876-74e3127f7295a7cc.js","206","static/chunks/app/accueil/page-eeceff806dc9e963.js"],"default",1]
4:I[4707,[],""]
5:I[6423,[],""]
6:I[5495,["185","static/chunks/app/layout-012feff5f2309838.js"],"ThemeProvider"]
7:I[1454,["185","static/chunks/app/layout-012feff5f2309838.js"],"default"]
0:["3c87ZLiEKCTo7fN65B1s7",[[["",{"children":["accueil",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["accueil",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","accueil","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/37740839d02c8860.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"fr","suppressHydrationWarning":true,"children":[["$","head",null,{"children":[["$","link",null,{"rel":"icon","href":"/logo-relais-marama.svg","type":"image/svg+xml"}],["$","link",null,{"rel":"apple-touch-icon","href":"/logo-relais-marama.svg"}]]}],["$","body",null,{"className":"__className_f367f3","children":["$","$L6",null,{"attribute":"class","defaultTheme":"light","enableSystem":true,"disableTransitionOnChange":false,"children":[["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}],["$","$L7",null,{}]]}]}]]}]],null],null],["$L8",null]]]]
8:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Compagnon du lagon - Pension Marama"}],["$","meta","3",{"name":"description","content":"Votre guide numérique pour votre séjour à Fakarava"}],["$","link","4",{"rel":"manifest","href":"/manifest.json","crossOrigin":"use-credentials"}],["$","meta","5",{"name":"apple-mobile-web-app-capable","content":"yes"}],["$","meta","6",{"name":"apple-mobile-web-app-title","content":"Compagnon du lagon - Pension Marama"}],["$","meta","7",{"name":"apple-mobile-web-app-status-bar-style","content":"default"}],["$","meta","8",{"name":"next-size-adjust"}]]
1:null

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"version":1,"files":["../../../../node_modules/next/dist/client/components/action-async-storage-instance.js","../../../../node_modules/next/dist/client/components/action-async-storage.external.js","../../../../node_modules/next/dist/client/components/async-local-storage.js","../../../../node_modules/next/dist/client/components/request-async-storage-instance.js","../../../../node_modules/next/dist/client/components/request-async-storage.external.js","../../../../node_modules/next/dist/client/components/static-generation-async-storage-instance.js","../../../../node_modules/next/dist/client/components/static-generation-async-storage.external.js","../../../../node_modules/next/dist/compiled/@opentelemetry/api/index.js","../../../../node_modules/next/dist/compiled/@opentelemetry/api/package.json","../../../../node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js","../../../../node_modules/next/dist/server/lib/trace/constants.js","../../../../node_modules/next/dist/server/lib/trace/tracer.js","../../../../node_modules/next/package.json","../../../../package.json","../../../package.json","../../chunks/276.js","../../chunks/341.js","../../chunks/740.js","../../chunks/87.js","../../webpack-runtime.js","page_client-reference-manifest.js"]}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,5 @@
{
"headers": {
"x-next-cache-tags": "_N_T_/layout,_N_T_/admin/layout,_N_T_/admin/page,_N_T_/admin"
}
}

View File

@ -0,0 +1,9 @@
2:I[9107,[],"ClientPageRoot"]
3:I[5176,["130","static/chunks/130-fbdba5ec657d70e2.js","659","static/chunks/659-547b5910f7777d12.js","3","static/chunks/app/admin/page-be00d3b5e7fb599b.js"],"default",1]
4:I[4707,[],""]
5:I[6423,[],""]
6:I[5495,["185","static/chunks/app/layout-012feff5f2309838.js"],"ThemeProvider"]
7:I[1454,["185","static/chunks/app/layout-012feff5f2309838.js"],"default"]
0:["3c87ZLiEKCTo7fN65B1s7",[[["",{"children":["admin",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["admin",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","admin","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/37740839d02c8860.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"fr","suppressHydrationWarning":true,"children":[["$","head",null,{"children":[["$","link",null,{"rel":"icon","href":"/logo-relais-marama.svg","type":"image/svg+xml"}],["$","link",null,{"rel":"apple-touch-icon","href":"/logo-relais-marama.svg"}]]}],["$","body",null,{"className":"__className_f367f3","children":["$","$L6",null,{"attribute":"class","defaultTheme":"light","enableSystem":true,"disableTransitionOnChange":false,"children":[["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}],["$","$L7",null,{}]]}]}]]}]],null],null],["$L8",null]]]]
8:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Compagnon du lagon - Pension Marama"}],["$","meta","3",{"name":"description","content":"Votre guide numérique pour votre séjour à Fakarava"}],["$","link","4",{"rel":"manifest","href":"/manifest.json","crossOrigin":"use-credentials"}],["$","meta","5",{"name":"apple-mobile-web-app-capable","content":"yes"}],["$","meta","6",{"name":"apple-mobile-web-app-title","content":"Compagnon du lagon - Pension Marama"}],["$","meta","7",{"name":"apple-mobile-web-app-status-bar-style","content":"default"}],["$","meta","8",{"name":"next-size-adjust"}]]
1:null

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,5 @@
{
"headers": {
"x-next-cache-tags": "_N_T_/layout,_N_T_/admin/layout,_N_T_/admin/login/layout,_N_T_/admin/login/page,_N_T_/admin/login"
}
}

View File

@ -0,0 +1,9 @@
2:I[9107,[],"ClientPageRoot"]
3:I[4507,["130","static/chunks/130-fbdba5ec657d70e2.js","920","static/chunks/app/admin/login/page-64d4a547eaf512e7.js"],"default",1]
4:I[4707,[],""]
5:I[6423,[],""]
6:I[5495,["185","static/chunks/app/layout-012feff5f2309838.js"],"ThemeProvider"]
7:I[1454,["185","static/chunks/app/layout-012feff5f2309838.js"],"default"]
0:["3c87ZLiEKCTo7fN65B1s7",[[["",{"children":["admin",{"children":["login",{"children":["__PAGE__",{}]}]}]},"$undefined","$undefined",true],["",{"children":["admin",{"children":["login",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","admin","children","login","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","admin","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/37740839d02c8860.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"fr","suppressHydrationWarning":true,"children":[["$","head",null,{"children":[["$","link",null,{"rel":"icon","href":"/logo-relais-marama.svg","type":"image/svg+xml"}],["$","link",null,{"rel":"apple-touch-icon","href":"/logo-relais-marama.svg"}]]}],["$","body",null,{"className":"__className_f367f3","children":["$","$L6",null,{"attribute":"class","defaultTheme":"light","enableSystem":true,"disableTransitionOnChange":false,"children":[["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}],["$","$L7",null,{}]]}]}]]}]],null],null],["$L8",null]]]]
8:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Compagnon du lagon - Pension Marama"}],["$","meta","3",{"name":"description","content":"Votre guide numérique pour votre séjour à Fakarava"}],["$","link","4",{"rel":"manifest","href":"/manifest.json","crossOrigin":"use-credentials"}],["$","meta","5",{"name":"apple-mobile-web-app-capable","content":"yes"}],["$","meta","6",{"name":"apple-mobile-web-app-title","content":"Compagnon du lagon - Pension Marama"}],["$","meta","7",{"name":"apple-mobile-web-app-status-bar-style","content":"default"}],["$","meta","8",{"name":"next-size-adjust"}]]
1:null

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"version":1,"files":["../../../../../node_modules/next/dist/client/components/action-async-storage-instance.js","../../../../../node_modules/next/dist/client/components/action-async-storage.external.js","../../../../../node_modules/next/dist/client/components/async-local-storage.js","../../../../../node_modules/next/dist/client/components/request-async-storage-instance.js","../../../../../node_modules/next/dist/client/components/request-async-storage.external.js","../../../../../node_modules/next/dist/client/components/static-generation-async-storage-instance.js","../../../../../node_modules/next/dist/client/components/static-generation-async-storage.external.js","../../../../../node_modules/next/dist/compiled/@opentelemetry/api/index.js","../../../../../node_modules/next/dist/compiled/@opentelemetry/api/package.json","../../../../../node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js","../../../../../node_modules/next/dist/server/lib/trace/constants.js","../../../../../node_modules/next/dist/server/lib/trace/tracer.js","../../../../../node_modules/next/package.json","../../../../../package.json","../../../../package.json","../../../chunks/276.js","../../../chunks/740.js","../../../chunks/87.js","../../../webpack-runtime.js","page_client-reference-manifest.js"]}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"version":1,"files":["../../../../node_modules/next/dist/client/components/action-async-storage-instance.js","../../../../node_modules/next/dist/client/components/action-async-storage.external.js","../../../../node_modules/next/dist/client/components/async-local-storage.js","../../../../node_modules/next/dist/client/components/request-async-storage-instance.js","../../../../node_modules/next/dist/client/components/request-async-storage.external.js","../../../../node_modules/next/dist/client/components/static-generation-async-storage-instance.js","../../../../node_modules/next/dist/client/components/static-generation-async-storage.external.js","../../../../node_modules/next/dist/compiled/@opentelemetry/api/index.js","../../../../node_modules/next/dist/compiled/@opentelemetry/api/package.json","../../../../node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js","../../../../node_modules/next/dist/server/lib/trace/constants.js","../../../../node_modules/next/dist/server/lib/trace/tracer.js","../../../../node_modules/next/package.json","../../../../package.json","../../../package.json","../../chunks/276.js","../../chunks/740.js","../../chunks/87.js","../../webpack-runtime.js","page_client-reference-manifest.js"]}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"version":1,"files":["../../../../../../data/.gitkeep","../../../../../../data/clients.json","../../../../../../node_modules/next/dist/client/components/action-async-storage-instance.js","../../../../../../node_modules/next/dist/client/components/action-async-storage.external.js","../../../../../../node_modules/next/dist/client/components/async-local-storage.js","../../../../../../node_modules/next/dist/client/components/request-async-storage-instance.js","../../../../../../node_modules/next/dist/client/components/request-async-storage.external.js","../../../../../../node_modules/next/dist/client/components/static-generation-async-storage-instance.js","../../../../../../node_modules/next/dist/client/components/static-generation-async-storage.external.js","../../../../../../node_modules/next/dist/compiled/@opentelemetry/api/index.js","../../../../../../node_modules/next/dist/compiled/@opentelemetry/api/package.json","../../../../../../node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js","../../../../../../node_modules/next/dist/compiled/next-server/app-route.runtime.prod.js","../../../../../../node_modules/next/dist/server/lib/trace/constants.js","../../../../../../node_modules/next/dist/server/lib/trace/tracer.js","../../../../../../node_modules/next/package.json","../../../../../../package.json","../../../../../package.json","../../../../chunks/276.js","../../../../webpack-runtime.js"]}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,5 @@
{
"headers": {
"x-next-cache-tags": "_N_T_/layout,_N_T_/explorer/layout,_N_T_/explorer/page,_N_T_/explorer"
}
}

View File

@ -0,0 +1,9 @@
2:I[9107,[],"ClientPageRoot"]
3:I[9566,["130","static/chunks/130-fbdba5ec657d70e2.js","876","static/chunks/876-74e3127f7295a7cc.js","743","static/chunks/app/explorer/page-94fbb37299b728f0.js"],"default",1]
4:I[4707,[],""]
5:I[6423,[],""]
6:I[5495,["185","static/chunks/app/layout-012feff5f2309838.js"],"ThemeProvider"]
7:I[1454,["185","static/chunks/app/layout-012feff5f2309838.js"],"default"]
0:["3c87ZLiEKCTo7fN65B1s7",[[["",{"children":["explorer",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["explorer",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[null,["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children","explorer","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/37740839d02c8860.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"fr","suppressHydrationWarning":true,"children":[["$","head",null,{"children":[["$","link",null,{"rel":"icon","href":"/logo-relais-marama.svg","type":"image/svg+xml"}],["$","link",null,{"rel":"apple-touch-icon","href":"/logo-relais-marama.svg"}]]}],["$","body",null,{"className":"__className_f367f3","children":["$","$L6",null,{"attribute":"class","defaultTheme":"light","enableSystem":true,"disableTransitionOnChange":false,"children":[["$","$L4",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L5",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}],["$","$L7",null,{}]]}]}]]}]],null],null],["$L8",null]]]]
8:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Compagnon du lagon - Pension Marama"}],["$","meta","3",{"name":"description","content":"Votre guide numérique pour votre séjour à Fakarava"}],["$","link","4",{"rel":"manifest","href":"/manifest.json","crossOrigin":"use-credentials"}],["$","meta","5",{"name":"apple-mobile-web-app-capable","content":"yes"}],["$","meta","6",{"name":"apple-mobile-web-app-title","content":"Compagnon du lagon - Pension Marama"}],["$","meta","7",{"name":"apple-mobile-web-app-status-bar-style","content":"default"}],["$","meta","8",{"name":"next-size-adjust"}]]
1:null

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"version":1,"files":["../../../../node_modules/next/dist/client/components/action-async-storage-instance.js","../../../../node_modules/next/dist/client/components/action-async-storage.external.js","../../../../node_modules/next/dist/client/components/async-local-storage.js","../../../../node_modules/next/dist/client/components/request-async-storage-instance.js","../../../../node_modules/next/dist/client/components/request-async-storage.external.js","../../../../node_modules/next/dist/client/components/static-generation-async-storage-instance.js","../../../../node_modules/next/dist/client/components/static-generation-async-storage.external.js","../../../../node_modules/next/dist/compiled/@opentelemetry/api/index.js","../../../../node_modules/next/dist/compiled/@opentelemetry/api/package.json","../../../../node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js","../../../../node_modules/next/dist/server/lib/trace/constants.js","../../../../node_modules/next/dist/server/lib/trace/tracer.js","../../../../node_modules/next/package.json","../../../../package.json","../../../package.json","../../chunks/276.js","../../chunks/341.js","../../chunks/740.js","../../chunks/87.js","../../chunks/933.js","../../webpack-runtime.js","page_client-reference-manifest.js"]}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,5 @@
{
"headers": {
"x-next-cache-tags": "_N_T_/layout,_N_T_/page,_N_T_/"
}
}

View File

@ -0,0 +1,9 @@
2:I[9107,[],"ClientPageRoot"]
3:I[7340,["931","static/chunks/app/page-66582cb216c486f4.js"],"default",1]
4:I[5495,["185","static/chunks/app/layout-012feff5f2309838.js"],"ThemeProvider"]
5:I[4707,[],""]
6:I[6423,[],""]
7:I[1454,["185","static/chunks/app/layout-012feff5f2309838.js"],"default"]
0:["3c87ZLiEKCTo7fN65B1s7",[[["",{"children":["__PAGE__",{}]},"$undefined","$undefined",true],["",{"children":["__PAGE__",{},[["$L1",["$","$L2",null,{"props":{"params":{},"searchParams":{}},"Component":"$3"}],null],null],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/37740839d02c8860.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"fr","suppressHydrationWarning":true,"children":[["$","head",null,{"children":[["$","link",null,{"rel":"icon","href":"/logo-relais-marama.svg","type":"image/svg+xml"}],["$","link",null,{"rel":"apple-touch-icon","href":"/logo-relais-marama.svg"}]]}],["$","body",null,{"className":"__className_f367f3","children":["$","$L4",null,{"attribute":"class","defaultTheme":"light","enableSystem":true,"disableTransitionOnChange":false,"children":[["$","$L5",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L6",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}],["$","$L7",null,{}]]}]}]]}]],null],null],["$L8",null]]]]
8:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Compagnon du lagon - Pension Marama"}],["$","meta","3",{"name":"description","content":"Votre guide numérique pour votre séjour à Fakarava"}],["$","link","4",{"rel":"manifest","href":"/manifest.json","crossOrigin":"use-credentials"}],["$","meta","5",{"name":"apple-mobile-web-app-capable","content":"yes"}],["$","meta","6",{"name":"apple-mobile-web-app-title","content":"Compagnon du lagon - Pension Marama"}],["$","meta","7",{"name":"apple-mobile-web-app-status-bar-style","content":"default"}],["$","meta","8",{"name":"next-size-adjust"}]]
1:null

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,5 @@
{
"headers": {
"x-next-cache-tags": "_N_T_/layout,_N_T_/infos/layout,_N_T_/infos/page,_N_T_/infos"
}
}

View File

@ -0,0 +1,15 @@
2:"$Sreact.suspense"
3:I[49,["130","static/chunks/130-fbdba5ec657d70e2.js","876","static/chunks/876-74e3127f7295a7cc.js","767","static/chunks/app/infos/page-9c23965cb3e698cb.js"],"PreloadCss"]
6:I[1110,["130","static/chunks/130-fbdba5ec657d70e2.js","876","static/chunks/876-74e3127f7295a7cc.js","767","static/chunks/app/infos/page-9c23965cb3e698cb.js"],"default"]
7:I[9673,["130","static/chunks/130-fbdba5ec657d70e2.js","876","static/chunks/876-74e3127f7295a7cc.js","767","static/chunks/app/infos/page-9c23965cb3e698cb.js"],"default"]
8:I[4707,[],""]
9:I[6423,[],""]
a:I[5495,["185","static/chunks/app/layout-012feff5f2309838.js"],"ThemeProvider"]
b:I[1454,["185","static/chunks/app/layout-012feff5f2309838.js"],"default"]
0:["3c87ZLiEKCTo7fN65B1s7",[[["",{"children":["infos",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["infos",{"children":["__PAGE__",{},[["$L1",["$","div",null,{"className":"min-h-screen bg-background dark:bg-background-dark pb-16","children":[["$","div",null,{"className":"px-4 py-6 space-y-8","children":[["$","header",null,{"children":[["$","h1",null,{"className":"text-2xl font-bold text-primary mb-2","children":"Infos Pratiques"}],["$","p",null,{"className":"text-gray-600","children":"Tout ce que vous devez savoir pour votre séjour"}]]}],["$","section",null,{"children":[["$","h2",null,{"className":"text-xl font-semibold text-primary mb-4","children":"Questions Fréquentes"}],["$","$2",null,{"fallback":["$","div",null,{"className":"h-64 bg-gray-100 rounded-2xl animate-pulse"}],"children":[["$","$L3",null,{"moduleIds":["app/infos/page.tsx -> @/components/infos/FAQAccordion"]}],"$L4"]}]]}],["$","section",null,{"children":["$","$2",null,{"fallback":["$","div",null,{"className":"h-48 bg-gray-100 rounded-2xl animate-pulse"}],"children":[["$","$L3",null,{"moduleIds":["app/infos/page.tsx -> @/components/infos/LexiqueSection"]}],"$L5"]}]}],["$","section",null,{"children":["$","$L6",null,{}]}]]}],["$","$L7",null,{}]]}],null],null],null]},[null,["$","$L8",null,{"parallelRouterKey":"children","segmentPath":["children","infos","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L9",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/37740839d02c8860.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"fr","suppressHydrationWarning":true,"children":[["$","head",null,{"children":[["$","link",null,{"rel":"icon","href":"/logo-relais-marama.svg","type":"image/svg+xml"}],["$","link",null,{"rel":"apple-touch-icon","href":"/logo-relais-marama.svg"}]]}],["$","body",null,{"className":"__className_f367f3","children":["$","$La",null,{"attribute":"class","defaultTheme":"light","enableSystem":true,"disableTransitionOnChange":false,"children":[["$","$L8",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L9",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}],["$","$Lb",null,{}]]}]}]]}]],null],null],["$Lc",null]]]]
d:I[646,["130","static/chunks/130-fbdba5ec657d70e2.js","876","static/chunks/876-74e3127f7295a7cc.js","767","static/chunks/app/infos/page-9c23965cb3e698cb.js"],"default"]
e:I[9795,["130","static/chunks/130-fbdba5ec657d70e2.js","876","static/chunks/876-74e3127f7295a7cc.js","767","static/chunks/app/infos/page-9c23965cb3e698cb.js"],"default"]
4:["$","$Ld",null,{}]
5:["$","$Le",null,{}]
c:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Compagnon du lagon - Pension Marama"}],["$","meta","3",{"name":"description","content":"Votre guide numérique pour votre séjour à Fakarava"}],["$","link","4",{"rel":"manifest","href":"/manifest.json","crossOrigin":"use-credentials"}],["$","meta","5",{"name":"apple-mobile-web-app-capable","content":"yes"}],["$","meta","6",{"name":"apple-mobile-web-app-title","content":"Compagnon du lagon - Pension Marama"}],["$","meta","7",{"name":"apple-mobile-web-app-status-bar-style","content":"default"}],["$","meta","8",{"name":"next-size-adjust"}]]
1:null

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"version":1,"files":["../../../../components/infos/FAQAccordion.tsx","../../../../components/infos/LexiqueSection.tsx","../../../../node_modules/next/dist/client/components/action-async-storage-instance.js","../../../../node_modules/next/dist/client/components/action-async-storage.external.js","../../../../node_modules/next/dist/client/components/async-local-storage.js","../../../../node_modules/next/dist/client/components/request-async-storage-instance.js","../../../../node_modules/next/dist/client/components/request-async-storage.external.js","../../../../node_modules/next/dist/client/components/static-generation-async-storage-instance.js","../../../../node_modules/next/dist/client/components/static-generation-async-storage.external.js","../../../../node_modules/next/dist/compiled/@opentelemetry/api/index.js","../../../../node_modules/next/dist/compiled/@opentelemetry/api/package.json","../../../../node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js","../../../../node_modules/next/dist/server/lib/trace/constants.js","../../../../node_modules/next/dist/server/lib/trace/tracer.js","../../../../node_modules/next/package.json","../../../../package.json","../../../package.json","../../chunks/174.js","../../chunks/276.js","../../chunks/341.js","../../chunks/698.js","../../chunks/740.js","../../chunks/87.js","../../chunks/99.js","../../webpack-runtime.js","page_client-reference-manifest.js"]}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,5 @@
{
"headers": {
"x-next-cache-tags": "_N_T_/layout,_N_T_/mana-tracker/layout,_N_T_/mana-tracker/page,_N_T_/mana-tracker"
}
}

View File

@ -0,0 +1,16 @@
2:I[7849,["130","static/chunks/130-fbdba5ec657d70e2.js","876","static/chunks/876-74e3127f7295a7cc.js","347","static/chunks/app/mana-tracker/page-190454f13d1cd3f9.js"],"default"]
3:I[1556,["130","static/chunks/130-fbdba5ec657d70e2.js","876","static/chunks/876-74e3127f7295a7cc.js","347","static/chunks/app/mana-tracker/page-190454f13d1cd3f9.js"],"default"]
4:"$Sreact.suspense"
5:I[49,["130","static/chunks/130-fbdba5ec657d70e2.js","876","static/chunks/876-74e3127f7295a7cc.js","347","static/chunks/app/mana-tracker/page-190454f13d1cd3f9.js"],"PreloadCss"]
8:I[9673,["130","static/chunks/130-fbdba5ec657d70e2.js","876","static/chunks/876-74e3127f7295a7cc.js","347","static/chunks/app/mana-tracker/page-190454f13d1cd3f9.js"],"default"]
9:I[4707,[],""]
a:I[6423,[],""]
b:I[5495,["185","static/chunks/app/layout-012feff5f2309838.js"],"ThemeProvider"]
c:I[1454,["185","static/chunks/app/layout-012feff5f2309838.js"],"default"]
0:["3c87ZLiEKCTo7fN65B1s7",[[["",{"children":["mana-tracker",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["mana-tracker",{"children":["__PAGE__",{},[["$L1",["$","div",null,{"className":"min-h-screen bg-background dark:bg-background-dark pb-16","children":[["$","div",null,{"className":"px-4 py-6 space-y-6","children":[["$","header",null,{"children":[["$","h1",null,{"className":"text-2xl font-bold text-primary mb-2","children":"Mana Tracker"}],["$","p",null,{"className":"text-gray-600","children":"Activités & Météo - Tout dépend de la mer et du soleil"}]]}],["$","$L2",null,{}],["$","$L3",null,{}],["$","$4",null,{"fallback":["$","div",null,{"className":"h-64 bg-gray-100 rounded-2xl animate-pulse"}],"children":[["$","$L5",null,{"moduleIds":["app/mana-tracker/page.tsx -> @/components/mana-tracker/ExcursionBooking"]}],"$L6"]}],["$","$4",null,{"fallback":["$","div",null,{"className":"h-48 bg-gray-100 rounded-2xl animate-pulse"}],"children":[["$","$L5",null,{"moduleIds":["app/mana-tracker/page.tsx -> @/components/mana-tracker/PushNotificationManager"]}],"$L7"]}]]}],["$","$L8",null,{}]]}],null],null],null]},[null,["$","$L9",null,{"parallelRouterKey":"children","segmentPath":["children","mana-tracker","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$La",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/37740839d02c8860.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"fr","suppressHydrationWarning":true,"children":[["$","head",null,{"children":[["$","link",null,{"rel":"icon","href":"/logo-relais-marama.svg","type":"image/svg+xml"}],["$","link",null,{"rel":"apple-touch-icon","href":"/logo-relais-marama.svg"}]]}],["$","body",null,{"className":"__className_f367f3","children":["$","$Lb",null,{"attribute":"class","defaultTheme":"light","enableSystem":true,"disableTransitionOnChange":false,"children":[["$","$L9",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$La",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}],["$","$Lc",null,{}]]}]}]]}]],null],null],["$Ld",null]]]]
e:I[4636,["130","static/chunks/130-fbdba5ec657d70e2.js","876","static/chunks/876-74e3127f7295a7cc.js","347","static/chunks/app/mana-tracker/page-190454f13d1cd3f9.js"],"default"]
f:I[845,["130","static/chunks/130-fbdba5ec657d70e2.js","876","static/chunks/876-74e3127f7295a7cc.js","347","static/chunks/app/mana-tracker/page-190454f13d1cd3f9.js"],"default"]
6:["$","$Le",null,{}]
7:["$","$Lf",null,{}]
d:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Compagnon du lagon - Pension Marama"}],["$","meta","3",{"name":"description","content":"Votre guide numérique pour votre séjour à Fakarava"}],["$","link","4",{"rel":"manifest","href":"/manifest.json","crossOrigin":"use-credentials"}],["$","meta","5",{"name":"apple-mobile-web-app-capable","content":"yes"}],["$","meta","6",{"name":"apple-mobile-web-app-title","content":"Compagnon du lagon - Pension Marama"}],["$","meta","7",{"name":"apple-mobile-web-app-status-bar-style","content":"default"}],["$","meta","8",{"name":"next-size-adjust"}]]
1:null

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"version":1,"files":["../../../../components/mana-tracker/ExcursionBooking.tsx","../../../../components/mana-tracker/PushNotificationManager.tsx","../../../../node_modules/next/dist/client/components/action-async-storage-instance.js","../../../../node_modules/next/dist/client/components/action-async-storage.external.js","../../../../node_modules/next/dist/client/components/async-local-storage.js","../../../../node_modules/next/dist/client/components/request-async-storage-instance.js","../../../../node_modules/next/dist/client/components/request-async-storage.external.js","../../../../node_modules/next/dist/client/components/static-generation-async-storage-instance.js","../../../../node_modules/next/dist/client/components/static-generation-async-storage.external.js","../../../../node_modules/next/dist/compiled/@opentelemetry/api/index.js","../../../../node_modules/next/dist/compiled/@opentelemetry/api/package.json","../../../../node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js","../../../../node_modules/next/dist/server/lib/trace/constants.js","../../../../node_modules/next/dist/server/lib/trace/tracer.js","../../../../node_modules/next/package.json","../../../../package.json","../../../package.json","../../chunks/174.js","../../chunks/180.js","../../chunks/207.js","../../chunks/276.js","../../chunks/341.js","../../chunks/740.js","../../chunks/87.js","../../webpack-runtime.js","page_client-reference-manifest.js"]}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,5 @@
{
"headers": {
"x-next-cache-tags": "_N_T_/layout,_N_T_/offline/layout,_N_T_/offline/page,_N_T_/offline"
}
}

View File

@ -0,0 +1,8 @@
2:I[9673,["130","static/chunks/130-fbdba5ec657d70e2.js","876","static/chunks/876-74e3127f7295a7cc.js","200","static/chunks/app/offline/page-c706c75d3862967d.js"],"default"]
3:I[4707,[],""]
4:I[6423,[],""]
5:I[5495,["185","static/chunks/app/layout-012feff5f2309838.js"],"ThemeProvider"]
6:I[1454,["185","static/chunks/app/layout-012feff5f2309838.js"],"default"]
0:["3c87ZLiEKCTo7fN65B1s7",[[["",{"children":["offline",{"children":["__PAGE__",{}]}]},"$undefined","$undefined",true],["",{"children":["offline",{"children":["__PAGE__",{},[["$L1",["$","div",null,{"className":"min-h-screen bg-background dark:bg-background-dark pb-16","children":[["$","div",null,{"className":"flex flex-col items-center justify-center min-h-[60vh] px-4 text-center","children":[["$","h1",null,{"className":"text-2xl font-bold text-primary mb-4","children":"Mode hors ligne"}],["$","p",null,{"className":"text-gray-600 mb-6","children":"Vous êtes actuellement hors ligne. Certaines fonctionnalités peuvent être limitées."}],["$","p",null,{"className":"text-sm text-gray-500","children":"Les données mises en cache restent disponibles."}]]}],["$","$L2",null,{}]]}],null],null],null]},[null,["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children","offline","children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L4",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","notFoundStyles":"$undefined"}]],null]},[[[["$","link","0",{"rel":"stylesheet","href":"/_next/static/css/37740839d02c8860.css","precedence":"next","crossOrigin":"$undefined"}]],["$","html",null,{"lang":"fr","suppressHydrationWarning":true,"children":[["$","head",null,{"children":[["$","link",null,{"rel":"icon","href":"/logo-relais-marama.svg","type":"image/svg+xml"}],["$","link",null,{"rel":"apple-touch-icon","href":"/logo-relais-marama.svg"}]]}],["$","body",null,{"className":"__className_f367f3","children":["$","$L5",null,{"attribute":"class","defaultTheme":"light","enableSystem":true,"disableTransitionOnChange":false,"children":[["$","$L3",null,{"parallelRouterKey":"children","segmentPath":["children"],"error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L4",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":[["$","title",null,{"children":"404: This page could not be found."}],["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","textAlign":"center","display":"flex","flexDirection":"column","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"children":[["$","style",null,{"dangerouslySetInnerHTML":{"__html":"body{color:#000;background:#fff;margin:0}.next-error-h1{border-right:1px solid rgba(0,0,0,.3)}@media (prefers-color-scheme:dark){body{color:#fff;background:#000}.next-error-h1{border-right:1px solid rgba(255,255,255,.3)}}"}}],["$","h1",null,{"className":"next-error-h1","style":{"display":"inline-block","margin":"0 20px 0 0","padding":"0 23px 0 0","fontSize":24,"fontWeight":500,"verticalAlign":"top","lineHeight":"49px"},"children":"404"}],["$","div",null,{"style":{"display":"inline-block"},"children":["$","h2",null,{"style":{"fontSize":14,"fontWeight":400,"lineHeight":"49px","margin":0},"children":"This page could not be found."}]}]]}]}]],"notFoundStyles":[]}],["$","$L6",null,{}]]}]}]]}]],null],null],["$L7",null]]]]
7:[["$","meta","0",{"name":"viewport","content":"width=device-width, initial-scale=1"}],["$","meta","1",{"charSet":"utf-8"}],["$","title","2",{"children":"Compagnon du lagon - Pension Marama"}],["$","meta","3",{"name":"description","content":"Votre guide numérique pour votre séjour à Fakarava"}],["$","link","4",{"rel":"manifest","href":"/manifest.json","crossOrigin":"use-credentials"}],["$","meta","5",{"name":"apple-mobile-web-app-capable","content":"yes"}],["$","meta","6",{"name":"apple-mobile-web-app-title","content":"Compagnon du lagon - Pension Marama"}],["$","meta","7",{"name":"apple-mobile-web-app-status-bar-style","content":"default"}],["$","meta","8",{"name":"next-size-adjust"}]]
1:null

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"version":1,"files":["../../../../node_modules/next/dist/client/components/action-async-storage-instance.js","../../../../node_modules/next/dist/client/components/action-async-storage.external.js","../../../../node_modules/next/dist/client/components/async-local-storage.js","../../../../node_modules/next/dist/client/components/request-async-storage-instance.js","../../../../node_modules/next/dist/client/components/request-async-storage.external.js","../../../../node_modules/next/dist/client/components/static-generation-async-storage-instance.js","../../../../node_modules/next/dist/client/components/static-generation-async-storage.external.js","../../../../node_modules/next/dist/compiled/@opentelemetry/api/index.js","../../../../node_modules/next/dist/compiled/@opentelemetry/api/package.json","../../../../node_modules/next/dist/compiled/next-server/app-page.runtime.prod.js","../../../../node_modules/next/dist/server/lib/trace/constants.js","../../../../node_modules/next/dist/server/lib/trace/tracer.js","../../../../node_modules/next/package.json","../../../../package.json","../../../package.json","../../chunks/276.js","../../chunks/341.js","../../chunks/740.js","../../chunks/87.js","../../webpack-runtime.js","page_client-reference-manifest.js"]}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
(()=>{var e={};e.id=931,e.ids=[931],e.modules={2934:e=>{"use strict";e.exports=require("next/dist/client/components/action-async-storage.external.js")},4580:e=>{"use strict";e.exports=require("next/dist/client/components/request-async-storage.external.js")},5869:e=>{"use strict";e.exports=require("next/dist/client/components/static-generation-async-storage.external.js")},399:e=>{"use strict";e.exports=require("next/dist/compiled/next-server/app-page.runtime.prod.js")},7954:(e,r,t)=>{"use strict";t.r(r),t.d(r,{GlobalError:()=>o.a,__next_app__:()=>c,originalPathname:()=>m,pages:()=>d,routeModule:()=>p,tree:()=>u}),t(908),t(5481),t(5866);var a=t(3191),n=t(8716),s=t(7922),o=t.n(s),i=t(5231),l={};for(let e in i)0>["default","tree","pages","GlobalError","originalPathname","__next_app__","routeModule"].indexOf(e)&&(l[e]=()=>i[e]);t.d(r,l);let u=["",{children:["__PAGE__",{},{page:[()=>Promise.resolve().then(t.bind(t,908)),"/home/syoul/Ccompagnon Marama/app/page.tsx"]}]},{layout:[()=>Promise.resolve().then(t.bind(t,5481)),"/home/syoul/Ccompagnon Marama/app/layout.tsx"],"not-found":[()=>Promise.resolve().then(t.t.bind(t,5866,23)),"next/dist/client/components/not-found-error"]}],d=["/home/syoul/Ccompagnon Marama/app/page.tsx"],m="/page",c={require:t,loadChunk:()=>Promise.resolve()},p=new a.AppPageRouteModule({definition:{kind:n.x.APP_PAGE,page:"/page",pathname:"/",bundlePath:"",filename:"",appPaths:[]},userland:{loaderTree:u}})},1213:(e,r,t)=>{Promise.resolve().then(t.bind(t,8743))},7274:(e,r,t)=>{Promise.resolve().then(t.bind(t,7904)),Promise.resolve().then(t.bind(t,7459))},9401:(e,r,t)=>{Promise.resolve().then(t.t.bind(t,2994,23)),Promise.resolve().then(t.t.bind(t,6114,23)),Promise.resolve().then(t.t.bind(t,9727,23)),Promise.resolve().then(t.t.bind(t,9671,23)),Promise.resolve().then(t.t.bind(t,1868,23)),Promise.resolve().then(t.t.bind(t,4759,23))},8743:(e,r,t)=>{"use strict";t.r(r),t.d(r,{default:()=>o});var a=t(326),n=t(7577),s=t(5047);function o(){(0,s.useRouter)();let[e,r]=(0,n.useState)(!1);return e?null:a.jsx("div",{className:"flex items-center justify-center min-h-screen bg-background dark:bg-background-dark",children:a.jsx("div",{className:"text-center",children:a.jsx("p",{className:"text-gray-600 dark:text-gray-400",children:"Chargement..."})})})}},7904:(e,r,t)=>{"use strict";function a(){return null}t.d(r,{default:()=>a}),t(7577)},7459:(e,r,t)=>{"use strict";t.d(r,{ThemeProvider:()=>s});var a=t(326),n=t(4831);function s({children:e,...r}){return a.jsx(n.f,{...r,children:e})}},5047:(e,r,t)=>{"use strict";var a=t(7389);t.o(a,"usePathname")&&t.d(r,{usePathname:function(){return a.usePathname}}),t.o(a,"useRouter")&&t.d(r,{useRouter:function(){return a.useRouter}})},5481:(e,r,t)=>{"use strict";t.r(r),t.d(r,{default:()=>d,metadata:()=>u});var a=t(9510),n=t(5384),s=t.n(n);t(7272);var o=t(8570);let i=(0,o.createProxy)(String.raw`/home/syoul/Ccompagnon Marama/components/PWARegister.tsx#default`),l=(0,o.createProxy)(String.raw`/home/syoul/Ccompagnon Marama/components/ThemeProvider.tsx#ThemeProvider`),u={title:"Compagnon du lagon - Pension Marama",description:"Votre guide num\xe9rique pour votre s\xe9jour \xe0 Fakarava",manifest:"/manifest.json",themeColor:"#0E7490",appleWebApp:{capable:!0,statusBarStyle:"default",title:"Compagnon du lagon - Pension Marama"},viewport:{width:"device-width",initialScale:1,maximumScale:1,userScalable:!1}};function d({children:e}){return(0,a.jsxs)("html",{lang:"fr",suppressHydrationWarning:!0,children:[(0,a.jsxs)("head",{children:[a.jsx("link",{rel:"icon",href:"/logo-relais-marama.svg",type:"image/svg+xml"}),a.jsx("link",{rel:"apple-touch-icon",href:"/logo-relais-marama.svg"})]}),a.jsx("body",{className:s().className,children:(0,a.jsxs)(l,{attribute:"class",defaultTheme:"light",enableSystem:!0,disableTransitionOnChange:!1,children:[e,a.jsx(i,{})]})})]})}},908:(e,r,t)=>{"use strict";t.r(r),t.d(r,{default:()=>a});let a=(0,t(8570).createProxy)(String.raw`/home/syoul/Ccompagnon Marama/app/page.tsx#default`)},7272:()=>{}};var r=require("../webpack-runtime.js");r.C(e);var t=e=>r(r.s=e),a=r.X(0,[276,740],()=>t(7954));module.exports=a})();

Some files were not shown because too many files have changed in this diff Show More