@redneckz/wildless-cms-uni-blocks 0.14.1021 → 0.14.1023
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.
- package/bundle/api/sendUserSurvey.d.ts +1 -0
- package/bundle/blocks.schema.json +1 -1
- package/bundle/bundle.umd.js +786 -745
- package/bundle/bundle.umd.min.js +1 -1
- package/bundle/components/ApplicationForm/handlers.d.ts +4 -3
- package/bundle/model/AspectsProps.d.ts +7 -1
- package/bundle/ui-kit/UserSurveyDialog/UserSurveyDialogContent.d.ts +4 -2
- package/bundle/ui-kit/UserSurveyDialog/useUserSurveyDialog.d.ts +1 -1
- package/dist/api/sendUserSurvey.d.ts +1 -0
- package/dist/api/sendUserSurvey.js.map +1 -1
- package/dist/components/ApplicationForm/ApplicationForm.js +3 -0
- package/dist/components/ApplicationForm/ApplicationForm.js.map +1 -1
- package/dist/components/ApplicationForm/handlers.d.ts +4 -3
- package/dist/components/ApplicationForm/handlers.js +9 -3
- package/dist/components/ApplicationForm/handlers.js.map +1 -1
- package/dist/components/ApplicationLeadForm/getLeadFormTaskData.js +3 -0
- package/dist/components/ApplicationLeadForm/getLeadFormTaskData.js.map +1 -1
- package/dist/components/DebitForm/DebitFormStatus.js +5 -1
- package/dist/components/DebitForm/DebitFormStatus.js.map +1 -1
- package/dist/model/AspectsProps.d.ts +7 -1
- package/dist/ui-kit/UserSurveyDialog/FirstStep.js +2 -2
- package/dist/ui-kit/UserSurveyDialog/FirstStep.js.map +1 -1
- package/dist/ui-kit/UserSurveyDialog/UserSurveyDialog.js +17 -2
- package/dist/ui-kit/UserSurveyDialog/UserSurveyDialog.js.map +1 -1
- package/dist/ui-kit/UserSurveyDialog/UserSurveyDialogContent.d.ts +4 -2
- package/dist/ui-kit/UserSurveyDialog/useUserSurveyDialog.d.ts +1 -1
- package/dist/ui-kit/UserSurveyDialog/useUserSurveyDialog.js +23 -11
- package/dist/ui-kit/UserSurveyDialog/useUserSurveyDialog.js.map +1 -1
- package/lib/api/sendUserSurvey.d.ts +1 -0
- package/lib/api/sendUserSurvey.js.map +1 -1
- package/lib/components/ApplicationForm/ApplicationForm.js +3 -0
- package/lib/components/ApplicationForm/ApplicationForm.js.map +1 -1
- package/lib/components/ApplicationForm/handlers.d.ts +4 -3
- package/lib/components/ApplicationForm/handlers.js +9 -3
- package/lib/components/ApplicationForm/handlers.js.map +1 -1
- package/lib/components/ApplicationLeadForm/getLeadFormTaskData.js +3 -0
- package/lib/components/ApplicationLeadForm/getLeadFormTaskData.js.map +1 -1
- package/lib/components/DebitForm/DebitFormStatus.js +5 -1
- package/lib/components/DebitForm/DebitFormStatus.js.map +1 -1
- package/lib/model/AspectsProps.d.ts +7 -1
- package/lib/ui-kit/UserSurveyDialog/FirstStep.js +2 -2
- package/lib/ui-kit/UserSurveyDialog/FirstStep.js.map +1 -1
- package/lib/ui-kit/UserSurveyDialog/UserSurveyDialog.js +17 -2
- package/lib/ui-kit/UserSurveyDialog/UserSurveyDialog.js.map +1 -1
- package/lib/ui-kit/UserSurveyDialog/UserSurveyDialogContent.d.ts +4 -2
- package/lib/ui-kit/UserSurveyDialog/useUserSurveyDialog.d.ts +1 -1
- package/lib/ui-kit/UserSurveyDialog/useUserSurveyDialog.js +24 -12
- package/lib/ui-kit/UserSurveyDialog/useUserSurveyDialog.js.map +1 -1
- package/mobile/bundle/api/sendUserSurvey.d.ts +1 -0
- package/mobile/bundle/bundle.umd.js +786 -745
- package/mobile/bundle/bundle.umd.min.js +1 -1
- package/mobile/bundle/components/ApplicationForm/handlers.d.ts +4 -3
- package/mobile/bundle/model/AspectsProps.d.ts +7 -1
- package/mobile/bundle/ui-kit/UserSurveyDialog/UserSurveyDialogContent.d.ts +4 -2
- package/mobile/bundle/ui-kit/UserSurveyDialog/useUserSurveyDialog.d.ts +1 -1
- package/mobile/dist/api/sendUserSurvey.d.ts +1 -0
- package/mobile/dist/api/sendUserSurvey.js.map +1 -1
- package/mobile/dist/components/ApplicationForm/ApplicationForm.js +3 -0
- package/mobile/dist/components/ApplicationForm/ApplicationForm.js.map +1 -1
- package/mobile/dist/components/ApplicationForm/handlers.d.ts +4 -3
- package/mobile/dist/components/ApplicationForm/handlers.js +9 -3
- package/mobile/dist/components/ApplicationForm/handlers.js.map +1 -1
- package/mobile/dist/components/ApplicationLeadForm/getLeadFormTaskData.js +3 -0
- package/mobile/dist/components/ApplicationLeadForm/getLeadFormTaskData.js.map +1 -1
- package/mobile/dist/components/DebitForm/DebitFormStatus.js +5 -1
- package/mobile/dist/components/DebitForm/DebitFormStatus.js.map +1 -1
- package/mobile/dist/model/AspectsProps.d.ts +7 -1
- package/mobile/dist/ui-kit/UserSurveyDialog/FirstStep.js +2 -2
- package/mobile/dist/ui-kit/UserSurveyDialog/FirstStep.js.map +1 -1
- package/mobile/dist/ui-kit/UserSurveyDialog/UserSurveyDialog.js +17 -2
- package/mobile/dist/ui-kit/UserSurveyDialog/UserSurveyDialog.js.map +1 -1
- package/mobile/dist/ui-kit/UserSurveyDialog/UserSurveyDialogContent.d.ts +4 -2
- package/mobile/dist/ui-kit/UserSurveyDialog/useUserSurveyDialog.d.ts +1 -1
- package/mobile/dist/ui-kit/UserSurveyDialog/useUserSurveyDialog.js +23 -11
- package/mobile/dist/ui-kit/UserSurveyDialog/useUserSurveyDialog.js.map +1 -1
- package/mobile/lib/api/sendUserSurvey.d.ts +1 -0
- package/mobile/lib/api/sendUserSurvey.js.map +1 -1
- package/mobile/lib/components/ApplicationForm/ApplicationForm.js +3 -0
- package/mobile/lib/components/ApplicationForm/ApplicationForm.js.map +1 -1
- package/mobile/lib/components/ApplicationForm/handlers.d.ts +4 -3
- package/mobile/lib/components/ApplicationForm/handlers.js +9 -3
- package/mobile/lib/components/ApplicationForm/handlers.js.map +1 -1
- package/mobile/lib/components/ApplicationLeadForm/getLeadFormTaskData.js +3 -0
- package/mobile/lib/components/ApplicationLeadForm/getLeadFormTaskData.js.map +1 -1
- package/mobile/lib/components/DebitForm/DebitFormStatus.js +5 -1
- package/mobile/lib/components/DebitForm/DebitFormStatus.js.map +1 -1
- package/mobile/lib/model/AspectsProps.d.ts +7 -1
- package/mobile/lib/ui-kit/UserSurveyDialog/FirstStep.js +2 -2
- package/mobile/lib/ui-kit/UserSurveyDialog/FirstStep.js.map +1 -1
- package/mobile/lib/ui-kit/UserSurveyDialog/UserSurveyDialog.js +17 -2
- package/mobile/lib/ui-kit/UserSurveyDialog/UserSurveyDialog.js.map +1 -1
- package/mobile/lib/ui-kit/UserSurveyDialog/UserSurveyDialogContent.d.ts +4 -2
- package/mobile/lib/ui-kit/UserSurveyDialog/useUserSurveyDialog.d.ts +1 -1
- package/mobile/lib/ui-kit/UserSurveyDialog/useUserSurveyDialog.js +24 -12
- package/mobile/lib/ui-kit/UserSurveyDialog/useUserSurveyDialog.js.map +1 -1
- package/mobile/src/api/sendUserSurvey.ts +1 -0
- package/mobile/src/components/ApplicationForm/ApplicationForm.tsx +3 -0
- package/mobile/src/components/ApplicationForm/handlers.ts +11 -0
- package/mobile/src/components/ApplicationLeadForm/getLeadFormTaskData.ts +3 -0
- package/mobile/src/components/DebitForm/DebitFormStatus.tsx +11 -5
- package/mobile/src/model/AspectsProps.ts +9 -1
- package/mobile/src/ui-kit/UserSurveyDialog/FirstStep.tsx +6 -2
- package/mobile/src/ui-kit/UserSurveyDialog/UserSurveyDialog.tsx +21 -2
- package/mobile/src/ui-kit/UserSurveyDialog/UserSurveyDialogContent.ts +5 -2
- package/mobile/src/ui-kit/UserSurveyDialog/useUserSurveyDialog.ts +30 -13
- package/package.json +1 -1
- package/src/api/sendUserSurvey.ts +1 -0
- package/src/components/ApplicationForm/ApplicationForm.tsx +3 -0
- package/src/components/ApplicationForm/handlers.ts +11 -0
- package/src/components/ApplicationLeadForm/getLeadFormTaskData.ts +3 -0
- package/src/components/DebitForm/DebitFormStatus.tsx +11 -5
- package/src/model/AspectsProps.ts +9 -1
- package/src/ui-kit/UserSurveyDialog/FirstStep.tsx +6 -2
- package/src/ui-kit/UserSurveyDialog/UserSurveyDialog.tsx +21 -2
- package/src/ui-kit/UserSurveyDialog/UserSurveyDialogContent.ts +5 -2
- package/src/ui-kit/UserSurveyDialog/useUserSurveyDialog.ts +30 -13
|
@@ -2,9 +2,11 @@ import { type JSONRefObject } from '../../data/JSONRefObject';
|
|
|
2
2
|
import { type OnCloseProps } from '../../model/OnCloseProps';
|
|
3
3
|
import { type UniBlockContent } from '../../UniBlock/UniBlockProps';
|
|
4
4
|
|
|
5
|
+
export type UserSurveyType = 'NPS' | 'CSI';
|
|
6
|
+
|
|
5
7
|
export type UserSurveyStoreSlice = {
|
|
6
8
|
userSurvey: {
|
|
7
|
-
lastShownType:
|
|
9
|
+
lastShownType: UserSurveyType;
|
|
8
10
|
nextDueAt: number;
|
|
9
11
|
};
|
|
10
12
|
};
|
|
@@ -18,7 +20,7 @@ export type StepProps = {
|
|
|
18
20
|
currentRating?: number;
|
|
19
21
|
currentReason?: Reason;
|
|
20
22
|
reasons?: Reason[];
|
|
21
|
-
surveyType:
|
|
23
|
+
surveyType: UserSurveyType;
|
|
22
24
|
isSending: boolean;
|
|
23
25
|
setCurrentReason: (value: Reason) => void;
|
|
24
26
|
setCurrentRating: (value: number) => void;
|
|
@@ -28,4 +30,5 @@ export type StepProps = {
|
|
|
28
30
|
|
|
29
31
|
export interface UserSurveyDialogContent extends OnCloseProps, UniBlockContent {
|
|
30
32
|
reasonsSource?: { reasons: Reason[] } | JSONRefObject;
|
|
33
|
+
isAfterTargetAction?: boolean;
|
|
31
34
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useEffect } from '@redneckz/uni-jsx/lib/hooks';
|
|
1
|
+
import { useCallback, useEffect } from '@redneckz/uni-jsx/lib/hooks';
|
|
2
2
|
import { useLocalStore } from '@redneckz/uni-jsx/lib/Store/useLocalStore';
|
|
3
3
|
import { useSessionStore } from '@redneckz/uni-jsx/lib/Store/useSessionStore';
|
|
4
4
|
import { noop } from '../../utils/noop';
|
|
@@ -10,47 +10,64 @@ const DELAY = 5 * 60 * 1000;
|
|
|
10
10
|
|
|
11
11
|
type SurveyTimerStore = {
|
|
12
12
|
surveyTimerStart: string;
|
|
13
|
+
surveyTimerId: NodeJS.Timeout;
|
|
14
|
+
isSurveySkipped: boolean;
|
|
13
15
|
};
|
|
14
16
|
|
|
15
17
|
// Хук отвечает за показ пользователю опроса
|
|
16
|
-
export const useUserSurveyDialog = () => {
|
|
18
|
+
export const useUserSurveyDialog = (withoutTimer?: boolean) => {
|
|
17
19
|
const userSurveyDialog = useDialog(UserSurveyDialog);
|
|
18
20
|
const userSurveyStore = useLocalStore<UserSurveyStoreSlice>();
|
|
19
21
|
const sessionStore = useSessionStore<SurveyTimerStore>();
|
|
22
|
+
const surveyTimer = sessionStore.surveyTimerId;
|
|
23
|
+
const isSurveySkipped = sessionStore.isSurveySkipped;
|
|
20
24
|
const elapsedTime = sessionStore.surveyTimerStart
|
|
21
25
|
? Date.now() - Number.parseInt(sessionStore.surveyTimerStart)
|
|
22
26
|
: 0;
|
|
27
|
+
const isShowSurvey =
|
|
28
|
+
!isSurveySkipped &&
|
|
29
|
+
(!userSurveyStore.userSurvey || userSurveyStore.userSurvey?.nextDueAt <= Date.now());
|
|
23
30
|
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
31
|
+
const handleCloseSurvey = useCallback(() => {
|
|
32
|
+
sessionStore.isSurveySkipped = true;
|
|
33
|
+
}, []);
|
|
34
|
+
|
|
35
|
+
const openUserSurveyDialog = useCallback((isAfterTargetAction?: boolean) => {
|
|
29
36
|
userSurveyDialog.open({
|
|
30
37
|
reasonsSource: {
|
|
31
38
|
$ref: '/wcms-resources/user-survey-reasons.json',
|
|
32
39
|
},
|
|
40
|
+
isAfterTargetAction,
|
|
41
|
+
onClose: handleCloseSurvey,
|
|
33
42
|
});
|
|
34
|
-
};
|
|
43
|
+
}, []);
|
|
44
|
+
|
|
45
|
+
const handleOpenSurveyAction = useCallback(() => {
|
|
46
|
+
if (isShowSurvey) {
|
|
47
|
+
surveyTimer && clearTimeout(surveyTimer);
|
|
48
|
+
openUserSurveyDialog(true);
|
|
49
|
+
}
|
|
50
|
+
}, [surveyTimer, isShowSurvey]);
|
|
35
51
|
|
|
36
52
|
useEffect(() => {
|
|
37
53
|
// Опрос показывается только если ранее пользоваютелю не показывался опрос или с того момента прошел месяц
|
|
38
|
-
if (!
|
|
54
|
+
if (!withoutTimer && isShowSurvey) {
|
|
39
55
|
// начинаем отсчитывать время от первого захода на сайт
|
|
40
56
|
if (!sessionStore.surveyTimerStart) {
|
|
41
57
|
sessionStore.surveyTimerStart = Date.now().toString();
|
|
42
58
|
}
|
|
43
59
|
// Опрос показывается спустя 5 минут нахождения на сайте
|
|
44
60
|
const timeout = setTimeout(openUserSurveyDialog, DELAY - elapsedTime);
|
|
61
|
+
sessionStore.surveyTimerId = timeout;
|
|
45
62
|
|
|
46
63
|
return () => {
|
|
47
64
|
clearTimeout(timeout);
|
|
65
|
+
sessionStore.surveyTimerId = null;
|
|
48
66
|
};
|
|
49
67
|
}
|
|
50
68
|
|
|
51
69
|
return noop;
|
|
52
|
-
}, []);
|
|
53
|
-
};
|
|
70
|
+
}, [isShowSurvey]);
|
|
54
71
|
|
|
55
|
-
|
|
56
|
-
|
|
72
|
+
return handleOpenSurveyAction;
|
|
73
|
+
};
|
package/package.json
CHANGED
|
@@ -8,6 +8,7 @@ import { getConsentDataProcessing } from '../../ui-kit/FormField/getConsentDataP
|
|
|
8
8
|
import { getFormValidator } from '../../ui-kit/FormField/getObjectValidator';
|
|
9
9
|
import { type PreventableEventWithTarget } from '../../ui-kit/PreventableEvent';
|
|
10
10
|
import { ResponseTypeDialog } from '../../ui-kit/ResponseTypeDialog/ResponseTypeDialog';
|
|
11
|
+
import { useUserSurveyDialog } from '../../ui-kit/UserSurveyDialog/useUserSurveyDialog';
|
|
11
12
|
import { UniBlock } from '../../UniBlock/UniBlock';
|
|
12
13
|
import { type UniBlockProps } from '../../UniBlock/UniBlockProps';
|
|
13
14
|
import { style } from '../../utils/style';
|
|
@@ -71,6 +72,7 @@ export const ApplicationForm = UniBlock<ApplicationFormProps>(
|
|
|
71
72
|
const formValidator = useMemo(() => getFormValidator(inputs), [inputs]);
|
|
72
73
|
const responseTypeDialog = useDialog(ResponseTypeDialog);
|
|
73
74
|
const verifyPhoneDialog = useDialog(VerifyPhoneDialog);
|
|
75
|
+
const openUserSurvey = useUserSurveyDialog(true);
|
|
74
76
|
|
|
75
77
|
const handleSubmit = useCallback(
|
|
76
78
|
async (formData: FormState, ev: PreventableEventWithTarget) => {
|
|
@@ -88,6 +90,7 @@ export const ApplicationForm = UniBlock<ApplicationFormProps>(
|
|
|
88
90
|
verifyPhoneDialog,
|
|
89
91
|
onSuccess,
|
|
90
92
|
withSnowplow,
|
|
93
|
+
openUserSurvey,
|
|
91
94
|
},
|
|
92
95
|
endpoint,
|
|
93
96
|
);
|
|
@@ -19,6 +19,7 @@ export type HandlerProps = {
|
|
|
19
19
|
verifyPhoneDialog?: any;
|
|
20
20
|
responseTypeDialog?: any;
|
|
21
21
|
onSuccess?: () => void;
|
|
22
|
+
openUserSurvey?: () => void;
|
|
22
23
|
withSnowplow?: boolean;
|
|
23
24
|
};
|
|
24
25
|
|
|
@@ -32,8 +33,10 @@ export const handleInitCorporateLead = async ({
|
|
|
32
33
|
data = [],
|
|
33
34
|
aspects = {},
|
|
34
35
|
ev,
|
|
36
|
+
openUserSurvey,
|
|
35
37
|
}: HandlerProps) => {
|
|
36
38
|
const { phone } = formatData;
|
|
39
|
+
const hasSurveyAspect = data?.find((_) => _.aspectName === 'openUserSurvey');
|
|
37
40
|
|
|
38
41
|
const response = await API.sendCode({ phone: String(phone) });
|
|
39
42
|
|
|
@@ -56,6 +59,7 @@ export const handleInitCorporateLead = async ({
|
|
|
56
59
|
id,
|
|
57
60
|
});
|
|
58
61
|
|
|
62
|
+
hasSurveyAspect && openUserSurvey?.();
|
|
59
63
|
handleAspects({
|
|
60
64
|
aspectsAttributes: getAspectsWithInclude(data, snowplowParams),
|
|
61
65
|
aspects,
|
|
@@ -74,13 +78,16 @@ export const handleCallback = async ({
|
|
|
74
78
|
responseTypeDialog,
|
|
75
79
|
onSuccess = noop,
|
|
76
80
|
endpoint,
|
|
81
|
+
openUserSurvey,
|
|
77
82
|
}: HandlerProps) => {
|
|
83
|
+
const hasSurveyAspect = data?.find((_) => _.aspectName === 'openUserSurvey');
|
|
78
84
|
const response = await API.sendPhoneCallRequest(formatData, endpoint);
|
|
79
85
|
|
|
80
86
|
onSuccess();
|
|
81
87
|
|
|
82
88
|
if (response?.status === 'success') {
|
|
83
89
|
responseTypeDialog.open({ ok: true, typeForm });
|
|
90
|
+
hasSurveyAspect && openUserSurvey?.();
|
|
84
91
|
handleAspects({ aspectsAttributes: data, aspects, ev });
|
|
85
92
|
} else if (response?.status === 'error') {
|
|
86
93
|
responseTypeDialog.open({
|
|
@@ -104,12 +111,16 @@ export const handleDefault = async ({
|
|
|
104
111
|
responseTypeDialog,
|
|
105
112
|
endpoint,
|
|
106
113
|
withSnowplow,
|
|
114
|
+
openUserSurvey,
|
|
107
115
|
}: HandlerProps) => {
|
|
116
|
+
const hasSurveyAspect = data?.find((_) => _.aspectName === 'openUserSurvey');
|
|
108
117
|
const response = await API.send({ body: formatData, router, endpoint });
|
|
109
118
|
const ok = Boolean(response);
|
|
110
119
|
|
|
111
120
|
responseTypeDialog.open({ ok });
|
|
121
|
+
|
|
112
122
|
if (ok) {
|
|
123
|
+
hasSurveyAspect && openUserSurvey?.();
|
|
113
124
|
const { requestId } = response;
|
|
114
125
|
const { phone } = formatData;
|
|
115
126
|
const utms = router.pathname.split('?')[1];
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { JSX } from '@redneckz/uni-jsx';
|
|
2
2
|
import type { DescriptionProps, LabelProps, TitleProps } from '../../model/HeadlineType';
|
|
3
3
|
import { BlockWrapper } from '../../ui-kit/BlockWrapper';
|
|
4
|
+
import { Button } from '../../ui-kit/Button/Button';
|
|
4
5
|
import { LinkButton } from '../../ui-kit/LinkButton/LinkButton';
|
|
5
6
|
import { Text } from '../../ui-kit/Text/Text';
|
|
6
7
|
import { type UniBlockProps } from '../../UniBlock/UniBlockProps';
|
|
@@ -19,6 +20,10 @@ type DebitFormStatusProps = UniBlockProps &
|
|
|
19
20
|
const INTERNET_BANK_LINK = 'https://online.rshb.ru/d?l=dcNqSvOE';
|
|
20
21
|
const PRELOGIN_LINK = 'https://online.rshb.ru/rshb-mbfl/webmodules/prelogin-zone';
|
|
21
22
|
|
|
23
|
+
const openLink = (url: string) => {
|
|
24
|
+
window.location.href = url;
|
|
25
|
+
};
|
|
26
|
+
|
|
22
27
|
export const DebitFormStatus = JSX<DebitFormStatusProps>(
|
|
23
28
|
({ title, description: dsc, sectionInfo, buttonText, isDboClient, isOffice, ...props }) => {
|
|
24
29
|
return (
|
|
@@ -36,12 +41,13 @@ export const DebitFormStatus = JSX<DebitFormStatusProps>(
|
|
|
36
41
|
<SectionInfo items={sectionInfo} />
|
|
37
42
|
{isOffice ? (
|
|
38
43
|
<div className="flex flex-col md:flex-row md:gap-lg">
|
|
39
|
-
<
|
|
40
|
-
|
|
41
|
-
text="Узнать статус заявки"
|
|
42
|
-
version="primary"
|
|
44
|
+
<Button
|
|
45
|
+
onClick={() => openLink(PRELOGIN_LINK)}
|
|
43
46
|
className="w-full mt-lg"
|
|
44
|
-
|
|
47
|
+
version="primary"
|
|
48
|
+
>
|
|
49
|
+
Узнать статус заявки
|
|
50
|
+
</Button>
|
|
45
51
|
<LinkButton
|
|
46
52
|
href="/natural"
|
|
47
53
|
text="Вернуться на главную"
|
|
@@ -35,6 +35,13 @@ export type ChatBotAspect = {
|
|
|
35
35
|
aspectName: 'openChatBot';
|
|
36
36
|
};
|
|
37
37
|
|
|
38
|
+
/**
|
|
39
|
+
* @title Отправить опрос пользователю
|
|
40
|
+
*/
|
|
41
|
+
export type UserSurveyAspect = {
|
|
42
|
+
aspectName: 'openUserSurvey';
|
|
43
|
+
};
|
|
44
|
+
|
|
38
45
|
/**
|
|
39
46
|
* @title Отправить событие партнёру
|
|
40
47
|
* @default {"aspectName": "partnersEvent", "params": {"partner": "", "typeAction": "targetaction"}}
|
|
@@ -62,7 +69,8 @@ export type AspectsDef =
|
|
|
62
69
|
| YandexReachGoalAspect
|
|
63
70
|
| MindboxEventAspect
|
|
64
71
|
| SnowplowEventAspect
|
|
65
|
-
| PartnersEventAspect
|
|
72
|
+
| PartnersEventAspect
|
|
73
|
+
| UserSurveyAspect;
|
|
66
74
|
|
|
67
75
|
export type AspectsProps = {
|
|
68
76
|
/** @title Дополнительные атрибуты */
|
|
@@ -8,7 +8,7 @@ import { type StepProps } from './UserSurveyDialogContent';
|
|
|
8
8
|
const stars = new Array(5).fill(Star);
|
|
9
9
|
|
|
10
10
|
const TITLE = {
|
|
11
|
-
NPS: 'Оцените, пожалуйста, от 1 до 5
|
|
11
|
+
NPS: 'Оцените, пожалуйста, от 1 до 5,\nнасколько вероятно, что вы порекомендуете Россельхозбанк коллегам, друзьям и знакомым?',
|
|
12
12
|
CSI: 'Оцените, пожалуйста, удовлетворённость пользования сайтом',
|
|
13
13
|
};
|
|
14
14
|
|
|
@@ -25,7 +25,11 @@ export const FirstStep = JSX<StepProps>(
|
|
|
25
25
|
|
|
26
26
|
return (
|
|
27
27
|
<div className="flex flex-col gap-xl items-center">
|
|
28
|
-
<Heading
|
|
28
|
+
<Heading
|
|
29
|
+
className="text-center whitespace-pre-line"
|
|
30
|
+
headingType="h5"
|
|
31
|
+
title={TITLE[surveyType]}
|
|
32
|
+
/>
|
|
29
33
|
<div className="flex justify-center">
|
|
30
34
|
{stars.map((StarItem, index) => (
|
|
31
35
|
<StarItem
|
|
@@ -12,6 +12,7 @@ import {
|
|
|
12
12
|
type Reason,
|
|
13
13
|
type UserSurveyDialogContent,
|
|
14
14
|
type UserSurveyStoreSlice,
|
|
15
|
+
type UserSurveyType,
|
|
15
16
|
} from './UserSurveyDialogContent';
|
|
16
17
|
|
|
17
18
|
export type UserSurveyDialogProps = UserSurveyDialogContent;
|
|
@@ -20,13 +21,13 @@ const STEPS = [FirstStep, SecondStep, FinalStep];
|
|
|
20
21
|
const LAST_STEP_INDEX = 2;
|
|
21
22
|
|
|
22
23
|
export const UserSurveyDialog = UniBlock<UserSurveyDialogProps>(
|
|
23
|
-
({ onClose = noop, reasonsSource = {} }) => {
|
|
24
|
+
({ onClose = noop, isAfterTargetAction = false, reasonsSource = {} }) => {
|
|
24
25
|
const [isSending, { setTrue: startSending, setFalse: endSending }] = useBool(false);
|
|
25
26
|
const [currentRating, setCurrentRating] = useState<number>(0);
|
|
26
27
|
const [currentReason, setCurrentReason] = useState<Reason>();
|
|
27
28
|
const [step, setStep] = useState<number>(0);
|
|
28
29
|
const userSurveyStore = useLocalStore<UserSurveyStoreSlice>();
|
|
29
|
-
const surveyType = userSurveyStore.userSurvey?.lastShownType
|
|
30
|
+
const surveyType = getUserSurveyType(userSurveyStore.userSurvey?.lastShownType);
|
|
30
31
|
|
|
31
32
|
const { reasons } = reasonsSource as { reasons: Reason[] };
|
|
32
33
|
|
|
@@ -46,8 +47,13 @@ export const UserSurveyDialog = UniBlock<UserSurveyDialogProps>(
|
|
|
46
47
|
message: getMessage(currentReason, message),
|
|
47
48
|
url: globalThis.location.href,
|
|
48
49
|
type: surveyType,
|
|
50
|
+
ip: isAfterTargetAction ? 'after_target_action' : 'time_on_site',
|
|
49
51
|
});
|
|
50
52
|
endSending();
|
|
53
|
+
userSurveyStore.userSurvey = {
|
|
54
|
+
lastShownType: surveyType,
|
|
55
|
+
nextDueAt: getTimeAfter30days(),
|
|
56
|
+
};
|
|
51
57
|
setStep(LAST_STEP_INDEX);
|
|
52
58
|
},
|
|
53
59
|
[currentRating, currentReason],
|
|
@@ -78,3 +84,16 @@ const getMessage = (currentReason?: Reason, message?: string) => {
|
|
|
78
84
|
|
|
79
85
|
return message?.length ? message : 'Другое. Клиент не оставил комментариев';
|
|
80
86
|
};
|
|
87
|
+
|
|
88
|
+
// Отсчитываем месяц с текущей даты
|
|
89
|
+
const getTimeAfter30days = () => Date.now() + 30 * 24 * 60 * 60 * 1000;
|
|
90
|
+
|
|
91
|
+
// Если пользователь проходил опрос то показываем другой, иначе показываем случайный тип опроса
|
|
92
|
+
const getUserSurveyType = (lastShownType?: UserSurveyType) => {
|
|
93
|
+
console.log('Расчитал');
|
|
94
|
+
if (lastShownType) {
|
|
95
|
+
return lastShownType === 'NPS' ? 'CSI' : 'NPS';
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
return ['NPS', 'CSI'][Date.now() % 2] as UserSurveyType;
|
|
99
|
+
};
|
|
@@ -2,9 +2,11 @@ import { type JSONRefObject } from '../../data/JSONRefObject';
|
|
|
2
2
|
import { type OnCloseProps } from '../../model/OnCloseProps';
|
|
3
3
|
import { type UniBlockContent } from '../../UniBlock/UniBlockProps';
|
|
4
4
|
|
|
5
|
+
export type UserSurveyType = 'NPS' | 'CSI';
|
|
6
|
+
|
|
5
7
|
export type UserSurveyStoreSlice = {
|
|
6
8
|
userSurvey: {
|
|
7
|
-
lastShownType:
|
|
9
|
+
lastShownType: UserSurveyType;
|
|
8
10
|
nextDueAt: number;
|
|
9
11
|
};
|
|
10
12
|
};
|
|
@@ -18,7 +20,7 @@ export type StepProps = {
|
|
|
18
20
|
currentRating?: number;
|
|
19
21
|
currentReason?: Reason;
|
|
20
22
|
reasons?: Reason[];
|
|
21
|
-
surveyType:
|
|
23
|
+
surveyType: UserSurveyType;
|
|
22
24
|
isSending: boolean;
|
|
23
25
|
setCurrentReason: (value: Reason) => void;
|
|
24
26
|
setCurrentRating: (value: number) => void;
|
|
@@ -28,4 +30,5 @@ export type StepProps = {
|
|
|
28
30
|
|
|
29
31
|
export interface UserSurveyDialogContent extends OnCloseProps, UniBlockContent {
|
|
30
32
|
reasonsSource?: { reasons: Reason[] } | JSONRefObject;
|
|
33
|
+
isAfterTargetAction?: boolean;
|
|
31
34
|
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { useEffect } from '@redneckz/uni-jsx/lib/hooks';
|
|
1
|
+
import { useCallback, useEffect } from '@redneckz/uni-jsx/lib/hooks';
|
|
2
2
|
import { useLocalStore } from '@redneckz/uni-jsx/lib/Store/useLocalStore';
|
|
3
3
|
import { useSessionStore } from '@redneckz/uni-jsx/lib/Store/useSessionStore';
|
|
4
4
|
import { noop } from '../../utils/noop';
|
|
@@ -10,47 +10,64 @@ const DELAY = 5 * 60 * 1000;
|
|
|
10
10
|
|
|
11
11
|
type SurveyTimerStore = {
|
|
12
12
|
surveyTimerStart: string;
|
|
13
|
+
surveyTimerId: NodeJS.Timeout;
|
|
14
|
+
isSurveySkipped: boolean;
|
|
13
15
|
};
|
|
14
16
|
|
|
15
17
|
// Хук отвечает за показ пользователю опроса
|
|
16
|
-
export const useUserSurveyDialog = () => {
|
|
18
|
+
export const useUserSurveyDialog = (withoutTimer?: boolean) => {
|
|
17
19
|
const userSurveyDialog = useDialog(UserSurveyDialog);
|
|
18
20
|
const userSurveyStore = useLocalStore<UserSurveyStoreSlice>();
|
|
19
21
|
const sessionStore = useSessionStore<SurveyTimerStore>();
|
|
22
|
+
const surveyTimer = sessionStore.surveyTimerId;
|
|
23
|
+
const isSurveySkipped = sessionStore.isSurveySkipped;
|
|
20
24
|
const elapsedTime = sessionStore.surveyTimerStart
|
|
21
25
|
? Date.now() - Number.parseInt(sessionStore.surveyTimerStart)
|
|
22
26
|
: 0;
|
|
27
|
+
const isShowSurvey =
|
|
28
|
+
!isSurveySkipped &&
|
|
29
|
+
(!userSurveyStore.userSurvey || userSurveyStore.userSurvey?.nextDueAt <= Date.now());
|
|
23
30
|
|
|
24
|
-
const
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
31
|
+
const handleCloseSurvey = useCallback(() => {
|
|
32
|
+
sessionStore.isSurveySkipped = true;
|
|
33
|
+
}, []);
|
|
34
|
+
|
|
35
|
+
const openUserSurveyDialog = useCallback((isAfterTargetAction?: boolean) => {
|
|
29
36
|
userSurveyDialog.open({
|
|
30
37
|
reasonsSource: {
|
|
31
38
|
$ref: '/wcms-resources/user-survey-reasons.json',
|
|
32
39
|
},
|
|
40
|
+
isAfterTargetAction,
|
|
41
|
+
onClose: handleCloseSurvey,
|
|
33
42
|
});
|
|
34
|
-
};
|
|
43
|
+
}, []);
|
|
44
|
+
|
|
45
|
+
const handleOpenSurveyAction = useCallback(() => {
|
|
46
|
+
if (isShowSurvey) {
|
|
47
|
+
surveyTimer && clearTimeout(surveyTimer);
|
|
48
|
+
openUserSurveyDialog(true);
|
|
49
|
+
}
|
|
50
|
+
}, [surveyTimer, isShowSurvey]);
|
|
35
51
|
|
|
36
52
|
useEffect(() => {
|
|
37
53
|
// Опрос показывается только если ранее пользоваютелю не показывался опрос или с того момента прошел месяц
|
|
38
|
-
if (!
|
|
54
|
+
if (!withoutTimer && isShowSurvey) {
|
|
39
55
|
// начинаем отсчитывать время от первого захода на сайт
|
|
40
56
|
if (!sessionStore.surveyTimerStart) {
|
|
41
57
|
sessionStore.surveyTimerStart = Date.now().toString();
|
|
42
58
|
}
|
|
43
59
|
// Опрос показывается спустя 5 минут нахождения на сайте
|
|
44
60
|
const timeout = setTimeout(openUserSurveyDialog, DELAY - elapsedTime);
|
|
61
|
+
sessionStore.surveyTimerId = timeout;
|
|
45
62
|
|
|
46
63
|
return () => {
|
|
47
64
|
clearTimeout(timeout);
|
|
65
|
+
sessionStore.surveyTimerId = null;
|
|
48
66
|
};
|
|
49
67
|
}
|
|
50
68
|
|
|
51
69
|
return noop;
|
|
52
|
-
}, []);
|
|
53
|
-
};
|
|
70
|
+
}, [isShowSurvey]);
|
|
54
71
|
|
|
55
|
-
|
|
56
|
-
|
|
72
|
+
return handleOpenSurveyAction;
|
|
73
|
+
};
|