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", message: "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", message: "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", message: "authentication:already-used", } } else if (message.endsWith("email to sign in.")) { return { type: "error", message: "authentication:email-required-to-sign-in", } } return { type: "error", message: "errors:server-error", } } return { type: "error", message: "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, { headers: { "Content-Type": "multipart/form-data", }, }, ) 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