@incodetech/prizma-core-screens 0.2.4 → 0.2.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/BiometricConsentScreen.d.ts +95 -0
- package/dist/BiometricConsentScreen.js +91 -0
- package/dist/BiometricConsentStrings.d.ts +84 -0
- package/dist/BiometricConsentStrings.js +31 -0
- package/dist/CaptureScreen.d.ts +13 -0
- package/dist/CaptureScreen.js +2 -2
- package/dist/CurpEnterScreen.d.ts +7 -0
- package/dist/CurpEnterScreen.js +17 -3
- package/dist/CurpGenerateScreen.d.ts +8 -0
- package/dist/CurpGenerateScreen.js +28 -13
- package/dist/CurpLayout.css +8 -34
- package/dist/CurpStrings.d.ts +16 -2
- package/dist/DemoScreensLayout.css +16 -0
- package/dist/DemoScreensRedirectScreen.d.ts +6 -1
- package/dist/DemoScreensRedirectScreen.js +3 -2
- package/dist/DemoScreensStrings.d.ts +5 -0
- package/dist/DigitalIdUploadErrorScreen.d.ts +31 -0
- package/dist/DigitalIdUploadErrorScreen.js +26 -0
- package/dist/DigitalIdUploadFileTooLargeScreen.d.ts +27 -0
- package/dist/DigitalIdUploadFileTooLargeScreen.js +21 -0
- package/dist/DigitalIdUploadReviewScreen.d.ts +57 -0
- package/dist/DigitalIdUploadReviewScreen.js +44 -0
- package/dist/DigitalIdUploadStrings.d.ts +64 -0
- package/dist/DigitalIdUploadStrings.js +19 -0
- package/dist/DigitalIdUploadTutorialScreen.d.ts +28 -0
- package/dist/DigitalIdUploadTutorialScreen.js +23 -0
- package/dist/DocumentCaptureIllustration.d.ts +1 -1
- package/dist/EkybAddressDetailsScreen.d.ts +7 -0
- package/dist/EkybAddressDetailsScreen.js +25 -7
- package/dist/EkybBusinessDetailsScreen.d.ts +6 -0
- package/dist/EkybBusinessDetailsScreen.js +23 -6
- package/dist/EkybCountryScreen.d.ts +13 -5
- package/dist/EkybCountryScreen.js +41 -10
- package/dist/EkybOwnersScreen.d.ts +8 -0
- package/dist/EkybOwnersScreen.js +26 -3
- package/dist/EkybStrings.d.ts +32 -10
- package/dist/EkycCountryCatalog.d.ts +4 -1
- package/dist/EkycCountryCatalog.js +5 -3
- package/dist/EkycCountryFormScreen.d.ts +12 -3
- package/dist/EkycCountryFormScreen.js +28 -10
- package/dist/EkycDetailsScreen.d.ts +7 -0
- package/dist/EkycDetailsScreen.js +21 -4
- package/dist/EkycStrings.d.ts +14 -2
- package/dist/ElectronicSignatureLayout.css +6 -0
- package/dist/EmailInputStrings.d.ts +11 -1
- package/dist/EmailInputVerifyScreen.d.ts +7 -0
- package/dist/EmailInputVerifyScreen.js +17 -3
- package/dist/ErrorScreensScreen.d.ts +5 -2
- package/dist/ErrorScreensScreen.js +15 -4
- package/dist/ErrorScreensStrings.d.ts +17 -2
- package/dist/ErrorScreensStrings.js +18 -10
- package/dist/FaceCaptureCapturingScreen.d.ts +63 -0
- package/dist/FaceCaptureCapturingScreen.js +62 -2
- package/dist/FaceCaptureLayout.css +69 -4
- package/dist/FaceCaptureStrings.d.ts +23 -0
- package/dist/FaceMatchComparisonScreen.d.ts +3 -3
- package/dist/FaceMatchLayout.css +21 -12
- package/dist/FormScreen.css +30 -0
- package/dist/FormScreen.d.ts +28 -0
- package/dist/FormScreen.js +3 -2
- package/dist/FormsLongFormScreen.d.ts +8 -0
- package/dist/FormsLongFormScreen.js +34 -13
- package/dist/FormsStrings.d.ts +11 -1
- package/dist/GeolocationBrowserStepsScreen.d.ts +6 -2
- package/dist/GeolocationBrowserStepsScreen.js +7 -3
- package/dist/GeolocationStrings.d.ts +3 -0
- package/dist/IdCaptureLayout.css +205 -2
- package/dist/IdCaptureStageScreen.d.ts +47 -0
- package/dist/IdCaptureStageScreen.js +39 -3
- package/dist/IdCaptureStrings.d.ts +19 -0
- package/dist/ListScreen.d.ts +21 -0
- package/dist/ListScreen.js +7 -2
- package/dist/LoaderScreen.d.ts +7 -5
- package/dist/LoaderScreen.js +7 -5
- package/dist/LoadersStrings.d.ts +18 -5
- package/dist/OcrReviewErrorScreen.d.ts +30 -0
- package/dist/OcrReviewErrorScreen.js +24 -0
- package/dist/OcrReviewLayout.css +24 -0
- package/dist/OcrReviewLoadingScreen.d.ts +25 -0
- package/dist/OcrReviewLoadingScreen.js +19 -0
- package/dist/OcrReviewScreen.d.ts +76 -0
- package/dist/OcrReviewScreen.js +65 -0
- package/dist/OcrReviewStrings.d.ts +47 -0
- package/dist/OcrReviewStrings.js +17 -0
- package/dist/OcrReviewSuccessScreen.d.ts +30 -0
- package/dist/OcrReviewSuccessScreen.js +24 -0
- package/dist/PermissionsAllowScreen.d.ts +8 -11
- package/dist/PermissionsAllowScreen.js +8 -11
- package/dist/PermissionsAskScreen.d.ts +41 -0
- package/dist/PermissionsAskScreen.js +43 -0
- package/dist/PermissionsBrowserStepsScreen.d.ts +9 -2
- package/dist/PermissionsBrowserStepsScreen.js +12 -3
- package/dist/PermissionsLayout.css +47 -0
- package/dist/PermissionsStrings.d.ts +20 -9
- package/dist/PermissionsStrings.js +10 -4
- package/dist/PhoneInputLayout.css +10 -9
- package/dist/PhoneInputOtpScreen.d.ts +8 -0
- package/dist/PhoneInputOtpScreen.js +26 -19
- package/dist/PhoneInputStrings.d.ts +22 -4
- package/dist/PhoneInputVerifyScreen.d.ts +8 -0
- package/dist/PhoneInputVerifyScreen.js +36 -7
- package/dist/QualifiedSignatureAcceptScreen.js +6 -1
- package/dist/QualifiedSignatureDocumentScreen.d.ts +17 -10
- package/dist/QualifiedSignatureDocumentScreen.js +22 -17
- package/dist/QualifiedSignatureLayout.css +76 -0
- package/dist/QualifiedSignatureResultScreen.d.ts +16 -13
- package/dist/QualifiedSignatureResultScreen.js +17 -18
- package/dist/QualifiedSignatureStrings.d.ts +19 -2
- package/dist/ResultScreen.d.ts +8 -0
- package/dist/ResultScreen.js +14 -3
- package/dist/ReusabilityCredentialSelectionScreen.d.ts +95 -0
- package/dist/ReusabilityCredentialSelectionScreen.js +94 -0
- package/dist/ReusabilityLayout.css +241 -0
- package/dist/ReusabilityPrivacyPolicyScreen.d.ts +55 -0
- package/dist/ReusabilityPrivacyPolicyScreen.js +44 -0
- package/dist/ReusabilityStrings.d.ts +85 -0
- package/dist/ReusabilityStrings.js +37 -0
- package/dist/ReviewScreen.d.ts +38 -12
- package/dist/ReviewScreen.js +41 -8
- package/dist/ScreenLayout.css +382 -6
- package/dist/ScreenNav.css +8 -0
- package/dist/ScreenNav.d.ts +15 -2
- package/dist/ScreenNav.js +10 -3
- package/dist/VideoSelfieErrorScreen.js +1 -1
- package/dist/VideoSelfieIdCaptureScreen.d.ts +10 -3
- package/dist/VideoSelfieIdCaptureScreen.js +45 -14
- package/dist/VideoSelfieLayout.css +467 -34
- package/dist/VideoSelfieSelfieCaptureScreen.d.ts +44 -27
- package/dist/VideoSelfieSelfieCaptureScreen.js +65 -39
- package/dist/VideoSelfieSpeakScreen.js +19 -2
- package/dist/VideoSelfieStrings.d.ts +82 -13
- package/dist/VideoSelfieTurnHeadScreen.d.ts +51 -0
- package/dist/VideoSelfieTurnHeadScreen.js +66 -0
- package/dist/VideoSelfieTutorialScreen.d.ts +9 -0
- package/dist/VideoSelfieTutorialScreen.js +22 -5
- package/dist/VideoSelfieWaveScreen.d.ts +53 -0
- package/dist/VideoSelfieWaveScreen.js +62 -0
- package/dist/ViewfinderScreen.css +36 -0
- package/dist/WatchlistBusinessFormScreen.d.ts +11 -7
- package/dist/WatchlistBusinessFormScreen.js +27 -13
- package/dist/WatchlistBusinessStrings.d.ts +21 -7
- package/dist/flows.d.ts +8 -0
- package/dist/flows.js +17 -0
- package/dist/index.d.ts +19 -1
- package/dist/index.js +14 -0
- package/dist/styles.css +3 -0
- package/dist/types.d.ts +3 -1
- package/package.json +79 -3
- package/samples/video-selfie-camera-wide.jpg +0 -0
- package/samples/video-selfie-room-wide.jpg +0 -0
- package/samples/video-selfie-room.png +0 -0
- package/src/BiometricConsentScreen.tsx +192 -0
- package/src/BiometricConsentStrings.ts +119 -0
- package/src/CaptureScreen.tsx +17 -0
- package/src/CurpEnterScreen.tsx +21 -4
- package/src/CurpGenerateScreen.tsx +46 -22
- package/src/CurpLayout.css +8 -34
- package/src/CurpStrings.ts +22 -2
- package/src/DemoScreensLayout.css +16 -0
- package/src/DemoScreensRedirectScreen.tsx +14 -6
- package/src/DemoScreensStrings.ts +5 -0
- package/src/DigitalIdUploadErrorScreen.tsx +83 -0
- package/src/DigitalIdUploadFileTooLargeScreen.tsx +67 -0
- package/src/DigitalIdUploadReviewScreen.tsx +119 -0
- package/src/DigitalIdUploadStrings.ts +88 -0
- package/src/DigitalIdUploadTutorialScreen.tsx +59 -0
- package/src/DocumentCaptureIllustration.tsx +1 -1
- package/src/EkybAddressDetailsScreen.tsx +32 -4
- package/src/EkybBusinessDetailsScreen.tsx +23 -5
- package/src/EkybCountryScreen.tsx +45 -7
- package/src/EkybOwnersScreen.tsx +34 -3
- package/src/EkybStrings.ts +34 -10
- package/src/EkycCountryCatalog.ts +9 -4
- package/src/EkycCountryFormScreen.tsx +51 -12
- package/src/EkycDetailsScreen.tsx +22 -1
- package/src/EkycStrings.ts +14 -2
- package/src/ElectronicSignatureLayout.css +6 -0
- package/src/EmailInputStrings.ts +12 -1
- package/src/EmailInputVerifyScreen.tsx +21 -4
- package/src/ErrorScreensScreen.tsx +15 -4
- package/src/ErrorScreensStrings.ts +37 -12
- package/src/FaceCaptureCapturingScreen.tsx +102 -13
- package/src/FaceCaptureLayout.css +69 -4
- package/src/FaceCaptureStrings.ts +24 -0
- package/src/FaceMatchComparisonScreen.tsx +3 -3
- package/src/FaceMatchLayout.css +21 -12
- package/src/FormScreen.css +30 -0
- package/src/FormScreen.tsx +34 -0
- package/src/FormsLongFormScreen.tsx +41 -13
- package/src/FormsStrings.ts +12 -1
- package/src/GeolocationBrowserStepsScreen.tsx +6 -3
- package/src/GeolocationStrings.ts +3 -0
- package/src/IdCaptureLayout.css +205 -2
- package/src/IdCaptureStageScreen.tsx +75 -0
- package/src/IdCaptureStrings.ts +19 -0
- package/src/ListScreen.tsx +58 -10
- package/src/LoaderScreen.tsx +7 -5
- package/src/LoadersStrings.ts +18 -5
- package/src/OcrReviewErrorScreen.tsx +53 -0
- package/src/OcrReviewLayout.css +24 -0
- package/src/OcrReviewLoadingScreen.tsx +48 -0
- package/src/OcrReviewScreen.tsx +190 -0
- package/src/OcrReviewStrings.ts +69 -0
- package/src/OcrReviewSuccessScreen.tsx +52 -0
- package/src/PermissionsAllowScreen.tsx +9 -10
- package/src/PermissionsAskScreen.tsx +105 -0
- package/src/PermissionsBrowserStepsScreen.tsx +11 -3
- package/src/PermissionsLayout.css +47 -0
- package/src/PermissionsStrings.ts +42 -12
- package/src/PhoneInputLayout.css +10 -9
- package/src/PhoneInputOtpScreen.tsx +23 -3
- package/src/PhoneInputStrings.ts +23 -4
- package/src/PhoneInputVerifyScreen.tsx +41 -5
- package/src/QualifiedSignatureAcceptScreen.tsx +12 -1
- package/src/QualifiedSignatureDocumentScreen.tsx +31 -19
- package/src/QualifiedSignatureLayout.css +76 -0
- package/src/QualifiedSignatureResultScreen.tsx +28 -26
- package/src/QualifiedSignatureStrings.ts +19 -2
- package/src/ResultScreen.tsx +33 -2
- package/src/ReusabilityCredentialSelectionScreen.tsx +246 -0
- package/src/ReusabilityLayout.css +241 -0
- package/src/ReusabilityPrivacyPolicyScreen.tsx +109 -0
- package/src/ReusabilityStrings.ts +127 -0
- package/src/ReviewScreen.tsx +96 -27
- package/src/ScreenLayout.css +382 -6
- package/src/ScreenNav.css +8 -0
- package/src/ScreenNav.tsx +35 -5
- package/src/VideoSelfieErrorScreen.tsx +1 -1
- package/src/VideoSelfieIdCaptureScreen.tsx +125 -31
- package/src/VideoSelfieLayout.css +467 -34
- package/src/VideoSelfieSelfieCaptureScreen.tsx +110 -57
- package/src/VideoSelfieSpeakScreen.tsx +34 -15
- package/src/VideoSelfieStrings.ts +89 -14
- package/src/VideoSelfieTurnHeadScreen.tsx +162 -0
- package/src/VideoSelfieTutorialScreen.tsx +45 -23
- package/src/VideoSelfieWaveScreen.tsx +143 -0
- package/src/ViewfinderScreen.css +36 -0
- package/src/WatchlistBusinessFormScreen.tsx +35 -16
- package/src/WatchlistBusinessStrings.ts +21 -7
- package/src/flows.ts +25 -0
- package/src/index.ts +88 -3
- package/src/styles.css +3 -0
- package/src/types.ts +3 -1
|
@@ -1,41 +1,61 @@
|
|
|
1
1
|
import React, { forwardRef, type ReactNode } from 'react';
|
|
2
|
-
import
|
|
3
|
-
|
|
2
|
+
import {
|
|
3
|
+
PrizmaSelfieCapture,
|
|
4
|
+
type PrizmaSelfieCaptureState,
|
|
5
|
+
} from '@incodetech/prizma-core-web/selfie-capture';
|
|
6
|
+
import { PrizmaStepper } from '@incodetech/prizma-core-web/stepper';
|
|
7
|
+
import { PrizmaScreenShell, type PrizmaScreenShellProps } from './ScreenShell';
|
|
4
8
|
import type { PrizmaScreenActionHandler, PrizmaScreenOverrides } from './types';
|
|
5
|
-
import type {
|
|
9
|
+
import type {
|
|
10
|
+
VideoSelfieDocumentType,
|
|
11
|
+
VideoSelfieFeedbackKind,
|
|
12
|
+
VideoSelfieStrings,
|
|
13
|
+
} from './VideoSelfieStrings';
|
|
6
14
|
import './ScreenLayout.css';
|
|
15
|
+
import './ViewfinderScreen.css';
|
|
16
|
+
import './VideoSelfieLayout.css';
|
|
7
17
|
|
|
8
18
|
/** Which purple liveness section to render (group 8). */
|
|
9
19
|
export type VideoSelfieSelfieState = 'start' | 'processing' | 'success' | 'failed';
|
|
10
20
|
|
|
11
|
-
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
21
|
+
/**
|
|
22
|
+
* Purple state → Core `PrizmaSelfieCapture` state, in the OVERLAY recipe.
|
|
23
|
+
*
|
|
24
|
+
* `start` is `filled`, not `empty`: `empty` is Core's *searching* beat and
|
|
25
|
+
* draws the dashed silhouette guide, which `8.0` and every `9.x` message
|
|
26
|
+
* deliberately hide (`silhouette hidden=true` on the frames — the guide
|
|
27
|
+
* belongs to the head-turn steps, which do draw it). `filled` is Core's
|
|
28
|
+
* "window open, neutral ring, no guide" beat, and in overlay mode there is no
|
|
29
|
+
* still to fill it with: the host's feed shows straight through the ring.
|
|
30
|
+
*/
|
|
15
31
|
const CAPTURE_STATE: Record<VideoSelfieSelfieState, PrizmaSelfieCaptureState> = {
|
|
16
|
-
start: '
|
|
32
|
+
start: 'filled',
|
|
17
33
|
processing: 'uploading',
|
|
18
34
|
success: 'success',
|
|
19
35
|
failed: 'error',
|
|
20
36
|
};
|
|
21
37
|
|
|
38
|
+
/** Which beat of the seven-step journey the liveness ring occupies — the
|
|
39
|
+
* microphone grant is 1, the two document sides 2 and 3. */
|
|
40
|
+
const STEP = 4;
|
|
41
|
+
|
|
22
42
|
export interface VideoSelfieSelfieCaptureScreenProps
|
|
23
|
-
extends Omit<
|
|
24
|
-
PrizmaCaptureScreenProps,
|
|
25
|
-
'state' | 'feedbackText' | 'statusLabels' | 'verifiedLabel' | 'navLabel'
|
|
26
|
-
> {
|
|
43
|
+
extends Omit<PrizmaScreenShellProps, 'dark' | 'title' | 'children'> {
|
|
27
44
|
/** Module copy — this screen reads the `selfieCapture` slice. */
|
|
28
45
|
strings: VideoSelfieStrings;
|
|
29
46
|
/** Which purple section of group 8 to render. Default `start`. */
|
|
30
47
|
state?: VideoSelfieSelfieState;
|
|
31
48
|
/**
|
|
32
|
-
* Which of group 9's
|
|
33
|
-
*
|
|
49
|
+
* Which of group 9's live-feedback lines to show under the ring. Only
|
|
50
|
+
* meaningful while the ring is live (`state="start"`): the sections of
|
|
34
51
|
* group 9 are that same frame with a different instruction. Omit for `8.0`,
|
|
35
52
|
* which shows the plain "Look at your front camera" line.
|
|
36
53
|
*/
|
|
37
54
|
feedback?: VideoSelfieFeedbackKind;
|
|
38
|
-
/**
|
|
55
|
+
/** Which document the journey collects — the Stepper's own `documentType`. */
|
|
56
|
+
documentType?: VideoSelfieDocumentType;
|
|
57
|
+
/** Live camera feed (<video>) or sample still (<img>), full-bleed behind the
|
|
58
|
+
* ring — NOT inside it. The overlay recipe makes the ring a window. */
|
|
39
59
|
camera?: ReactNode;
|
|
40
60
|
screenId?: string;
|
|
41
61
|
overrides?: PrizmaScreenOverrides;
|
|
@@ -43,29 +63,41 @@ export interface VideoSelfieSelfieCaptureScreenProps
|
|
|
43
63
|
}
|
|
44
64
|
|
|
45
65
|
/**
|
|
46
|
-
* Video Selfie — the liveness ring (Archetype
|
|
47
|
-
* ONE screen for
|
|
48
|
-
* `selfie capture feedback 9.
|
|
49
|
-
* variants of Core's `PrizmaSelfieCapture`, which
|
|
50
|
-
*
|
|
51
|
-
*
|
|
52
|
-
*
|
|
66
|
+
* Video Selfie — the liveness ring (Archetype D, GUIDELINES.md §6-D; always
|
|
67
|
+
* dark). ONE screen for every purple section of groups 8 and 9: `selfie
|
|
68
|
+
* capture 8.0–8.3` and every `selfie capture feedback 9.x` message. They are
|
|
69
|
+
* `state` × `feedbackText` variants of Core's `PrizmaSelfieCapture`, which is
|
|
70
|
+
* exactly how the component is axed.
|
|
71
|
+
*
|
|
72
|
+
* **Rebuilt 2026-09-30 to follow the frames.** The first pass shipped Core's
|
|
73
|
+
* INLINE recipe — the feed inside a circular window on a WHITE surface, the
|
|
74
|
+
* verdicts dissolving the ring into a centred mark — and logged the gap. On
|
|
75
|
+
* the module page that read as a different product from the rest of the flow:
|
|
76
|
+
* a small ring on white between two full-bleed dark camera screens, with the
|
|
77
|
+
* ring vanishing on the very beats Figma keeps it (owner, 2026-09-30: "they
|
|
78
|
+
* are looking very broken… a broken experience"). Rather than hand-roll the
|
|
79
|
+
* full-bleed composition here, Core's `PrizmaSelfieCapture` grew the
|
|
80
|
+
* `mode="overlay"` + `scrim` axis `PrizmaIdCapture` already carries — it is
|
|
81
|
+
* the Figma library's own `Capture / Selfie overlay` component — and this
|
|
82
|
+
* screen composes it. Nothing about the ring, the scrim, the glow sweeps, the
|
|
83
|
+
* verdict marks or the instruction typography is re-implemented (§7).
|
|
84
|
+
* DEVIATIONS #VS-22.
|
|
85
|
+
*
|
|
86
|
+
* The composition, measured off `8.0` (390×844):
|
|
53
87
|
*
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
* Face Capture pilot settled it.
|
|
88
|
+
* - the camera runs FULL-BLEED on `.prizma-viewfinder__surface` (`selfie bg
|
|
89
|
+
* image`, 390×844 — it passes under the browser chrome too);
|
|
90
|
+
* - the journey stepper sits in the band the logo nav normally occupies
|
|
91
|
+
* (`top content` y=56, the Stepper 342 wide at x=24), the module-wide
|
|
92
|
+
* treatment `VideoSelfieLayout.css` owns;
|
|
93
|
+
* - the ring is 335 centred in the remaining air (Figma 27,188 → 362,523
|
|
94
|
+
* against a 708-high content area), with the instruction stacked under it.
|
|
95
|
+
* Core's own Spacing/32 gap replaces Figma's 25.5 (the token wins, §4).
|
|
63
96
|
*
|
|
64
|
-
*
|
|
65
|
-
*
|
|
66
|
-
*
|
|
67
|
-
*
|
|
68
|
-
* instruction copy.
|
|
97
|
+
* NO verified tag: `8.x` and `9.x` draw nothing between the instruction and
|
|
98
|
+
* the bottom of the screen (GUIDELINES §1 — follow the module's section, not
|
|
99
|
+
* the default). The document stage keeps its tag because its own sections
|
|
100
|
+
* draw one (#VS-3).
|
|
69
101
|
*/
|
|
70
102
|
export const VideoSelfieSelfieCaptureScreen = forwardRef<
|
|
71
103
|
HTMLDivElement,
|
|
@@ -76,10 +108,12 @@ export const VideoSelfieSelfieCaptureScreen = forwardRef<
|
|
|
76
108
|
strings,
|
|
77
109
|
state = 'start',
|
|
78
110
|
feedback,
|
|
111
|
+
documentType = 'id',
|
|
79
112
|
camera,
|
|
80
113
|
screenId = `video-selfie-selfie-capture-${feedback ?? state}`,
|
|
81
114
|
overrides,
|
|
82
115
|
onAction,
|
|
116
|
+
className,
|
|
83
117
|
...shell
|
|
84
118
|
},
|
|
85
119
|
ref,
|
|
@@ -89,31 +123,50 @@ export const VideoSelfieSelfieCaptureScreen = forwardRef<
|
|
|
89
123
|
carry Core's own status copy instead (its `statusLabels` slot), which is
|
|
90
124
|
why the feedback line is scoped to the live state. */
|
|
91
125
|
const feedbackText =
|
|
92
|
-
|
|
93
|
-
? feedback
|
|
94
|
-
? slice.feedback[feedback]
|
|
95
|
-
: slice.startLabel
|
|
96
|
-
: undefined;
|
|
126
|
+
state === 'start' ? (feedback ? slice.feedback[feedback] : slice.startLabel) : undefined;
|
|
97
127
|
|
|
98
128
|
return (
|
|
99
|
-
<
|
|
129
|
+
<PrizmaScreenShell
|
|
100
130
|
ref={ref}
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
uploading: slice.processingLabel,
|
|
107
|
-
success: slice.successLabel,
|
|
108
|
-
error: slice.failedLabel,
|
|
109
|
-
}}
|
|
110
|
-
verifiedLabel={strings.verifiedLabel}
|
|
111
|
-
navLabel={strings.navLabel}
|
|
112
|
-
screenId={screenId}
|
|
113
|
-
overrides={overrides}
|
|
114
|
-
onAction={onAction}
|
|
131
|
+
dark
|
|
132
|
+
/* The camera owns the whole window, never a column of it — see the
|
|
133
|
+
contract note in `VideoSelfieLayout.css`. */
|
|
134
|
+
data-pcs-overlay="window"
|
|
135
|
+
className={className}
|
|
115
136
|
{...shell}
|
|
116
|
-
|
|
137
|
+
>
|
|
138
|
+
<div className="prizma-viewfinder__surface">{camera}</div>
|
|
139
|
+
<div className="video-selfie-stepper">
|
|
140
|
+
<PrizmaStepper
|
|
141
|
+
steps={7}
|
|
142
|
+
currentState={STEP}
|
|
143
|
+
documentType={documentType}
|
|
144
|
+
completedValueText={strings.stepperCompletedLabel}
|
|
145
|
+
/>
|
|
146
|
+
</div>
|
|
147
|
+
<div
|
|
148
|
+
className={[
|
|
149
|
+
'prizma-viewfinder__content',
|
|
150
|
+
overrides?.align === 'left' ? 'prizma-viewfinder__content--left' : '',
|
|
151
|
+
]
|
|
152
|
+
.filter(Boolean)
|
|
153
|
+
.join(' ')}
|
|
154
|
+
>
|
|
155
|
+
<div className="video-selfie-band video-selfie-band--ring">
|
|
156
|
+
<PrizmaSelfieCapture
|
|
157
|
+
mode="overlay"
|
|
158
|
+
scrim
|
|
159
|
+
state={CAPTURE_STATE[state]}
|
|
160
|
+
feedbackText={feedbackText}
|
|
161
|
+
statusLabels={{
|
|
162
|
+
uploading: slice.processingLabel,
|
|
163
|
+
success: slice.successLabel,
|
|
164
|
+
error: slice.failedLabel,
|
|
165
|
+
}}
|
|
166
|
+
/>
|
|
167
|
+
</div>
|
|
168
|
+
</div>
|
|
169
|
+
</PrizmaScreenShell>
|
|
117
170
|
);
|
|
118
171
|
},
|
|
119
172
|
);
|
|
@@ -120,23 +120,31 @@ export const VideoSelfieSpeakScreen = forwardRef<
|
|
|
120
120
|
onSecondaryClick: () => onAction?.({ type: 'secondary', screenId }),
|
|
121
121
|
}}
|
|
122
122
|
/>
|
|
123
|
-
) : stage === 'processing' ? (
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
123
|
+
) : stage === 'processing' || stage === 'success' ? (
|
|
124
|
+
/* The two verdict cards. They carry no buttons, so left alone they came
|
|
125
|
+
out shorter than the prompt they replace and the sheet jumped between
|
|
126
|
+
steps; and Core's Modal renders `body` AFTER the heading, which put
|
|
127
|
+
the spinner and the check UNDER their own label. Both are fixed in
|
|
128
|
+
the module: `--status` gives the card the prompt's measure and centres
|
|
129
|
+
its content, and the mark is passed as the LEADING slot so it stacks
|
|
130
|
+
above the copy the way `10.2` / `10.3` draw it.
|
|
131
|
+
|
|
132
|
+
No ✕ either. Figma draws one, but it is the same call #VS-5 already
|
|
133
|
+
made on the prompt: closing mid-step strands the user with no way
|
|
134
|
+
back, and a dismiss that appears on two of five cards and not the
|
|
135
|
+
other three is the inconsistency, not the fix (owner, 2026-09-30).
|
|
136
|
+
DEVIATIONS #VS-25. */
|
|
132
137
|
<PrizmaModalContent
|
|
133
|
-
title={slice.successLabel}
|
|
138
|
+
title={stage === 'processing' ? slice.processingLabel : slice.successLabel}
|
|
139
|
+
showCloseIcon={false}
|
|
134
140
|
showButtonGroup={false}
|
|
135
|
-
|
|
136
|
-
onClose={() => onAction?.({ type: 'tertiary', screenId })}
|
|
137
|
-
body={
|
|
141
|
+
leading={
|
|
138
142
|
<span className="video-selfie-sheet-status">
|
|
139
|
-
|
|
143
|
+
{stage === 'processing' ? (
|
|
144
|
+
<PrizmaLoadingSpinner loadingLabel={slice.processingLabel} />
|
|
145
|
+
) : (
|
|
146
|
+
<IconStatusPositive size="xl" />
|
|
147
|
+
)}
|
|
140
148
|
</span>
|
|
141
149
|
}
|
|
142
150
|
/>
|
|
@@ -170,7 +178,15 @@ export const VideoSelfieSpeakScreen = forwardRef<
|
|
|
170
178
|
);
|
|
171
179
|
|
|
172
180
|
return (
|
|
173
|
-
<PrizmaScreenShell
|
|
181
|
+
<PrizmaScreenShell
|
|
182
|
+
ref={ref}
|
|
183
|
+
dark
|
|
184
|
+
/* The camera owns the whole window, never a column of it — see the
|
|
185
|
+
contract note in `VideoSelfieLayout.css`. */
|
|
186
|
+
data-pcs-overlay="window"
|
|
187
|
+
className={className}
|
|
188
|
+
{...shell}
|
|
189
|
+
>
|
|
174
190
|
<div className="prizma-viewfinder__surface">{camera}</div>
|
|
175
191
|
<div className="video-selfie-stepper">
|
|
176
192
|
<PrizmaStepper
|
|
@@ -214,6 +230,9 @@ export const VideoSelfieSpeakScreen = forwardRef<
|
|
|
214
230
|
className={[
|
|
215
231
|
'video-selfie-sheet-panel',
|
|
216
232
|
isConfirm ? 'video-selfie-sheet-panel--centered' : '',
|
|
233
|
+
stage === 'processing' || stage === 'success'
|
|
234
|
+
? 'video-selfie-sheet-panel--status'
|
|
235
|
+
: '',
|
|
217
236
|
]
|
|
218
237
|
.filter(Boolean)
|
|
219
238
|
.join(' ')}
|
|
@@ -38,7 +38,10 @@ export type VideoSelfieTutorialRowKind =
|
|
|
38
38
|
| 'questions'
|
|
39
39
|
| 'speak';
|
|
40
40
|
|
|
41
|
-
/** The
|
|
41
|
+
/** The live-feedback messages of group 9, in Figma order. Fourteen since
|
|
42
|
+
* 2026-09-30: `9.12`–`9.14` (head cover · closed eyes · face occlusion) were
|
|
43
|
+
* added to the frames after the module's first build and are on the Web, iOS
|
|
44
|
+
* and Android full-flow maps. */
|
|
42
45
|
export type VideoSelfieFeedbackKind =
|
|
43
46
|
| 'dark'
|
|
44
47
|
| 'blurry'
|
|
@@ -50,19 +53,67 @@ export type VideoSelfieFeedbackKind =
|
|
|
50
53
|
| 'turnLeft'
|
|
51
54
|
| 'alignFace'
|
|
52
55
|
| 'moveCloser'
|
|
53
|
-
| 'moveAway'
|
|
56
|
+
| 'moveAway'
|
|
57
|
+
| 'headCover'
|
|
58
|
+
| 'closedEyes'
|
|
59
|
+
| 'faceOcclusion';
|
|
60
|
+
|
|
61
|
+
/** Which head-turn the liveness step is asking for (the `🙂↔️ Turn Head` band
|
|
62
|
+
* of the full-flow frames: Left · Right · Upward · Downward, each drawn as a
|
|
63
|
+
* guide beat and a captured beat). */
|
|
64
|
+
export type VideoSelfieTurnDirection = 'left' | 'right' | 'up' | 'down';
|
|
54
65
|
|
|
55
66
|
/** Which face of the document the ID stage is on (groups 3 and 5). */
|
|
56
67
|
export type VideoSelfieIdSide = 'front' | 'back';
|
|
57
68
|
|
|
58
|
-
/** Why an ID read was rejected (group 6, the `.1`–`.4` variants). */
|
|
59
69
|
/**
|
|
60
|
-
*
|
|
61
|
-
*
|
|
62
|
-
*
|
|
63
|
-
*
|
|
64
|
-
*
|
|
70
|
+
* Why an ID read was rejected — the `.1`–`.4` suffix of every group 6 section.
|
|
71
|
+
*
|
|
72
|
+
* RESTORED 2026-09-30. It was removed on 2026-08-19 on the reading that "group
|
|
73
|
+
* 6 draws exactly four sections", because the `📐 Screens specs & behavior`
|
|
74
|
+
* page documents ONE representative per group (`6.1.1`, `6.2.1`, `6.3.1`,
|
|
75
|
+
* `6.4.1`) and the rest are component variants inside it. The `🔸 Full flow
|
|
76
|
+
* map` draws them all, and they carry DIFFERENT copy, not a translation of
|
|
77
|
+
* one line: `6.2.2 - name failed` reads "Name verification failed",
|
|
78
|
+
* `6.2.3 - photo failed` reads "ID photo verification failed",
|
|
79
|
+
* `6.1.4 - type mismatch try again` reads "ID type mismatch, show the same ID".
|
|
80
|
+
* Collapsing them to one line lost three rejections a user can actually hit.
|
|
81
|
+
* DEVIATIONS #VS-1.
|
|
65
82
|
*/
|
|
83
|
+
export type VideoSelfieIdErrorReason = 'scan' | 'name' | 'photo' | 'typeMismatch';
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* A live CONDITION the document stage can coach the user out of, as opposed
|
|
87
|
+
* to a rejection it has to report.
|
|
88
|
+
*
|
|
89
|
+
* BOTH legs run five of these before the identity checks — the frames draw
|
|
90
|
+
* them on the back only, and the owner extended them to the front on
|
|
91
|
+
* 2026-09-30 ("I think it would be nice to add them for the front as well").
|
|
92
|
+
* Each one draws its OWN screen: the frame in its
|
|
93
|
+
* matching red treatment with a `Capture feedback` bubble above it saying
|
|
94
|
+
* what to do. They were all wired to the single "ID scan failed, try again"
|
|
95
|
+
* card until 2026-09-30 — the five screens are `frame` nodes rather than
|
|
96
|
+
* component instances in the flow map, so the first trace walked straight
|
|
97
|
+
* past them (owner: "we do have those states in figma").
|
|
98
|
+
*
|
|
99
|
+
* All five map 1:1 onto states Core already ships: four onto
|
|
100
|
+
* `PrizmaIdCapture`'s own `error-*` treatments, and `blurry` onto the plain
|
|
101
|
+
* error border plus the bubble, which is the recipe the owner set for
|
|
102
|
+
* detection results on 2026-07-28 (the border is the state, the message is
|
|
103
|
+
* the bubble).
|
|
104
|
+
*/
|
|
105
|
+
/** One coaching bubble's copy: what is wrong, and what to do about it. */
|
|
106
|
+
export interface VideoSelfieConditionCopy {
|
|
107
|
+
title: string;
|
|
108
|
+
subtitle: string;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
export type VideoSelfieIdCondition =
|
|
112
|
+
| 'wrongSide'
|
|
113
|
+
| 'notAligned'
|
|
114
|
+
| 'blurry'
|
|
115
|
+
| 'glare'
|
|
116
|
+
| 'tooDark';
|
|
66
117
|
|
|
67
118
|
/** Whether the rejection invites a retry (`6.1` / `6.3`) or is terminal
|
|
68
119
|
* (`6.2` / `6.4`). */
|
|
@@ -172,9 +223,26 @@ export interface VideoSelfieStrings {
|
|
|
172
223
|
processingLabel: string;
|
|
173
224
|
/** Accepted label (`3.3` / `5.3`). */
|
|
174
225
|
successLabel: string;
|
|
175
|
-
/** Rejection copy, keyed reason → severity (group 6).
|
|
176
|
-
|
|
177
|
-
|
|
226
|
+
/** Rejection copy, keyed reason → severity (group 6). The two axes are
|
|
227
|
+
* independent: `6.1.x` / `6.3.x` are the try-again lines, `6.2.x` /
|
|
228
|
+
* `6.4.x` the terminal ones, and the `.1`–`.4` suffix is the reason. The
|
|
229
|
+
* two sides share the copy — only the stepper beat differs. */
|
|
230
|
+
errors: Record<VideoSelfieIdErrorReason, Record<VideoSelfieIdErrorSeverity, string>>;
|
|
231
|
+
/**
|
|
232
|
+
* The five coaching bubbles — title + what to do about it.
|
|
233
|
+
*
|
|
234
|
+
* Only `wrongSide` is keyed by side, because it is the only one that
|
|
235
|
+
* NAMES the face the user should be showing; the other four describe the
|
|
236
|
+
* shot, which is the same problem whichever face is up. Keying all five by
|
|
237
|
+
* side would duplicate four strings per language for nothing.
|
|
238
|
+
*/
|
|
239
|
+
conditions: {
|
|
240
|
+
wrongSide: Record<VideoSelfieIdSide, VideoSelfieConditionCopy>;
|
|
241
|
+
notAligned: VideoSelfieConditionCopy;
|
|
242
|
+
blurry: VideoSelfieConditionCopy;
|
|
243
|
+
glare: VideoSelfieConditionCopy;
|
|
244
|
+
tooDark: VideoSelfieConditionCopy;
|
|
245
|
+
};
|
|
178
246
|
};
|
|
179
247
|
|
|
180
248
|
/** Group 4 — the flip interstitial. */
|
|
@@ -193,8 +261,13 @@ export interface VideoSelfieStrings {
|
|
|
193
261
|
successLabel: string;
|
|
194
262
|
/** `8.3` rejected. */
|
|
195
263
|
failedLabel: string;
|
|
196
|
-
/** Group 9 — the
|
|
264
|
+
/** Group 9 — the fourteen live-feedback lines. */
|
|
197
265
|
feedback: Record<VideoSelfieFeedbackKind, string>;
|
|
266
|
+
/** The head-turn step's own instruction, one per direction (the
|
|
267
|
+
* `🙂↔️ Turn Head` band of the full-flow frames). */
|
|
268
|
+
turn: Record<VideoSelfieTurnDirection, string>;
|
|
269
|
+
/** The wave step's instruction and its three checkpoints (`👋 Wave`). */
|
|
270
|
+
wave: { instruction: string; steps: string[]; doneLabel: string };
|
|
198
271
|
};
|
|
199
272
|
|
|
200
273
|
/** Groups 10 · 11 — the spoken steps. */
|
|
@@ -216,7 +289,9 @@ export interface VideoSelfieStrings {
|
|
|
216
289
|
stepError: { title: string; ctaLabel: string };
|
|
217
290
|
/** `14.3` — the whole module blew up. */
|
|
218
291
|
moduleError: { title: string; ctaLabel: string; quitLabel: string };
|
|
219
|
-
/** `14.4` — connectivity.
|
|
220
|
-
|
|
292
|
+
/** `14.4` — connectivity. The supporting line is the generic family's
|
|
293
|
+
* (`ErrorScreensStrings.noConnection.subtitle`), so this screen reads
|
|
294
|
+
* like every other module's connectivity screen (#F-34, #PI-8). */
|
|
295
|
+
noConnection: { title: string; subtitle?: string; ctaLabel: string; quitLabel: string };
|
|
221
296
|
};
|
|
222
297
|
}
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import React, { forwardRef, type ReactNode } from 'react';
|
|
2
|
+
import {
|
|
3
|
+
IconChevronDown,
|
|
4
|
+
IconChevronLeft,
|
|
5
|
+
IconChevronRight,
|
|
6
|
+
IconChevronUp,
|
|
7
|
+
} from '@incodetech/prizma-core-icons';
|
|
8
|
+
import { PrizmaSelfieCapture } from '@incodetech/prizma-core-web/selfie-capture';
|
|
9
|
+
import { PrizmaStepper } from '@incodetech/prizma-core-web/stepper';
|
|
10
|
+
import { PrizmaScreenShell, type PrizmaScreenShellProps } from './ScreenShell';
|
|
11
|
+
import type { PrizmaScreenActionHandler, PrizmaScreenOverrides } from './types';
|
|
12
|
+
import type {
|
|
13
|
+
VideoSelfieDocumentType,
|
|
14
|
+
VideoSelfieStrings,
|
|
15
|
+
VideoSelfieTurnDirection,
|
|
16
|
+
} from './VideoSelfieStrings';
|
|
17
|
+
import './ScreenLayout.css';
|
|
18
|
+
import './ViewfinderScreen.css';
|
|
19
|
+
import './VideoSelfieLayout.css';
|
|
20
|
+
|
|
21
|
+
/** The two beats each direction is drawn in: the stage ASKING (dashed guide
|
|
22
|
+
* ring) and the stage having SEEN it (the positive ring). */
|
|
23
|
+
export type VideoSelfieTurnStage = 'ask' | 'done';
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* Direction → the mark under the ring, from the canonical bank at 2xl (48) —
|
|
27
|
+
* the size the frames draw it (`element container` 342×48, the glyph centred).
|
|
28
|
+
*
|
|
29
|
+
* Since the Core and Enterprise icon unification (Sofia, 2026-10-06) the
|
|
30
|
+
* mark is the library chevron at 2xl: the four solid circle arrows left the
|
|
31
|
+
* bank (their old names now alias the chevrons). Nothing is drawn here (§10).
|
|
32
|
+
*
|
|
33
|
+
* The mark never mirrors in RTL (Sofia, 2026-10-07): a head turn is a
|
|
34
|
+
* physical direction, so the chevrons keep their LTR orientation in Hebrew.
|
|
35
|
+
* The opt-out is one scoped rule in `VideoSelfieLayout.css`; the chevrons
|
|
36
|
+
* still mirror everywhere else.
|
|
37
|
+
*/
|
|
38
|
+
const TURN_ICON: Record<VideoSelfieTurnDirection, ReactNode> = {
|
|
39
|
+
left: <IconChevronLeft size="2xl" />,
|
|
40
|
+
right: <IconChevronRight size="2xl" />,
|
|
41
|
+
up: <IconChevronUp size="2xl" />,
|
|
42
|
+
down: <IconChevronDown size="2xl" />,
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
export interface VideoSelfieTurnHeadScreenProps
|
|
46
|
+
extends Omit<PrizmaScreenShellProps, 'dark' | 'title' | 'children'> {
|
|
47
|
+
/** Module copy — this screen reads `selfieCapture.turn`. */
|
|
48
|
+
strings: VideoSelfieStrings;
|
|
49
|
+
/** Which way the user is asked to turn. Default `left`. */
|
|
50
|
+
direction?: VideoSelfieTurnDirection;
|
|
51
|
+
/** Asking, or seen. Default `ask`. */
|
|
52
|
+
stage?: VideoSelfieTurnStage;
|
|
53
|
+
/** Which document the journey collects — the Stepper's own `documentType`. */
|
|
54
|
+
documentType?: VideoSelfieDocumentType;
|
|
55
|
+
/** Live camera feed (<video>) or sample still (<img>), full-bleed behind
|
|
56
|
+
* the ring. */
|
|
57
|
+
camera?: ReactNode;
|
|
58
|
+
screenId?: string;
|
|
59
|
+
overrides?: PrizmaScreenOverrides;
|
|
60
|
+
onAction?: PrizmaScreenActionHandler;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Video Selfie — the head-turn beats of the liveness sequence (Archetype D,
|
|
65
|
+
* GUIDELINES.md §6-D; always dark). NEW 2026-09-30: the `🙂↔️ Turn Head` band
|
|
66
|
+
* of the Web / iOS / Android full-flow frames draws four directions, each in
|
|
67
|
+
* two beats, and none of them existed in the screens package — the module
|
|
68
|
+
* jumped straight from the liveness ring to the spoken steps.
|
|
69
|
+
*
|
|
70
|
+
* The frames are the liveness stage with three changes, and nothing else:
|
|
71
|
+
*
|
|
72
|
+
* - the ring is Core's GUIDE stroke (`ring="dashed"`) while the stage waits
|
|
73
|
+
* for the turn, and the positive ring once it has seen it;
|
|
74
|
+
* - the silhouette guide is ON (Core's `empty`), because the user is being
|
|
75
|
+
* asked to move their face rather than hold it still;
|
|
76
|
+
* - a small arrow chip sits between the ring and the instruction, saying
|
|
77
|
+
* which way.
|
|
78
|
+
*
|
|
79
|
+
* The mark under the ring is a canonical bank glyph at 2xl — the disc is part
|
|
80
|
+
* of the drawing, not something this screen paints. `PrizmaTitle.icon` takes
|
|
81
|
+
* `status | spinner | none` only (DEVIATIONS #10), so the block below the ring
|
|
82
|
+
* is composed here; it declares a gap and nothing else. CORE REQUEST stands: a
|
|
83
|
+
* `glyph` slot on the capture stage, so this and Face Capture's future hint
|
|
84
|
+
* marks share one component. DEVIATIONS #VS-20.
|
|
85
|
+
*/
|
|
86
|
+
export const VideoSelfieTurnHeadScreen = forwardRef<
|
|
87
|
+
HTMLDivElement,
|
|
88
|
+
VideoSelfieTurnHeadScreenProps
|
|
89
|
+
>(
|
|
90
|
+
(
|
|
91
|
+
{
|
|
92
|
+
strings,
|
|
93
|
+
direction = 'left',
|
|
94
|
+
stage = 'ask',
|
|
95
|
+
documentType = 'id',
|
|
96
|
+
camera,
|
|
97
|
+
screenId = `video-selfie-turn-${direction}-${stage}`,
|
|
98
|
+
overrides,
|
|
99
|
+
onAction,
|
|
100
|
+
className,
|
|
101
|
+
...shell
|
|
102
|
+
},
|
|
103
|
+
ref,
|
|
104
|
+
) => (
|
|
105
|
+
<PrizmaScreenShell
|
|
106
|
+
ref={ref}
|
|
107
|
+
dark
|
|
108
|
+
/* The camera owns the whole window, never a column of it — see the
|
|
109
|
+
contract note in `VideoSelfieLayout.css`. */
|
|
110
|
+
data-pcs-overlay="window"
|
|
111
|
+
className={className}
|
|
112
|
+
{...shell}
|
|
113
|
+
>
|
|
114
|
+
<div className="prizma-viewfinder__surface">{camera}</div>
|
|
115
|
+
<div className="video-selfie-stepper">
|
|
116
|
+
<PrizmaStepper
|
|
117
|
+
steps={7}
|
|
118
|
+
currentState={4}
|
|
119
|
+
documentType={documentType}
|
|
120
|
+
completedValueText={strings.stepperCompletedLabel}
|
|
121
|
+
/>
|
|
122
|
+
</div>
|
|
123
|
+
<div
|
|
124
|
+
className={[
|
|
125
|
+
'prizma-viewfinder__content',
|
|
126
|
+
overrides?.align === 'left' ? 'prizma-viewfinder__content--left' : '',
|
|
127
|
+
]
|
|
128
|
+
.filter(Boolean)
|
|
129
|
+
.join(' ')}
|
|
130
|
+
>
|
|
131
|
+
<div className="video-selfie-band video-selfie-band--ring">
|
|
132
|
+
<PrizmaSelfieCapture
|
|
133
|
+
mode="overlay"
|
|
134
|
+
scrim
|
|
135
|
+
/* The ring says WHICH WAY: the half on the side being asked for
|
|
136
|
+
is dashed while the stage waits and positive once it has seen
|
|
137
|
+
the turn, and the other half stays the neutral track. The state
|
|
138
|
+
is `filled` on both beats — the verdict lives in the arc, not in
|
|
139
|
+
the whole ring, so nothing else about the stage changes. */
|
|
140
|
+
guide={{ side: direction, state: stage === 'ask' ? 'waiting' : 'seen' }}
|
|
141
|
+
state="filled"
|
|
142
|
+
showFeedback={false}
|
|
143
|
+
/>
|
|
144
|
+
{/* Both beats carry the SAME chip and the same instruction — the
|
|
145
|
+
frames change only the ring. Nothing is announced on the turn
|
|
146
|
+
itself, which is why the stage is handed no `statusLabels`: in
|
|
147
|
+
overlay mode a verdict with no copy is a ring colour, not a
|
|
148
|
+
message. */}
|
|
149
|
+
<div className="video-selfie-turn">
|
|
150
|
+
<span className="video-selfie-turn__mark">{TURN_ICON[direction]}</span>
|
|
151
|
+
<p className="prizma-viewfinder__title">
|
|
152
|
+
{strings.selfieCapture.turn[direction]}
|
|
153
|
+
</p>
|
|
154
|
+
</div>
|
|
155
|
+
</div>
|
|
156
|
+
</div>
|
|
157
|
+
</PrizmaScreenShell>
|
|
158
|
+
),
|
|
159
|
+
);
|
|
160
|
+
VideoSelfieTurnHeadScreen.displayName = 'VideoSelfieTurnHeadScreen';
|
|
161
|
+
|
|
162
|
+
export default VideoSelfieTurnHeadScreen;
|