@redneckz/wildless-cms-uni-blocks 0.14.1022 → 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 +781 -746
- 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/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/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 +781 -746
- 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/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/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/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/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
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"FirstStep.js","sourceRoot":"","sources":["../../../src/ui-kit/UserSurveyDialog/FirstStep.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAChE,OAAO,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAC;AACvD,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAG9B,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEtC,MAAM,KAAK,GAAG;IACZ,GAAG,EAAE,
|
|
1
|
+
{"version":3,"file":"FirstStep.js","sourceRoot":"","sources":["../../../src/ui-kit/UserSurveyDialog/FirstStep.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AACxC,OAAO,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AACvD,OAAO,EAAE,YAAY,EAAE,MAAM,kCAAkC,CAAC;AAChE,OAAO,EAAE,OAAO,EAAE,MAAM,8BAA8B,CAAC;AACvD,OAAO,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAC;AAG9B,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAEtC,MAAM,KAAK,GAAG;IACZ,GAAG,EAAE,yHAAyH;IAC9H,GAAG,EAAE,2DAA2D;CACjE,CAAC;AAEF,MAAM,CAAC,MAAM,SAAS,GAAG,GAAG,CAC1B,CAAC,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,gBAAgB,EAAE,UAAU,EAAE,QAAQ,EAAE,EAAE,EAAE;IACnF,MAAM,CAAC,YAAY,EAAE,eAAe,CAAC,GAAG,QAAQ,EAAU,CAAC;IAE3D,MAAM,WAAW,GAAG,CAAC,KAAa,EAAQ,EAAE;QAC1C,gBAAgB,CAAC,KAAK,CAAC,CAAC;QACxB,IAAI,KAAK,GAAG,CAAC,EAAE;YACb,UAAU,EAAE,CAAC;SACd;IACH,CAAC,CAAC;IAEF,OAAO,CACL,eAAK,SAAS,EAAC,mCAAmC,aAChD,KAAC,OAAO,IACN,SAAS,EAAC,iCAAiC,EAC3C,WAAW,EAAC,IAAI,EAChB,KAAK,EAAE,KAAK,CAAC,UAAU,CAAC,GACxB,EACF,cAAK,SAAS,EAAC,qBAAqB,YACjC,KAAK,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE,CAAC,CAC9B,KAAC,QAAQ,IAEP,KAAK,EAAE,KAAK,GAAG,CAAC,EAChB,MAAM,EAAE,aAAa,EACrB,KAAK,EAAE,YAAY,EACnB,SAAS,EAAE,WAAW,EACtB,QAAQ,EAAE,eAAe,EACzB,SAAS,EAAC,sBAAsB,IAN3B,KAAK,CAOV,CACH,CAAC,GACE,EACL,aAAa,KAAK,CAAC,CAAC,CAAC,CAAC,CACrB,KAAC,YAAY,IAAC,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,SAAS,uEAE9C,CAChB,CAAC,CAAC,CAAC,IAAI,IACJ,CACP,CAAC;AACJ,CAAC,CACF,CAAC"}
|
|
@@ -11,13 +11,13 @@ import { FirstStep } from './FirstStep.js';
|
|
|
11
11
|
import { SecondStep } from './SecondStep.js';
|
|
12
12
|
const STEPS = [FirstStep, SecondStep, FinalStep];
|
|
13
13
|
const LAST_STEP_INDEX = 2;
|
|
14
|
-
export const UserSurveyDialog = UniBlock(({ onClose = noop, reasonsSource = {} }) => {
|
|
14
|
+
export const UserSurveyDialog = UniBlock(({ onClose = noop, isAfterTargetAction = false, reasonsSource = {} }) => {
|
|
15
15
|
const [isSending, { setTrue: startSending, setFalse: endSending }] = useBool(false);
|
|
16
16
|
const [currentRating, setCurrentRating] = useState(0);
|
|
17
17
|
const [currentReason, setCurrentReason] = useState();
|
|
18
18
|
const [step, setStep] = useState(0);
|
|
19
19
|
const userSurveyStore = useLocalStore();
|
|
20
|
-
const surveyType = userSurveyStore.userSurvey?.lastShownType
|
|
20
|
+
const surveyType = getUserSurveyType(userSurveyStore.userSurvey?.lastShownType);
|
|
21
21
|
const { reasons } = reasonsSource;
|
|
22
22
|
const ActiveStep = STEPS[step];
|
|
23
23
|
const handleNextStep = useCallback(() => {
|
|
@@ -31,8 +31,13 @@ export const UserSurveyDialog = UniBlock(({ onClose = noop, reasonsSource = {} }
|
|
|
31
31
|
message: getMessage(currentReason, message),
|
|
32
32
|
url: globalThis.location.href,
|
|
33
33
|
type: surveyType,
|
|
34
|
+
ip: isAfterTargetAction ? 'after_target_action' : 'time_on_site',
|
|
34
35
|
});
|
|
35
36
|
endSending();
|
|
37
|
+
userSurveyStore.userSurvey = {
|
|
38
|
+
lastShownType: surveyType,
|
|
39
|
+
nextDueAt: getTimeAfter30days(),
|
|
40
|
+
};
|
|
36
41
|
setStep(LAST_STEP_INDEX);
|
|
37
42
|
}, [currentRating, currentReason]);
|
|
38
43
|
return (_jsx(Dialog, { maxWidth: "xl", onClose: onClose, children: _jsx(ActiveStep, { currentRating: currentRating, currentReason: currentReason, reasons: reasons, surveyType: surveyType, isSending: isSending, setCurrentReason: setCurrentReason, setCurrentRating: setCurrentRating, onSubmit: handleSubmit, onNextStep: handleNextStep }) }));
|
|
@@ -43,4 +48,14 @@ const getMessage = (currentReason, message) => {
|
|
|
43
48
|
}
|
|
44
49
|
return message?.length ? message : 'Другое. Клиент не оставил комментариев';
|
|
45
50
|
};
|
|
51
|
+
// Отсчитываем месяц с текущей даты
|
|
52
|
+
const getTimeAfter30days = () => Date.now() + 30 * 24 * 60 * 60 * 1000;
|
|
53
|
+
// Если пользователь проходил опрос то показываем другой, иначе показываем случайный тип опроса
|
|
54
|
+
const getUserSurveyType = (lastShownType) => {
|
|
55
|
+
console.log('Расчитал');
|
|
56
|
+
if (lastShownType) {
|
|
57
|
+
return lastShownType === 'NPS' ? 'CSI' : 'NPS';
|
|
58
|
+
}
|
|
59
|
+
return ['NPS', 'CSI'][Date.now() % 2];
|
|
60
|
+
};
|
|
46
61
|
//# sourceMappingURL=UserSurveyDialog.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"UserSurveyDialog.js","sourceRoot":"","sources":["../../../src/ui-kit/UserSurveyDialog/UserSurveyDialog.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,6BAA6B,CAAC;AACpE,OAAO,EAAE,OAAO,EAAE,MAAM,qCAAqC,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,MAAM,2CAA2C,CAAC;AAC1E,OAAO,EAAE,cAAc,EAAE,MAAM,0BAA0B,CAAC;AAC1D,OAAO,EAAE,MAAM,EAAE,MAAM,mCAAmC,CAAC;AAC3D,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AACxC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"UserSurveyDialog.js","sourceRoot":"","sources":["../../../src/ui-kit/UserSurveyDialog/UserSurveyDialog.tsx"],"names":[],"mappings":"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"}
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { type JSONRefObject } from '../../data/JSONRefObject';
|
|
2
2
|
import { type OnCloseProps } from '../../model/OnCloseProps';
|
|
3
3
|
import { type UniBlockContent } from '../../UniBlock/UniBlockProps';
|
|
4
|
+
export declare type UserSurveyType = 'NPS' | 'CSI';
|
|
4
5
|
export declare type UserSurveyStoreSlice = {
|
|
5
6
|
userSurvey: {
|
|
6
|
-
lastShownType:
|
|
7
|
+
lastShownType: UserSurveyType;
|
|
7
8
|
nextDueAt: number;
|
|
8
9
|
};
|
|
9
10
|
};
|
|
@@ -15,7 +16,7 @@ export declare type StepProps = {
|
|
|
15
16
|
currentRating?: number;
|
|
16
17
|
currentReason?: Reason;
|
|
17
18
|
reasons?: Reason[];
|
|
18
|
-
surveyType:
|
|
19
|
+
surveyType: UserSurveyType;
|
|
19
20
|
isSending: boolean;
|
|
20
21
|
setCurrentReason: (value: Reason) => void;
|
|
21
22
|
setCurrentRating: (value: number) => void;
|
|
@@ -26,4 +27,5 @@ export interface UserSurveyDialogContent extends OnCloseProps, UniBlockContent {
|
|
|
26
27
|
reasonsSource?: {
|
|
27
28
|
reasons: Reason[];
|
|
28
29
|
} | JSONRefObject;
|
|
30
|
+
isAfterTargetAction?: boolean;
|
|
29
31
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const useUserSurveyDialog: () => void;
|
|
1
|
+
export declare const useUserSurveyDialog: (withoutTimer?: boolean) => () => void;
|
|
@@ -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.js';
|
|
@@ -6,40 +6,52 @@ import { useDialog } from '../DialogManager/useDialog.js';
|
|
|
6
6
|
import { UserSurveyDialog } from './UserSurveyDialog.js';
|
|
7
7
|
const DELAY = 5 * 60 * 1000;
|
|
8
8
|
// Хук отвечает за показ пользователю опроса
|
|
9
|
-
export const useUserSurveyDialog = () => {
|
|
9
|
+
export const useUserSurveyDialog = (withoutTimer) => {
|
|
10
10
|
const userSurveyDialog = useDialog(UserSurveyDialog);
|
|
11
11
|
const userSurveyStore = useLocalStore();
|
|
12
12
|
const sessionStore = useSessionStore();
|
|
13
|
+
const surveyTimer = sessionStore.surveyTimerId;
|
|
14
|
+
const isSurveySkipped = sessionStore.isSurveySkipped;
|
|
13
15
|
const elapsedTime = sessionStore.surveyTimerStart
|
|
14
16
|
? Date.now() - Number.parseInt(sessionStore.surveyTimerStart)
|
|
15
17
|
: 0;
|
|
16
|
-
const
|
|
17
|
-
userSurveyStore.userSurvey
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
const isShowSurvey = !isSurveySkipped &&
|
|
19
|
+
(!userSurveyStore.userSurvey || userSurveyStore.userSurvey?.nextDueAt <= Date.now());
|
|
20
|
+
const handleCloseSurvey = useCallback(() => {
|
|
21
|
+
sessionStore.isSurveySkipped = true;
|
|
22
|
+
}, []);
|
|
23
|
+
const openUserSurveyDialog = useCallback((isAfterTargetAction) => {
|
|
21
24
|
userSurveyDialog.open({
|
|
22
25
|
reasonsSource: {
|
|
23
26
|
$ref: '/wcms-resources/user-survey-reasons.json',
|
|
24
27
|
},
|
|
28
|
+
isAfterTargetAction,
|
|
29
|
+
onClose: handleCloseSurvey,
|
|
25
30
|
});
|
|
26
|
-
};
|
|
31
|
+
}, []);
|
|
32
|
+
const handleOpenSurveyAction = useCallback(() => {
|
|
33
|
+
if (isShowSurvey) {
|
|
34
|
+
surveyTimer && clearTimeout(surveyTimer);
|
|
35
|
+
openUserSurveyDialog(true);
|
|
36
|
+
}
|
|
37
|
+
}, [surveyTimer, isShowSurvey]);
|
|
27
38
|
useEffect(() => {
|
|
28
39
|
// Опрос показывается только если ранее пользоваютелю не показывался опрос или с того момента прошел месяц
|
|
29
|
-
if (!
|
|
40
|
+
if (!withoutTimer && isShowSurvey) {
|
|
30
41
|
// начинаем отсчитывать время от первого захода на сайт
|
|
31
42
|
if (!sessionStore.surveyTimerStart) {
|
|
32
43
|
sessionStore.surveyTimerStart = Date.now().toString();
|
|
33
44
|
}
|
|
34
45
|
// Опрос показывается спустя 5 минут нахождения на сайте
|
|
35
46
|
const timeout = setTimeout(openUserSurveyDialog, DELAY - elapsedTime);
|
|
47
|
+
sessionStore.surveyTimerId = timeout;
|
|
36
48
|
return () => {
|
|
37
49
|
clearTimeout(timeout);
|
|
50
|
+
sessionStore.surveyTimerId = null;
|
|
38
51
|
};
|
|
39
52
|
}
|
|
40
53
|
return noop;
|
|
41
|
-
}, []);
|
|
54
|
+
}, [isShowSurvey]);
|
|
55
|
+
return handleOpenSurveyAction;
|
|
42
56
|
};
|
|
43
|
-
// Отсчитываем месяц с текущей даты
|
|
44
|
-
const getTimeAfter30days = () => Date.now() + 30 * 24 * 60 * 60 * 1000;
|
|
45
57
|
//# sourceMappingURL=useUserSurveyDialog.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useUserSurveyDialog.js","sourceRoot":"","sources":["../../../src/ui-kit/UserSurveyDialog/useUserSurveyDialog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;
|
|
1
|
+
{"version":3,"file":"useUserSurveyDialog.js","sourceRoot":"","sources":["../../../src/ui-kit/UserSurveyDialog/useUserSurveyDialog.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,aAAa,EAAE,MAAM,2CAA2C,CAAC;AAC1E,OAAO,EAAE,eAAe,EAAE,MAAM,6CAA6C,CAAC;AAC9E,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,SAAS,EAAE,MAAM,4BAA4B,CAAC;AACvD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAGtD,MAAM,KAAK,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI,CAAC;AAQ5B,4CAA4C;AAC5C,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,YAAsB,EAAE,EAAE;IAC5D,MAAM,gBAAgB,GAAG,SAAS,CAAC,gBAAgB,CAAC,CAAC;IACrD,MAAM,eAAe,GAAG,aAAa,EAAwB,CAAC;IAC9D,MAAM,YAAY,GAAG,eAAe,EAAoB,CAAC;IACzD,MAAM,WAAW,GAAG,YAAY,CAAC,aAAa,CAAC;IAC/C,MAAM,eAAe,GAAG,YAAY,CAAC,eAAe,CAAC;IACrD,MAAM,WAAW,GAAG,YAAY,CAAC,gBAAgB;QAC/C,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAC,gBAAgB,CAAC;QAC7D,CAAC,CAAC,CAAC,CAAC;IACN,MAAM,YAAY,GAChB,CAAC,eAAe;QAChB,CAAC,CAAC,eAAe,CAAC,UAAU,IAAI,eAAe,CAAC,UAAU,EAAE,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;IAEvF,MAAM,iBAAiB,GAAG,WAAW,CAAC,GAAG,EAAE;QACzC,YAAY,CAAC,eAAe,GAAG,IAAI,CAAC;IACtC,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,oBAAoB,GAAG,WAAW,CAAC,CAAC,mBAA6B,EAAE,EAAE;QACzE,gBAAgB,CAAC,IAAI,CAAC;YACpB,aAAa,EAAE;gBACb,IAAI,EAAE,0CAA0C;aACjD;YACD,mBAAmB;YACnB,OAAO,EAAE,iBAAiB;SAC3B,CAAC,CAAC;IACL,CAAC,EAAE,EAAE,CAAC,CAAC;IAEP,MAAM,sBAAsB,GAAG,WAAW,CAAC,GAAG,EAAE;QAC9C,IAAI,YAAY,EAAE;YAChB,WAAW,IAAI,YAAY,CAAC,WAAW,CAAC,CAAC;YACzC,oBAAoB,CAAC,IAAI,CAAC,CAAC;SAC5B;IACH,CAAC,EAAE,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC,CAAC;IAEhC,SAAS,CAAC,GAAG,EAAE;QACb,0GAA0G;QAC1G,IAAI,CAAC,YAAY,IAAI,YAAY,EAAE;YACjC,uDAAuD;YACvD,IAAI,CAAC,YAAY,CAAC,gBAAgB,EAAE;gBAClC,YAAY,CAAC,gBAAgB,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,EAAE,CAAC;aACvD;YACD,wDAAwD;YACxD,MAAM,OAAO,GAAG,UAAU,CAAC,oBAAoB,EAAE,KAAK,GAAG,WAAW,CAAC,CAAC;YACtE,YAAY,CAAC,aAAa,GAAG,OAAO,CAAC;YAErC,OAAO,GAAG,EAAE;gBACV,YAAY,CAAC,OAAO,CAAC,CAAC;gBACtB,YAAY,CAAC,aAAa,GAAG,IAAI,CAAC;YACpC,CAAC,CAAC;SACH;QAED,OAAO,IAAI,CAAC;IACd,CAAC,EAAE,CAAC,YAAY,CAAC,CAAC,CAAC;IAEnB,OAAO,sBAAsB,CAAC;AAChC,CAAC,CAAC"}
|
|
@@ -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];
|
|
@@ -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
|
+
};
|
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];
|
|
@@ -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
|