Merge branch 'feat/inda-383-daily-stat' into 'main'
[ProtonMail-WebClient.git] / applications / drive / src / app / components / modals / CreateFolderModal.tsx
blob80f811a344c7fa9445abac82d513fd09c752127d
1 import type { ChangeEvent, FocusEvent } from 'react';
2 import React, { useState } from 'react';
4 import { c } from 'ttag';
6 import { Button } from '@proton/atoms';
7 import type { ModalStateProps } from '@proton/components';
8 import {
9     InputFieldTwo,
10     ModalTwo,
11     ModalTwoContent,
12     ModalTwoFooter,
13     ModalTwoHeader,
14     PrimaryButton,
15     useFormErrors,
16     useModalTwoStatic,
17 } from '@proton/components';
18 import { useLoading } from '@proton/hooks';
19 import noop from '@proton/utils/noop';
21 import { formatLinkName, validateLinkNameField } from '../../store';
23 interface Props {
24     onClose?: () => void;
25     onCreateDone?: (folderId: string) => void;
26     folder: { shareId: string; linkId: string };
27     createFolder: (abortSignal: AbortSignal, shareId: string, parentLinkId: string, name: string) => Promise<string>;
30 const CreateFolderModal = ({ createFolder, onClose, folder, onCreateDone, ...modalProps }: Props & ModalStateProps) => {
31     const [folderName, setFolderName] = useState('');
32     const [loading, withLoading] = useLoading();
33     const { validator, onFormSubmit } = useFormErrors();
35     const handleBlur = ({ target }: FocusEvent<HTMLInputElement>) => {
36         setFolderName(formatLinkName(target.value));
37     };
39     const handleChange = ({ target }: ChangeEvent<HTMLInputElement>) => {
40         setFolderName(target.value);
41     };
43     const handleSubmit = async (e: React.FormEvent) => {
44         e.preventDefault();
46         if (!onFormSubmit()) {
47             return;
48         }
50         const formattedName = formatLinkName(folderName);
51         setFolderName(formattedName);
53         const parentFolder = folder;
54         if (!parentFolder) {
55             return;
56         }
58         const folderId = await createFolder(
59             new AbortController().signal,
60             parentFolder.shareId,
61             parentFolder.linkId,
62             formattedName
63         );
64         onCreateDone?.(folderId);
65         onClose?.();
66     };
68     return (
69         <ModalTwo
70             as="form"
71             disableCloseOnEscape={loading}
72             onClose={onClose}
73             onSubmit={(e: React.FormEvent) => withLoading(handleSubmit(e)).catch(noop)}
74             size="large"
75             {...modalProps}
76         >
77             <ModalTwoHeader closeButtonProps={{ disabled: loading }} title={c('Title').t`Create a new folder`} />
78             <ModalTwoContent>
79                 <InputFieldTwo
80                     id="folder-name"
81                     autoFocus
82                     value={folderName}
83                     label={c('Label').t`Folder name`}
84                     placeholder={c('Placeholder').t`Enter a new folder name`}
85                     onChange={handleChange}
86                     onBlur={handleBlur}
87                     error={validator([validateLinkNameField(folderName) || ''])}
88                     data-testid="input-new-folder-name"
89                     required
90                 />
91             </ModalTwoContent>
92             <ModalTwoFooter>
93                 <Button type="button" onClick={onClose} disabled={loading}>
94                     {c('Action').t`Cancel`}
95                 </Button>
96                 <PrimaryButton type="submit" loading={loading}>
97                     {c('Action').t`Create`}
98                 </PrimaryButton>
99             </ModalTwoFooter>
100         </ModalTwo>
101     );
104 export default CreateFolderModal;
105 export const useCreateFolderModal = () => {
106     return useModalTwoStatic(CreateFolderModal);