Skip to content

Commit

Permalink
feat: ORV2-1502 Challenge Claim workflow (#951)
Browse files Browse the repository at this point in the history
  • Loading branch information
krishnan-aot authored Dec 22, 2023
1 parent 4bed27b commit 27a0af2
Show file tree
Hide file tree
Showing 27 changed files with 927 additions and 406 deletions.
2 changes: 1 addition & 1 deletion docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ services:
NODE_ENV: development
TPS_API_LOG_LEVEL: ${TPS_API_LOG_LEVEL}
TPS_API_TYPEORM_LOG_LEVEL: ${TPS_API_TYPEORM_LOG_LEVEL}
TPS_API_MAX_QUERY_EXECUTION_TIME_MS: ${TPS_API_MAX_QUERY_EXECUTION_TIME_MS}
TPS_API_MAX_QUERY_EXECUTION_TIME_MS: ${TPS_API_MAX_QUERY_EXECUTION_TIME_MS}
DB_TYPE: ${DB_TYPE}
MSSQL_HOST: sql-server-db
MSSQL_PORT: ${MSSQL_PORT}
Expand Down
Binary file added frontend/public/New_Permit_Sample.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added frontend/public/Old_Permit_Sample.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions frontend/src/common/authentication/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@ export type CompanyMetadata = {
alternateName?: string;
};

/**
* Partial Information about a company.
*/
export type ClientInformation = {
migratedClientHash?: string;
mailingAddress: {
addressLine1: string;
addressLine2: string;
Expand All @@ -34,6 +38,9 @@ export type ClientInformation = {
extension: string;
};

/**
* The information a migrated client will have.
*/
export type MigratedClient = ClientInformation & CompanyMetadata;

/**
Expand Down
17 changes: 17 additions & 0 deletions frontend/src/common/components/icons/GreenCheckIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { faCircleCheck } from "@fortawesome/free-regular-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { BC_COLOURS } from "../../../themes/bcGovStyles";
import { SizeProp } from "@fortawesome/fontawesome-svg-core";

/**
* Reusable green check icon.
*/
export const GreenCheckIcon = ({ size }: { size?: SizeProp }) => (
<span>
<FontAwesomeIcon
color={BC_COLOURS.bc_green}
icon={faCircleCheck}
size={size ?? "lg"}
/>
</span>
);
17 changes: 17 additions & 0 deletions frontend/src/common/components/icons/RedXMarkIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { faCircleXmark } from "@fortawesome/free-regular-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { BC_COLOURS } from "../../../themes/bcGovStyles";
import { SizeProp } from "@fortawesome/fontawesome-svg-core";

/**
* Reusable red x mark icon.
*/
export const RedXMarkIcon = ({ size }: { size?: SizeProp }) => (
<span>
<FontAwesomeIcon
color={BC_COLOURS.bc_red}
icon={faCircleXmark}
size={size ?? "lg"}
/>
</span>
);
185 changes: 116 additions & 69 deletions frontend/src/features/homePage/welcome/WelcomePage.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,24 @@
import {
CardActionArea,
CardContent,
Grid,
Container,
Paper,
Stack,
Typography
Typography,
} from "@mui/material";
import Card from "@mui/material/Card";
import React, { useContext } from "react";
import { useNavigate } from "react-router-dom";

import { getCompanyNameFromSession } from "../../../common/apiManager/httpRequestHandler";
import OnRouteBCContext from "../../../common/authentication/OnRouteBCContext";
import { GreenCheckIcon } from "../../../common/components/icons/GreenCheckIcon";
import { RedXMarkIcon } from "../../../common/components/icons/RedXMarkIcon";
import { Nullable } from "../../../common/types/common";
import {
CREATE_PROFILE_WIZARD_ROUTES,
PROFILE_ROUTES,
} from "../../../routes/constants";
import { BC_COLOURS } from "../../../themes/bcGovStyles";
import "./welcome.scss";

const isInvitedUser = (companyNameFromContext?: string): boolean =>
Expand All @@ -41,8 +44,90 @@ const WelcomeCompanyName = ({
);
};

export const WelcomePage = React.memo(() => {
/**
* Reusable Card component to display a possible action for the user.
* @returns A react component.
*/
const ProfileAction = ({
navigateTo,
}: {
navigateTo: string;
}): React.ReactElement => {
const navigate = useNavigate();
return (
<div className="welcome-page__profile-actions">
<Card
className="welcome-cards welcome-cards--new"
sx={{
":hover": {
boxShadow: 10,
},
}}
>
<CardContent onClick={() => navigate(navigateTo)}>
<Stack spacing={3}>
<div className="welcome-cards__img">
<img
height="80"
width="80"
className="welcome-account-graphics"
src="./Create_New_Profile_Graphic.svg"
alt="New onRouteBC Profile"
/>
</div>

<Typography variant="body2">
Finish creating your onRouteBC Profile
</Typography>
</Stack>
</CardContent>
</Card>
</div>
);
};

const ChallengeOption = ({
navigateTo,
label,
labelIcon,
}: {
navigateTo: string;
label: string;
labelIcon: JSX.Element;
}): React.ReactElement => {
const navigate = useNavigate();
return (
<Paper
sx={{
":hover": {
background: BC_COLOURS.bc_messages_blue_background,
},
cursor: "pointer",
width: "220px",
height: "80px",
}}
onClick={() => navigate(navigateTo)}
>
<Stack
direction="row"
spacing={2}
sx={{
marginLeft: "5em",
marginTop: "1.82em",
}}
>
<div>{labelIcon}</div>
<div>{label}</div>
</Stack>
</Paper>
);
};

/**
* The BCeID welcome page of the application.
* A BCeID user reaches this page on their very first login.
*/
export const WelcomePage = React.memo(() => {
const companyNameFromToken = getCompanyNameFromSession();
const { companyLegalName: companyNameFromContext } =
useContext(OnRouteBCContext);
Expand All @@ -61,73 +146,35 @@ export const WelcomePage = React.memo(() => {
)}
<div className="separator-line"></div>
{isInvitedUser(companyNameFromContext) && (
<>
<br />
<Card elevation={12} sx={{ maxWidth: 200 }}>
<CardActionArea
onClick={() => navigate(PROFILE_ROUTES.USER_INFO)}
>
<Stack>
<Stack direction="row">
<Grid container>
<Grid item xs={3}></Grid>
<Grid item xs={6} sx={{ paddingTop: "2rem" }}>
<div className="welcome-cards__img">
<img
height="80"
width="80"
className="welcome-account-graphics"
src="./Create_New_Profile_Graphic.svg"
alt="New onRouteBC Profile"
/>
</div>
</Grid>
</Grid>
</Stack>
<CardContent>
<Typography variant="body2">
Finish creating your <br /> onRouteBC Profile
</Typography>
</CardContent>
</Stack>

<div className="welcome-cards__img"></div>
</CardActionArea>
</Card>
</>
<ProfileAction navigateTo={PROFILE_ROUTES.USER_INFO} />
)}
{isNewCompanyProfile(companyNameFromContext) && (
<div className="welcome-page__profile-actions">
<Card
className="welcome-cards welcome-cards--new"
sx={{
":hover": {
boxShadow: 10,
},
}}
>
<CardContent
onClick={() => navigate(CREATE_PROFILE_WIZARD_ROUTES.CREATE)}
>
<Stack spacing={3}>
<div className="welcome-cards__img">
<img
height="80"
width="80"
className="welcome-account-graphics"
src="./Create_New_Profile_Graphic.svg"
alt="New onRouteBC Profile"
/>
</div>

<Typography variant="body2">
Finish creating your onRouteBC Profile
</Typography>
</Stack>
</CardContent>
</Card>
</div>
{companyNameFromContext && isNewCompanyProfile(companyNameFromContext) && (
<ProfileAction navigateTo={CREATE_PROFILE_WIZARD_ROUTES.CREATE} />
)}
{!companyNameFromContext &&
<Stack spacing={2} sx={{ justifyContent: "center" }}>
<div style={{ alignSelf: "center" }}>
Has this company purchased a commercial vehicle
</div>
<div style={{ alignSelf: "center", marginTop: "0px" }}>
permit in the last 7 years?
</div>
<Container>
<Stack direction="row" spacing={3}>
<ChallengeOption
navigateTo={CREATE_PROFILE_WIZARD_ROUTES.CREATE}
label="No"
labelIcon={<RedXMarkIcon size="xl" />}
/>
<ChallengeOption
navigateTo={CREATE_PROFILE_WIZARD_ROUTES.MIGRATED_CLIENT}
label="Yes"
labelIcon={<GreenCheckIcon size="xl" />}
/>
</Stack>
</Container>
</Stack>
}
</div>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ import {
CompanyAndUserRequest,
UserInformation,
Contact,
VerifyMigratedClientRequest,
VerifyMigratedClientResponse,
} from "../types/manageProfile";

export const getCompanyInfo = async (): Promise<CompanyProfile> => {
Expand Down Expand Up @@ -90,15 +92,29 @@ export const createMyOnRouteBCUserProfile = async ({
* @param onRouteBCProfileRequestObject The request object containing the profile details
* @returns A Promise containing the response from the API.
*/
export const createOnRouteBCProfile = async (
export const createOnRouteBCProfile = (
onRouteBCProfileRequestObject: CompanyAndUserRequest,
) => {
return await httpPOSTRequest(
return httpPOSTRequest(
`${MANAGE_PROFILE_API.COMPANIES}`,
replaceEmptyValuesWithNull(onRouteBCProfileRequestObject),
);
};

/**
* Verifies a migrated client through an API call.
* @param requestPayload The verify migrated client form values.
* @returns A promise containing details of the verification.
*/
export const verifyMigratedClient = (
requestPayload: VerifyMigratedClientRequest,
): Promise<VerifyMigratedClientResponse> => {
return httpPOSTRequest(
`${VEHICLES_URL}/users/verify-migrated-client`,
replaceEmptyValuesWithNull(requestPayload),
).then((response) => response.data);
};

/**
* Retrieve the company and user details post login.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,4 @@
import {
faCircleCheck,
faCircleXmark,
faUserGroup,
} from "@fortawesome/free-solid-svg-icons";
import { faUserGroup } from "@fortawesome/free-solid-svg-icons";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import CloseIcon from "@mui/icons-material/Close";
import Dialog from "@mui/material/Dialog";
Expand All @@ -17,24 +13,8 @@ import TableContainer from "@mui/material/TableContainer";
import TableHead from "@mui/material/TableHead";
import TableRow from "@mui/material/TableRow";
import { BC_COLOURS } from "../../../../themes/bcGovStyles";

/**
* Reusable green check icon.
*/
const GreenCheckIcon = () => (
<span>
<FontAwesomeIcon color={BC_COLOURS.bc_green} icon={faCircleCheck} />
</span>
);

/**
* Reusable red x mark icon.
*/
const RedXMarkIcon = () => (
<span>
<FontAwesomeIcon color={BC_COLOURS.bc_red} icon={faCircleXmark} />
</span>
);
import { GreenCheckIcon } from "../../../../common/components/icons/GreenCheckIcon";
import { RedXMarkIcon } from "../../../../common/components/icons/RedXMarkIcon";

/**
* A stateless modal that displays the user groups and permissions for CV Clients.
Expand Down
19 changes: 19 additions & 0 deletions frontend/src/features/manageProfile/types/manageProfile.d.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { ClientInformation } from "../../../common/authentication/types";

interface Address {
addressLine1: string;
addressLine2?: string;
Expand Down Expand Up @@ -55,6 +57,23 @@ export interface CompanyAndUserRequest {
adminUser: Contact;
}

/**
* The request object to verify a migrated client
*/
export type VerifyMigratedClientRequest = {
clientNumber: string;
permitNumber: string;
};

/**
* The response object from the API to verify a migrated client
*/
export type VerifyMigratedClientResponse = {
foundClient: boolean;
foundPermit: boolean;
migratedClient?: MigratedClient;
};

/**
* The tabs on the user profile management page.
*/
Expand Down
Loading

0 comments on commit 27a0af2

Please sign in to comment.