Skip to content

Commit

Permalink
Use the new GraphQL APIs in the frontend to add emails
Browse files Browse the repository at this point in the history
  • Loading branch information
sandhose committed Jan 10, 2025
1 parent 658a39d commit 58f4749
Show file tree
Hide file tree
Showing 16 changed files with 420 additions and 620 deletions.
2 changes: 1 addition & 1 deletion frontend/locales/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,9 @@
},
"add_email_form": {
"email_denied_error": "The entered email is not allowed by the server policy",
"email_exists_error": "The entered email is already added to this account",
"email_field_help": "Add an alternative email you can use to access this account.",
"email_field_label": "Add email",
"email_in_use_error": "The entered email is already in use",
"email_invalid_error": "The entered email is invalid"
},
"browser_session_details": {
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/components/PageHeading/PageHeading.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@ type Props = {
Icon: React.ComponentType<React.SVGAttributes<SVGElement>>;
invalid?: boolean;
success?: boolean;
title: string;
subtitle?: string;
title: React.ReactNode;
subtitle?: React.ReactNode;
};

const PageHeading: React.FC<Props> = ({
Expand Down
41 changes: 20 additions & 21 deletions frontend/src/components/UserProfile/AddEmailForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,44 +15,42 @@ import { graphql } from "../../gql";
import { graphqlRequest } from "../../graphql";

const ADD_EMAIL_MUTATION = graphql(/* GraphQL */ `
mutation AddEmail($userId: ID!, $email: String!) {
addEmail(input: { userId: $userId, email: $email }) {
mutation AddEmail($email: String!, $language: String!) {
startEmailAuthentication(input: { email: $email, language: $language }) {
status
violations
email {
authentication {
id
...UserEmail_email
}
}
}
`);

const AddEmailForm: React.FC<{
userId: string;
onAdd: (id: string) => Promise<void>;
}> = ({ userId, onAdd }) => {
const { t } = useTranslation();
}> = ({ onAdd }) => {
const { t, i18n } = useTranslation();
const queryClient = useQueryClient();
const addEmail = useMutation({
mutationFn: ({ userId, email }: { userId: string; email: string }) =>
mutationFn: ({ email, language }: { email: string; language: string }) =>
graphqlRequest({
query: ADD_EMAIL_MUTATION,
variables: { userId, email },
variables: { email, language },
}),
onSuccess: async (data) => {
queryClient.invalidateQueries({ queryKey: ["userEmails"] });

// Don't clear the form if the email was invalid or already exists
if (data.addEmail.status !== "ADDED") {
if (data.startEmailAuthentication.status !== "STARTED") {
return;
}

if (!data.addEmail.email?.id) {
if (!data.startEmailAuthentication.authentication?.id) {
throw new Error("Unexpected response from server");
}

// Call the onAdd callback
await onAdd(data.addEmail.email?.id);
await onAdd(data.startEmailAuthentication.authentication?.id);
},
});

Expand All @@ -63,34 +61,35 @@ const AddEmailForm: React.FC<{

const formData = new FormData(e.currentTarget);
const email = formData.get("input") as string;
addEmail.mutate({ userId, email });
addEmail.mutate({ email, language: i18n.languages[0] });
};

const status = addEmail.data?.addEmail.status ?? null;
const violations = addEmail.data?.addEmail.violations ?? [];
const status = addEmail.data?.startEmailAuthentication.status ?? null;
const violations = addEmail.data?.startEmailAuthentication.violations ?? [];

return (
<EditInPlace
onSave={handleSubmit}
required
type="email"
serverInvalid={
status === "INVALID" || status === "EXISTS" || status === "DENIED"
}
serverInvalid={!!status && status !== "STARTED"}
label={t("frontend.add_email_form.email_field_label")}
helpLabel={t("frontend.add_email_form.email_field_help")}
saveButtonLabel={t("action.save")}
savingLabel={t("common.saving")}
savedLabel={t("common.saved")}
cancelButtonLabel={t("action.cancel")}
>
<ErrorMessage match="typeMismatch" forceMatch={status === "INVALID"}>
<ErrorMessage
match="typeMismatch"
forceMatch={status === "INVALID_EMAIL_ADDRESS"}
>
{t("frontend.add_email_form.email_invalid_error")}
</ErrorMessage>

{status === "EXISTS" && (
{status === "IN_USE" && (
<ErrorMessage>
{t("frontend.add_email_form.email_exists_error")}
{t("frontend.add_email_form.email_in_use_error")}
</ErrorMessage>
)}

Expand Down
32 changes: 0 additions & 32 deletions frontend/src/components/VerifyEmail/VerifyEmail.module.css

This file was deleted.

169 changes: 0 additions & 169 deletions frontend/src/components/VerifyEmail/VerifyEmail.tsx

This file was deleted.

Loading

0 comments on commit 58f4749

Please sign in to comment.