"use client"; import React, { createContext, useContext, useState, useEffect } from "react"; export type ThemeMode = "light" | "dark" | "system"; export type ColorScheme = "orange" | "blue" | "green" | "purple" | "red"; export interface ThemeConfig { mode: ThemeMode; colorScheme: ColorScheme; customColors?: { primary?: string; secondary?: string; accent?: string; }; } interface ThemeContextType { theme: ThemeConfig; setTheme: (theme: Partial) => void; toggleMode: () => void; isDark: boolean; colors: { primary: string; secondary: string; accent: string; background: string; surface: string; text: string; textSecondary: string; border: string; hover: string; }; } const ThemeContext = createContext(undefined); const colorSchemes = { orange: { primary: "#f97316", secondary: "#ea580c", accent: "#fb923c", }, blue: { primary: "#3b82f6", secondary: "#2563eb", accent: "#60a5fa", }, green: { primary: "#10b981", secondary: "#059669", accent: "#34d399", }, purple: { primary: "#8b5cf6", secondary: "#7c3aed", accent: "#a78bfa", }, red: { primary: "#ef4444", secondary: "#dc2626", accent: "#f87171", }, }; const lightColors = { background: "#ffffff", surface: "#f8fafc", text: "#1f2937", textSecondary: "#6b7280", border: "#e5e7eb", hover: "#f3f4f6", }; const darkColors = { background: "#0f172a", surface: "#1e293b", text: "#f1f5f9", textSecondary: "#94a3b8", border: "#334155", hover: "#334155", }; export const ThemeProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => { const [theme, setThemeState] = useState({ mode: "system", colorScheme: "orange", }); const [isDark, setIsDark] = useState(false); // 시스템 테마 감지 useEffect(() => { const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)"); const handleChange = () => { if (theme.mode === "system") { setIsDark(mediaQuery.matches); } }; handleChange(); mediaQuery.addEventListener("change", handleChange); return () => mediaQuery.removeEventListener("change", handleChange); }, [theme.mode]); // 테마 모드에 따른 다크모드 설정 useEffect(() => { switch (theme.mode) { case "light": setIsDark(false); break; case "dark": setIsDark(true); break; case "system": const mediaQuery = window.matchMedia("(prefers-color-scheme: dark)"); setIsDark(mediaQuery.matches); break; } }, [theme.mode]); const setTheme = (newTheme: Partial) => { setThemeState(prev => ({ ...prev, ...newTheme })); }; const toggleMode = () => { setThemeState(prev => ({ ...prev, mode: prev.mode === "light" ? "dark" : "light" })); }; const baseColors = colorSchemes[theme.colorScheme]; const themeColors = isDark ? darkColors : lightColors; const colors = { primary: theme.customColors?.primary || baseColors.primary, secondary: theme.customColors?.secondary || baseColors.secondary, accent: theme.customColors?.accent || baseColors.accent, background: themeColors.background, surface: themeColors.surface, text: themeColors.text, textSecondary: themeColors.textSecondary, border: themeColors.border, hover: themeColors.hover, }; return ( {children} ); }; export const useTheme = () => { const context = useContext(ThemeContext); if (context === undefined) { throw new Error("useTheme must be used within a ThemeProvider"); } return context; };