strapi-plugin-payone-provider 4.6.10 → 4.6.12

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 (68) hide show
  1. package/README.md +64 -0
  2. package/admin/src/pages/App/components/AppHeader.jsx +3 -2
  3. package/admin/src/pages/App/components/AppTabs.jsx +34 -88
  4. package/admin/src/pages/App/components/DocsPanel.jsx +1726 -1726
  5. package/admin/src/pages/App/components/GooglePaybutton.jsx +300 -300
  6. package/admin/src/pages/App/components/StatusBadge.jsx +1 -1
  7. package/admin/src/pages/App/components/common/InfoTooltip.jsx +16 -0
  8. package/admin/src/pages/App/components/{ApplePayConfig.jsx → configuration/ApplePayConfig.jsx} +191 -62
  9. package/admin/src/pages/App/components/{ApplePayConfigPanel.jsx → configuration/ApplePayConfigPanel.jsx} +71 -70
  10. package/admin/src/pages/App/components/configuration/ConfigurationFields.jsx +408 -0
  11. package/admin/src/pages/App/components/configuration/ConfigurationPanel.jsx +67 -0
  12. package/admin/src/pages/App/components/{GooglePayConfig.jsx → configuration/GooglePayConfig.jsx} +254 -254
  13. package/admin/src/pages/App/components/{GooglePayConfigPanel.jsx → configuration/GooglePayConfigPanel.jsx} +82 -82
  14. package/admin/src/pages/App/components/configuration/TestConnection.jsx +129 -0
  15. package/admin/src/pages/App/components/paymentActions/ApplePayPanel.jsx +137 -95
  16. package/admin/src/pages/App/components/paymentActions/CaptureForm.jsx +119 -14
  17. package/admin/src/pages/App/components/paymentActions/CardDetailsInput.jsx +85 -24
  18. package/admin/src/pages/App/components/paymentActions/PaymentActionsPanel.jsx +361 -0
  19. package/admin/src/pages/App/components/paymentActions/PaymentMethodSelector.jsx +22 -4
  20. package/admin/src/pages/App/components/paymentActions/RefundForm.jsx +91 -20
  21. package/admin/src/pages/App/components/paymentActions/authorization/AuthorizationForm.jsx +157 -0
  22. package/admin/src/pages/App/components/paymentActions/authorization/AuthorizationFormFields.jsx +308 -0
  23. package/admin/src/pages/App/components/paymentActions/authorization/AuthorizationFormHeader.jsx +27 -0
  24. package/admin/src/pages/App/components/paymentActions/authorization/AuthorizationPaymentButtons.jsx +93 -0
  25. package/admin/src/pages/App/components/paymentActions/preauthorization/PreauthorizationForm.jsx +134 -0
  26. package/admin/src/pages/App/components/paymentActions/preauthorization/PreauthorizationFormFields.jsx +295 -0
  27. package/admin/src/pages/App/components/paymentActions/preauthorization/PreauthorizationFormHeader.jsx +27 -0
  28. package/admin/src/pages/App/components/paymentActions/preauthorization/PreauthorizationPaymentButtons.jsx +53 -0
  29. package/admin/src/pages/App/components/transaction-history/FiltersPanel.jsx +182 -0
  30. package/admin/src/pages/App/components/transaction-history/HistoryPanel.jsx +49 -0
  31. package/admin/src/pages/App/components/transaction-history/TransactionTable.jsx +199 -0
  32. package/admin/src/pages/App/components/transaction-history/TransactionTablePagination.jsx +28 -0
  33. package/admin/src/pages/App/components/transaction-history/details/TransactionDetails.jsx +155 -0
  34. package/admin/src/pages/App/index.jsx +5 -29
  35. package/admin/src/pages/hooks/usePaymentActions.js +87 -11
  36. package/admin/src/pages/hooks/useSettings.js +64 -22
  37. package/admin/src/pages/hooks/useTransactionHistory.js +121 -85
  38. package/admin/src/pages/utils/api.js +31 -3
  39. package/admin/src/pages/utils/countryLanguageUtils.js +236 -0
  40. package/admin/src/pages/utils/transactionTableUtils.js +60 -0
  41. package/package.json +2 -2
  42. package/server/bootstrap.js +6 -6
  43. package/server/content-types/index.js +5 -0
  44. package/server/content-types/transactions/index.js +5 -0
  45. package/server/content-types/transactions/schema.json +87 -0
  46. package/server/controllers/payone.js +29 -3
  47. package/server/index.js +2 -1
  48. package/server/policies/index.js +2 -1
  49. package/server/policies/is-payone-notification.js +31 -0
  50. package/server/routes/index.js +10 -0
  51. package/server/services/applePayService.js +0 -2
  52. package/server/services/payone.js +16 -4
  53. package/server/services/settingsService.js +8 -2
  54. package/server/services/testConnectionService.js +11 -72
  55. package/server/services/transactionService.js +147 -154
  56. package/server/services/transactionStatusService.js +63 -0
  57. package/server/utils/sanitize.js +41 -0
  58. package/admin/src/pages/App/components/ConfigurationPanel.jsx +0 -517
  59. package/admin/src/pages/App/components/CustomerInfoPopover.jsx +0 -147
  60. package/admin/src/pages/App/components/HistoryPanel.jsx +0 -94
  61. package/admin/src/pages/App/components/PaymentActionsPanel.jsx +0 -280
  62. package/admin/src/pages/App/components/RawDataPopover.jsx +0 -113
  63. package/admin/src/pages/App/components/TransactionHistoryItem.jsx +0 -522
  64. package/admin/src/pages/App/components/TransactionHistoryTable/TransactionHistoryTableFilters.jsx +0 -113
  65. package/admin/src/pages/App/components/TransactionHistoryTable/TransactionHistoryTablePagination.jsx +0 -180
  66. package/admin/src/pages/App/components/TransactionHistoryTable/index.jsx +0 -225
  67. package/admin/src/pages/App/components/paymentActions/AuthorizationForm.jsx +0 -197
  68. package/admin/src/pages/App/components/paymentActions/PreauthorizationForm.jsx +0 -142
@@ -1,517 +0,0 @@
1
- import React, { useEffect } from "react";
2
- import {
3
- Box,
4
- Button,
5
- Card,
6
- CardBody,
7
- Flex,
8
- Stack,
9
- Typography,
10
- TextInput,
11
- Select,
12
- Option,
13
- Alert,
14
- Switch,
15
- } from "@strapi/design-system";
16
- import { Play, Cog } from "@strapi/icons";
17
- import { useHistory } from "react-router-dom";
18
- import pluginId from "../../../pluginId";
19
-
20
- const ConfigurationPanel = ({
21
- settings,
22
- isTesting,
23
- testResult,
24
- onTestConnection,
25
- onInputChange,
26
- onPaymentMethodToggle,
27
- }) => {
28
- const history = useHistory();
29
- const mode = (settings?.mode || "test").toLowerCase();
30
-
31
- const handleNavigateToApplePayConfig = () => {
32
- history.push(`/plugins/${pluginId}/apple-pay-config`);
33
- };
34
-
35
- const handleNavigateToGooglePayConfig = () => {
36
- history.push(`/plugins/${pluginId}/google-pay-config`);
37
- };
38
-
39
- return (
40
- <Box
41
- className="payment-container"
42
- paddingTop={8}
43
- paddingBottom={8}
44
- paddingLeft={8}
45
- paddingRight={8}
46
- >
47
- <Flex direction="column" alignItems="stretch" gap={8}>
48
- <Box>
49
- <Typography
50
- variant="beta"
51
- as="h2"
52
- fontWeight="bold"
53
- className="payment-title"
54
- style={{ fontSize: "20px", marginBottom: "4px" }}
55
- >
56
- Payone API Configuration
57
- </Typography>
58
- <Typography
59
- variant="pi"
60
- textColor="neutral600"
61
- marginTop={2}
62
- className="payment-subtitle"
63
- style={{ fontSize: "14px" }}
64
- >
65
- Configure your Payone payment gateway settings
66
- </Typography>
67
- </Box>
68
- <Box
69
- style={{
70
- display: "flex",
71
- flexDirection: "row",
72
- gap: "16px",
73
- flexWrap: "wrap",
74
- }}
75
- >
76
- <Card className="payment-card">
77
- <CardBody padding={6}>
78
- <Stack spacing={6}>
79
- <Flex gap={4} wrap="wrap">
80
- <TextInput
81
- label="Account ID (aid)"
82
- name="aid"
83
- value={settings.aid || ""}
84
- onChange={(e) => onInputChange("aid", e.target.value)}
85
- required
86
- hint="Your Payone account ID"
87
- className="payment-input"
88
- style={{ flex: 1, minWidth: "300px" }}
89
- />
90
-
91
- <TextInput
92
- label="Portal ID"
93
- name="portalid"
94
- value={settings.portalid || ""}
95
- onChange={(e) => onInputChange("portalid", e.target.value)}
96
- required
97
- hint="Your Payone portal ID"
98
- className="payment-input"
99
- style={{ flex: 1, minWidth: "300px" }}
100
- />
101
- </Flex>
102
-
103
- <Flex gap={4} wrap="wrap">
104
- <TextInput
105
- label="Merchant ID (mid)"
106
- name="mid"
107
- value={settings.mid || ""}
108
- onChange={(e) => onInputChange("mid", e.target.value)}
109
- required
110
- hint="Your Payone merchant ID"
111
- className="payment-input"
112
- style={{ flex: 1, minWidth: "300px" }}
113
- />
114
-
115
- <TextInput
116
- label="Portal Key"
117
- name="key"
118
- type="password"
119
- value={settings.key || ""}
120
- onChange={(e) => onInputChange("key", e.target.value)}
121
- required
122
- hint="Your Payone portal key (will be encrypted)"
123
- className="payment-input"
124
- style={{ flex: 1, minWidth: "300px" }}
125
- />
126
- </Flex>
127
-
128
- <Flex gap={4} wrap="wrap">
129
- <TextInput
130
- label="Domain Name"
131
- name="domainName"
132
- value={settings.domainName || ""}
133
- onChange={(e) =>
134
- onInputChange("domainName", e.target.value)
135
- }
136
- hint="Your domain name (optional)"
137
- className="payment-input"
138
- style={{ flex: 1, minWidth: "300px" }}
139
- />
140
-
141
- <TextInput
142
- label="Display Name"
143
- name="displayName"
144
- value={settings.displayName || ""}
145
- onChange={(e) =>
146
- onInputChange("displayName", e.target.value)
147
- }
148
- hint="Display name for payment methods (optional)"
149
- className="payment-input"
150
- style={{ flex: 1, minWidth: "300px" }}
151
- />
152
- </Flex>
153
-
154
- <Flex gap={4} wrap="wrap">
155
- <Select
156
- label="Mode"
157
- name="mode"
158
- value={settings.mode || "test"}
159
- onChange={(value) => onInputChange("mode", value)}
160
- hint="Select the API mode"
161
- className="payment-input"
162
- style={{ flex: 1, minWidth: "300px" }}
163
- >
164
- <Option value="test">Test</Option>
165
- <Option value="live">Live</Option>
166
- </Select>
167
-
168
- <TextInput
169
- label="API Version"
170
- name="api_version"
171
- value={settings.api_version || "3.10"}
172
- onChange={(e) =>
173
- onInputChange("api_version", e.target.value)
174
- }
175
- hint="Payone API version"
176
- className="payment-input"
177
- style={{ flex: 1, minWidth: "300px" }}
178
- />
179
- </Flex>
180
-
181
- <Flex
182
- direction="column"
183
- wrap="wrap"
184
- gap={1}
185
- alignItems="flex-start"
186
- >
187
- <Select
188
- label="Enable 3D Secure"
189
- name="enable3DSecure"
190
- value={settings.enable3DSecure ? "yes" : "no"}
191
- onChange={(value) =>
192
- onInputChange("enable3DSecure", value === "yes")
193
- }
194
- hint="Enable 3D Secure authentication for credit card payments"
195
- className="payment-input"
196
- >
197
- <Option value="yes">Enabled</Option>
198
- <Option value="no">Disabled</Option>
199
- </Select>
200
- <Typography variant="pi" textColor="neutral600" marginTop={1}>
201
- When enabled, credit card payments will require 3D Secure
202
- authentication (SCA compliance)
203
- </Typography>
204
- </Flex>
205
-
206
- <Flex
207
- direction="row"
208
- gap={2}
209
- wrap="wrap"
210
- alignItems="flex-start"
211
- marginTop={2}
212
- >
213
- <Button
214
- variant="secondary"
215
- startIcon={<Cog />}
216
- onClick={handleNavigateToApplePayConfig}
217
- className="payment-button"
218
- >
219
- Apple Pay Config
220
- </Button>
221
- <Button
222
- variant="secondary"
223
- startIcon={<Cog />}
224
- onClick={handleNavigateToGooglePayConfig}
225
- className="payment-button"
226
- >
227
- Google Pay Config
228
- </Button>
229
- </Flex>
230
- </Stack>
231
- </CardBody>
232
- </Card>
233
-
234
- <Card className="payment-card">
235
- <CardBody padding={6}>
236
- <Stack spacing={6}>
237
- <Box>
238
- <Typography
239
- variant="delta"
240
- as="h3"
241
- fontWeight="bold"
242
- marginBottom={4}
243
- >
244
- Payment Methods
245
- </Typography>
246
- <Typography
247
- variant="pi"
248
- textColor="neutral600"
249
- marginBottom={4}
250
- >
251
- Enable or disable payment methods for your Payone
252
- integration
253
- </Typography>
254
- </Box>
255
-
256
- <Stack spacing={4}>
257
- <Flex
258
- direction="row"
259
- justifyContent="space-between"
260
- alignItems="center"
261
- gap={4}
262
- >
263
- <Typography variant="omega" fontWeight="semiBold">
264
- Credit Card (Visa, Mastercard)
265
- </Typography>
266
- <Switch
267
- label="Credit Card"
268
- selected={settings.enableCreditCard !== false}
269
- onChange={() =>
270
- onPaymentMethodToggle(
271
- "enableCreditCard",
272
- !settings.enableCreditCard
273
- )
274
- }
275
- />
276
- </Flex>
277
-
278
- <Flex
279
- direction="row"
280
- justifyContent="space-between"
281
- alignItems="center"
282
- gap={4}
283
- >
284
- <Typography variant="omega" fontWeight="semiBold">
285
- PayPal
286
- </Typography>
287
- <Switch
288
- label="PayPal"
289
- selected={settings.enablePayPal !== false}
290
- onChange={() =>
291
- onPaymentMethodToggle(
292
- "enablePayPal",
293
- !settings.enablePayPal
294
- )
295
- }
296
- />
297
- </Flex>
298
-
299
- <Flex
300
- direction="row"
301
- justifyContent="space-between"
302
- alignItems="center"
303
- gap={4}
304
- >
305
- <Typography variant="omega" fontWeight="semiBold">
306
- Google Pay
307
- </Typography>
308
- <Switch
309
- label="Google Pay"
310
- selected={settings.enableGooglePay !== false}
311
- onChange={() =>
312
- onPaymentMethodToggle(
313
- "enableGooglePay",
314
- !settings.enableGooglePay
315
- )
316
- }
317
- />
318
- </Flex>
319
-
320
- <Flex
321
- direction="row"
322
- justifyContent="space-between"
323
- alignItems="center"
324
- gap={4}
325
- >
326
- <Typography variant="omega" fontWeight="semiBold">
327
- Apple Pay
328
- </Typography>
329
- <Switch
330
- label="Apple Pay"
331
- selected={settings.enableApplePay !== false}
332
- onChange={() =>
333
- onPaymentMethodToggle(
334
- "enableApplePay",
335
- !settings.enableApplePay
336
- )
337
- }
338
- />
339
- </Flex>
340
-
341
- <Flex
342
- direction="row"
343
- justifyContent="space-between"
344
- alignItems="center"
345
- gap={4}
346
- >
347
- <Typography variant="omega" fontWeight="semiBold">
348
- Sofort Banking
349
- </Typography>
350
- <Switch
351
- label="Sofort Banking"
352
- selected={settings.enableSofort !== false}
353
- onChange={() =>
354
- onPaymentMethodToggle(
355
- "enableSofort",
356
- !settings.enableSofort
357
- )
358
- }
359
- />
360
- </Flex>
361
-
362
- <Flex
363
- direction="row"
364
- justifyContent="space-between"
365
- alignItems="center"
366
- gap={4}
367
- >
368
- <Typography variant="omega" fontWeight="semiBold">
369
- SEPA Direct Debit
370
- </Typography>
371
- <Switch
372
- label="SEPA Direct Debit"
373
- selected={settings.enableSepaDirectDebit !== false}
374
- onChange={() =>
375
- onPaymentMethodToggle(
376
- "enableSepaDirectDebit",
377
- !settings.enableSepaDirectDebit
378
- )
379
- }
380
- />
381
- </Flex>
382
- </Stack>
383
- </Stack>
384
- </CardBody>
385
- </Card>
386
- </Box>
387
- <Box paddingTop={6}>
388
- <Card className="payment-card">
389
- <CardBody padding={6}>
390
- <Stack spacing={6}>
391
- <Box>
392
- <Typography
393
- variant="delta"
394
- as="h3"
395
- fontWeight="bold"
396
- marginBottom={2}
397
- >
398
- Test Connection
399
- </Typography>
400
- <Typography variant="pi" textColor="neutral600">
401
- Verify your Payone configuration by testing the API
402
- connection
403
- </Typography>
404
- </Box>
405
-
406
- <Button
407
- variant="default"
408
- onClick={onTestConnection}
409
- loading={isTesting}
410
- startIcon={<Play />}
411
- className="payment-button payment-button-success"
412
- disabled={mode === "live"}
413
- >
414
- {isTesting ? "Testing Connection..." : "Test Connection"}
415
- </Button>
416
- {mode === "live" && (
417
- <Typography
418
- variant="pi"
419
- textColor="neutral600"
420
- style={{ marginTop: "8px" }}
421
- >
422
- Test Connection is disabled in live mode for security
423
- reasons.
424
- </Typography>
425
- )}
426
-
427
- {testResult && (
428
- <Alert
429
- variant={Boolean(testResult.success) ? "success" : "danger"}
430
- title={
431
- Boolean(testResult.success)
432
- ? "Connection Successful"
433
- : "Connection Failed"
434
- }
435
- className="payment-alert"
436
- >
437
- <Typography
438
- variant="pi"
439
- fontWeight="medium"
440
- marginBottom={2}
441
- >
442
- {testResult.message}
443
- </Typography>
444
- {testResult.details && (
445
- <Box paddingTop={3}>
446
- {Boolean(testResult.success) ? (
447
- <Card className="payment-card">
448
- <CardBody padding={4}>
449
- <Typography variant="pi">
450
- <strong>Mode:</strong> {testResult.details.mode}{" "}
451
- |<strong> AID:</strong> {testResult.details.aid}{" "}
452
- |<strong> Portal ID:</strong>{" "}
453
- {testResult.details.portalid} |
454
- <strong> Merchant ID:</strong>{" "}
455
- {testResult.details.mid || ""}
456
- </Typography>
457
- </CardBody>
458
- </Card>
459
- ) : (
460
- <Card
461
- className="payment-card"
462
- style={{ background: "#fff5f5" }}
463
- >
464
- <CardBody padding={4}>
465
- <Stack spacing={2}>
466
- {testResult.errorcode && (
467
- <Typography
468
- variant="pi"
469
- textColor="neutral600"
470
- >
471
- <strong>Error Code:</strong>{" "}
472
- {testResult.errorcode}
473
- </Typography>
474
- )}
475
- {testResult.details.errorCode && (
476
- <Typography
477
- variant="pi"
478
- textColor="neutral600"
479
- >
480
- <strong>Error Code:</strong>{" "}
481
- {testResult.details.errorCode}
482
- </Typography>
483
- )}
484
- {testResult.details &&
485
- testResult.details.rawResponse && (
486
- <Typography
487
- variant="pi"
488
- textColor="neutral600"
489
- >
490
- <strong>Debug Info:</strong>{" "}
491
- {testResult.details.rawResponse}
492
- </Typography>
493
- )}
494
- </Stack>
495
- </CardBody>
496
- </Card>
497
- )}
498
- </Box>
499
- )}
500
- </Alert>
501
- )}
502
- </Stack>
503
- </CardBody>
504
- </Card>
505
- </Box>
506
- <Box paddingTop={4}>
507
- <Typography variant="sigma" textColor="neutral600">
508
- Note: These settings are used for all Payone API requests. Make sure
509
- to use the correct credentials for your selected mode.
510
- </Typography>
511
- </Box>
512
- </Flex>
513
- </Box>
514
- );
515
- };
516
-
517
- export default ConfigurationPanel;
@@ -1,147 +0,0 @@
1
- import React, { useState, useRef, useEffect } from "react";
2
- import { Box, Typography } from "@strapi/design-system";
3
-
4
- const CustomerInfoPopover = ({ transaction, children }) => {
5
- const [isOpen, setIsOpen] = useState(false);
6
- const [position, setPosition] = useState("top"); // 'top' or 'bottom'
7
- const popoverRef = useRef(null);
8
- const buttonRef = useRef(null);
9
-
10
- const calculatePosition = (buttonElement) => {
11
- if (!buttonElement) return "top";
12
-
13
- const buttonRect = buttonElement.getBoundingClientRect();
14
- // Find the scrollable parent container
15
- let scrollableParent = buttonElement.parentElement;
16
- while (scrollableParent && scrollableParent !== document.body) {
17
- const style = window.getComputedStyle(scrollableParent);
18
- if (style.overflow === 'auto' || style.overflowY === 'auto' || style.overflow === 'scroll' || style.overflowY === 'scroll') {
19
- const parentRect = scrollableParent.getBoundingClientRect();
20
- const spaceAbove = buttonRect.top - parentRect.top;
21
- const spaceBelow = parentRect.bottom - buttonRect.bottom;
22
- // If there's less space above than below (or less than 200px), show popover below
23
- return spaceAbove < 200 || spaceAbove < spaceBelow ? "bottom" : "top";
24
- }
25
- scrollableParent = scrollableParent.parentElement;
26
- }
27
- // Fallback: use viewport space
28
- const spaceAbove = buttonRect.top;
29
- return spaceAbove < 200 ? "bottom" : "top";
30
- };
31
-
32
- const handleButtonClick = () => {
33
- if (!isOpen && buttonRef.current) {
34
- // Calculate position before opening
35
- const newPosition = calculatePosition(buttonRef.current);
36
- setPosition(newPosition);
37
- }
38
- setIsOpen(!isOpen);
39
- };
40
-
41
- useEffect(() => {
42
- const handleClickOutside = (event) => {
43
- if (
44
- popoverRef.current &&
45
- buttonRef.current &&
46
- !popoverRef.current.contains(event.target) &&
47
- !buttonRef.current.contains(event.target)
48
- ) {
49
- setIsOpen(false);
50
- }
51
- };
52
-
53
- if (isOpen) {
54
- document.addEventListener("mousedown", handleClickOutside);
55
- return () => {
56
- document.removeEventListener("mousedown", handleClickOutside);
57
- };
58
- }
59
- }, [isOpen]);
60
-
61
- const rawRequest = transaction?.raw_request || {};
62
- const salutation = rawRequest.salutation || "";
63
- const firstname = rawRequest.firstname || "";
64
- const lastname = rawRequest.lastname || "";
65
- const street = rawRequest.street || "";
66
- const zip = rawRequest.zip || "";
67
- const city = rawRequest.city || "";
68
- const telephonenumber = rawRequest.telephonenumber || "";
69
- const email = rawRequest.email || "";
70
-
71
- const hasCustomerInfo =
72
- salutation ||
73
- firstname ||
74
- lastname ||
75
- street ||
76
- zip ||
77
- city ||
78
- telephonenumber ||
79
- email;
80
-
81
- if (!hasCustomerInfo) {
82
- return children;
83
- }
84
-
85
- return (
86
- <Box position="relative" style={{ display: "inline-block" }}>
87
- <Box
88
- ref={buttonRef}
89
- onClick={handleButtonClick}
90
- style={{ display: "inline-block" }}
91
- >
92
- {children}
93
- </Box>
94
- {isOpen && (
95
- <Box
96
- ref={popoverRef}
97
- position="absolute"
98
- zIndex={1000}
99
- left={0}
100
- {...(position === "top"
101
- ? { bottom: "100%", marginBottom: 2 }
102
- : { top: "100%", marginTop: 2 }
103
- )}
104
- padding={3}
105
- background="neutral0"
106
- hasRadius
107
- style={{
108
- minWidth: "250px",
109
- maxWidth: "350px",
110
- boxShadow: "0 4px 12px rgba(0, 0, 0, 0.15)",
111
- border: "1px solid var(--strapi-colors-neutral200)",
112
- }}
113
- >
114
- <Box paddingBottom={2}>
115
- <Typography variant="pi" fontWeight="bold" textColor="neutral800">
116
- 👤 {[salutation, firstname, lastname].filter(Boolean).join(" ")}
117
- </Typography>
118
- </Box>
119
- {(street || zip || city) && (
120
- <Box paddingBottom={2}>
121
- <Typography variant="pi" textColor="neutral800">
122
- 📍 {[street, zip, city].filter(Boolean).join(" ")}
123
- </Typography>
124
- </Box>
125
- )}
126
- {telephonenumber && (
127
- <Box paddingBottom={2}>
128
- <Typography variant="pi" textColor="neutral800">
129
- 📞 {telephonenumber}
130
- </Typography>
131
- </Box>
132
- )}
133
- {email && (
134
- <Box>
135
- <Typography variant="pi" textColor="neutral800">
136
- ✉️ {email}
137
- </Typography>
138
- </Box>
139
- )}
140
- </Box>
141
- )}
142
- </Box>
143
- );
144
- };
145
-
146
- export default CustomerInfoPopover;
147
-