Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Add Preview/Draft Layout Wrapper for Testing Links #4090

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 29 additions & 10 deletions editor.planx.uk/src/@planx/components/shared/Preview/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,17 @@ import { useStore } from "pages/FlowEditor/lib/store";
import React, { useEffect } from "react";
import { ApplicationPath } from "types";

import SaveResumeButton from "./SaveResumeButton";
import OrNavigationButton from "./OrNavigationButton";

interface Props {
children: React.ReactNode;
isValid?: boolean;
isTestWarningWrapper?: boolean;
RODO94 marked this conversation as resolved.
Show resolved Hide resolved
handleSubmit?: (data?: any) => void;
}

export type OrNavigationType = "save-resume" | "navigate-to-published";

export const contentFlowSpacing = (theme: Theme): React.CSSProperties => ({
marginTop: theme.spacing(2),
[theme.breakpoints.up("md")]: {
Expand All @@ -41,11 +44,13 @@ const InnerContainer = styled(Box)(({ theme }) => ({
* @param {object} props Component props
* @param {bool} props.handleSubmit if included then show the Continue button
* @param {bool} props.isValid if falsey then disable Continue button, otherwise enable
* @param {bool} props.isTestWarningWrapper if truthy then show navigate to publish Or button
*/
const Card: React.FC<Props> = ({
children,
isValid = true,
handleSubmit,
isTestWarningWrapper,
...props
}) => {
const theme = useTheme();
Expand All @@ -55,22 +60,34 @@ const Card: React.FC<Props> = ({
state.breadcrumbs,
state.flow,
]);
const { track } = useAnalyticsTracking();

// Check if we have a Send node in our breadcrumbs
// This is a better/more immediate proxy for "submitted" in the frontend because actual send events that populate lowcal_sessions.submitted_at are queued via Hasura
const hasSent = Object.keys(breadcrumbs).some(
(breadcrumbNodeId: string) => flow[breadcrumbNodeId]?.type === TYPES.Send,
);
const defineNavigationType = (): OrNavigationType | undefined => {
// Check if we have a Send node in our breadcrumbs
// This is a better/more immediate proxy for "submitted" in the frontend because actual send events that populate lowcal_sessions.submitted_at are queued via Hasura
const hasSent = Object.keys(breadcrumbs).some(
(breadcrumbNodeId: string) => flow[breadcrumbNodeId]?.type === TYPES.Send,
);

const showSaveResumeButton =
path === ApplicationPath.SaveAndReturn && handleSubmit && !hasSent;
const { track } = useAnalyticsTracking();
const showSaveResumeButton =
path === ApplicationPath.SaveAndReturn && handleSubmit && !hasSent;

if (showSaveResumeButton && !isTestWarningWrapper) {
return "save-resume";
}

if (!showSaveResumeButton && isTestWarningWrapper) {
return "navigate-to-published";
}
};

useEffect(() => {
// The Card component is only rendered when there's content the user will see
if (visibleNode?.id) track(visibleNode?.id);
}, []);

const orNavigationType = defineNavigationType();

return (
<Fade
in={true}
Expand Down Expand Up @@ -101,7 +118,9 @@ const Card: React.FC<Props> = ({
Continue
</Button>
)}
{showSaveResumeButton && <SaveResumeButton />}
{orNavigationType !== undefined && (
<OrNavigationButton type={orNavigationType} />
)}
</Box>
</InnerContainer>
</Container>
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import Link from "@mui/material/Link";
import Typography from "@mui/material/Typography";
import React from "react";
import { useNavigation } from "react-navi";
const NavigateToPublishedButton: React.FC = () => {
const { navigate } = useNavigation();

const handleClick = () => {
navigate("published");
};

return (
<Link onClick={handleClick} component="button">
<Typography variant="body1" textAlign="left">
Go to the live service
</Typography>
</Link>
);
};

export default NavigateToPublishedButton;
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import Box from "@mui/material/Box";
import { styled } from "@mui/material/styles";
import Typography from "@mui/material/Typography";
import React from "react";

import { contentFlowSpacing, OrNavigationType } from "./Card";
import NavigateToPublishedButton from "./NavigateToPublishedButton";
import SaveResumeButton from "./SaveResumeButton";

type OrNavigationProps = {
type: OrNavigationType;
};

export const InnerContainer = styled(Box)(({ theme }) => ({
"& p": {
...contentFlowSpacing(theme),
},
}));

const OrNavigationButton = ({ type }: OrNavigationProps) => {
const BUTTON_COMPONENTS = {
"save-resume": SaveResumeButton,
"navigate-to-published": NavigateToPublishedButton,
} as const;

const ButtonComponent = BUTTON_COMPONENTS[type];

return (
<InnerContainer>
<Typography variant="body1">or</Typography>
{<ButtonComponent />}
</InnerContainer>
);
};

export default OrNavigationButton;
Original file line number Diff line number Diff line change
@@ -1,20 +1,9 @@
import Box from "@mui/material/Box";
import Link from "@mui/material/Link";
import { styled } from "@mui/material/styles";
import Typography from "@mui/material/Typography";
import { useAnalyticsTracking } from "pages/FlowEditor/lib/analytics/provider";
import { useStore } from "pages/FlowEditor/lib/store";
import React from "react";
import { ApplicationPath } from "types";

import { contentFlowSpacing } from "./Card";

const InnerContainer = styled(Box)(({ theme }) => ({
"& p": {
...contentFlowSpacing(theme),
},
}));

const SaveResumeButton: React.FC = () => {
const saveToEmail = useStore((state) => state.saveToEmail);
const { trackEvent } = useAnalyticsTracking();
Expand All @@ -33,19 +22,14 @@ const SaveResumeButton: React.FC = () => {
}
};

const onClick = () => handleClick();

return (
<InnerContainer>
<Typography variant="body1">or</Typography>
<Link component="button" onClick={onClick}>
<Typography variant="body1" textAlign="left">
{saveToEmail
? "Save and return to this application later"
: "Resume an application you have already started"}
</Typography>
</Link>
</InnerContainer>
<Link component="button" onClick={handleClick}>
<Typography variant="body1" textAlign="left">
{saveToEmail
? "Save and return to this application later"
: "Resume an application you have already started"}
</Typography>
</Link>
);
};

Expand Down
27 changes: 27 additions & 0 deletions editor.planx.uk/src/pages/Preview/TestWarningPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import Box from "@mui/material/Box";
import Card from "@planx/components/shared/Preview/Card";
import { CardHeader } from "@planx/components/shared/Preview/CardHeader/CardHeader";
import React, { PropsWithChildren, useState } from "react";

export const TestWarningPage = ({ children }: PropsWithChildren) => {
const [hasAcknowledgedWarning, setHasAcknowledgedWarning] = useState(false);
return (
<>
{hasAcknowledgedWarning ? (
children
) : (
<Box width="100%">
<Card
handleSubmit={() => setHasAcknowledgedWarning(true)}
isTestWarningWrapper={true}
>
<CardHeader
title="This is a test environment"
description="This version of the service is unpublished and for testing only. Do not use it to submit real applications"
></CardHeader>
</Card>
</Box>
)}
</>
);
};
5 changes: 4 additions & 1 deletion editor.planx.uk/src/routes/views/draft.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { publicClient } from "lib/graphql";
import { NaviRequest, NotFoundError } from "navi";
import { useStore } from "pages/FlowEditor/lib/store";
import PublicLayout from "pages/layout/PublicLayout";
import { TestWarningPage } from "pages/Preview/TestWarningPage";
import React from "react";
import { View } from "react-navi";
import { Flow, GlobalSettings } from "types";
Expand Down Expand Up @@ -39,7 +40,9 @@ export const draftView = async (req: NaviRequest) => {

return (
<PublicLayout>
<View />
<TestWarningPage>
<View />
</TestWarningPage>
</PublicLayout>
);
};
Expand Down
5 changes: 4 additions & 1 deletion editor.planx.uk/src/routes/views/preview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import axios, { AxiosError } from "axios";
import { NaviRequest, NotFoundError } from "navi";
import { useStore } from "pages/FlowEditor/lib/store";
import PublicLayout from "pages/layout/PublicLayout";
import { TestWarningPage } from "pages/Preview/TestWarningPage";
import React from "react";
import { View } from "react-navi";
import { getTeamFromDomain } from "routes/utils";
Expand Down Expand Up @@ -40,7 +41,9 @@ export const previewView = async (req: NaviRequest) => {

return (
<PublicLayout>
<View />
<TestWarningPage>
<View />
</TestWarningPage>
</PublicLayout>
);
};
Expand Down
Loading