import { useState, useEffect, ReactNode, ComponentPropsWithoutRef, } from "react"; import { useTranslation } from "react-i18next"; // For change language. import { useNavigate } from "react-router-dom"; import classNames from "classnames"; import { useUser, userService } from "~src/services/user"; import { getHttpUserClient } from "~src/http/user"; import { useC, I18nText } from "~src/components/common"; import { pushAlert } from "~src/components/alert"; import { useDialog, ConfirmDialog } from "~src/components/dialog"; import Card from "~src/components/Card"; import Spinner from "~src/components/Spinner"; import Page from "~src/components/Page"; import ChangePasswordDialog from "./ChangePasswordDialog"; import ChangeAvatarDialog from "./ChangeAvatarDialog"; import ChangeNicknameDialog from "./ChangeNicknameDialog"; import "./index.css"; interface SettingSectionProps extends Omit, "title"> { title: I18nText; children?: ReactNode; } function SettingSection({ title, className, children, ...otherProps }: SettingSectionProps) { const c = useC(); return (

{c(title)}

{children}
); } interface SettingItemContainerProps extends Omit, "title"> { title: I18nText; description?: I18nText; danger?: boolean; extraClassName?: string; } function SettingItemContainer({ title, description, danger, extraClassName, className, children, ...otherProps }: SettingItemContainerProps) { const c = useC(); return (
{c(title)}
{description && ( {c(description)} )}
{children}
); } type ButtonSettingItemProps = Omit; function ButtonSettingItem(props: ButtonSettingItemProps) { return ( ); } interface SelectSettingItemProps extends Omit { options: { value: string; label: I18nText; }[]; value?: string | null; onSelect: (value: string) => void; } function SelectSettingsItem({ options, value, onSelect, ...extraProps }: SelectSettingItemProps) { const c = useC(); return ( {value == null ? ( ) : ( )} ); } function RegisterCodeSettingItem() { const user = useUser(); // undefined: loading const [registerCode, setRegisterCode] = useState(); const { createDialogSwitch, dialogPropsMap } = useDialog(["confirm"]); useEffect(() => { setRegisterCode(undefined); }, [user]); useEffect(() => { if (user != null && registerCode === undefined) { void getHttpUserClient() .getRegisterCode(user.username) .then((code) => { setRegisterCode(code.registerCode ?? null); }); } }, [user, registerCode]); return ( <> {registerCode === undefined ? ( ) : registerCode === null ? ( Noop ) : ( { void navigator.clipboard.writeText(registerCode).then(() => { pushAlert({ color: "create", message: "settings.myRegisterCodeCopied", }); }); event.stopPropagation(); }} > {registerCode} )} { if (user == null) throw new Error(); void getHttpUserClient() .renewRegisterCode(user.username) .then(() => { setRegisterCode(undefined); }); }} {...dialogPropsMap["confirm"]} /> ); } function LanguageChangeSettingItem() { const { i18n } = useTranslation(); const language = i18n.language.slice(0, 2); return ( { void i18n.changeLanguage(value); }} /> ); } export default function SettingPage() { const user = useUser(); const navigate = useNavigate(); const { createDialogSwitch, dialogPropsMap } = useDialog([ "change-nickname", "change-avatar", "change-password", "logout", ]); return ( {user ? ( { void userService.logout().then(() => { navigate("/"); }); }} {...dialogPropsMap["logout"]} /> ) : null} ); }