mirror of
https://github.com/Zproger/Aurum.git
synced 2026-10-13 02:56:39 +07:00
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:
@@ -6,7 +6,7 @@ from pydantic_settings import BaseSettings, SettingsConfigDict
|
|||||||
# Single source of truth for the running app's version — surfaced in the API
|
# 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
|
# title and embedded in exported backups so an old file can be told apart
|
||||||
# from a current one.
|
# from a current one.
|
||||||
APP_VERSION = "0.19.0"
|
APP_VERSION = "0.19.1"
|
||||||
|
|
||||||
|
|
||||||
class Settings(BaseSettings):
|
class Settings(BaseSettings):
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"name": "aurum-frontend",
|
"name": "aurum-frontend",
|
||||||
"private": true,
|
"private": true,
|
||||||
"version": "0.19.0",
|
"version": "0.19.1",
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite",
|
"dev": "vite",
|
||||||
|
|||||||
@@ -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>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
42
frontend/src/components/settings/PreferencesCard.tsx
Normal file
42
frontend/src/components/settings/PreferencesCard.tsx
Normal 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>
|
||||||
|
);
|
||||||
|
}
|
||||||
@@ -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>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,14 +1,12 @@
|
|||||||
import { AlertThresholdsCard } from "@/components/settings/AlertThresholdsCard";
|
import { AlertThresholdsCard } from "@/components/settings/AlertThresholdsCard";
|
||||||
import { BackupCard } from "@/components/settings/BackupCard";
|
import { BackupCard } from "@/components/settings/BackupCard";
|
||||||
import { CurrencyCard } from "@/components/settings/CurrencyCard";
|
import { CurrencyCard } from "@/components/settings/CurrencyCard";
|
||||||
import { LanguageCard } from "@/components/settings/LanguageCard";
|
import { PreferencesCard } from "@/components/settings/PreferencesCard";
|
||||||
import { ThemeCard } from "@/components/settings/ThemeCard";
|
|
||||||
|
|
||||||
export function SettingsPage() {
|
export function SettingsPage() {
|
||||||
return (
|
return (
|
||||||
<div className="space-y-5">
|
<div className="space-y-5">
|
||||||
<ThemeCard />
|
<PreferencesCard />
|
||||||
<LanguageCard />
|
|
||||||
<CurrencyCard />
|
<CurrencyCard />
|
||||||
<AlertThresholdsCard />
|
<AlertThresholdsCard />
|
||||||
<BackupCard />
|
<BackupCard />
|
||||||
|
|||||||
Reference in New Issue
Block a user