import Image from 'next/image' import useTranslation from 'next-translate/useTranslation' import { useState, useMemo } from 'react' import { Form, useForm } from 'react-component-form' import { EyeIcon, PhotographIcon } from '@heroicons/react/solid' import { Type } from '@sinclair/typebox' import axios from 'axios' import Link from 'next/link' import type { HandleUseFormCallback } from 'react-component-form' import { Input } from '../../design/Input' import { Checkbox } from '../../design/Checkbox' import { Textarea } from '../../design/Textarea' import { SocialMediaButton } from '../../design/SocialMediaButton' import { SwitchTheme } from '../../Header/SwitchTheme' import { Language } from '../../Header/Language' import { useAuthentication } from '../../../tools/authentication' import { Button } from '../../design/Button' import { FormState } from '../../design/FormState' import { userSchema } from '../../../models/User' import { userSettingsSchema } from '../../../models/UserSettings' import type { ProviderOAuth } from '../../../models/OAuth' import { providers } from '../../../models/OAuth' import { useFormTranslation } from '../../../hooks/useFormTranslation' const schema = { name: userSchema.name, status: Type.Optional(userSchema.status), email: Type.Optional(Type.Union([userSchema.email, Type.Null()])), website: Type.Optional(userSchema.website), biography: Type.Optional(userSchema.biography), isPublicGuilds: userSettingsSchema.isPublicGuilds, isPublicEmail: userSettingsSchema.isPublicEmail } export const UserSettings: React.FC = () => { const { user, setUser, authentication } = useAuthentication() const { t } = useTranslation() const [inputValues, setInputValues] = useState({ name: user.name, status: user.status, email: user.email, website: user.website, biography: user.biography, isPublicGuilds: user.settings.isPublicGuilds, isPublicEmail: user.settings.isPublicEmail }) const { handleUseForm, fetchState, setFetchState, message, setMessage, errors } = useForm(schema) const { getFirstErrorTranslation } = useFormTranslation() const hasAllProviders = useMemo(() => { return providers.every((provider) => { return user.strategies.includes(provider) }) }, [user.strategies]) const onSubmit: HandleUseFormCallback = async (formData) => { try { const { isPublicGuilds, isPublicEmail, ...userData } = formData const userSettings = { isPublicEmail, isPublicGuilds } const { data: userCurrentData } = await authentication.api.put( `/users/current?redirectURI=${window.location.origin}/authentication/signin`, userData ) setInputValues(formData as unknown as any) const hasEmailChanged = user.email !== userCurrentData.user.email if (hasEmailChanged) { return { type: 'success', value: 'application:success-email-changed' } } const { data: userCurrentSettings } = await authentication.api.put( '/users/current/settings', userSettings ) setUser((oldUser) => { return { ...oldUser, ...userCurrentData, settings: { ...oldUser.settings, ...userCurrentSettings.settings } } }) return { type: 'success', value: 'application:saved-information' } } catch (error) { if (axios.isAxiosError(error) && error.response?.status === 400) { const message = error.response.data.message as string if (message.endsWith('already taken.')) { return { type: 'error', value: 'authentication:already-used' } } else if (message.endsWith('email to sign in.')) { return { type: 'error', value: 'authentication:email-required-to-sign-in' } } return { type: 'error', value: 'errors:server-error' } } return { type: 'error', value: 'errors:server-error' } } } const onChange: React.ChangeEventHandler< HTMLInputElement | HTMLTextAreaElement > = (event) => { setInputValues((oldInputValues) => { return { ...oldInputValues, [event.target.name]: event.target.value } }) } const onChangeCheckbox: React.ChangeEventHandler = ( event ) => { setInputValues((oldInputValues) => { return { ...oldInputValues, [event.target.name]: event.target.checked } }) } const handleFileChange: React.ChangeEventHandler = async ( event ) => { setFetchState('loading') const files = event?.target?.files if (files != null && files.length === 1 && files[0] != null) { const file = files[0] const formData = new FormData() formData.append('logo', file) try { const { data } = await authentication.api.put( `/users/current/logo`, formData ) setUser((oldUser) => { return { ...oldUser, logo: data.user.logo } }) setFetchState('idle') } catch (error) { setFetchState('error') setMessage('errors:server-error') } } } const handleSignout = async (): Promise => { setFetchState('loading') await authentication.signoutServerSide() } const handleSignoutAllDevices = async (): Promise => { setFetchState('loading') await authentication.signoutAllDevicesServerSide() } const handleDeletionProvider = ( provider: ProviderOAuth ): (() => Promise) => { return async () => { try { setFetchState('loading') await authentication.api.delete(`/users/oauth2/${provider}`) setUser((oldUser) => { return { ...oldUser, strategies: oldUser.strategies.filter((strategy) => { return strategy !== provider }) } }) setMessage('application:success-deleted-provider') } catch (error) { setFetchState('error') setMessage('errors:server-error') } } } const handleAddProvider = ( provider: ProviderOAuth ): (() => Promise) => { return async () => { const redirect = window.location.href.replace(location.search, '') const { data: url } = await authentication.api.get( `/users/oauth2/${provider.toLowerCase()}/add-strategy?redirectURI=${redirect}` ) window.location.href = url } } return (
Profil Picture