From 0196ba764bac9abb958b8ded48d9a97991e2ddbb Mon Sep 17 00:00:00 2001 From: crupest Date: Tue, 26 Apr 2022 15:15:18 +0800 Subject: ... --- FrontEnd/src/views/about/index.tsx | 4 - FrontEnd/src/views/settings/index.tsx | 203 +++++++++++++++++++++++++--------- 2 files changed, 153 insertions(+), 54 deletions(-) diff --git a/FrontEnd/src/views/about/index.tsx b/FrontEnd/src/views/about/index.tsx index 11618086..438c1757 100644 --- a/FrontEnd/src/views/about/index.tsx +++ b/FrontEnd/src/views/about/index.tsx @@ -24,10 +24,6 @@ const frontendCredits: { name: "bootstrap", url: "https://getbootstrap.com", }, - { - name: "react-bootstrap", - url: "https://react-bootstrap.github.io", - }, { name: "vite", url: "https://vitejs.dev", diff --git a/FrontEnd/src/views/settings/index.tsx b/FrontEnd/src/views/settings/index.tsx index 86a8b263..1f526ee0 100644 --- a/FrontEnd/src/views/settings/index.tsx +++ b/FrontEnd/src/views/settings/index.tsx @@ -1,6 +1,7 @@ import React, { useState } from "react"; import { useNavigate } from "react-router-dom"; import { useTranslation } from "react-i18next"; +import classnames from "classnames"; import { useUser, userService } from "@/services/user"; @@ -11,9 +12,116 @@ import ConfirmDialog from "../common/dailog/ConfirmDialog"; import Card from "../common/Card"; import "./index.css"; +import { convertI18nText, I18nText } from "@/common"; +import Spinner from "../common/Spinner"; + +interface SettingSectionProps { + title: I18nText; +} + +const SettingSection: React.FC = ({ title, children }) => { + const { t } = useTranslation(); + + return ( + +

+ {convertI18nText(title, t)} +

+ {children} +
+ ); +}; + +interface ButtonSettingItemProps { + title: I18nText; + subtext?: I18nText; + onClick: () => void; + first?: boolean; + danger?: boolean; +} + +const ButtonSettingItem: React.FC = ({ + title, + subtext, + onClick, + first, + danger, +}) => { + const { t } = useTranslation(); + + return ( +
+ {convertI18nText(title, t)} + {subtext && ( + + {convertI18nText(subtext, t)} + + )} +
+ ); +}; + +interface SelectSettingItemProps { + title: I18nText; + subtext?: I18nText; + options: { + value: string; + label: I18nText; + }[]; + value?: string; + onSelect: (value: string) => void; + first?: boolean; +} + +const SelectSettingsItem: React.FC = ({ + title, + subtext, + options, + value, + onSelect, + first, +}) => { + const { t } = useTranslation(); + + return ( +
+
+
{convertI18nText(title, t)}
+ + {convertI18nText(subtext, t)} + +
+
+ {value == null ? ( + + ) : ( + + )} +
+
+ ); +}; const SettingsPage: React.FC = (_) => { - const { i18n, t } = useTranslation(); + const { i18n } = useTranslation(); const user = useUser(); const navigate = useNavigate(); @@ -27,62 +135,57 @@ const SettingsPage: React.FC = (_) => { <>
{user ? ( - -

- {t("settings.subheaders.account")} -

-
+ setDialog("changeavatar")} - > - {t("settings.changeAvatar")} -
-
+ setDialog("changenickname")} - > - {t("settings.changeNickname")} -
-
+ setDialog("changepassword")} - > - {t("settings.changePassword")} -
-
+ { setDialog("logout"); }} - > - {t("settings.logout")} -
-
+ danger + /> + ) : null} - -

- {t("settings.subheaders.customization")} -

-
-
-
{t("settings.languagePrimary")}
- - {t("settings.languageSecondary")} - -
-
- -
-
-
+ + { + void i18n.changeLanguage(value); + }} + first + /> +