RELEASE V0.0.1.2 : Insertion des données de la BDD + Suppression des données mockées
This commit is contained in:
1 parent
3eed2b9cd4
commit
9b7ff6e295
8 files changed
+1372
-757
No files matched your search
@@ -0,0 +1,24 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512" width="512" height="512">
|
||||
<defs>
|
||||
<linearGradient id="sncf-grad" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||
<stop offset="0%" stop-color="#0066a4"/>
|
||||
<stop offset="100%" stop-color="#004b7a"/>
|
||||
</linearGradient>
|
||||
<filter id="shadow" x="-10%" y="-10%" width="120%" height="120%">
|
||||
<feDropShadow dx="0" dy="4" stdDeviation="8" flood-color="#000" flood-opacity="0.2"/>
|
||||
</filter>
|
||||
</defs>
|
||||
<rect width="512" height="512" rx="108" fill="url(#sncf-grad)"/>
|
||||
|
||||
<!-- SNCF Red Badge -->
|
||||
<rect x="80" y="80" width="160" height="70" rx="8" fill="#cd0037" filter="url(#shadow)"/>
|
||||
<text x="160" y="130" fill="#ffffff" font-family="Avenir, sans-serif" font-weight="900" font-size="44" text-anchor="middle" letter-spacing="2">SNCF</text>
|
||||
|
||||
<!-- Train Icon -->
|
||||
<g transform="translate(136, 170)" fill="#ffffff">
|
||||
<path d="M120 0C53.7 0 0 53.7 0 120v100c0 33.1 26.9 60 60 60v20c0 11 9 20 20 20s20-9 20-20v-20h80v20c0 11 9 20 20 20s20-9 20-20v-20c33.1 0 60-26.9 60-60V120C240 53.7 186.3 0 120 0zm-80 60h160v60H40V60zm30 150c-11 0-20-9-20-20s9-20 20-20 20 9 20 20-9 20-20 20zm100 0c-11 0-20-9-20-20s9-20 20-20 20 9 20 20-9 20-20 20z"/>
|
||||
</g>
|
||||
|
||||
<!-- TER ZOU text / Tag -->
|
||||
<text x="256" y="440" fill="#ffffff" font-family="Avenir, sans-serif" font-weight="800" font-size="34" text-anchor="middle" letter-spacing="1">FERROVIA RÉGIONS</text>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.4 KiB |
@@ -0,0 +1,36 @@
|
||||
{
|
||||
"name": "FERROVIA - Sites TER Régionaux",
|
||||
"short_name": "FERROVIA",
|
||||
"description": "Consultez les horaires, l'info trafic et achetez vos billets TER dans toutes les régions de France.",
|
||||
"start_url": "/",
|
||||
"id": "/",
|
||||
"display": "standalone",
|
||||
"background_color": "#ffffff",
|
||||
"theme_color": "#0066a4",
|
||||
"orientation": "portrait-primary",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/icon.svg",
|
||||
"sizes": "any",
|
||||
"type": "image/svg+xml",
|
||||
"purpose": "any maskable"
|
||||
},
|
||||
{
|
||||
"src": "/icon.svg",
|
||||
"sizes": "192x192",
|
||||
"type": "image/svg+xml"
|
||||
},
|
||||
{
|
||||
"src": "/icon.svg",
|
||||
"sizes": "512x512",
|
||||
"type": "image/svg+xml"
|
||||
}
|
||||
],
|
||||
"categories": [
|
||||
"travel",
|
||||
"transportation"
|
||||
],
|
||||
"lang": "fr-FR",
|
||||
"dir": "ltr",
|
||||
"prefer_related_applications": false
|
||||
}
|
||||
@@ -0,0 +1,48 @@
|
||||
const CACHE_NAME = 'ferrovia-pwa-v2';
|
||||
|
||||
self.addEventListener('install', (event) => {
|
||||
self.skipWaiting();
|
||||
});
|
||||
|
||||
self.addEventListener('activate', (event) => {
|
||||
event.waitUntil(
|
||||
caches.keys().then((keys) => {
|
||||
return Promise.all(
|
||||
keys.map((key) => {
|
||||
if (key !== CACHE_NAME) {
|
||||
return caches.delete(key);
|
||||
}
|
||||
})
|
||||
);
|
||||
}).then(() => self.clients.claim())
|
||||
);
|
||||
});
|
||||
|
||||
// Network-First strategy: Always try network first to guarantee live updates
|
||||
self.addEventListener('fetch', (event) => {
|
||||
if (event.request.method !== 'GET') return;
|
||||
|
||||
const url = new URL(event.request.url);
|
||||
|
||||
// Do not cache API or Supabase requests
|
||||
if (url.pathname.startsWith('/api') || url.hostname.includes('supabase')) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.respondWith(
|
||||
fetch(event.request)
|
||||
.then((networkResponse) => {
|
||||
if (networkResponse && networkResponse.status === 200 && networkResponse.type === 'basic') {
|
||||
const responseToCache = networkResponse.clone();
|
||||
caches.open(CACHE_NAME).then((cache) => {
|
||||
cache.put(event.request, responseToCache);
|
||||
});
|
||||
}
|
||||
return networkResponse;
|
||||
})
|
||||
.catch(() => {
|
||||
return caches.match(event.request);
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React from 'react';
|
||||
import { supabase } from '@/lib/supabase';
|
||||
import RegionContent from '@/components/RegionContent';
|
||||
import RegionContent, { InfoTraficItem, ActualiteItem, HoraireItem } from '@/components/RegionContent';
|
||||
|
||||
interface RegionData {
|
||||
nom_site: string;
|
||||
@@ -8,12 +8,8 @@ interface RegionData {
|
||||
description_site: string;
|
||||
}
|
||||
|
||||
interface GeneralParams {
|
||||
region: string;
|
||||
regions: Record<string, RegionData>;
|
||||
}
|
||||
|
||||
export const revalidate = 60; // Revalidate every 60s
|
||||
export const dynamic = 'force-dynamic';
|
||||
export const revalidate = 0;
|
||||
|
||||
export default async function RegionPage({
|
||||
params,
|
||||
@@ -22,7 +18,8 @@ export default async function RegionPage({
|
||||
}) {
|
||||
const { region } = await params;
|
||||
|
||||
const { data, error } = await supabase
|
||||
// 1. Fetch general settings
|
||||
const { data } = await supabase
|
||||
.from('parametres')
|
||||
.select('valeur')
|
||||
.eq('cle', 'general')
|
||||
@@ -69,5 +66,79 @@ export default async function RegionPage({
|
||||
};
|
||||
}
|
||||
|
||||
return <RegionContent regionSlug={region} regionData={regionData} />;
|
||||
// 2. Fetch info trafic from Supabase table "info_trafic"
|
||||
let infoTraficList: InfoTraficItem[] = [];
|
||||
try {
|
||||
const { data: trafficData } = await supabase
|
||||
.from('info_trafic')
|
||||
.select('*')
|
||||
.eq('actif', true)
|
||||
.is('deleted_at', null)
|
||||
.order('created_at', { ascending: false });
|
||||
if (trafficData) {
|
||||
infoTraficList = trafficData as InfoTraficItem[];
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Error fetching info_trafic:', e);
|
||||
}
|
||||
|
||||
// 3. Fetch actualites from Supabase table "actualites"
|
||||
let actualitesList: ActualiteItem[] = [];
|
||||
try {
|
||||
const { data: actusData } = await supabase
|
||||
.from('actualites')
|
||||
.select('*')
|
||||
.eq('actif', true)
|
||||
.is('deleted_at', null)
|
||||
.order('date_publication', { ascending: false })
|
||||
.order('created_at', { ascending: false });
|
||||
if (actusData) {
|
||||
actualitesList = actusData as ActualiteItem[];
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Error fetching actualites:', e);
|
||||
}
|
||||
|
||||
// 4. Fetch gares and horaires from Supabase table "horaires"
|
||||
let horairesList: HoraireItem[] = [];
|
||||
try {
|
||||
const { data: garesData } = await supabase
|
||||
.from('gares')
|
||||
.select('id, nom');
|
||||
|
||||
const garesMap: Record<string, string> = {};
|
||||
if (garesData) {
|
||||
garesData.forEach((g: any) => {
|
||||
garesMap[g.id] = g.nom;
|
||||
});
|
||||
}
|
||||
|
||||
const { data: rawHoraires } = await supabase
|
||||
.from('horaires')
|
||||
.select('*')
|
||||
.eq('actif', true)
|
||||
.is('deleted_at', null)
|
||||
.order('heure_depart', { ascending: true });
|
||||
|
||||
if (rawHoraires) {
|
||||
horairesList = rawHoraires.map((h: any) => ({
|
||||
...h,
|
||||
gare_depart_nom: garesMap[h.gare_depart_id] || '',
|
||||
gare_arrivee_nom: garesMap[h.gare_arrivee_id] || '',
|
||||
})) as HoraireItem[];
|
||||
}
|
||||
} catch (e) {
|
||||
console.error('Error fetching horaires:', e);
|
||||
}
|
||||
|
||||
return (
|
||||
<RegionContent
|
||||
regionSlug={region}
|
||||
regionData={regionData}
|
||||
initialInfoTrafic={infoTraficList}
|
||||
initialActualites={actualitesList}
|
||||
initialHoraires={horairesList}
|
||||
/>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -145,3 +145,27 @@ body {
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
}
|
||||
|
||||
@keyframes fadeIn {
|
||||
from { opacity: 0; }
|
||||
to { opacity: 1; }
|
||||
}
|
||||
|
||||
@keyframes slideInLeftDrawer {
|
||||
from {
|
||||
transform: translateX(-100%);
|
||||
}
|
||||
to {
|
||||
transform: translateX(0);
|
||||
}
|
||||
}
|
||||
|
||||
.animate-fadeIn {
|
||||
animation: fadeIn 0.2s ease-out forwards;
|
||||
}
|
||||
|
||||
.animate-slideInLeftDrawer {
|
||||
animation: slideInLeftDrawer 0.28s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
||||
}
|
||||
|
||||
|
||||
+51
-10
@@ -1,6 +1,7 @@
|
||||
import type { Metadata } from "next";
|
||||
import type { Metadata, Viewport } from "next";
|
||||
import { Geist, Geist_Mono } from "next/font/google";
|
||||
import "./globals.css";
|
||||
|
||||
const geistSans = Geist({
|
||||
variable: "--font-geist-sans",
|
||||
subsets: ["latin"],
|
||||
@@ -12,20 +13,60 @@ const geistMono = Geist_Mono({
|
||||
});
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Create Next App",
|
||||
description: "Generated by create next app",
|
||||
title: "FERROVIA - Sites TER Régionaux",
|
||||
description: "Consultez les horaires, l'info trafic et achetez vos billets TER dans toutes les régions de France.",
|
||||
manifest: "/manifest.json",
|
||||
appleWebApp: {
|
||||
capable: true,
|
||||
statusBarStyle: "default",
|
||||
title: "FERROVIA",
|
||||
},
|
||||
icons: {
|
||||
icon: "/icon.svg",
|
||||
apple: "/icon.svg",
|
||||
},
|
||||
};
|
||||
export default function RootLayout({ children }: { children: React.ReactNode })
|
||||
{
|
||||
return (
|
||||
|
||||
export const viewport: Viewport = {
|
||||
themeColor: "#0066a4",
|
||||
width: "device-width",
|
||||
initialScale: 1,
|
||||
maximumScale: 1,
|
||||
userScalable: false,
|
||||
viewportFit: "cover",
|
||||
};
|
||||
|
||||
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
||||
return (
|
||||
<html
|
||||
lang="en"
|
||||
lang="fr"
|
||||
className={`${geistSans.variable} ${geistMono.variable} h-full antialiased`}
|
||||
>
|
||||
<body className="sncf-voyageurs">{children}
|
||||
|
||||
|
||||
<head>
|
||||
<link rel="manifest" href="/manifest.json" />
|
||||
<meta name="mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
|
||||
<meta name="apple-mobile-web-app-title" content="FERROVIA" />
|
||||
<link rel="apple-touch-icon" href="/icon.svg" />
|
||||
</head>
|
||||
<body className="sncf-voyageurs min-h-full">
|
||||
{children}
|
||||
<script
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: `
|
||||
if ('serviceWorker' in navigator) {
|
||||
window.addEventListener('load', function() {
|
||||
navigator.serviceWorker.register('/sw.js').then(function(reg) {
|
||||
reg.update();
|
||||
}).catch(function(err) {
|
||||
console.log('ServiceWorker registration failed: ', err);
|
||||
});
|
||||
});
|
||||
}
|
||||
`,
|
||||
}}
|
||||
/>
|
||||
</body>
|
||||
</html>
|
||||
);
|
||||
|
||||
+11
-18
@@ -1,31 +1,24 @@
|
||||
import React from 'react';
|
||||
import { redirect } from 'next/navigation';
|
||||
import { supabase } from '@/lib/supabase';
|
||||
import HomeContent from '@/components/HomeContent';
|
||||
|
||||
interface RegionData {
|
||||
nom_site: string;
|
||||
logo_header_url: string;
|
||||
description_site: string;
|
||||
}
|
||||
|
||||
interface GeneralParams {
|
||||
region: string;
|
||||
regions: Record<string, RegionData>;
|
||||
}
|
||||
|
||||
export const revalidate = 60; // Revalidate every 60s
|
||||
export const dynamic = 'force-dynamic';
|
||||
export const revalidate = 0;
|
||||
|
||||
export default async function HomePage() {
|
||||
const { data, error } = await supabase
|
||||
const { data } = await supabase
|
||||
.from('parametres')
|
||||
.select('valeur')
|
||||
.eq('cle', 'general')
|
||||
.single();
|
||||
|
||||
let general: GeneralParams | null = null;
|
||||
let targetRegion = 'bourgogne-franche-comte';
|
||||
if (data && data.valeur) {
|
||||
general = data.valeur as GeneralParams;
|
||||
const val = data.valeur as any;
|
||||
if (val.region) {
|
||||
targetRegion = val.region;
|
||||
}
|
||||
}
|
||||
|
||||
return <HomeContent general={general} />;
|
||||
redirect(`/${targetRegion}`);
|
||||
}
|
||||
|
||||
+1098
-720
File diff suppressed because it is too large.
Load diff
Reference in new issue
Block a user