Skip to content

Commit

Permalink
chore: allow users to request registration codes
Browse files Browse the repository at this point in the history
  • Loading branch information
Fidesnoella committed Jan 23, 2025
1 parent c6c2124 commit 08c580e
Show file tree
Hide file tree
Showing 6 changed files with 277 additions and 58 deletions.
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import React, { useCallback, useState } from "react";
import Modal from "@mui/material/Modal";

import { Box, CircularProgress, TextField, Typography, useTheme } from "@mui/material";
import { Box, CircularProgress, Link, styled, TextField, Typography, useTheme } from "@mui/material";
import PrimaryButton from "src/theme/PrimaryButton/PrimaryButton";
import PrimaryIconButton from "src/theme/PrimaryIconButton/PrimaryIconButton";
import CloseIcon from "@mui/icons-material/Close";
import RequestRegistrationFormModal from "src/auth/components/requestRegistrationFormModal/RequestRegistrationFormModal";

export enum RegistrationCodeFormModalState {
SHOW,
Expand Down Expand Up @@ -56,71 +57,94 @@ const style = {
p: 4,
};

const StyledLink = styled(Link)(({ theme }) => ({
color: theme.palette.text.textAccent,
cursor: "pointer",
textDecoration: "none",
"&:hover": {
textDecoration: "underline",
},
}));

const RegistrationCodeFormModal: React.FC<InvitationCodeFormModalProps> = ({ modalState, onSuccess, onClose }) => {
const theme = useTheme();
const [registrationCode, setRegistrationCode] = useState("");
const [isModalOpen, setIsModalOpen] = useState<boolean>(false);

const handleAcceptRegistrationCode = useCallback(async () => {
onSuccess(registrationCode);
}, [onSuccess, registrationCode]);

const handleOpenRequestModal = () => {
onClose();
setIsModalOpen(true);
};

return (
<Modal
open={modalState === RegistrationCodeFormModalState.SHOW || modalState === RegistrationCodeFormModalState.LOADING}
onClose={onClose}
aria-labelledby="modal-modal-title"
aria-describedby="modal-modal-description"
data-testid={DATA_TEST_ID.CONTAINER}
>
<Box sx={style}>
<PrimaryIconButton
data-testid={DATA_TEST_ID.CLOSE_ICON}
title="Close registration code form"
onClick={onClose}
sx={{
position: "absolute",
right: 8,
top: 8,
color: (theme) => theme.palette.grey[500],
}}
>
<CloseIcon />
</PrimaryIconButton>
<Typography variant="h4" gutterBottom data-testid={DATA_TEST_ID.MODAL_TITLE}>
Registration code
</Typography>
<Typography variant="body2" gutterBottom data-testid={DATA_TEST_ID.MODAL_SUBTITLE}>
Enter your registration code
</Typography>
<TextField
fullWidth
label="Registration code"
variant="outlined"
placeholder={"Enter your registration code"}
margin="normal"
required
onChange={(e) => setRegistrationCode(e.target.value)}
inputProps={{ "data-testid": DATA_TEST_ID.INVITATION_CODE_INPUT }}
/>
<PrimaryButton
data-testid={DATA_TEST_ID.SUBMIT_BUTTON}
fullWidth
disableWhenOffline
onClick={handleAcceptRegistrationCode}
disabled={!registrationCode.length}
>
{modalState === RegistrationCodeFormModalState.LOADING ? (
<CircularProgress
sx={{ color: (theme) => theme.palette.info.contrastText }}
size={2 * theme.typography.fontSize}
data-testid={DATA_TEST_ID.PROGRESS_ELEMENT}
/>
) : (
"Submit"
)}
</PrimaryButton>
</Box>
</Modal>
<>
<Modal
open={
modalState === RegistrationCodeFormModalState.SHOW || modalState === RegistrationCodeFormModalState.LOADING
}
onClose={onClose}
aria-labelledby="modal-modal-title"
aria-describedby="modal-modal-description"
data-testid={DATA_TEST_ID.CONTAINER}
>
<Box sx={style}>
<PrimaryIconButton
data-testid={DATA_TEST_ID.CLOSE_ICON}
title="Close registration code form"
onClick={onClose}
sx={{
position: "absolute",
right: 8,
top: 8,
color: (theme) => theme.palette.grey[500],
}}
>
<CloseIcon />
</PrimaryIconButton>
<Typography variant="h4" gutterBottom data-testid={DATA_TEST_ID.MODAL_TITLE}>
Registration code
</Typography>
<Typography variant="body2" gutterBottom data-testid={DATA_TEST_ID.MODAL_SUBTITLE}>
Enter your registration code
</Typography>
<TextField
fullWidth
label="Registration code"
variant="outlined"
placeholder={"Enter your registration code"}
margin="normal"
required
onChange={(e) => setRegistrationCode(e.target.value)}
inputProps={{ "data-testid": DATA_TEST_ID.INVITATION_CODE_INPUT }}
/>
<PrimaryButton
data-testid={DATA_TEST_ID.SUBMIT_BUTTON}
fullWidth
disableWhenOffline
onClick={handleAcceptRegistrationCode}
disabled={!registrationCode.length}
>
{modalState === RegistrationCodeFormModalState.LOADING ? (
<CircularProgress
sx={{ color: (theme) => theme.palette.info.contrastText }}
size={2 * theme.typography.fontSize}
data-testid={DATA_TEST_ID.PROGRESS_ELEMENT}
/>
) : (
"Submit"
)}
</PrimaryButton>
<Typography variant="body2" sx={{ marginY: 2, textAlign: "center" }}>
If you don't have a registration code, <StyledLink onClick={handleOpenRequestModal}>reach out.</StyledLink>
</Typography>
</Box>
</Modal>
<RequestRegistrationFormModal open={isModalOpen} onClose={() => setIsModalOpen(false)} />
</>
);
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,16 @@ exports[`RegistrationCodeFormModal closes the modal when the close icon is click
>
Submit
</button>
<p
class="MuiTypography-root MuiTypography-body2 css-9ril-MuiTypography-root"
>
If you don't have a registration code,
<a
class="MuiTypography-root MuiTypography-inherit MuiLink-root MuiLink-underlineAlways css-1jrfl4g-MuiTypography-root-MuiLink-root"
>
reach out.
</a>
</p>
</div>
<div
data-testid="sentinelEnd"
Expand Down Expand Up @@ -230,6 +240,16 @@ exports[`RegistrationCodeFormModal renders correctly when modal is shown and cal
>
Submit
</button>
<p
class="MuiTypography-root MuiTypography-body2 css-9ril-MuiTypography-root"
>
If you don't have a registration code,
<a
class="MuiTypography-root MuiTypography-inherit MuiLink-root MuiLink-underlineAlways css-1jrfl4g-MuiTypography-root-MuiLink-root"
>
reach out.
</a>
</p>
</div>
<div
data-testid="sentinelEnd"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import RequestRegistrationFormModal from "./RequestRegistrationFormModal";
import { Meta, StoryObj } from "@storybook/react";

const meta: Meta<typeof RequestRegistrationFormModal> = {
title: "Invitations/RequestRegistrationFormModal",
component: RequestRegistrationFormModal,
tags: ["autodocs"],
argTypes: {
onClose: { action: "close" },
},
};

export default meta;

type Story = StoryObj<typeof RequestRegistrationFormModal>;

export const Shown: Story = {
args: {
open: true,
},
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import React, { useState } from "react";
import * as Sentry from "@sentry/react";
import { useSnackbar } from "src/theme/SnackbarProvider/SnackbarProvider";
import { Box, Modal, TextField, Typography, useTheme } from "@mui/material";
import PrimaryButton from "src/theme/PrimaryButton/PrimaryButton";
import PrimaryIconButton from "src/theme/PrimaryIconButton/PrimaryIconButton";
import CloseIcon from "@mui/icons-material/Close";

export interface RequestRegistrationFormModalProps {
open: boolean;
onClose: () => void;
}

const style = {
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
maxWidth: 400,
width: "100%",
bgcolor: "background.paper",
boxShadow: 24,
borderRadius: 1,
p: 4,
};

const RequestRegistrationFormModal: React.FC<RequestRegistrationFormModalProps> = ({ open, onClose }) => {
const theme = useTheme();
const { enqueueSnackbar } = useSnackbar();

const [name, setName] = useState("");
const [email, setEmail] = useState("");
const [message, setMessage] = useState("");

const handleSubmit = async () => {
// Send the user information to Sentry
Sentry.captureFeedback({
name,
email,
message: `User requested a registration code. Additional info: ${message || "None"}`,
});

enqueueSnackbar("Registration code request submitted successfully. We will get back to you soon.", {
variant: "success",
});

resetForm();
};

// Reset the form fields and close the modal
const resetForm = () => {
setName("");
setEmail("");
setMessage("");
onClose();
};

return (
<Modal open={open} onClose={onClose}>
<Box sx={style}>
<PrimaryIconButton
title="Close request registration code form"
onClick={onClose}
sx={{
position: "absolute",
right: 8,
top: 8,
color: theme.palette.grey[500],
}}
>
<CloseIcon />
</PrimaryIconButton>
<Typography variant="h4" gutterBottom>
Registration Code Request
</Typography>
<Typography variant="body2" gutterBottom>
Your request will be reviewed, and we will reach out to you soon.
</Typography>
<TextField
fullWidth
label="Name"
type="text"
variant="outlined"
margin="normal"
required
value={name}
onChange={(e) => setName(e.target.value)}
/>
<TextField
fullWidth
label="Email"
type="email"
variant="outlined"
margin="normal"
required
value={email}
onChange={(e) => setEmail(e.target.value)}
/>
<TextField
fullWidth
placeholder="Tell us how you intend to use compass"
variant="outlined"
margin="normal"
required
multiline
rows={3}
value={message}
onChange={(e) => setMessage(e.target.value)}
/>
<PrimaryButton
disableWhenOffline={true}
fullWidth
onClick={handleSubmit}
disabled={!name || !email || !message}
>
Submit
</PrimaryButton>
</Box>
</Modal>
);
};

export default RequestRegistrationFormModal;
Loading

0 comments on commit 08c580e

Please sign in to comment.