import { useCallback, useEffect, useState } from "react"; import { useRouter } from "next/router"; import useSWR, { mutate } from "swr"; // react-hook-form import { Controller, useForm } from "react-hook-form"; import { IProject, IWorkspace } from "types"; // lib import { requiredAdmin } from "lib/auth"; // layouts import SettingsLayout from "layouts/settings-layout"; // services import projectService from "services/project.service"; import workspaceService from "services/workspace.service"; // components import ConfirmProjectDeletion from "components/project/confirm-project-deletion"; import EmojiIconPicker from "components/emoji-icon-picker"; // hooks import useToast from "hooks/use-toast"; // ui import { Button, Input, TextArea, Loader, CustomSelect } from "components/ui"; import { BreadcrumbItem, Breadcrumbs } from "components/breadcrumbs"; import OutlineButton from "components/ui/outline-button"; // helpers import { debounce } from "helpers/functions.helper"; // types import type { NextPage, NextPageContext } from "next"; // fetch-keys import { PROJECTS_LIST, PROJECT_DETAILS, WORKSPACE_DETAILS } from "constants/fetch-keys"; // constants import { NETWORK_CHOICES } from "constants/"; const defaultValues: Partial = { name: "", description: "", identifier: "", network: 0, }; type TGeneralSettingsProps = { isMember: boolean; isOwner: boolean; isViewer: boolean; isGuest: boolean; }; const GeneralSettings: NextPage = (props) => { const { isMember, isOwner, isViewer, isGuest } = props; const [selectProject, setSelectedProject] = useState(null); const { setToastAlert } = useToast(); const router = useRouter(); const { workspaceSlug, projectId } = router.query; const { data: activeWorkspace } = useSWR( workspaceSlug ? WORKSPACE_DETAILS(workspaceSlug as string) : null, () => (workspaceSlug ? workspaceService.getWorkspace(workspaceSlug as string) : null) ); const { data: projectDetails } = useSWR( workspaceSlug && projectId ? PROJECT_DETAILS(projectId as string) : null, workspaceSlug && projectId ? () => projectService.getProject(workspaceSlug as string, projectId as string) : null ); const { register, handleSubmit, reset, control, setError, formState: { errors, isSubmitting }, } = useForm({ defaultValues, }); const checkIdentifier = (slug: string, value: string) => { projectService.checkProjectIdentifierAvailability(slug, value).then((response) => { if (response.exists) setError("identifier", { message: "Identifier already exists" }); }); }; // eslint-disable-next-line react-hooks/exhaustive-deps const checkIdentifierAvailability = useCallback(debounce(checkIdentifier, 1500), []); useEffect(() => { if (projectDetails) reset({ ...projectDetails, default_assignee: projectDetails.default_assignee?.id, project_lead: projectDetails.project_lead?.id, workspace: (projectDetails.workspace as IWorkspace).id, }); }, [projectDetails, reset]); const onSubmit = async (formData: IProject) => { if (!activeWorkspace || !projectDetails) return; const payload: Partial = { name: formData.name, network: formData.network, identifier: formData.identifier, description: formData.description, default_assignee: formData.default_assignee, project_lead: formData.project_lead, icon: formData.icon, }; await projectService .updateProject(activeWorkspace.slug, projectDetails.id, payload) .then((res) => { mutate( PROJECT_DETAILS(projectDetails.id), (prevData) => ({ ...prevData, ...res }), false ); mutate(PROJECTS_LIST(activeWorkspace.slug)); setToastAlert({ title: "Success", type: "success", message: "Project updated successfully", }); }) .catch((err) => { console.error(err); }); }; return ( } > setSelectedProject(null)} onSuccess={() => { router.push(`/${workspaceSlug}/projects`); }} />

General

This information will be displayed to every member of the project.

Icon & Name

Select an icon and a name for the project.

{projectDetails ? ( ( )} /> ) : ( )} {projectDetails ? ( ) : ( )}

Description

Give a description to the project.

{projectDetails ? (