"use client"; import Editor from "@/components/editor"; import sanitizeHtml from "sanitize-html"; import { getCookie, hasCookie } from "@/helpers/cookie"; import { UserType } from "@/types/UserType"; import { Avatar, Button, Form, Input } from "@nextui-org/react"; import { redirect, usePathname } from "next/navigation"; import { useEffect, useState } from "react"; import { toast } from "react-toastify"; import { LoaderCircle } from "lucide-react"; import Image from "next/image"; import { getSelf, updateUser } from "@/requests/user"; export default function UserPage() { const [user, setUser] = useState<UserType>(); const [profilePicture, setProfilePicture] = useState(""); const [name, setName] = useState(""); const [bannerPicture, setBannerPicture] = useState(""); const [bio, setBio] = useState(""); const [errors] = useState({}); const pathname = usePathname(); const [waitingSave, setWaitingSave] = useState(false); useEffect(() => { loadUser(); async function loadUser() { if (!hasCookie("token")) { setUser(undefined); redirect("/"); return; } const response = await getSelf(); if (response.status == 200) { const data = await response.json(); setUser(data); setProfilePicture(data.profilePicture ?? ""); setBannerPicture(data.bannerPicture ?? ""); setBio(data.bio ?? ""); setName(data.name ?? ""); } else { setUser(undefined); } } }, [pathname]); return ( <div className="flex items-center justify-center"> {!user ? ( "Loading settings..." ) : ( <Form className="w-full max-w-2xl flex flex-col gap-4" validationErrors={errors} onReset={() => { setProfilePicture(user.profilePicture ?? ""); setBannerPicture(user.bannerPicture ?? ""); setBio(user.bio ?? ""); setName(user.name ?? ""); }} onSubmit={async (e) => { e.preventDefault(); const sanitizedBio = sanitizeHtml(bio); if (!name) { toast.error("You need to enter a name"); return; } setWaitingSave(true); const response = await updateUser(user.slug, name, sanitizedBio, profilePicture, bannerPicture); if (response.ok) { toast.success("Changed settings"); setUser(await response.json()); setWaitingSave(false); } else { toast.error("Failed to update settings"); setWaitingSave(false); } }} > <p className="text-3xl">Settings</p> <Input label="Name" labelPlacement="outside" name="name" placeholder="Enter a name" type="text" value={name} onValueChange={setName} /> <p>Bio</p> <Editor content={bio} setContent={setBio} /> <Input label="Profile Picture" labelPlacement="outside" name="profilePicture" placeholder="Enter a url to an image" type="text" value={profilePicture} onValueChange={setProfilePicture} /> {profilePicture && <Avatar src={profilePicture} />} <Input label="Banner Picture" labelPlacement="outside" name="bannerPicture" placeholder="Enter a url to an image" type="text" value={bannerPicture} onValueChange={setBannerPicture} /> {bannerPicture && bannerPicture.startsWith("https://") && bannerPicture.length > 8 && ( <div className="bg-[#222222] h-28 w-full relative"> <Image src={bannerPicture} alt={`${user.name}'s profile banner`} className="object-cover" fill /> </div> )} <div className="flex gap-2"> <Button color="primary" type="submit"> {waitingSave ? ( <LoaderCircle className="animate-spin" size={16} /> ) : ( <p>Save</p> )} </Button> <Button type="reset" variant="flat"> Reset </Button> </div> </Form> )} </div> ); }