From 364c84cf2fd1e6a2733c02b157c8aa725fec49c5 Mon Sep 17 00:00:00 2001 From: kimjaehyeon0101 <47347352-kimjaehyeon0101@users.noreply.replit.com> Date: Mon, 29 Sep 2025 22:03:13 +0000 Subject: [PATCH] Add settings modal for theme and language customization Introduces a new SettingsModal component allowing users to select themes (light, dark, system) and languages, saving preferences to localStorage. The modal is integrated into Home and Landing pages. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 069d4324-6c40-4355-955e-c714a50de1ea Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/3df548ff-50ae-432f-9be4-25d34eccc983/069d4324-6c40-4355-955e-c714a50de1ea/9tQ591o --- client/src/components/SettingsModal.tsx | 143 ++++++++++++++++++++++++ client/src/pages/Home.tsx | 9 ++ client/src/pages/Landing.tsx | 9 ++ 3 files changed, 161 insertions(+) create mode 100644 client/src/components/SettingsModal.tsx diff --git a/client/src/components/SettingsModal.tsx b/client/src/components/SettingsModal.tsx new file mode 100644 index 0000000..acf9471 --- /dev/null +++ b/client/src/components/SettingsModal.tsx @@ -0,0 +1,143 @@ +import { Dialog, DialogContent, DialogHeader, DialogTitle } from "@/components/ui/dialog"; +import { Label } from "@/components/ui/label"; +import { useState, useEffect } from "react"; +import { Sun, Moon, Monitor } from "lucide-react"; + +interface SettingsModalProps { + isOpen: boolean; + onClose: () => void; +} + +type Theme = 'light' | 'dark' | 'system'; +type Language = 'en' | 'fr' | 'de' | 'it' | 'hi' | 'ar' | 'ja' | 'ko' | 'zh-TW' | 'zh-CN'; + +const languages = [ + { code: 'en', name: 'English' }, + { code: 'fr', name: 'Français' }, + { code: 'de', name: 'Deutsch' }, + { code: 'it', name: 'Italiano' }, + { code: 'hi', name: 'हिन्दी' }, + { code: 'ar', name: 'العربية' }, + { code: 'ja', name: '日本語' }, + { code: 'ko', name: '한국어' }, + { code: 'zh-TW', name: '繁體中文' }, + { code: 'zh-CN', name: '简体中文' }, +]; + +export default function SettingsModal({ isOpen, onClose }: SettingsModalProps) { + const [theme, setTheme] = useState('system'); + const [language, setLanguage] = useState('en'); + + useEffect(() => { + // Load saved settings + const savedTheme = localStorage.getItem('theme') as Theme || 'system'; + const savedLanguage = localStorage.getItem('language') as Language || 'en'; + setTheme(savedTheme); + setLanguage(savedLanguage); + + // Apply theme + applyTheme(savedTheme); + }, []); + + const applyTheme = (selectedTheme: Theme) => { + const root = document.documentElement; + + if (selectedTheme === 'system') { + const systemPreference = window.matchMedia('(prefers-color-scheme: dark)').matches ? 'dark' : 'light'; + root.classList.toggle('dark', systemPreference === 'dark'); + } else { + root.classList.toggle('dark', selectedTheme === 'dark'); + } + }; + + const handleThemeChange = (newTheme: Theme) => { + setTheme(newTheme); + localStorage.setItem('theme', newTheme); + applyTheme(newTheme); + }; + + const handleLanguageChange = (newLanguage: Language) => { + setLanguage(newLanguage); + localStorage.setItem('language', newLanguage); + // Here you would trigger language change in your app + // For now, just save to localStorage + }; + + return ( + + + + Settings + + +
+ {/* Theme Selection */} +
+ +
+ + + + + +
+
+ + {/* Language Selection */} +
+ +
+ {languages.map((lang) => ( + + ))} +
+
+
+
+
+ ); +} diff --git a/client/src/pages/Home.tsx b/client/src/pages/Home.tsx index 8d6870c..4e03051 100644 --- a/client/src/pages/Home.tsx +++ b/client/src/pages/Home.tsx @@ -6,6 +6,7 @@ import { useState } from "react"; import MainContent from "@/components/MainContent"; import LoginModal from "@/components/LoginModal"; import SearchModal from "@/components/SearchModal"; +import SettingsModal from "@/components/SettingsModal"; import { useToast } from "@/hooks/use-toast"; import { queryClient } from "@/lib/queryClient"; import { useLocation } from "wouter"; @@ -14,6 +15,7 @@ export default function Home() { const { user, isAuthenticated } = useAuth(); const [isLoginModalOpen, setIsLoginModalOpen] = useState(false); const [isSearchModalOpen, setIsSearchModalOpen] = useState(false); + const [isSettingsModalOpen, setIsSettingsModalOpen] = useState(false); const { toast } = useToast(); const [, setLocation] = useLocation(); @@ -120,6 +122,7 @@ export default function Home() {