Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions frontend/Front.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -930,7 +930,7 @@ export default function PickupDeliveryUI() {
};

return (
<div className="h-screen bg-gray-800 text-white flex flex-col overflow-hidden">
<div className="h-screen bg-[#0c111d] text-slate-100 flex flex-col overflow-hidden font-sans antialiased">
{/* Navigation Bar avec titre intégré */}
<div className={isMapSelectionActive ? 'pointer-events-none opacity-50' : ''}>
<Navigation
Expand All @@ -954,11 +954,11 @@ export default function PickupDeliveryUI() {
<main className="flex-1 flex flex-col min-h-0 overflow-hidden">
{/* Home View */}
{activeTab === 'home' && !showMapUpload && (
<div className="p-8 mt-20">
<h2 className="text-3xl font-bold text-center">
Bienvenue sur votre plateforme de gestion de tournées de livraison à vélo !
<div className="p-8 mt-20 text-center space-y-3">
<h2 className="text-3xl md:text-4xl font-semibold tracking-tight leading-tight text-slate-50">
Bienvenue sur votre plateforme de gestion de tournées de livraison à vélo
</h2>
<p className="text-center text-gray-300 mt-4">
<p className="text-lg text-slate-300 leading-relaxed">
Cliquez sur l'icône de localisation pour charger une carte.
</p>
</div>
Expand Down Expand Up @@ -1016,7 +1016,7 @@ export default function PickupDeliveryUI() {
{/* Ligne principale : Carte + Panneau d'informations */}
<div className="flex-1 flex gap-4 min-h-0">
{/* Carte sur la gauche - plus grande */}
<div className="w-2/3 flex flex-col bg-gray-700 rounded-lg overflow-hidden min-w-0">
<div className="w-2/3 flex flex-col bg-slate-900/70 border border-slate-800 rounded-xl overflow-hidden min-w-0 shadow-[0_10px_40px_rgba(0,0,0,0.35)] backdrop-blur-sm">
<MapViewer
mapData={mapData}
onClearMap={handleClearMap}
Expand All @@ -1033,8 +1033,8 @@ export default function PickupDeliveryUI() {
{/* Panneau droit avec informations et boutons */}
<div className={`flex-1 flex flex-col gap-4 min-h-0 min-w-0 ${isMapSelectionActive ? 'pointer-events-none opacity-50' : ''}`}>
{/* Tableau de tournée ou onglets multi-tours */}
<div className="bg-gray-700 rounded-lg p-6 flex flex-col flex-1 min-h-0 min-w-0 overflow-hidden">
<h3 className="text-xl font-semibold mb-4 flex-shrink-0">
<div className="bg-slate-900/70 border border-slate-800 rounded-xl p-6 flex flex-col flex-1 min-h-0 min-w-0 overflow-hidden shadow-[0_10px_40px_rgba(0,0,0,0.35)] backdrop-blur-sm">
<h3 className="panel-title mb-4 flex-shrink-0 tracking-tight">
{tourData ? (Array.isArray(tourData) && tourData.length > 1 ? 'Tournées Multi-Coursiers' : 'Tournée Calculée') : 'Informations'}
</h3>
<div className="flex-1 overflow-auto min-h-0">
Expand Down Expand Up @@ -1118,7 +1118,7 @@ export default function PickupDeliveryUI() {
</div>

{/* Boutons d'action */}
<div className="bg-gray-700 rounded-lg p-4 flex-shrink-0">
<div className="bg-slate-900/70 border border-slate-800 rounded-xl p-4 flex-shrink-0 shadow-[0_10px_40px_rgba(0,0,0,0.35)] backdrop-blur-sm">
{!tourData ? (
// Avant calcul de tournée : Sélecteur + Boutons
<div className="flex flex-col gap-4">
Expand Down
17 changes: 17 additions & 0 deletions frontend/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,23 @@
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Pickup & Delivery</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
<link
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&display=swap"
rel="stylesheet"
/>
<script>
tailwind.config = {
theme: {
extend: {
fontFamily: {
sans: ['Inter', 'SF Pro Display', 'Segoe UI', 'system-ui', 'sans-serif'],
},
},
},
};
</script>
<script src="https://cdn.tailwindcss.com"></script>
</head>
<body>
Expand Down
1 change: 1 addition & 0 deletions frontend/main.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React from 'react'
import ReactDOM from 'react-dom/client'
import PickupDeliveryUI from './Front.jsx'
import './src/styles/typography.css'

ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
Expand Down
52 changes: 36 additions & 16 deletions frontend/src/components/Navigation.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,33 +7,45 @@ import Icon from './Icon';
*/
export default function Navigation({ activeTab, onTabChange, showMapMessage, hasMap, onLoadDeliveryRequests, onRestoreTour }) {
return (
<nav className="bg-gray-700 border-b border-gray-600">
<div className="flex items-center justify-between px-6">
<nav className="bg-slate-950/80 border-b border-slate-800 backdrop-blur">
<div className="flex items-center justify-between px-6 py-3">
{/* Titre de l'application à gauche */}
<div className="flex items-center gap-3">
<Icon name="bike" className="text-3xl text-white" />
<Icon name="bike" className="text-3xl text-slate-100" />
<div>
<h1 className="text-xl font-bold">Pickup & Delivery</h1>
<p className="text-sm text-gray-300">Optimisation des tournées de livraison à vélo</p>
<h1 className="text-2xl font-semibold tracking-tight leading-tight text-slate-50">
Pickup & Delivery
</h1>
<p className="text-sm text-slate-300 leading-snug">
Optimisation des tournées de livraison à vélo
</p>
</div>
</div>

{/* Boutons de navigation à droite */}
<div className="flex">
{/* Home Icon */}
<button
className={`p-6 hover:bg-gray-600 transition-colors cursor-pointer ${activeTab === 'home' ? 'bg-gray-500' : ''}`}
onClick={() => onTabChange('home')}
>
<Home size={32} className="text-white" />
</button>
className={`p-4 rounded-xl transition-all duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500/70 focus-visible:ring-offset-2 focus-visible:ring-offset-slate-900 ${
activeTab === 'home'
? 'bg-slate-800 text-slate-50 shadow-lg shadow-black/30'
: 'text-slate-300 hover:bg-slate-800/70 hover:text-slate-50'
}`}
onClick={() => onTabChange('home')}
>
<Home size={28} className="text-current" />
</button>

{/* Map Pin Icon */}
<button
className={`p-6 relative cursor-pointer ${activeTab === 'map' ? 'bg-gray-500' : 'hover:bg-gray-600'} transition-colors`}
className={`p-4 rounded-xl relative transition-all duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500/70 focus-visible:ring-offset-2 focus-visible:ring-offset-slate-900 ${
activeTab === 'map'
? 'bg-slate-800 text-slate-50 shadow-lg shadow-black/30'
: 'text-slate-300 hover:bg-slate-800/70 hover:text-slate-50'
}`}
onClick={() => onTabChange('map')}
>
<MapPin size={32} className={`${!hasMap && activeTab === 'map' ? 'text-yellow-400 fill-yellow-400' : 'text-white'}`} />
<MapPin size={28} className={`${!hasMap && activeTab === 'map' ? 'text-yellow-400 fill-yellow-400' : 'text-current'}`} />
{showMapMessage && (
<div className="absolute top-16 left-1/2 -translate-x-1/2 bg-yellow-400 text-gray-800 px-4 py-3 rounded-2xl shadow-lg whitespace-nowrap pointer-events-none">
<div className="text-sm font-semibold text-center leading-tight">
Expand All @@ -46,11 +58,15 @@ export default function Navigation({ activeTab, onTabChange, showMapMessage, has

{/* Bike Icon - Charger demandes XML */}
<button
className={`p-6 relative hover:bg-gray-600 transition-colors cursor-pointer ${activeTab === 'deliveries' ? 'bg-gray-500' : ''}`}
className={`p-4 rounded-xl relative transition-all duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500/70 focus-visible:ring-offset-2 focus-visible:ring-offset-slate-900 ${
activeTab === 'deliveries'
? 'bg-slate-800 text-slate-50 shadow-lg shadow-black/30'
: 'text-slate-300 hover:bg-slate-800/70 hover:text-slate-50'
}`}
onClick={() => hasMap ? onLoadDeliveryRequests() : alert('Veuillez d\'abord charger une carte')}
title={hasMap ? "Charger un fichier de demandes XML" : "Chargez d'abord une carte"}
>
<Bike size={32} className={`${hasMap ? 'text-yellow-400' : 'text-gray-500'}`} />
<Bike size={28} className={`${hasMap ? 'text-yellow-400' : 'text-current'}`} />
{hasMap && (
<div className="absolute -bottom-1 left-1/2 -translate-x-1/2 bg-yellow-400 text-gray-900 px-2 py-0.5 rounded text-xs font-bold pointer-events-none">
XML
Expand All @@ -60,11 +76,15 @@ export default function Navigation({ activeTab, onTabChange, showMapMessage, has

{/* Route Icon - Restaurer tournée */}
<button
className={`p-6 relative hover:bg-gray-600 transition-colors cursor-pointer ${activeTab === 'tours' ? 'bg-gray-500' : ''}`}
className={`p-4 rounded-xl relative transition-all duration-200 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-indigo-500/70 focus-visible:ring-offset-2 focus-visible:ring-offset-slate-900 ${
activeTab === 'tours'
? 'bg-slate-800 text-slate-50 shadow-lg shadow-black/30'
: 'text-slate-300 hover:bg-slate-800/70 hover:text-slate-50'
}`}
onClick={() => hasMap ? onRestoreTour() : alert('Veuillez d\'abord charger une carte')}
title={hasMap ? "Restaurer une tournée depuis un fichier JSON" : "Chargez d'abord une carte"}
>
<Route size={32} className={`${hasMap ? 'text-yellow-400' : 'text-gray-500'}`} />
<Route size={28} className={`${hasMap ? 'text-yellow-400' : 'text-current'}`} />
{hasMap && (
<div className="absolute -bottom-1 left-1/2 -translate-x-1/2 bg-yellow-400 text-gray-900 px-2 py-0.5 rounded text-xs font-bold pointer-events-none">
JSON
Expand Down
94 changes: 94 additions & 0 deletions frontend/src/styles/typography.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
:root {
--font-sans: 'Inter', 'SF Pro Display', 'Segoe UI', system-ui, -apple-system, sans-serif;
--bg-body: #0c111d;
--text-strong: #e8edf5;
--text-soft: #cdd5e5;
--text-muted: #94a3b8;
--accent: #6366f1;
--accent-strong: #7c3aed;
}

* {
box-sizing: border-box;
}

body {
margin: 0;
font-family: var(--font-sans);
color: var(--text-soft);
background-color: var(--bg-body);
line-height: 1.6;
letter-spacing: 0.01em;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
font-feature-settings: "liga" 1, "calt" 1;
}

h1,
h2,
h3,
h4,
h5,
h6 {
font-family: var(--font-sans);
color: var(--text-strong);
letter-spacing: -0.015em;
line-height: 1.25;
}

p,
span,
label,
input,
textarea,
button {
font-family: var(--font-sans);
}

p {
color: var(--text-soft);
}

small,
.text-muted {
color: var(--text-muted);
}

a {
color: var(--accent);
text-decoration: none;
transition: color 0.15s ease;
}

a:hover {
color: var(--accent-strong);
}

.helper-eyebrow {
text-transform: uppercase;
letter-spacing: 0.08em;
font-weight: 600;
font-size: 0.75rem;
color: var(--text-muted);
}

.section-title {
font-size: 1.5rem;
font-weight: 700;
letter-spacing: -0.02em;
color: var(--text-strong);
}

.panel-title {
font-size: 1.125rem;
font-weight: 700;
letter-spacing: -0.015em;
color: var(--text-strong);
}

.lead {
font-size: 1.05rem;
color: var(--text-soft);
letter-spacing: 0.005em;
}