refactor: merge Language and Theme settings into one two-column card

Language and Theme were two separate Cards stacked on top of each other —
both are pure client-side display preferences, so splitting them side by
side (language left, theme right) saves a card's worth of vertical space.
Collapses back to a single column on mobile.
This commit is contained in:
ZProger
2026-08-16 23:27:55 +03:00
parent 75dd43c8e3
commit 1f5fab5010
6 changed files with 46 additions and 55 deletions

View File

@@ -6,7 +6,7 @@ from pydantic_settings import BaseSettings, SettingsConfigDict
# Single source of truth for the running app's version — surfaced in the API
# title and embedded in exported backups so an old file can be told apart
# from a current one.
APP_VERSION = "0.19.0"
APP_VERSION = "0.19.1"
class Settings(BaseSettings):

View File

@@ -1,7 +1,7 @@
{
"name": "aurum-frontend",
"private": true,
"version": "0.19.0",
"version": "0.19.1",
"type": "module",
"scripts": {
"dev": "vite",

View File

@@ -1,23 +0,0 @@
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/Card";
import { PillSelector } from "@/components/layout/PillSelector";
import { useTranslation, type Language } from "@/lib/i18n";
export function LanguageCard() {
const { t, language, setLanguage } = useTranslation();
const options: Array<{ value: Language; label: string }> = [
{ value: "ru", label: t("settings.languageRussian") },
{ value: "en", label: t("settings.languageEnglish") },
];
return (
<Card>
<CardHeader>
<CardTitle>{t("settings.language")}</CardTitle>
</CardHeader>
<CardContent>
<PillSelector options={options} value={language} onChange={setLanguage} />
</CardContent>
</Card>
);
}

View File

@@ -0,0 +1,42 @@
import { Card, CardContent } from "@/components/ui/Card";
import { PillSelector } from "@/components/layout/PillSelector";
import { useTranslation, type Language } from "@/lib/i18n";
import { useTheme, type Theme } from "@/lib/theme";
/** Language and theme side by side — both are pure client-side display
* preferences (unlike currency, which is server-persisted), so pairing
* them saves a whole card's worth of vertical space over listing each on
* its own. Stacks back to one column on mobile. */
export function PreferencesCard() {
const { t, language, setLanguage } = useTranslation();
const { theme, setTheme } = useTheme();
const languageOptions: Array<{ value: Language; label: string }> = [
{ value: "ru", label: t("settings.languageRussian") },
{ value: "en", label: t("settings.languageEnglish") },
];
const themeOptions: Array<{ value: Theme; label: string }> = [
{ value: "light", label: t("settings.themeLight") },
{ value: "dark", label: t("settings.themeDark") },
{ value: "system", label: t("settings.themeSystem") },
];
return (
<Card>
<CardContent className="grid grid-cols-1 gap-5 divide-y divide-border pt-4 sm:grid-cols-2 sm:gap-6 sm:divide-x sm:divide-y-0 sm:pt-5">
<div>
<p className="text-xs font-semibold uppercase tracking-wide text-text-muted">{t("settings.language")}</p>
<div className="mt-2">
<PillSelector options={languageOptions} value={language} onChange={setLanguage} />
</div>
</div>
<div className="pt-5 sm:pl-6 sm:pt-0">
<p className="text-xs font-semibold uppercase tracking-wide text-text-muted">{t("settings.theme")}</p>
<div className="mt-2">
<PillSelector options={themeOptions} value={theme} onChange={setTheme} />
</div>
</div>
</CardContent>
</Card>
);
}

View File

@@ -1,26 +0,0 @@
import { Card, CardContent, CardHeader, CardTitle } from "@/components/ui/Card";
import { PillSelector } from "@/components/layout/PillSelector";
import { useTranslation } from "@/lib/i18n";
import { useTheme, type Theme } from "@/lib/theme";
export function ThemeCard() {
const { t } = useTranslation();
const { theme, setTheme } = useTheme();
const options: Array<{ value: Theme; label: string }> = [
{ value: "light", label: t("settings.themeLight") },
{ value: "dark", label: t("settings.themeDark") },
{ value: "system", label: t("settings.themeSystem") },
];
return (
<Card>
<CardHeader>
<CardTitle>{t("settings.theme")}</CardTitle>
</CardHeader>
<CardContent>
<PillSelector options={options} value={theme} onChange={setTheme} />
</CardContent>
</Card>
);
}

View File

@@ -1,14 +1,12 @@
import { AlertThresholdsCard } from "@/components/settings/AlertThresholdsCard";
import { BackupCard } from "@/components/settings/BackupCard";
import { CurrencyCard } from "@/components/settings/CurrencyCard";
import { LanguageCard } from "@/components/settings/LanguageCard";
import { ThemeCard } from "@/components/settings/ThemeCard";
import { PreferencesCard } from "@/components/settings/PreferencesCard";
export function SettingsPage() {
return (
<div className="space-y-5">
<ThemeCard />
<LanguageCard />
<PreferencesCard />
<CurrencyCard />
<AlertThresholdsCard />
<BackupCard />