diff --git a/packages/constants/onboarding-data.js b/packages/constants/onboarding-data.js
new file mode 100644
index 000000000..5951bc33d
--- /dev/null
+++ b/packages/constants/onboarding-data.js
@@ -0,0 +1,46 @@
+export const UNCONFIRMED_REQUEST = {
+ status: 'pending',
+ requestType: 'delete',
+ requestStatus: 'pending',
+ emails: [
+ {id: 'dummy@datawallet.com', status: 'confirmed'},
+ {id: 'dummy@datawallet.com', status: 'pending'},
+ ],
+ phones: [{id: '+13224324234', status: 'confirmed'}],
+ addresses: [
+ {
+ line1: 'Dummy address1',
+ line2: 'Dummy address2',
+ zip: '12345',
+ state: 'DU',
+ status: 'confirmed',
+ },
+ ],
+ identity: {
+ firstName: 'dummy first name',
+ lastName: 'dummy last name',
+ middleNames: 'dummy middle name',
+ },
+};
+
+export const CONFIRMED_REQUEST = {
+ status: 'pending',
+ requestType: 'delete',
+ requestStatus: 'pending',
+ emails: [{id: 'dummy@datawallet.com', status: 'confirmed'}],
+ phones: [{id: '+13224324234', status: 'confirmed'}],
+ addresses: [
+ {
+ line1: 'Dummy address1',
+ line2: 'Dummy address2',
+ zip: '12345',
+ state: 'DU',
+ status: 'confirmed',
+ },
+ ],
+ identity: {
+ firstName: 'dummy first name',
+ lastName: 'dummy last name',
+ middleNames: 'dummy middle name',
+ },
+};
diff --git a/packages/no-account-app/src/app.js b/packages/no-account-app/src/app.js
index d98ef9aae..9058c4ddf 100644
--- a/packages/no-account-app/src/app.js
+++ b/packages/no-account-app/src/app.js
@@ -4,7 +4,10 @@ import {Route} from 'react-router-dom';
import {injectIntl} from 'react-intl';
import Container from '@datawallet/ui/components/data-lookup/container';
+import Onboarding from '@datawallet/ui/components/onboarding/index';
+import TourEnded from '@datawallet/ui/modals/dashboard/tour-ended';
+import OnboardingState from './state/onboarding';
import Theme from './state/theme';
import Company from './state/company';
@@ -23,8 +26,20 @@ const App = ({intl}) => {
const {publicData} = Company.useContainer();
const {theme} = Theme.useContainer();
const {brandSettings} = theme.global;
-
const companyName = publicData && publicData.name;
+ const {
+ onBoardingStep,
+ tourOpen,
+ nextStep,
+ prevStep,
+ pauseTour,
+ endTour,
+ tourEnded,
+ startTour,
+ openTourEndedModal,
+ closeTourEndedModal,
+ ONBOARDING_STEPS,
+ } = OnboardingState.useContainer();
return (
@@ -37,6 +52,10 @@ const App = ({intl}) => {
}}
minBoxHeight="100vh"
helpUrl={publicData && publicData.helpUrl}
+ showTour={!tourEnded && !openTourEndedModal}
+ tourEnded={tourEnded}
+ tourOpen={tourOpen}
+ startTour={() => startTour({delay: 1000})}
>
{
{companyName},
)}
/>
-
@@ -62,6 +80,30 @@ const App = ({intl}) => {
+ {openTourEndedModal && (
+ <>
+
+ >
+ )}
+ {tourOpen && (
+ nextStep({delay: 200})}
+ prevStep={() => prevStep({delay: 100})}
+ startAt={onBoardingStep}
+ goToStep={onBoardingStep}
+ endTour={endTour}
+ rounded={18}
+ scrollOffset={10}
+ disableInteraction
+ />
+ )}
);
diff --git a/packages/no-account-app/src/index.js b/packages/no-account-app/src/index.js
index 21210e876..f1fdba3cf 100644
--- a/packages/no-account-app/src/index.js
+++ b/packages/no-account-app/src/index.js
@@ -9,6 +9,7 @@ import '@datawallet/ui/css/base.css';
import App from './app';
import Theme from './state/theme';
import Company from './state/company';
+import Onboarding from './state/onboarding';
function IntlApp({defaultMessages}) {
const {messages} = Intl.useContainer();
@@ -31,11 +32,13 @@ export default function Root({messages}) {
return (
-
-
-
-
-
+
+
+
+
+
+
+
);
diff --git a/packages/no-account-app/src/screens/confirm-identity.js b/packages/no-account-app/src/screens/confirm-identity.js
index 24cce41b8..b3b623c89 100644
--- a/packages/no-account-app/src/screens/confirm-identity.js
+++ b/packages/no-account-app/src/screens/confirm-identity.js
@@ -4,7 +4,14 @@ import {Box} from 'grommet';
import ConfirmIdentity from '@datawallet/ui/screens/data-lookup/confirm-identity';
import {ACTIONS} from '@datawallet/constants/cosmos';
-import {CONFIRMED} from '@datawallet/common/shared/request-service-statuses';
+import {
+ CONFIRMED,
+ PENDING,
+} from '@datawallet/common/shared/request-service-statuses';
+import {
+ UNCONFIRMED_REQUEST,
+ CONFIRMED_REQUEST,
+} from '@datawallet/constants/onboarding-data';
import ConfirmModal from '@datawallet/ui/modals/confirm';
import FormattedText from '@datawallet/ui/components/formatted-text';
import {
@@ -18,6 +25,7 @@ import {
updateUserIdentity,
startLookupProcess,
} from '../services/data-lookup';
+import OnboardingState from '../state/onboarding';
const ConfirmIdentityContainer = ({history, match}) => {
const {id} = match.params;
@@ -26,7 +34,7 @@ const ConfirmIdentityContainer = ({history, match}) => {
const [showConfirmModal, setShowConfirmModal] = useState(false);
const [submittingRequest, setSubmittingRequest] = useState(false);
const [request, setRequest] = useState({
- status: 'pending',
+ status: PENDING,
requestType: undefined,
requestStatus: undefined,
emails: [],
@@ -47,11 +55,20 @@ const ConfirmIdentityContainer = ({history, match}) => {
status,
requestStatus,
} = request;
+ const {dummyUser} = OnboardingState.useContainer();
const fetchUser = useCallback(async () => {
+ if (dummyUser && id === 'unconfirmed') {
+ setRequest(UNCONFIRMED_REQUEST);
+ return;
+ }
+ if (dummyUser && (id === 'confirmed' || id === 'confirmed-accepted')) {
+ setRequest(CONFIRMED_REQUEST);
+ return;
+ }
const user = await retrieveUserData(id);
setRequest(user);
- }, [id]);
+ }, [id, dummyUser]);
useEffect(() => {
if (id) {
diff --git a/packages/no-account-app/src/screens/request-form.js b/packages/no-account-app/src/screens/request-form.js
index e396c177c..53265c7af 100644
--- a/packages/no-account-app/src/screens/request-form.js
+++ b/packages/no-account-app/src/screens/request-form.js
@@ -8,6 +8,7 @@ import RequestForm from '@datawallet/ui/screens/data-lookup/request-form';
import Back from '@datawallet/ui/components/back';
import Company from '../state/company';
+import OnboardingState from '../state/onboarding';
import {sendRequestForm} from '../services/data-lookup';
const recaptchaSiteKey = process.env.RECAPTCHA_SITE_KEY;
@@ -18,6 +19,7 @@ const RequestFormContainer = ({
match,
}) => {
const {publicData} = Company.useContainer();
+ const {dummyUser} = OnboardingState.useContainer();
const {privacyUrl} = publicData;
const {requestType} = match.params;
const [submitting, setSubmitting] = useState(false);
@@ -54,6 +56,7 @@ const RequestFormContainer = ({
modules={getAvailableModules(requestType)}
requiredIdentityPieces={minRequirements(requestType)}
recaptchaSiteKey={recaptchaSiteKey}
+ dummyUser={dummyUser}
/>
>
);
diff --git a/packages/no-account-app/src/state/onboarding.js b/packages/no-account-app/src/state/onboarding.js
new file mode 100644
index 000000000..327d005a1
--- /dev/null
+++ b/packages/no-account-app/src/state/onboarding.js
@@ -0,0 +1,174 @@
+import {useState, useEffect} from 'react';
+import {useHistory, useLocation} from 'react-router';
+import {createContainer} from 'unstated-next';
+import {
+ ONBOARDING_LANDING,
+ ONBOARDING_REQUEST_TYPE,
+ ONBOARDING_CONTACT_SECTIION,
+ ONBOARDING_EMAIL,
+ ONBOARDING_IDENTITY,
+ ONBOARDING_PHONE,
+ ONBOARDING_CONFIRMATION,
+ ONBOARDING_CONFIRMED_EMAIL,
+ ONBOARDING_PENDING_EMAIL,
+ ONBOARDING_ADD_MORE,
+ ONBOARDING_CONFIRM_EMAIL,
+ ONBOARDING_DELETE_EMAIL,
+ ONBOARDING_CONFIRMED,
+ ONBOARDING_DECLARATION,
+ ONBOARDING_DECLARATION_ACCEPTED,
+} from '@datawallet/ui/components/onboarding/no-account-steps';
+import {
+ ONBOARDING_STEP,
+ ONBOARDING_ENDED,
+ ONBOARDING_ENDED_MODAL,
+ ONBOARDING_TOUR_OPEN,
+} from '@datawallet/constants/onboarding';
+
+const ONBOARDING_DELAY = 1000;
+export const ONBOARDING_NEXT = 'NEXT';
+export const ONBOARDING_PREV = 'PREV';
+
+export function useOnboarding() {
+ const {push: redirect} = useHistory();
+ const {pathname} = useLocation();
+ const [tourOpen, setTourOpen] = useState(
+ localStorage.getItem(ONBOARDING_TOUR_OPEN) === 'true',
+ );
+ const localStorageStep = localStorage.getItem(ONBOARDING_STEP);
+ const [onBoardingStep, setOnBoardingStep] = useState(
+ localStorageStep ? Number(localStorageStep) : 0,
+ );
+ const [action, setAction] = useState(null);
+ const [dummyUser, setDummyUser] = useState(true);
+ const [tourEnded, setTourEnded] = useState(
+ localStorage.getItem(ONBOARDING_ENDED) === 'true',
+ );
+
+ const ONBOARDING_STEPS = [
+ ONBOARDING_LANDING,
+ ONBOARDING_CONTACT_SECTIION,
+ ONBOARDING_REQUEST_TYPE,
+ ONBOARDING_EMAIL,
+ ONBOARDING_PHONE,
+ ONBOARDING_IDENTITY,
+ ONBOARDING_CONFIRMATION,
+ ONBOARDING_CONFIRMED_EMAIL,
+ ONBOARDING_PENDING_EMAIL,
+ ONBOARDING_CONFIRM_EMAIL,
+ ONBOARDING_DELETE_EMAIL,
+ ONBOARDING_ADD_MORE,
+ ONBOARDING_DECLARATION,
+ ONBOARDING_DECLARATION_ACCEPTED,
+ ONBOARDING_CONFIRMED,
+ ];
+
+ const [openTourEndedModal, setTourEndedModal] = useState(
+ localStorage.getItem(ONBOARDING_ENDED_MODAL) === 'true',
+ );
+
+ useEffect(() => {
+ localStorage.setItem(ONBOARDING_STEP, onBoardingStep);
+ }, [onBoardingStep]);
+ useEffect(() => {
+ localStorage.setItem(ONBOARDING_TOUR_OPEN, tourOpen);
+ }, [tourOpen]);
+ useEffect(() => {
+ localStorage.setItem(ONBOARDING_ENDED, tourEnded);
+ }, [tourEnded]);
+ useEffect(() => {
+ localStorage.setItem(ONBOARDING_ENDED_MODAL, openTourEndedModal);
+ }, [openTourEndedModal]);
+
+ const prevStep = ({delay}) => {
+ const prev = onBoardingStep - 1;
+ setOnBoardingStep(prev);
+ if (ONBOARDING_STEPS[prev].redirect) {
+ setTourOpen(false);
+ redirect(ONBOARDING_STEPS[prev].redirect);
+ if (delay) {
+ setTimeout(() => setTourOpen(true), delay);
+ } else {
+ setTourOpen(true);
+ }
+ }
+ setAction(ONBOARDING_PREV);
+ };
+
+ const pauseTour = () => {
+ setTourOpen(false);
+ setDummyUser(false);
+ };
+ const startTour = ({delay}) => {
+ if (
+ ONBOARDING_STEPS[onBoardingStep] &&
+ pathname !== ONBOARDING_STEPS[onBoardingStep].redirect
+ ) {
+ redirect(ONBOARDING_STEPS[onBoardingStep].redirect);
+ }
+ if (!onBoardingStep) {
+ setOnBoardingStep(0);
+ setTourEnded(false);
+ }
+
+ setDummyUser(true);
+ if (delay) {
+ setTimeout(() => setTourOpen(true), ONBOARDING_DELAY);
+ } else {
+ setTourOpen(true);
+ }
+ };
+
+ const endTour = () => {
+ setTourEnded(true);
+ setTourEndedModal(true);
+ setTourOpen(false);
+ setOnBoardingStep(null);
+ setDummyUser(false);
+ redirect('/');
+ };
+
+ const nextStep = ({delay}) => {
+ const next = onBoardingStep + 1;
+ if (next >= ONBOARDING_STEPS.length) {
+ return endTour();
+ }
+ setOnBoardingStep(next);
+ if (ONBOARDING_STEPS[next].redirect) {
+ setTourOpen(false);
+ redirect(ONBOARDING_STEPS[next].redirect);
+ if (delay) {
+ setTimeout(() => setTourOpen(true), delay);
+ } else {
+ setTourOpen(true);
+ }
+ }
+ return setAction(ONBOARDING_NEXT);
+ };
+
+ const closeTourEndedModal = () => {
+ setTourEndedModal(false);
+ };
+ return {
+ tourEnded,
+ setTourEnded,
+ onBoardingStep,
+ setOnBoardingStep,
+ tourOpen,
+ setTourOpen,
+ openTourEndedModal,
+ setTourEndedModal,
+ nextStep,
+ prevStep,
+ pauseTour,
+ startTour,
+ endTour,
+ action,
+ closeTourEndedModal,
+ dummyUser,
+ ONBOARDING_STEPS,
+ };
+}
+
+const Onboarding = createContainer(useOnboarding);
+export default Onboarding;
diff --git a/packages/storybook/__snapshots__/storyshots.test.js.snap b/packages/storybook/__snapshots__/storyshots.test.js.snap
index 8e57362c5..d8912ace8 100644
--- a/packages/storybook/__snapshots__/storyshots.test.js.snap
+++ b/packages/storybook/__snapshots__/storyshots.test.js.snap
@@ -20150,7 +20150,7 @@ exports[`Storyshots Screens/Data Lookup Confirm Identity - Already submitted + f
}
>