update frontend

This commit is contained in:
Your Name 2025-12-09 22:15:52 -05:00
parent a3bcb933b3
commit 60a51bdf8e
6 changed files with 190 additions and 9 deletions

View File

@ -1,11 +1,42 @@
import React from "react"; import React, { useEffect, useState } from "react";
import TopBar from "./components/Layout/TopBar"; import TopBar from "./components/Layout/TopBar";
import MapView from "./components/Map/MapView"; import MapView from "./components/Map/MapView";
const THEME_KEY = "sociowire:theme";
export default function App() { export default function App() {
const [theme, setTheme] = useState("dark");
// charge le thème depuis le localStorage au démarrage
useEffect(() => {
if (typeof window === "undefined") return;
try {
const saved = localStorage.getItem(THEME_KEY);
if (saved === "dark" || saved === "blue" || saved === "light") {
setTheme(saved);
document.body.setAttribute("data-theme", saved);
} else {
document.body.setAttribute("data-theme", "dark");
}
} catch {
document.body.setAttribute("data-theme", "dark");
}
}, []);
// applique le thème + sauvegarde
useEffect(() => {
if (typeof window === "undefined") return;
try {
document.body.setAttribute("data-theme", theme);
localStorage.setItem(THEME_KEY, theme);
} catch {
// ignore
}
}, [theme]);
return ( return (
<div className="app-root"> <div className="app-root">
<TopBar /> <TopBar theme={theme} onChangeTheme={setTheme} />
<div className="main-shell"> <div className="main-shell">
<div className="map-shell"> <div className="map-shell">
<MapView /> <MapView />

View File

@ -1,14 +1,39 @@
import React from "react"; import React from "react";
export default function TopBar() { const THEME_LABELS = {
dark: "Dark",
blue: "Blue",
light: "Light",
};
export default function TopBar({ theme = "dark", onChangeTheme }) {
return ( return (
<header className="topbar"> <header className="topbar">
<div className="logo-circle">SW</div> <div className="logo-circle">SW</div>
<div className="title-block"> <div className="title-block">
<div className="main-title">SOCIOWIRE.com</div> <div className="main-title">SOCIOWIRE.com</div>
<div className="sub-title">Wired to life</div> <div className="sub-title">Wired to life</div>
</div> </div>
<div className="topbar-right">
<div className="theme-switch">
{["dark", "blue", "light"].map((t) => (
<button
key={t}
type="button"
className={
"theme-dot" + (theme === t ? " theme-dot-active" : "")
}
title={THEME_LABELS[t]}
onClick={() => onChangeTheme && onChangeTheme(t)}
>
{THEME_LABELS[t][0]}
</button>
))}
</div>
<button className="btn-primary">Login</button> <button className="btn-primary">Login</button>
</div>
</header> </header>
); );
} }

View File

@ -9,7 +9,8 @@ import "./styles/map.css";
import "./styles/markers.css"; import "./styles/markers.css";
import "./styles/popup.css"; import "./styles/popup.css";
import "./styles/overlays.css"; import "./styles/overlays.css";
import "./styles/posts.css"; // Sociowall + chat import "./styles/posts.css";
import "./styles/theme.css";
ReactDOM.createRoot(document.getElementById("root")).render( ReactDOM.createRoot(document.getElementById("root")).render(
<React.StrictMode> <React.StrictMode>

View File

@ -6,18 +6,19 @@
flex-direction: column; flex-direction: column;
} }
/* plus aucun espace entre la topbar et la carte */
.main-shell { .main-shell {
flex: 1; flex: 1;
display: flex; display: flex;
padding: 0.6rem; padding: 0;
} }
/* Conteneur de la carte plein écran */ /* Conteneur de la carte plein écran collé aux bords */
.map-shell { .map-shell {
position: relative; position: relative;
flex: 1; flex: 1;
border-radius: 1rem; border-radius: 0;
overflow: hidden; overflow: hidden;
border: 1px solid #1f2937; border: none;
background: #020617; background: #020617;
} }

89
src/styles/theme.css Normal file
View File

@ -0,0 +1,89 @@
/* ==========================================
THEME SYSTEM body[data-theme="..."]
Trois thèmes : dark (par défaut), blue, light
========================================== */
/* Thème noir (par défaut) */
body[data-theme="dark"] {
background: #050816;
color: #ffffff;
}
/* ===================== BLUE ===================== */
body[data-theme="blue"] .sociowall-panel,
body[data-theme="blue"] .chat-panel,
body[data-theme="blue"] .post-card,
body[data-theme="blue"] .post-pin--expanded .post-card,
body[data-theme="blue"] .post-pin--compact .post-pin-bubble,
body[data-theme="blue"] .popup-post-card {
background: rgba(12, 20, 60, 0.96);
border-color: rgba(96, 165, 250, 0.95);
}
body[data-theme="blue"] .chip-round,
body[data-theme="blue"] .chip-pill,
body[data-theme="blue"] .chip-egg,
body[data-theme="blue"] .chip-hex {
background: rgba(10, 22, 60, 0.96);
border-color: rgba(96, 165, 250, 0.9);
}
body[data-theme="blue"] .chip-selected,
body[data-theme="blue"] .chip-egg-active {
background: linear-gradient(135deg, #1d4ed8, #38bdf8);
border-color: #bfdbfe;
}
/* ===================== LIGHT ===================== */
body[data-theme="light"] {
background: #e5e7eb;
color: #111827;
}
/* panneaux principaux clairs */
body[data-theme="light"] .sociowall-panel,
body[data-theme="light"] .chat-panel,
body[data-theme="light"] .post-card,
body[data-theme="light"] .post-pin--expanded .post-card,
body[data-theme="light"] .popup-post-card {
background: rgba(248, 250, 252, 0.97);
border-color: rgba(148, 163, 184, 0.9);
color: #111827;
}
/* petits marqueurs compacts */
body[data-theme="light"] .post-pin--compact .post-pin-bubble {
background: rgba(255, 255, 255, 0.96);
border-color: rgba(148, 163, 184, 0.9);
color: #0f172a;
}
/* chips claires */
body[data-theme="light"] .chip-round,
body[data-theme="light"] .chip-pill,
body[data-theme="light"] .chip-egg,
body[data-theme="light"] .chip-hex {
background: rgba(255, 255, 255, 0.98);
border-color: rgba(148, 163, 184, 0.9);
color: #111827;
}
body[data-theme="light"] .chip-selected,
body[data-theme="light"] .chip-egg-active {
background: linear-gradient(135deg, #38bdf8, #0ea5e9);
border-color: #0ea5e9;
color: #0f172a;
}
/* topbar clair */
body[data-theme="light"] .topbar {
background: #f9fafb;
border-bottom-color: #e5e7eb;
}
body[data-theme="light"] .main-title,
body[data-theme="light"] .sub-title {
color: #0f172a;
}

View File

@ -36,6 +36,40 @@
opacity: 0.7; opacity: 0.7;
} }
/* bloc de droite : thèmes + bouton login */
.topbar-right {
display: flex;
align-items: center;
gap: 0.5rem;
}
/* petits boutons de thème (D / B / L) */
.theme-switch {
display: flex;
gap: 0.25rem;
}
.theme-dot {
width: 22px;
height: 22px;
border-radius: 999px;
border: 1px solid #4b5563;
background: #020617;
color: #e5e7eb;
font-size: 0.65rem;
display: flex;
align-items: center;
justify-content: center;
padding: 0;
cursor: pointer;
}
.theme-dot-active {
border-color: #facc15;
box-shadow: 0 0 10px rgba(250, 204, 21, 0.7);
}
/* bouton Login */
.btn-primary { .btn-primary {
padding: 0.25rem 0.7rem; padding: 0.25rem 0.7rem;
font-size: 0.75rem; font-size: 0.75rem;