Cleanup - unused files / unused exports / duplicate exports
[ProtonMail-WebClient.git] / packages / components / containers / smtp / SMTPTokenModal.tsx
blob95ce249ec3e4b89e1e2ccc9de1ee253124541a3d
1 import { useState } from 'react';
3 import { c } from 'ttag';
5 import { Button, Href } from '@proton/atoms';
6 import Copy from '@proton/components/components/button/Copy';
7 import PrimaryButton from '@proton/components/components/button/PrimaryButton';
8 import Form from '@proton/components/components/form/Form';
9 import type { ModalProps } from '@proton/components/components/modalTwo/Modal';
10 import ModalTwo from '@proton/components/components/modalTwo/Modal';
11 import ModalTwoContent from '@proton/components/components/modalTwo/ModalContent';
12 import ModalTwoFooter from '@proton/components/components/modalTwo/ModalFooter';
13 import ModalTwoHeader from '@proton/components/components/modalTwo/ModalHeader';
14 import Option from '@proton/components/components/option/Option';
15 import SelectTwo from '@proton/components/components/selectTwo/SelectTwo';
16 import InputFieldTwo from '@proton/components/components/v2/field/InputField';
17 import useFormErrors from '@proton/components/components/v2/useFormErrors';
18 import useApi from '@proton/components/hooks/useApi';
19 import useNotifications from '@proton/components/hooks/useNotifications';
20 import { useLoading } from '@proton/hooks';
21 import { createToken } from '@proton/shared/lib/api/smtptokens';
22 import { ADDRESS_TYPE } from '@proton/shared/lib/constants';
23 import { maxLengthValidator, requiredValidator } from '@proton/shared/lib/helpers/formValidators';
24 import { getKnowledgeBaseUrl } from '@proton/shared/lib/helpers/url';
25 import type { Address } from '@proton/shared/lib/interfaces';
26 import noop from '@proton/utils/noop';
28 import './SMTPTokenModal.scss';
30 const Steps = {
31     TokenForm: 0,
32     TokenValue: 1,
35 const SMTP_SERVER = 'smtp.protonmail.ch';
36 const SMTP_PORT = '587';
38 interface Props extends ModalProps {
39     addresses: Address[];
40     onCreate: () => void; // fetch new tokens
43 const SMTPTokenModal = ({ addresses, onCreate, ...rest }: Props) => {
44     const { onClose } = rest;
45     const { validator, onFormSubmit } = useFormErrors();
46     const [step, setStep] = useState(Steps.TokenForm);
47     const [loading, withLoading] = useLoading();
48     const { createNotification } = useNotifications();
49     const [tokenName, setTokenName] = useState('');
50     const [token, setToken] = useState('');
51     // This modal can be open only if it has at least one custom address
52     const customAddresses = addresses.filter(({ Type }) => Type === ADDRESS_TYPE.TYPE_CUSTOM_DOMAIN);
53     const [addressID, setAddressID] = useState(customAddresses[0].ID);
54     const api = useApi();
55     const title = step === Steps.TokenForm ? c('Title').t`Generate SMTP token` : c('Title').t`Your SMTP token`;
56     const emailAddress = addresses.find(({ ID }) => ID === addressID)?.Email || '';
58     const handleClose = loading ? noop : onClose;
60     const handleSubmit = async () => {
61         if (step === Steps.TokenForm) {
62             if (loading || !onFormSubmit()) {
63                 return;
64             }
65             const { SmtpTokenCode } = await api(createToken(addressID, tokenName));
66             setToken(SmtpTokenCode);
67             setStep(Steps.TokenValue);
68             onCreate();
69         }
70     };
72     const handleCopyEmail = () => {
73         createNotification({ type: 'success', text: c('Success').t`Email address copied to clipboard` });
74     };
76     const handleCopyToken = () => {
77         createNotification({ type: 'success', text: c('Success').t`Token copied to clipboard` });
78     };
80     const handleCopyServer = () => {
81         createNotification({ type: 'success', text: c('Success').t`Server copied to clipboard` });
82     };
84     const handleCopyPort = () => {
85         createNotification({ type: 'success', text: c('Success').t`Port copied to clipboard` });
86     };
88     const content = () => {
89         if (step === Steps.TokenForm) {
90             return (
91                 <>
92                     <p>{c('Info')
93                         .t`Give the token a descriptive name, such as the service you plan to use it with, and select one of your active custom domain addresses. Only this address will be able to send emails with this token.`}</p>
94                     <InputFieldTwo
95                         label={c('Label').t`Token name`}
96                         id="token-name"
97                         autoFocus
98                         maxLength={100}
99                         error={validator([requiredValidator(tokenName), maxLengthValidator(tokenName, 100)])}
100                         placeholder={c('Placeholder').t`Printer`}
101                         value={tokenName}
102                         onValue={(value: string) => setTokenName(value)}
103                         disabled={loading}
104                         required
105                     />
106                     <InputFieldTwo
107                         as={SelectTwo}
108                         id="token-address"
109                         label={c('Label').t`Email address`}
110                         value={addressID}
111                         onValue={(value: unknown) => setAddressID(value as string)}
112                         disabled={loading}
113                     >
114                         {customAddresses.map(({ ID, Email }) => (
115                             <Option key={ID} value={ID} title={Email} />
116                         ))}
117                     </InputFieldTwo>
118                 </>
119             );
120         }
121         return (
122             <>
123                 <p>
124                     {c('Info')
125                         .t`Use the selected email address as the SMTP username in the external service, and the generated token as the SMTP password.`}
126                     <br />
127                     <Href href={getKnowledgeBaseUrl('/smtp-submission')}>{c('Link').t`Learn more`}</Href>
128                 </p>
129                 <div className="flex items-center flex-nowrap mb-4">
130                     <InputFieldTwo
131                         id="smtp-username"
132                         label={c('Label').t`SMTP username`}
133                         readOnly
134                         value={emailAddress}
135                         inputClassName="bg-weak"
136                     />
137                     <Copy
138                         color="norm"
139                         shape="solid"
140                         value={emailAddress}
141                         className="smtp-token-copy relative shrink-0 ml-2"
142                         onCopy={handleCopyEmail}
143                     />
144                 </div>
145                 <div className="flex items-center flex-nowrap mb-4">
146                     <InputFieldTwo
147                         id="smtp-token"
148                         label={c('Label').t`SMTP token`}
149                         readOnly
150                         value={token}
151                         inputClassName="bg-weak"
152                     />
153                     <Copy
154                         color="norm"
155                         shape="solid"
156                         value={token}
157                         className="smtp-token-copy relative shrink-0 ml-2"
158                         onCopy={handleCopyToken}
159                     />
160                 </div>
161                 <p className="color-danger">{c('Info')
162                     .t`This token won’t be available after you close this window, and you should not share it with anyone.`}</p>
163                 <div className="flex items-center flex-nowrap mb-4">
164                     <InputFieldTwo
165                         id="server"
166                         label={c('Label').t`SMTP server`}
167                         readOnly
168                         value={SMTP_SERVER}
169                         inputClassName="bg-weak"
170                     />
171                     <Copy
172                         color="norm"
173                         shape="solid"
174                         value={SMTP_SERVER}
175                         className="smtp-token-copy relative shrink-0 ml-2"
176                         onCopy={handleCopyServer}
177                     />
178                 </div>
179                 <div className="flex items-center flex-nowrap mb-4">
180                     <InputFieldTwo
181                         id="port"
182                         label={c('Label').t`SMTP port`}
183                         readOnly
184                         value={SMTP_PORT}
185                         inputClassName="bg-weak"
186                     />
187                     <Copy
188                         color="norm"
189                         shape="solid"
190                         value={SMTP_PORT}
191                         className="smtp-token-copy relative shrink-0 ml-2"
192                         onCopy={handleCopyPort}
193                     />
194                 </div>
195                 <p>{c('Info').t`Enable TLS or SSL on the external service if it is supported.`}</p>
196             </>
197         );
198     };
200     const footer = () => {
201         if (step === Steps.TokenForm) {
202             return (
203                 <>
204                     <Button onClick={handleClose}>{c('Action').t`Cancel`}</Button>
205                     <PrimaryButton type="submit" loading={loading}>
206                         {c('Action').t`Generate`}
207                     </PrimaryButton>
208                 </>
209             );
210         }
211         return (
212             <>
213                 <Button shape="outline" color="norm" className="ml-auto" onClick={handleClose}>{c('Action')
214                     .t`Close`}</Button>
215             </>
216         );
217     };
219     return (
220         <ModalTwo as={Form} onSubmit={() => withLoading(handleSubmit())} onClose={handleClose} {...rest}>
221             <ModalTwoHeader closeButtonProps={{ disabled: loading }} title={title} />
222             <ModalTwoContent>{content()}</ModalTwoContent>
223             <ModalTwoFooter>{footer()}</ModalTwoFooter>
224         </ModalTwo>
225     );
228 export default SMTPTokenModal;