Merge branch 'pass-lifetime-fixes' into 'main'
[ProtonMail-WebClient.git] / packages / components / containers / contacts / view / ContactView.tsx
blob516af96d47ad5dcd9b1c086eed1c8ff3c9e2cbc7
1 import { c } from 'ttag';
3 import { Button } from '@proton/atoms';
4 import type { CryptoProcessingError } from '@proton/shared/lib/contacts/decrypt';
5 import type { ContactEmail, ContactGroup } from '@proton/shared/lib/interfaces/contacts/Contact';
6 import type { VCardContact } from '@proton/shared/lib/interfaces/contacts/VCard';
8 import type { ContactEmailSettingsProps } from '../email/ContactEmailSettingsModal';
9 import type { ContactGroupEditProps } from '../group/ContactGroupEditModal';
10 import ContactSummary from './ContactSummary';
11 import ContactViewErrors from './ContactViewErrors';
12 import ContactViewAdrs from './properties/ContactViewAdrs';
13 import ContactViewBdy from './properties/ContactViewBdy';
14 import ContactViewEmails from './properties/ContactViewEmails';
15 import ContactViewFns from './properties/ContactViewFns';
16 import ContactViewNotes from './properties/ContactViewNotes';
17 import ContactViewOthers from './properties/ContactViewOthers';
18 import ContactViewTels from './properties/ContactViewTels';
20 import './ContactView.scss';
22 interface Props {
23     vCardContact: VCardContact;
24     contactID: string;
25     contactEmails: ContactEmail[];
26     contactGroupsMap: { [contactGroupID: string]: ContactGroup };
27     ownAddresses: string[];
28     errors?: (CryptoProcessingError | Error)[];
29     isSignatureVerified?: boolean;
30     onReload: () => void;
31     onEdit: (newField?: string) => void;
32     onEmailSettings: (props: ContactEmailSettingsProps) => void;
33     onGroupDetails: (contactGroupID: string) => void;
34     onGroupEdit: (props: ContactGroupEditProps) => void;
35     onUpgrade: () => void;
36     onSignatureError: (contactID: string) => void;
37     onDecryptionError: (contactID: string) => void;
38     isPreview?: boolean;
41 const ShortcutButton = ({ onClick, label }: { onClick: () => void; label: string }) => (
42     <div className="mb-2">
43         <Button shape="outline" size="small" onClick={onClick}>
44             {label}
45         </Button>
46     </div>
49 const ContactView = ({
50     vCardContact,
51     contactID,
52     contactEmails,
53     contactGroupsMap,
54     ownAddresses,
55     errors,
56     isSignatureVerified = false,
57     onReload,
58     onEdit,
59     onEmailSettings,
60     onGroupDetails,
61     onGroupEdit,
62     onUpgrade,
63     onSignatureError,
64     onDecryptionError,
65     isPreview = false,
66 }: Props) => {
67     const hasEmail = vCardContact.email?.length || 0 > 0;
68     const hasTel = vCardContact.tel?.length || 0 > 0;
69     const hasAdr = vCardContact.adr?.length || 0 > 0;
70     const hasNote = vCardContact.note?.length || 0 > 0;
71     const hasBday = Boolean(vCardContact.bday);
73     return (
74         <div>
75             <div className="contact-summary-wrapper border-bottom pb-4 mb-4">
76                 <ContactSummary
77                     vCardContact={vCardContact}
78                     leftBlockWidth="w-auto md:w-full max-w-custom"
79                     style={{ '--max-w-custom': '6.25rem' }}
80                 />
81                 <ContactViewErrors
82                     errors={errors}
83                     onReload={onReload}
84                     contactID={contactID}
85                     onSignatureError={onSignatureError}
86                     onDecryptionError={onDecryptionError}
87                     isPreview={isPreview}
88                 />
89             </div>
90             <div>
91                 <ContactViewFns vCardContact={vCardContact} isSignatureVerified={isSignatureVerified} />
92                 <ContactViewEmails
93                     vCardContact={vCardContact}
94                     isSignatureVerified={isSignatureVerified}
95                     isPreview={isPreview}
96                     contactEmails={contactEmails}
97                     contactGroupsMap={contactGroupsMap}
98                     ownAddresses={ownAddresses}
99                     contactID={contactID}
100                     onEmailSettings={onEmailSettings}
101                     onGroupDetails={onGroupDetails}
102                     onUpgrade={onUpgrade}
103                     onGroupEdit={onGroupEdit}
104                 />
105                 <ContactViewTels vCardContact={vCardContact} isSignatureVerified={isSignatureVerified} />
106                 <ContactViewAdrs vCardContact={vCardContact} isSignatureVerified={isSignatureVerified} />
107                 <ContactViewBdy vCardContact={vCardContact} isSignatureVerified={isSignatureVerified} />
108                 <ContactViewNotes vCardContact={vCardContact} isSignatureVerified={isSignatureVerified} />
109                 <ContactViewOthers vCardContact={vCardContact} isSignatureVerified={isSignatureVerified} />
110             </div>
111             {!isPreview ? (
112                 <div className="mt-6">
113                     {hasEmail ? null : (
114                         <ShortcutButton onClick={() => onEdit('email')} label={c('Action').t`Add email`} />
115                     )}
116                     {hasTel ? null : (
117                         <ShortcutButton onClick={() => onEdit('tel')} label={c('Action').t`Add phone number`} />
118                     )}
119                     {hasAdr ? null : (
120                         <ShortcutButton onClick={() => onEdit('adr')} label={c('Action').t`Add address`} />
121                     )}
122                     {hasBday ? null : (
123                         <ShortcutButton onClick={() => onEdit('bday')} label={c('Action').t`Add birthday`} />
124                     )}
125                     {hasNote ? null : <ShortcutButton onClick={() => onEdit('note')} label={c('Action').t`Add note`} />}
126                 </div>
127             ) : null}
128         </div>
129     );
132 export default ContactView;