diff --git a/components/AccountModal/index.scss b/components/AccountModal/index.scss index fa254155..781fb148 100644 --- a/components/AccountModal/index.scss +++ b/components/AccountModal/index.scss @@ -45,81 +45,6 @@ transform: translateX(21px); } } - - .field { - align-items: center; - display: flex; - flex-direction: row; - gap: $unit * 2; - - .left { - display: flex; - flex-direction: column; - flex-grow: 1; - gap: calc($unit / 2); - - label { - color: var(--text-tertiary); - font-size: $font-regular; - } - - p { - color: var(--text-secondary); - font-size: $font-small; - line-height: 1.1; - max-width: 300px; - - &.jp { - max-width: 270px; - } - } - } - - .preview { - $diameter: $unit * 6; - background-color: $grey-90; - border-radius: 999px; - height: $diameter; - width: $diameter; - - img { - height: $diameter; - width: $diameter; - } - - &.fire { - background: $fire-bg-20; - } - - &.water { - background: $water-bg-20; - } - - &.wind { - background: $wind-bg-20; - } - - &.earth { - background: $earth-bg-20; - } - - &.dark { - background: $dark-bg-10; - } - - &.light { - background: $light-bg-20; - } - } - } - - section { - margin-bottom: $unit; - - h2 { - margin-bottom: $unit * 3; - } - } } .DialogDescription { diff --git a/components/AccountModal/index.tsx b/components/AccountModal/index.tsx index 858e48f7..46c62e40 100644 --- a/components/AccountModal/index.tsx +++ b/components/AccountModal/index.tsx @@ -1,4 +1,5 @@ -import React, { useEffect, useState } from 'react' +import React, { useState } from 'react' +import { getCookie, setCookie } from 'cookies-next' import { useRouter } from 'next/router' import { useTranslation } from 'next-i18next' @@ -9,30 +10,46 @@ import { DialogTitle, DialogTrigger, } from '~components/Dialog' -// import * as Dialog from '@radix-ui/react-dialog' -import * as Switch from '@radix-ui/react-switch' - -import Select from '~components/Select' +import Button from '~components/Button' import SelectItem from '~components/SelectItem' import PictureSelectItem from '~components/PictureSelectItem' +// import * as Switch from '@radix-ui/react-switch' import api from '~utils/api' +import changeLanguage from 'utils/changeLanguage' import { accountState } from '~utils/accountState' import { pictureData } from '~utils/pictureData' -import Button from '~components/Button' - import CrossIcon from '~public/icons/Cross.svg' import './index.scss' -import { useSnapshot } from 'valtio' -import { getCookie, setCookie } from 'cookies-next' +import { subscribe } from 'valtio' +import SelectTableField from '~components/SelectTableField' -const AccountModal = () => { - const router = useRouter() +type StateVariables = { + [key: string]: boolean + picture: boolean + gender: boolean + language: boolean + theme: boolean +} + +interface Props { + username?: string + picture?: string + gender?: number + language?: string + theme?: string + private?: boolean +} + +const AccountModal = (props: Props) => { + // Localization const { t } = useTranslation('common') + const router = useRouter() const locale = router.locale && ['en', 'ja'].includes(router.locale) ? router.locale : 'en' + // Cookies const accountCookie = getCookie('account') const userCookie = getCookie('user') @@ -41,28 +58,110 @@ const AccountModal = () => { user: userCookie ? JSON.parse(userCookie as string) : undefined, } - // State + // UI State const [open, setOpen] = useState(false) - const [openPictureSelect, setOpenPictureSelect] = useState(false) - const [openGenderSelect, setOpenGenderSelect] = useState(false) - const [openLanguageSelect, setOpenLanguageSelect] = useState(false) - const [openThemeSelect, setOpenThemeSelect] = useState(false) + const [selectOpenState, setSelectOpenState] = useState({ + picture: false, + gender: false, + language: false, + theme: false, + }) - const [username, setUsername] = useState('') - const [picture, setPicture] = useState('') - const [language, setLanguage] = useState('') - const [gender, setGender] = useState(0) - const [theme, setTheme] = useState('system') + // Values + const [username, setUsername] = useState(props.username || '') + const [picture, setPicture] = useState(props.picture || '') + const [language, setLanguage] = useState(props.language || '') + const [gender, setGender] = useState(props.gender || 0) + const [theme, setTheme] = useState(props.theme || 'system') // const [privateProfile, setPrivateProfile] = useState(false) - useEffect(() => { - setUsername(cookieData.account.username) - setGender(cookieData.user.gender) - setPicture(cookieData.user.picture) - setLanguage(cookieData.user.language) - setTheme(cookieData.user.theme ? cookieData.user.theme : 'system') - }, [cookieData]) + // Setup + // UI management + function openChange(open: boolean) { + setOpen(open) + } + + function openSelect(name: 'picture' | 'gender' | 'language' | 'theme') { + const stateVars = selectOpenState + Object.keys(stateVars).forEach((key) => { + if (key === name) { + stateVars[name] = true + } else { + stateVars[key] = false + } + }) + + setSelectOpenState(stateVars) + } + + // Event handlers + function handlePictureChange(value: string) { + setPicture(value) + } + + function handleLanguageChange(value: string) { + setLanguage(value) + } + + function handleGenderChange(value: string) { + setGender(parseInt(value)) + } + + function handleThemeChange(value: string) { + setTheme(value) + } + + // API calls + function update(event: React.FormEvent) { + event.preventDefault() + + const object = { + user: { + picture: picture, + element: pictureData.find((i) => i.filename === picture)?.element, + language: language, + gender: gender, + theme: theme, + // private: privateProfile, + }, + } + + if (accountState.account.user) { + api.endpoints.users + .update(accountState.account.user?.id, object) + .then((response) => { + const user = response.data + console.log(user) + + const cookieObj = { + picture: user.avatar.picture, + element: user.avatar.element, + gender: user.gender, + language: user.language, + theme: user.theme, + } + + setCookie('user', cookieObj, { path: '/' }) + + accountState.account.user = { + id: user.id, + username: user.username, + picture: user.avatar.picture, + element: user.avatar.element, + language: user.language, + theme: user.theme, + gender: user.gender, + } + + setOpen(false) + changeLanguage(router, user.language) + router.push(router.asPath, undefined) + }) + } + } + + // Views const pictureOptions = pictureData .sort((a, b) => (a.name.en > b.name.en ? 1 : -1)) .map((item, i) => { @@ -81,78 +180,81 @@ const AccountModal = () => { ) }) - function handlePictureChange(value: string) { - setPicture(value) - } + const pictureField = () => ( + openSelect('picture')} + onChange={handlePictureChange} + imageAlt={t('modals.settings.labels.image_alt')} + imageClass={pictureData.find((i) => i.filename === picture)?.element} + imageSrc={[`/profile/${picture}.png`, `/profile/${picture}@2x.png 2x`]} + value={picture} + > + {pictureOptions} + + ) - function handleLanguageChange(value: string) { - setLanguage(value) - } + const genderField = () => ( + openSelect('gender')} + onChange={handleGenderChange} + value={`${gender}`} + > + + {t('modals.settings.gender.gran')} + + + {t('modals.settings.gender.djeeta')} + + + ) - function handleGenderChange(value: string) { - setGender(parseInt(value)) - } + const languageField = () => ( + openSelect('language')} + onChange={handleLanguageChange} + value={language} + > + + {t('modals.settings.language.english')} + + + {t('modals.settings.language.japanese')} + + + ) - function handleThemeChange(value: string) { - setTheme(value) - } - - // function handlePrivateChange(checked: boolean) { - // setPrivateProfile(checked) - // } - - function update(event: React.FormEvent) { - event.preventDefault() - - const object = { - user: { - picture: picture, - element: pictureData.find((i) => i.filename === picture)?.element, - language: language, - gender: gender, - // private: privateProfile, - }, - } - - api.endpoints.users - .update(cookieData.account.user_id, object) - .then((response) => { - const user = response.data.user - - const cookieObj = { - picture: user.picture.picture, - element: user.picture.element, - gender: user.gender, - language: user.language, - } - - setCookie('user', cookieObj, { path: '/' }) - - accountState.account.user = { - id: user.id, - username: user.username, - picture: user.picture.picture, - element: user.picture.element, - language: user.language, - theme: user.theme, - gender: user.gender, - } - - setOpen(false) - changeLanguage(user.language) - }) - } - - function changeLanguage(newLanguage: string) { - if (newLanguage !== router.locale) { - // setCookies("NEXT_LOCALE", newLanguage, { path: "/" }) - // router.push(router.asPath, undefined, { locale: newLanguage }) - } - } - - function openChange(open: boolean) { - setOpen(open) - } + const themeField = () => ( + openSelect('theme')} + onChange={handleThemeChange} + value={theme} + > + + {t('modals.settings.theme.system')} + + + {t('modals.settings.theme.light')} + + + {t('modals.settings.theme.dark')} + + + ) return ( @@ -177,126 +279,10 @@ const AccountModal = () => {
-
-
- - {/*

Displayed next to your name

*/} -
- -
i.filename === picture)?.element - }`} - > - {picture ? ( - Profile preview - ) : ( - '' - )} -
- - -
-
-
- - {/*

- Displayed on the Character tab of your teams -

*/} -
- - -
-
-
- -
- - -
-
-
- -
- - -
- {/*
-
- -

- {t('modals.settings.descriptions.private')} -

-
- - - - -
*/} - + {pictureField()} + {genderField()} + {languageField()} + {themeField()}