chore: update

This commit is contained in:
2026-03-30 20:02:39 +02:00
parent 32e129da31
commit 25cd6429f2
32 changed files with 1024 additions and 540 deletions
+3
View File
@@ -1,5 +1,6 @@
import { BrowserRouter as Router, Routes, Route } from "react-router-dom"; import { BrowserRouter as Router, Routes, Route } from "react-router-dom";
import { CartProvider } from "./context/CartContext"; import { CartProvider } from "./context/CartContext";
import { ThemeProvider } from "./context/ThemeContext";
import "./App.css"; import "./App.css";
// Pages principales // Pages principales
@@ -21,6 +22,7 @@ import ChangePasswordPage from "./pages/ChangePassword/ChangePassword";
function App() { function App() {
return ( return (
<ThemeProvider>
<Router> <Router>
<Routes> <Routes>
{/* Routes Login - SANS CartProvider */} {/* Routes Login - SANS CartProvider */}
@@ -87,6 +89,7 @@ function App() {
/> />
</Routes> </Routes>
</Router> </Router>
</ThemeProvider>
); );
} }
+49
View File
@@ -1858,6 +1858,7 @@ export interface PublicSettings {
points_enabled: boolean; points_enabled: boolean;
points_separated: boolean; points_separated: boolean;
referral_enabled: boolean; referral_enabled: boolean;
referral_amount: number;
pool_names: string[]; pool_names: string[];
crypto_payment_enabled: boolean; crypto_payment_enabled: boolean;
crypto_only: boolean; crypto_only: boolean;
@@ -1871,6 +1872,7 @@ export const getPublicSettings = async (): Promise<PublicSettings> => {
points_enabled: true, points_enabled: true,
points_separated: true, points_separated: true,
referral_enabled: true, referral_enabled: true,
referral_amount: 0,
pool_names: ["Pool 1", "Pool 2"], pool_names: ["Pool 1", "Pool 2"],
crypto_payment_enabled: false, crypto_payment_enabled: false,
crypto_only: false, crypto_only: false,
@@ -1886,6 +1888,7 @@ export const getPublicSettings = async (): Promise<PublicSettings> => {
points_enabled: data.points_enabled ?? true, points_enabled: data.points_enabled ?? true,
points_separated: data.points_separated ?? true, points_separated: data.points_separated ?? true,
referral_enabled: data.referral_enabled ?? true, referral_enabled: data.referral_enabled ?? true,
referral_amount: data.referral_amount ?? 0,
pool_names: pool_names:
Array.isArray(data.pool_names) && data.pool_names.length > 0 Array.isArray(data.pool_names) && data.pool_names.length > 0
? data.pool_names ? data.pool_names
@@ -1903,6 +1906,7 @@ export const getPublicSettings = async (): Promise<PublicSettings> => {
export interface CryptoPaymentStatus { export interface CryptoPaymentStatus {
command_id: number; command_id: number;
client_order_number?: number;
payment_status: string; payment_status: string;
pay_address: string; pay_address: string;
pay_amount: number; pay_amount: number;
@@ -2001,3 +2005,48 @@ export const updateMyProfile = async (fields: {
return { success: false, message: "Erreur de connexion" }; return { success: false, message: "Erreur de connexion" };
} }
}; };
// ============================================
// 🤖 TELEGRAM
// ============================================
export const getTelegramStatus = async (): Promise<{ linked: boolean; enabled: boolean }> => {
const token = getAuthToken();
if (!token) return { linked: false, enabled: false };
try {
const response = await fetch(`${API_URL}/telegram/status`, {
headers: { Authorization: `Bearer ${token}` },
});
return await safeJson(response);
} catch {
return { linked: false, enabled: false };
}
};
export const generateTelegramLinkToken = async (): Promise<{
link_url?: string;
error?: string;
}> => {
const token = getAuthToken();
if (!token) return { error: "Non authentifié" };
try {
const response = await fetch(`${API_URL}/telegram/link-token`, {
method: "POST",
headers: { Authorization: `Bearer ${token}` },
});
return await safeJson(response);
} catch {
return { error: "Erreur de connexion" };
}
};
export const unlinkTelegram = async (): Promise<void> => {
const token = getAuthToken();
if (!token) return;
try {
await fetch(`${API_URL}/telegram/unlink`, {
method: "DELETE",
headers: { Authorization: `Bearer ${token}` },
});
} catch { /* silencieux */ }
};
+4
View File
@@ -227,6 +227,8 @@ export interface OrderItem {
*/ */
export interface OrderDetail { export interface OrderDetail {
id: number; id: number;
client_order_number?: number;
client_order_id?: number;
username: string; username: string;
status: string; status: string;
delivery_address?: string; delivery_address?: string;
@@ -565,6 +567,8 @@ export interface CheckoutFormState {
export interface CompletedOrder { export interface CompletedOrder {
id: number; id: number;
client_order_number?: number;
client_order_id?: number;
username: string; username: string;
status: string; status: string;
adresse: string; adresse: string;
+30 -30
View File
@@ -30,8 +30,8 @@
/* Modal Content */ /* Modal Content */
.items-modal-content { .items-modal-content {
background: linear-gradient(to bottom, #1a1a1a, #0f0f0f); background: linear-gradient(to bottom, var(--surface), var(--bg));
border: 1px solid rgba(255, 255, 255, 0.1); border: 1px solid var(--border);
border-radius: 16px; border-radius: 16px;
max-width: 800px; max-width: 800px;
width: 100%; width: 100%;
@@ -62,8 +62,8 @@
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
padding: 1.5rem 2rem; padding: 1.5rem 2rem;
border-bottom: 1px solid rgba(255, 255, 255, 0.08); border-bottom: 1px solid var(--border);
background: rgba(255, 255, 255, 0.02); background: var(--surface-2);
flex-shrink: 0; flex-shrink: 0;
} }
@@ -71,7 +71,7 @@
display: flex; display: flex;
align-items: center; align-items: center;
gap: 0.75rem; gap: 0.75rem;
color: #ffffff; color: var(--text);
font-size: 1.25rem; font-size: 1.25rem;
margin: 0; margin: 0;
font-weight: 600; font-weight: 600;
@@ -102,7 +102,7 @@
.items-modal-close { .items-modal-close {
background: transparent; background: transparent;
border: none; border: none;
color: #6b7280; color: var(--text-muted);
width: 36px; width: 36px;
height: 36px; height: 36px;
border-radius: 8px; border-radius: 8px;
@@ -117,8 +117,8 @@
} }
.items-modal-close:hover { .items-modal-close:hover {
background: rgba(255, 255, 255, 0.05); background: var(--surface-2);
color: #ffffff; color: var(--text);
} }
/* Body */ /* Body */
@@ -126,7 +126,7 @@
padding: 2rem; padding: 2rem;
overflow-y: auto; overflow-y: auto;
flex: 1; flex: 1;
background: #0a0a0a; background: var(--bg);
} }
.items-modal-body::-webkit-scrollbar { .items-modal-body::-webkit-scrollbar {
@@ -153,19 +153,19 @@
align-items: center; align-items: center;
justify-content: center; justify-content: center;
padding: 4rem 2rem; padding: 4rem 2rem;
color: #6b7280; color: var(--text-muted);
gap: 1rem; gap: 1rem;
} }
.items-modal-empty svg { .items-modal-empty svg {
color: #374151; color: var(--text-muted);
opacity: 0.5; opacity: 0.5;
} }
.items-modal-empty p { .items-modal-empty p {
font-size: 1rem; font-size: 1rem;
margin: 0; margin: 0;
color: #9ca3af; color: var(--text-muted);
} }
/* Summary */ /* Summary */
@@ -181,14 +181,14 @@
flex-direction: column; flex-direction: column;
gap: 0.5rem; gap: 0.5rem;
padding: 1.25rem; padding: 1.25rem;
background: rgba(255, 255, 255, 0.03); background: var(--surface);
border: 1px solid rgba(255, 255, 255, 0.08); border: 1px solid var(--border);
border-radius: 12px; border-radius: 12px;
transition: all 0.2s ease; transition: all 0.2s ease;
} }
.summary-item:hover { .summary-item:hover {
background: rgba(255, 255, 255, 0.05); background: var(--surface-2);
border-color: rgba(124, 58, 237, 0.3); border-color: rgba(124, 58, 237, 0.3);
} }
@@ -199,7 +199,7 @@
} }
.summary-item span { .summary-item span {
color: #ffffff; color: var(--text);
font-weight: 600; font-weight: 600;
font-size: 1.5rem; font-size: 1.5rem;
line-height: 1; line-height: 1;
@@ -207,7 +207,7 @@
.summary-item::before { .summary-item::before {
content: attr(data-label); content: attr(data-label);
color: #9ca3af; color: var(--text-muted);
font-size: 0.875rem; font-size: 0.875rem;
font-weight: 500; font-weight: 500;
text-transform: uppercase; text-transform: uppercase;
@@ -224,8 +224,8 @@
/* Item Card */ /* Item Card */
.items-modal-card { .items-modal-card {
background: rgba(255, 255, 255, 0.03); background: var(--surface);
border: 1px solid rgba(255, 255, 255, 0.08); border: 1px solid var(--border);
border-radius: 12px; border-radius: 12px;
padding: 1.5rem; padding: 1.5rem;
transition: all 0.2s ease; transition: all 0.2s ease;
@@ -234,7 +234,7 @@
} }
.items-modal-card:hover { .items-modal-card:hover {
background: rgba(255, 255, 255, 0.05); background: var(--surface-2);
border-color: rgba(124, 58, 237, 0.4); border-color: rgba(124, 58, 237, 0.4);
box-shadow: 0 8px 24px rgba(124, 58, 237, 0.15); box-shadow: 0 8px 24px rgba(124, 58, 237, 0.15);
} }
@@ -271,7 +271,7 @@
} }
.item-name { .item-name {
color: #f9fafb; color: var(--text);
font-size: 1rem; font-size: 1rem;
font-weight: 600; font-weight: 600;
line-height: 1.5; line-height: 1.5;
@@ -325,7 +325,7 @@
} }
.detail-label { .detail-label {
color: #9ca3af; color: var(--text-muted);
font-size: 0.8125rem; font-size: 0.8125rem;
font-weight: 500; font-weight: 500;
text-transform: uppercase; text-transform: uppercase;
@@ -333,7 +333,7 @@
} }
.detail-value { .detail-value {
color: #f9fafb; color: var(--text);
font-size: 1.125rem; font-size: 1.125rem;
font-weight: 600; font-weight: 600;
} }
@@ -350,11 +350,11 @@
gap: 0.75rem; gap: 0.75rem;
padding-top: 0.75rem; padding-top: 0.75rem;
margin-top: 0.75rem; margin-top: 0.75rem;
border-top: 1px solid rgba(255, 255, 255, 0.05); border-top: 1px solid var(--border);
} }
.item-id { .item-id {
color: #6b7280; color: var(--text-muted);
font-size: 0.8125rem; font-size: 0.8125rem;
font-family: 'SF Mono', 'Monaco', 'Courier New', monospace; font-family: 'SF Mono', 'Monaco', 'Courier New', monospace;
} }
@@ -372,7 +372,7 @@
} }
.items-modal-total span { .items-modal-total span {
color: #9ca3af; color: var(--text-muted);
font-size: 0.875rem; font-size: 0.875rem;
font-weight: 500; font-weight: 500;
text-transform: uppercase; text-transform: uppercase;
@@ -525,13 +525,13 @@
/* Touch Devices */ /* Touch Devices */
@media (hover: none) { @media (hover: none) {
.items-modal-card:hover { .items-modal-card:hover {
background: rgba(255, 255, 255, 0.03); background: var(--surface);
border-color: rgba(255, 255, 255, 0.08); border-color: var(--border);
box-shadow: none; box-shadow: none;
} }
.summary-item:hover { .summary-item:hover {
background: rgba(255, 255, 255, 0.03); background: var(--surface);
border-color: rgba(255, 255, 255, 0.08); border-color: var(--border);
} }
} }
+47 -2
View File
@@ -20,6 +20,24 @@
--transition: 0.22s cubic-bezier(0.4, 0, 0.2, 1); --transition: 0.22s cubic-bezier(0.4, 0, 0.2, 1);
} }
/* ============================================================
Light theme overrides
============================================================ */
[data-theme="light"] {
--bg: #f4f4f8;
--surface: #ffffff;
--surface-2: #ebebf2;
--border: rgba(0, 0, 0, 0.08);
--primary: #7c3aed;
--primary-soft: rgba(124, 58, 237, 0.08);
--primary-glow: rgba(124, 58, 237, 0.18);
--cyan: #0891b2;
--cyan-soft: rgba(8, 145, 178, 0.1);
--red: #dc2626;
--text: #18181b;
--text-muted: #52525b;
}
/* ============================================================ /* ============================================================
Body offset Body offset
============================================================ */ ============================================================ */
@@ -41,11 +59,11 @@ body {
align-items: center; align-items: center;
padding: 0 0.75rem; padding: 0 0.75rem;
gap: 0.5rem; gap: 0.5rem;
background: rgba(9, 9, 11, 0.92); background: color-mix(in srgb, var(--bg) 92%, transparent);
backdrop-filter: blur(20px); backdrop-filter: blur(20px);
-webkit-backdrop-filter: blur(20px); -webkit-backdrop-filter: blur(20px);
border-bottom: 1px solid var(--border); border-bottom: 1px solid var(--border);
box-shadow: 0 1px 24px rgba(0, 0, 0, 0.4); box-shadow: 0 1px 24px rgba(0, 0, 0, 0.15);
} }
.topbar-toggle { .topbar-toggle {
@@ -91,6 +109,33 @@ body {
gap: 0.25rem; gap: 0.25rem;
} }
/* ── Theme toggle button ── */
.topbar-theme-btn {
width: 40px;
height: 40px;
display: flex;
align-items: center;
justify-content: center;
background: transparent;
border: 1px solid transparent;
border-radius: var(--radius);
color: var(--text-muted);
font-size: 1rem;
cursor: pointer;
transition: all var(--transition);
-webkit-tap-highlight-color: transparent;
}
.topbar-theme-btn:hover {
background: var(--surface-2);
border-color: var(--border);
color: var(--text);
}
.topbar-theme-btn:active {
transform: scale(0.93);
}
/* ── Icon button (notif / cart) ── */ /* ── Icon button (notif / cart) ── */
.topbar-icon-btn { .topbar-icon-btn {
position: relative; position: relative;
+13
View File
@@ -1,6 +1,7 @@
import { useState, useEffect, useRef, useCallback } from "react"; import { useState, useEffect, useRef, useCallback } from "react";
import { useNavigate, useLocation } from "react-router-dom"; import { useNavigate, useLocation } from "react-router-dom";
import { useCart } from "../context/useCart"; import { useCart } from "../context/useCart";
import { useTheme } from "../context/ThemeContext";
import "./Navbar.css"; import "./Navbar.css";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome"; import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { import {
@@ -15,6 +16,8 @@ import {
faBell, faBell,
faGift, faGift,
faUserCircle, faUserCircle,
faSun,
faMoon,
} from "@fortawesome/free-solid-svg-icons"; } from "@fortawesome/free-solid-svg-icons";
import { faTelegram } from "@fortawesome/free-brands-svg-icons"; import { faTelegram } from "@fortawesome/free-brands-svg-icons";
import type { IconDefinition } from "@fortawesome/fontawesome-svg-core"; import type { IconDefinition } from "@fortawesome/fontawesome-svg-core";
@@ -29,6 +32,7 @@ interface MenuItem {
} }
function Navbar() { function Navbar() {
const { theme, toggleTheme } = useTheme();
const [isMenuOpen, setIsMenuOpen] = useState<boolean>(false); const [isMenuOpen, setIsMenuOpen] = useState<boolean>(false);
const [isLoggingOut, setIsLoggingOut] = useState<boolean>(false); const [isLoggingOut, setIsLoggingOut] = useState<boolean>(false);
const [notifications, setNotifications] = useState<ClientNotification[]>([]); const [notifications, setNotifications] = useState<ClientNotification[]>([]);
@@ -155,6 +159,15 @@ function Navbar() {
<span className="topbar-brand">MilieuNantais</span> <span className="topbar-brand">MilieuNantais</span>
<div className="topbar-actions"> <div className="topbar-actions">
{/* Theme toggle */}
<button
className="topbar-theme-btn"
onClick={toggleTheme}
aria-label={theme === "dark" ? "Passer en mode clair" : "Passer en mode sombre"}
>
<FontAwesomeIcon icon={theme === "dark" ? faSun : faMoon} />
</button>
{/* Notifications */} {/* Notifications */}
<div className="notif-wrapper" ref={notifPanelRef}> <div className="notif-wrapper" ref={notifPanelRef}>
<button <button
+21 -21
View File
@@ -1,5 +1,5 @@
.product-card { .product-card {
background-color: #1a1a1a; background-color: var(--surface);
border: 2px solid var(--category-color, white); border: 2px solid var(--category-color, white);
border-radius: 15px; border-radius: 15px;
overflow: hidden; overflow: hidden;
@@ -20,7 +20,7 @@
.product-card:active { .product-card:active {
transform: scale(0.97); transform: scale(0.97);
background-color: #2a2a2a; background-color: var(--surface-2);
} }
.product-card-content { .product-card-content {
@@ -30,7 +30,7 @@
.product-image-container { .product-image-container {
width: 100%; width: 100%;
aspect-ratio: 1; aspect-ratio: 1;
background-color: #2a2a2a; background-color: var(--surface-2);
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
@@ -78,12 +78,12 @@
.product-info { .product-info {
padding: clamp(0.8rem, 3vw, 1.2rem); padding: clamp(0.8rem, 3vw, 1.2rem);
background-color: #1a1a1a; background-color: var(--surface);
border-top: 1px solid #333; border-top: 1px solid var(--border);
} }
.product-name { .product-name {
color: white; color: var(--text);
margin: 0 0 0.5rem 0; margin: 0 0 0.5rem 0;
font-size: clamp(1rem, 3.5vw, 1.2rem); font-size: clamp(1rem, 3.5vw, 1.2rem);
font-weight: 600; font-weight: 600;
@@ -99,18 +99,18 @@
} }
.product-stock { .product-stock {
color: #cccccc; color: var(--text-muted);
font-size: clamp(0.85rem, 2.5vw, 1rem); font-size: clamp(0.85rem, 2.5vw, 1rem);
text-align: center; text-align: center;
padding: clamp(0.6rem, 2vw, 0.8rem); padding: clamp(0.6rem, 2vw, 0.8rem);
background-color: #0a0a0a; background-color: var(--bg);
border-top: 1px solid #333; border-top: 1px solid var(--border);
} }
.quick-add-section { .quick-add-section {
padding: clamp(0.8rem, 3vw, 1rem); padding: clamp(0.8rem, 3vw, 1rem);
background-color: #0a0a0a; background-color: var(--bg);
border-top: 1px solid #333; border-top: 1px solid var(--border);
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 0.6rem; gap: 0.6rem;
@@ -224,8 +224,8 @@ div[data-category="gros&semi"] .quick-add-btn:active {
.quantity-select { .quantity-select {
width: 100%; width: 100%;
padding: clamp(0.7rem, 2.5vw, 0.9rem); padding: clamp(0.7rem, 2.5vw, 0.9rem);
background-color: #2a2a2a; background-color: var(--surface-2);
color: white; color: var(--text);
border: 2px solid #4ade80; border: 2px solid #4ade80;
border-radius: 8px; border-radius: 8px;
font-size: clamp(0.9rem, 3vw, 1.05rem); font-size: clamp(0.9rem, 3vw, 1.05rem);
@@ -241,7 +241,7 @@ div[data-category="gros&semi"] .quick-add-btn:active {
.quantity-select:hover { .quantity-select:hover {
border-color: #22c55e; border-color: #22c55e;
background-color: #333; background-color: var(--surface);
} }
.quantity-select:focus { .quantity-select:focus {
@@ -260,7 +260,7 @@ div[data-category="weed&hash"] .quantity-select {
div[data-category="weed&hash"] .quantity-select:hover { div[data-category="weed&hash"] .quantity-select:hover {
border-color: #059669; border-color: #059669;
background-color: #333; background-color: var(--surface);
} }
div[data-category="weed&hash"] .quantity-select:focus { div[data-category="weed&hash"] .quantity-select:focus {
@@ -276,7 +276,7 @@ div[data-category="tous"] .quantity-select {
div[data-category="tous"] .quantity-select:hover { div[data-category="tous"] .quantity-select:hover {
border-color: #7e22ce; border-color: #7e22ce;
background-color: #333; background-color: var(--surface);
} }
div[data-category="tous"] .quantity-select:focus { div[data-category="tous"] .quantity-select:focus {
@@ -292,7 +292,7 @@ div[data-category="zipette&co"] .quantity-select {
div[data-category="zipette&co"] .quantity-select:hover { div[data-category="zipette&co"] .quantity-select:hover {
border-color: #e8e8e0; border-color: #e8e8e0;
background-color: #333; background-color: var(--surface);
} }
div[data-category="zipette&co"] .quantity-select:focus { div[data-category="zipette&co"] .quantity-select:focus {
@@ -308,7 +308,7 @@ div[data-category="gros&semi"] .quantity-select {
div[data-category="gros&semi"] .quantity-select:hover { div[data-category="gros&semi"] .quantity-select:hover {
border-color: #0ea5e9; border-color: #0ea5e9;
background-color: #333; background-color: var(--surface);
} }
div[data-category="gros&semi"] .quantity-select:focus { div[data-category="gros&semi"] .quantity-select:focus {
@@ -317,8 +317,8 @@ div[data-category="gros&semi"] .quantity-select:focus {
} }
.quantity-select option { .quantity-select option {
background-color: #2a2a2a; background-color: var(--surface-2);
color: white; color: var(--text);
padding: 0.5rem; padding: 0.5rem;
} }
@@ -706,7 +706,7 @@ div[data-category="gros&semi"] .details-button:hover {
@media (hover: none) { @media (hover: none) {
.product-card:hover { .product-card:hover {
transform: none; transform: none;
background-color: #1a1a1a; background-color: var(--surface);
} }
.quick-add-btn:hover { .quick-add-btn:hover {
+43 -43
View File
@@ -37,7 +37,7 @@
width: 90%; width: 90%;
max-width: 900px; max-width: 900px;
max-height: 90vh; max-height: 90vh;
background: linear-gradient(135deg, rgba(20, 20, 25, 0.98), rgba(15, 15, 20, 0.98)); background: linear-gradient(135deg, var(--surface), var(--bg));
border: 1px solid rgba(124, 58, 237, 0.3); border: 1px solid rgba(124, 58, 237, 0.3);
border-radius: 20px; border-radius: 20px;
box-shadow: 0 20px 60px rgba(124, 58, 237, 0.3), 0 0 0 1px rgba(255, 255, 255, 0.05); box-shadow: 0 20px 60px rgba(124, 58, 237, 0.3), 0 0 0 1px rgba(255, 255, 255, 0.05);
@@ -67,8 +67,8 @@
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
padding: 1.8rem 2rem; padding: 1.8rem 2rem;
border-bottom: 1px solid rgba(255, 255, 255, 0.08); border-bottom: 1px solid var(--border);
background: linear-gradient(135deg, rgba(124, 58, 237, 0.08), rgba(109, 40, 217, 0.04)); background: var(--primary-soft);
flex-shrink: 0; flex-shrink: 0;
} }
@@ -84,7 +84,7 @@
} }
.modal-header h2 { .modal-header h2 {
color: white; color: var(--text);
font-size: 1.6rem; font-size: 1.6rem;
font-weight: 700; font-weight: 700;
margin: 0; margin: 0;
@@ -92,7 +92,7 @@
} }
.modal-subtitle { .modal-subtitle {
color: #888; color: var(--text-muted);
font-size: 0.9rem; font-size: 0.9rem;
margin: 0.3rem 0 0 0; margin: 0.3rem 0 0 0;
font-weight: 500; font-weight: 500;
@@ -102,12 +102,12 @@
width: 40px; width: 40px;
height: 40px; height: 40px;
border-radius: 10px; border-radius: 10px;
background: linear-gradient(135deg, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.02)); background: var(--surface-2);
border: 1px solid rgba(255, 255, 255, 0.08); border: 1px solid var(--border);
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
color: #888; color: var(--text-muted);
cursor: pointer; cursor: pointer;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
flex-shrink: 0; flex-shrink: 0;
@@ -128,7 +128,7 @@
overflow-y: auto; overflow-y: auto;
padding: 2rem; padding: 2rem;
scrollbar-width: thin; scrollbar-width: thin;
scrollbar-color: rgba(124, 58, 237, 0.4) rgba(255, 255, 255, 0.05); scrollbar-color: rgba(124, 58, 237, 0.4) var(--surface-2);
} }
.modal-content::-webkit-scrollbar { .modal-content::-webkit-scrollbar {
@@ -136,7 +136,7 @@
} }
.modal-content::-webkit-scrollbar-track { .modal-content::-webkit-scrollbar-track {
background: rgba(255, 255, 255, 0.05); background: var(--surface-2);
border-radius: 4px; border-radius: 4px;
} }
@@ -331,8 +331,8 @@
} }
.detail-section { .detail-section {
background: linear-gradient(135deg, rgba(255, 255, 255, 0.03), rgba(255, 255, 255, 0.01)); background: var(--surface);
border: 1px solid rgba(255, 255, 255, 0.08); border: 1px solid var(--border);
border-radius: 12px; border-radius: 12px;
padding: 1.5rem; padding: 1.5rem;
} }
@@ -345,7 +345,7 @@
display: flex; display: flex;
align-items: center; align-items: center;
gap: 0.6rem; gap: 0.6rem;
color: white; color: var(--text);
font-size: 0.95rem; font-size: 0.95rem;
font-weight: 600; font-weight: 600;
text-transform: uppercase; text-transform: uppercase;
@@ -358,7 +358,7 @@
} }
.detail-description { .detail-description {
color: #aaa; color: var(--text-muted);
font-size: 1rem; font-size: 1rem;
line-height: 1.6; line-height: 1.6;
margin: 0; margin: 0;
@@ -403,8 +403,8 @@
align-items: center; align-items: center;
gap: 1rem; gap: 1rem;
padding: 0.8rem 1.2rem; padding: 0.8rem 1.2rem;
background: rgba(0, 0, 0, 0.2); background: var(--bg);
border: 1px solid rgba(255, 255, 255, 0.05); border: 1px solid var(--border);
border-radius: 8px; border-radius: 8px;
} }
@@ -415,7 +415,7 @@
.quantity-value, .quantity-value,
.amount-value { .amount-value {
color: white; color: var(--text);
font-size: 1.1rem; font-size: 1.1rem;
font-weight: 600; font-weight: 600;
} }
@@ -435,7 +435,7 @@
display: flex; display: flex;
align-items: center; align-items: center;
gap: 0.6rem; gap: 0.6rem;
color: #aaa; color: var(--text-muted);
font-size: 0.95rem; font-size: 0.95rem;
font-weight: 500; font-weight: 500;
} }
@@ -445,13 +445,13 @@
} }
.date-text { .date-text {
color: #aaa; color: var(--text-muted);
font-size: 0.95rem; font-size: 0.95rem;
margin: 0; margin: 0;
} }
.no-data { .no-data {
color: #666; color: var(--text-muted);
font-style: italic; font-style: italic;
margin: 0; margin: 0;
} }
@@ -460,8 +460,8 @@
FORM SECTIONS (Create & Edit Modals) FORM SECTIONS (Create & Edit Modals)
============================================ */ ============================================ */
.form-section { .form-section {
background: linear-gradient(135deg, rgba(255, 255, 255, 0.03), rgba(255, 255, 255, 0.01)); background: var(--surface);
border: 1px solid rgba(255, 255, 255, 0.08); border: 1px solid var(--border);
border-radius: 12px; border-radius: 12px;
padding: 1.5rem; padding: 1.5rem;
margin-bottom: 1.5rem; margin-bottom: 1.5rem;
@@ -472,7 +472,7 @@
} }
.form-section h3 { .form-section h3 {
color: white; color: var(--text);
font-size: 1.1rem; font-size: 1.1rem;
font-weight: 600; font-weight: 600;
margin: 0 0 1.2rem 0; margin: 0 0 1.2rem 0;
@@ -526,7 +526,7 @@
.form-group label { .form-group label {
display: block; display: block;
color: white; color: var(--text);
font-size: 0.9rem; font-size: 0.9rem;
font-weight: 600; font-weight: 600;
margin-bottom: 0.6rem; margin-bottom: 0.6rem;
@@ -539,10 +539,10 @@
.form-group textarea { .form-group textarea {
width: 100%; width: 100%;
padding: 0.9rem 1.2rem; padding: 0.9rem 1.2rem;
background: linear-gradient(135deg, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.02)); background: var(--surface-2);
border: 1px solid rgba(255, 255, 255, 0.08); border: 1px solid var(--border);
border-radius: 10px; border-radius: 10px;
color: white; color: var(--text);
font-size: 0.95rem; font-size: 0.95rem;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
font-family: inherit; font-family: inherit;
@@ -552,7 +552,7 @@
.form-group select:focus, .form-group select:focus,
.form-group textarea:focus { .form-group textarea:focus {
outline: none; outline: none;
background: linear-gradient(135deg, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0.04)); background: var(--surface);
border-color: rgba(124, 58, 237, 0.5); border-color: rgba(124, 58, 237, 0.5);
box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.1); box-shadow: 0 0 0 3px rgba(124, 58, 237, 0.1);
} }
@@ -602,7 +602,7 @@
} }
.price-input-group label { .price-input-group label {
color: #888; color: var(--text-muted);
font-size: 0.85rem; font-size: 0.85rem;
font-weight: 600; font-weight: 600;
text-transform: uppercase; text-transform: uppercase;
@@ -708,8 +708,8 @@
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
padding: 0.8rem 1.2rem; padding: 0.8rem 1.2rem;
background: rgba(0, 0, 0, 0.2); background: var(--bg);
border: 1px solid rgba(255, 255, 255, 0.05); border: 1px solid var(--border);
border-radius: 8px; border-radius: 8px;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
} }
@@ -727,13 +727,13 @@
} }
.file-name { .file-name {
color: white; color: var(--text);
font-size: 0.9rem; font-size: 0.9rem;
font-weight: 500; font-weight: 500;
} }
.file-size { .file-size {
color: #888; color: var(--text-muted);
font-size: 0.8rem; font-size: 0.8rem;
} }
@@ -772,8 +772,8 @@
aspect-ratio: 1; aspect-ratio: 1;
border-radius: 8px; border-radius: 8px;
overflow: hidden; overflow: hidden;
background: rgba(0, 0, 0, 0.3); background: var(--surface-2);
border: 1px solid rgba(255, 255, 255, 0.08); border: 1px solid var(--border);
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
} }
@@ -859,8 +859,8 @@
display: flex; display: flex;
gap: 1rem; gap: 1rem;
padding: 1.5rem 2rem; padding: 1.5rem 2rem;
border-top: 1px solid rgba(255, 255, 255, 0.08); border-top: 1px solid var(--border);
background: linear-gradient(135deg, rgba(255, 255, 255, 0.03), rgba(255, 255, 255, 0.01)); background: var(--surface);
flex-shrink: 0; flex-shrink: 0;
} }
@@ -888,15 +888,15 @@
} }
.action-button.secondary { .action-button.secondary {
background: linear-gradient(135deg, rgba(255, 255, 255, 0.05), rgba(255, 255, 255, 0.02)); background: var(--surface-2);
border-color: rgba(255, 255, 255, 0.08); border-color: var(--border);
color: #888; color: var(--text-muted);
} }
.action-button.secondary:hover:not(:disabled) { .action-button.secondary:hover:not(:disabled) {
background: linear-gradient(135deg, rgba(255, 255, 255, 0.08), rgba(255, 255, 255, 0.04)); background: var(--surface);
border-color: rgba(255, 255, 255, 0.15); border-color: var(--border);
color: white; color: var(--text);
} }
.action-button:disabled { .action-button:disabled {
+1 -1
View File
@@ -128,7 +128,7 @@
line-height: 1.5; line-height: 1.5;
flex: 1; flex: 1;
letter-spacing: 0.1px; letter-spacing: 0.1px;
color: rgba(255, 255, 255, 0.85); color: var(--text);
} }
.toast-progress { .toast-progress {
@@ -0,0 +1,41 @@
import { createContext, useContext, useEffect, useState } from "react";
import type { ReactNode } from "react";
type Theme = "dark" | "light";
interface ThemeContextValue {
theme: Theme;
toggleTheme: () => void;
}
const ThemeContext = createContext<ThemeContextValue>({
theme: "dark",
toggleTheme: () => {},
});
export function ThemeProvider({ children }: { children: ReactNode }) {
const [theme, setTheme] = useState<Theme>(() => {
const stored = localStorage.getItem("theme");
if (stored === "light" || stored === "dark") return stored;
return "dark";
});
useEffect(() => {
document.documentElement.setAttribute("data-theme", theme);
localStorage.setItem("theme", theme);
}, [theme]);
const toggleTheme = () => {
setTheme((prev) => (prev === "dark" ? "light" : "dark"));
};
return (
<ThemeContext.Provider value={{ theme, toggleTheme }}>
{children}
</ThemeContext.Provider>
);
}
export function useTheme(): ThemeContextValue {
return useContext(ThemeContext);
}
+7 -2
View File
@@ -12,7 +12,6 @@
line-height: 1.5; line-height: 1.5;
font-weight: 400; font-weight: 400;
color-scheme: dark; color-scheme: dark;
color: rgba(255, 255, 255, 0.87);
font-synthesis: none; font-synthesis: none;
text-rendering: optimizeLegibility; text-rendering: optimizeLegibility;
-webkit-font-smoothing: antialiased; -webkit-font-smoothing: antialiased;
@@ -21,6 +20,10 @@
font-size: 16px; font-size: 16px;
} }
[data-theme="light"] {
color-scheme: light;
}
html, body { html, body {
margin: 0; margin: 0;
padding: 0; padding: 0;
@@ -36,6 +39,8 @@ body {
position: fixed; position: fixed;
width: 100%; width: 100%;
height: 100%; height: 100%;
background-color: var(--bg);
color: var(--text);
} }
#root { #root {
@@ -75,7 +80,7 @@ button {
font-size: 1em; font-size: 1em;
font-weight: 500; font-weight: 500;
font-family: inherit; font-family: inherit;
background-color: #1a1a1a; background-color: var(--surface);
cursor: pointer; cursor: pointer;
transition: all 0.2s; transition: all 0.2s;
-webkit-tap-highlight-color: transparent; -webkit-tap-highlight-color: transparent;
@@ -4,7 +4,7 @@
left: 0; left: 0;
right: 0; right: 0;
bottom: 0; bottom: 0;
background-color: #09090b; background-color: var(--bg);
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
@@ -37,21 +37,21 @@
.cp-title { .cp-title {
font-size: 1.6rem; font-size: 1.6rem;
font-weight: 700; font-weight: 700;
color: #f4f4f5; color: var(--text);
margin-bottom: 0.5rem; margin-bottom: 0.5rem;
} }
.cp-subtitle { .cp-subtitle {
color: #71717a; color: var(--text-muted);
font-size: 0.9rem; font-size: 0.9rem;
line-height: 1.5; line-height: 1.5;
padding: 0 0.5rem; padding: 0 0.5rem;
} }
.cp-card { .cp-card {
background-color: #111115; background-color: var(--surface);
border-radius: 1rem; border-radius: 1rem;
border: 1px solid rgba(255, 255, 255, 0.07); border: 1px solid var(--border);
box-shadow: 0 25px 50px rgba(0, 0, 0, 0.5); box-shadow: 0 25px 50px rgba(0, 0, 0, 0.5);
padding: 2rem; padding: 2rem;
} }
@@ -71,7 +71,7 @@
.cp-label { .cp-label {
font-size: 0.875rem; font-size: 0.875rem;
font-weight: 500; font-weight: 500;
color: #d1d5db; color: var(--text);
} }
.cp-input-wrapper { .cp-input-wrapper {
@@ -84,23 +84,23 @@
left: 1rem; left: 1rem;
transform: translateY(-50%); transform: translateY(-50%);
pointer-events: none; pointer-events: none;
color: #52525b; color: var(--text-muted);
} }
.cp-input { .cp-input {
width: 100%; width: 100%;
padding: 0.75rem 3rem 0.75rem 3rem; padding: 0.75rem 3rem 0.75rem 3rem;
background-color: #09090b; background-color: var(--bg);
border: 1px solid rgba(255, 255, 255, 0.1); border: 1px solid var(--border);
border-radius: 0.5rem; border-radius: 0.5rem;
color: #f4f4f5; color: var(--text);
font-size: 1rem; font-size: 1rem;
transition: border-color 0.2s, box-shadow 0.2s; transition: border-color 0.2s, box-shadow 0.2s;
box-sizing: border-box; box-sizing: border-box;
} }
.cp-input::placeholder { .cp-input::placeholder {
color: #52525b; color: var(--text-muted);
} }
.cp-input:focus { .cp-input:focus {
@@ -120,7 +120,7 @@
transform: translateY(-50%); transform: translateY(-50%);
background: transparent; background: transparent;
border: none; border: none;
color: #52525b; color: var(--text-muted);
cursor: pointer; cursor: pointer;
padding: 0.25rem; padding: 0.25rem;
display: flex; display: flex;
@@ -129,12 +129,12 @@
} }
.cp-toggle:hover { .cp-toggle:hover {
color: #a1a1aa; color: var(--text);
} }
.cp-hint { .cp-hint {
font-size: 0.78rem; font-size: 0.78rem;
color: #71717a; color: var(--text-muted);
margin: 0; margin: 0;
} }
@@ -189,7 +189,7 @@
gap: 0.75rem; gap: 0.75rem;
padding: 1.5rem 0; padding: 1.5rem 0;
text-align: center; text-align: center;
color: #f4f4f5; color: var(--text);
} }
.cp-success-icon { .cp-success-icon {
@@ -212,7 +212,7 @@
} }
.cp-success-sub { .cp-success-sub {
color: #71717a; color: var(--text-muted);
font-size: 0.85rem; font-size: 0.85rem;
font-weight: 400 !important; font-weight: 400 !important;
} }
+1 -2
View File
@@ -10,7 +10,6 @@
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', sans-serif; font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', 'Ubuntu', 'Cantarell', sans-serif;
line-height: 1.5; line-height: 1.5;
font-weight: 400; font-weight: 400;
color-scheme: dark;
color: rgba(255, 255, 255, 0.87); color: rgba(255, 255, 255, 0.87);
font-synthesis: none; font-synthesis: none;
text-rendering: optimizeLegibility; text-rendering: optimizeLegibility;
@@ -145,7 +144,7 @@ button {
font-size: 1em; font-size: 1em;
font-weight: 500; font-weight: 500;
font-family: inherit; font-family: inherit;
background-color: #1a1a1a; background-color: var(--surface);
cursor: pointer; cursor: pointer;
transition: all 0.2s; transition: all 0.2s;
-webkit-tap-highlight-color: transparent; -webkit-tap-highlight-color: transparent;
+29 -18
View File
@@ -4,7 +4,7 @@
left: 0; left: 0;
right: 0; right: 0;
bottom: 0; bottom: 0;
background-color: #1a1a1a; background-color: var(--bg);
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: center; justify-content: center;
@@ -38,20 +38,20 @@
.login-title { .login-title {
font-size: 1.875rem; font-size: 1.875rem;
font-weight: bold; font-weight: bold;
color: white; color: var(--text);
margin-bottom: 0.5rem; margin-bottom: 0.5rem;
} }
.login-subtitle { .login-subtitle {
color: #9ca3af; color: var(--text-muted);
} }
.login-card { .login-card {
background-color: #000000; background-color: var(--surface);
backdrop-filter: blur(16px); backdrop-filter: blur(16px);
border-radius: 1rem; border-radius: 1rem;
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25); box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
border: 1px solid rgba(75, 85, 99, 0.5); border: 1px solid var(--border);
padding: 2rem; padding: 2rem;
} }
@@ -70,7 +70,7 @@
display: block; display: block;
font-size: 0.875rem; font-size: 0.875rem;
font-weight: 500; font-weight: 500;
color: #d1d5db; color: var(--text);
margin-bottom: 0.5rem; margin-bottom: 0.5rem;
} }
@@ -84,22 +84,22 @@
left: 1rem; left: 1rem;
transform: translateY(-50%); transform: translateY(-50%);
pointer-events: none; pointer-events: none;
color: #6b7280; color: var(--text-muted);
} }
.form-input { .form-input {
width: 100%; width: 100%;
padding: 0.75rem 1rem 0.75rem 3rem; padding: 0.75rem 1rem 0.75rem 3rem;
background-color: #000000; background-color: var(--bg);
border: 1px solid #4b5563; border: 1px solid var(--border);
border-radius: 0.5rem; border-radius: 0.5rem;
color: white; color: var(--text);
font-size: 1rem; font-size: 1rem;
transition: all 0.3s; transition: all 0.3s;
} }
.form-input::placeholder { .form-input::placeholder {
color: #6b7280; color: var(--text-muted);
} }
.form-input:focus { .form-input:focus {
@@ -121,7 +121,7 @@
transform: translateY(-50%); transform: translateY(-50%);
background: transparent; background: transparent;
border: none; border: none;
color: #6b7280; color: var(--text-muted);
cursor: pointer; cursor: pointer;
padding: 0.25rem; padding: 0.25rem;
display: flex; display: flex;
@@ -130,7 +130,7 @@
} }
.password-toggle:hover { .password-toggle:hover {
color: #d1d5db; color: var(--text);
} }
.error-message { .error-message {
@@ -139,6 +139,17 @@
color: #f87171; color: #f87171;
} }
.error-banner {
padding: 0.75rem 1rem;
margin-bottom: 1rem;
background: rgba(239, 68, 68, 0.1);
border-left: 4px solid #ef4444;
border-radius: 6px;
color: #f87171;
font-size: 0.875rem;
font-weight: 500;
}
.form-options { .form-options {
display: flex; display: flex;
align-items: center; align-items: center;
@@ -154,8 +165,8 @@
.remember-me input { .remember-me input {
width: 1rem; width: 1rem;
height: 1rem; height: 1rem;
background-color: #111827; background-color: var(--surface-2);
border: 1px solid #4b5563; border: 1px solid var(--border);
border-radius: 0.25rem; border-radius: 0.25rem;
cursor: pointer; cursor: pointer;
accent-color: #7c3aed; accent-color: #7c3aed;
@@ -164,7 +175,7 @@
.remember-me span { .remember-me span {
margin-left: 0.5rem; margin-left: 0.5rem;
font-size: 0.875rem; font-size: 0.875rem;
color: #9ca3af; color: var(--text-muted);
} }
.forgot-password { .forgot-password {
@@ -236,7 +247,7 @@
} }
.signup-text { .signup-text {
color: #9ca3af; color: var(--text-muted);
font-size: 0.875rem; font-size: 0.875rem;
} }
@@ -257,6 +268,6 @@
.login-footer { .login-footer {
margin-top: 2rem; margin-top: 2rem;
text-align: center; text-align: center;
color: #6b7280; color: var(--text-muted);
font-size: 0.875rem; font-size: 0.875rem;
} }
+1 -11
View File
@@ -158,17 +158,7 @@ const LoginClient = () => {
<form className="login-form" onSubmit={handleSubmit}> <form className="login-form" onSubmit={handleSubmit}>
{/* ✅ Erreur API globale */} {/* ✅ Erreur API globale */}
{apiError && ( {apiError && (
<div <div className="error-banner">
className="error-banner"
style={{
padding: "12px",
marginBottom: "16px",
backgroundColor: "#fee",
borderLeft: "4px solid #f44",
borderRadius: "4px",
color: "#c33",
}}
>
{apiError} {apiError}
</div> </div>
)} )}
+32 -48
View File
@@ -9,7 +9,7 @@
padding-top: calc(60px + clamp(1rem, 3vw, 2rem)); padding-top: calc(60px + clamp(1rem, 3vw, 2rem));
max-width: 1200px; max-width: 1200px;
margin: 0 auto; margin: 0 auto;
background: linear-gradient(135deg, #0f0f0f 0%, #1a1a1a 100%); background: linear-gradient(135deg, var(--bg) 0%, var(--surface) 100%);
} }
.cart-header { .cart-header {
@@ -23,15 +23,11 @@
} }
.cart-header h1 { .cart-header h1 {
color: white;
font-size: clamp(1.8rem, 5vw, 2.5rem); font-size: clamp(1.8rem, 5vw, 2.5rem);
margin: 0; margin: 0;
font-weight: bold; font-weight: bold;
letter-spacing: -0.5px; letter-spacing: -0.5px;
background: #ffffff; color: var(--text);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
} }
.clear-all-button { .clear-all-button {
@@ -80,12 +76,12 @@
.empty-cart-icon { .empty-cart-icon {
margin-bottom: 1.5rem; margin-bottom: 1.5rem;
opacity: 0.4; opacity: 0.4;
color: rgba(255, 255, 255, 0.5); color: var(--text-muted);
} }
.empty-cart p { .empty-cart p {
font-size: 1.2rem; font-size: 1.2rem;
color: #888; color: var(--text-muted);
margin-bottom: 2rem; margin-bottom: 2rem;
} }
@@ -121,12 +117,8 @@
.cart-item { .cart-item {
position: relative; position: relative;
background: linear-gradient( background: var(--surface);
135deg, border: 1px solid var(--border);
rgba(255, 255, 255, 0.03) 0%,
rgba(255, 255, 255, 0.01) 100%
);
border: 1px solid rgba(255, 255, 255, 0.08);
border-radius: 16px; border-radius: 16px;
padding: clamp(1.5rem, 4vw, 2rem); padding: clamp(1.5rem, 4vw, 2rem);
display: flex; display: flex;
@@ -156,11 +148,7 @@
} }
.cart-item:hover { .cart-item:hover {
background: linear-gradient( background: var(--surface-2);
135deg,
rgba(255, 255, 255, 0.05) 0%,
rgba(255, 255, 255, 0.02) 100%
);
border-color: rgba(124, 58, 237, 0.3); border-color: rgba(124, 58, 237, 0.3);
box-shadow: 0 12px 32px rgba(124, 58, 237, 0.15); box-shadow: 0 12px 32px rgba(124, 58, 237, 0.15);
transform: translateY(-4px); transform: translateY(-4px);
@@ -177,12 +165,8 @@
height: 220px; height: 220px;
border-radius: 12px; border-radius: 12px;
overflow: hidden; overflow: hidden;
background: linear-gradient( background: var(--surface-2);
135deg, border: 1px solid var(--border);
rgba(255, 255, 255, 0.08) 0%,
rgba(255, 255, 255, 0.04) 100%
);
border: 1px solid rgba(255, 255, 255, 0.1);
} }
.cart-item-image { .cart-item-image {
@@ -241,7 +225,7 @@
} }
.cart-item-info h3 { .cart-item-info h3 {
color: white; color: var(--text);
font-size: clamp(1.2rem, 4vw, 1.4rem); font-size: clamp(1.2rem, 4vw, 1.4rem);
margin: 0; margin: 0;
font-weight: 600; font-weight: 600;
@@ -262,7 +246,7 @@
/* ✨ NOUVEAU: Affichage de la quantité en grammes */ /* ✨ NOUVEAU: Affichage de la quantité en grammes */
.cart-item-quantity { .cart-item-quantity {
font-size: 1rem; font-size: 1rem;
color: rgba(255, 255, 255, 0.8); color: var(--text-muted);
margin: 0.5rem 0; margin: 0.5rem 0;
padding: 0.5rem 1rem; padding: 0.5rem 1rem;
background: rgba(124, 58, 237, 0.1); background: rgba(124, 58, 237, 0.1);
@@ -294,7 +278,7 @@
align-items: center; align-items: center;
justify-content: flex-end; justify-content: flex-end;
padding-top: 1rem; padding-top: 1rem;
border-top: 1px solid rgba(255, 255, 255, 0.08); border-top: 1px solid var(--border);
} }
.remove-item-button { .remove-item-button {
@@ -336,8 +320,8 @@
/* Cart Summary */ /* Cart Summary */
.cart-summary { .cart-summary {
background-color: rgba(255, 255, 255, 0.02); background-color: var(--surface);
border: 1px solid rgba(255, 255, 255, 0.08); border: 1px solid var(--border);
border-radius: 12px; border-radius: 12px;
padding: clamp(1.5rem, 4vw, 2rem); padding: clamp(1.5rem, 4vw, 2rem);
position: sticky; position: sticky;
@@ -350,20 +334,20 @@
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
margin-bottom: 1rem; margin-bottom: 1rem;
color: rgba(255, 255, 255, 0.7); color: var(--text-muted);
font-size: clamp(0.95rem, 3vw, 1.05rem); font-size: clamp(0.95rem, 3vw, 1.05rem);
} }
.summary-row span:last-child { .summary-row span:last-child {
font-weight: 600; font-weight: 600;
color: white; color: var(--text);
} }
.total-row { .total-row {
color: white; color: var(--text);
font-size: clamp(1.2rem, 4vw, 1.4rem); font-size: clamp(1.2rem, 4vw, 1.4rem);
padding-top: 1rem; padding-top: 1rem;
border-top: 1px solid rgba(255, 255, 255, 0.1); border-top: 1px solid var(--border);
margin-top: 1rem; margin-top: 1rem;
margin-bottom: 1.5rem; margin-bottom: 1.5rem;
font-weight: 700; font-weight: 700;
@@ -431,7 +415,7 @@
.loading-cart p { .loading-cart p {
font-size: 1.2rem; font-size: 1.2rem;
color: #666; color: var(--text-muted);
animation: pulse 1.5s ease-in-out infinite; animation: pulse 1.5s ease-in-out infinite;
} }
@@ -471,7 +455,7 @@
} }
.modal-content2 { .modal-content2 {
background: #1a1a1a; background: var(--surface);
border: 1px solid rgba(239, 68, 68, 0.3); border: 1px solid rgba(239, 68, 68, 0.3);
border-radius: 20px; border-radius: 20px;
padding: clamp(2rem, 5vw, 3rem); padding: clamp(2rem, 5vw, 3rem);
@@ -529,7 +513,7 @@
} }
.modal-title { .modal-title {
color: white; color: var(--text);
font-size: clamp(1.5rem, 4vw, 1.8rem); font-size: clamp(1.5rem, 4vw, 1.8rem);
font-weight: 700; font-weight: 700;
text-align: center; text-align: center;
@@ -538,7 +522,7 @@
} }
.modal-message { .modal-message {
color: rgba(255, 255, 255, 0.7); color: var(--text-muted);
font-size: clamp(0.95rem, 3vw, 1.05rem); font-size: clamp(0.95rem, 3vw, 1.05rem);
text-align: center; text-align: center;
line-height: 1.6; line-height: 1.6;
@@ -570,15 +554,15 @@
} }
.modal-cancel { .modal-cancel {
background: #0f0f0f; background: var(--bg);
color: rgba(255, 255, 255, 0.8); color: var(--text-muted);
border: 1px solid rgba(255, 255, 255, 0.15); border: 1px solid var(--border);
} }
.modal-cancel:hover { .modal-cancel:hover {
background: rgba(255, 255, 255, 0.1); background: var(--surface-2);
color: white; color: var(--text);
border-color: rgba(255, 255, 255, 0.3); border-color: var(--text-muted);
transform: translateY(-2px); transform: translateY(-2px);
} }
@@ -628,7 +612,7 @@
position: relative; position: relative;
width: 100%; width: 100%;
max-width: 900px; max-width: 900px;
background: #1a1a1a; background: var(--surface);
border-radius: 16px; border-radius: 16px;
overflow: hidden; overflow: hidden;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5); box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
@@ -675,9 +659,9 @@
.cart-item-media-container.loading { .cart-item-media-container.loading {
background: linear-gradient( background: linear-gradient(
90deg, 90deg,
rgba(255, 255, 255, 0.05) 0%, var(--surface) 0%,
rgba(255, 255, 255, 0.1) 50%, var(--surface-2) 50%,
rgba(255, 255, 255, 0.05) 100% var(--surface) 100%
); );
background-size: 200% 100%; background-size: 200% 100%;
animation: shimmer 1.5s infinite; animation: shimmer 1.5s infinite;
+138 -73
View File
@@ -1,3 +1,40 @@
.checkout-telegram-note {
display: flex;
gap: 0.875rem;
align-items: flex-start;
background: rgba(41, 182, 246, 0.08);
border: 1px solid rgba(41, 182, 246, 0.3);
border-radius: 10px;
padding: 0.9rem 1rem;
margin-bottom: 1.25rem;
}
.checkout-telegram-note .fa-telegram {
font-size: 1.4rem;
color: #229ed9;
flex-shrink: 0;
margin-top: 0.1rem;
}
.checkout-telegram-note strong {
display: block;
color: #29b6f6;
font-size: 0.875rem;
margin-bottom: 0.2rem;
}
.checkout-telegram-note p {
color: var(--text-muted);
font-size: 0.82rem;
line-height: 1.5;
margin: 0;
}
.checkout-telegram-note a {
color: #29b6f6;
text-decoration: underline;
}
.form-prefill-hint { .form-prefill-hint {
font-size: 0.75rem; font-size: 0.75rem;
color: #6ee7b7; color: #6ee7b7;
@@ -12,15 +49,12 @@
padding-top: calc(60px + clamp(1rem, 3vw, 2rem)); padding-top: calc(60px + clamp(1rem, 3vw, 2rem));
max-width: 1200px; max-width: 1200px;
margin: 0 auto; margin: 0 auto;
background: linear-gradient(135deg, #0f0f0f 0%, #1a1a1a 100%); background: linear-gradient(135deg, var(--bg) 0%, var(--surface) 100%);
} }
.checkout-container h1 { .checkout-container h1 {
font-size: clamp(1.8rem, 5vw, 2.5rem); font-size: clamp(1.8rem, 5vw, 2.5rem);
background: linear-gradient(135deg, #ffffff 0%, #b0b0b0 100%); color: var(--text);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
text-align: center; text-align: center;
margin-bottom: clamp(1.5rem, 4vw, 2rem); margin-bottom: clamp(1.5rem, 4vw, 2rem);
font-weight: 300; font-weight: 300;
@@ -36,8 +70,8 @@
/* Résumé de la commande */ /* Résumé de la commande */
.order-summary-box { .order-summary-box {
background: linear-gradient(135deg, rgba(255, 255, 255, 0.03) 0%, rgba(255, 255, 255, 0.01) 100%); background: var(--surface);
border: 1px solid rgba(255, 255, 255, 0.08); border: 1px solid var(--border);
border-radius: 16px; border-radius: 16px;
padding: clamp(1.5rem, 4vw, 2rem); padding: clamp(1.5rem, 4vw, 2rem);
height: fit-content; height: fit-content;
@@ -47,17 +81,17 @@
} }
.order-summary-box:hover { .order-summary-box:hover {
background: linear-gradient(135deg, rgba(255, 255, 255, 0.05) 0%, rgba(255, 255, 255, 0.02) 100%); background: var(--surface-2);
border-color: rgba(16, 185, 129, 0.3); border-color: rgba(16, 185, 129, 0.3);
box-shadow: 0 12px 32px rgba(16, 185, 129, 0.15); box-shadow: 0 12px 32px rgba(16, 185, 129, 0.15);
} }
.order-summary-box h2 { .order-summary-box h2 {
font-size: clamp(1.2rem, 4vw, 1.3rem); font-size: clamp(1.2rem, 4vw, 1.3rem);
color: white; color: var(--text);
margin: 0 0 clamp(1rem, 3vw, 1.5rem) 0; margin: 0 0 clamp(1rem, 3vw, 1.5rem) 0;
padding-bottom: 1rem; padding-bottom: 1rem;
border-bottom: 1px solid rgba(255, 255, 255, 0.1); border-bottom: 1px solid var(--border);
font-weight: 600; font-weight: 600;
letter-spacing: -0.3px; letter-spacing: -0.3px;
} }
@@ -74,7 +108,7 @@
gap: clamp(1rem, 3vw, 1.5rem); gap: clamp(1rem, 3vw, 1.5rem);
margin-bottom: 1rem; margin-bottom: 1rem;
padding-bottom: 1rem; padding-bottom: 1rem;
border-bottom: 1px solid rgba(255, 255, 255, 0.08); border-bottom: 1px solid var(--border);
transition: all 0.2s ease; transition: all 0.2s ease;
} }
@@ -93,10 +127,10 @@
height: 80px; height: 80px;
object-fit: cover; object-fit: cover;
border-radius: 12px; border-radius: 12px;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.15);
border: 1px solid rgba(255, 255, 255, 0.1); border: 1px solid var(--border);
flex-shrink: 0; flex-shrink: 0;
background: linear-gradient(135deg, rgba(255, 255, 255, 0.08) 0%, rgba(255, 255, 255, 0.04) 100%); background: var(--surface-2);
transition: transform 0.3s ease; transition: transform 0.3s ease;
} }
@@ -114,7 +148,7 @@
.summary-item-name { .summary-item-name {
margin: 0; margin: 0;
color: white; color: var(--text);
font-weight: 600; font-weight: 600;
font-size: clamp(0.9rem, 3vw, 1rem); font-size: clamp(0.9rem, 3vw, 1rem);
line-height: 1.3; line-height: 1.3;
@@ -122,7 +156,7 @@
.summary-item-details { .summary-item-details {
margin: 0; margin: 0;
color: rgba(255, 255, 255, 0.6); color: var(--text-muted);
font-size: clamp(0.8rem, 2vw, 0.9rem); font-size: clamp(0.8rem, 2vw, 0.9rem);
} }
@@ -131,10 +165,10 @@
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
padding-top: clamp(1rem, 3vw, 1.5rem); padding-top: clamp(1rem, 3vw, 1.5rem);
border-top: 1px solid rgba(255, 255, 255, 0.1); border-top: 1px solid var(--border);
font-size: clamp(1.1rem, 4vw, 1.3rem); font-size: clamp(1.1rem, 4vw, 1.3rem);
font-weight: 700; font-weight: 700;
color: white; color: var(--text);
margin-top: clamp(1rem, 3vw, 1.5rem); margin-top: clamp(1rem, 3vw, 1.5rem);
} }
@@ -146,8 +180,8 @@
/* Formulaire */ /* Formulaire */
.checkout-form { .checkout-form {
background: linear-gradient(135deg, rgba(255, 255, 255, 0.03) 0%, rgba(255, 255, 255, 0.01) 100%); background: var(--surface);
border: 1px solid rgba(255, 255, 255, 0.08); border: 1px solid var(--border);
border-radius: 16px; border-radius: 16px;
padding: clamp(1.5rem, 4vw, 2rem); padding: clamp(1.5rem, 4vw, 2rem);
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2); box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
@@ -160,7 +194,7 @@
padding: clamp(1rem, 3vw, 1.5rem); padding: clamp(1rem, 3vw, 1.5rem);
margin-bottom: clamp(1rem, 3vw, 1.5rem); margin-bottom: clamp(1rem, 3vw, 1.5rem);
border-radius: 8px; border-radius: 8px;
color: #f472b6; color: #f87171;
font-weight: 500; font-weight: 500;
box-shadow: 0 0 15px rgba(239, 68, 68, 0.1); box-shadow: 0 0 15px rgba(239, 68, 68, 0.1);
} }
@@ -175,10 +209,10 @@
.form-section h3 { .form-section h3 {
font-size: clamp(1.1rem, 3vw, 1.2rem); font-size: clamp(1.1rem, 3vw, 1.2rem);
color: white; color: var(--text);
margin: 0 0 clamp(1rem, 3vw, 1.5rem) 0; margin: 0 0 clamp(1rem, 3vw, 1.5rem) 0;
padding-bottom: 0.75rem; padding-bottom: 0.75rem;
border-bottom: 1px solid rgba(255, 255, 255, 0.1); border-bottom: 1px solid var(--border);
font-weight: 600; font-weight: 600;
letter-spacing: -0.3px; letter-spacing: -0.3px;
} }
@@ -197,25 +231,25 @@
} }
.form-group label { .form-group label {
color: rgba(255, 255, 255, 0.9); color: var(--text);
font-weight: 600; font-weight: 600;
font-size: clamp(0.9rem, 3vw, 1rem); font-size: clamp(0.9rem, 3vw, 1rem);
} }
.form-group input { .form-group input {
padding: clamp(0.75rem, 2vw, 1rem); padding: clamp(0.75rem, 2vw, 1rem);
border: 1px solid rgba(255, 255, 255, 0.1); border: 1px solid var(--border);
border-radius: 10px; border-radius: 10px;
font-size: clamp(0.9rem, 3vw, 1rem); font-size: clamp(0.9rem, 3vw, 1rem);
color: white; color: var(--text);
background-color: rgba(255, 255, 255, 0.03); background-color: var(--surface-2);
font-family: inherit; font-family: inherit;
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1); transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
-webkit-tap-highlight-color: transparent; -webkit-tap-highlight-color: transparent;
} }
.form-group input::placeholder { .form-group input::placeholder {
color: rgba(255, 255, 255, 0.3); color: var(--text-muted);
} }
.form-group input:focus { .form-group input:focus {
@@ -226,10 +260,10 @@
} }
.form-group input:disabled { .form-group input:disabled {
background-color: rgba(255, 255, 255, 0.02); background-color: var(--surface);
cursor: not-allowed; cursor: not-allowed;
opacity: 0.5; opacity: 0.5;
border-color: rgba(255, 255, 255, 0.05); border-color: var(--border);
} }
/* Actions */ /* Actions */
@@ -237,7 +271,7 @@
display: flex; display: flex;
gap: 1rem; gap: 1rem;
padding-top: clamp(1.5rem, 4vw, 2rem); padding-top: clamp(1.5rem, 4vw, 2rem);
border-top: 1px solid rgba(255, 255, 255, 0.1); border-top: 1px solid var(--border);
margin-top: clamp(1.5rem, 4vw, 2rem); margin-top: clamp(1.5rem, 4vw, 2rem);
} }
@@ -261,15 +295,15 @@
} }
.back-button { .back-button {
background-color: #1a1a1a; background-color: var(--surface);
color: rgba(255, 255, 255, 0.9); color: var(--text);
border: 1px solid rgba(255, 255, 255, 0.15); border: 1px solid var(--border);
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
} }
.back-button:hover:not(:disabled) { .back-button:hover:not(:disabled) {
background-color: #252525; background-color: var(--surface-2);
border-color: rgba(255, 255, 255, 0.25); border-color: var(--text-muted);
transform: translateY(-2px); transform: translateY(-2px);
box-shadow: 0 8px 20px rgba(0, 0, 0, 0.4); box-shadow: 0 8px 20px rgba(0, 0, 0, 0.4);
} }
@@ -353,7 +387,7 @@
} }
.confirmation-modal { .confirmation-modal {
background: #1a1a1a; background: var(--surface);
border: 2px solid #5b21b6; border: 2px solid #5b21b6;
border-radius: 20px; border-radius: 20px;
max-width: 600px; max-width: 600px;
@@ -376,7 +410,7 @@
} }
.confirmation-modal-header { .confirmation-modal-header {
background: #0f0f0f; background: var(--bg);
padding: 2rem; padding: 2rem;
border-bottom: 2px solid #5b21b6; border-bottom: 2px solid #5b21b6;
display: flex; display: flex;
@@ -404,20 +438,20 @@
.confirmation-modal-header h2 { .confirmation-modal-header h2 {
margin: 0; margin: 0;
font-size: clamp(1.5rem, 4vw, 2rem); font-size: clamp(1.5rem, 4vw, 2rem);
color: #ffffff; color: var(--text);
font-weight: 700; font-weight: 700;
letter-spacing: -0.5px; letter-spacing: -0.5px;
} }
.confirmation-modal-body { .confirmation-modal-body {
padding: 2rem; padding: 2rem;
background: #1a1a1a; background: var(--surface);
} }
.confirmation-section { .confirmation-section {
margin-bottom: 1.5rem; margin-bottom: 1.5rem;
padding: 1.25rem; padding: 1.25rem;
background: #0f0f0f; background: var(--bg);
border-radius: 12px; border-radius: 12px;
border: 1px solid #5b21b6; border: 1px solid #5b21b6;
} }
@@ -431,7 +465,7 @@
align-items: center; align-items: center;
gap: 0.75rem; gap: 0.75rem;
font-size: 1.1rem; font-size: 1.1rem;
color: #ffffff; color: var(--text);
font-weight: 600; font-weight: 600;
margin-bottom: 1rem; margin-bottom: 1rem;
} }
@@ -445,7 +479,7 @@
} }
.confirmation-detail { .confirmation-detail {
color: rgba(255, 255, 255, 0.8); color: var(--text-muted);
font-size: 0.95rem; font-size: 0.95rem;
line-height: 1.8; line-height: 1.8;
margin: 0.5rem 0; margin: 0.5rem 0;
@@ -453,7 +487,7 @@
} }
.confirmation-detail strong { .confirmation-detail strong {
color: rgba(255, 255, 255, 0.95); color: var(--text);
font-weight: 600; font-weight: 600;
} }
@@ -494,19 +528,19 @@
} }
.confirmation-footer { .confirmation-footer {
color: rgba(255, 255, 255, 0.75); color: var(--text-muted);
font-size: 0.9rem; font-size: 0.9rem;
line-height: 1.8; line-height: 1.8;
text-align: center; text-align: center;
padding: 1.25rem; padding: 1.25rem;
background: #0f0f0f; background: var(--bg);
border-radius: 12px; border-radius: 12px;
border: 1px solid #5b21b6; border: 1px solid #5b21b6;
margin-top: 1.5rem; margin-top: 1.5rem;
} }
.confirmation-footer-highlight { .confirmation-footer-highlight {
color: rgba(255, 255, 255, 0.95); color: var(--text);
font-weight: 600; font-weight: 600;
display: inline-flex; display: inline-flex;
align-items: center; align-items: center;
@@ -532,7 +566,7 @@
.confirmation-modal-actions { .confirmation-modal-actions {
padding: 1.5rem 2rem 2rem; padding: 1.5rem 2rem 2rem;
background: #1a1a1a; background: var(--surface);
border-radius: 0 0 18px 18px; border-radius: 0 0 18px 18px;
} }
@@ -568,6 +602,37 @@
transform: translateY(-1px) scale(0.98); transform: translateY(-1px) scale(0.98);
} }
.confirmation-modal-header--error {
background: linear-gradient(135deg, #dc2626 0%, #991b1b 100%);
}
.confirmation-modal-header--crypto {
background: linear-gradient(135deg, #f7931a 0%, #c2620a 100%);
}
.confirmation-button--neutral {
background: var(--surface-2);
border-color: var(--border);
color: var(--text);
box-shadow: none;
}
.confirmation-button--neutral:hover {
background: var(--surface);
box-shadow: none;
transform: translateY(-1px);
}
.confirmation-detail--centered {
text-align: center;
padding: 1rem 0;
}
.confirmation-detail--muted {
color: var(--text-muted);
font-size: 0.875rem;
}
/* Scrollbar personnalisée pour le modal */ /* Scrollbar personnalisée pour le modal */
.confirmation-modal::-webkit-scrollbar { .confirmation-modal::-webkit-scrollbar {
width: 8px; width: 8px;
@@ -879,7 +944,7 @@
} }
.back-button:hover { .back-button:hover {
background-color: #1a1a1a; background-color: var(--surface);
transform: none; transform: none;
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3); box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
} }
@@ -920,7 +985,7 @@
} }
.referral-toggle-label { .referral-toggle-label {
color: #e5e7eb; color: var(--text);
font-size: 0.9rem; font-size: 0.9rem;
font-weight: 600; font-weight: 600;
margin: 0 0 0.2rem; margin: 0 0 0.2rem;
@@ -950,7 +1015,7 @@
.referral-switch-slider { .referral-switch-slider {
position: absolute; position: absolute;
inset: 0; inset: 0;
background: #374151; background: var(--surface-2);
border-radius: 26px; border-radius: 26px;
cursor: pointer; cursor: pointer;
transition: background 0.2s; transition: background 0.2s;
@@ -988,10 +1053,10 @@
.payment-method-btn { .payment-method-btn {
flex: 1; flex: 1;
padding: 0.75rem 1rem; padding: 0.75rem 1rem;
border: 2px solid #2d2d2d; border: 2px solid var(--border);
border-radius: 10px; border-radius: 10px;
background: #1a1a1a; background: var(--surface);
color: #9ca3af; color: var(--text-muted);
font-size: 0.95rem; font-size: 0.95rem;
cursor: pointer; cursor: pointer;
transition: all 0.2s; transition: all 0.2s;
@@ -1002,8 +1067,8 @@
} }
.payment-method-btn:hover { .payment-method-btn:hover {
border-color: #4b5563; border-color: var(--text-muted);
color: #fff; color: var(--text);
} }
.payment-method-btn.active { .payment-method-btn.active {
@@ -1022,7 +1087,7 @@
.crypto-currency-selector label { .crypto-currency-selector label {
display: block; display: block;
font-size: 0.85rem; font-size: 0.85rem;
color: #9ca3af; color: var(--text-muted);
margin-bottom: 0.5rem; margin-bottom: 0.5rem;
} }
@@ -1034,10 +1099,10 @@
.crypto-currency-btn { .crypto-currency-btn {
padding: 0.4rem 0.9rem; padding: 0.4rem 0.9rem;
border: 2px solid #2d2d2d; border: 2px solid var(--border);
border-radius: 8px; border-radius: 8px;
background: #1a1a1a; background: var(--surface);
color: #9ca3af; color: var(--text-muted);
font-size: 0.8rem; font-size: 0.8rem;
font-weight: 600; font-weight: 600;
cursor: pointer; cursor: pointer;
@@ -1046,8 +1111,8 @@
} }
.crypto-currency-btn:hover { .crypto-currency-btn:hover {
border-color: #4b5563; border-color: var(--text-muted);
color: #fff; color: var(--text);
} }
.crypto-currency-btn.active { .crypto-currency-btn.active {
@@ -1058,7 +1123,7 @@
.crypto-info-hint { .crypto-info-hint {
font-size: 0.78rem; font-size: 0.78rem;
color: #6b7280; color: var(--text-muted);
margin-top: 0.6rem; margin-top: 0.6rem;
} }
@@ -1069,8 +1134,8 @@
display: flex; display: flex;
align-items: center; align-items: center;
gap: 0.75rem; gap: 0.75rem;
background: #111; background: var(--bg);
border: 1px solid #2d2d2d; border: 1px solid var(--border);
border-radius: 8px; border-radius: 8px;
padding: 0.75rem 1rem; padding: 0.75rem 1rem;
margin-top: 0.5rem; margin-top: 0.5rem;
@@ -1080,17 +1145,17 @@
.crypto-address { .crypto-address {
font-family: monospace; font-family: monospace;
font-size: 0.78rem; font-size: 0.78rem;
color: #d1d5db; color: var(--text-muted);
word-break: break-all; word-break: break-all;
flex: 1; flex: 1;
} }
.crypto-copy-btn { .crypto-copy-btn {
padding: 0.35rem 0.75rem; padding: 0.35rem 0.75rem;
border: 1px solid #374151; border: 1px solid var(--border);
border-radius: 6px; border-radius: 6px;
background: #1f2937; background: var(--surface-2);
color: #9ca3af; color: var(--text-muted);
font-size: 0.8rem; font-size: 0.8rem;
cursor: pointer; cursor: pointer;
white-space: nowrap; white-space: nowrap;
@@ -1098,12 +1163,12 @@
} }
.crypto-copy-btn:hover { .crypto-copy-btn:hover {
background: #374151; background: var(--surface);
color: #fff; color: var(--text);
} }
.crypto-equiv { .crypto-equiv {
color: #6b7280; color: var(--text-muted);
font-size: 0.85rem; font-size: 0.85rem;
margin-left: 0.5rem; margin-left: 0.5rem;
} }
@@ -1117,7 +1182,7 @@
.crypto-polling-info { .crypto-polling-info {
text-align: center; text-align: center;
color: #6b7280; color: var(--text-muted);
font-size: 0.82rem; font-size: 0.82rem;
margin-top: 0.5rem; margin-top: 0.5rem;
} }
+23 -9
View File
@@ -11,6 +11,7 @@ import './Checkout.css';
// ============================================ // ============================================
interface ConfirmationData { interface ConfirmationData {
command_id: number; command_id: number;
client_order_number?: number;
assigned_to?: { assigned_to?: {
username: string; username: string;
distance_km?: number; distance_km?: number;
@@ -267,6 +268,7 @@ function Checkout() {
if (response.success && response.payment_method === 'crypto') { if (response.success && response.payment_method === 'crypto') {
setCryptoPaymentData({ setCryptoPaymentData({
command_id: response.command_id!, command_id: response.command_id!,
client_order_number: (response as any).client_order_number,
payment_status: response.payment_status!, payment_status: response.payment_status!,
pay_address: response.pay_address!, pay_address: response.pay_address!,
pay_amount: response.pay_amount!, pay_amount: response.pay_amount!,
@@ -325,6 +327,7 @@ function Checkout() {
// ✅ Préparer les données pour le modal // ✅ Préparer les données pour le modal
setConfirmationData({ setConfirmationData({
command_id, command_id,
client_order_number: (response as any).client_order_number,
assigned_to, assigned_to,
queue_info, queue_info,
delivery_address: delivery_address || address, delivery_address: delivery_address || address,
@@ -537,6 +540,17 @@ function Checkout() {
</div> </div>
)} )}
<div className="checkout-telegram-note">
<i className="fab fa-telegram" />
<div>
<strong>Compte Telegram requis</strong>
<p>
Votre commande ne pourra être validée que si votre compte Telegram est lié.
Rendez-vous dans votre <a href="/user/profil">profil</a> pour le lier avant de confirmer.
</p>
</div>
</div>
<div className="form-actions"> <div className="form-actions">
<button <button
type="button" type="button"
@@ -565,14 +579,14 @@ function Checkout() {
{showCryptoModal && cryptoPaymentData && ( {showCryptoModal && cryptoPaymentData && (
<div className="confirmation-modal-overlay"> <div className="confirmation-modal-overlay">
<div className="confirmation-modal"> <div className="confirmation-modal">
<div className="confirmation-modal-header" style={{ background: 'linear-gradient(135deg, #f7931a, #c2620a)' }}> <div className="confirmation-modal-header confirmation-modal-header--crypto">
<i className="fas fa-coins confirmation-icon" /> <i className="fas fa-coins confirmation-icon" />
<h2>Paiement Crypto</h2> <h2>Paiement Crypto</h2>
</div> </div>
<div className="confirmation-modal-body"> <div className="confirmation-modal-body">
<div className="confirmation-section"> <div className="confirmation-section">
<div className="confirmation-section-title"> <div className="confirmation-section-title">
<i className="fas fa-receipt icon" /> Commande #{cryptoPaymentData.command_id} <i className="fas fa-receipt icon" /> Commande #{cryptoPaymentData.client_order_number ?? cryptoPaymentData.command_id}
</div> </div>
<div className="confirmation-detail"> <div className="confirmation-detail">
<strong>Statut :</strong>{' '} <strong>Statut :</strong>{' '}
@@ -627,7 +641,7 @@ function Checkout() {
)} )}
</div> </div>
<div className="confirmation-modal-actions"> <div className="confirmation-modal-actions">
<button className="confirmation-button" style={{ background: '#374151' }} onClick={handleCryptoModalClose}> <button className="confirmation-button confirmation-button--neutral" onClick={handleCryptoModalClose}>
<i className="fas fa-location-arrow" /> Suivre ma commande <i className="fas fa-location-arrow" /> Suivre ma commande
</button> </button>
</div> </div>
@@ -641,22 +655,22 @@ function Checkout() {
{showZoneModal && ( {showZoneModal && (
<div className="confirmation-modal-overlay" onClick={() => setShowZoneModal(false)}> <div className="confirmation-modal-overlay" onClick={() => setShowZoneModal(false)}>
<div className="confirmation-modal" onClick={(e) => e.stopPropagation()}> <div className="confirmation-modal" onClick={(e) => e.stopPropagation()}>
<div className="confirmation-modal-header" style={{ background: 'linear-gradient(135deg, #dc2626, #991b1b)' }}> <div className="confirmation-modal-header confirmation-modal-header--error">
<i className="fas fa-map-marker-alt confirmation-icon"></i> <i className="fas fa-map-marker-alt confirmation-icon"></i>
<h2>Zone non desservie</h2> <h2>Zone non desservie</h2>
</div> </div>
<div className="confirmation-modal-body"> <div className="confirmation-modal-body">
<div className="confirmation-section"> <div className="confirmation-section">
<div className="confirmation-detail" style={{ textAlign: 'center', padding: '1rem 0' }}> <div className="confirmation-detail confirmation-detail--centered">
<p style={{ fontSize: '1rem', marginBottom: '0.75rem' }}>{zoneErrorMsg}</p> <p style={{ marginBottom: '0.75rem' }}>{zoneErrorMsg}</p>
<p style={{ color: '#9ca3af', fontSize: '0.875rem' }}> <p className="confirmation-detail--muted">
Vérifiez l'adresse saisie ou contactez-nous pour connaître les zones de livraison disponibles. Vérifiez l'adresse saisie ou contactez-nous pour connaître les zones de livraison disponibles.
</p> </p>
</div> </div>
</div> </div>
</div> </div>
<div className="confirmation-modal-actions"> <div className="confirmation-modal-actions">
<button className="confirmation-button" style={{ background: '#374151' }} onClick={() => setShowZoneModal(false)}> <button className="confirmation-button confirmation-button--neutral" onClick={() => setShowZoneModal(false)}>
<i className="fas fa-arrow-left"></i> Modifier l'adresse <i className="fas fa-arrow-left"></i> Modifier l'adresse
</button> </button>
</div> </div>
@@ -685,7 +699,7 @@ function Checkout() {
Détails de la commande Détails de la commande
</div> </div>
<div className="confirmation-detail"> <div className="confirmation-detail">
<strong>Numéro:</strong> #{confirmationData.command_id} <strong>Numéro:</strong> #{confirmationData.client_order_number ?? confirmationData.command_id}
</div> </div>
<div className="confirmation-detail"> <div className="confirmation-detail">
<strong>Date:</strong> {new Date().toLocaleString('fr-FR')} <strong>Date:</strong> {new Date().toLocaleString('fr-FR')}
@@ -10,7 +10,7 @@
padding-top: calc(60px + clamp(1rem, 3vw, 2rem)); padding-top: calc(60px + clamp(1rem, 3vw, 2rem));
max-width: 1400px; max-width: 1400px;
margin: 0 auto; margin: 0 auto;
background: linear-gradient(to bottom, #0a0a0a, #1a1a1a); background: linear-gradient(to bottom, var(--bg), var(--surface));
} }
/* ============================================ /* ============================================
@@ -24,18 +24,14 @@
} }
.history-title { .history-title {
color: white;
font-size: clamp(2rem, 6vw, 2.5rem); font-size: clamp(2rem, 6vw, 2.5rem);
margin: 0 0 0.5rem 0; margin: 0 0 0.5rem 0;
font-weight: 700; font-weight: 700;
background: #ffffff; color: var(--text);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
} }
.history-subtitle { .history-subtitle {
color: #9ca3af; color: var(--text-muted);
font-size: clamp(0.9rem, 2vw, 1.1rem); font-size: clamp(0.9rem, 2vw, 1.1rem);
margin: 0; margin: 0;
} }
@@ -52,8 +48,8 @@
} }
.stat-card2 { .stat-card2 {
background: linear-gradient(135deg, #1a1a1a, #2a2a2a); background: linear-gradient(135deg, var(--surface), var(--surface-2));
border: 2px solid #333; border: 2px solid var(--border);
border-radius: 12px; border-radius: 12px;
padding: 1.5rem; padding: 1.5rem;
display: flex; display: flex;
@@ -160,14 +156,14 @@
} }
.stat-label { .stat-label {
color: #9ca3af; color: var(--text-muted);
font-size: 0.9rem; font-size: 0.9rem;
margin: 0 0 0.5rem 0; margin: 0 0 0.5rem 0;
font-weight: 500; font-weight: 500;
} }
.stat-value { .stat-value {
color: white; color: var(--text);
font-size: 1.8rem; font-size: 1.8rem;
font-weight: 700; font-weight: 700;
margin: 0; margin: 0;
@@ -213,7 +209,7 @@
.penalty-limit { .penalty-limit {
font-size: 1rem; font-size: 1rem;
color: #6b7280; color: var(--text-muted);
font-weight: 500; font-weight: 500;
} }
@@ -242,7 +238,7 @@
} }
.referral-link-hint { .referral-link-hint {
color: #6b7280; color: var(--text-muted);
font-size: 0.8rem; font-size: 0.8rem;
margin: 0.25rem 0 0; margin: 0.25rem 0 0;
} }
@@ -268,7 +264,7 @@
.spinner { .spinner {
width: 100%; width: 100%;
height: 100%; height: 100%;
border: 4px solid #333; border: 4px solid var(--border);
border-top-color: #7c3aed; border-top-color: #7c3aed;
border-radius: 50%; border-radius: 50%;
animation: spin 1s linear infinite; animation: spin 1s linear infinite;
@@ -281,7 +277,7 @@
} }
.loading-text { .loading-text {
color: #9ca3af; color: var(--text-muted);
font-size: 1.1rem; font-size: 1.1rem;
margin: 0; margin: 0;
} }
@@ -318,27 +314,27 @@
.empty-history { .empty-history {
text-align: center; text-align: center;
padding: 4rem 2rem; padding: 4rem 2rem;
background: linear-gradient(135deg, #1a1a1a, #2a2a2a); background: linear-gradient(135deg, var(--surface), var(--surface-2));
border: 2px solid #333; border: 2px solid var(--border);
border-radius: 12px; border-radius: 12px;
margin-top: 2rem; margin-top: 2rem;
} }
.empty-icon { .empty-icon {
color: #4b5563; color: var(--text-muted);
margin-bottom: 1.5rem; margin-bottom: 1.5rem;
opacity: 0.5; opacity: 0.5;
} }
.empty-history h2 { .empty-history h2 {
color: white; color: var(--text);
font-size: 1.5rem; font-size: 1.5rem;
margin: 0 0 0.5rem 0; margin: 0 0 0.5rem 0;
font-weight: 600; font-weight: 600;
} }
.empty-history p { .empty-history p {
color: #9ca3af; color: var(--text-muted);
font-size: 1.1rem; font-size: 1.1rem;
margin: 0 0 2rem 0; margin: 0 0 2rem 0;
} }
@@ -391,8 +387,8 @@
.table-wrapper { .table-wrapper {
overflow-x: auto; overflow-x: auto;
background-color: #1a1a1a; background-color: var(--surface);
border: 2px solid #333; border: 2px solid var(--border);
border-radius: 12px; border-radius: 12px;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3); box-shadow: 0 4px 15px rgba(0, 0, 0, 0.3);
} }
@@ -404,12 +400,12 @@
} }
.history-table thead { .history-table thead {
background: linear-gradient(135deg, #0a0a0a, #1a1a1a); background: linear-gradient(135deg, var(--bg), var(--surface));
border-bottom: 2px solid #7c3aed; border-bottom: 2px solid #7c3aed;
} }
.history-table th { .history-table th {
color: white; color: var(--text);
font-size: clamp(0.85rem, 2vw, 0.95rem); font-size: clamp(0.85rem, 2vw, 0.95rem);
font-weight: 700; font-weight: 700;
text-align: left; text-align: left;
@@ -419,7 +415,7 @@
} }
.history-table tbody tr { .history-table tbody tr {
border-bottom: 1px solid #333; border-bottom: 1px solid var(--border);
transition: all 0.2s ease; transition: all 0.2s ease;
cursor: pointer; cursor: pointer;
} }
@@ -435,11 +431,11 @@
} }
.history-table tbody tr:active { .history-table tbody tr:active {
background-color: #2a2a2a; background-color: var(--surface-2);
} }
.history-table td { .history-table td {
color: #cccccc; color: var(--text-muted);
font-size: clamp(0.85rem, 2vw, 0.95rem); font-size: clamp(0.85rem, 2vw, 0.95rem);
padding: 1.25rem 1rem; padding: 1.25rem 1rem;
vertical-align: middle; vertical-align: middle;
@@ -450,7 +446,7 @@
============================================ */ ============================================ */
.order-id { .order-id {
color: white !important; color: var(--text) !important;
font-weight: 700; font-weight: 700;
font-family: "Courier New", monospace; font-family: "Courier New", monospace;
font-size: 1rem; font-size: 1rem;
@@ -463,13 +459,13 @@
} }
.date-main { .date-main {
color: white; color: var(--text);
font-weight: 600; font-weight: 600;
font-size: 0.95rem; font-size: 0.95rem;
} }
.date-time { .date-time {
color: #9ca3af; color: var(--text-muted);
font-size: 0.85rem; font-size: 0.85rem;
} }
@@ -491,7 +487,7 @@
} }
.address-text { .address-text {
color: #d1d5db; color: var(--text-muted);
font-size: 0.9rem; font-size: 0.9rem;
} }
@@ -507,12 +503,12 @@
} }
.no-livreur { .no-livreur {
color: #6b7280; color: var(--text-muted);
font-style: italic; font-style: italic;
} }
.products-count { .products-count {
color: #9ca3af; color: var(--text-muted);
font-size: 0.9rem; font-size: 0.9rem;
} }
@@ -41,7 +41,7 @@ function ConsultationHistorique() {
const [orders, setOrders] = useState<CompletedOrder[]>([]); const [orders, setOrders] = useState<CompletedOrder[]>([]);
const [clientStats, setClientStats] = useState<ClientStats | null>(null); const [clientStats, setClientStats] = useState<ClientStats | null>(null);
const [penalties, setPenalties] = useState<PenaltyInfo | null>(null); const [penalties, setPenalties] = useState<PenaltyInfo | null>(null);
const [appSettings, setAppSettings] = useState<PublicSettings>({ penalties_enabled: true, show_amende_score: true, points_enabled: true, points_separated: true, referral_enabled: true, pool_names: ['Pool 1', 'Pool 2'], crypto_payment_enabled: false, crypto_only: false, nowpayments_currencies: [] }); const [appSettings, setAppSettings] = useState<PublicSettings>({ penalties_enabled: true, show_amende_score: true, points_enabled: true, points_separated: true, referral_enabled: true, referral_amount: 0, pool_names: ['Pool 1', 'Pool 2'], crypto_payment_enabled: false, crypto_only: false, nowpayments_currencies: [] });
const [referralBalance, setReferralBalance] = useState<number>(0); const [referralBalance, setReferralBalance] = useState<number>(0);
const [isLoading, setIsLoading] = useState(true); const [isLoading, setIsLoading] = useState(true);
const [error, setError] = useState<string>(''); const [error, setError] = useState<string>('');
@@ -365,7 +365,7 @@ function ConsultationHistorique() {
className="clickable-row" className="clickable-row"
> >
<td className="order-id"> <td className="order-id">
#{order.id.toString().padStart(5, '0')} #{(order.client_order_number ?? 0).toString().padStart(4, '0')}
</td> </td>
<td> <td>
<div className="date-cell"> <div className="date-cell">
@@ -26,7 +26,7 @@
} }
.modal2-success-container { .modal2-success-container {
background: linear-gradient(135deg, rgba(0, 0, 0, 0.95) 0%, rgba(26, 26, 26, 0.95) 100%); background: var(--surface);
border: 1px solid rgba(124, 58, 237, 0.3); border: 1px solid rgba(124, 58, 237, 0.3);
border-radius: 20px; border-radius: 20px;
padding: 52px 44px; padding: 52px 44px;
@@ -156,7 +156,7 @@
align-items: center; align-items: center;
font-size: 15px; font-size: 15px;
padding: 12px 0; padding: 12px 0;
border-bottom: 1px solid rgba(255, 255, 255, 0.04); border-bottom: 1px solid var(--border);
transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94); transition: all 0.3s cubic-bezier(0.25, 0.46, 0.45, 0.94);
} }
@@ -172,7 +172,7 @@
} }
.detail2-label { .detail2-label {
color: rgba(255, 255, 255, 0.6); color: var(--text-muted);
font-weight: 600; font-weight: 600;
letter-spacing: 0.4px; letter-spacing: 0.4px;
text-transform: uppercase; text-transform: uppercase;
+41 -41
View File
@@ -9,7 +9,7 @@
padding-top: calc(60px + clamp(1rem, 3vw, 2rem)); padding-top: calc(60px + clamp(1rem, 3vw, 2rem));
max-width: 1400px; max-width: 1400px;
margin: 0 auto; margin: 0 auto;
background: linear-gradient(to bottom, #0a0a0a, #1a1a1a); background: linear-gradient(to bottom, var(--bg), var(--surface));
} }
/* ============================================ /* ============================================
@@ -34,7 +34,7 @@
.spinner { .spinner {
width: 100%; width: 100%;
height: 100%; height: 100%;
border: 4px solid #1a1a1a; border: 4px solid var(--surface);
border-top-color: #7c3aed; border-top-color: #7c3aed;
border-radius: 50%; border-radius: 50%;
animation: spin 1s linear infinite; animation: spin 1s linear infinite;
@@ -47,7 +47,7 @@
} }
.loading-text { .loading-text {
color: #9ca3af; color: var(--text-muted);
font-size: 1.1rem; font-size: 1.1rem;
margin: 0; margin: 0;
} }
@@ -58,14 +58,14 @@
} }
.error-container h2 { .error-container h2 {
color: white; color: var(--text);
font-size: 1.8rem; font-size: 1.8rem;
margin: 0; margin: 0;
font-weight: 700; font-weight: 700;
} }
.error-container p { .error-container p {
color: #9ca3af; color: var(--text-muted);
font-size: 1.1rem; font-size: 1.1rem;
margin: 0; margin: 0;
text-align: center; text-align: center;
@@ -88,9 +88,9 @@
align-items: center; align-items: center;
gap: 0.5rem; gap: 0.5rem;
padding: 0.75rem 1.5rem; padding: 0.75rem 1.5rem;
background: #1a1a1a; background: var(--surface);
color: white; color: var(--text);
border: 1px solid #333; border: 1px solid var(--border);
border-radius: 8px; border-radius: 8px;
font-size: 1rem; font-size: 1rem;
font-weight: 600; font-weight: 600;
@@ -101,7 +101,7 @@
} }
.back-button:hover { .back-button:hover {
background: #2a2a2a; background: var(--surface-2);
border-color: #7c3aed; border-color: #7c3aed;
transform: translateX(-4px); transform: translateX(-4px);
} }
@@ -167,8 +167,8 @@
} }
.details-card { .details-card {
background: #000000; background: var(--bg);
border: 1px solid #333; border: 1px solid var(--border);
border-radius: 16px; border-radius: 16px;
overflow: hidden; overflow: hidden;
transition: all 0.3s ease; transition: all 0.3s ease;
@@ -186,8 +186,8 @@
align-items: center; align-items: center;
gap: 0.75rem; gap: 0.75rem;
padding: 1.5rem; padding: 1.5rem;
background: #1a1a1a; background: var(--surface);
border-bottom: 1px solid #333; border-bottom: 1px solid var(--border);
} }
.card-header svg { .card-header svg {
@@ -196,7 +196,7 @@
} }
.card-header h2 { .card-header h2 {
color: white; color: var(--text);
font-size: 1.25rem; font-size: 1.25rem;
margin: 0; margin: 0;
font-weight: 700; font-weight: 700;
@@ -240,7 +240,7 @@
} }
.info-label { .info-label {
color: #9ca3af; color: var(--text-muted);
font-size: 0.85rem; font-size: 0.85rem;
font-weight: 500; font-weight: 500;
text-transform: uppercase; text-transform: uppercase;
@@ -248,7 +248,7 @@
} }
.info-value { .info-value {
color: white; color: var(--text);
font-size: 1rem; font-size: 1rem;
font-weight: 600; font-weight: 600;
line-height: 1.4; line-height: 1.4;
@@ -279,8 +279,8 @@
display: flex; display: flex;
gap: 1rem; gap: 1rem;
padding: 1rem; padding: 1rem;
background: #1a1a1a; background: var(--surface);
border: 1px solid #333; border: 1px solid var(--border);
border-radius: 12px; border-radius: 12px;
transition: all 0.2s ease; transition: all 0.2s ease;
} }
@@ -295,8 +295,8 @@
height: 80px; height: 80px;
object-fit: cover; object-fit: cover;
border-radius: 8px; border-radius: 8px;
background: #0a0a0a; background: var(--bg);
border: 1px solid #333; border: 1px solid var(--border);
flex-shrink: 0; flex-shrink: 0;
} }
@@ -375,7 +375,7 @@
position: relative; position: relative;
width: 100%; width: 100%;
max-width: 900px; max-width: 900px;
background: #1a1a1a; background: var(--surface);
border-radius: 16px; border-radius: 16px;
overflow: hidden; overflow: hidden;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5); box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
@@ -446,7 +446,7 @@
} }
.product-name { .product-name {
color: white; color: var(--text);
font-size: 1.1rem; font-size: 1.1rem;
margin: 0; margin: 0;
font-weight: 600; font-weight: 600;
@@ -468,13 +468,13 @@
} }
.product-quantity { .product-quantity {
color: #9ca3af; color: var(--text-muted);
font-size: 0.9rem; font-size: 0.9rem;
font-weight: 500; font-weight: 500;
} }
.product-price { .product-price {
color: white; color: var(--text);
font-size: 0.9rem; font-size: 0.9rem;
font-weight: 600; font-weight: 600;
} }
@@ -497,19 +497,19 @@
} }
.placeholder-icon { .placeholder-icon {
color: #4b5563; color: var(--text-muted);
opacity: 0.5; opacity: 0.5;
} }
.products-placeholder p { .products-placeholder p {
color: white; color: var(--text);
font-size: 1.1rem; font-size: 1.1rem;
margin: 0; margin: 0;
font-weight: 600; font-weight: 600;
} }
.placeholder-note { .placeholder-note {
color: #6b7280; color: var(--text-muted);
font-size: 0.9rem; font-size: 0.9rem;
font-style: italic; font-style: italic;
} }
@@ -519,19 +519,19 @@
============================================ */ ============================================ */
.summary-card { .summary-card {
background: linear-gradient(135deg, #1a1a1a, #0a0a0a); background: linear-gradient(135deg, var(--surface), var(--bg));
} }
.summary-row { .summary-row {
display: flex; display: flex;
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
color: #9ca3af; color: var(--text-muted);
font-size: 1rem; font-size: 1rem;
} }
.summary-row span:last-child { .summary-row span:last-child {
color: white; color: var(--text);
font-weight: 600; font-weight: 600;
} }
@@ -542,7 +542,7 @@
.summary-divider { .summary-divider {
height: 1px; height: 1px;
background: linear-gradient(to right, transparent, #333, transparent); background: linear-gradient(to right, transparent, var(--border), transparent);
margin: 0.5rem 0; margin: 0.5rem 0;
} }
@@ -553,7 +553,7 @@
} }
.total-row span:first-child { .total-row span:first-child {
color: white; color: var(--text);
} }
.total-amount { .total-amount {
@@ -570,12 +570,12 @@
} }
.delivery-notes { .delivery-notes {
color: #d1d5db; color: var(--text-muted);
font-size: 1rem; font-size: 1rem;
line-height: 1.6; line-height: 1.6;
margin: 0; margin: 0;
padding: 1rem; padding: 1rem;
background: #1a1a1a; background: var(--surface);
border-left: 3px solid #7c3aed; border-left: 3px solid #7c3aed;
border-radius: 8px; border-radius: 8px;
} }
@@ -585,15 +585,15 @@
============================================ */ ============================================ */
.delivery-timeline { .delivery-timeline {
background: #000000; background: var(--bg);
border: 1px solid #333; border: 1px solid var(--border);
border-radius: 16px; border-radius: 16px;
padding: 2rem; padding: 2rem;
margin-top: 2rem; margin-top: 2rem;
} }
.timeline-title { .timeline-title {
color: white; color: var(--text);
font-size: 1.5rem; font-size: 1.5rem;
margin: 0 0 2rem 0; margin: 0 0 2rem 0;
font-weight: 700; font-weight: 700;
@@ -629,8 +629,8 @@
top: 0; top: 0;
width: 16px; width: 16px;
height: 16px; height: 16px;
background: #1a1a1a; background: var(--surface);
border: 3px solid #333; border: 3px solid var(--border);
border-radius: 50%; border-radius: 50%;
z-index: 1; z-index: 1;
transition: all 0.3s ease; transition: all 0.3s ease;
@@ -643,14 +643,14 @@
} }
.timeline-content h3 { .timeline-content h3 {
color: white; color: var(--text);
font-size: 1.1rem; font-size: 1.1rem;
margin: 0 0 0.5rem 0; margin: 0 0 0.5rem 0;
font-weight: 600; font-weight: 600;
} }
.timeline-content p { .timeline-content p {
color: #9ca3af; color: var(--text-muted);
font-size: 0.95rem; font-size: 0.95rem;
margin: 0; margin: 0;
} }
+8 -10
View File
@@ -1,9 +1,3 @@
// ============================================
// pages/OrderDetails.tsx
// ============================================
// Page de détails d'une commande spécifique
// ✅ AJOUT: Vérification continue de l'authentification
import { useState, useEffect } from "react"; import { useState, useEffect } from "react";
import { useParams, useNavigate } from "react-router-dom"; import { useParams, useNavigate } from "react-router-dom";
import Navbar from "../../components/Navbar"; import Navbar from "../../components/Navbar";
@@ -251,7 +245,6 @@ function OrderDetails() {
}, [order?.products]); }, [order?.products]);
const fetchOrderDetails = async (id: number) => { const fetchOrderDetails = async (id: number) => {
// ✅ Vérifier l'auth avant de charger les détails
if (!isUserAuthenticated()) { if (!isUserAuthenticated()) {
console.log("❌ [fetchOrderDetails] Non authentifié"); console.log("❌ [fetchOrderDetails] Non authentifié");
navigate("/login/client", { replace: true }); navigate("/login/client", { replace: true });
@@ -276,6 +269,8 @@ function OrderDetails() {
const orderData: OrderDetailsData = { const orderData: OrderDetailsData = {
// Infos de command_info // Infos de command_info
id: apiData.command_info?.id || id, id: apiData.command_info?.id || id,
client_order_number:
apiData.command_info?.client_order_number || 0,
username: apiData.client_info?.username || "", username: apiData.client_info?.username || "",
status: apiData.command_info?.command_status || "unknown", status: apiData.command_info?.command_status || "unknown",
adresse: apiData.command_info?.command_address || "", adresse: apiData.command_info?.command_address || "",
@@ -302,11 +297,11 @@ function OrderDetails() {
id: item.id, id: item.id,
product_id: item.product_id, product_id: item.product_id,
name_product: item.produit, name_product: item.produit,
category: "Non spécifié", // Pas de catégorie dans command_items category: "Non spécifié",
price: item.prix, price: item.prix,
quantity: item.quantite, quantity: item.quantite,
status: item.status, status: item.status,
image: item.image, // Si vous avez des images image: item.image,
})) || [], })) || [],
}; };
@@ -390,7 +385,10 @@ function OrderDetails() {
</button> </button>
<div className="header-info"> <div className="header-info">
<h1 className="order-number"> <h1 className="order-number">
Commande #{order.id.toString().padStart(5, "0")} Commande #
{(order.client_order_number ?? 0)
.toString()
.padStart(4, "0")}
</h1> </h1>
<div className="status-container"> <div className="status-container">
<span className="status-badge delivered"> <span className="status-badge delivered">
+60 -13
View File
@@ -9,7 +9,7 @@
padding-top: calc(60px + clamp(1.5rem, 4vw, 2.5rem)); padding-top: calc(60px + clamp(1.5rem, 4vw, 2.5rem));
max-width: 900px; max-width: 900px;
margin: 0 auto; margin: 0 auto;
background: linear-gradient(to bottom, #0a0a0a, #1a1a1a); background: linear-gradient(to bottom, var(--bg), var(--surface));
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 2rem; gap: 2rem;
@@ -41,7 +41,7 @@
} }
.parrainage-subtitle { .parrainage-subtitle {
color: #9ca3af; color: var(--text-muted);
font-size: clamp(0.95rem, 2.5vw, 1.1rem); font-size: clamp(0.95rem, 2.5vw, 1.1rem);
margin: 0; margin: 0;
} }
@@ -59,7 +59,7 @@
} }
.balance-label { .balance-label {
color: #9ca3af; color: var(--text-muted);
font-size: 0.875rem; font-size: 0.875rem;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.08em; letter-spacing: 0.08em;
@@ -67,7 +67,7 @@
} }
.balance-amount { .balance-amount {
color: #6b7280; color: var(--text-muted);
font-size: clamp(2.5rem, 7vw, 3.5rem); font-size: clamp(2.5rem, 7vw, 3.5rem);
font-weight: 700; font-weight: 700;
line-height: 1; line-height: 1;
@@ -79,7 +79,7 @@
} }
.balance-loading { .balance-loading {
color: #6b7280; color: var(--text-muted);
font-size: 1.1rem; font-size: 1.1rem;
} }
@@ -89,12 +89,59 @@
margin-top: 0.5rem; margin-top: 0.5rem;
} }
/* ============================================
RÉCOMPENSE PAR PARRAINAGE
============================================ */
.parrainage-reward-card {
display: flex;
gap: 1rem;
background: linear-gradient(135deg, rgba(139, 92, 246, 0.12), rgba(99, 102, 241, 0.08));
border: 1px solid rgba(139, 92, 246, 0.35);
border-radius: 14px;
padding: 1.5rem;
align-items: center;
}
.reward-icon {
font-size: 2.2rem;
flex-shrink: 0;
color: #8b5cf6;
}
.reward-content {
display: flex;
flex-direction: column;
gap: 0.25rem;
}
.reward-label {
color: var(--text-muted);
font-size: 0.8rem;
text-transform: uppercase;
letter-spacing: 0.08em;
}
.reward-amount {
color: #8b5cf6;
font-size: clamp(1.8rem, 5vw, 2.4rem);
font-weight: 700;
line-height: 1.1;
}
.reward-hint {
color: var(--text-muted);
font-size: 0.82rem;
line-height: 1.5;
margin: 0.2rem 0 0;
}
/* ============================================ /* ============================================
ÉTAPES ÉTAPES
============================================ */ ============================================ */
.parrainage-section-title { .parrainage-section-title {
color: #e5e7eb; color: var(--text);
font-size: 1.2rem; font-size: 1.2rem;
font-weight: 600; font-weight: 600;
margin: 0 0 1.25rem; margin: 0 0 1.25rem;
@@ -110,8 +157,8 @@
} }
.step-card { .step-card {
background: #111115; background: var(--surface);
border: 1px solid rgba(255, 255, 255, 0.07); border: 1px solid var(--border);
border-radius: 12px; border-radius: 12px;
padding: 1.25rem 1rem; padding: 1.25rem 1rem;
text-align: center; text-align: center;
@@ -138,14 +185,14 @@
} }
.step-title { .step-title {
color: #f4f4f5; color: var(--text);
font-size: 0.95rem; font-size: 0.95rem;
font-weight: 600; font-weight: 600;
margin: 0 0 0.5rem; margin: 0 0 0.5rem;
} }
.step-desc { .step-desc {
color: #9ca3af; color: var(--text-muted);
font-size: 0.82rem; font-size: 0.82rem;
line-height: 1.5; line-height: 1.5;
margin: 0; margin: 0;
@@ -179,7 +226,7 @@
} }
.warning-text { .warning-text {
color: #d1d5db; color: var(--text-muted);
font-size: 0.875rem; font-size: 0.875rem;
line-height: 1.55; line-height: 1.55;
margin: 0 0 0.75rem; margin: 0 0 0.75rem;
@@ -190,7 +237,7 @@
border-radius: 8px; border-radius: 8px;
padding: 0.6rem 0.75rem; padding: 0.6rem 0.75rem;
font-size: 0.85rem; font-size: 0.85rem;
color: #e5e7eb; color: var(--text);
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
gap: 0.4rem; gap: 0.4rem;
@@ -213,7 +260,7 @@
} }
.cta-text { .cta-text {
color: #9ca3af; color: var(--text-muted);
font-size: 0.9rem; font-size: 0.9rem;
margin: 0 0 1.25rem; margin: 0 0 1.25rem;
} }
@@ -2,6 +2,7 @@ import { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import Navbar from '../../components/Navbar'; import Navbar from '../../components/Navbar';
import { getReferralBalance, isUserAuthenticated, getPublicSettings } from '../../api/api'; import { getReferralBalance, isUserAuthenticated, getPublicSettings } from '../../api/api';
import type { PublicSettings } from '../../api/api';
import './Parrainage.css'; import './Parrainage.css';
const TELEGRAM_URL = 'https://t.me/'; const TELEGRAM_URL = 'https://t.me/';
@@ -37,6 +38,7 @@ export default function Parrainage() {
const navigate = useNavigate(); const navigate = useNavigate();
const [balance, setBalance] = useState<number>(0); const [balance, setBalance] = useState<number>(0);
const [loading, setLoading] = useState(true); const [loading, setLoading] = useState(true);
const [settings, setSettings] = useState<PublicSettings | null>(null);
useEffect(() => { useEffect(() => {
if (!isUserAuthenticated()) { if (!isUserAuthenticated()) {
@@ -48,6 +50,7 @@ export default function Parrainage() {
navigate('/user/accueil', { replace: true }); navigate('/user/accueil', { replace: true });
return; return;
} }
setSettings(s);
getReferralBalance().then((res) => { getReferralBalance().then((res) => {
if (res.success) setBalance(res.balance); if (res.success) setBalance(res.balance);
setLoading(false); setLoading(false);
@@ -85,6 +88,21 @@ export default function Parrainage() {
)} )}
</div> </div>
{/* Montant par parrainage */}
{settings && settings.referral_amount > 0 && (
<div className="parrainage-reward-card">
<div className="reward-icon"><i className="fas fa-coins"></i></div>
<div className="reward-content">
<div className="reward-label">Crédit par filleul parrainé</div>
<div className="reward-amount">{settings.referral_amount.toFixed(2)} </div>
<p className="reward-hint">
Vous recevrez ce montant sur votre solde dès que votre filleul
effectue sa première commande validée.
</p>
</div>
</div>
)}
{/* Étapes */} {/* Étapes */}
<div className="parrainage-steps-section"> <div className="parrainage-steps-section">
<h2 className="parrainage-section-title">Comment ça marche ?</h2> <h2 className="parrainage-section-title">Comment ça marche ?</h2>
+40 -43
View File
@@ -9,14 +9,14 @@
padding: clamp(1rem, 3vw, 2rem); padding: clamp(1rem, 3vw, 2rem);
padding-top: calc(60px + clamp(1rem, 3vw, 2rem)); padding-top: calc(60px + clamp(1rem, 3vw, 2rem));
box-sizing: border-box; box-sizing: border-box;
background: linear-gradient(135deg, #0f0f0f 0%, #1a1a1a 100%); background: var(--bg);
} }
/* Back Button */ /* Back Button */
.product-detail-container > .back-button { .product-detail-container > .back-button {
background: linear-gradient(135deg, rgba(255, 255, 255, 0.05) 0%, rgba(255, 255, 255, 0.02) 100%); background: var(--surface-2);
color: white; color: var(--text);
border: 1px solid rgba(255, 255, 255, 0.1); border: 1px solid var(--border);
border-radius: 12px; border-radius: 12px;
padding: clamp(0.75rem, 2vw, 1rem) clamp(1.5rem, 3vw, 2rem); padding: clamp(0.75rem, 2vw, 1rem) clamp(1.5rem, 3vw, 2rem);
font-size: clamp(0.95rem, 3vw, 1.05rem); font-size: clamp(0.95rem, 3vw, 1.05rem);
@@ -33,10 +33,10 @@
} }
.product-detail-container > .back-button:hover { .product-detail-container > .back-button:hover {
background: linear-gradient(135deg, rgba(255, 255, 255, 0.08) 0%, rgba(255, 255, 255, 0.04) 100%); background: var(--surface);
border-color: rgba(255, 255, 255, 0.2); border-color: var(--border);
transform: translateY(-2px); transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3); box-shadow: 0 6px 20px rgba(0, 0, 0, 0.15);
} }
.product-detail-container > .back-button:active { .product-detail-container > .back-button:active {
@@ -71,9 +71,9 @@
border-radius: 20px; border-radius: 20px;
overflow: hidden; overflow: hidden;
display: flex; display: flex;
background: linear-gradient(135deg, rgba(255, 255, 255, 0.03) 0%, rgba(255, 255, 255, 0.01) 100%); background: var(--surface);
border: 1px solid rgba(255, 255, 255, 0.08); border: 1px solid var(--border);
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.3); box-shadow: 0 8px 32px rgba(0, 0, 0, 0.15);
backdrop-filter: blur(8px); backdrop-filter: blur(8px);
transition: all 0.3s ease; transition: all 0.3s ease;
} }
@@ -140,15 +140,12 @@
} }
.product-detail-name { .product-detail-name {
color: white; color: var(--text);
font-size: clamp(2rem, 7vw, 3.5rem); font-size: clamp(2rem, 7vw, 3.5rem);
margin: 0; margin: 0;
font-weight: 700; font-weight: 700;
line-height: 1.1; line-height: 1.1;
background: linear-gradient(135deg, #ffffff 0%, #e0e0e0 100%); -webkit-text-fill-color: unset;
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
letter-spacing: -1px; letter-spacing: -1px;
} }
@@ -175,8 +172,8 @@
/* Description */ /* Description */
.product-description { .product-description {
background: linear-gradient(135deg, rgba(255, 255, 255, 0.03) 0%, rgba(255, 255, 255, 0.01) 100%); background: var(--surface);
border: 1px solid rgba(255, 255, 255, 0.08); border: 1px solid var(--border);
border-left: 3px solid var(--cat-color, #7c3aed); border-left: 3px solid var(--cat-color, #7c3aed);
border-radius: 12px; border-radius: 12px;
padding: clamp(1.25rem, 3vw, 1.75rem); padding: clamp(1.25rem, 3vw, 1.75rem);
@@ -191,7 +188,7 @@
} }
.product-description h3 { .product-description h3 {
color: rgba(255, 255, 255, 0.9); color: var(--text);
font-size: clamp(1.1rem, 4vw, 1.3rem); font-size: clamp(1.1rem, 4vw, 1.3rem);
margin: 0 0 1rem 0; margin: 0 0 1rem 0;
font-weight: 600; font-weight: 600;
@@ -200,7 +197,7 @@
} }
.product-description p { .product-description p {
color: rgba(255, 255, 255, 0.7); color: var(--text-muted);
font-size: clamp(1rem, 3vw, 1.1rem); font-size: clamp(1rem, 3vw, 1.1rem);
margin: 0; margin: 0;
line-height: 1.7; line-height: 1.7;
@@ -213,9 +210,9 @@
gap: clamp(1rem, 3vw, 1.5rem); gap: clamp(1rem, 3vw, 1.5rem);
flex-wrap: wrap; flex-wrap: wrap;
padding: clamp(1rem, 3vw, 1.5rem); padding: clamp(1rem, 3vw, 1.5rem);
background: rgba(255, 255, 255, 0.02); background: var(--surface);
border-radius: 12px; border-radius: 12px;
border: 1px solid rgba(255, 255, 255, 0.05); border: 1px solid var(--border);
} }
/* Grams Selector */ /* Grams Selector */
@@ -228,7 +225,7 @@
} }
.grams-selector label { .grams-selector label {
color: rgba(255, 255, 255, 0.9); color: var(--text);
font-size: clamp(1rem, 3vw, 1.15rem); font-size: clamp(1rem, 3vw, 1.15rem);
font-weight: 600; font-weight: 600;
white-space: nowrap; white-space: nowrap;
@@ -236,9 +233,9 @@
.grams-dropdown { .grams-dropdown {
flex: 1; flex: 1;
background: linear-gradient(135deg, rgba(255, 255, 255, 0.05) 0%, rgba(255, 255, 255, 0.02) 100%); background: var(--surface-2);
color: white; color: var(--text);
border: 1px solid rgba(255, 255, 255, 0.1); border: 1px solid var(--border);
border-radius: 10px; border-radius: 10px;
padding: clamp(0.75rem, 2vw, 1rem) clamp(1rem, 3vw, 1.25rem); padding: clamp(0.75rem, 2vw, 1rem) clamp(1rem, 3vw, 1.25rem);
font-size: clamp(1rem, 3vw, 1.1rem); font-size: clamp(1rem, 3vw, 1.1rem);
@@ -275,17 +272,17 @@
/* Styles des options - Supprimer le hover natif */ /* Styles des options - Supprimer le hover natif */
.grams-dropdown option { .grams-dropdown option {
background-color: #1a1a1a; background-color: var(--surface);
color: white; color: var(--text);
padding: 1rem; padding: 1rem;
font-size: 1rem; font-size: 1rem;
font-weight: 600; font-weight: 600;
} }
.grams-dropdown option:hover { .grams-dropdown option:hover {
background-color: #1a1a1a !important; background-color: var(--surface) !important;
background: #1a1a1a !important; background: var(--surface) !important;
color: white !important; color: var(--text) !important;
} }
.grams-dropdown option:checked { .grams-dropdown option:checked {
@@ -295,7 +292,7 @@
} }
.grams-dropdown option:focus { .grams-dropdown option:focus {
background-color: #1a1a1a !important; background-color: var(--surface) !important;
outline: none !important; outline: none !important;
} }
@@ -303,7 +300,7 @@
.grams-dropdown option:hover, .grams-dropdown option:hover,
.grams-dropdown option:focus, .grams-dropdown option:focus,
.grams-dropdown option:active { .grams-dropdown option:active {
background-color: #1a1a1a !important; background-color: var(--surface) !important;
background-image: none !important; background-image: none !important;
box-shadow: none !important; box-shadow: none !important;
} }
@@ -311,7 +308,7 @@
/* Pour Firefox */ /* Pour Firefox */
@-moz-document url-prefix() { @-moz-document url-prefix() {
.grams-dropdown option:hover { .grams-dropdown option:hover {
background-color: #1a1a1a !important; background-color: var(--surface) !important;
} }
} }
@@ -386,8 +383,8 @@
} }
.add-to-cart-button.disabled { .add-to-cart-button.disabled {
background: linear-gradient(135deg, rgba(255, 255, 255, 0.08) 0%, rgba(255, 255, 255, 0.05) 100%); background: var(--surface-2);
color: rgba(255, 255, 255, 0.4); color: var(--text-muted);
cursor: not-allowed; cursor: not-allowed;
box-shadow: none; box-shadow: none;
} }
@@ -407,7 +404,7 @@
background: linear-gradient(135deg, rgba(239, 68, 68, 0.1) 0%, rgba(239, 68, 68, 0.05) 100%); background: linear-gradient(135deg, rgba(239, 68, 68, 0.1) 0%, rgba(239, 68, 68, 0.05) 100%);
border: 1px solid rgba(239, 68, 68, 0.3); border: 1px solid rgba(239, 68, 68, 0.3);
border-radius: 16px; border-radius: 16px;
color: white; color: var(--text);
animation: slideUp 0.5s ease-out; animation: slideUp 0.5s ease-out;
} }
@@ -418,9 +415,9 @@
} }
.error-message .back-button { .error-message .back-button {
background: linear-gradient(135deg, rgba(255, 255, 255, 0.05) 0%, rgba(255, 255, 255, 0.02) 100%); background: var(--surface-2);
color: white; color: var(--text);
border: 1px solid rgba(255, 255, 255, 0.1); border: 1px solid var(--border);
border-radius: 10px; border-radius: 10px;
padding: clamp(0.75rem, 2vw, 1rem) clamp(1.5rem, 3vw, 2rem); padding: clamp(0.75rem, 2vw, 1rem) clamp(1.5rem, 3vw, 2rem);
font-size: clamp(1rem, 3vw, 1.1rem); font-size: clamp(1rem, 3vw, 1.1rem);
@@ -431,8 +428,8 @@
} }
.error-message .back-button:hover { .error-message .back-button:hover {
background: linear-gradient(135deg, rgba(255, 255, 255, 0.08) 0%, rgba(255, 255, 255, 0.04) 100%); background: var(--surface);
border-color: rgba(255, 255, 255, 0.2); border-color: var(--border);
transform: translateY(-2px); transform: translateY(-2px);
} }
@@ -449,13 +446,13 @@
padding: clamp(3rem, 8vw, 5rem); padding: clamp(3rem, 8vw, 5rem);
text-align: center; text-align: center;
min-height: 400px; min-height: 400px;
color: white; color: var(--text);
animation: slideUp 0.5s ease-out; animation: slideUp 0.5s ease-out;
} }
.loading-container p { .loading-container p {
font-size: clamp(1rem, 3vw, 1.2rem); font-size: clamp(1rem, 3vw, 1.2rem);
color: rgba(255, 255, 255, 0.7); color: var(--text-muted);
margin-top: 1.5rem; margin-top: 1.5rem;
} }
+141 -13
View File
@@ -33,13 +33,13 @@
.profile-title { .profile-title {
font-size: 1.6rem; font-size: 1.6rem;
font-weight: 700; font-weight: 700;
color: #f0f0f0; color: var(--text);
margin: 0; margin: 0;
} }
.profile-username { .profile-username {
font-size: 0.9rem; font-size: 0.9rem;
color: #9ca3af; color: var(--text-muted);
margin: 0.2rem 0 0; margin: 0.2rem 0 0;
} }
@@ -66,8 +66,8 @@
/* Cards */ /* Cards */
.profile-card { .profile-card {
background: #1e1e2e; background: var(--surface);
border: 1px solid #2d2d40; border: 1px solid var(--border);
border-radius: 12px; border-radius: 12px;
padding: 1.5rem; padding: 1.5rem;
margin-bottom: 1.2rem; margin-bottom: 1.2rem;
@@ -76,7 +76,7 @@
.profile-card-title { .profile-card-title {
font-size: 1rem; font-size: 1rem;
font-weight: 600; font-weight: 600;
color: #e2e8f0; color: var(--text);
margin: 0 0 1rem; margin: 0 0 1rem;
display: flex; display: flex;
align-items: center; align-items: center;
@@ -86,10 +86,11 @@
.profile-card-icon { color: #7c3aed; } .profile-card-icon { color: #7c3aed; }
.profile-card-icon--address { color: #10b981; } .profile-card-icon--address { color: #10b981; }
.profile-card-icon--phone { color: #3b82f6; } .profile-card-icon--phone { color: #3b82f6; }
.profile-card-icon--telegram { color: #2AABEE; }
.profile-hint { .profile-hint {
font-size: 0.82rem; font-size: 0.82rem;
color: #6b7280; color: var(--text-muted);
margin: -0.5rem 0 1rem; margin: -0.5rem 0 1rem;
line-height: 1.5; line-height: 1.5;
} }
@@ -108,15 +109,15 @@
.profile-group label { .profile-group label {
font-size: 0.82rem; font-size: 0.82rem;
font-weight: 500; font-weight: 500;
color: #9ca3af; color: var(--text-muted);
} }
.profile-group input { .profile-group input {
background: #12121f; background: var(--bg);
border: 1px solid #2d2d40; border: 1px solid var(--border);
border-radius: 8px; border-radius: 8px;
padding: 0.65rem 0.9rem; padding: 0.65rem 0.9rem;
color: #e2e8f0; color: var(--text);
font-size: 0.9rem; font-size: 0.9rem;
outline: none; outline: none;
transition: border-color 0.2s; transition: border-color 0.2s;
@@ -125,7 +126,7 @@
} }
.profile-group input:focus { border-color: #7c3aed; } .profile-group input:focus { border-color: #7c3aed; }
.profile-group input::placeholder { color: #4b5563; } .profile-group input::placeholder { color: var(--text-muted); }
/* Buttons */ /* Buttons */
.profile-btn { .profile-btn {
@@ -145,14 +146,141 @@
} }
.profile-btn--secondary { .profile-btn--secondary {
background: #1a3a5c; background: var(--surface-2);
color: #60a5fa; color: #60a5fa;
border: 1px solid #2563eb44; border: 1px solid rgba(37, 99, 235, 0.27);
} }
.profile-btn:hover { opacity: 0.85; } .profile-btn:hover { opacity: 0.85; }
.profile-btn:disabled { opacity: 0.5; cursor: not-allowed; } .profile-btn:disabled { opacity: 0.5; cursor: not-allowed; }
.profile-btn--telegram {
background: #2AABEE;
}
.profile-btn--danger {
background: transparent;
border: 1px solid #ef444466;
color: #ef4444;
}
.profile-telegram-linked {
display: flex;
flex-direction: column;
gap: 0.8rem;
}
.profile-telegram-status {
display: flex;
align-items: center;
gap: 0.5rem;
color: #10b981;
font-size: 0.88rem;
font-weight: 500;
}
@media (max-width: 480px) { @media (max-width: 480px) {
.profile-row { grid-template-columns: 1fr; } .profile-row { grid-template-columns: 1fr; }
} }
/* Modal confirmation */
.profile-modal-overlay {
position: fixed;
inset: 0;
background: rgba(0, 0, 0, 0.6);
display: flex;
align-items: center;
justify-content: center;
z-index: 1000;
padding: 1rem;
backdrop-filter: blur(2px);
}
.profile-modal {
background: var(--surface);
border: 1px solid var(--border);
border-radius: 14px;
padding: 2rem 1.8rem 1.6rem;
max-width: 400px;
width: 100%;
position: relative;
text-align: center;
box-shadow: 0 20px 60px rgba(0, 0, 0, 0.5);
}
.profile-modal-close {
position: absolute;
top: 0.8rem;
right: 0.9rem;
background: transparent;
border: none;
color: var(--text-muted);
font-size: 1rem;
cursor: pointer;
padding: 0.3rem 0.5rem;
border-radius: 6px;
transition: color 0.2s;
}
.profile-modal-close:hover { color: var(--text); }
.profile-modal-icon {
width: 52px;
height: 52px;
border-radius: 50%;
background: rgba(37, 99, 235, 0.15);
border: 1px solid rgba(37, 99, 235, 0.3);
display: flex;
align-items: center;
justify-content: center;
font-size: 1.3rem;
color: #60a5fa;
margin: 0 auto 1.1rem;
}
.profile-modal-title {
font-size: 1.05rem;
font-weight: 700;
color: var(--text);
margin: 0 0 0.6rem;
}
.profile-modal-body {
font-size: 0.85rem;
color: var(--text-muted);
line-height: 1.55;
margin: 0 0 1.5rem;
}
.profile-modal-actions {
display: flex;
gap: 0.8rem;
justify-content: center;
}
.profile-modal-btn {
flex: 1;
padding: 0.65rem 1rem;
border-radius: 8px;
font-size: 0.88rem;
font-weight: 600;
cursor: pointer;
border: none;
transition: opacity 0.2s;
display: flex;
align-items: center;
justify-content: center;
gap: 0.4rem;
}
.profile-modal-btn:hover { opacity: 0.85; }
.profile-modal-btn--cancel {
background: var(--bg);
border: 1px solid var(--border);
color: var(--text-muted);
}
.profile-modal-btn--confirm {
background: var(--surface-2);
border: 1px solid rgba(37, 99, 235, 0.27);
color: #60a5fa;
}
+88 -3
View File
@@ -1,11 +1,11 @@
import { useState, useEffect } from 'react'; import { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom'; import { useNavigate } from 'react-router-dom';
import Navbar from '../../components/Navbar'; import Navbar from '../../components/Navbar';
import { isUserAuthenticated, extractUsernameFromToken, getMyProfile, updateMyProfile } from '../../api/api'; import { isUserAuthenticated, extractUsernameFromToken, getMyProfile, updateMyProfile, getTelegramStatus, generateTelegramLinkToken, unlinkTelegram } from '../../api/api';
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'; import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
import { import {
faUser, faMapMarkerAlt, faPhone, faCommentDots, faUser, faMapMarkerAlt, faPhone, faCommentDots,
faSave, faCheckCircle, faExclamationTriangle, faSave, faCheckCircle, faExclamationTriangle, faPaperPlane, faUnlink, faTimes, faLock,
} from '@fortawesome/free-solid-svg-icons'; } from '@fortawesome/free-solid-svg-icons';
import './ProfilePage.css'; import './ProfilePage.css';
@@ -32,6 +32,14 @@ export default function ProfilePage() {
const [successMsg, setSuccessMsg] = useState(''); const [successMsg, setSuccessMsg] = useState('');
const [errorMsg, setErrorMsg] = useState(''); const [errorMsg, setErrorMsg] = useState('');
// Telegram
const [tgLinked, setTgLinked] = useState(false);
const [tgEnabled, setTgEnabled] = useState(false);
const [tgLoading, setTgLoading] = useState(false);
// Modal confirmation infos par défaut
const [showSaveModal, setShowSaveModal] = useState(false);
const username = extractUsernameFromToken() ?? ''; const username = extractUsernameFromToken() ?? '';
useEffect(() => { useEffect(() => {
@@ -44,6 +52,9 @@ export default function ProfilePage() {
setDefaultPhone(localStorage.getItem(STORAGE_PHONE) ?? ''); setDefaultPhone(localStorage.getItem(STORAGE_PHONE) ?? '');
setSignalPseudo(localStorage.getItem(STORAGE_SIGNAL) || username); setSignalPseudo(localStorage.getItem(STORAGE_SIGNAL) || username);
// Statut Telegram
getTelegramStatus().then((s) => { setTgLinked(s.linked); setTgEnabled(s.enabled); });
// Charger depuis backend // Charger depuis backend
getMyProfile().then((res) => { getMyProfile().then((res) => {
if (res.success && res.client) { if (res.success && res.client) {
@@ -74,9 +85,28 @@ export default function ProfilePage() {
localStorage.setItem(STORAGE_ADDRESS, defaultAddress.trim()); localStorage.setItem(STORAGE_ADDRESS, defaultAddress.trim());
localStorage.setItem(STORAGE_PHONE, defaultPhone.trim()); localStorage.setItem(STORAGE_PHONE, defaultPhone.trim());
localStorage.setItem(STORAGE_SIGNAL, signalPseudo.trim()); localStorage.setItem(STORAGE_SIGNAL, signalPseudo.trim());
setShowSaveModal(false);
showSuccess('Informations par défaut enregistrées'); showSuccess('Informations par défaut enregistrées');
}; };
const handleLinkTelegram = async () => {
setTgLoading(true);
const res = await generateTelegramLinkToken();
setTgLoading(false);
if (res.error || !res.link_url) {
showError(res.error || 'Service Telegram non disponible');
return;
}
window.open(res.link_url, '_blank');
};
const handleUnlinkTelegram = async () => {
if (!window.confirm('Délier votre compte Telegram ? Vous ne recevrez plus de notifications.')) return;
await unlinkTelegram();
setTgLinked(false);
showSuccess('Compte Telegram délié');
};
const saveContact = async () => { const saveContact = async () => {
setSavingContact(true); setSavingContact(true);
const res = await updateMyProfile({ nom: nom.trim(), prenom: prenom.trim(), telephone: telephone.trim() }); const res = await updateMyProfile({ nom: nom.trim(), prenom: prenom.trim(), telephone: telephone.trim() });
@@ -165,6 +195,9 @@ export default function ProfilePage() {
<FontAwesomeIcon icon={faSave} /> <FontAwesomeIcon icon={faSave} />
{savingContact ? ' Enregistrement...' : ' Enregistrer le compte'} {savingContact ? ' Enregistrement...' : ' Enregistrer le compte'}
</button> </button>
<button className="profile-btn profile-btn--secondary" onClick={() => navigate('/user/change-password')} style={{ marginTop: '0.6rem' }}>
<FontAwesomeIcon icon={faLock} /> Changer le mot de passe
</button>
</div> </div>
{/* Section adresse par défaut */} {/* Section adresse par défaut */}
@@ -217,11 +250,63 @@ export default function ProfilePage() {
placeholder="@votre.pseudo.signal" placeholder="@votre.pseudo.signal"
/> />
</div> </div>
<button className="profile-btn profile-btn--secondary" onClick={saveLocal}> <button className="profile-btn profile-btn--secondary" onClick={() => setShowSaveModal(true)}>
<FontAwesomeIcon icon={faSave} /> Enregistrer les infos par défaut <FontAwesomeIcon icon={faSave} /> Enregistrer les infos par défaut
</button> </button>
</div> </div>
{/* Section Telegram */}
{tgEnabled && (
<div className="profile-card">
<h2 className="profile-card-title">
<FontAwesomeIcon icon={faPaperPlane} className="profile-card-icon profile-card-icon--telegram" />
Notifications Telegram
</h2>
<p className="profile-hint">
Recevez vos notifications sur Telegram, même quand le site est fermé.
</p>
{tgLinked ? (
<div className="profile-telegram-linked">
<span className="profile-telegram-status">
<FontAwesomeIcon icon={faCheckCircle} /> Compte Telegram lié
</span>
<button className="profile-btn profile-btn--danger" onClick={handleUnlinkTelegram}>
<FontAwesomeIcon icon={faUnlink} /> Délier Telegram
</button>
</div>
) : (
<button className="profile-btn profile-btn--telegram" onClick={handleLinkTelegram} disabled={tgLoading}>
<FontAwesomeIcon icon={faPaperPlane} />
{tgLoading ? ' Génération du lien...' : ' Lier mon compte Telegram'}
</button>
)}
</div>
)}
</div> </div>
{showSaveModal && (
<div className="profile-modal-overlay" onClick={() => setShowSaveModal(false)}>
<div className="profile-modal" onClick={(e) => e.stopPropagation()}>
<button className="profile-modal-close" onClick={() => setShowSaveModal(false)}>
<FontAwesomeIcon icon={faTimes} />
</button>
<div className="profile-modal-icon">
<FontAwesomeIcon icon={faSave} />
</div>
<h3 className="profile-modal-title">Enregistrer les infos par défaut ?</h3>
<p className="profile-modal-body">
Adresse, téléphone de livraison et pseudo Signal seront sauvegardés localement et pré-remplis lors de vos prochaines commandes.
</p>
<div className="profile-modal-actions">
<button className="profile-modal-btn profile-modal-btn--cancel" onClick={() => setShowSaveModal(false)}>
Annuler
</button>
<button className="profile-modal-btn profile-modal-btn--confirm" onClick={saveLocal}>
<FontAwesomeIcon icon={faCheckCircle} /> Confirmer
</button>
</div>
</div>
</div>
)}
</> </>
); );
} }
+68 -68
View File
@@ -9,8 +9,8 @@
padding-top: calc(60px + clamp(1.5rem, 4vw, 2.5rem)); padding-top: calc(60px + clamp(1.5rem, 4vw, 2.5rem));
max-width: 860px; max-width: 860px;
margin: 0 auto; margin: 0 auto;
background: #0d0d0d; background: var(--bg);
color: white; color: var(--text);
} }
/* ===== HEADER ===== */ /* ===== HEADER ===== */
@@ -21,14 +21,14 @@
.suivi-header h1 { .suivi-header h1 {
font-size: clamp(1.6rem, 5vw, 2.2rem); font-size: clamp(1.6rem, 5vw, 2.2rem);
color: #fff; color: var(--text);
margin: 0 0 0.3rem 0; margin: 0 0 0.3rem 0;
letter-spacing: -0.5px; letter-spacing: -0.5px;
} }
.suivi-header p { .suivi-header p {
font-size: clamp(0.85rem, 2.5vw, 0.95rem); font-size: clamp(0.85rem, 2.5vw, 0.95rem);
color: rgba(255, 255, 255, 0.4); color: var(--text-muted);
margin: 0; margin: 0;
} }
@@ -88,7 +88,7 @@
} }
.loading-state p { .loading-state p {
color: rgba(255, 255, 255, 0.45); color: var(--text-muted);
font-size: 0.95rem; font-size: 0.95rem;
} }
@@ -96,26 +96,26 @@
.empty-state { .empty-state {
text-align: center; text-align: center;
padding: clamp(3rem, 8vw, 5rem) 2rem; padding: clamp(3rem, 8vw, 5rem) 2rem;
border: 1px solid rgba(255, 255, 255, 0.06); border: 1px solid var(--border);
border-radius: 20px; border-radius: 20px;
background: rgba(255, 255, 255, 0.02); background: var(--surface);
} }
.empty-state-icon { .empty-state-icon {
font-size: 3.5rem; font-size: 3.5rem;
color: rgba(255, 255, 255, 0.15); color: var(--text-muted);
margin-bottom: 1.5rem; margin-bottom: 1.5rem;
} }
.empty-state h2 { .empty-state h2 {
font-size: 1.3rem; font-size: 1.3rem;
font-weight: 700; font-weight: 700;
color: rgba(255, 255, 255, 0.8); color: var(--text);
margin: 0 0 0.5rem 0; margin: 0 0 0.5rem 0;
} }
.empty-state p { .empty-state p {
color: rgba(255, 255, 255, 0.4); color: var(--text-muted);
font-size: 0.95rem; font-size: 0.95rem;
margin: 0 0 2rem 0; margin: 0 0 2rem 0;
} }
@@ -149,8 +149,8 @@
/* ===== ORDER CARD ===== */ /* ===== ORDER CARD ===== */
.order-card { .order-card {
background: #161616; background: var(--surface);
border: 1px solid rgba(255, 255, 255, 0.07); border: 1px solid var(--border);
border-radius: 18px; border-radius: 18px;
overflow: hidden; overflow: hidden;
transition: transition:
@@ -196,7 +196,7 @@
} }
.order-header:hover { .order-header:hover {
background: rgba(255, 255, 255, 0.02); background: var(--surface-2);
} }
.order-header-left { .order-header-left {
@@ -217,7 +217,7 @@
.order-id { .order-id {
font-size: 1rem; font-size: 1rem;
font-weight: 700; font-weight: 700;
color: #fff; color: var(--text);
} }
.status-badge { .status-badge {
@@ -300,7 +300,7 @@
.order-date { .order-date {
font-size: 0.8rem; font-size: 0.8rem;
color: rgba(255, 255, 255, 0.35); color: var(--text-muted);
} }
.order-header-right { .order-header-right {
@@ -323,8 +323,8 @@
width: 28px; width: 28px;
height: 28px; height: 28px;
border-radius: 8px; border-radius: 8px;
background: rgba(255, 255, 255, 0.05); background: var(--surface-2);
color: rgba(255, 255, 255, 0.4); color: var(--text-muted);
font-size: 0.75rem; font-size: 0.75rem;
transition: all 0.2s ease; transition: all 0.2s ease;
} }
@@ -336,7 +336,7 @@
/* ===== EXPANDED DETAILS ===== */ /* ===== EXPANDED DETAILS ===== */
.order-details { .order-details {
border-top: 1px solid rgba(255, 255, 255, 0.05); border-top: 1px solid var(--border);
animation: expandDown 0.3s ease-out; animation: expandDown 0.3s ease-out;
overflow: hidden; overflow: hidden;
} }
@@ -383,7 +383,7 @@
left: calc(-50% + 14px); left: calc(-50% + 14px);
right: calc(50% + 14px); right: calc(50% + 14px);
height: 2px; height: 2px;
background: rgba(255, 255, 255, 0.08); background: var(--border);
z-index: 0; z-index: 0;
} }
@@ -404,9 +404,9 @@
align-items: center; align-items: center;
justify-content: center; justify-content: center;
font-size: 0.7rem; font-size: 0.7rem;
border: 2px solid rgba(255, 255, 255, 0.1); border: 2px solid var(--border);
background: #1e1e1e; background: var(--surface-2);
color: rgba(255, 255, 255, 0.3); color: var(--text-muted);
transition: all 0.3s ease; transition: all 0.3s ease;
z-index: 1; z-index: 1;
position: relative; position: relative;
@@ -427,7 +427,7 @@
.timeline-label { .timeline-label {
font-size: 0.62rem; font-size: 0.62rem;
color: rgba(255, 255, 255, 0.3); color: var(--text-muted);
margin-top: 0.4rem; margin-top: 0.4rem;
text-align: center; text-align: center;
line-height: 1.3; line-height: 1.3;
@@ -440,7 +440,7 @@
} }
.timeline-step.done .timeline-label { .timeline-step.done .timeline-label {
color: rgba(255, 255, 255, 0.5); color: var(--text-muted);
} }
/* ===== DETAIL SECTIONS ===== */ /* ===== DETAIL SECTIONS ===== */
@@ -452,7 +452,7 @@
.detail-section { .detail-section {
padding: 1rem 1.4rem; padding: 1rem 1.4rem;
border-top: 1px solid rgba(255, 255, 255, 0.04); border-top: 1px solid var(--border);
} }
.detail-section:first-child { .detail-section:first-child {
@@ -467,13 +467,13 @@
font-size: 0.72rem; font-size: 0.72rem;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.8px; letter-spacing: 0.8px;
color: rgba(255, 255, 255, 0.35); color: var(--text-muted);
font-weight: 700; font-weight: 700;
} }
.detail-section p { .detail-section p {
margin: 0; margin: 0;
color: rgba(255, 255, 255, 0.85); color: var(--text);
font-size: 0.95rem; font-size: 0.95rem;
line-height: 1.5; line-height: 1.5;
} }
@@ -481,16 +481,16 @@
.detail-section small { .detail-section small {
display: block; display: block;
margin-top: 0.35rem; margin-top: 0.35rem;
color: rgba(255, 255, 255, 0.35); color: var(--text-muted);
font-size: 0.8rem; font-size: 0.8rem;
} }
.address { .address {
font-weight: 600; font-weight: 600;
color: #fff; color: var(--text);
} }
.contact { .contact {
color: rgba(255, 255, 255, 0.5); color: var(--text-muted);
font-size: 0.85rem; font-size: 0.85rem;
margin-top: 0.25rem; margin-top: 0.25rem;
} }
@@ -574,7 +574,7 @@
font-size: 0.75rem; font-size: 0.75rem;
text-transform: uppercase; text-transform: uppercase;
letter-spacing: 0.7px; letter-spacing: 0.7px;
color: rgba(255, 255, 255, 0.4); color: var(--text-muted);
font-weight: 700; font-weight: 700;
margin: 0 0 0.2rem 0; margin: 0 0 0.2rem 0;
} }
@@ -593,7 +593,7 @@
.eta-card-sub { .eta-card-sub {
font-size: 0.8rem; font-size: 0.8rem;
color: rgba(255, 255, 255, 0.4); color: var(--text-muted);
margin: 0.2rem 0 0 0; margin: 0.2rem 0 0 0;
} }
@@ -609,13 +609,13 @@
justify-content: space-between; justify-content: space-between;
align-items: center; align-items: center;
padding: 0.6rem 0.9rem; padding: 0.6rem 0.9rem;
background: rgba(255, 255, 255, 0.025); background: var(--surface-2);
border-radius: 9px; border-radius: 9px;
border: 1px solid rgba(255, 255, 255, 0.04); border: 1px solid var(--border);
} }
.item-name { .item-name {
color: rgba(255, 255, 255, 0.8); color: var(--text);
font-size: 0.9rem; font-size: 0.9rem;
} }
@@ -637,8 +637,8 @@
/* ===== ACTIONS ===== */ /* ===== ACTIONS ===== */
.order-actions { .order-actions {
padding: 1.2rem 1.4rem; padding: 1.2rem 1.4rem;
border-top: 1px solid rgba(255, 255, 255, 0.05); border-top: 1px solid var(--border);
background: rgba(0, 0, 0, 0.15); background: var(--surface-2);
} }
.action-buttons { .action-buttons {
@@ -668,7 +668,7 @@
.notice-title { .notice-title {
font-size: 1rem; font-size: 1rem;
font-weight: 700; font-weight: 700;
color: #fff; color: var(--text);
margin: 0 0 0.3rem 0; margin: 0 0 0.3rem 0;
display: flex; display: flex;
align-items: center; align-items: center;
@@ -678,7 +678,7 @@
.notice-subtitle { .notice-subtitle {
font-size: 0.85rem; font-size: 0.85rem;
color: rgba(255, 255, 255, 0.5); color: var(--text-muted);
margin: 0; margin: 0;
} }
@@ -727,15 +727,15 @@
.btn-secondary, .btn-secondary,
.btn-cancel { .btn-cancel {
background: rgba(255, 255, 255, 0.06); background: var(--surface-2);
color: rgba(255, 255, 255, 0.7); color: var(--text-muted);
border: 1px solid rgba(255, 255, 255, 0.1); border: 1px solid var(--border);
} }
.btn-secondary:hover, .btn-secondary:hover,
.btn-cancel:hover { .btn-cancel:hover {
background: rgba(255, 255, 255, 0.09); background: var(--surface);
color: #fff; color: var(--text);
} }
.btn-danger, .btn-danger,
@@ -754,7 +754,7 @@
.btn-confirm-delivery:disabled, .btn-confirm-delivery:disabled,
.btn-cancel-order:disabled, .btn-cancel-order:disabled,
.btn-danger:disabled { .btn-danger:disabled {
background: rgba(255, 255, 255, 0.07); background: var(--surface-2);
cursor: not-allowed; cursor: not-allowed;
box-shadow: none; box-shadow: none;
opacity: 0.5; opacity: 0.5;
@@ -791,10 +791,10 @@
margin-top: 2rem; margin-top: 2rem;
text-align: center; text-align: center;
padding: 1rem; padding: 1rem;
background: rgba(255, 255, 255, 0.02); background: var(--surface);
border: 1px solid rgba(255, 255, 255, 0.05); border: 1px solid var(--border);
border-radius: 12px; border-radius: 12px;
color: rgba(255, 255, 255, 0.3); color: var(--text-muted);
font-size: 0.8rem; font-size: 0.8rem;
} }
@@ -826,8 +826,8 @@
} }
.confirm-dialog { .confirm-dialog {
background: #1a1a1a; background: var(--surface);
border: 1px solid rgba(255, 255, 255, 0.12); border: 1px solid var(--border);
border-radius: 20px; border-radius: 20px;
max-width: 480px; max-width: 480px;
width: 90%; width: 90%;
@@ -856,14 +856,14 @@
.confirm-dialog-header { .confirm-dialog-header {
padding: 1.4rem 1.5rem; padding: 1.4rem 1.5rem;
border-bottom: 1px solid rgba(255, 255, 255, 0.07); border-bottom: 1px solid var(--border);
flex-shrink: 0; flex-shrink: 0;
} }
.confirm-dialog-header h3 { .confirm-dialog-header h3 {
margin: 0; margin: 0;
font-size: 1.1rem; font-size: 1.1rem;
color: white; color: var(--text);
font-weight: 700; font-weight: 700;
display: flex; display: flex;
align-items: center; align-items: center;
@@ -872,7 +872,7 @@
.confirm-dialog-body { .confirm-dialog-body {
padding: 1.5rem; padding: 1.5rem;
color: rgba(255, 255, 255, 0.75); color: var(--text);
overflow-y: auto; overflow-y: auto;
flex: 1; flex: 1;
-webkit-overflow-scrolling: touch; -webkit-overflow-scrolling: touch;
@@ -932,7 +932,7 @@
display: flex; display: flex;
gap: 0.75rem; gap: 0.75rem;
flex-shrink: 0; flex-shrink: 0;
border-top: 1px solid rgba(255, 255, 255, 0.06); border-top: 1px solid var(--border);
} }
.confirm-dialog-actions .btn-cancel, .confirm-dialog-actions .btn-cancel,
@@ -958,16 +958,16 @@
.cancel-form label { .cancel-form label {
font-weight: 600; font-weight: 600;
color: rgba(255, 255, 255, 0.8); color: var(--text);
font-size: 0.9rem; font-size: 0.9rem;
} }
.cancel-form textarea { .cancel-form textarea {
background: rgba(255, 255, 255, 0.04); background: var(--bg);
border: 1px solid rgba(255, 255, 255, 0.1); border: 1px solid var(--border);
border-radius: 10px; border-radius: 10px;
padding: 0.75rem; padding: 0.75rem;
color: white; color: var(--text);
font-family: inherit; font-family: inherit;
resize: vertical; resize: vertical;
min-height: 90px; min-height: 90px;
@@ -982,7 +982,7 @@
} }
.cancel-form small { .cancel-form small {
color: rgba(255, 255, 255, 0.35); color: var(--text-muted);
font-size: 0.8rem; font-size: 0.8rem;
text-align: right; text-align: right;
} }
@@ -997,7 +997,7 @@
align-items: flex-start; align-items: flex-start;
font-size: 0.88rem; font-size: 0.88rem;
line-height: 1.5; line-height: 1.5;
color: rgba(255, 255, 255, 0.6); color: var(--text-muted);
} }
.info-message svg { .info-message svg {
@@ -1041,15 +1041,15 @@
} }
.warning-details { .warning-details {
background: rgba(255, 255, 255, 0.04); background: var(--surface-2);
padding: 0.9rem; padding: 0.9rem;
border-radius: 10px; border-radius: 10px;
border: 1px solid rgba(255, 255, 255, 0.08); border: 1px solid var(--border);
} }
.warning-details p { .warning-details p {
margin: 0.4rem 0; margin: 0.4rem 0;
color: rgba(255, 255, 255, 0.7); color: var(--text);
font-size: 0.9rem; font-size: 0.9rem;
} }
@@ -1068,14 +1068,14 @@
} }
.penalty-message { .penalty-message {
color: rgba(255, 255, 255, 0.65); color: var(--text-muted);
text-align: center; text-align: center;
margin-bottom: 1rem; margin-bottom: 1rem;
font-size: 0.9rem; font-size: 0.9rem;
} }
.penalty-scale { .penalty-scale {
background: rgba(255, 255, 255, 0.03); background: var(--surface-2);
padding: 0.9rem; padding: 0.9rem;
border-radius: 8px; border-radius: 8px;
} }
@@ -1092,9 +1092,9 @@
} }
.penalty-scale li { .penalty-scale li {
padding: 0.4rem 0; padding: 0.4rem 0;
border-bottom: 1px solid rgba(255, 255, 255, 0.05); border-bottom: 1px solid var(--border);
font-size: 0.85rem; font-size: 0.85rem;
color: rgba(255, 255, 255, 0.65); color: var(--text-muted);
} }
.penalty-scale li:last-child { .penalty-scale li:last-child {
border-bottom: none; border-bottom: none;
@@ -1103,7 +1103,7 @@
.warning-question { .warning-question {
font-size: 0.95rem; font-size: 0.95rem;
font-weight: 700; font-weight: 700;
color: rgba(255, 255, 255, 0.85); color: var(--text);
text-align: center; text-align: center;
margin-top: 0.5rem; margin-top: 0.5rem;
} }
@@ -675,7 +675,7 @@ function SuiviLivraison() {
<div className="order-header-left"> <div className="order-header-left">
<div className="order-id-row"> <div className="order-id-row">
<span className="order-id"> <span className="order-id">
Commande #{order.id} Commande #{order.client_order_number}
</span> </span>
<div <div
className="status-badge" className="status-badge"
+13 -21
View File
@@ -15,7 +15,7 @@
box-sizing: border-box; box-sizing: border-box;
overflow-x: hidden; overflow-x: hidden;
margin-top: 0; margin-top: 0;
background-color: #1a1a1a; background-color: var(--bg);
position: relative; position: relative;
} }
@@ -77,8 +77,8 @@
.category-button { .category-button {
background-color: transparent; background-color: transparent;
color: white; color: var(--text);
border: 2px solid rgba(255, 255, 255, 0.3); border: 2px solid var(--border);
border-radius: 25px; border-radius: 25px;
padding: clamp(0.6rem, 2vw, 0.8rem) clamp(1.2rem, 3vw, 1.5rem); padding: clamp(0.6rem, 2vw, 0.8rem) clamp(1.2rem, 3vw, 1.5rem);
font-size: clamp(0.9rem, 3vw, 1rem); font-size: clamp(0.9rem, 3vw, 1rem);
@@ -95,9 +95,9 @@
} }
.category-button.active { .category-button.active {
background-color: white; background-color: var(--text);
color: black; color: var(--bg);
border-color: white; border-color: var(--text);
} }
/* ===== CATEGORY HEADER ===== */ /* ===== CATEGORY HEADER ===== */
@@ -121,22 +121,14 @@
.category-title { .category-title {
font-size: clamp(1.8rem, 5vw, 2.8rem); font-size: clamp(1.8rem, 5vw, 2.8rem);
font-weight: 700; font-weight: 700;
color: white; color: var(--text);
margin: 0 0 0.8rem 0; margin: 0 0 0.8rem 0;
letter-spacing: -0.5px; letter-spacing: -0.5px;
background: linear-gradient(
135deg,
#ffffff 0%,
rgba(255, 255, 255, 0.8) 100%
);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
} }
.category-subtitle { .category-subtitle {
font-size: clamp(0.95rem, 3vw, 1.1rem); font-size: clamp(0.95rem, 3vw, 1.1rem);
color: rgba(255, 255, 255, 0.65); color: var(--text-muted);
margin: 0; margin: 0;
font-weight: 400; font-weight: 400;
letter-spacing: 0.3px; letter-spacing: 0.3px;
@@ -226,12 +218,12 @@
@media (hover: none) { @media (hover: none) {
.category-button:hover { .category-button:hover {
background-color: transparent; background-color: transparent;
color: white; color: var(--text);
} }
.category-button.active:hover { .category-button.active:hover {
background-color: white; background-color: var(--text);
color: black; color: var(--bg);
} }
} }
@@ -245,13 +237,13 @@
padding: 3rem; padding: 3rem;
text-align: center; text-align: center;
min-height: 300px; min-height: 300px;
color: white; color: var(--text);
} }
.loading-container p, .loading-container p,
.empty-container p { .empty-container p {
font-size: 1.1rem; font-size: 1.1rem;
color: rgba(255, 255, 255, 0.8); color: var(--text-muted);
} }
.error-message { .error-message {
+12 -12
View File
@@ -11,7 +11,7 @@
} }
.page-container h1 { .page-container h1 {
color: white; color: var(--text);
font-size: clamp(1.8rem, 6vw, 2.5rem); font-size: clamp(1.8rem, 6vw, 2.5rem);
margin-bottom: clamp(1.5rem, 4vh, 2rem); margin-bottom: clamp(1.5rem, 4vh, 2rem);
text-align: center; text-align: center;
@@ -29,9 +29,9 @@
} }
.page-link { .page-link {
background-color: #1a1a1a; background-color: var(--surface);
border: 2px solid white; border: 2px solid var(--text);
color: white; color: var(--text);
padding: clamp(1rem, 3vw, 1.5rem); padding: clamp(1rem, 3vw, 1.5rem);
text-decoration: none; text-decoration: none;
border-radius: 12px; border-radius: 12px;
@@ -45,16 +45,16 @@
.page-link:active { .page-link:active {
transform: scale(0.97); transform: scale(0.97);
background-color: #2a2a2a; background-color: var(--surface-2);
} }
.back-link { .back-link {
color: white; color: var(--text);
text-decoration: none; text-decoration: none;
margin-top: clamp(1rem, 3vh, 2rem); margin-top: clamp(1rem, 3vh, 2rem);
font-size: clamp(0.9rem, 3vw, 1.1rem); font-size: clamp(0.9rem, 3vw, 1.1rem);
padding: clamp(0.6rem, 2vw, 0.8rem) clamp(1rem, 3vw, 1.5rem); padding: clamp(0.6rem, 2vw, 0.8rem) clamp(1rem, 3vw, 1.5rem);
border: 1.5px solid white; border: 1.5px solid var(--text);
border-radius: 8px; border-radius: 8px;
transition: all 0.2s ease; transition: all 0.2s ease;
touch-action: manipulation; touch-action: manipulation;
@@ -62,19 +62,19 @@
} }
.back-link:active { .back-link:active {
background-color: #1a1a1a; background-color: var(--surface);
transform: scale(0.95); transform: scale(0.95);
} }
.content { .content {
color: white; color: var(--text);
font-size: clamp(1rem, 3.5vw, 1.2rem); font-size: clamp(1rem, 3.5vw, 1.2rem);
text-align: center; text-align: center;
width: 100%; width: 100%;
max-width: 500px; max-width: 500px;
padding: clamp(1.5rem, 4vw, 2rem); padding: clamp(1.5rem, 4vw, 2rem);
background-color: #1a1a1a; background-color: var(--surface);
border: 2px solid white; border: 2px solid var(--text);
border-radius: 15px; border-radius: 15px;
margin-bottom: clamp(1.5rem, 4vh, 2rem); margin-bottom: clamp(1.5rem, 4vh, 2rem);
box-sizing: border-box; box-sizing: border-box;
@@ -111,7 +111,7 @@
@media (hover: none) { @media (hover: none) {
.page-link:hover { .page-link:hover {
transform: none; transform: none;
background-color: #1a1a1a; background-color: var(--surface);
} }
.back-link:hover { .back-link:hover {