import { useCallback, useEffect, useState } from "react"; import { useRouter } from "next/router"; import type { NextPage, NextPageContext } from "next"; import useSWR, { mutate } from "swr"; import { Controller, useForm } from "react-hook-form"; // fetch-keys import { PROJECTS_LIST, PROJECT_DETAILS, WORKSPACE_DETAILS } from "constants/fetch-keys"; // common import { debounce } from "constants/common"; // constants import { NETWORK_CHOICES } from "constants/"; // lib import { requiredAdmin } from "lib/auth"; // layouts import SettingsLayout from "layouts/settings-layout"; // services import projectService from "lib/services/project.service"; import workspaceService from "lib/services/workspace.service"; // components import ConfirmProjectDeletion from "components/project/confirm-project-deletion"; // hooks import useToast from "lib/hooks/useToast"; // ui import { BreadcrumbItem, Breadcrumbs, Button, EmojiIconPicker, Input, Select, TextArea, Loader, CustomSelect, } from "ui"; import OutlineButton from "ui/outline-button"; // types import { IProject, IWorkspace } from "types"; 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), (prevData) => { const newData = prevData?.map((item) => { if (item.id === res.id) { return res; } return item; }); return newData; }, false ); 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 ? (