diff --git a/frontend/app/components/Client/Projects/ProjectForm.tsx b/frontend/app/components/Client/Projects/ProjectForm.tsx new file mode 100644 index 000000000..42c85bed5 --- /dev/null +++ b/frontend/app/components/Client/Projects/ProjectForm.tsx @@ -0,0 +1,148 @@ +import React, { ChangeEvent, FormEvent, useEffect } from 'react'; +import styles from 'Components/Client/Sites/siteForm.module.css'; +import { Icon } from 'UI'; +import Project from '@/mstore/types/project'; +import { projectStore, useStore } from '@/mstore'; +import { Modal, Segmented, Form, Input, Button } from 'antd'; +import { toast } from 'react-toastify'; +import { observer } from 'mobx-react-lite'; + +interface Props { + project?: Project; + onClose?: (arg: any) => void; +} + +function ProjectForm(props: Props) { + const { onClose } = props; + const { projectsStore } = useStore(); + const project = projectsStore.instance as Project; + const loading = projectsStore.loading; + const canDelete = projectsStore.list.length > 1; + const pathname = window.location.pathname; + + useEffect(() => { + if (props.project && props.project.id) { + projectsStore.initProject(props.project); + } else { + projectsStore.initProject({}); + } + }, []); + + const handleEdit = ({ target: { name, value } }: ChangeEvent) => { + projectsStore.editInstance({ [name]: value }); + }; + + const onSubmit = (e: FormEvent) => { + e.preventDefault(); + if (!projectsStore.instance) return; + if (projectsStore.instance.id && projectsStore.instance.exists()) { + projectsStore + .updateProject(projectsStore.instance.id, project) + .then((response: any) => { + if (!response || !response.errors || response.errors.size === 0) { + if (onClose) { + onClose(null); + } + if (!pathname.includes('onboarding')) { + void projectsStore.fetchList(); + } + toast.success('Project updated successfully'); + } else { + toast.error(response.errors[0]); + } + }); + } else { + projectsStore.save(projectsStore.instance!).then((response: any) => { + if (!response || !response.errors || response.errors.size === 0) { + if (onClose) { + onClose(null); + } + // searchStore.clearSearch(); + // mstore.searchStoreLive.clearSearch(); + // mstore.initClient(); + toast.success('Project added successfully'); + } else { + toast.error(response.errors[0]); + } + }); + } + }; + + const handleRemove = async () => { + Modal.confirm({ + title: 'Project Deletion Alert', + content: 'Are you sure you want to delete this project? Deleting it will permanently remove the project, along with all associated sessions and data.', + onOk: () => { + projectsStore.removeProject(project.id!).then(() => { + if (onClose) { + onClose(null); + } + if (project.id === projectsStore.active?.id) { + projectsStore.setSiteId(projectStore.list[0].id!); + } + }); + } + }); + }; + + return ( +
null}> +
+ + + + + + +
+ { + projectsStore.editInstance({ platform: value }); + }} + /> +
+
+
+ + {project.exists() && ( + + )} +
+
+
+ ); +} + +export default observer(ProjectForm); diff --git a/frontend/app/components/Client/Projects/ProjectList.tsx b/frontend/app/components/Client/Projects/ProjectList.tsx index bb8816b09..3832ecfdb 100644 --- a/frontend/app/components/Client/Projects/ProjectList.tsx +++ b/frontend/app/components/Client/Projects/ProjectList.tsx @@ -21,7 +21,12 @@ function ProjectList() { return (
- + setSearch('')} + allowClear + /> item.name.toLowerCase().includes(search.toLowerCase()))} renderItem={(item: Project) => ( diff --git a/frontend/app/components/Client/Projects/ProjectTabs.tsx b/frontend/app/components/Client/Projects/ProjectTabs.tsx index 26599666d..f84e46a98 100644 --- a/frontend/app/components/Client/Projects/ProjectTabs.tsx +++ b/frontend/app/components/Client/Projects/ProjectTabs.tsx @@ -1,8 +1,12 @@ import React from 'react'; -import { Tabs } from 'antd'; +import { Tabs, TabsProps } from 'antd'; import { useStore } from '@/mstore'; import { observer } from 'mobx-react-lite'; +const customTabBar: TabsProps['renderTabBar'] = (props, DefaultTabBar) => ( + +); + function ProjectTabs() { const { projectsStore } = useStore(); const activeTab = projectsStore.config.tab; @@ -22,14 +26,14 @@ function ProjectTabs() { return ( ({ key: tab.key, label: tab.label - // children: tab.content, }))} /> ); diff --git a/frontend/app/components/Client/Projects/Projects.tsx b/frontend/app/components/Client/Projects/Projects.tsx index f6984ac19..50f371409 100644 --- a/frontend/app/components/Client/Projects/Projects.tsx +++ b/frontend/app/components/Client/Projects/Projects.tsx @@ -7,8 +7,9 @@ import { useStore } from '@/mstore'; import { observer } from 'mobx-react-lite'; import { PlusIcon } from 'lucide-react'; import ProjectTabContent from 'Components/Client/Projects/ProjectTabContent'; -import NewSiteForm from 'Components/Client/Sites/NewSiteForm'; import { useModal } from 'Components/ModalContext'; +import ProjectForm from 'Components/Client/Projects/ProjectForm'; +import Project from '@/mstore/types/project'; function Projects() { const { projectsStore } = useStore(); @@ -37,7 +38,7 @@ function Projects() { }, [pid, tab]); const createProject = () => { - openModal(, { + openModal(, { title: 'New Project' }); }; @@ -52,23 +53,25 @@ function Projects() { style={{ height: 'calc(100vh - 140px)' }} extra={ - } > - - - + + +
+ +
- - + + {project?.name} - -
+ +
{project && }