Files
projet_gestion_commande/frontend-admin/src/context/ThemeContext.tsx
T
2026-06-19 19:42:37 +02:00

86 lines
3.0 KiB
TypeScript

import React, { createContext, useContext, useState, useEffect, useCallback, type ReactNode } from "react";
import { AppState } from "react-native";
import AsyncStorage from "@react-native-async-storage/async-storage";
import { darkColors, lightColors, type Colors } from "../theme/colors";
import { getSettings } from "../api/api_admin";
type ThemeMode = "dark" | "light";
interface ThemeContextType {
colors: Colors;
mode: ThemeMode;
toggleTheme: () => void;
isDark: boolean;
}
const STORAGE_KEY = "@theme_mode";
const COLORS_CACHE_KEY = "@admin_colors_cache";
const ThemeContext = createContext<ThemeContextType | undefined>(undefined);
export function ThemeProvider({ children }: { children: ReactNode }) {
const [mode, setMode] = useState<ThemeMode>("dark");
const [colorOverrides, setColorOverrides] = useState<Partial<Colors>>({});
const fetchAdminColors = useCallback(async () => {
try {
const result = await getSettings();
if (result.success && result.settings) {
const s = result.settings;
const overrides: Partial<Colors> = {};
if (s.admin_color_primary) overrides.accent = s.admin_color_primary;
if (s.admin_color_secondary) overrides.secondary = s.admin_color_secondary;
if (s.admin_color_success) overrides.success = s.admin_color_success;
if (s.admin_color_danger) overrides.danger = s.admin_color_danger;
if (s.admin_color_warning) overrides.warning = s.admin_color_warning;
setColorOverrides(overrides);
AsyncStorage.setItem(COLORS_CACHE_KEY, JSON.stringify(overrides)).catch(() => {});
}
} catch {}
}, []);
useEffect(() => {
AsyncStorage.getItem(STORAGE_KEY).then((val) => {
if (val === "light" || val === "dark") setMode(val);
});
AsyncStorage.getItem(COLORS_CACHE_KEY).then((val) => {
if (val) {
try { setColorOverrides(JSON.parse(val)); } catch {}
}
});
fetchAdminColors();
}, [fetchAdminColors]);
useEffect(() => {
const sub = AppState.addEventListener("change", (state) => {
if (state === "active") fetchAdminColors();
});
return () => sub.remove();
}, [fetchAdminColors]);
const toggleTheme = () => {
const next = mode === "dark" ? "light" : "dark";
setMode(next);
AsyncStorage.setItem(STORAGE_KEY, next);
};
const baseColors = mode === "dark" ? darkColors : lightColors;
const colors: Colors = { ...baseColors, ...colorOverrides };
const value: ThemeContextType = {
colors,
mode,
toggleTheme,
isDark: mode === "dark",
};
return (
<ThemeContext.Provider value={value}>{children}</ThemeContext.Provider>
);
}
export function useTheme() {
const ctx = useContext(ThemeContext);
if (!ctx) throw new Error("useTheme must be used within ThemeProvider");
return ctx;
}