@antscorp/antsomi-ui 2.0.107 → 2.0.108

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 (67) hide show
  1. package/es/components/molecules/EditingListV2/components/List/List.d.ts +1 -1
  2. package/es/components/molecules/EditingListV2/components/List/List.js +16 -7
  3. package/es/components/molecules/TagifyInput/TagifyInput.js +15 -4
  4. package/es/components/molecules/TagifyInput/constants.d.ts +7 -3
  5. package/es/components/molecules/TagifyInput/constants.js +7 -2
  6. package/es/components/molecules/TagifyInput/patternHandlers.js +34 -1
  7. package/es/components/molecules/TagifyInput/types.d.ts +13 -3
  8. package/es/components/molecules/TagifyInput/utils.d.ts +1 -0
  9. package/es/components/molecules/TagifyInput/utils.js +2 -1
  10. package/es/components/molecules/UnsubscribePreferences/constants.d.ts +27 -0
  11. package/es/components/molecules/UnsubscribePreferences/constants.js +28 -0
  12. package/es/components/molecules/UnsubscribePreferences/index.d.ts +17 -0
  13. package/es/components/molecules/UnsubscribePreferences/index.js +203 -0
  14. package/es/components/molecules/UnsubscribePreferences/styled.d.ts +2 -0
  15. package/es/components/molecules/UnsubscribePreferences/styled.js +11 -0
  16. package/es/components/molecules/UnsubscribePreferences/utils.d.ts +15 -0
  17. package/es/components/molecules/UnsubscribePreferences/utils.js +56 -0
  18. package/es/components/molecules/UnsubscribePreview/components/PreferencesPage/index.d.ts +12 -0
  19. package/es/components/molecules/UnsubscribePreview/components/PreferencesPage/index.js +159 -0
  20. package/es/components/molecules/UnsubscribePreview/components/ResultPage/index.d.ts +13 -0
  21. package/es/components/molecules/UnsubscribePreview/components/ResultPage/index.js +28 -0
  22. package/es/components/molecules/UnsubscribePreview/components/TestAlert/index.d.ts +9 -0
  23. package/es/components/molecules/UnsubscribePreview/components/TestAlert/index.js +18 -0
  24. package/es/components/molecules/UnsubscribePreview/components/UnsubscribedPage/index.d.ts +13 -0
  25. package/es/components/molecules/UnsubscribePreview/components/UnsubscribedPage/index.js +85 -0
  26. package/es/components/molecules/UnsubscribePreview/components/index.d.ts +3 -0
  27. package/es/components/molecules/UnsubscribePreview/components/index.js +3 -0
  28. package/es/components/molecules/UnsubscribePreview/components/styled.d.ts +13 -0
  29. package/es/components/molecules/UnsubscribePreview/components/styled.js +65 -0
  30. package/es/components/molecules/UnsubscribePreview/index.d.ts +10 -0
  31. package/es/components/molecules/UnsubscribePreview/index.js +66 -0
  32. package/es/components/molecules/UnsubscribePreview/styled.d.ts +9 -0
  33. package/es/components/molecules/UnsubscribePreview/styled.js +51 -0
  34. package/es/components/molecules/UnsubscribePreview/type.d.ts +5 -0
  35. package/es/components/molecules/UnsubscribePreview/type.js +1 -0
  36. package/es/components/molecules/UnsubscribePreview/utils.d.ts +9 -0
  37. package/es/components/molecules/UnsubscribePreview/utils.js +27 -0
  38. package/es/components/molecules/UploadImage/index.d.ts +4 -0
  39. package/es/components/molecules/UploadImage/index.js +2 -2
  40. package/es/components/molecules/index.d.ts +4 -0
  41. package/es/components/molecules/index.js +2 -0
  42. package/es/components/organism/PreviewCollections/WhatsappMessage/FooterMessage/index.js +3 -1
  43. package/es/constants/index.d.ts +1 -0
  44. package/es/constants/index.js +1 -0
  45. package/es/constants/queries.d.ts +5 -0
  46. package/es/constants/queries.js +6 -0
  47. package/es/constants/unsubscribe.d.ts +56 -0
  48. package/es/constants/unsubscribe.js +77 -0
  49. package/es/queries/Unsubscribe/index.d.ts +5 -0
  50. package/es/queries/Unsubscribe/index.js +5 -0
  51. package/es/queries/Unsubscribe/useGetUnsubscribeList.d.ts +8 -0
  52. package/es/queries/Unsubscribe/useGetUnsubscribeList.js +18 -0
  53. package/es/queries/Unsubscribe/useGetUnsubscribeListByIdentifier.d.ts +8 -0
  54. package/es/queries/Unsubscribe/useGetUnsubscribeListByIdentifier.js +11 -0
  55. package/es/queries/Unsubscribe/useGetUnsubscribeListPermission.d.ts +8 -0
  56. package/es/queries/Unsubscribe/useGetUnsubscribeListPermission.js +17 -0
  57. package/es/queries/Unsubscribe/useGetUnsubscribePreferences.d.ts +23 -0
  58. package/es/queries/Unsubscribe/useGetUnsubscribePreferences.js +26 -0
  59. package/es/services/Unsubscribe/index.d.ts +41 -0
  60. package/es/services/Unsubscribe/index.js +78 -0
  61. package/es/types/index.d.ts +1 -0
  62. package/es/types/index.js +1 -0
  63. package/es/types/unsubscribe.d.ts +25 -0
  64. package/es/types/unsubscribe.js +1 -0
  65. package/es/utils/common.d.ts +1 -0
  66. package/es/utils/common.js +3 -0
  67. package/package.json +1 -1
@@ -0,0 +1,56 @@
1
+ import { compareStrings } from '@antscorp/antsomi-ui/es/utils';
2
+ import { UNSUBSCRIBE_LIST_MESSAGE_ERRORS, UNSUBSCRIBE_LIST_STATUS } from './constants';
3
+ import { GLOBAL_UNSUBSCRIBED_LIST, GLOBAL_UNSUBSCRIBED_WHATSAPP, } from '@antscorp/antsomi-ui/es/constants';
4
+ export const buildOptionUnsubscribedList = (list, selected) => {
5
+ const arrSelected = Array.isArray(selected) ? selected : [selected];
6
+ const result = list?.filter(each => compareStrings(each.status, UNSUBSCRIBE_LIST_STATUS.ACTIVE) === 0 ||
7
+ arrSelected.includes(each.list_id)) || [];
8
+ return result;
9
+ };
10
+ export const unsubscribeListNotExist = (options, value) => {
11
+ // eslint-disable-next-line no-extra-boolean-cast
12
+ if (!!value) {
13
+ const selected = options?.find(item => compareStrings(item.list_id, value) === 0);
14
+ if (!selected) {
15
+ return `[ID - ${value}]`;
16
+ }
17
+ }
18
+ return value;
19
+ };
20
+ export const checkUnsubscribeList = ({ listUnsubscribe, unsubscribeId, }) => {
21
+ let errorMessage = '';
22
+ const listSelected = listUnsubscribe?.find(({ list_id }) => list_id === unsubscribeId);
23
+ if (listSelected) {
24
+ switch (listSelected.status) {
25
+ case UNSUBSCRIBE_LIST_STATUS.INACTIVE:
26
+ errorMessage = UNSUBSCRIBE_LIST_MESSAGE_ERRORS.DISABLED;
27
+ break;
28
+ default:
29
+ errorMessage = '';
30
+ break;
31
+ }
32
+ }
33
+ else {
34
+ errorMessage = UNSUBSCRIBE_LIST_MESSAGE_ERRORS.UNAUTHORIZED;
35
+ }
36
+ return { errorMessage };
37
+ };
38
+ export const buildOptionPreferencesList = (list, selected) => {
39
+ const arrSelected = Array.isArray(selected) ? selected : [selected];
40
+ const result = list
41
+ ?.filter(each => !arrSelected.includes(each.list_id) &&
42
+ [GLOBAL_UNSUBSCRIBED_LIST, GLOBAL_UNSUBSCRIBED_WHATSAPP].every(({ list_id }) => compareStrings(each.list_id, list_id) !== 0))
43
+ .map(each => {
44
+ let messageError;
45
+ if (compareStrings(each.status, UNSUBSCRIBE_LIST_STATUS.INACTIVE) === 0) {
46
+ messageError = UNSUBSCRIBE_LIST_MESSAGE_ERRORS.DISABLED;
47
+ }
48
+ return {
49
+ value: each.list_id,
50
+ label: each.list_name,
51
+ key: each.list_id,
52
+ errorMessage: messageError,
53
+ };
54
+ }) || [];
55
+ return result;
56
+ };
@@ -0,0 +1,12 @@
1
+ import React from 'react';
2
+ import { TUnsubscribePayloadInfo } from '@antscorp/antsomi-ui/es/services/Unsubscribe';
3
+ import { TUnsubscribeSettings, TUnsubscribeType } from '@antscorp/antsomi-ui/es';
4
+ interface PreferencesProps {
5
+ preferences: TUnsubscribeSettings['unsubscribePreferences'];
6
+ identifier: string[];
7
+ onOptOutAll?: () => void;
8
+ apiConfig: TUnsubscribePayloadInfo;
9
+ type: TUnsubscribeType;
10
+ }
11
+ export declare const Preferences: React.FC<PreferencesProps>;
12
+ export {};
@@ -0,0 +1,159 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // Libraries
3
+ import { useEffect, useMemo, useState } from 'react';
4
+ // Icons
5
+ import { DataIcon, UnsubscribeIcon } from '@antscorp/antsomi-ui/es/components/icons';
6
+ // Utils
7
+ import { maskEmail, maskPhone } from '../../utils';
8
+ import { compareStrings } from '@antscorp/antsomi-ui/es/utils';
9
+ // Queries
10
+ import { useGetUnsubscribeList } from '@antscorp/antsomi-ui/es/queries/Unsubscribe';
11
+ // Constants
12
+ import { UNSUBSCRIBE_LIST_STATUS } from '../../../UnsubscribePreferences/constants';
13
+ // Components
14
+ import { Button, EmptyData, Flex, Spin, Typography, } from '@antscorp/antsomi-ui/es';
15
+ import { TestAlert } from '../TestAlert';
16
+ import { CheckboxStyled, Description, Identifier, ListStyled, LogoContainer, LogoImg, Title, Wrapper, } from '../styled';
17
+ import { SpinContainer } from '../../styled';
18
+ export const Preferences = props => {
19
+ const { preferences, identifier, onOptOutAll, apiConfig, type } = props;
20
+ const identifierLabel = useMemo(() => {
21
+ switch (type) {
22
+ case 'sms':
23
+ case 'whatsapp':
24
+ return identifier.length > 1
25
+ ? identifier.map(item => maskPhone(item)).join(', ')
26
+ : maskPhone(identifier[0]);
27
+ default:
28
+ return identifier.length > 1
29
+ ? identifier.map(item => maskEmail(item)).join(', ')
30
+ : maskEmail(identifier[0]);
31
+ }
32
+ }, [type, identifier]);
33
+ const DESCRIPTION = {
34
+ email: 'Please check the types of emails you would like to receive. Uncheck any that you do not wish to subscribe to.',
35
+ sms: 'Select the SMS message types you wish to receive. Uncheck any to stop.',
36
+ whatsapp: 'Select the WhatsApp message types you wish to receive. Uncheck any to stop.',
37
+ };
38
+ const BTN_UNSUBSCRIBE_ALL = {
39
+ email: 'Unsubscribe from all emails',
40
+ sms: 'Unsubscribe from all messages',
41
+ whatsapp: 'Unsubscribe from all messages',
42
+ };
43
+ // Hooks
44
+ const { data: unsubscribeData, isLoading: isLoadingUnsubscribeList, isFetching: isFetchingUnsubscribeList, } = useGetUnsubscribeList({
45
+ args: {
46
+ data: {
47
+ type,
48
+ portalId: Number(apiConfig.portalId),
49
+ },
50
+ },
51
+ options: {
52
+ enabled: !!apiConfig.portalId,
53
+ },
54
+ }, apiConfig);
55
+ // Memo
56
+ const allUnsubscribeList = useMemo(() => unsubscribeData?.entries[0], [unsubscribeData]);
57
+ const preferencesUnsubscribeList = useMemo(() => {
58
+ if (!allUnsubscribeList)
59
+ return [];
60
+ // Lấy listId đang được chọn (mảng hoặc 1 id)
61
+ const prefIds = Array.isArray(preferences.preferenceListIds)
62
+ ? preferences.preferenceListIds
63
+ : preferences.preferenceListIds
64
+ ? [`${preferences.preferenceListIds}`]
65
+ : [];
66
+ // Lọc theo preferenceListIds
67
+ let filtered = allUnsubscribeList.filter(list => prefIds.includes(list.list_id) &&
68
+ compareStrings(list.status, UNSUBSCRIBE_LIST_STATUS.ACTIVE) === 0);
69
+ // Tìm thêm list theo unsubscribeListId
70
+ const unsubscribeItem = allUnsubscribeList.find(list => compareStrings(list.list_id, preferences.unsubscribeListId) === 0 &&
71
+ compareStrings(list.status, UNSUBSCRIBE_LIST_STATUS.ACTIVE) === 0);
72
+ // Nếu có và chưa nằm trong filtered thì thêm vào
73
+ if (unsubscribeItem && !filtered.some(l => l.list_id === unsubscribeItem.list_id)) {
74
+ filtered = [unsubscribeItem, ...filtered];
75
+ }
76
+ return filtered;
77
+ }, [allUnsubscribeList, preferences.preferenceListIds, preferences.unsubscribeListId]);
78
+ // States
79
+ const initialState = {
80
+ isUpdated: false,
81
+ isChanged: false,
82
+ };
83
+ const [preferenceList, setPreferenceList] = useState([]);
84
+ const [pageStatus, setPageStatus] = useState(initialState);
85
+ const { isUpdated, isChanged } = pageStatus;
86
+ // Effects
87
+ useEffect(() => {
88
+ // setState(prevState => ({
89
+ // ...prevState,
90
+ // preferenceList: [
91
+ // ...(preferencesUnsubscribeList || []),
92
+ // // ...(Array.isArray(allUnsubscribeList)
93
+ // // ? allUnsubscribeList?.filter(
94
+ // // list =>
95
+ // // (Array.isArray(preferences.preferenceListIds)
96
+ // // ? [...preferences.preferenceListIds]
97
+ // // : preferences.preferenceListIds
98
+ // // ? [`${preferences.preferenceListIds}`]
99
+ // // : []
100
+ // // )?.includes(list.list_id) &&
101
+ // // compareStrings(list.status, UNSUBSCRIBE_LIST_STATUS.ACTIVE) === 0,
102
+ // // )
103
+ // // : []),
104
+ // ],
105
+ // }));
106
+ setPreferenceList((preferencesUnsubscribeList || []).map(item => ({
107
+ ...item,
108
+ checked: true,
109
+ })));
110
+ }, [preferencesUnsubscribeList, allUnsubscribeList]);
111
+ const onChangeSelectPreference = (event, index) => {
112
+ const { checked } = event.target;
113
+ setPreferenceList(prev => prev.map((item, i) => (i === index ? { ...item, checked } : item)));
114
+ setPageStatus(prev => ({
115
+ ...prev,
116
+ isChanged: true,
117
+ }));
118
+ };
119
+ const onClickSavePreferences = () => {
120
+ // If already updated, do nothing
121
+ if (!isChanged) {
122
+ return;
123
+ }
124
+ const timeout = setTimeout(() => {
125
+ setPageStatus(prevState => ({ ...prevState, isUpdated: true }));
126
+ }, 1000);
127
+ setPageStatus(prevState => ({ ...prevState, isChanged: false }));
128
+ return () => clearTimeout(timeout);
129
+ };
130
+ const onClickOptOutAll = async () => {
131
+ onOptOutAll?.();
132
+ };
133
+ const renderPreferencesList = () => {
134
+ if (isLoadingUnsubscribeList || isFetchingUnsubscribeList) {
135
+ return (_jsx(SpinContainer, { children: _jsx(Spin, { spinning: true }) }));
136
+ }
137
+ return preferenceList?.length > 0 ? (preferenceList?.map((preference, index) => (_jsx(ListStyled.Item, { style: { gap: '9px' }, children: _jsxs(CheckboxStyled, { checked: preference?.checked, className: "ants-flex ants-self-start", onChange: event => onChangeSelectPreference(event, index), style: {
138
+ alignItems: 'flex-start',
139
+ }, children: [_jsx("div", { style: { width: '100%', fontSize: '12px' }, children: preference?.list_name }), _jsx(Typography.Paragraph, { style: { fontSize: '11px', color: '#595959', marginBottom: '0px' }, children: preference?.description })] }) }, preference?.list_id)))) : (_jsx(EmptyData, { style: { marginBottom: '10px' }, icon: _jsx(DataIcon, {}), size: "medium", title: "No data available" }));
140
+ };
141
+ const renderActions = () => {
142
+ if (!preferenceList?.length)
143
+ return null;
144
+ return (_jsxs(Flex, { justify: "space-between", align: "center", style: {
145
+ width: '100%',
146
+ fontSize: '12px',
147
+ paddingTop: 15,
148
+ borderTop: '1px solid #E5E5E5',
149
+ }, children: [_jsx(Button, { type: "primary", onClick: onClickSavePreferences, disabled: !isChanged, children: "Save preferences" }), _jsx(Button, { onClick: onClickOptOutAll, icon: _jsx(UnsubscribeIcon, { color: "#005EB8" }), disabled: preferenceList?.length === 0, children: BTN_UNSUBSCRIBE_ALL[type] })] }));
150
+ };
151
+ return (_jsxs(Wrapper, { children: [_jsx(LogoContainer, { children: _jsx(LogoImg, { src: preferences.logo, alt: "Antsomi Logo" }) }), _jsx(Identifier, { children: identifierLabel }), !isUpdated || isChanged ? (_jsx(Title, { children: "Communication Preference" })) : (_jsx(Title, { style: { color: '#12B800' }, children: "Communication Preferences Updated!" })), _jsx(Description, { style: {
152
+ marginBottom: preferences.haveResubscribeButton || preferenceList?.length > 0 ? '30px' : 0,
153
+ }, children: DESCRIPTION[type] }), _jsx(ListStyled, { style: {
154
+ maxHeight: '400px',
155
+ overflow: 'auto',
156
+ }, header: _jsx("span", {}), children: renderPreferencesList() }), renderActions(), !!preferenceList?.length && (_jsx(TestAlert, { type: type, style: {
157
+ marginTop: !preferences.haveResubscribeButton ? '30px' : '10px',
158
+ } }))] }));
159
+ };
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ import { RESULT_PAGE_TYPES } from '@antscorp/antsomi-ui/es/constants';
3
+ import { TUnsubscribeSettings, TUnsubscribeType } from '@antscorp/antsomi-ui/es/types';
4
+ type ResultPageType = (typeof RESULT_PAGE_TYPES)[keyof typeof RESULT_PAGE_TYPES];
5
+ interface ResultProps {
6
+ unsubscribeType: TUnsubscribeType;
7
+ type: ResultPageType;
8
+ preferences: TUnsubscribeSettings['unsubscribePreferences'];
9
+ identifier: string[];
10
+ onClickOptIn?: () => void;
11
+ }
12
+ export declare const Result: React.FC<ResultProps>;
13
+ export {};
@@ -0,0 +1,28 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // Libraries
3
+ import { useMemo } from 'react';
4
+ // Constants
5
+ import { RESULT_PAGE_TYPES, RESULT_PAGE_MESSAGES } from '@antscorp/antsomi-ui/es/constants';
6
+ // Utils
7
+ import { maskEmail, maskPhone } from '../../utils';
8
+ // Components
9
+ import { Button } from '@antscorp/antsomi-ui/es/components';
10
+ import { TestAlert } from '../TestAlert';
11
+ import { Description, Identifier, LogoContainer, LogoImg, TaskAltIconStyled, Title, Wrapper, } from '../styled';
12
+ export const Result = props => {
13
+ const { unsubscribeType, preferences, identifier, type, onClickOptIn } = props;
14
+ const identifierLabel = useMemo(() => {
15
+ switch (unsubscribeType) {
16
+ case 'sms':
17
+ case 'whatsapp':
18
+ return identifier.length > 1
19
+ ? identifier.map(item => maskPhone(item)).join(', ')
20
+ : maskPhone(identifier[0]);
21
+ default:
22
+ return identifier.length > 1
23
+ ? identifier.map(item => maskEmail(item)).join(', ')
24
+ : maskEmail(identifier[0]);
25
+ }
26
+ }, [unsubscribeType, identifier]);
27
+ return (_jsxs(Wrapper, { children: [_jsx(LogoContainer, { children: _jsx(LogoImg, { src: preferences.logo, alt: "Antsomi Logo" }) }), _jsx(Identifier, { style: { textAlign: 'center' }, children: identifierLabel }), _jsx(TaskAltIconStyled, { size: 100, color: "#005EB8", style: { margin: '0px auto 30px' } }), RESULT_PAGE_MESSAGES[type][unsubscribeType].title && (_jsx(Title, { children: RESULT_PAGE_MESSAGES[type][unsubscribeType].title })), _jsx(Description, { style: { marginBottom: 0, textAlign: 'center' }, children: RESULT_PAGE_MESSAGES[type][unsubscribeType].description || '' }), _jsx(TestAlert, { type: unsubscribeType, showIcon: false, justify: "center", className: "ants-text-center !ants-m-[-9px]", style: { margin: '15px 0px' } }), type === RESULT_PAGE_TYPES.OPT_OUT && (_jsx(Button, { style: { height: '30px', width: 'fit-content', margin: '0px auto' }, onClick: onClickOptIn, children: "Opt In + Restore Preferences" }))] }));
28
+ };
@@ -0,0 +1,9 @@
1
+ import React from 'react';
2
+ import { TUnsubscribeType } from '@antscorp/antsomi-ui/es/types';
3
+ import { FlexProps } from '@antscorp/antsomi-ui/es/components';
4
+ interface TestAlertProps extends Omit<FlexProps, 'children'> {
5
+ showIcon?: boolean;
6
+ type: TUnsubscribeType;
7
+ }
8
+ export declare const TestAlert: React.FC<TestAlertProps>;
9
+ export {};
@@ -0,0 +1,18 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // Libraries
3
+ import { memo } from 'react';
4
+ import classNames from 'classnames';
5
+ // Icons
6
+ import { ViewDetailsInformationIcon } from '@antscorp/antsomi-ui/es/components/icons';
7
+ // Components
8
+ import { Flex } from '@antscorp/antsomi-ui/es/components';
9
+ const TEXT_ALERT = {
10
+ email: 'Unsubscribers from emails are not recorded',
11
+ sms: 'Unsubscribers from SMS messages are not recorded',
12
+ whatsapp: 'Unsubscribers from test WhatsApp messages are not recorded',
13
+ };
14
+ export const TestAlert = memo(({ className, showIcon = true, type, ...props }) => (_jsxs(Flex, { className: classNames(className), gap: 6, align: "center", ...props, children: [showIcon && (_jsx(ViewDetailsInformationIcon, { color: "#005EB8", size: 24, className: "ants-text-primary" })), _jsx("span", { style: {
15
+ fontSize: 11,
16
+ color: '#7F7F7F',
17
+ }, children: TEXT_ALERT[type] })] })));
18
+ TestAlert.displayName = 'TestAlert';
@@ -0,0 +1,13 @@
1
+ import React from 'react';
2
+ import { TUnsubscribeSettings, TUnsubscribeType } from '@antscorp/antsomi-ui/es/types';
3
+ import { TUnsubscribePayloadInfo } from '@antscorp/antsomi-ui/es/services/Unsubscribe';
4
+ interface UnsubscribedProps {
5
+ preferences: TUnsubscribeSettings['unsubscribePreferences'];
6
+ identifier: string[];
7
+ onViewPreferences?: () => void;
8
+ onResubscribe?: () => void;
9
+ apiConfig: TUnsubscribePayloadInfo;
10
+ type: TUnsubscribeType;
11
+ }
12
+ export declare const Unsubscribed: React.FC<UnsubscribedProps>;
13
+ export {};
@@ -0,0 +1,85 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ // Libraries
3
+ import { useMemo } from 'react';
4
+ // Utils
5
+ import { maskEmail, maskPhone } from '../../utils';
6
+ import { compareStrings } from '@antscorp/antsomi-ui/es/utils';
7
+ // Constants
8
+ import { UNSUBSCRIBE_LIST_STATUS } from '../../../UnsubscribePreferences/constants';
9
+ import { GLOBAL_UNSUBSCRIBED_LIST, GLOBAL_UNSUBSCRIBED_WHATSAPP, } from '@antscorp/antsomi-ui/es/constants';
10
+ // Icons
11
+ import { DataIcon } from '@antscorp/antsomi-ui/es/components/icons';
12
+ // Queries
13
+ import { useGetUnsubscribeList } from '@antscorp/antsomi-ui/es/queries/Unsubscribe';
14
+ // Components
15
+ import { Button, EmptyData, Flex, Spin, Typography } from '@antscorp/antsomi-ui/es/components';
16
+ import { TestAlert } from '../TestAlert';
17
+ import { Description, Identifier, ListStyled, LogoContainer, LogoImg, Title, Wrapper, } from '../styled';
18
+ export const Unsubscribed = props => {
19
+ const { preferences, identifier, onViewPreferences, onResubscribe, apiConfig, type } = props;
20
+ // Hooks
21
+ const { data: unsubscribeData, isLoading: isLoadingUnsubscribe, isFetching: isFetchingUnsubscribeList, } = useGetUnsubscribeList({
22
+ args: {
23
+ data: {
24
+ type,
25
+ portalId: Number(apiConfig.portalId),
26
+ },
27
+ },
28
+ options: {
29
+ enabled: !!apiConfig.portalId,
30
+ },
31
+ }, apiConfig);
32
+ // Memo
33
+ const isGlobal = useMemo(() => [GLOBAL_UNSUBSCRIBED_LIST, GLOBAL_UNSUBSCRIBED_WHATSAPP].some(({ list_id }) => compareStrings(list_id, preferences.unsubscribeListId) === 0), [preferences.unsubscribeListId]);
34
+ const unsubscribeList = useMemo(() => {
35
+ const unsubscribeDataList = unsubscribeData?.entries[0];
36
+ return (unsubscribeDataList?.find(list => compareStrings(list.list_id, preferences.unsubscribeListId) === 0 &&
37
+ compareStrings(list.status, UNSUBSCRIBE_LIST_STATUS.ACTIVE) === 0) || null);
38
+ }, [unsubscribeData, preferences.unsubscribeListId]);
39
+ const identifierLabel = useMemo(() => {
40
+ switch (type) {
41
+ case 'sms':
42
+ case 'whatsapp':
43
+ return identifier.length > 1
44
+ ? identifier.map(item => maskPhone(item)).join(', ')
45
+ : maskPhone(identifier[0]);
46
+ default:
47
+ return identifier.length > 1
48
+ ? identifier.map(item => maskEmail(item)).join(', ')
49
+ : maskEmail(identifier[0]);
50
+ }
51
+ }, [type, identifier]);
52
+ // Handlers
53
+ const onClickResubscribe = async () => {
54
+ onResubscribe?.();
55
+ };
56
+ const renderUnsubscribedList = () => {
57
+ if (isLoadingUnsubscribe || isFetchingUnsubscribeList) {
58
+ if (isGlobal) {
59
+ return (_jsx("div", { className: "ants-absolute ants-inset-0 ants-h-full ants-top-0 ants-bottom-0 ants-flex ants-justify-center ants-items-center ants-bg-white/70 ants-z-10", children: _jsx(Spin, { spinning: true }) }));
60
+ }
61
+ return (_jsx("div", { className: "ants-my-5 ants-flex ants-justify-center", children: _jsx(Spin, { spinning: true }) }));
62
+ }
63
+ return isGlobal ? null : unsubscribeList ? (_jsx(ListStyled, { header: _jsx("span", {}), children: _jsxs(ListStyled.Item, { children: [_jsx("div", { style: { fontSize: 12 }, children: unsubscribeList?.list_name }), _jsx(Typography.Paragraph, { style: { fontSize: '11px', color: '#595959', marginBottom: '0px' }, children: unsubscribeList?.description })] }) })) : (_jsx(EmptyData, { icon: _jsx(DataIcon, {}), size: "medium", title: "No data available" }));
64
+ };
65
+ const renderActions = () => {
66
+ let actionItem = null;
67
+ if (!isGlobal) {
68
+ actionItem = (_jsx(Button, { type: "primary", className: "!ants-text-[12px] ants-p-2.5", onClick: onViewPreferences, disabled: isLoadingUnsubscribe, children: "View preferences" }));
69
+ }
70
+ if (isGlobal && preferences.haveResubscribeButton) {
71
+ actionItem = (_jsx(Button, { type: "primary", danger: true, className: "ants-color-primary !ants-text-[14px] !ants-p-2.5", onClick: onClickResubscribe, children: "Resubscribe" }));
72
+ }
73
+ if (actionItem) {
74
+ return (_jsx(Flex, { align: "center", justify: "center", style: {
75
+ paddingTop: 15,
76
+ borderTop: '1px solid #E5E5E5',
77
+ }, children: actionItem }));
78
+ }
79
+ };
80
+ return (_jsxs(Wrapper, { style: {
81
+ paddingBottom: isGlobal ? (!preferences.haveResubscribeButton ? '20px' : '10px') : '10px',
82
+ }, children: [_jsx(LogoContainer, { children: _jsx(LogoImg, { src: preferences.logo, alt: "Antsomi Logo" }) }), _jsx(Identifier, { children: identifierLabel }), _jsx(Title, { children: preferences.title }), _jsx(Description, { children: preferences.description }), renderUnsubscribedList(), renderActions(), _jsx(TestAlert, { type: type, showIcon: isGlobal && !preferences.haveResubscribeButton, justify: isGlobal && !preferences.haveResubscribeButton ? 'left' : 'center', style: {
83
+ marginTop: '10px',
84
+ } })] }));
85
+ };
@@ -0,0 +1,3 @@
1
+ export * from './UnsubscribedPage';
2
+ export * from './PreferencesPage';
3
+ export * from './ResultPage';
@@ -0,0 +1,3 @@
1
+ export * from './UnsubscribedPage';
2
+ export * from './PreferencesPage';
3
+ export * from './ResultPage';
@@ -0,0 +1,13 @@
1
+ /// <reference types="react" />
2
+ import { List } from 'antd';
3
+ export declare const Wrapper: import("styled-components").StyledComponent<"div", any, {}, never>;
4
+ export declare const LogoContainer: import("styled-components").StyledComponent<"div", any, {}, never>;
5
+ export declare const LogoImg: import("styled-components").StyledComponent<"img", any, {}, never>;
6
+ export declare const Identifier: import("styled-components").StyledComponent<"div", any, {}, never>;
7
+ export declare const Title: import("styled-components").StyledComponent<"div", any, {}, never>;
8
+ export declare const Description: import("styled-components").StyledComponent<"div", any, {}, never>;
9
+ export declare const ListStyled: import("styled-components").StyledComponent<typeof List, any, {}, never>;
10
+ export declare const TaskAltIconStyled: import("styled-components").StyledComponent<import("react").ForwardRefExoticComponent<import("../../../icons/types").IconProps & import("react").RefAttributes<SVGSVGElement>>, any, {}, never>;
11
+ export declare const CheckboxStyled: import("styled-components").StyledComponent<import("react").ForwardRefExoticComponent<import("antd").CheckboxProps & import("react").RefAttributes<import("rc-checkbox").CheckboxRef>> & {
12
+ Group: import("react").MemoExoticComponent<import("react").ForwardRefExoticComponent<import("antd/es/checkbox").CheckboxGroupProps & import("react").RefAttributes<HTMLDivElement>>>;
13
+ }, any, {}, never>;
@@ -0,0 +1,65 @@
1
+ import { Checkbox, List } from 'antd';
2
+ import styled from 'styled-components';
3
+ import { TaskAltIcon } from '../../../icons';
4
+ export const Wrapper = styled.div `
5
+ width: 550px;
6
+ display: flex;
7
+ flex-direction: column;
8
+ padding: 30px 20px;
9
+ `;
10
+ export const LogoContainer = styled.div `
11
+ display: flex;
12
+ justify-content: center;
13
+ margin-bottom: 30px;
14
+ `;
15
+ export const LogoImg = styled.img `
16
+ max-width: 60%;
17
+ `;
18
+ export const Identifier = styled.div `
19
+ font-size: 14px;
20
+ font-weight: 700;
21
+ margin-bottom: 15px;
22
+ `;
23
+ export const Title = styled.div `
24
+ font-size: 24px;
25
+ font-weight: 500;
26
+ margin-bottom: 15px;
27
+ text-align: center;
28
+ `;
29
+ export const Description = styled.div `
30
+ font-size: 14px;
31
+ font-weight: 400;
32
+ margin-bottom: 30px;
33
+ `;
34
+ export const ListStyled = styled(List) `
35
+ .antsomi-list-header {
36
+ padding-block: 0px !important;
37
+ border-color: #e5e5e5 !important;
38
+ }
39
+
40
+ .antsomi-list-item {
41
+ border-color: #e5e5e5 !important;
42
+ padding: 15px 0px;
43
+ display: flex;
44
+ flex-direction: column;
45
+ gap: 3px;
46
+ align-items: flex-start !important;
47
+ }
48
+ `;
49
+ export const TaskAltIconStyled = styled(TaskAltIcon) `
50
+ border-radius: 100%;
51
+ background-color: #c8cedb45;
52
+ padding: 20px;
53
+ margin-bottom: 30px;
54
+ `;
55
+ export const CheckboxStyled = styled(Checkbox) `
56
+ align-items: flex-start;
57
+
58
+ & .antsomi-checkbox {
59
+ align-self: auto !important;
60
+ }
61
+
62
+ & .antsomi-typography {
63
+ margin-bottom: 0px !important;
64
+ }
65
+ `;
@@ -0,0 +1,10 @@
1
+ import React from 'react';
2
+ import { TUnsubscribePayloadInfo } from '@antscorp/antsomi-ui/es/services/Unsubscribe';
3
+ import { TUnsubscribeSettings, TUnsubscribeType } from '@antscorp/antsomi-ui/es';
4
+ export type TUnsubscribePreviewProps = {
5
+ unsubscribePreferences: TUnsubscribeSettings['unsubscribePreferences'];
6
+ apiConfig: TUnsubscribePayloadInfo;
7
+ type: TUnsubscribeType;
8
+ identifier?: string[];
9
+ };
10
+ export declare const UnsubscribePreview: React.FC<TUnsubscribePreviewProps>;
@@ -0,0 +1,66 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ // Libraries
3
+ import { useEffect, useState } from 'react';
4
+ // Constants
5
+ import { LANDING_PAGE_TYPE, RESULT_PAGE_TYPES } from '@antscorp/antsomi-ui/es/constants';
6
+ import { LANDING_PAGE_TYPE as UNSUBSCRIBE_LANDING_PAGE_TYPE } from '../UnsubscribePreferences/constants';
7
+ // Components
8
+ import { Unsubscribed, Preferences, Result } from './components';
9
+ // Styles
10
+ import { UnsubscribeLandingPageWrapper } from './styled';
11
+ export const UnsubscribePreview = props => {
12
+ const { unsubscribePreferences, apiConfig, type, identifier = [] } = props;
13
+ const { landingPageType, customLink } = unsubscribePreferences || {};
14
+ // States
15
+ const initialState = {
16
+ page: LANDING_PAGE_TYPE.UNSUBSCRIBE,
17
+ resultPage: RESULT_PAGE_TYPES.RESUBSCRIBED,
18
+ };
19
+ const [state, setState] = useState(initialState);
20
+ const { page, resultPage } = state;
21
+ const onChangePage = (newPage) => {
22
+ setState(prevState => ({
23
+ ...prevState,
24
+ page: newPage,
25
+ }));
26
+ };
27
+ // Effects
28
+ useEffect(() => {
29
+ if (!apiConfig?.accountId)
30
+ return;
31
+ const updateAndRedirect = async () => {
32
+ window.location.replace(customLink || '');
33
+ };
34
+ if (landingPageType === UNSUBSCRIBE_LANDING_PAGE_TYPE.SPECIFIC_LINK.value) {
35
+ updateAndRedirect();
36
+ }
37
+ }, [landingPageType, apiConfig?.accountId, customLink]);
38
+ useEffect(() => {
39
+ onChangePage(LANDING_PAGE_TYPE.UNSUBSCRIBE);
40
+ }, [unsubscribePreferences]);
41
+ // Renders
42
+ const renderContent = () => {
43
+ if (landingPageType !== UNSUBSCRIBE_LANDING_PAGE_TYPE.SPECIFIC_LINK.value) {
44
+ switch (page) {
45
+ case LANDING_PAGE_TYPE.UNSUBSCRIBE:
46
+ return (_jsx(Unsubscribed, { preferences: unsubscribePreferences, identifier: identifier, onViewPreferences: () => onChangePage(LANDING_PAGE_TYPE.PREFERENCES), onResubscribe: () => {
47
+ onChangePage(LANDING_PAGE_TYPE.RESULT);
48
+ setState(prevState => ({
49
+ ...prevState,
50
+ resultPage: RESULT_PAGE_TYPES.RESUBSCRIBED,
51
+ }));
52
+ }, apiConfig: apiConfig, type: type }));
53
+ case LANDING_PAGE_TYPE.PREFERENCES:
54
+ return (_jsx(Preferences, { preferences: unsubscribePreferences, identifier: identifier, onOptOutAll: () => {
55
+ onChangePage(LANDING_PAGE_TYPE.RESULT);
56
+ setState(prevState => ({ ...prevState, resultPage: RESULT_PAGE_TYPES.OPT_OUT }));
57
+ }, apiConfig: apiConfig, type: type }));
58
+ case LANDING_PAGE_TYPE.RESULT:
59
+ return (_jsx(Result, { unsubscribeType: type, type: resultPage, preferences: unsubscribePreferences, identifier: identifier, onClickOptIn: () => onChangePage(LANDING_PAGE_TYPE.PREFERENCES) }));
60
+ default:
61
+ return null;
62
+ }
63
+ }
64
+ };
65
+ return (_jsx(UnsubscribeLandingPageWrapper, { className: "unsubscribe-preview", children: renderContent() }));
66
+ };
@@ -0,0 +1,9 @@
1
+ export declare const UnsubscribeLandingPageWrapper: import("styled-components").StyledComponent<"div", any, {}, never>;
2
+ export declare const SpinContainer: import("styled-components").StyledComponent<"div", any, {}, never>;
3
+ export declare const Wrapper: import("styled-components").StyledComponent<"div", any, {}, never>;
4
+ export declare const LogoContainer: import("styled-components").StyledComponent<"div", any, {}, never>;
5
+ export declare const Logo: import("styled-components").StyledComponent<"img", any, {}, never>;
6
+ export declare const Identifier: import("styled-components").StyledComponent<"div", any, {}, never>;
7
+ export declare const Title: import("styled-components").StyledComponent<"div", any, {}, never>;
8
+ export declare const Description: import("styled-components").StyledComponent<"div", any, {}, never>;
9
+ export declare const ButtonWrapper: import("styled-components").StyledComponent<"div", any, {}, never>;
@@ -0,0 +1,51 @@
1
+ // Libraries
2
+ import styled from 'styled-components';
3
+ export const UnsubscribeLandingPageWrapper = styled.div `
4
+ .antsomi-card-body {
5
+ padding: 0px !important;
6
+ }
7
+ .ant-list-item {
8
+ align-items: flex-start;
9
+ justify-content: flex-start;
10
+ }
11
+ `;
12
+ export const SpinContainer = styled.div `
13
+ width: 100%;
14
+ height: 100%;
15
+ display: flex;
16
+ justify-content: center;
17
+ align-items: center;
18
+ `;
19
+ export const Wrapper = styled.div `
20
+ padding: 30px 20px;
21
+
22
+ display: flex;
23
+ flex-direction: column;
24
+ `;
25
+ export const LogoContainer = styled.div `
26
+ display: flex;
27
+ justify-content: center;
28
+ width: 100%;
29
+ margin-bottom: 30px;
30
+ `;
31
+ export const Logo = styled.img `
32
+ width: 60%;
33
+ `;
34
+ export const Identifier = styled.div `
35
+ font-size: 14px;
36
+ font-weight: 700;
37
+ line-height: 1;
38
+ padding: 7px 0px;
39
+ `;
40
+ export const Title = styled.div `
41
+ font-size: 24px;
42
+ font-weight: 500;
43
+ `;
44
+ export const Description = styled.div `
45
+ font-size: 16px;
46
+ font-weight: 400;
47
+ `;
48
+ export const ButtonWrapper = styled.div `
49
+ padding-top: 15px;
50
+ border-top: 1px solid #e5e5e5;
51
+ `;
@@ -0,0 +1,5 @@
1
+ import { UNSUBSCRIBE_STATUS } from '@antscorp/antsomi-ui/es/constants';
2
+ export type UnsubscribeParams = {
3
+ unsubscribeId: string;
4
+ };
5
+ export type TUnsubscribeStatus = (typeof UNSUBSCRIBE_STATUS)[keyof typeof UNSUBSCRIBE_STATUS];
@@ -0,0 +1 @@
1
+ export {};