Remove payments API routing initialization
[ProtonMail-WebClient.git] / packages / components / containers / addresses / EditAddressesSection.tsx
blob7b8cba26cedfecaa9d9e6f79ef895fb35d2bcaab
1 import type { ChangeEvent } from 'react';
2 import { useEffect, useRef, useState } from 'react';
4 import { c } from 'ttag';
6 import { Button, Input } from '@proton/atoms';
7 import Editor from '@proton/components/components/editor/Editor';
8 import { useToolbar } from '@proton/components/components/editor/hooks/useToolbar';
9 import type { EditorActions } from '@proton/components/components/editor/interface';
10 import Info from '@proton/components/components/link/Info';
11 import useActiveBreakpoint from '@proton/components/hooks/useActiveBreakpoint';
12 import useApi from '@proton/components/hooks/useApi';
13 import useEventManager from '@proton/components/hooks/useEventManager';
14 import useNotifications from '@proton/components/hooks/useNotifications';
15 import { useLoading } from '@proton/hooks';
16 import { useMailSettings } from '@proton/mail/mailSettings/hooks';
17 import { updateAddress } from '@proton/shared/lib/api/addresses';
18 import { getKnowledgeBaseUrl } from '@proton/shared/lib/helpers/url';
19 import type { Address } from '@proton/shared/lib/interfaces';
20 import { DEFAULT_MAILSETTINGS } from '@proton/shared/lib/mail/mailSettings';
22 import { useHotkeys } from '../../hooks/useHotkeys';
23 import SettingsLayout from '../account/SettingsLayout';
24 import SettingsLayoutLeft from '../account/SettingsLayoutLeft';
25 import SettingsLayoutRight from '../account/SettingsLayoutRight';
27 const EMPTY_VALUES = [/^(<div><br><\/div>)+$/, /^(<div>\s*<\/div>)+$/];
29 const formatSignature = (value: string) => (EMPTY_VALUES.some((regex) => regex.test(value)) ? '' : value);
31 interface Props {
32     address: Address;
35 const EditAddressesSection = ({ address }: Props) => {
36     const [mailSettings = DEFAULT_MAILSETTINGS] = useMailSettings();
37     const api = useApi();
38     const { call } = useEventManager();
39     const [loading, withLoading] = useLoading();
40     const [editorReady, setEditorReady] = useState(false);
41     const [displayName, setDisplayName] = useState(address.DisplayName);
42     const [signatureUpdated, setSignatureUpdated] = useState(false);
43     const { createNotification } = useNotifications();
44     const { viewportWidth } = useActiveBreakpoint();
46     const editorWrapperRef = useRef<HTMLDivElement>(null);
47     const editorRef = useRef<EditorActions>();
49     const handleReady = (actions: EditorActions) => {
50         actions.setContent(address.Signature);
51         editorRef.current = actions;
52         setEditorReady(true);
53     };
55     const handleDisplayName = ({ target }: ChangeEvent<HTMLInputElement>) => {
56         setDisplayName(target.value);
57     };
59     const handleSubmit = async () => {
60         const signature = signatureUpdated ? (editorRef.current?.getContent() as string) : address.Signature;
62         await api(
63             updateAddress(address.ID, {
64                 DisplayName: displayName,
65                 Signature: formatSignature(signature),
66             })
67         );
68         await call();
69         createNotification({ text: c('Success').t`Address updated` });
70     };
72     useHotkeys(editorWrapperRef, [
73         [
74             ['Meta', 'Enter'],
75             () => {
76                 if (mailSettings.Shortcuts) {
77                     void withLoading(handleSubmit());
78                 }
79             },
80         ],
81     ]);
83     // On address change
84     useEffect(() => {
85         setDisplayName(address.DisplayName);
86         setTimeout(() => {
87             if (editorRef?.current && editorReady) {
88                 setSignatureUpdated(false);
89                 editorRef.current.setContent(address.Signature);
90             }
91         }, 100);
92     }, [address]);
94     const { openEmojiPickerRef, toolbarConfig, setToolbarConfig, modalLink, modalImage, modalDefaultFont } = useToolbar(
95         {}
96     );
98     return (
99         <form
100             onSubmit={async (e) => {
101                 e.preventDefault();
102                 await withLoading(handleSubmit());
103             }}
104         >
105             <SettingsLayout>
106                 <SettingsLayoutLeft>
107                     <label htmlFor="displayName" className="text-semibold">
108                         {c('Label').t`Display name`}
109                     </label>
110                 </SettingsLayoutLeft>
111                 <SettingsLayoutRight>
112                     <Input
113                         id="displayName"
114                         value={displayName}
115                         placeholder={c('Placeholder').t`Choose display name`}
116                         onChange={handleDisplayName}
117                         data-testid="settings:identity-section:display-name"
118                     />
119                 </SettingsLayoutRight>
120             </SettingsLayout>
122             <SettingsLayout stackEarlier className="max-w-custom" style={{ '--max-w-custom': '49em' }}>
123                 <SettingsLayoutLeft>
124                     {/* eslint-disable-next-line */}
125                     <label htmlFor="editor" className="text-semibold" onClick={() => editorRef.current?.focus()}>
126                         <span className="mr-2">{c('Label').t`Signature`}</span>
127                         <Info
128                             url={getKnowledgeBaseUrl('/display-name-email-signature')}
129                             title={c('Tooltip').t`Click here to learn how to create a customized signature with HTML.`}
130                         />
131                     </label>
132                 </SettingsLayoutLeft>
133                 <SettingsLayoutRight>
134                     <div ref={editorWrapperRef} tabIndex={-1}>
135                         <Editor
136                             onReady={handleReady}
137                             onChange={() => {
138                                 setSignatureUpdated(true);
139                             }}
140                             simple
141                             openEmojiPickerRef={openEmojiPickerRef}
142                             toolbarConfig={toolbarConfig}
143                             setToolbarConfig={setToolbarConfig}
144                             modalLink={modalLink}
145                             modalImage={modalImage}
146                             modalDefaultFont={modalDefaultFont}
147                             isSmallViewportForToolbar={viewportWidth['<=medium']}
148                             mailSettings={mailSettings}
149                         />
150                     </div>
152                     <Button
153                         color="norm"
154                         type="submit"
155                         disabled={loading}
156                         loading={loading}
157                         className="mt-4"
158                         data-testid="settings:identity-section:update"
159                     >
160                         {c('Action').t`Update`}
161                     </Button>
162                 </SettingsLayoutRight>
163             </SettingsLayout>
164         </form>
165     );
168 export default EditAddressesSection;