diff --git a/components/AccountModal/index.scss b/components/AccountModal/index.scss new file mode 100644 index 00000000..81371cce --- /dev/null +++ b/components/AccountModal/index.scss @@ -0,0 +1,160 @@ +.Account.Dialog { + display: flex; + flex-direction: column; + gap: $unit * 2; + width: $unit * 60; + + form { + display: flex; + flex-direction: column; + gap: $unit * 2; + + .Switch { + $height: 34px; + background: $grey-70; + border-radius: $height / 2; + border: none; + position: relative; + width: 58px; + height: $height; + + &:focus { + box-shadow: 0 0 0 2px $grey-00; + } + + &[data-state="checked"] { + background: $grey-00; + } + } + + .Thumb { + background: white; + border-radius: 13px; + display: block; + height: 26px; + width: 26px; + transition: transform 100ms; + transform: translateX(-1px); + + &:hover { + cursor: pointer; + } + + &[data-state="checked"] { + background: white; + transform: translateX(21px); + } + } + + .Button { + font-size: $font-regular; + padding: ($unit * 1.5) ($unit * 2); + margin-top: $unit * 2; + width: 100%; + + &.btn-disabled { + background: $grey-90; + color: $grey-70; + cursor: not-allowed; + } + + &:not(.btn-disabled) { + background: $grey-90; + color: $grey-40; + + &:hover { + background: $grey-80; + } + } + } + + .field { + align-items: center; + display: flex; + flex-direction: row; + gap: $unit * 2; + + select { + background: no-repeat url('/icons/ArrowDark.svg'), $grey-90; + background-position-y: center; + background-position-x: 95%; + margin: 0; + width: 240px; + } + + .left { + display: flex; + flex-direction: column; + flex-grow: 1; + gap: $unit / 2; + + label { + color: $grey-00; + font-size: $font-regular; + } + + p { + color: $grey-60; + font-size: $font-small; + line-height: 1.1; + max-width: 300px; + } + } + + .preview { + $diameter: 48px; + background-color: $grey-90; + border-radius: 999px; + height: $diameter; + width: $diameter; + + img { + height: $diameter; + width: $diameter; + } + + &.fire { + background: $fire-bg-light; + } + + &.water { + background: $water-bg-light; + } + + &.wind { + background: $wind-bg-light; + } + + &.earth { + background: $earth-bg-light; + } + + &.dark { + background: $dark-bg-light; + } + + &.light { + background: $light-bg-light; + } + } + } + + section { + margin-bottom: $unit; + + h2 { + margin-bottom: $unit * 3; + } + } + } + + .DialogDescription { + font-size: $font-regular; + line-height: 1.24; + margin-bottom: $unit; + + &:last-of-type { + margin-bottom: 0; + } + } +} diff --git a/components/AccountModal/index.tsx b/components/AccountModal/index.tsx new file mode 100644 index 00000000..3d13c347 --- /dev/null +++ b/components/AccountModal/index.tsx @@ -0,0 +1,158 @@ +import React, { useEffect, useState } from 'react' +import { useCookies } from 'react-cookie' +import { useSnapshot } from 'valtio' + +import * as Dialog from '@radix-ui/react-dialog' +import * as Switch from '@radix-ui/react-switch' + +import api from '~utils/api' +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' + +const AccountModal = () => { + const { account } = useSnapshot(accountState) + + // Cookies + const [cookies] = useCookies(['user']) + const headers = (cookies.user != null) ? { + headers: { + 'Authorization': `Bearer ${cookies.user.access_token}` + } + } : {} + + // State + const [open, setOpen] = useState(false) + const [picture, setPicture] = useState('') + const [language, setLanguage] = useState('') + const [privateProfile, setPrivateProfile] = useState(false) + + // Refs + const pictureSelect = React.createRef() + const languageSelect = React.createRef() + const privateSelect = React.createRef() + + useEffect(() => { + if (cookies.user) setPicture(cookies.user.picture) + if (cookies.user) setLanguage(cookies.user.language) + }, [cookies]) + + const pictureOptions = ( + pictureData.sort((a, b) => (a.name.en > b.name.en) ? 1 : -1).map((item, i) => { + return ( + + ) + }) + ) + + function handlePictureChange(event: React.ChangeEvent) { + if (pictureSelect.current) + setPicture(pictureSelect.current.value) + } + + function handleLanguageChange(event: React.ChangeEvent) { + if (languageSelect.current) + setLanguage(languageSelect.current.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, + private: privateProfile + } + } + + api.endpoints.users.update(cookies.user.user_id, object, headers) + .then(response => { + setOpen(false) + }) + } + + function openChange(open: boolean) { + setOpen(open) + } + + return ( + + +
  • + Settings +
  • +
    + + event.preventDefault() }> +
    +
    + Account Settings + @{account.user?.username} +
    + + + + + +
    + +
    +
    +
    + +
    + +
    i.filename === picture)?.element}`}> + Profile preview +
    + + +
    +
    +
    + +
    + + +
    +
    +
    + +

    Hide your profile and prevent your grids from showing up in collections

    +
    + + + + +
    + + +
    +
    + +
    +
    + ) +} + +export default AccountModal