Skip to content

Commit

Permalink
try to download application file on email submit - no verification
Browse files Browse the repository at this point in the history
  • Loading branch information
jamdelion committed Nov 21, 2024
1 parent 40c1f2d commit 766abcc
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 41 deletions.
10 changes: 5 additions & 5 deletions api.planx.uk/modules/send/email/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
export const sendToEmail: SendIntegrationController = async (
req,
res,
next,
next
) => {
req.setTimeout(120 * 1000); // Temporary bump to address submission timeouts

Expand All @@ -33,7 +33,7 @@ export const sendToEmail: SendIntegrationController = async (
// Get the applicant email and flow slug associated with the session
const { email, flow } = await getSessionEmailDetailsById(sessionId);
const flowName = flow.name;
const serviceURL = `${process.env.EDITOR_URL_EXT}/${localAuthority}/${flow.slug}`;
const serviceURL = `${process.env.EDITOR_URL_EXT}/${localAuthority}/${flow.slug}/${sessionId}`;

// Prepare email template
const config: EmailSubmissionNotifyConfig = {
Expand All @@ -42,7 +42,7 @@ export const sendToEmail: SendIntegrationController = async (
sessionId,
applicantEmail: email,
// downloadLink: `${process.env.API_URL_EXT}/download-application-files/${sessionId}?email=${teamSettings.submissionEmail}&localAuthority=${localAuthority}`,
downloadLink: `${serviceURL}/verify-email`,
downloadLink: `${serviceURL}/verify-email`, // redirect to verify email before download
...teamSettings,
},
};
Expand All @@ -51,7 +51,7 @@ export const sendToEmail: SendIntegrationController = async (
const response = await sendEmail(
"submit",
teamSettings.submissionEmail,
config,
config
);

// Mark session as submitted so that reminder and expiry emails are not triggered
Expand All @@ -63,7 +63,7 @@ export const sendToEmail: SendIntegrationController = async (
localAuthority,
teamSettings.submissionEmail,
config,
response,
response
);

return res.status(200).send({
Expand Down
26 changes: 14 additions & 12 deletions api.planx.uk/modules/send/email/service.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { gql } from "graphql-request";
import { $api } from "../../../client/index.js";
import type {
Session,
TeamContactSettings,
} from "@opensystemslab/planx-core/types";
import { gql } from "graphql-request";
import { $api } from "../../../client/index.js";
import type { EmailSubmissionNotifyConfig } from "../../../types.js";

interface GetTeamEmailSettings {
Expand All @@ -12,9 +12,7 @@ interface GetTeamEmailSettings {
}[];
}

export async function getTeamEmailSettings(localAuthority: string) {
const response = await $api.client.request<GetTeamEmailSettings>(
gql`
export const TEAM_EMAIL_SETTINGS_QUERY = `
query GetTeamEmailSettings($slug: String) {
teams(where: { slug: { _eq: $slug } }) {
teamSettings: team_settings {
Expand All @@ -26,10 +24,14 @@ export async function getTeamEmailSettings(localAuthority: string) {
}
}
}
`,
`;

export async function getTeamEmailSettings(localAuthority: string) {
const response = await $api.client.request<GetTeamEmailSettings>(
gql`${TEAM_EMAIL_SETTINGS_QUERY}`,
{
slug: localAuthority,
},
}
);

return response?.teams[0];
Expand All @@ -50,7 +52,7 @@ export async function getSessionData(sessionId: string) {
`,
{
id: sessionId,
},
}
);

return response?.session?.data;
Expand Down Expand Up @@ -81,12 +83,12 @@ export async function getSessionEmailDetailsById(sessionId: string) {
`,
{
id: sessionId,
},
}
);

if (!response.session)
throw Error(
`Cannot find session ${sessionId} in GetSessionEmailDetails query`,
`Cannot find session ${sessionId} in GetSessionEmailDetails query`
);

return response.session;
Expand All @@ -106,7 +108,7 @@ export async function insertAuditEntry(
sendEmailResponse: {
message: string;
expiryDate?: string;
},
}
) {
const response = await $api.client.request<CreateEmailApplication>(
gql`
Expand Down Expand Up @@ -136,7 +138,7 @@ export async function insertAuditEntry(
recipient: recipient,
request: notifyRequest,
response: sendEmailResponse,
},
}
);

return response?.application?.id;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,5 @@ export default meta;
type Story = StoryObj<typeof meta>;

export const Basic = {
render: () => <VerifyEmail />,
render: () => <VerifyEmail params={{ sessionId: "1" }} />,
};
34 changes: 25 additions & 9 deletions editor.planx.uk/src/pages/VerifyEmail/VerifyEmail.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,46 @@
import { gql, useQuery } from "@apollo/client";
import Box from "@mui/material/Box";
import Container from "@mui/material/Container";
import Typography from "@mui/material/Typography";
import Card from "@planx/components/shared/Preview/Card";
import { CardHeader } from "@planx/components/shared/Preview/CardHeader/CardHeader";
import { useFormik } from "formik";
import React from "react";
import React, { useMemo } from "react";
import InputLabel from "ui/public/InputLabel";
import Input from "ui/shared/Input/Input";
import InputRow from "ui/shared/InputRow";
import { object, string } from "yup";
import { TEAM_EMAIL_SETTINGS_QUERY } from "./../../../../api.planx.uk/modules/send/email/service";

const verifyEmailSchema = object({
email: string().email("Invalid email").required("Email address required"),
});

// interface VerifyEmailProps {
// handleSubmit: (email: string) => void;
// }
interface VerifyEmailProps {
params: Record<string, string>;
}

// export const VerifyEmail = ({
// handleSubmit,
// }: VerifyEmailProps): JSX.Element => {
export const VerifyEmail = ({ params }: VerifyEmailProps): JSX.Element => {
const { sessionId, team } = params;

const { data, loading, error } = useQuery(
gql`
${TEAM_EMAIL_SETTINGS_QUERY}
`,
{
variables: { slug: team },
}
);

const teamEmail = useMemo(
() => data?.teamSettings.submissionEmail || null,
[data]
);

export const VerifyEmail = (): JSX.Element => {
const handleSubmit = (email: string) => {
console.log("submitting!", email);
console.log("need to validate this email!", email);
const url = `${process.env.API_URL_EXT}/download-application-files/${sessionId}?email=${teamEmail}&localAuthority=${team}`;
window.open(url, "_blank");
};

const formik = useFormik({
Expand Down
30 changes: 16 additions & 14 deletions editor.planx.uk/src/routes/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ import { compose, lazy, map, mount, redirect, route, withView } from "navi";
import { loadingView } from "pages/layout/LoadingLayout";
import * as React from "react";

import { VerifyEmail } from "pages/VerifyEmail/VerifyEmail";
import { client } from "../lib/graphql";
import ErrorPage from "../pages/ErrorPage";
import Login from "../pages/Login";
import { isPreviewOnlyDomain, makeTitle } from "./utils";
import { VerifyEmail } from "pages/VerifyEmail/VerifyEmail";

type RoutingContext = {
currentUser?: any;
Expand All @@ -23,17 +23,19 @@ const editorRoutes = mount({
? redirect(
req.params.redirectTo
? decodeURIComponent(req.params.redirectTo)
: "/",
: "/"
)
: route({
title: makeTitle("Login"),
view: <Login />,
}),
})
),

":team/:flow/verify-email": route({
title: makeTitle("Verify your email"),
view: <VerifyEmail />,
":team/:flow/:sessionId/verify-email": map((req) => {
return route({
title: makeTitle("Verify your email"),
view: <VerifyEmail params={req.params} />,
});
}),

"/logout": map((): any => {
Expand All @@ -47,7 +49,7 @@ const editorRoutes = mount({
document.cookie = cookieString;
// remove jwt cookie for planx domains (staging and production)
document.cookie = cookieString.concat(
` domain=.${window.location.host};`,
` domain=.${window.location.host};`
);
// redirect to editor landing page with no jwt cookie set
window.location.href = "/";
Expand All @@ -59,32 +61,32 @@ const editorRoutes = mount({
? lazy(() => import("./authenticated"))
: redirect(`/login/?redirectTo=${encodeURIComponent(req.originalUrl)}`, {
exact: false,
}),
})
),
});

const loadPayRoutes = () =>
compose(
withView(loadingView),
lazy(() => import("./pay")),
lazy(() => import("./pay"))
);

const loadPublishedRoutes = () =>
compose(
withView(loadingView),
lazy(() => import("./published")),
lazy(() => import("./published"))
);

const loadPreviewRoutes = () =>
compose(
withView(loadingView),
lazy(() => import("./preview")),
lazy(() => import("./preview"))
);

const loadDraftRoutes = () =>
compose(
withView(loadingView),
lazy(() => import("./draft")),
lazy(() => import("./draft"))
);

export default isPreviewOnlyDomain
Expand All @@ -100,8 +102,8 @@ export default isPreviewOnlyDomain
"/canterbury/find-out-if-you-need-planning-permission/preview": map(
async (req) =>
redirect(
`/canterbury/find-out-if-you-need-planning-permission/published${req?.search}`,
),
`/canterbury/find-out-if-you-need-planning-permission/published${req?.search}`
)
), // temporary redirect while Canterbury works with internal IT to update advertised service links
"/:team/:flow/preview": loadPreviewRoutes(), // loads current draft flow and latest published external portals, or throws Not Found if any external portal is unpublished
"/:team/:flow/draft": loadDraftRoutes(), // loads current draft flow and draft external portals
Expand Down

0 comments on commit 766abcc

Please sign in to comment.