Skip to content

Commit

Permalink
feat: sections overview page with dynamic status tags (#1491)
Browse files Browse the repository at this point in the history
  • Loading branch information
jessicamcinchak authored Mar 1, 2023
1 parent f44e757 commit f15193c
Show file tree
Hide file tree
Showing 2 changed files with 130 additions and 13 deletions.
130 changes: 125 additions & 5 deletions editor.planx.uk/src/@planx/components/Section/Public.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,136 @@
import Box from "@mui/material/Box";
import { styled } from "@mui/material/styles";
import Typography from "@mui/material/Typography";
import type { PublicProps } from "@planx/components/ui";
import { useEffect } from "react";
import { hasFeatureFlag } from "lib/featureFlags";
import { useStore } from "pages/FlowEditor/lib/store";
import React, { useEffect } from "react";

import Card from "../shared/Preview/Card";
import QuestionHeader from "../shared/Preview/QuestionHeader";
import type { Section } from "./model";

export type Props = PublicProps<Section>;

enum SectionStatus {
NotStarted = "CANNOT START YET",
ReadyToStart = "READY TO START",
Completed = "COMPLETED",
NeedsUpdated = "NEEDS UPDATED", // future reconciliation scenario, not used yet
}

export default function Component(props: Props) {
const showSection = hasFeatureFlag("NAVIGATION_UI");

const [
flowName,
currentSectionIndex,
sectionCount,
sectionNodes,
currentCard,
upcomingCardIds,
] = useStore((state) => [
state.flowName,
state.currentSectionIndex,
state.sectionCount,
state.sectionNodes,
state.currentCard(),
state.upcomingCardIds(),
]);

useEffect(() => {
props.handleSubmit?.({
auto: true, // hides this node when navigating through cards in a flow
});
// if the feature flag is toggled off, hide this node (by auto-answering it) when navigating through a flow
!showSection &&
props.handleSubmit?.({
auto: true,
});
}, []);

return null;
const getStatus = (
sectionId: string,
currentCardId: string | undefined,
upcomingCardIds: string[] | undefined
): SectionStatus => {
if (currentCardId === sectionId) {
return SectionStatus.ReadyToStart;
} else if (upcomingCardIds?.includes(sectionId)) {
return SectionStatus.NotStarted;
} else {
return SectionStatus.Completed;
}
};

return !showSection ? null : (
<Card isValid handleSubmit={props.handleSubmit}>
<QuestionHeader title={flowName} />
<Box sx={{ lineHeight: ".5em" }}>
<Typography variant="body1" component="h2" sx={{ fontWeight: "bold" }}>
Application incomplete.
</Typography>
<Typography variant="body2">
{`You have completed ${
Object.keys(sectionNodes)[0] === currentCard?.id
? 0
: currentSectionIndex
} of ${sectionCount} sections`}
</Typography>
</Box>
<DescriptionList>
{Object.entries(sectionNodes).map(([sectionId, sectionNode]) => (
<React.Fragment key={sectionId}>
<dt>{sectionNode.data.title}</dt>
<dd>
<Tag>
{getStatus(sectionId, currentCard?.id, upcomingCardIds)}
</Tag>
</dd>
</React.Fragment>
))}
</DescriptionList>
</Card>
);
}

const Tag = styled("div")(({ theme }) => ({
backgroundColor: "lightgrey",
paddingTop: theme.spacing(0.5),
paddingBottom: theme.spacing(0.5),
paddingLeft: theme.spacing(2),
paddingRight: theme.spacing(2),
}));

const Grid = styled("dl")(({ theme }) => ({
display: "grid",
gridTemplateColumns: "1fr 175px",
gridRowGap: "5px",
marginTop: theme.spacing(2),
marginBottom: theme.spacing(2),
"& > *": {
borderBottom: "1px solid grey",
paddingBottom: theme.spacing(2),
paddingTop: theme.spacing(2),
verticalAlign: "top",
margin: 0,
},
"& ul": {
listStylePosition: "inside",
padding: 0,
margin: 0,
},
"& dt": {
// left column
fontWeight: 500,
},
"& dd:nth-of-type(1n)": {
// right column
textAlign: "center",
},
}));

interface DescriptionListProps {
children: React.ReactNode;
}

const DescriptionList: React.FC<DescriptionListProps> = ({ children }) => {
return <Grid>{children}</Grid>;
};
13 changes: 5 additions & 8 deletions editor.planx.uk/src/pages/FlowEditor/lib/store/navigation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,15 +73,12 @@ export const navigationStore: StateCreator<

const breadcrumbIds = Object.keys(breadcrumbs);
const sectionIds = Object.keys(sectionNodes);
const mostRecentSectionId = findLast(
breadcrumbIds,
(breadcrumbId: string) => sectionIds.includes(breadcrumbId)
);

// This should not happen - if we have sections, we should have a most recent section
// Failing noisily for now will help identify issues whilst this is being developed & tested
// TODO: Fail more gracefully once feature is complete
if (!mostRecentSectionId) throw Error("Error finding mostRecentSectionId");
// Fallback to the first sectionId, which allows us to have a mostRecentSectionId on the first node ("Card") before it exists in breadcrumbs (eg "Continue" hasn't been clicked yet)
const mostRecentSectionId =
findLast(breadcrumbIds, (breadcrumbId: string) =>
sectionIds.includes(breadcrumbId)
) || sectionIds[0];

// Update section
const currentSectionTitle = sectionNodes[mostRecentSectionId].data.title;
Expand Down

0 comments on commit f15193c

Please sign in to comment.