diff --git a/packages/frontend/src/components/shared/CustomIcon/CopyUnfilledIcon.tsx b/packages/frontend/src/components/shared/CustomIcon/CopyUnfilledIcon.tsx new file mode 100644 index 00000000..7add0b35 --- /dev/null +++ b/packages/frontend/src/components/shared/CustomIcon/CopyUnfilledIcon.tsx @@ -0,0 +1,20 @@ +import { CustomIcon, CustomIconProps } from './CustomIcon'; + +export const CopyUnfilledIcon = (props: CustomIconProps) => { + return ( + + + + ); +}; diff --git a/packages/frontend/src/components/shared/CustomIcon/TrashIcon.tsx b/packages/frontend/src/components/shared/CustomIcon/TrashIcon.tsx new file mode 100644 index 00000000..348e03c1 --- /dev/null +++ b/packages/frontend/src/components/shared/CustomIcon/TrashIcon.tsx @@ -0,0 +1,20 @@ +import { CustomIcon, CustomIconProps } from './CustomIcon'; + +export const TrashIcon: React.FC = (props) => { + return ( + + + + ); +}; diff --git a/packages/frontend/src/components/shared/CustomIcon/index.ts b/packages/frontend/src/components/shared/CustomIcon/index.ts index 02c372df..f271b978 100644 --- a/packages/frontend/src/components/shared/CustomIcon/index.ts +++ b/packages/frontend/src/components/shared/CustomIcon/index.ts @@ -67,6 +67,8 @@ export * from './AppleIcon'; export * from './CalendarDaysIcon'; export * from './GoogleIcon'; export * from './KeyIcon'; +export * from './TrashIcon'; +export * from './CopyUnfilledIcon'; // Templates export * from './templates'; diff --git a/packages/frontend/src/pages/org-slug/projects/id/settings/General.tsx b/packages/frontend/src/pages/org-slug/projects/id/settings/General.tsx index 6dd1b8f8..b6e31c9a 100644 --- a/packages/frontend/src/pages/org-slug/projects/id/settings/General.tsx +++ b/packages/frontend/src/pages/org-slug/projects/id/settings/General.tsx @@ -1,54 +1,35 @@ import { useState, useEffect, useCallback, useMemo } from 'react'; -import { Link, useOutletContext } from 'react-router-dom'; -import { useForm, Controller } from 'react-hook-form'; -import toast from 'react-hot-toast'; -import { Organization } from 'gql-client'; - -import { - Button, - Typography, - Input, - Option, -} from '@snowballtools/material-tailwind-react-fork'; +import { useOutletContext } from 'react-router-dom'; +import { useForm } from 'react-hook-form'; import DeleteProjectDialog from 'components/projects/project/settings/DeleteProjectDialog'; import { useGQLClient } from 'context/GQLClientContext'; -import AsyncSelect from 'components/shared/AsyncSelect'; -import { OutletContextType } from '../../../../../types/types'; +import { OutletContextType } from '../../../../../types'; import { TransferProjectDialog } from 'components/projects/Dialog/TransferProjectDialog'; - -const CopyIcon = ({ value }: { value: string }) => { - return ( - { - navigator.clipboard.writeText(value); - toast.success('Project ID copied'); - }} - className="cursor-pointer" - > - ^ - - ); -}; +import { Input } from 'components/shared/Input'; +import { Heading } from 'components/shared/Heading'; +import { Button } from 'components/shared/Button'; +import { Select, SelectOption } from 'components/shared/Select'; +import { TrashIcon, CopyUnfilledIcon } from 'components/shared/CustomIcon'; +import { useToast } from 'components/shared/Toast'; const GeneralTabPanel = () => { const client = useGQLClient(); + const { toast } = useToast(); const { project, onUpdate } = useOutletContext(); const [transferOrganizations, setTransferOrganizations] = useState< - Organization[] + SelectOption[] >([]); const [selectedTransferOrganization, setSelectedTransferOrganization] = - useState(''); + useState(); - const { - handleSubmit: handleTransfer, - control, - formState, - reset: transferFormReset, - } = useForm({ + const { handleSubmit: handleTransfer, reset: transferFormReset } = useForm({ defaultValues: { - orgId: '', + org: { + value: '', + label: '', + }, }, }); @@ -75,33 +56,47 @@ const GeneralTabPanel = () => { const orgsToTransfer = organizations.filter( (org) => org.id !== project.organization.id, ); - setTransferOrganizations(orgsToTransfer); + const selectableOrgs: SelectOption[] = orgsToTransfer.map((org) => ({ + value: org.id, + label: org.name, + })); + + setTransferOrganizations(selectableOrgs); }, [project]); const handleTransferProject = useCallback(async () => { const { updateProject: isTransferred } = await client.updateProject( project.id, { - organizationId: selectedTransferOrganization, + organizationId: selectedTransferOrganization?.value, }, ); setOpenTransferDialog(!openTransferDialog); if (isTransferred) { - toast.success('Project transferred'); + toast({ + id: 'project_transferred', + title: 'Project transferred successfully', + variant: 'success', + onDismiss() {}, + }); await fetchUserOrganizations(); await onUpdate(); transferFormReset(); } else { - toast.error('Project not transrfered'); + toast({ + id: 'project_transfer_failed', + title: 'Project transfer failed', + variant: 'error', + onDismiss() {}, + }); } }, [project, selectedTransferOrganization]); const selectedUserOrgName = useMemo(() => { return ( - transferOrganizations.find( - (org) => org.id === selectedTransferOrganization, - )?.name || '' + transferOrganizations.find((org) => org === selectedTransferOrganization) + ?.label || '' ); }, [transferOrganizations, selectedTransferOrganization]); @@ -114,7 +109,7 @@ const GeneralTabPanel = () => { }, [project]); return ( - <> +
{ const { updateProject } = await client.updateProject(project.id, { @@ -125,110 +120,100 @@ const GeneralTabPanel = () => { await onUpdate(); } })} + className="self-stretch space-y-3 px-2" > - Project info - - App name - + + Project Info + - - Description (Optional) - - - - Project ID - } + label="Description (Optional)" + {...register('description')} /> +
{ + navigator.clipboard.writeText(project.id); + toast({ + id: 'copied_project_id', + title: 'Project ID copied to clipboard', + variant: 'success', + onDismiss() {}, + }); + }} + > + } + /> +
-
- Transfer project - +
{ + setSelectedTransferOrganization(org.org); + setOpenTransferDialog(!openTransferDialog); + })} + className="self-stretch space-y-3 px-2" + > + + Transfer project + +

Transfer this app to your personal account or a team you are a member - of.{' '} - - Learn more - - - { - setSelectedTransferOrganization(orgId); - setOpenTransferDialog(!openTransferDialog); - })} - > - - Choose team - - ( - - {transferOrganizations.map((org, key) => ( - - ))} - - )} - /> - - - setOpenTransferDialog(!openTransferDialog)} - open={openTransferDialog} - handleConfirm={handleTransferProject} - projectName={project.name} - from={project.organization.name} - to={selectedUserOrgName} + of. +

+