'use client'; import { updateProfile } from '@services/settings/profile' import React, { useEffect } from 'react' import { Formik, Form } from 'formik' import { useLHSession } from '@components/Contexts/LHSessionContext' import { ArrowBigUpDash, Check, FileWarning, Info, UploadCloud, AlertTriangle, LogOut } from 'lucide-react' import UserAvatar from '@components/Objects/UserAvatar' import { updateUserAvatar } from '@services/users/users' import { constructAcceptValue } from '@/lib/constants' import * as Yup from 'yup' import { Input } from "@components/ui/input" import { Textarea } from "@components/ui/textarea" import { Button } from "@components/ui/button" import { Label } from "@components/ui/label" import { toast } from 'react-hot-toast' import { signOut } from 'next-auth/react' import { getUriWithoutOrg } from '@services/config/config'; const SUPPORTED_FILES = constructAcceptValue(['image']) const validationSchema = Yup.object().shape({ email: Yup.string().email('Invalid email').required('Email is required'), username: Yup.string().required('Username is required'), first_name: Yup.string().required('First name is required'), last_name: Yup.string().required('Last name is required'), bio: Yup.string().max(400, 'Bio must be 400 characters or less'), }) interface FormValues { username: string; first_name: string; last_name: string; email: string; bio: string; } function UserEditGeneral() { const session = useLHSession() as any; const access_token = session?.data?.tokens?.access_token; const [localAvatar, setLocalAvatar] = React.useState(null) as any const [isLoading, setIsLoading] = React.useState(false) as any const [error, setError] = React.useState() as any const [success, setSuccess] = React.useState('') as any const handleFileChange = async (event: any) => { const file = event.target.files[0] setLocalAvatar(file) setIsLoading(true) const res = await updateUserAvatar(session.data.user_uuid, file, access_token) // wait for 1 second to show loading animation await new Promise((r) => setTimeout(r, 1500)) if (res.success === false) { setError(res.HTTPmessage) } else { setIsLoading(false) setError('') setSuccess('Avatar Updated') } } const handleEmailChange = async (newEmail: string) => { toast.success('Profile Updated Successfully', { duration: 4000 }) // Show message about logging in with new email toast((t) => (
Please login again with your new email: {newEmail}
), { duration: 4000, icon: '📧' }) // Wait for 4 seconds before signing out await new Promise(resolve => setTimeout(resolve, 4000)) signOut({ redirect: true, callbackUrl: getUriWithoutOrg('/') }) } useEffect(() => { }, [session, session.data]) return (
{session.data.user && ( enableReinitialize initialValues={{ username: session.data.user.username, first_name: session.data.user.first_name, last_name: session.data.user.last_name, email: session.data.user.email, bio: session.data.user.bio || '', }} validationSchema={validationSchema} onSubmit={(values, { setSubmitting }) => { const isEmailChanged = values.email !== session.data.user.email const loadingToast = toast.loading('Updating profile...') setTimeout(() => { setSubmitting(false) updateProfile(values, session.data.user.id, access_token) .then(() => { toast.dismiss(loadingToast) if (isEmailChanged) { handleEmailChange(values.email) } else { toast.success('Profile Updated Successfully') } }) .catch(() => { toast.error('Failed to update profile', { id: loadingToast }) }) }, 400) }} > {({ isSubmitting, values, handleChange, errors, touched }) => (

Account Settings

Manage your personal information and preferences

{/* Profile Information Section */}
{touched.email && errors.email && (

{errors.email}

)} {values.email !== session.data.user.email && (
You will be logged out after changing your email
)}
{touched.username && errors.username && (

{errors.username}

)}
{touched.first_name && errors.first_name && (

{errors.first_name}

)}
{touched.last_name && errors.last_name && (

{errors.last_name}

)}