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 <neeraj.gupta983@gmail.com>
This commit is contained in:
Abhinav Kumar 2023-11-29 11:07:56 +05:30 committed by GitHub
parent e3ad4cc21f
commit bd8c5f8f73
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 73 additions and 7 deletions

View file

@ -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.",

View file

@ -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(

View file

@ -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<FormValues>
) => {
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) {
<PasswordStrengthHint
password={values.passphrase}
/>
<Box sx={{ width: '100%' }}>
<Typography
textAlign={'left'}
color="text.secondary"
mt={'24px'}>
{t('REFERRAL_CODE_HINT')}
</Typography>
<TextField
hiddenLabel
InputProps={{
endAdornment: (
<InputAdornment position="end">
<Tooltip
title={t('REFERRAL_INFO')}>
<IconButton
tabIndex={-1}
color="secondary"
edge={'end'}>
<InfoOutlined />
</IconButton>
</Tooltip>
</InputAdornment>
),
}}
fullWidth
name="referral"
type="text"
value={values.referral}
onChange={handleChange('referral')}
error={Boolean(errors.referral)}
disabled={loading}
/>
</Box>
<FormGroup sx={{ width: '100%' }}>
<FormControlLabel
sx={{
color: 'text.muted',
ml: 0,
mt: 2,
mb: 0,
}}
control={
<Checkbox
@ -234,7 +279,7 @@ export default function SignUp({ router, appName, login }: SignUpProps) {
/>
</FormGroup>
</VerticallyCentered>
<Box my={4}>
<Box mb={4}>
<SubmitButton
sx={{ my: 0 }}
buttonText={t('CREATE_ACCOUNT')}

View file

@ -7,7 +7,10 @@ import { verifyOtt, sendOtt, putAttributes } from '../api/user';
import { logoutUser } from '../services/user';
import { configureSRP } from '../services/srp';
import { clearFiles } from '@ente/shared/storage/localForage/helpers';
import { setIsFirstLogin } from '@ente/shared/storage/localStorage/helpers';
import {
getLocalReferralSource,
setIsFirstLogin,
} from '@ente/shared/storage/localStorage/helpers';
import { clearKeys } from '@ente/shared/storage/sessionStorage';
import { PAGES } from '../constants/pages';
import { KeyAttributes, User } from '@ente/shared/user/types';
@ -58,7 +61,8 @@ export default function VerifyPage({ appContext, router, appName }: PageProps) {
setFieldError
) => {
try {
const resp = await verifyOtt(email, ott);
const referralSource = getLocalReferralSource();
const resp = await verifyOtt(email, ott, referralSource);
const {
keyAttributes,
encryptedToken,

View file

@ -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 });
}

View file

@ -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) => {