From bd8c5f8f735fa1a56860325b2f231800402d0a67 Mon Sep 17 00:00:00 2001 From: Abhinav Kumar <46242073+abhinavkgrd@users.noreply.github.com> Date: Wed, 29 Nov 2023 11:07:56 +0530 Subject: [PATCH] Add referral - sign-up form (#1473) * add referral field to sign up form * Added referral info * fix ui issues * clean referral before post * send referral info on verifyOTT * add ":web" suffix to referral * fix copy * Add `web:` as prefix * Update param name during verify-email --------- Co-authored-by: Neeraj Gupta --- .../photos/public/locales/en/translation.json | 2 + packages/accounts/api/user.ts | 10 +++- packages/accounts/components/SignUp.tsx | 51 +++++++++++++++++-- packages/accounts/pages/verify.tsx | 8 ++- .../shared/storage/localStorage/helpers.ts | 8 +++ packages/shared/storage/localStorage/index.ts | 1 + 6 files changed, 73 insertions(+), 7 deletions(-) diff --git a/apps/photos/public/locales/en/translation.json b/apps/photos/public/locales/en/translation.json index 63f85572c..ba29fbb37 100644 --- a/apps/photos/public/locales/en/translation.json +++ b/apps/photos/public/locales/en/translation.json @@ -38,6 +38,8 @@ "KEY_GENERATION_IN_PROGRESS_MESSAGE": "Generating encryption keys...", "PASSPHRASE_HINT": "Password", "CONFIRM_PASSPHRASE": "Confirm password", + "REFERRAL_CODE_HINT":"How did you hear abut Ente? (optional)", + "REFERRAL_INFO":"We don't track app installs, It'd help us if you told us where you found us!", "PASSPHRASE_MATCH_ERROR": "Passwords don't match", "CONSOLE_WARNING_STOP": "STOP!", "CONSOLE_WARNING_DESC": "This is a browser feature intended for developers. Please don't copy-paste unverified code here.", diff --git a/packages/accounts/api/user.ts b/packages/accounts/api/user.ts index 7bac4e05a..50e266fc4 100644 --- a/packages/accounts/api/user.ts +++ b/packages/accounts/api/user.ts @@ -25,8 +25,14 @@ export const sendOtt = (appName: APPS, email: string) => { }); }; -export const verifyOtt = (email: string, ott: string) => - HTTPService.post(`${ENDPOINT}/users/verify-email`, { email, ott }); +export const verifyOtt = (email: string, ott: string, referral: string) => { + const cleanedReferral = `web:${referral?.trim() || ''}`; + return HTTPService.post(`${ENDPOINT}/users/verify-email`, { + email, + ott, + source: cleanedReferral, + }); +}; export const putAttributes = (token: string, keyAttributes: KeyAttributes) => HTTPService.put( diff --git a/packages/accounts/components/SignUp.tsx b/packages/accounts/components/SignUp.tsx index 7705d4e84..d7e80438e 100644 --- a/packages/accounts/components/SignUp.tsx +++ b/packages/accounts/components/SignUp.tsx @@ -11,7 +11,10 @@ import { import { isWeakPassword } from '@ente/accounts/utils'; import { generateKeyAndSRPAttributes } from '@ente/accounts/utils/srp'; -import { setJustSignedUp } from '@ente/shared/storage/localStorage/helpers'; +import { + setJustSignedUp, + setLocalReferralSource, +} from '@ente/shared/storage/localStorage/helpers'; import { SESSION_KEYS } from '@ente/shared/storage/sessionStorage'; import { PAGES } from '@ente/accounts/constants/pages'; import { @@ -19,8 +22,11 @@ import { Checkbox, FormControlLabel, FormGroup, + IconButton, + InputAdornment, Link, TextField, + Tooltip, Typography, } from '@mui/material'; import FormPaperTitle from '@ente/shared/components/Form/FormPaper/Title'; @@ -34,11 +40,13 @@ import ShowHidePassword from '@ente/shared/components/Form/ShowHidePassword'; import { APPS } from '@ente/shared/apps/constants'; import { NextRouter } from 'next/router'; import { logError } from '@ente/shared/sentry'; +import InfoOutlined from '@mui/icons-material/InfoOutlined'; interface FormValues { email: string; passphrase: string; confirm: string; + referral: string; } interface SignUpProps { @@ -63,7 +71,7 @@ export default function SignUp({ router, appName, login }: SignUpProps) { }; const registerUser = async ( - { email, passphrase, confirm }: FormValues, + { email, passphrase, confirm, referral }: FormValues, { setFieldError }: FormikHelpers ) => { try { @@ -74,6 +82,7 @@ export default function SignUp({ router, appName, login }: SignUpProps) { setLoading(true); try { setData(LS_KEYS.USER, { email }); + setLocalReferralSource(referral); await sendOtt(appName, email); } catch (e) { setFieldError('confirm', `${t('UNKNOWN_ERROR')} ${e.message}`); @@ -115,6 +124,7 @@ export default function SignUp({ router, appName, login }: SignUpProps) { email: '', passphrase: '', confirm: '', + referral: '', }} validationSchema={Yup.object().shape({ email: Yup.string() @@ -192,12 +202,47 @@ export default function SignUp({ router, appName, login }: SignUpProps) { + + + + {t('REFERRAL_CODE_HINT')} + + + + + + + + + ), + }} + fullWidth + name="referral" + type="text" + value={values.referral} + onChange={handleChange('referral')} + error={Boolean(errors.referral)} + disabled={loading} + /> + - + { try { - const resp = await verifyOtt(email, ott); + const referralSource = getLocalReferralSource(); + const resp = await verifyOtt(email, ott, referralSource); const { keyAttributes, encryptedToken, diff --git a/packages/shared/storage/localStorage/helpers.ts b/packages/shared/storage/localStorage/helpers.ts index fb95d0498..91970e77f 100644 --- a/packages/shared/storage/localStorage/helpers.ts +++ b/packages/shared/storage/localStorage/helpers.ts @@ -57,3 +57,11 @@ export function getLocalSentryUserID() { export function setLocalSentryUserID(id: string) { setData(LS_KEYS.AnonymizedUserID, { id }); } + +export function getLocalReferralSource() { + return getData(LS_KEYS.REFERRAL_SOURCE)?.source; +} + +export function setLocalReferralSource(source: string) { + setData(LS_KEYS.REFERRAL_SOURCE, { source }); +} diff --git a/packages/shared/storage/localStorage/index.ts b/packages/shared/storage/localStorage/index.ts index d9a61e992..5dc7ce5ca 100644 --- a/packages/shared/storage/localStorage/index.ts +++ b/packages/shared/storage/localStorage/index.ts @@ -27,6 +27,7 @@ export enum LS_KEYS { SRP_ATTRIBUTES = 'srpAttributes', OPT_OUT_OF_CRASH_REPORTS = 'optOutOfCrashReports', CF_PROXY_DISABLED = 'cfProxyDisabled', + REFERRAL_SOURCE = 'referralSource', } export const setData = (key: LS_KEYS, value: object) => {