diff --git a/src/app/options/Options.tsx b/src/app/options/Options.tsx index fe08ccc..3994e91 100644 --- a/src/app/options/Options.tsx +++ b/src/app/options/Options.tsx @@ -9,15 +9,18 @@ import type { Locale, PlatformId, RepositoryTemplateSegment, + ThemeMode, } from "../../core/types/domain"; import type { RuntimeMessageResponse } from "../../core/types/messages"; import { BrandWordmark } from "../../shared/components/BrandWordmark"; +import { useResolvedTheme } from "../../shared/theme"; const ISSUE_URL = "https://github.com/dev-minsoo/AlgorithmHub/issues"; const REPOSITORY_URL = "https://github.com/dev-minsoo/AlgorithmHub"; const emptySettings: ExtensionSettings = { locale: "en", + themeMode: "system", github: { oauthClientId: "", token: "", @@ -78,6 +81,10 @@ const OPTIONS_COPY = { noRepository: "No repository connected", connectHint: "Connect a repository from the welcome flow first.", solving: "Start solving problems right away:", + theme: "Theme", + themeSystem: "System", + themeLight: "Light", + themeDark: "Dark", language: "Language", autoUpload: "Auto Upload", enabled: "Enabled", @@ -102,6 +109,10 @@ const OPTIONS_COPY = { noRepository: "연결된 저장소가 없습니다", connectHint: "먼저 welcome 화면에서 저장소를 연결하세요.", solving: "바로 문제를 풀어보세요:", + theme: "테마", + themeSystem: "System", + themeLight: "Light", + themeDark: "Dark", language: "언어", autoUpload: "자동 업로드", enabled: "활성화", @@ -137,6 +148,7 @@ function PathTemplateCard({ onToggleSegment, onToggleCombine, copy, + resolvedTheme, }: { platform: PlatformId; settings: ExtensionSettings; @@ -152,6 +164,7 @@ function PathTemplateCard({ ) => Promise; onToggleCombine: (platform: PlatformId) => Promise; copy: OptionsCopy; + resolvedTheme: "light" | "dark"; }) { const template = settings.repositoryTemplate[platform]; const previewPath = buildRepositoryDirectory(template, { @@ -163,18 +176,40 @@ function PathTemplateCard({ const fileName = platform === "leetcode" ? "solution.py" : "solution.js"; return ( -
+

{platform === "leetcode" ? copy.templateLeetCode : copy.templateProgrammers}

-

+

{copy.templateHint}

-
+
-

{copy.combine}

+

+ {copy.combine} +

-
+
{previewPath}/{fileName}
@@ -429,9 +484,38 @@ export default function Options() { const isConnected = Boolean(settings.github.repository.trim()); const copy = OPTIONS_COPY[settings.locale]; + const resolvedTheme = useResolvedTheme(settings.themeMode); + + async function handleChangeTheme(themeMode: ThemeMode) { + const response = (await chrome.runtime.sendMessage({ + type: "SAVE_SETTINGS", + settings: { themeMode }, + })) as RuntimeMessageResponse; + + if (response.type === "SETTINGS_SAVED") { + setSettings(response.settings); + } + } + + const pageClass = + resolvedTheme === "dark" + ? "min-h-screen bg-[radial-gradient(circle_at_top,_rgba(251,191,36,0.16),_transparent_30%),linear-gradient(180deg,_#140f0c,_#060606)] text-stone-100" + : "min-h-screen bg-[radial-gradient(circle_at_top,_rgba(251,191,36,0.16),_transparent_30%),linear-gradient(180deg,_#fcf5e8,_#fffdf8)] text-stone-900"; + const shellClass = + resolvedTheme === "dark" + ? "border-amber-950/60 bg-[linear-gradient(180deg,rgba(41,24,13,0.92),rgba(12,12,12,0.94))] shadow-[0_24px_80px_rgba(0,0,0,0.45)]" + : "border-amber-300 bg-[linear-gradient(180deg,rgba(255,255,255,0.99),rgba(255,247,232,0.98))] shadow-[0_24px_64px_rgba(180,120,0,0.10)]"; + const cardClass = + resolvedTheme === "dark" + ? "border-stone-800 bg-stone-950/60" + : "border-amber-300 bg-white"; + const rowClass = + resolvedTheme === "dark" + ? "border-stone-800 bg-stone-900/70" + : "border-amber-300 bg-amber-50/85"; return ( -
+

@@ -440,20 +524,42 @@ export default function Options() {

-

+

{copy.description}

-
-
-

+

+
+

{copy.connected}

{isConnected ? ( -

+

) : ( -

+

{copy.noRepository}

)} {!isConnected ? ( -

+

{copy.connectHint}

) : null}
-
+
-
-

+

+

{copy.autoUpload} {extensionEnabled ? copy.enabled : copy.disabled}

-
- +
+ + {copy.theme} + + +
+ +
+ {copy.language} { const nextMode = event.target.value as RepoMode; @@ -259,7 +305,11 @@ export default function Welcome() { setRepositoryName(event.target.value)} placeholder="algorithm" @@ -270,8 +320,18 @@ export default function Welcome() { {mode === "link" ? (
{!settings.github.token.trim() ? ( -
-

+

+

Authenticate with GitHub to load your repositories.