richie-education 3.2.1 → 3.2.2-dev27

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (78) hide show
  1. package/js/api/joanie.ts +144 -0
  2. package/js/components/PaymentInterfaces/types.ts +7 -0
  3. package/js/components/PaymentScheduleGrid/index.tsx +4 -2
  4. package/js/components/SaleTunnel/AddressSelector/index.spec.tsx +9 -2
  5. package/js/components/SaleTunnel/GenericSaleTunnel.tsx +33 -0
  6. package/js/components/SaleTunnel/SaleTunnelInformation/SaleTunnelInformationGroup.tsx +253 -0
  7. package/js/components/SaleTunnel/SaleTunnelInformation/SaleTunnelInformationSingular.tsx +314 -0
  8. package/js/components/SaleTunnel/SaleTunnelInformation/StepContent.tsx +528 -0
  9. package/js/components/SaleTunnel/SaleTunnelInformation/index.tsx +47 -271
  10. package/js/components/SaleTunnel/SaleTunnelSuccess/index.tsx +25 -11
  11. package/js/components/SaleTunnel/SubscriptionButton/index.tsx +54 -6
  12. package/js/components/SaleTunnel/_styles.scss +55 -0
  13. package/js/components/SaleTunnel/index.full-process-b2b.spec.tsx +356 -0
  14. package/js/components/SaleTunnel/{index.full-process.spec.tsx → index.full-process-b2c.spec.tsx} +4 -1
  15. package/js/components/SaleTunnel/index.spec.tsx +104 -0
  16. package/js/hooks/useBatchOrder/index.tsx +36 -0
  17. package/js/hooks/useContractArchive/index.ts +2 -0
  18. package/js/hooks/useOfferingOrganizations/index.tsx +38 -0
  19. package/js/hooks/useOrganizationAgreements.tsx/index.tsx +66 -0
  20. package/js/hooks/useOrganizationQuotes/index.tsx +56 -0
  21. package/js/hooks/useTeacherPendingAgreementsCount/index.ts +34 -0
  22. package/js/pages/DashboardBatchOrderLayout/_styles.scss +5 -0
  23. package/js/pages/DashboardBatchOrderLayout/index.spec.tsx +78 -0
  24. package/js/pages/DashboardBatchOrderLayout/index.tsx +45 -0
  25. package/js/pages/DashboardBatchOrders/index.spec.tsx +237 -0
  26. package/js/pages/DashboardBatchOrders/index.tsx +84 -0
  27. package/js/pages/TeacherDashboardContractsLayout/TeacherDashboardCourseContractsLayout/index.tsx +0 -1
  28. package/js/pages/TeacherDashboardContractsLayout/hooks/useDownloadContractArchive/index.tsx +3 -1
  29. package/js/pages/TeacherDashboardOrganizationAgreements/AgreementActionsBar.tsx +49 -0
  30. package/js/pages/TeacherDashboardOrganizationAgreements/BulkAgreementContractButton.tsx +79 -0
  31. package/js/pages/TeacherDashboardOrganizationAgreements/OrganizationAgreementFrame.tsx +71 -0
  32. package/js/pages/TeacherDashboardOrganizationAgreements/SignOrganizationAgreementButton.tsx +60 -0
  33. package/js/pages/TeacherDashboardOrganizationAgreements/hooks/useAgreementsAbilities.tsx +8 -0
  34. package/js/pages/TeacherDashboardOrganizationAgreements/hooks/useHasAgreementToDownload.tsx +27 -0
  35. package/js/pages/TeacherDashboardOrganizationAgreements/hooks/useTeacherAgreementsToSign.tsx +32 -0
  36. package/js/pages/TeacherDashboardOrganizationAgreements/index.spec.tsx +433 -0
  37. package/js/pages/TeacherDashboardOrganizationAgreements/index.tsx +130 -0
  38. package/js/pages/TeacherDashboardOrganizationAgreementsLayout/index.tsx +25 -0
  39. package/js/pages/TeacherDashboardOrganizationCourseLoader/index.spec.tsx +9 -0
  40. package/js/pages/TeacherDashboardOrganizationQuotes/_styles.scss +40 -0
  41. package/js/pages/TeacherDashboardOrganizationQuotes/index.full-process.spec.tsx +194 -0
  42. package/js/pages/TeacherDashboardOrganizationQuotes/index.spec.tsx +144 -0
  43. package/js/pages/TeacherDashboardOrganizationQuotes/index.tsx +521 -0
  44. package/js/pages/TeacherDashboardOrganizationQuotesLayout/index.tsx +26 -0
  45. package/js/types/Joanie.ts +216 -1
  46. package/js/utils/AbilitiesHelper/agreementAbilities.ts +14 -0
  47. package/js/utils/AbilitiesHelper/index.ts +7 -0
  48. package/js/utils/AbilitiesHelper/types.ts +12 -3
  49. package/js/utils/ObjectHelper/index.ts +20 -0
  50. package/js/utils/OrderHelper/index.ts +10 -0
  51. package/js/utils/test/factories/joanie.ts +156 -1
  52. package/js/widgets/Dashboard/components/DashboardBatchOrderLoader/_styles.scss +14 -0
  53. package/js/widgets/Dashboard/components/DashboardBatchOrderLoader/index.tsx +32 -0
  54. package/js/widgets/Dashboard/components/DashboardCard/index.spec.tsx +18 -0
  55. package/js/widgets/Dashboard/components/DashboardCard/index.stories.tsx +25 -2
  56. package/js/widgets/Dashboard/components/DashboardCard/index.tsx +4 -2
  57. package/js/widgets/Dashboard/components/DashboardItem/BatchOrder/BatchOrderPaymentModal/BatchOrderPaymentManager.tsx +88 -0
  58. package/js/widgets/Dashboard/components/DashboardItem/BatchOrder/BatchOrderPaymentModal/index.tsx +216 -0
  59. package/js/widgets/Dashboard/components/DashboardItem/BatchOrder/DashboardBatchOrderSubItems.tsx +316 -0
  60. package/js/widgets/Dashboard/components/DashboardItem/BatchOrder/index.spec.tsx +27 -0
  61. package/js/widgets/Dashboard/components/DashboardItem/BatchOrder/index.tsx +175 -0
  62. package/js/widgets/Dashboard/components/DashboardItem/Order/DashboardItemOrder.tsx +5 -2
  63. package/js/widgets/Dashboard/components/DashboardItem/Order/OrganizationBlock/index.tsx +4 -1
  64. package/js/widgets/Dashboard/components/DashboardItem/Order/_styles.scss +5 -0
  65. package/js/widgets/Dashboard/components/DashboardItem/_styles.scss +43 -0
  66. package/js/widgets/Dashboard/components/DashboardSidebar/components/AgreementNavLink/index.spec.tsx +214 -0
  67. package/js/widgets/Dashboard/components/DashboardSidebar/components/AgreementNavLink/index.tsx +47 -0
  68. package/js/widgets/Dashboard/components/LearnerDashboardSidebar/index.tsx +1 -0
  69. package/js/widgets/Dashboard/components/TeacherDashboardOrganizationSidebar/index.spec.tsx +21 -3
  70. package/js/widgets/Dashboard/components/TeacherDashboardOrganizationSidebar/index.tsx +9 -0
  71. package/js/widgets/Dashboard/utils/learnerRoutes.tsx +30 -0
  72. package/js/widgets/Dashboard/utils/learnerRoutesPaths.tsx +12 -0
  73. package/js/widgets/Dashboard/utils/teacherDashboardPaths.tsx +12 -0
  74. package/js/widgets/Dashboard/utils/teacherRoutes.tsx +17 -0
  75. package/js/widgets/SyllabusCourseRunsList/components/CourseProductItem/index.spec.tsx +8 -2
  76. package/package.json +4 -1
  77. package/scss/colors/_theme.scss +1 -1
  78. package/scss/components/_index.scss +1 -0
@@ -1,6 +1,5 @@
1
1
  import { Meta, StoryObj } from '@storybook/react';
2
2
  import { Button } from '@openfun/cunningham-react';
3
- import Input from 'components/Form/Input';
4
3
  import { DashboardBox } from '../DashboardBox';
5
4
  import { DashboardCard } from './index';
6
5
 
@@ -18,7 +17,15 @@ type Story = StoryObj<typeof DashboardCard>;
18
17
  export const Default: Story = {
19
18
  args: {
20
19
  header: 'Billing Addresses',
21
- children: <Input name="default" label="Country" />,
20
+ children: (
21
+ <div>
22
+ <div>
23
+ <div>Home</div>
24
+ <strong>Pierre Léger</strong>
25
+ <p>21 rue du pavillon - 78130 Chapter ( France )</p>
26
+ </div>
27
+ </div>
28
+ ),
22
29
  footer: <Button color="primary">Update</Button>,
23
30
  },
24
31
  };
@@ -47,3 +54,19 @@ export const WithBoxes: Story = {
47
54
  ),
48
55
  },
49
56
  };
57
+
58
+ export const NotExpanded: Story = {
59
+ args: {
60
+ header: 'Not expanded',
61
+ defaultExpanded: false,
62
+ children: (
63
+ <div>
64
+ <div>
65
+ <div>Home</div>
66
+ <strong>Pierre Léger</strong>
67
+ <p>21 rue du pavillon - 78130 Chapter ( France )</p>
68
+ </div>
69
+ </div>
70
+ ),
71
+ },
72
+ };
@@ -9,6 +9,7 @@ interface Props {
9
9
  expandable?: boolean;
10
10
  fullWidth?: boolean;
11
11
  className?: string;
12
+ defaultExpanded?: boolean;
12
13
  }
13
14
 
14
15
  export const DashboardCard = ({
@@ -18,10 +19,11 @@ export const DashboardCard = ({
18
19
  className,
19
20
  expandable = true,
20
21
  fullWidth = false,
22
+ defaultExpanded = true,
21
23
  }: PropsWithChildren<Props>) => {
22
- const [opened, setOpened] = useState(true);
24
+ const [opened, setOpened] = useState(defaultExpanded);
23
25
  const expandableRef = useRef<HTMLDivElement>(null);
24
- const [wrapperHeight, setWrapperHeight] = useState('auto');
26
+ const [wrapperHeight, setWrapperHeight] = useState(defaultExpanded ? 'auto' : '0');
25
27
 
26
28
  const toggle = () => {
27
29
  if (opened) {
@@ -0,0 +1,88 @@
1
+ import React, { useEffect } from 'react';
2
+ import { Button, useModal } from '@openfun/cunningham-react';
3
+ import { useIntl, FormattedMessage, defineMessages } from 'react-intl';
4
+ import { useBatchOrder } from 'hooks/useBatchOrder';
5
+ import { BatchOrderRead, BatchOrderState } from 'types/Joanie';
6
+ import { DashboardSubItem } from 'widgets/Dashboard/components/DashboardItem/DashboardSubItem';
7
+ import { DashboardSubItemsList } from '../../DashboardSubItemsList';
8
+ import { BatchOrderPaymentModal } from '.';
9
+
10
+ const messages = defineMessages({
11
+ batchOrderPayment: {
12
+ id: 'components.ProductCertificateFooter.batchOrderPayment',
13
+ description: 'Label before the payment button',
14
+ defaultMessage: 'We are waiting for your payment to finalize the batch order.',
15
+ },
16
+ paymentProcessing: {
17
+ id: 'components.ProductCertificateFooter.paymentProcessing',
18
+ description: 'Button label for the payment is processing message',
19
+ defaultMessage: 'Payment processing...',
20
+ },
21
+ paymentNeededButton: {
22
+ id: 'components.ProductCertificateFooter.paymentNeededButton',
23
+ description: 'Button label for the payment needed message',
24
+ defaultMessage: 'Pay {amount}',
25
+ },
26
+ paymentSectionTitle: {
27
+ id: 'batchOrder.payment.sectionTitle',
28
+ description: 'Title for the payment section in dashboard',
29
+ defaultMessage: 'Payment required',
30
+ },
31
+ });
32
+
33
+ interface BatchPaymentManagerProps {
34
+ batchOrder: BatchOrderRead;
35
+ }
36
+
37
+ export const BatchOrderPaymentManager = ({ batchOrder }: BatchPaymentManagerProps) => {
38
+ const intl = useIntl();
39
+ const retryModal = useModal();
40
+ const batchOrderQuery = useBatchOrder(batchOrder.id);
41
+ const processingPayment = batchOrder.state === BatchOrderState.PROCESS_PAYMENT;
42
+
43
+ useEffect(() => {
44
+ if (batchOrderQuery.item) {
45
+ batchOrderQuery.methods.invalidate();
46
+ }
47
+ }, [batchOrderQuery.item]);
48
+
49
+ return (
50
+ <DashboardSubItemsList
51
+ subItems={[
52
+ <DashboardSubItem
53
+ title={intl.formatMessage(messages.paymentSectionTitle)}
54
+ footer={
55
+ <div className="content">
56
+ <FormattedMessage {...messages.batchOrderPayment} />
57
+ <Button
58
+ size="small"
59
+ color="primary"
60
+ onClick={retryModal.open}
61
+ disabled={processingPayment}
62
+ >
63
+ {processingPayment ? (
64
+ <FormattedMessage {...messages.paymentProcessing} />
65
+ ) : (
66
+ <FormattedMessage
67
+ {...messages.paymentNeededButton}
68
+ values={{
69
+ amount: intl.formatNumber(batchOrder.total ?? 0, {
70
+ style: 'currency',
71
+ currency: batchOrder.currency ?? 'EUR',
72
+ }),
73
+ }}
74
+ />
75
+ )}
76
+ </Button>
77
+ <BatchOrderPaymentModal
78
+ {...retryModal}
79
+ batchOrder={batchOrder}
80
+ onClose={batchOrderQuery.methods.invalidate}
81
+ />
82
+ </div>
83
+ }
84
+ />,
85
+ ]}
86
+ />
87
+ );
88
+ };
@@ -0,0 +1,216 @@
1
+ import {
2
+ Alert,
3
+ Button,
4
+ Modal,
5
+ ModalProps,
6
+ ModalSize,
7
+ useModals,
8
+ VariantType,
9
+ } from '@openfun/cunningham-react';
10
+ import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
11
+ import { useRef, useState } from 'react';
12
+ import { BatchOrderRead, BatchOrderState } from 'types/Joanie';
13
+ import { useJoanieApi } from 'contexts/JoanieApiContext';
14
+ import { Payment, PaymentErrorMessageId } from 'components/PaymentInterfaces/types';
15
+ import PaymentInterface from 'components/PaymentInterfaces';
16
+ import { PAYMENT_SETTINGS } from 'settings';
17
+ import { Spinner } from 'components/Spinner';
18
+ import { useBatchOrders, useBatchOrdersActions } from 'hooks/useBatchOrder';
19
+
20
+ const messages = defineMessages({
21
+ title: {
22
+ id: 'components.DashboardItemBatchOrder.BatchOrderPaymentModal.title',
23
+ defaultMessage: 'Batch order payment',
24
+ description: 'Title of the modal prompting the user to complete a batch order payment.',
25
+ },
26
+ description: {
27
+ id: 'components.DashboardItemBatchOrder.BatchOrderPaymentModal.description',
28
+ defaultMessage:
29
+ 'Since you selected payment by credit card, please finalize your batch order to complete the process.',
30
+ description:
31
+ 'Informational message displayed when the user needs to complete the batch order payment.',
32
+ },
33
+ submit: {
34
+ id: 'components.DashboardItemBatchOrder.BatchOrderPaymentModal.submit',
35
+ defaultMessage: 'Pay {amount}',
36
+ description: 'Label of the button used to start the batch order payment.',
37
+ },
38
+ paymentInProgress: {
39
+ id: 'components.DashboardItemBatchOrder.BatchOrderPaymentModal.paymentInProgress',
40
+ defaultMessage: 'Payment in progress',
41
+ description: 'Label displayed when the payment process is currently ongoing.',
42
+ },
43
+ paymentError: {
44
+ id: 'components.DashboardItemBatchOrder.BatchOrderPaymentModal.paymentError',
45
+ defaultMessage: 'An error occurred during the payment process.',
46
+ description: 'Error message displayed when the payment fails.',
47
+ },
48
+ successTitle: {
49
+ id: 'components.DashboardItemBatchOrder.BatchOrderPaymentModal.successTitle',
50
+ defaultMessage: 'Payment successful',
51
+ description: 'Title of the modal displayed when the payment completes successfully.',
52
+ },
53
+ successDescription: {
54
+ id: 'components.DashboardItemBatchOrder.BatchOrderPaymentModal.successDescription',
55
+ defaultMessage: 'Your payment has been processed successfully.',
56
+ description: 'Description displayed in the success modal after a successful payment.',
57
+ },
58
+ abortError: {
59
+ id: 'components.DashboardItemBatchOrder.BatchOrderPaymentModal.abortError',
60
+ defaultMessage: 'Your payment was aborted during the process. Please try again.',
61
+ description:
62
+ 'Error message displayed when the payment process is aborted by the user or system.',
63
+ },
64
+ errorAbortingPolling: {
65
+ id: 'components.DashboardItemBatchOrder.BatchOrderPaymentModal.errorAbortingPolling',
66
+ defaultMessage:
67
+ 'Your payment was successful, but order validation is taking longer than expected. You can close this dialog and check your order later.',
68
+ description:
69
+ 'Message displayed when the payment succeeded but the order validation polling timed out.',
70
+ },
71
+ });
72
+
73
+ interface Props extends Pick<ModalProps, 'isOpen' | 'onClose'> {
74
+ batchOrder: BatchOrderRead;
75
+ }
76
+
77
+ enum ComponentStates {
78
+ IDLE = 'idle',
79
+ LOADING = 'loading',
80
+ ERROR = 'error',
81
+ }
82
+
83
+ export const BatchOrderPaymentModal = ({ batchOrder, ...props }: Props) => {
84
+ const intl = useIntl();
85
+ const API = useJoanieApi();
86
+ const timeoutRef = useRef<NodeJS.Timeout>(undefined);
87
+ const { methods: batchOrderMethods } = useBatchOrders();
88
+ const [payment, setPayment] = useState<Payment>();
89
+ const [state, setState] = useState<ComponentStates>(ComponentStates.IDLE);
90
+ const [error, setError] = useState<string>();
91
+
92
+ const modals = useModals();
93
+ const { submitForPayment } = useBatchOrdersActions();
94
+ const pay = async () => {
95
+ setState(ComponentStates.LOADING);
96
+ try {
97
+ const paymentResponse = await submitForPayment({
98
+ id: batchOrder.id,
99
+ });
100
+
101
+ if (paymentResponse) {
102
+ setPayment(paymentResponse);
103
+ } else {
104
+ // In case of bug.
105
+ setError(intl.formatMessage(messages.paymentError));
106
+ setState(ComponentStates.ERROR);
107
+ }
108
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
109
+ } catch (_error) {
110
+ setError(intl.formatMessage(messages.paymentError));
111
+ setState(ComponentStates.ERROR);
112
+ }
113
+ };
114
+
115
+ const handleError = (messageId: string = PaymentErrorMessageId.ERROR_DEFAULT) => {
116
+ setState(ComponentStates.ERROR);
117
+
118
+ if (messageId === PaymentErrorMessageId.ERROR_ABORT) {
119
+ setError(intl.formatMessage(messages.abortError));
120
+ } else {
121
+ setError(intl.formatMessage(messages.paymentError));
122
+ }
123
+ };
124
+
125
+ const isBatchOrderValidated = async (id: string): Promise<Boolean> => {
126
+ const batchOrderToCheck = await API.user.batchOrders.get({ id });
127
+ return batchOrderToCheck !== null && batchOrderToCheck.state === BatchOrderState.COMPLETED;
128
+ };
129
+
130
+ const settled = async () => {
131
+ await batchOrderMethods.invalidate();
132
+ props.onClose();
133
+ await modals.messageModal({
134
+ messageType: VariantType.SUCCESS,
135
+ title: intl.formatMessage(messages.successTitle),
136
+ children: intl.formatMessage(messages.successDescription),
137
+ });
138
+ };
139
+
140
+ const handleSuccess = () => {
141
+ let round = 0;
142
+
143
+ const checkBatchOrderValidity = async () => {
144
+ if (round >= PAYMENT_SETTINGS.pollLimit) {
145
+ timeoutRef.current = undefined;
146
+ setState(ComponentStates.ERROR);
147
+ setError(intl.formatMessage(messages.errorAbortingPolling));
148
+ } else {
149
+ const isValidated = await isBatchOrderValidated(batchOrder.id);
150
+ if (isValidated) {
151
+ setState(ComponentStates.IDLE);
152
+ timeoutRef.current = undefined;
153
+ settled();
154
+ } else {
155
+ round++;
156
+ timeoutRef.current = setTimeout(checkBatchOrderValidity, PAYMENT_SETTINGS.pollInterval);
157
+ }
158
+ }
159
+ };
160
+
161
+ checkBatchOrderValidity();
162
+ };
163
+
164
+ return (
165
+ <>
166
+ <Modal
167
+ {...props}
168
+ size={ModalSize.MEDIUM}
169
+ title={intl.formatMessage(messages.title)}
170
+ closeOnEsc={state !== ComponentStates.LOADING}
171
+ preventClose={state === ComponentStates.LOADING}
172
+ hideCloseButton={state === ComponentStates.LOADING}
173
+ actions={
174
+ <Button
175
+ color="primary"
176
+ size="small"
177
+ fullWidth={true}
178
+ onClick={pay}
179
+ disabled={state === ComponentStates.LOADING}
180
+ data-testid="order-payment-retry-modal-submit-button"
181
+ >
182
+ {state === ComponentStates.LOADING ? (
183
+ <Spinner theme="light" aria-labelledby="payment-in-progress">
184
+ <span id="payment-in-progress">
185
+ <FormattedMessage {...messages.paymentInProgress} />
186
+ </span>
187
+ </Spinner>
188
+ ) : (
189
+ <FormattedMessage
190
+ {...messages.submit}
191
+ values={{
192
+ amount: intl.formatNumber(batchOrder.total ?? 0, {
193
+ style: 'currency',
194
+ currency: batchOrder.currency ?? 'EUR',
195
+ }),
196
+ }}
197
+ />
198
+ )}
199
+ </Button>
200
+ }
201
+ >
202
+ {error && (
203
+ <Alert type={VariantType.ERROR} className="mb-t">
204
+ {error}
205
+ </Alert>
206
+ )}
207
+ {!error && (
208
+ <Alert className="mb-b">
209
+ <FormattedMessage {...messages.description} />
210
+ </Alert>
211
+ )}
212
+ </Modal>
213
+ {payment && <PaymentInterface {...payment} onError={handleError} onSuccess={handleSuccess} />}
214
+ </>
215
+ );
216
+ };
@@ -0,0 +1,316 @@
1
+ import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
2
+ import { PaymentMethod } from 'components/PaymentInterfaces/types';
3
+ import { BatchOrderRead } from 'types/Joanie';
4
+ import { DashboardSubItem } from 'widgets/Dashboard/components/DashboardItem/DashboardSubItem';
5
+ import { DashboardSubItemsList } from '../DashboardSubItemsList';
6
+
7
+ const messages = defineMessages({
8
+ stepCompany: {
9
+ id: 'batchOrder.title.company',
10
+ description: 'Step label for company information in the batch order form',
11
+ defaultMessage: 'Organization',
12
+ },
13
+ stepAdmin: {
14
+ id: 'batchOrder.title.admin',
15
+ description: 'Step label for administrative follow-up in the batch order form',
16
+ defaultMessage: 'Follow-up',
17
+ },
18
+ stepParticipants: {
19
+ id: 'batchOrder.title.partipants',
20
+ description: 'Step label for participants information in the batch order form',
21
+ defaultMessage: 'Participants',
22
+ },
23
+ stepFinancing: {
24
+ id: 'batchOrder.title.financing',
25
+ description: 'Step label for financing/payment in the batch order form',
26
+ defaultMessage: 'Financing',
27
+ },
28
+ stepSignatory: {
29
+ id: 'batchOrder.title.signatory',
30
+ description: 'section with details about the person responsible for signing the quote',
31
+ defaultMessage: 'Signatory',
32
+ },
33
+ seats: {
34
+ id: 'batchOrder.seats',
35
+ description: 'Text displayed for seats value in batch order',
36
+ defaultMessage: 'Seats',
37
+ },
38
+ labelName: {
39
+ id: 'batchOrder.label.name',
40
+ description: 'Label displayed for the name field in batch order form',
41
+ defaultMessage: 'Name',
42
+ },
43
+ labelProfession: {
44
+ id: 'batchOrder.label.profession',
45
+ description: 'Label displayed for the profession field in batch order form',
46
+ defaultMessage: 'Profession',
47
+ },
48
+ labelEmail: {
49
+ id: 'batchOrder.label.email',
50
+ description: 'Label displayed for the email field in batch order form',
51
+ defaultMessage: 'Email',
52
+ },
53
+ labelPhone: {
54
+ id: 'batchOrder.label.phone',
55
+ description: 'Label displayed for the phone field in batch order form',
56
+ defaultMessage: 'Phone',
57
+ },
58
+ labelMethod: {
59
+ id: 'batchOrder.label.method',
60
+ description: 'Label displayed for the payment method field in batch order form',
61
+ defaultMessage: 'Method',
62
+ },
63
+ labelEntity: {
64
+ id: 'batchOrder.label.entity',
65
+ description: 'Label displayed for the entity field in batch order form',
66
+ defaultMessage: 'Entity',
67
+ },
68
+ labelAmount: {
69
+ id: 'batchOrder.label.amount',
70
+ description: 'Label displayed for the amount field in batch order form',
71
+ defaultMessage: 'Amount',
72
+ },
73
+ labelCompany: {
74
+ id: 'batchOrder.label.company',
75
+ description: 'Label displayed for the company field in batch order form',
76
+ defaultMessage: 'Company',
77
+ },
78
+ labelSiret: {
79
+ id: 'batchOrder.label.siret',
80
+ description: 'Label displayed for the SIRET field in batch order form',
81
+ defaultMessage: 'SIRET',
82
+ },
83
+ labelVAT: {
84
+ id: 'batchOrder.label.vat',
85
+ description: 'Label displayed for the VAT field in batch order form',
86
+ defaultMessage: 'VAT',
87
+ },
88
+ labelAddress: {
89
+ id: 'batchOrder.label.address',
90
+ description: 'Label displayed for the address field in batch order form',
91
+ defaultMessage: 'Address',
92
+ },
93
+ labelPostcode: {
94
+ id: 'batchOrder.label.postcode',
95
+ description: 'Label displayed for the postcode field in batch order form',
96
+ defaultMessage: 'Postcode',
97
+ },
98
+ labelCity: {
99
+ id: 'batchOrder.label.city',
100
+ description: 'Label displayed for the city field in batch order form',
101
+ defaultMessage: 'City',
102
+ },
103
+ labelCountry: {
104
+ id: 'batchOrder.label.country',
105
+ description: 'Label displayed for the country field in batch order form',
106
+ defaultMessage: 'Country',
107
+ },
108
+ labelBilling: {
109
+ id: 'batchOrder.label.billing',
110
+ description: 'Label displayed for the billing field in batch order form',
111
+ defaultMessage: 'Billing',
112
+ },
113
+ [PaymentMethod.BANK_TRANSFER]: {
114
+ id: 'batchOrder.payment.bank',
115
+ description: 'Label for bank transfer payment method',
116
+ defaultMessage: 'Bank transfer',
117
+ },
118
+ [PaymentMethod.CARD_PAYMENT]: {
119
+ id: 'batchOrder.payment.card',
120
+ description: 'Label for card payment method',
121
+ defaultMessage: 'Card payment',
122
+ },
123
+ [PaymentMethod.PURCHASE_ORDER]: {
124
+ id: 'batchOrder.payment.order',
125
+ description: 'Label for purchase order payment method',
126
+ defaultMessage: 'Purchase order',
127
+ },
128
+ });
129
+
130
+ const DashboardItemField = ({
131
+ label,
132
+ value,
133
+ }: {
134
+ label: React.ReactNode;
135
+ value?: React.ReactNode;
136
+ }) =>
137
+ value ? (
138
+ <div>
139
+ <span className="dashboard-item__label">{label}: </span>
140
+ {value}
141
+ </div>
142
+ ) : null;
143
+
144
+ export const DashboardBatchOrderSubItems = ({ batchOrder }: { batchOrder: BatchOrderRead }) => {
145
+ const intl = useIntl();
146
+
147
+ const items = [
148
+ <DashboardSubItem
149
+ key="company"
150
+ title={intl.formatMessage(messages.stepCompany)}
151
+ footer={
152
+ <div className="content">
153
+ <DashboardItemField
154
+ label={<FormattedMessage {...messages.labelCompany} />}
155
+ value={batchOrder.company_name}
156
+ />
157
+ <DashboardItemField
158
+ label={<FormattedMessage {...messages.labelSiret} />}
159
+ value={batchOrder.identification_number}
160
+ />
161
+ <DashboardItemField
162
+ label={<FormattedMessage {...messages.labelVAT} />}
163
+ value={batchOrder.vat_registration}
164
+ />
165
+ <DashboardItemField
166
+ label={<FormattedMessage {...messages.labelAddress} />}
167
+ value={batchOrder.address}
168
+ />
169
+ <DashboardItemField
170
+ label={<FormattedMessage {...messages.labelPostcode} />}
171
+ value={batchOrder.postcode}
172
+ />
173
+ <DashboardItemField
174
+ label={<FormattedMessage {...messages.labelCity} />}
175
+ value={batchOrder.city}
176
+ />
177
+ <DashboardItemField
178
+ label={<FormattedMessage {...messages.labelCountry} />}
179
+ value={batchOrder.country}
180
+ />
181
+ </div>
182
+ }
183
+ />,
184
+ <DashboardSubItem
185
+ key="admin"
186
+ title={intl.formatMessage(messages.stepAdmin)}
187
+ footer={
188
+ <div className="content">
189
+ <DashboardItemField
190
+ label={<FormattedMessage {...messages.labelName} />}
191
+ value={`${batchOrder.administrative_firstname} ${batchOrder.administrative_lastname}`}
192
+ />
193
+ <DashboardItemField
194
+ label={<FormattedMessage {...messages.labelProfession} />}
195
+ value={batchOrder.administrative_profession}
196
+ />
197
+ <DashboardItemField
198
+ label={<FormattedMessage {...messages.labelEmail} />}
199
+ value={batchOrder.administrative_email}
200
+ />
201
+ <DashboardItemField
202
+ label={<FormattedMessage {...messages.labelPhone} />}
203
+ value={batchOrder.administrative_telephone}
204
+ />
205
+ </div>
206
+ }
207
+ />,
208
+ <DashboardSubItem
209
+ key="signatory"
210
+ title={intl.formatMessage(messages.stepSignatory)}
211
+ footer={
212
+ <div className="content">
213
+ <DashboardItemField
214
+ label={<FormattedMessage {...messages.labelName} />}
215
+ value={`${batchOrder.signatory_firstname} ${batchOrder.signatory_lastname}`}
216
+ />
217
+ <DashboardItemField
218
+ label={<FormattedMessage {...messages.labelProfession} />}
219
+ value={batchOrder.signatory_profession}
220
+ />
221
+ <DashboardItemField
222
+ label={<FormattedMessage {...messages.labelEmail} />}
223
+ value={batchOrder.signatory_email}
224
+ />
225
+ <DashboardItemField
226
+ label={<FormattedMessage {...messages.labelPhone} />}
227
+ value={batchOrder.signatory_telephone}
228
+ />
229
+ </div>
230
+ }
231
+ />,
232
+ <DashboardSubItem
233
+ key="participants"
234
+ title={intl.formatMessage(messages.stepParticipants)}
235
+ footer={
236
+ <div className="content">
237
+ <DashboardItemField
238
+ label={<FormattedMessage {...messages.seats} />}
239
+ value={batchOrder.nb_seats}
240
+ />
241
+ </div>
242
+ }
243
+ />,
244
+ <DashboardSubItem
245
+ key="financing"
246
+ title={intl.formatMessage(messages.stepFinancing)}
247
+ footer={
248
+ <div className="content">
249
+ <DashboardItemField
250
+ label={<FormattedMessage {...messages.labelMethod} />}
251
+ value={
252
+ batchOrder.payment_method && (
253
+ <FormattedMessage {...messages[batchOrder.payment_method]} />
254
+ )
255
+ }
256
+ />
257
+ <DashboardItemField
258
+ label={<FormattedMessage {...messages.labelEntity} />}
259
+ value={batchOrder.funding_entity}
260
+ />
261
+ <DashboardItemField
262
+ label={<FormattedMessage {...messages.labelAmount} />}
263
+ value={batchOrder.funding_amount}
264
+ />
265
+ </div>
266
+ }
267
+ />,
268
+ ];
269
+
270
+ if (batchOrder.billing_address) {
271
+ items.push(
272
+ <DashboardSubItem
273
+ key="billing"
274
+ title={intl.formatMessage(messages.labelBilling)}
275
+ footer={
276
+ <div className="content">
277
+ <DashboardItemField
278
+ label={<FormattedMessage {...messages.labelCompany} />}
279
+ value={batchOrder.billing_address.company_name}
280
+ />
281
+ <DashboardItemField
282
+ label={<FormattedMessage {...messages.labelSiret} />}
283
+ value={batchOrder.billing_address.identification_number}
284
+ />
285
+ <DashboardItemField
286
+ label={<FormattedMessage {...messages.labelName} />}
287
+ value={batchOrder.billing_address.contact_name}
288
+ />
289
+ <DashboardItemField
290
+ label={<FormattedMessage {...messages.labelEmail} />}
291
+ value={batchOrder.billing_address.contact_email}
292
+ />
293
+ <DashboardItemField
294
+ label={<FormattedMessage {...messages.labelAddress} />}
295
+ value={batchOrder.billing_address.address}
296
+ />
297
+ <DashboardItemField
298
+ label={<FormattedMessage {...messages.labelPostcode} />}
299
+ value={batchOrder.billing_address.postcode}
300
+ />
301
+ <DashboardItemField
302
+ label={<FormattedMessage {...messages.labelCity} />}
303
+ value={batchOrder.billing_address.city}
304
+ />
305
+ <DashboardItemField
306
+ label={<FormattedMessage {...messages.labelCountry} />}
307
+ value={batchOrder.billing_address.country}
308
+ />
309
+ </div>
310
+ }
311
+ />,
312
+ );
313
+ }
314
+
315
+ return <DashboardSubItemsList subItems={items} />;
316
+ };