├── CNAME
├── .prettierignore
├── src
├── react-app-env.d.ts
├── Assets
│ ├── venmo.png
│ ├── RAPSheet.png
│ ├── democracylab-logo.png
│ ├── openseattle-logo.png
│ ├── Onboarding
│ │ ├── circleCheck.png
│ │ ├── openCircle.png
│ │ ├── arrowRight.svg
│ │ ├── video.svg
│ │ ├── checklist.svg
│ │ ├── person.svg
│ │ ├── heart.svg
│ │ ├── fb.svg
│ │ ├── file.svg
│ │ ├── chat.svg
│ │ ├── paper.svg
│ │ ├── link.svg
│ │ ├── exclamation.svg
│ │ ├── head.svg
│ │ ├── simpleQuestion.svg
│ │ ├── linkedIn.svg
│ │ ├── world.svg
│ │ ├── venn.svg
│ │ ├── screens.svg
│ │ ├── tool.svg
│ │ ├── meditate.svg
│ │ ├── remote.svg
│ │ ├── progress.svg
│ │ ├── circleArrow.svg
│ │ ├── checkmark.svg
│ │ ├── symbols.svg
│ │ ├── boat.svg
│ │ ├── twitter.svg
│ │ ├── doc.svg
│ │ ├── userResearch.svg
│ │ ├── bug.svg
│ │ ├── group.svg
│ │ ├── question.svg
│ │ └── smallLogo.svg
│ ├── gsStep1.svg
│ ├── gsStep4.svg
│ ├── gsStep2.svg
│ ├── gsStep3.svg
│ ├── topScrollButton.svg
│ ├── diversity2.svg
│ ├── cv_small_logo_dark. 1.svg
│ └── marketing.svg
├── Components
│ ├── __tests__
│ │ ├── jsconfig.json
│ │ ├── GivingTuesday.spec.js
│ │ ├── Footer.spec.js
│ │ ├── ProgressBar.spec.js
│ │ └── ToolTipModal.spec.js
│ ├── DonationVideo.jsx
│ ├── customHooks
│ │ └── useDocumentTitle.jsx
│ ├── Fact.jsx
│ ├── FactIconGroup.jsx
│ ├── ResponsiveJumpButtonGroup.jsx
│ ├── Onboarding
│ │ ├── PrimaryButton.jsx
│ │ ├── Footer.jsx
│ │ ├── MiroVideoModal.jsx
│ │ ├── FindVideoModal.jsx
│ │ ├── SocialContainer.jsx
│ │ └── CompleteButton.jsx
│ ├── FactSubList.jsx
│ ├── FactGroup.jsx
│ ├── LegalDisclaimer.jsx
│ ├── FactSimpleCard.jsx
│ ├── ContentSection.jsx
│ ├── NavigationLogo.jsx
│ ├── RestartButton.jsx
│ ├── AccordionBuilder.jsx
│ ├── HeroPanel.jsx
│ ├── Table.jsx
│ ├── DonateLevelCard.jsx
│ ├── DonationForm.jsx
│ ├── VolunteerRolesCard.jsx
│ ├── RedesignHeroPanel.jsx
│ ├── StepsIconGroup.jsx
│ ├── ImageContentCard.jsx
│ ├── TabPanelGroup.jsx
│ ├── FactCard.jsx
│ ├── FactImageCard.jsx
│ ├── ToolTipModal.jsx
│ ├── DonateDialog.jsx
│ ├── PublicHousingList.jsx
│ ├── ShelterList.jsx
│ ├── FactExpandMoreCard.jsx
│ ├── ProgressBar.jsx
│ └── NavCardGroup.jsx
├── App.css
├── setupTests.js
├── index.css
├── ui-kit
│ ├── ListItemLink.jsx
│ ├── ExternalLink.jsx
│ ├── RedesignButtonSecondary.jsx
│ ├── RedesignButtonPrimary.jsx
│ ├── BulletedListMui.jsx
│ ├── RedesignButtonWide.jsx
│ ├── CalulatorDialog.jsx
│ ├── PrimaryButton.jsx
│ ├── SecondaryButton.jsx
│ ├── SkipLink.tsx
│ ├── ListItem.jsx
│ ├── NavButtonMobile.jsx
│ ├── BackButton.jsx
│ ├── ListItemMobileSnap.jsx
│ └── NavButton.jsx
├── CSS
│ ├── constants.css
│ └── Calculator.css
├── reportWebVitals.js
├── Pages
│ ├── Calculator
│ │ ├── MainBranchTitleStyles.js
│ │ ├── QuickStartGuideStyles.js
│ │ ├── EndScreenStyles.js
│ │ ├── SpecialCaseTitleStyles.js
│ │ ├── MainBranchTitle.jsx
│ │ └── QuestionScreenStyles.js
│ ├── ErrorPage.jsx
│ ├── ContactPage.jsx
│ ├── ContactSuccessPage.jsx
│ ├── PartnerPage.jsx
│ └── Onboarding
│ │ └── OnboardingHome.jsx
├── trackingUtils.js
├── index.jsx
├── Styles
│ ├── Onboarding
│ │ ├── useFooterStyles.js
│ │ ├── useMod2Styles.js
│ │ ├── useModalStyles.js
│ │ ├── useButtonStyles.js
│ │ └── useHomeStyles.js
│ ├── WhyVacateEducationStyles.ts
│ ├── WhyVacateHousingStyles.ts
│ ├── WhyVacateEmploymentStyle.js
│ ├── useWhyVacateStyles.js
│ ├── useHomeStyles.js
│ └── useGetInvolvedStyles.js
├── data
│ ├── siteMap.ts
│ └── calculatorPagesTypes.ts
└── Subpages
│ ├── WhyVacate
│ ├── IconWithHeaderAndText.jsx
│ ├── TextWithImage.jsx
│ ├── TextWithCTAButton.jsx
│ ├── TwoParagraphTextWithHeader.jsx
│ ├── HousingBarriers.jsx
│ ├── GovBarriers.jsx
│ ├── EducationBarriers.jsx
│ └── HousingOtherOptions.jsx
│ └── GetStarted
│ ├── RecordInformation.jsx
│ └── LegalAidServices.jsx
├── public
├── robot.txt
├── styles.css
├── favicon.ico
├── apple-touch-icon.png
└── manifest.json
├── .vscode
├── extensions.json
└── settings.json
├── .env
├── .prettierrc.json
├── CODEOWNERS
├── .gitignore
├── .github
└── workflows
│ ├── post-commit-action.yml
│ └── pull-request-checks.yml
├── tsconfig.json
├── LICENSE
├── pull_request_template.md
├── .eslintrc.yaml
├── 404.html
├── scripts
└── generate-sitemap.mjs
└── package.json
/CNAME:
--------------------------------------------------------------------------------
1 | convictionvacation.org
--------------------------------------------------------------------------------
/.prettierignore:
--------------------------------------------------------------------------------
1 | CODEOWNERS
2 | LICENSE
--------------------------------------------------------------------------------
/src/react-app-env.d.ts:
--------------------------------------------------------------------------------
1 | ///
2 |
--------------------------------------------------------------------------------
/public/robot.txt:
--------------------------------------------------------------------------------
1 | User-agent:*
2 | Sitemap: https://clearviction.org/sitemap.xml
--------------------------------------------------------------------------------
/public/styles.css:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | margin: 0;
4 | padding: 0;
5 | }
6 |
--------------------------------------------------------------------------------
/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openseattle/clearviction-v1/HEAD/public/favicon.ico
--------------------------------------------------------------------------------
/src/Assets/venmo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openseattle/clearviction-v1/HEAD/src/Assets/venmo.png
--------------------------------------------------------------------------------
/src/Assets/RAPSheet.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openseattle/clearviction-v1/HEAD/src/Assets/RAPSheet.png
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": ["esbenp.prettier-vscode", "dbaeumer.vscode-eslint"]
3 | }
4 |
--------------------------------------------------------------------------------
/public/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openseattle/clearviction-v1/HEAD/public/apple-touch-icon.png
--------------------------------------------------------------------------------
/src/Components/__tests__/jsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "typeAcquisition": {
3 | "include": ["jest"]
4 | }
5 | }
6 |
--------------------------------------------------------------------------------
/src/Assets/democracylab-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openseattle/clearviction-v1/HEAD/src/Assets/democracylab-logo.png
--------------------------------------------------------------------------------
/src/Assets/openseattle-logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openseattle/clearviction-v1/HEAD/src/Assets/openseattle-logo.png
--------------------------------------------------------------------------------
/src/Assets/Onboarding/circleCheck.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openseattle/clearviction-v1/HEAD/src/Assets/Onboarding/circleCheck.png
--------------------------------------------------------------------------------
/src/Assets/Onboarding/openCircle.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/openseattle/clearviction-v1/HEAD/src/Assets/Onboarding/openCircle.png
--------------------------------------------------------------------------------
/.env:
--------------------------------------------------------------------------------
1 | REACT_APP_SERVICE_ID = "service_yp3zmqj"
2 | REACT_APP_TEMPLATE_ID = "template_juz0rzp"
3 | REACT_APP_USER_ID = "user_oO1g8se7aDgjbfVNT50uo"
--------------------------------------------------------------------------------
/src/App.css:
--------------------------------------------------------------------------------
1 | .App {
2 | text-align: center;
3 | position: relative;
4 | min-height: 100vh;
5 | margin: 0;
6 | padding: 0;
7 | line-height: 1;
8 | }
9 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "editor.formatOnSave": true,
3 | "editor.defaultFormatter": "esbenp.prettier-vscode",
4 | "[javascriptreact]": {
5 | "editor.defaultFormatter": "rvest.vs-code-prettier-eslint"
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/.prettierrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "trailingComma": "es5",
3 | "tabWidth": 4,
4 | "semi": true,
5 | "singleQuote": false,
6 | "printWidth": 120,
7 | "bracketSpacing": true,
8 | "bracketSameLine": false,
9 | "arrowParens": "avoid"
10 | }
11 |
--------------------------------------------------------------------------------
/src/setupTests.js:
--------------------------------------------------------------------------------
1 | // jest-dom adds custom jest matchers for asserting on DOM nodes.
2 | // allows you to do things like:
3 | // expect(element).toHaveTextContent(/react/i)
4 | // learn more: https://github.com/testing-library/jest-dom
5 | import "@testing-library/jest-dom";
6 |
--------------------------------------------------------------------------------
/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # These owners will be the default owners for everything in
2 |
3 | # the repo. Unless a later match takes precedence,
4 |
5 | # all of these users will be requested for
6 |
7 | # review when someone opens a pull request.
8 |
9 | * @stuttskl @mhyneman8 @erluebbers @ShepleySound
10 |
--------------------------------------------------------------------------------
/src/index.css:
--------------------------------------------------------------------------------
1 | body {
2 | font-family: "Roboto", sans-serif;
3 | -webkit-font-smoothing: antialiased;
4 | -moz-osx-font-smoothing: grayscale;
5 | line-height: 1.5;
6 | }
7 |
8 | code {
9 | font-family: source-code-pro, Menlo, Monaco, Consolas, "Courier New", monospace;
10 | }
11 |
--------------------------------------------------------------------------------
/src/ui-kit/ListItemLink.jsx:
--------------------------------------------------------------------------------
1 | import { ListItem } from "@mui/material";
2 |
3 | // eslint-disable-next-line import/prefer-default-export
4 | export const ListItemLink = props => {
5 | // eslint-disable-next-line react/jsx-props-no-spreading
6 | return ;
7 | };
8 |
--------------------------------------------------------------------------------
/src/Components/DonationVideo.jsx:
--------------------------------------------------------------------------------
1 | import ReactPlayer from "react-player";
2 |
3 | const DonationVideo = () => {
4 | return (
5 |
6 |
7 |
8 | );
9 | };
10 |
11 | export default DonationVideo;
12 |
--------------------------------------------------------------------------------
/src/Assets/Onboarding/arrowRight.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # dependencies
2 | /node_modules
3 | /.pnp
4 | .pnp.js
5 |
6 | # testing
7 | /coverage
8 |
9 | # production
10 | /build
11 |
12 | # misc
13 | .DS_Store
14 | .env.local
15 | .env.development.local
16 | .env.test.local
17 | .env.production.local
18 |
19 | npm-debug.log*
20 | yarn-debug.log*
21 | yarn-error.log*
22 |
23 | node_modules
24 |
25 | /public/sitemap.xml
--------------------------------------------------------------------------------
/src/CSS/constants.css:
--------------------------------------------------------------------------------
1 | :root {
2 | --dark-blue: #2d3047;
3 | --heavy-blue: #2f3554;
4 | --light-gray: #dcdcdc;
5 | --gray: #c4c4c4;
6 | --blue: #a6b5cc;
7 | --light-blue: #4e6c99;
8 | --light-blue-transparent: rgba(78, 108, 153, 0.5);
9 | --z-index-front: 999;
10 | --gray90: #e5e5e5;
11 | --white: #ffffff;
12 | --black: #000000;
13 | }
14 |
--------------------------------------------------------------------------------
/src/Assets/Onboarding/video.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/Assets/Onboarding/checklist.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/Components/customHooks/useDocumentTitle.jsx:
--------------------------------------------------------------------------------
1 | import { useEffect, useState } from "react";
2 |
3 | const useDocumentTitle = title => {
4 | const [documentTitle, setDocumentTitle] = useState(title);
5 |
6 | useEffect(() => {
7 | document.title = `${documentTitle}Clearviction`;
8 | }, [documentTitle]);
9 |
10 | return [documentTitle, setDocumentTitle];
11 | };
12 |
13 | export { useDocumentTitle };
14 |
--------------------------------------------------------------------------------
/src/Assets/Onboarding/person.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/Assets/Onboarding/heart.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/reportWebVitals.js:
--------------------------------------------------------------------------------
1 | const reportWebVitals = onPerfEntry => {
2 | if (onPerfEntry && onPerfEntry instanceof Function) {
3 | import("web-vitals").then(({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {
4 | getCLS(onPerfEntry);
5 | getFID(onPerfEntry);
6 | getFCP(onPerfEntry);
7 | getLCP(onPerfEntry);
8 | getTTFB(onPerfEntry);
9 | });
10 | }
11 | };
12 |
13 | export default reportWebVitals;
14 |
--------------------------------------------------------------------------------
/src/Components/Fact.jsx:
--------------------------------------------------------------------------------
1 | import { Box, Typography } from "@mui/material";
2 |
3 | const Fact = ({ icon, text }) => {
4 | return (
5 | <>
6 |
7 | {icon}
8 |
9 |
10 | {text}
11 |
12 | >
13 | );
14 | };
15 |
16 | export default Fact;
17 |
--------------------------------------------------------------------------------
/.github/workflows/post-commit-action.yml:
--------------------------------------------------------------------------------
1 | name: Run prettier
2 |
3 | on:
4 | pull_request:
5 | branches:
6 | - master
7 |
8 | jobs:
9 | prettier:
10 | runs-on: ubuntu-latest
11 |
12 | steps:
13 | - name: Checkout repo
14 | uses: actions/checkout@v2
15 |
16 | - name: Use Node.js
17 | uses: actions/setup-node@v2
18 |
19 | - name: run prettier
20 | run: npx prettier --check .
21 |
--------------------------------------------------------------------------------
/src/Components/FactIconGroup.jsx:
--------------------------------------------------------------------------------
1 | import { Grid } from "@mui/material";
2 | import Fact from "./Fact";
3 |
4 | const FactIconGroup = ({ facts }) => {
5 | return (
6 |
7 | {facts.map(fact => (
8 |
9 |
10 |
11 | ))}
12 |
13 | );
14 | };
15 |
16 | export default FactIconGroup;
17 |
--------------------------------------------------------------------------------
/public/manifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "short_name": "Clearviction",
3 | "name": "Conviction Vacation Eligibility and Legal, Housing, Education, Employment Resources",
4 | "icons": [
5 | {
6 | "src": "favicon.ico",
7 | "sizes": "64x64 32x32 24x24 16x16",
8 | "type": "image/x-icon"
9 | },
10 | {
11 | "src": "apple-touch-icon.png",
12 | "sizes": "192x192",
13 | "type": "image/png"
14 | }
15 | ]
16 | }
17 |
--------------------------------------------------------------------------------
/src/Assets/Onboarding/fb.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/Pages/Calculator/MainBranchTitleStyles.js:
--------------------------------------------------------------------------------
1 | import { makeStyles } from "@mui/styles";
2 |
3 | export const MainBranchTitleStyles = makeStyles(() => ({
4 | grid: {
5 | display: "inline-block",
6 | marginTop: "72px",
7 | justifyContent: "center",
8 | textAlign: "center",
9 | },
10 | header: {
11 | marginBottom: "24px",
12 | },
13 | body: {
14 | marginBottom: "72px",
15 | },
16 | button: {
17 | marginBottom: "40px",
18 | },
19 | }));
20 |
--------------------------------------------------------------------------------
/src/ui-kit/ExternalLink.jsx:
--------------------------------------------------------------------------------
1 | import { Link } from "@mui/material";
2 | import { OpenInNewOutlined } from "@mui/icons-material";
3 |
4 | // eslint-disable-next-line import/prefer-default-export
5 | export const ExternalLink = ({ href, children, name = "_blank", className }) => {
6 | return (
7 |
8 | {children}
9 |
10 |
11 | );
12 | };
13 |
--------------------------------------------------------------------------------
/src/Components/__tests__/GivingTuesday.spec.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { render, screen } from "@testing-library/react";
3 | import { ThemeProvider } from "@mui/material/styles";
4 | import Theme from "../Theme.tsx";
5 | import GivingTuesdayPage from "../../Pages/GivingTuesdayPage.jsx";
6 |
7 | describe("", () => {
8 | it("renders", () => {
9 | render(
10 |
11 |
12 |
13 | );
14 | });
15 | });
16 |
--------------------------------------------------------------------------------
/src/Assets/Onboarding/file.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/Assets/Onboarding/chat.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/Assets/gsStep1.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/ui-kit/RedesignButtonSecondary.jsx:
--------------------------------------------------------------------------------
1 | import { Button } from "@mui/material";
2 | import { styled } from "@mui/material/styles";
3 |
4 | // Uses styled() instead of makeStyles()
5 | export const RedesignButtonSecondary = styled(Button)(({ theme }) => ({
6 | width: 248,
7 | height: 48,
8 | borderRadius: 50,
9 | backgroundColor: "white",
10 | color: theme.palette.primary.dark,
11 | boxShadow: "0 2px 4px rgba(0, 0, 0, 0.2)",
12 | "&:hover": {
13 | backgroundColor: theme.palette.primary.main,
14 | color: theme.palette.primary.contrastText,
15 | },
16 | }));
17 |
--------------------------------------------------------------------------------
/src/Assets/gsStep4.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/ui-kit/RedesignButtonPrimary.jsx:
--------------------------------------------------------------------------------
1 | import { Button } from "@mui/material";
2 | import { styled } from "@mui/material/styles";
3 |
4 | // Uses styled() instead of makeStyles()
5 | export const RedesignButtonPrimary = styled(Button)(({ theme }) => ({
6 | width: 248,
7 | height: 48,
8 | borderRadius: 50,
9 | backgroundColor: theme.palette.primary.main,
10 | boxShadow: "0 2px 4px rgba(0, 0, 0, 0.2)",
11 | color: theme.palette.primary.contrastText,
12 | "&:hover": {
13 | backgroundColor: theme.palette.secondary.main,
14 | color: theme.palette.secondary.contrastText,
15 | },
16 | }));
17 |
--------------------------------------------------------------------------------
/src/Assets/Onboarding/paper.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/ui-kit/BulletedListMui.jsx:
--------------------------------------------------------------------------------
1 | import { Typography } from "@mui/material";
2 |
3 | /**
4 | * BulletedListMui is a solution for unordered lists that want bullet points
5 | * since Material-Ui does not have a specific solution for this scenario.
6 | * @param {*} props
7 | * @returns ul element with Material Ui style applied to it
8 | */
9 | const BulletedListMui = props => {
10 | const { children, textColor } = props;
11 | return (
12 |
13 | {children}
14 |
15 | );
16 | };
17 |
18 | export default BulletedListMui;
19 |
--------------------------------------------------------------------------------
/src/Components/ResponsiveJumpButtonGroup.jsx:
--------------------------------------------------------------------------------
1 | import { Button, ButtonGroup, useMediaQuery } from "@mui/material";
2 |
3 | const ResponsiveJumpButtonGroup = ({ links }) => {
4 | const matches = useMediaQuery("(min-width:600px)");
5 | return (
6 |
7 | {links.map((link, idx) => (
8 |
11 | ))}
12 |
13 | );
14 | };
15 |
16 | export default ResponsiveJumpButtonGroup;
17 |
--------------------------------------------------------------------------------
/src/trackingUtils.js:
--------------------------------------------------------------------------------
1 | const GA_MEASUREMENT_ID = "UA-215117449-1";
2 |
3 | export function trackPageview(pageTitle) {
4 | if (typeof window.gtag !== "undefined") {
5 | window.gtag("event", "page_view", {
6 | page_title: pageTitle,
7 | page_location: window.location.href,
8 | page_path: window.location.pathname,
9 | send_to: GA_MEASUREMENT_ID,
10 | });
11 | }
12 | }
13 |
14 | export function trackClick(clickedText) {
15 | if (typeof window.gtag !== "undefined") {
16 | window.gtag("event", "click", {
17 | event_label: clickedText,
18 | });
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/src/ui-kit/RedesignButtonWide.jsx:
--------------------------------------------------------------------------------
1 | import { Button } from "@mui/material";
2 | import { styled } from "@mui/material/styles";
3 |
4 | // Uses styled() instead of makeStyles()
5 | const RedesignButtonWide = styled(Button)(({ theme }) => ({
6 | width: "300px",
7 | height: 48,
8 | borderRadius: 50,
9 | backgroundColor: theme.palette.primary.main,
10 | boxShadow: "0 2px 4px rgba(0, 0, 0, 0.2)",
11 | color: theme.palette.primary.contrastText,
12 | "&:hover": {
13 | backgroundColor: theme.palette.secondary.main,
14 | color: theme.palette.secondary.contrastText,
15 | },
16 | }));
17 |
18 | export default RedesignButtonWide;
19 |
--------------------------------------------------------------------------------
/src/Components/Onboarding/PrimaryButton.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Link } from "react-router-dom";
3 | import { Typography } from "@mui/material";
4 | import { useButtonStyles } from "../../Styles/Onboarding/useButtonStyles";
5 |
6 | const PrimaryButton = ({ button }) => {
7 | const classes = useButtonStyles();
8 | const { text, link } = button;
9 | return (
10 |
11 |
12 | {text}
13 |
14 |
15 | );
16 | };
17 |
18 | export default PrimaryButton;
19 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "lib": ["dom", "dom.iterable", "esnext"],
5 | "allowJs": true,
6 | "skipLibCheck": true,
7 | "esModuleInterop": true,
8 | "allowSyntheticDefaultImports": true,
9 | "strict": true,
10 | "forceConsistentCasingInFileNames": true,
11 | "noFallthroughCasesInSwitch": true,
12 | "module": "esnext",
13 | "moduleResolution": "node",
14 | "resolveJsonModule": true,
15 | "isolatedModules": true,
16 | "noEmit": true,
17 | "jsx": "react-jsx"
18 | },
19 | "include": ["src", "scripts/generate-sitemap.mjs"]
20 | }
21 |
--------------------------------------------------------------------------------
/src/Assets/Onboarding/link.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/index.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import ReactDOM from "react-dom";
3 | import "./index.css";
4 | import "./CSS/constants.css";
5 | import { BrowserRouter as Router } from "react-router-dom";
6 | import App from "./App";
7 | import reportWebVitals from "./reportWebVitals";
8 |
9 | ReactDOM.render(
10 |
11 |
12 |
13 |
14 | ,
15 | document.getElementById("root")
16 | );
17 |
18 | // If you want to start measuring performance in your app, pass a function
19 | // to log results (for example: reportWebVitals(console.log))
20 | // or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
21 | reportWebVitals();
22 |
--------------------------------------------------------------------------------
/src/Assets/Onboarding/exclamation.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/Styles/Onboarding/useFooterStyles.js:
--------------------------------------------------------------------------------
1 | import { makeStyles } from "@mui/styles";
2 |
3 | export const useFooterStyles = makeStyles(theme => ({
4 | footerContainer: {
5 | display: "flex",
6 | flexDirection: "row",
7 | justifyContent: "space-between",
8 | margin: theme.spacing(6),
9 | [theme.breakpoints.down("sm")]: {
10 | margin: theme.spacing(2),
11 | },
12 | },
13 | completeContainer: {
14 | display: "flex",
15 | justifyContent: "flex-end",
16 | margin: theme.spacing(3.625, 6, 3.625, 6),
17 | marginBottom: "-20px",
18 | [theme.breakpoints.down("md")]: {
19 | justifyContent: "center",
20 | },
21 | },
22 | }));
23 |
--------------------------------------------------------------------------------
/src/Components/Onboarding/Footer.jsx:
--------------------------------------------------------------------------------
1 | import { useFooterStyles } from "../../Styles/Onboarding/useFooterStyles";
2 | import PrimaryButton from "./PrimaryButton";
3 | import CompleteButton from "./CompleteButton";
4 |
5 | const Footer = ({ button1, button2 }) => {
6 | const classes = useFooterStyles();
7 |
8 | return (
9 | <>
10 |
11 |
12 |
13 |
17 | >
18 | );
19 | };
20 |
21 | export default Footer;
22 |
--------------------------------------------------------------------------------
/src/Components/FactSubList.jsx:
--------------------------------------------------------------------------------
1 | import { Link, List, ListItem } from "@mui/material";
2 |
3 | const FactSubList = ({ resources }) => {
4 | return (
5 |
6 | {resources.map(resource => (
7 |
8 |
15 | {resource.name}
16 |
17 |
18 | ))}
19 |
20 | );
21 | };
22 | export default FactSubList;
23 |
--------------------------------------------------------------------------------
/src/Components/FactGroup.jsx:
--------------------------------------------------------------------------------
1 | import { Grid } from "@mui/material";
2 | import FactExpandMoreCard from "./FactExpandMoreCard";
3 |
4 | const FactGroup = ({ facts }) => {
5 | return (
6 |
7 | {facts.map(fact => (
8 |
9 |
16 |
17 | ))}
18 |
19 | );
20 | };
21 |
22 | export default FactGroup;
23 |
--------------------------------------------------------------------------------
/src/Assets/gsStep2.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/Assets/Onboarding/head.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/Components/LegalDisclaimer.jsx:
--------------------------------------------------------------------------------
1 | import PropTypes from "prop-types";
2 | import { Box, Typography } from "@mui/material";
3 | import { makeStyles } from "@mui/styles";
4 |
5 | const useStyles = makeStyles(theme => ({
6 | disclaimer: {
7 | margin: theme.spacing(2),
8 | fontSize: 14,
9 | },
10 | }));
11 |
12 | const LegalDisclaimer = ({ text }) => {
13 | const classes = useStyles();
14 | return (
15 |
16 |
17 | {text}
18 |
19 |
20 | );
21 | };
22 |
23 | export default LegalDisclaimer;
24 |
25 | LegalDisclaimer.propTypes = {
26 | text: PropTypes.string.isRequired,
27 | };
28 |
--------------------------------------------------------------------------------
/src/Assets/Onboarding/simpleQuestion.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/Assets/gsStep3.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/Assets/Onboarding/linkedIn.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/Components/FactSimpleCard.jsx:
--------------------------------------------------------------------------------
1 | import { Card, CardContent, Typography } from "@mui/material";
2 | import { makeStyles } from "@mui/styles";
3 |
4 | const useStyles = makeStyles(theme => ({
5 | rootStyle: {
6 | minHeight: "14em",
7 | display: "flex",
8 | justifyContent: "center",
9 | alignItems: "center",
10 | margin: theme.spacing(2),
11 | },
12 | }));
13 |
14 | const FactSimpleCard = props => {
15 | const { children } = props;
16 | const classes = useStyles();
17 | return (
18 |
19 |
20 |
21 | {children}
22 |
23 |
24 |
25 | );
26 | };
27 |
28 | export default FactSimpleCard;
29 |
--------------------------------------------------------------------------------
/src/Components/ContentSection.jsx:
--------------------------------------------------------------------------------
1 | import { Container, Paper, Typography } from "@mui/material";
2 | import { useHomeStyles } from "../Styles/useHomeStyles";
3 |
4 | const ContentSection = props => {
5 | const { sectionId, sectionSize, sectionTitle, children } = props;
6 | const classes = useHomeStyles();
7 |
8 | return (
9 |
10 |
11 | {sectionTitle && (
12 |
13 | {sectionTitle}
14 |
15 | )}
16 | {children}
17 |
18 |
19 | );
20 | };
21 |
22 | export default ContentSection;
23 |
--------------------------------------------------------------------------------
/src/Assets/Onboarding/world.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/Pages/ErrorPage.jsx:
--------------------------------------------------------------------------------
1 | import { useEffect } from "react";
2 | import { Typography, Container, Grid } from "@mui/material";
3 | import { trackPageview } from "../trackingUtils";
4 | import { useDocumentTitle } from "../Components/customHooks/useDocumentTitle";
5 |
6 | /** MATERIAL UI IMPORTS */
7 |
8 | const ErrorPage = () => {
9 | useEffect(() => trackPageview("Error"), []);
10 | useDocumentTitle("Error Page - ");
11 |
12 | return (
13 |
14 |
15 |
16 |
17 | Oops, page not found!
18 |
19 |
20 |
21 |
22 | );
23 | };
24 |
25 | export default ErrorPage;
26 |
--------------------------------------------------------------------------------
/src/Components/__tests__/Footer.spec.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { render, screen } from "@testing-library/react";
3 | import { BrowserRouter } from "react-router-dom";
4 | import { ThemeProvider } from "@mui/material/styles";
5 | import Footer from "../Footer";
6 | import Theme from "../Theme.tsx";
7 |
8 | describe("", () => {
9 | it("should render the footer with expected elements", () => {
10 | render(
11 |
12 |
13 | ,
14 | { wrapper: BrowserRouter }
15 | );
16 |
17 | const footer = screen.getByTestId("footer");
18 | expect(footer).toBeVisible();
19 |
20 | const footerLinks = screen.getAllByTestId("footer-link");
21 | expect(footerLinks.length).toEqual(4);
22 | expect(footerLinks[0]).toHaveAttribute("href", "/get-started");
23 | });
24 | });
25 |
--------------------------------------------------------------------------------
/src/Components/__tests__/ProgressBar.spec.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { render, screen } from "@testing-library/react";
3 | import ProgressBar from "../ProgressBar";
4 |
5 | const getDefaultProps = () => ({
6 | currentSectionName: "Surrounding Circumstances",
7 | totalSections: 3,
8 | });
9 |
10 | describe("", () => {
11 | it("should render a progress bar with expected elements", () => {
12 | render();
13 | const progressBar = screen.getByTestId("progress-bar");
14 | expect(progressBar).toBeVisible();
15 |
16 | const steps = screen.getAllByTestId("progress-bar-step");
17 | expect(steps.length).toEqual(3);
18 |
19 | const firstStepLabel = screen.getByText("Surrounding Circumstances");
20 | expect(firstStepLabel).toBeVisible();
21 | expect(firstStepLabel).toHaveClass("Mui-active");
22 | });
23 | });
24 |
--------------------------------------------------------------------------------
/src/Assets/Onboarding/venn.svg:
--------------------------------------------------------------------------------
1 |
6 |
--------------------------------------------------------------------------------
/src/Components/NavigationLogo.jsx:
--------------------------------------------------------------------------------
1 | import { ButtonBase } from "@mui/material";
2 | import { useEffect, useState } from "react";
3 | import largeLogo from "../Assets/cVLogoInlineLight.svg";
4 | import smallLogo from "../Assets/cv_small_logo_dark. 1.svg";
5 |
6 | const NavigationLogo = () => {
7 | const [isLargeScreen, setIsLargeScreen] = useState(true);
8 |
9 | useEffect(() => {
10 | const mediaSize = window.innerWidth;
11 | const shouldSetAsLargeScreen = mediaSize >= 768;
12 | setIsLargeScreen(shouldSetAsLargeScreen);
13 | }, []);
14 |
15 | return (
16 |
17 | {isLargeScreen ? (
18 |
19 | ) : (
20 |
21 | )}
22 |
23 | );
24 | };
25 |
26 | export default NavigationLogo;
27 |
--------------------------------------------------------------------------------
/src/Assets/Onboarding/screens.svg:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/src/Assets/Onboarding/tool.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/Pages/Calculator/QuickStartGuideStyles.js:
--------------------------------------------------------------------------------
1 | import { makeStyles } from "@mui/styles";
2 |
3 | export const QuickStartGuideStyles = makeStyles(theme => ({
4 | grid: {
5 | display: "inline-block",
6 | marginTop: "32px",
7 | justifyContent: "center",
8 | },
9 | header: {
10 | marginBottom: "16px",
11 | textAlign: "center",
12 | },
13 | body: {
14 | textAlign: "left",
15 | marginTop: "24px",
16 | marginBottom: "24px",
17 | },
18 | bodyGrid: {
19 | marginBottom: "72px",
20 | },
21 | buttonGrid: {},
22 | button: {
23 | marginBottom: "16px",
24 | },
25 | backButton: {
26 | marginTop: "16px",
27 | marginBottom: "32px",
28 | justifyContent: "flex-start",
29 | },
30 | progressBar: {
31 | marginBottom: "16px",
32 | marginLeft: "5vw",
33 | },
34 | list: {
35 | fontSize: "18px",
36 | [theme.breakpoints.down("sm")]: {
37 | fontSize: "14px",
38 | },
39 | },
40 | }));
41 |
--------------------------------------------------------------------------------
/src/Components/Onboarding/MiroVideoModal.jsx:
--------------------------------------------------------------------------------
1 | const MiroVideoModal = () => {
2 | const miro = "https://drive.google.com/file/d/1dPIDPah9GbxFhOwi25t_x8YgvPU_33LZ/preview";
3 |
4 | return (
5 |
17 |
29 |
30 | );
31 | };
32 |
33 | export default MiroVideoModal;
34 |
--------------------------------------------------------------------------------
/src/Components/Onboarding/FindVideoModal.jsx:
--------------------------------------------------------------------------------
1 | const FindVideoModal = () => {
2 | const find = "https://drive.google.com/file/d/1TG5iz3ioxMFxNsS1YO8MoKaY9uD-NHjm/preview";
3 |
4 | return (
5 |
17 |
29 |
30 | );
31 | };
32 |
33 | export default FindVideoModal;
34 |
--------------------------------------------------------------------------------
/src/Assets/Onboarding/meditate.svg:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Clearviction
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/src/ui-kit/CalulatorDialog.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Typography, DialogTitle, DialogContent, DialogContentText } from "@mui/material";
3 | import { ExternalLink } from "./ExternalLink";
4 |
5 | const CalulatorDialog = props => {
6 | return (
7 | <>
8 | Not sure?
9 |
10 |
11 |
12 | If you don't know the answer, request your criminal record through{" "}
13 |
14 |
15 | Washington State Patrol.
16 |
17 |
18 |
19 | >
20 | );
21 | };
22 |
23 | export default CalulatorDialog;
24 |
25 | // updated modal content can be found here: https://github.com/openseattle/clearviction/commit/eb1621134394170665fbfdb7837b750c31ba5bdc
26 |
--------------------------------------------------------------------------------
/src/Assets/topScrollButton.svg:
--------------------------------------------------------------------------------
1 |
19 |
--------------------------------------------------------------------------------
/src/Styles/WhyVacateEducationStyles.ts:
--------------------------------------------------------------------------------
1 | import { makeStyles } from "@mui/styles";
2 |
3 | export const WhyVacateHousingStyles = makeStyles(theme => ({
4 | containerStyles: {
5 | margin: theme.spacing(2),
6 | marginTop: theme.spacing(5),
7 | marginBottom: theme.spacing(5),
8 | [theme.breakpoints.down("md")]: {
9 | padding: theme.spacing(3),
10 | },
11 | },
12 | contentText: {
13 | margin: theme.spacing(2),
14 | },
15 | contentTextAlt: {
16 | color: "white",
17 | margin: theme.spacing(2),
18 | paddingBottom: theme.spacing(2),
19 | },
20 | title: {
21 | margin: theme.spacing(2),
22 | },
23 | roleImage: {
24 | height: 300,
25 | width: 300,
26 | },
27 | headingRoles: {
28 | color: theme.palette.primary.main,
29 | paddingBottom: theme.spacing(2),
30 | },
31 | blackHeaderText: {
32 | color: "black",
33 | padding: theme.spacing(2),
34 | },
35 | lightBlueSectionBackground: {
36 | backgroundColor: theme.palette.primary.main,
37 | color: "white",
38 | },
39 | }));
40 |
--------------------------------------------------------------------------------
/src/Components/RestartButton.jsx:
--------------------------------------------------------------------------------
1 | import { makeStyles } from "@mui/styles";
2 |
3 | const BACK_ARROW_TRANSFORM = "scale(-1, 1) rotate(270deg)";
4 | const useStyles = makeStyles(theme => ({
5 | root: {
6 | margin: "0 auto",
7 | textDecoration: "underline",
8 | color: theme.palette.primary.main,
9 | fontWeight: theme.typography.h4.fontWeight,
10 | "&:before": {
11 | content: "'↺'",
12 | position: "absolute",
13 | marginLeft: "-1em",
14 | marginTop: "-0.3em",
15 | fontSize: "1.75em",
16 | "-moz-transform": BACK_ARROW_TRANSFORM,
17 | "-webkit-transform": BACK_ARROW_TRANSFORM,
18 | "-o-transform": BACK_ARROW_TRANSFORM,
19 | "-ms-transform": BACK_ARROW_TRANSFORM,
20 | transform: BACK_ARROW_TRANSFORM,
21 | },
22 | },
23 | }));
24 |
25 | const RestartButton = () => {
26 | const classes = useStyles();
27 |
28 | return (
29 |
30 | Check another conviction
31 |
32 | );
33 | };
34 |
35 | export default RestartButton;
36 |
--------------------------------------------------------------------------------
/src/Assets/Onboarding/remote.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/Components/AccordionBuilder.jsx:
--------------------------------------------------------------------------------
1 | import { Accordion, AccordionDetails, AccordionSummary, Typography, Box } from "@mui/material";
2 | import { ExpandMore } from "@mui/icons-material";
3 |
4 | function a11yProps(index) {
5 | return {
6 | id: `panel${index}a-header`,
7 | "aria-controls": `panel${index}a-content`,
8 | };
9 | }
10 |
11 | const AccordionBuilder = ({ faqs }) => {
12 | return (
13 |
14 | {faqs.map((faq, idx) => (
15 |
16 | } aria-controls={faq.detailsID} {...a11yProps}>
17 |
18 | {faq.summary}
19 |
20 |
21 |
22 | {faq.details}
23 |
24 |
25 | ))}
26 |
27 | );
28 | };
29 | export default AccordionBuilder;
30 |
--------------------------------------------------------------------------------
/src/Styles/Onboarding/useMod2Styles.js:
--------------------------------------------------------------------------------
1 | import { makeStyles } from "@mui/styles";
2 |
3 | export const useMod2Styles = makeStyles(theme => ({
4 | subHeading: {
5 | color: theme.palette.primary.main,
6 | fontSize: "64px",
7 | margin: "0 auto",
8 | marginLeft: "auto",
9 | marginRight: "auto",
10 | marginTop: theme.spacing(10),
11 | marginBottom: theme.spacing(8),
12 | textAlign: "center",
13 | paddingLeft: theme.spacing(3),
14 | [theme.breakpoints.down("md")]: {
15 | fontSize: "40px",
16 | marginTop: theme.spacing(8),
17 | marginBottom: theme.spacing(6),
18 | paddingLeft: 0,
19 | lineHeight: 1.2,
20 | },
21 | gridStyle: {
22 | display: "flex",
23 | flexDirection: "row",
24 | margin: "20px auto",
25 | justifyContent: "space-around",
26 | textAlign: "center",
27 | padding: "0 50px",
28 | [theme.breakpoints.down("md")]: {
29 | padding: 0,
30 | flexDirection: "column",
31 | margin: "auto",
32 | },
33 | },
34 | },
35 | }));
36 |
--------------------------------------------------------------------------------
/src/Pages/Calculator/EndScreenStyles.js:
--------------------------------------------------------------------------------
1 | import { makeStyles } from "@mui/styles";
2 |
3 | export const EndScreenStyles = makeStyles(theme => ({
4 | grid: {
5 | display: "inline-block",
6 | marginTop: "24px",
7 | justifyContent: "center",
8 | textAlign: "center",
9 | },
10 | header: {
11 | marginTop: "32px",
12 | marginBottom: "16px",
13 | textAlign: "left",
14 | },
15 | body: {
16 | textAlign: "left",
17 | marginBottom: "16px",
18 | },
19 | bodyList: {
20 | textAlign: "left",
21 | marginBottom: "16px",
22 | },
23 | bodyGrid: {
24 | marginBottom: "72px",
25 | },
26 | buttonGrid: {
27 | marginTop: "40px",
28 | marginBottom: "32px",
29 | },
30 | button: {
31 | marginBottom: "16px",
32 | },
33 | backButton: {
34 | marginTop: "16px",
35 | marginBottom: "40px",
36 | justifyContent: "flex-start",
37 | },
38 | restartButton: {
39 | marginBottom: "72px",
40 | },
41 | list: {
42 | fontSize: "18px",
43 | [theme.breakpoints.down("sm")]: {
44 | fontSize: "14px",
45 | },
46 | },
47 | }));
48 |
--------------------------------------------------------------------------------
/pull_request_template.md:
--------------------------------------------------------------------------------
1 | ### Ticket(s)
2 |
3 | _Required unless this is just a change to documentation._
4 |
5 | - _[Replace with link]_
6 |
7 | ### Type of change
8 |
9 | _Please delete any options that are not relevant_
10 |
11 | - [ ] Bug fix (non-breaking change which fixes an issue)
12 | - [ ] New feature (non-breaking change which adds functionality)
13 | - [ ] Breaking change (fix or feature that would cause existing functionality to not work as expected)
14 |
15 | ### Description
16 |
17 | Please include a summary of the change and which issue is fixed. Please also include relevant motivation and context. List any dependencies that are required for this change.
18 |
19 | Fixes # (issue)
20 |
21 | ### Screenshots
22 |
23 | #### Before
24 |
25 | #### After
26 |
27 | ### Checklist:
28 |
29 | - [ ] I have performed a self-review of my own code
30 | - [ ] I have commented my code, particularly in hard-to-understand areas
31 | - [ ] I have made corresponding changes to the documentation (if applicable)
32 | - [ ] My changes generate no new warnings
33 | - [ ] I have added tests that prove my fix is effective or that my feature works (if applicable)
34 | - [ ] New and existing unit tests pass locally with my changes
35 |
--------------------------------------------------------------------------------
/src/Assets/Onboarding/progress.svg:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/src/Components/__tests__/ToolTipModal.spec.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { render, screen } from "@testing-library/react";
3 | import userEvent from "@testing-library/user-event";
4 | import ToolTipModal from "../ToolTipModal";
5 |
6 | describe("", () => {
7 | const template = ;
8 |
9 | it("should render the default modal ui", () => {
10 | render(template);
11 |
12 | expect(screen.getByTestId("tooltip-modal-wrapper")).toBeVisible();
13 | expect(screen.getByRole("button", { name: /test/i })).toBeInTheDocument();
14 | expect(screen.queryByTestId("tooltip-modal")).not.toBeInTheDocument();
15 | });
16 |
17 | it("should open and close the modal", async () => {
18 | const user = userEvent.setup();
19 | const contentMatcher = /If you don't know the answer, you may check your criminal record/i;
20 |
21 | render(template);
22 |
23 | await user.click(screen.getByRole("button", { name: /test/i }));
24 |
25 | expect(screen.getByText(contentMatcher)).toBeVisible();
26 |
27 | await user.keyboard("{Esc}");
28 |
29 | expect(screen.queryByText(contentMatcher)).not.toBeInTheDocument();
30 | });
31 | });
32 |
--------------------------------------------------------------------------------
/src/Assets/Onboarding/circleArrow.svg:
--------------------------------------------------------------------------------
1 |
9 |
--------------------------------------------------------------------------------
/src/Components/HeroPanel.jsx:
--------------------------------------------------------------------------------
1 | import { Box, Typography } from "@mui/material";
2 | import { makeStyles } from "@mui/styles";
3 |
4 | const useStyles = makeStyles(theme => ({
5 | hero: {
6 | paddingTop: theme.spacing(5),
7 | paddingBottom: theme.spacing(5),
8 | },
9 | heroTitle: {
10 | paddingTop: theme.spacing(2),
11 | paddingBottom: theme.spacing(2),
12 | },
13 | heroSubtitle: {
14 | paddingTop: theme.spacing(2),
15 | paddingBottom: theme.spacing(2),
16 | fontSize: 24,
17 | [theme.breakpoints.down("sm")]: {
18 | fontSize: 18,
19 | },
20 | },
21 | }));
22 | const HeroPanel = props => {
23 | const { title, subtitle } = props;
24 | const classes = useStyles();
25 | return (
26 |
27 |
28 | {title}
29 |
30 | {subtitle && (
31 |
32 | {subtitle}
33 |
34 | )}
35 |
36 | );
37 | };
38 |
39 | export default HeroPanel;
40 |
--------------------------------------------------------------------------------
/src/Pages/Calculator/SpecialCaseTitleStyles.js:
--------------------------------------------------------------------------------
1 | import { makeStyles } from "@mui/styles";
2 |
3 | export const SpecialCaseTitleStyles = makeStyles(theme => ({
4 | grid: {
5 | display: "inline-block",
6 | marginTop: "32px",
7 | justifyContent: "center",
8 | textAlign: "center",
9 | },
10 | header: {
11 | marginBottom: "24px",
12 | fontWeight: 600,
13 | textAlign: "left",
14 | },
15 | body: {
16 | textAlign: "left",
17 | padding: "5px",
18 | },
19 | bodyGrid: {
20 | display: "inline-block",
21 | marginBottom: "72px",
22 | },
23 | button: {
24 | marginBottom: "40px",
25 | },
26 | backButton: {
27 | marginBlock: "32px",
28 | justifyContent: "flex-start",
29 | },
30 | // temporary placeholder for Blake vacation -- sprint 26, 6/27/22
31 | blakeLink: {
32 | fontSize: "24px",
33 | lineHeight: 3,
34 | [theme.breakpoints.down("sm")]: {
35 | fontSize: "18px",
36 | fontWeight: "bold",
37 | },
38 | },
39 | list: {
40 | fontSize: "18px",
41 | [theme.breakpoints.down("sm")]: {
42 | fontSize: "14px",
43 | },
44 | },
45 | }));
46 |
--------------------------------------------------------------------------------
/src/Styles/WhyVacateHousingStyles.ts:
--------------------------------------------------------------------------------
1 | import { makeStyles } from "@mui/styles";
2 |
3 | export const WhyVacateHousingStyles = makeStyles(theme => ({
4 | containerStyles: {
5 | margin: theme.spacing(2),
6 | marginTop: theme.spacing(5),
7 | marginBottom: theme.spacing(5),
8 | [theme.breakpoints.down("md")]: {
9 | padding: theme.spacing(3),
10 | },
11 | },
12 | containerSpaceOnlyStyles: {
13 | marginTop: theme.spacing(8),
14 | marginBottom: theme.spacing(8),
15 | },
16 | contentText: {
17 | margin: theme.spacing(2),
18 | },
19 | contentTextAlt: {
20 | color: "white",
21 | margin: theme.spacing(2),
22 | paddingBottom: theme.spacing(2),
23 | },
24 | title: {
25 | margin: theme.spacing(2),
26 | },
27 | roleImage: {
28 | height: 300,
29 | maxWidth: 300,
30 | },
31 | headingRoles: {
32 | color: theme.palette.primary.main,
33 | paddingBottom: theme.spacing(2),
34 | },
35 | blackHeaderText: {
36 | color: "black",
37 | padding: theme.spacing(2),
38 | },
39 | lightBlueSectionBackground: {
40 | backgroundColor: theme.palette.primary.main,
41 | color: "white",
42 | },
43 | }));
44 |
--------------------------------------------------------------------------------
/src/Components/Table.jsx:
--------------------------------------------------------------------------------
1 | import { Table, TableBody, TableCell, TableContainer, TableHead, TableRow, Paper, Typography } from "@mui/material";
2 |
3 | const DataTable = ({ tableHeader, data }) => {
4 | return (
5 |
6 | {tableHeader}
7 |
8 |
9 |
10 | Question
11 | Your Answer
12 |
13 |
14 |
15 | {data.map((row, idx) => (
16 |
17 |
18 | {row[0].question}
19 |
20 | {row[0].answer}
21 |
22 | ))}
23 |
24 |
25 |
26 | );
27 | };
28 |
29 | export default DataTable;
30 |
--------------------------------------------------------------------------------
/src/Assets/Onboarding/checkmark.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/Components/DonateLevelCard.jsx:
--------------------------------------------------------------------------------
1 | import { Box, Card, Typography } from "@mui/material";
2 | import { makeStyles } from "@mui/styles";
3 |
4 | const useStyles = makeStyles(theme => ({
5 | rootCardStyle: {
6 | height: 470,
7 | width: 300,
8 | display: "flex",
9 | flexDirection: "column",
10 | },
11 | amountStyle: {
12 | padding: theme.spacing(3),
13 | },
14 | donationImageStyle: {
15 | width: 250,
16 | padding: theme.spacing(1),
17 | },
18 | }));
19 |
20 | const DonateLevelCard = ({ amount, image, text, alt }) => {
21 | const classes = useStyles();
22 | return (
23 |
24 |
25 | {amount}
26 |
27 |
28 |
29 |
30 |
31 |
32 | {text}
33 |
34 |
35 |
36 | );
37 | };
38 |
39 | export default DonateLevelCard;
40 |
--------------------------------------------------------------------------------
/src/Components/Onboarding/SocialContainer.jsx:
--------------------------------------------------------------------------------
1 | import { useHeaderStyles } from "../../Styles/Onboarding/useHeaderStyles";
2 |
3 | import fb from "../../Assets/Onboarding/fb.svg";
4 | import linkedIn from "../../Assets/Onboarding/linkedIn.svg";
5 | import twitter from "../../Assets/Onboarding/twitter.svg";
6 |
7 | const SocialContainer = () => {
8 | const classes = useHeaderStyles();
9 |
10 | return (
11 |
32 | );
33 | };
34 |
35 | export default SocialContainer;
36 |
--------------------------------------------------------------------------------
/src/Assets/Onboarding/symbols.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/ui-kit/PrimaryButton.jsx:
--------------------------------------------------------------------------------
1 | import { Button } from "@mui/material";
2 | import { makeStyles } from "@mui/styles";
3 |
4 | const useStyles = makeStyles(theme => ({
5 | flexGrow: {
6 | flex: "1",
7 | },
8 | button: {
9 | backgroundColor: theme.palette.primary.main,
10 | color: theme.palette.primary.contrastText,
11 | textTransform: "uppercase",
12 | minHeight: "48px",
13 | minWidth: "248px",
14 | maxWidth: "30vw",
15 | fontSize: "18px",
16 | [theme.breakpoints.down("lg")]: {
17 | width: "100%",
18 | fontSize: "14px",
19 | },
20 | [theme.breakpoints.down("md")]: {
21 | width: "100%",
22 | fontSize: "12px",
23 | },
24 | borderRadius: "30px",
25 | padding: "10px",
26 | margin: "10px",
27 |
28 | "&:hover": {
29 | backgroundColor: theme.palette.secondary.main,
30 | color: theme.palette.secondary.contrastText,
31 | },
32 | },
33 | }));
34 |
35 | const PrimaryButton = ({ href, target, text }) => {
36 | const classes = useStyles();
37 |
38 | return (
39 |
42 | );
43 | };
44 |
45 | export default PrimaryButton;
46 |
--------------------------------------------------------------------------------
/src/Assets/Onboarding/boat.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/data/siteMap.ts:
--------------------------------------------------------------------------------
1 | enum PageId {
2 | Donate = "DONATE",
3 | Home = "HOME",
4 | GivingTuesday = "GIVINGTUESDAY",
5 | GetStarted = "GET-STARTED",
6 | GetInvolved = "GET-INVOLVED",
7 | WhyVacate = "WHY-VACATE",
8 | Contact = "CONTACT",
9 | AccessCalculator = "ACCESS-CALCULATOR",
10 | About = "ABOUT",
11 | }
12 |
13 | interface Page {
14 | name: string;
15 | url: string;
16 | key: PageId;
17 | subpages?: Page[];
18 | }
19 |
20 | const headerPages: Page[] = [
21 | { name: "Home", url: "/", key: PageId.Home },
22 | { name: "Get Started", url: "/get-started", key: PageId.GetStarted },
23 | { name: "Get Involved", url: "/get-involved", key: PageId.GetInvolved },
24 | { name: "Why Vacate", url: "/why-vacate", key: PageId.WhyVacate },
25 | { name: "Donate", url: "/donate", key: PageId.Donate },
26 | { name: "Contact", url: "/contact", key: PageId.Contact },
27 | { name: "Access Calculator", url: "/calculator/landing-0", key: PageId.AccessCalculator },
28 | ];
29 |
30 | const footerPages: Page[] = [
31 | { name: "Get Started", url: "/get-started", key: PageId.GetStarted },
32 | { name: "About", url: "/about", key: PageId.About },
33 | { name: "Get Involved", url: "/get-involved", key: PageId.GetInvolved },
34 | { name: "Contact", url: "/contact", key: PageId.Contact },
35 | ];
36 |
37 | export { headerPages, footerPages, PageId };
38 |
--------------------------------------------------------------------------------
/src/Components/Onboarding/CompleteButton.jsx:
--------------------------------------------------------------------------------
1 | import { useState, useEffect } from "react";
2 | import { useLocation } from "react-router-dom";
3 | import { Button } from "@mui/material";
4 | import CheckCircleOutlineIcon from "@mui/icons-material/CheckCircleOutline";
5 |
6 | const CompleteButton = () => {
7 | const location = useLocation();
8 | const [isComplete, setIsComplete] = useState();
9 |
10 | useEffect(() => {
11 | const completedMod = localStorage.getItem(`${location.pathname}`);
12 | if (completedMod) {
13 | setIsComplete(true);
14 | }
15 | }, [location.pathname]);
16 |
17 | const handleComplete = () => {
18 | const completedMod = localStorage.getItem(`${location.pathname}`);
19 | if (completedMod) {
20 | localStorage.removeItem(`${location.pathname}`);
21 | } else {
22 | localStorage.setItem(`${location.pathname}`, !isComplete);
23 | }
24 | setIsComplete(!isComplete);
25 | };
26 |
27 | return (
28 | : null}
32 | onClick={handleComplete}
33 | >
34 | {isComplete ? "Completed" : "Mark as complete"}
35 |
36 | );
37 | };
38 |
39 | export default CompleteButton;
40 |
--------------------------------------------------------------------------------
/src/Assets/Onboarding/twitter.svg:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/src/Components/DonationForm.jsx:
--------------------------------------------------------------------------------
1 | import { Box } from "@mui/material";
2 |
3 | const DonationForm = () => {
4 | return (
5 |
19 | );
20 | };
21 |
22 | const DonationMeter = () => {
23 | return (
24 |
25 |
40 |
41 | );
42 | };
43 |
44 | export { DonationForm, DonationMeter };
45 |
--------------------------------------------------------------------------------
/src/Pages/Calculator/MainBranchTitle.jsx:
--------------------------------------------------------------------------------
1 | import { Grid, Typography } from "@mui/material";
2 | import PrimaryButton from "../../ui-kit/PrimaryButton";
3 | import { MainBranchTitleStyles } from "./MainBranchTitleStyles";
4 | import { BackButton } from "../../ui-kit/BackButton";
5 | import ProgressBar from "../../Components/ProgressBar";
6 |
7 | const MainBranchTitle = ({ progressBar, backButton, header, body, buttonText, buttonHref }) => {
8 | const classes = MainBranchTitleStyles();
9 | return (
10 |
11 | {progressBar && }
12 |
13 | {backButton && (
14 |
15 |
16 |
17 | )}
18 |
19 |
20 | {header}
21 |
22 |
23 | {body &&
24 | body.map(bodyElement => (
25 |
26 | {bodyElement.text}
27 |
28 | ))}
29 |
30 |
31 | );
32 | };
33 |
34 | export default MainBranchTitle;
35 |
--------------------------------------------------------------------------------
/src/Components/VolunteerRolesCard.jsx:
--------------------------------------------------------------------------------
1 | import { Box, Card, Typography } from "@mui/material";
2 | import { makeStyles } from "@mui/styles";
3 |
4 | const useStyles = makeStyles(theme => ({
5 | roleRootStyle: {
6 | maxWidth: "16em",
7 | height: "30em",
8 | margin: theme.spacing(2),
9 | paddingTop: theme.spacing(5),
10 | paddingBottom: theme.spacing(8),
11 | },
12 | roleImageStyle: {
13 | width: "100%",
14 | margin: theme.spacing(2),
15 | },
16 | roleHeadingStyle: {
17 | margin: theme.spacing(3),
18 | },
19 | }));
20 |
21 | const VolunteerRolesCard = ({ image, discipline, roles, alt }) => {
22 | const classes = useStyles();
23 | return (
24 |
25 |
26 |
27 |
28 |
29 | {discipline}
30 |
31 | {roles.map((role, idx) => (
32 |
33 | {role}
34 |
35 | ))}
36 |
37 | );
38 | };
39 |
40 | export default VolunteerRolesCard;
41 |
--------------------------------------------------------------------------------
/src/Subpages/WhyVacate/IconWithHeaderAndText.jsx:
--------------------------------------------------------------------------------
1 | import { SvgIcon, Grid, Typography } from "@mui/material";
2 | import { makeStyles } from "@mui/styles";
3 |
4 | const useStyles = makeStyles(theme => ({
5 | mainText: {
6 | minWidth: 150,
7 | fontSize: 16,
8 | paddingTop: 5,
9 | },
10 | icons: {
11 | color: theme.palette.secondary.main,
12 | fontSize: "64px",
13 | margin: theme.spacing(2),
14 | },
15 | gridItemStyle: {
16 | paddingBottom: theme.spacing(5),
17 | },
18 | }));
19 |
20 | export const IconWithHeaderAndText = props => {
21 | const classes = useStyles();
22 | const { icon, header, text } = props;
23 | const textItems = text.map((t, idx) => (
24 |
25 | {t}
26 |
27 | ));
28 |
29 | return (
30 |
31 |
32 |
33 |
34 |
35 |
36 | {header}
37 | {textItems}
38 |
39 |
40 |
41 | );
42 | };
43 |
--------------------------------------------------------------------------------
/src/Components/RedesignHeroPanel.jsx:
--------------------------------------------------------------------------------
1 | import { Box, Container, Typography } from "@mui/material";
2 | import { makeStyles } from "@mui/styles";
3 |
4 | const useStyles = makeStyles(theme => ({
5 | hero: {
6 | paddingTop: theme.spacing(16),
7 | paddingBottom: theme.spacing(16),
8 | backgroundColor: theme.palette.primary.dark,
9 | color: theme.palette.primary.contrastText,
10 | },
11 | heroTitle: {
12 | paddingTop: theme.spacing(3),
13 | paddingBottom: theme.spacing(3),
14 | },
15 | heroSubtitle: {
16 | maxWidth: "27em",
17 | paddingTop: theme.spacing(2),
18 | paddingBottom: theme.spacing(5),
19 | },
20 | }));
21 | const RedesignHeroPanel = props => {
22 | const { title, subtitle, children } = props;
23 | const classes = useStyles();
24 | return (
25 |
26 |
27 |
28 | {title}
29 |
30 | {subtitle && (
31 |
32 | {subtitle}
33 |
34 | )}
35 | {children}
36 |
37 |
38 | );
39 | };
40 |
41 | export default RedesignHeroPanel;
42 |
--------------------------------------------------------------------------------
/src/Pages/Calculator/QuestionScreenStyles.js:
--------------------------------------------------------------------------------
1 | import { makeStyles } from "@mui/styles";
2 |
3 | export const QuestionScreenStyles = makeStyles(theme => ({
4 | grid: {
5 | display: "inline-block",
6 | marginTop: "32px",
7 | justifyContent: "center",
8 | },
9 | header: {
10 | marginBottom: "16px",
11 | textAlign: "center",
12 | },
13 | body: {
14 | textAlign: "left",
15 | color: "black",
16 | },
17 | bodyGrid: {
18 | marginBottom: "72px",
19 | },
20 | buttonGrid: {
21 | paddingBottom: "32px",
22 | textAlign: "center",
23 | },
24 | button: {
25 | marginBottom: "16px",
26 | },
27 | backButton: {
28 | marginTop: "16px",
29 | marginBottom: "32px",
30 | justifyContent: "flex-start",
31 | },
32 | progressBar: {
33 | marginBottom: "16px",
34 | marginLeft: "5vw",
35 | },
36 | list: {
37 | fontSize: "18px",
38 | [theme.breakpoints.down("sm")]: {
39 | fontSize: "14px",
40 | },
41 | },
42 | dialogImg: {
43 | display: "flex",
44 | justifyContent: "center",
45 | [theme.breakpoints.down("sm")]: {
46 | width: "175px",
47 | height: "90px",
48 | },
49 | [theme.breakpoints.down("md")]: {
50 | width: "375px",
51 | height: "150px",
52 | },
53 | },
54 | }));
55 |
--------------------------------------------------------------------------------
/.eslintrc.yaml:
--------------------------------------------------------------------------------
1 | ---
2 | env:
3 | browser: true
4 | es2021: true
5 | jest: true
6 | extends:
7 | - eslint:recommended
8 | - plugin:react/recommended
9 | - airbnb
10 | - airbnb/hooks
11 | - standard-with-typescript
12 | - plugin:prettier/recommended
13 | overrides:
14 | - files:
15 | - "*.jsx"
16 | - "*.js"
17 | - "*.ts"
18 | - "*.tsx"
19 | ignorePatterns:
20 | - "*/*-env.d.ts"
21 | - "**/__tests__/**"
22 | - "**/*.spec.js"
23 | - "build/"
24 | settings:
25 | import/resolver:
26 | - typescript: "{}"
27 | parser: "@typescript-eslint/parser"
28 | parserOptions:
29 | ecmaFeatures:
30 | jsx: false
31 | ecmaVersion: latest
32 | sourceType: module
33 | project: "./tsconfig.json"
34 | plugins:
35 | - react
36 | - "@typescript-eslint"
37 | - unused-imports
38 | - import
39 | rules:
40 | unused-imports/no-unused-imports:
41 | - error
42 | jsx-quotes:
43 | - error
44 | - prefer-double
45 | no-shadow: "off"
46 | "@typescript-eslint/no-shadow":
47 | - error
48 | react/react-in-jsx-scope: "off"
49 | react/function-component-definition:
50 | - error
51 | - namedComponents: arrow-function
52 | react/prop-types: 1
53 | react/no-array-index-key: 1
54 | react/jsx-props-no-spreading: 1
55 | import/prefer-default-export: 1
56 | react/no-unescaped-entities: 0
57 | camelcase: 1
58 |
--------------------------------------------------------------------------------
/src/Pages/ContactPage.jsx:
--------------------------------------------------------------------------------
1 | import { Container, Typography, Box, Grid } from "@mui/material";
2 | import ContactForm from "../Components/ContactForm";
3 | import { useContactStyles } from "../Styles/useContactStyles";
4 | import new_message from "../Assets/new_message.svg";
5 | import { useDocumentTitle } from "../Components/customHooks/useDocumentTitle";
6 |
7 | const ContactPage = () => {
8 | const classes = useContactStyles();
9 | useDocumentTitle("Contact Us - ");
10 |
11 | return (
12 |
13 |
14 |
15 | Contact Us
16 |
17 |
18 |
19 |
20 | Have questions? Send us a message and we’ll get back to you within 24 hours.
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 | );
34 | };
35 | export default ContactPage;
36 |
--------------------------------------------------------------------------------
/src/Styles/Onboarding/useModalStyles.js:
--------------------------------------------------------------------------------
1 | import { makeStyles } from "@mui/styles";
2 |
3 | export const useModalStyles = makeStyles(theme => ({
4 | mainModal: {
5 | overflowY: "auto",
6 | height: "auto",
7 | },
8 | modalStyle: {
9 | position: "relative",
10 | backgroundColor: "white",
11 | margin: "auto",
12 | padding: "50px 80px",
13 | },
14 | modalContainer: {
15 | backgroundColor: "white",
16 | boxShadow: 24,
17 | padding: "75px",
18 | },
19 | videoContainer: {
20 | overflowY: "auto",
21 | backgroundColor: "white",
22 | },
23 | contentStyle: {
24 | margin: theme.spacing(3),
25 | maxWidth: "1000px",
26 | fontWeight: 400,
27 | fontSize: "16px",
28 | lineHeight: "22px",
29 | padding: 0,
30 | },
31 | button: {
32 | backgroundColor: theme.palette.primary.main,
33 | color: "white",
34 | textTransform: "capitalize",
35 | minWidth: "248px",
36 | maxWidth: "300px",
37 | height: "48px",
38 | textAlign: "center",
39 | display: "flex",
40 | verticalAlign: "middle",
41 | padding: "auto",
42 | boxShadow: "0 2px 4px rgba(0, 0, 0, 0.2)",
43 | borderRadius: "50px",
44 | margin: "auto",
45 | fontSize: "18px",
46 | fontWeight: "bold",
47 | lineHeight: 2.7,
48 | "&:hover": {
49 | color: "#000",
50 | backgroundColor: "#ffd200",
51 | },
52 | },
53 | }));
54 |
--------------------------------------------------------------------------------
/src/ui-kit/SecondaryButton.jsx:
--------------------------------------------------------------------------------
1 | import { Button } from "@mui/material";
2 | import { makeStyles } from "@mui/styles";
3 |
4 | const useStyles = makeStyles(theme => ({
5 | flexGrow: {
6 | flex: "1",
7 | },
8 | button: {
9 | backgroundColor: theme.palette.common.white,
10 | color: theme.palette.primary.main,
11 | textTransform: "uppercase",
12 | width: "248px",
13 | height: "48px",
14 | fontSize: "18px",
15 | [theme.breakpoints.down("lg")]: {
16 | fontSize: "14px",
17 | },
18 | [theme.breakpoints.down("sm")]: {
19 | fontSize: "12px",
20 | },
21 | border: `${theme.palette.primary.main} solid`,
22 | borderRadius: "30px",
23 | padding: "10px",
24 | margin: "10px",
25 | "&:hover": {
26 | border: `${theme.palette.primary.dark} solid`,
27 | backgroundColor: theme.palette.primary.dark,
28 | color: theme.palette.common.white,
29 | },
30 | },
31 | }));
32 |
33 | const SecondaryButton = ({ text, type, linkTo, externalLink, onClick }) => {
34 | const classes = useStyles();
35 | return externalLink ? (
36 |
39 | ) : (
40 |
43 | );
44 | };
45 |
46 | export default SecondaryButton;
47 |
--------------------------------------------------------------------------------
/src/ui-kit/SkipLink.tsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | interface SkipLinkProperties {
4 | className?: string;
5 |
6 | children: React.ReactElement;
7 | /**
8 | * The css query aiding the selection of the
9 | * container (main, section etc) we want to scroll to;
10 | */
11 | skipTo: string;
12 | }
13 |
14 | const SkipLink: React.FC = props => {
15 | /**
16 | * On click event for sighted folks
17 | * 'enter' key works as well
18 | */
19 | const onClick = (event: React.SyntheticEvent): void => {
20 | event.preventDefault();
21 | /**
22 | * Catch-all 'container' looking for HTML tags
23 | */
24 | const container: HTMLElement | null = document.querySelector(props.skipTo);
25 |
26 | /**
27 | * tabIndex seems to work well with the general layout of the site
28 | * Sets outline focus for screen-readers and sigthed alike
29 | */
30 | if (container != null) {
31 | container.tabIndex = -1;
32 | container.focus();
33 | setTimeout(() => container.removeAttribute("tabindex"), 1000);
34 | }
35 | };
36 |
37 | return React.cloneElement(props.children, { onClick, className: props.className });
38 | };
39 | /**
40 | * skipTo set as h1 seems to work well with general layout of site
41 | * Most, if not all, Subpages begin with this hiearchy
42 | */
43 |
44 | SkipLink.defaultProps = {
45 | className: "skipLink",
46 | skipTo: "h1:first-of-type",
47 | };
48 |
49 | export default SkipLink;
50 |
--------------------------------------------------------------------------------
/src/Subpages/WhyVacate/TextWithImage.jsx:
--------------------------------------------------------------------------------
1 | import { Box, Grid, Typography } from "@mui/material";
2 | import { makeStyles } from "@mui/styles";
3 |
4 | const useStyles = makeStyles(theme => ({
5 | rootGrid: {
6 | padding: theme.spacing(3),
7 | },
8 | headingRoles: {
9 | color: theme.palette.primary.main,
10 | paddingBottom: theme.spacing(2),
11 | },
12 | altHeadingRoles: {
13 | color: "white",
14 | paddingBottom: theme.spacing(2),
15 | },
16 | roleImage: {
17 | height: 300,
18 | width: "100%",
19 | },
20 | textMinimumStyle: {
21 | minHeight: "4em",
22 | },
23 | }));
24 |
25 | export const TextWithImage = props => {
26 | const classes = useStyles();
27 | const { img, header, text, cols, altStyle } = props;
28 | const textItems = text.map((t, idx) => (
29 |
30 | {t}
31 |
32 | ));
33 |
34 | return (
35 |
36 |
37 |
38 |
39 |
44 | {header}
45 |
46 | {textItems}
47 |
48 | );
49 | };
50 |
--------------------------------------------------------------------------------
/src/Components/StepsIconGroup.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Grid, Box, Typography } from "@mui/material";
3 | import useGetInvolvedStyles from "../Styles/useGetInvolvedStyles";
4 | import gsStep1 from "../Assets/gsStep1.svg";
5 | import gsStep2 from "../Assets/gsStep2.svg";
6 | import gsStep3 from "../Assets/gsStep3.svg";
7 | import gsStep4 from "../Assets/gsStep4.svg";
8 |
9 | const StepsIconGroup = () => {
10 | const classes = useGetInvolvedStyles();
11 |
12 | const gettingStartedSteps = [
13 | {
14 | id: "step1",
15 | icon: gsStep1,
16 | text: "Gather Documents",
17 | },
18 | {
19 | id: "step2",
20 | icon: gsStep2,
21 | text: "Calculate Eligibility",
22 | },
23 | {
24 | id: "step3",
25 | icon: gsStep3,
26 | text: "File with Court",
27 | },
28 | {
29 | id: "step4",
30 | icon: gsStep4,
31 | text: "Schedule Hearing",
32 | },
33 | ];
34 |
35 | return (
36 | <>
37 | {gettingStartedSteps.map(step => (
38 |
39 |
40 |
41 | {step.text}
42 |
43 |
44 | ))}
45 | >
46 | );
47 | };
48 |
49 | export default StepsIconGroup;
50 |
--------------------------------------------------------------------------------
/src/Components/ImageContentCard.jsx:
--------------------------------------------------------------------------------
1 | import { Paper, Typography, Box } from "@mui/material";
2 | import { makeStyles } from "@mui/styles";
3 | import { RedesignButtonPrimary } from "../ui-kit/RedesignButtonPrimary";
4 |
5 | const useStyles = makeStyles(() => ({
6 | rootStyle: {
7 | height: 460,
8 | minWidth: 280,
9 | maxWidth: 324,
10 | },
11 | cardTextSTyle: {
12 | padding: 34,
13 | },
14 | cardButtonBoxStyle: {
15 | marginTop: 64,
16 | display: "flex",
17 | justifyContent: "center",
18 | width: "100%",
19 | },
20 | }));
21 |
22 | const ImageContentCard = ({ content, image, buttonText, buttonHref }) => {
23 | const classes = useStyles();
24 |
25 | const retrieveImage = bgImage => `url(${bgImage})`;
26 |
27 | return (
28 |
29 |
38 |
39 | {content}
40 |
41 |
42 |
43 | {buttonText}
44 |
45 |
46 |
47 | );
48 | };
49 |
50 | export default ImageContentCard;
51 |
--------------------------------------------------------------------------------
/src/Assets/Onboarding/doc.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/src/Components/TabPanelGroup.jsx:
--------------------------------------------------------------------------------
1 | import { Tabs, Tab, Box } from "@mui/material";
2 | import { makeStyles } from "@mui/styles";
3 | import { useState } from "react";
4 |
5 | const TabPanel = props => {
6 | const { children, value, index, ...other } = props;
7 |
8 | return (
9 |
10 | {value === index && {children}}
11 |
12 | );
13 | };
14 |
15 | const useStyles = makeStyles(() => ({
16 | tabPanelStyle: {
17 | backgroundColor: "white",
18 | color: "black",
19 | borderBottomRightRadius: 5,
20 | borderBottomLeftRadius: 5,
21 | },
22 | }));
23 |
24 | function a11yProps(index) {
25 | return {
26 | id: `tab-${index}`,
27 | "aria-controls": `tabpanel-${index}`,
28 | };
29 | }
30 |
31 | const TabPanelGroup = props => {
32 | const classes = useStyles();
33 | const [value, setValue] = useState(0);
34 | const { tabs } = props;
35 |
36 | const handleChange = (event, newValue) => {
37 | setValue(newValue);
38 | };
39 | return (
40 |
41 |
42 | {tabs.map(tab => (
43 |
44 | ))}
45 |
46 |
47 | {tabs.map(tab => (
48 |
49 | {tab.content}
50 |
51 | ))}
52 |
53 | );
54 | };
55 |
56 | export default TabPanelGroup;
57 |
--------------------------------------------------------------------------------
/src/Subpages/WhyVacate/TextWithCTAButton.jsx:
--------------------------------------------------------------------------------
1 | import { Box, Typography, Container } from "@mui/material";
2 | import { makeStyles } from "@mui/styles";
3 | import SecondaryButton from "../../ui-kit/SecondaryButton";
4 |
5 | const useStyles = makeStyles(theme => ({
6 | mainText: {
7 | minWidth: 150,
8 | },
9 | backgroundSecondary: {
10 | minHeight: 250,
11 | backgroundColor: theme.palette.primary.dark,
12 | color: theme.palette.primary.contrastText,
13 | align: "center",
14 | paddingTop: theme.spacing(8),
15 | paddingBottom: theme.spacing(8),
16 | padding: theme.spacing(5),
17 | [theme.breakpoints.down("md")]: {
18 | paddingTop: theme.spacing(5),
19 | paddingBottom: theme.spacing(5),
20 | padding: theme.spacing(2),
21 | },
22 | [theme.breakpoints.down("sm")]: {
23 | minHeight: 300,
24 | },
25 | },
26 | buttonBoxStyles: {
27 | marginTop: theme.spacing(5),
28 | justifyContent: "center",
29 | display: "flex",
30 | },
31 | }));
32 |
33 | export const TextWithCTAButton = props => {
34 | const { text, buttonText, buttonLinkTo } = props;
35 | const classes = useStyles();
36 | return (
37 |
38 |
39 |
40 | {text}
41 |
42 |
43 |
44 |
45 |
46 |
47 | );
48 | };
49 |
--------------------------------------------------------------------------------
/src/Assets/Onboarding/userResearch.svg:
--------------------------------------------------------------------------------
1 |
7 |
--------------------------------------------------------------------------------
/src/Components/FactCard.jsx:
--------------------------------------------------------------------------------
1 | import { Card, CardContent, Typography } from "@mui/material";
2 | import { makeStyles } from "@mui/styles";
3 |
4 | const useStyles = makeStyles(theme => ({
5 | root: {
6 | height: "100%",
7 | display: "flex",
8 | flexDirection: "column",
9 | justifyContent: "center",
10 | padding: theme.spacing(2),
11 | margin: theme.spacing(1),
12 | },
13 | headingStyle: {
14 | marginBottom: theme.spacing(2),
15 | marginTop: theme.spacing(4),
16 | },
17 | contentStyle: {
18 | margin: "auto",
19 | },
20 | cardImageStyle: {
21 | maxWidth: "100%",
22 | },
23 | }));
24 |
25 | const FactCard = ({ simpleCardContents, isSimpleCard, fact }) => {
26 | const classes = useStyles();
27 | return (
28 |
29 |
30 | {isSimpleCard && (
31 |
32 | {simpleCardContents}
33 |
34 | )}
35 |
36 | {!isSimpleCard && fact?.textList && (
37 |
38 | {fact?.textList.map((listItem, idx) => (
39 | {listItem}
40 | ))}
41 |
42 | )}
43 |
44 | {!isSimpleCard && fact?.text && (
45 |
46 | {fact?.text}
47 |
48 | )}
49 |
50 |
51 | );
52 | };
53 |
54 | export default FactCard;
55 |
--------------------------------------------------------------------------------
/src/Components/FactImageCard.jsx:
--------------------------------------------------------------------------------
1 | import { Box, Card, CardContent, Typography } from "@mui/material";
2 | import { makeStyles } from "@mui/styles";
3 |
4 | const useStyles = makeStyles(theme => ({
5 | root: {
6 | height: "100%",
7 | display: "flex",
8 | flexDirection: "column",
9 | justifyContent: "space-between",
10 | padding: theme.spacing(2),
11 | },
12 | headingStyle: {
13 | marginBottom: theme.spacing(2),
14 | marginTop: theme.spacing(4),
15 | },
16 | contentStyle: {
17 | margin: "auto",
18 | },
19 | cardImageStyle: {
20 | maxWidth: "100%",
21 | },
22 | }));
23 |
24 | const FactImageCard = ({ fact }) => {
25 | const classes = useStyles();
26 | return (
27 |
28 |
29 |
30 |
31 |
32 | {fact.title}
33 |
34 |
35 | {fact.textList && (
36 |
37 | {fact.textList.map((listItem, idx) => (
38 | {listItem}
39 | ))}
40 |
41 | )}
42 |
43 | {fact.text && (
44 |
45 | {fact.text}
46 |
47 | )}
48 |
49 |
50 | );
51 | };
52 |
53 | export default FactImageCard;
54 |
--------------------------------------------------------------------------------
/src/ui-kit/ListItem.jsx:
--------------------------------------------------------------------------------
1 | import { Grid, ListItem, ListItemIcon, ListItemText, Link } from "@mui/material";
2 | import { makeStyles } from "@mui/styles";
3 | import FiberManualRecordIcon from "@mui/icons-material/FiberManualRecord";
4 |
5 | const useStyles = makeStyles(() => ({
6 | icon: {
7 | minWidth: "20px",
8 | },
9 | }));
10 |
11 | // eslint-disable-next-line import/prefer-default-export
12 | export const CVPListItem = props => {
13 | const { text, useBulletPoint, isLink, href, onClick } = props;
14 | const classes = useStyles();
15 |
16 | const renderListItem = listType => {
17 | switch (listType) {
18 | case "link":
19 | return (
20 |
28 | {text}
29 |
30 | );
31 | case "text":
32 | return {text};
33 | default:
34 | return null;
35 | }
36 | };
37 |
38 | return (
39 |
40 | {useBulletPoint && (
41 |
42 |
43 |
44 | )}
45 |
46 | {isLink && renderListItem("link")}
47 | {!isLink && renderListItem("text")}
48 |
49 |
50 | );
51 | };
52 |
--------------------------------------------------------------------------------
/src/Assets/diversity2.svg:
--------------------------------------------------------------------------------
1 |
12 |
--------------------------------------------------------------------------------
/src/Styles/WhyVacateEmploymentStyle.js:
--------------------------------------------------------------------------------
1 | import { makeStyles } from "@mui/styles";
2 |
3 | export const WhyVacateEmploymentStyles = makeStyles(theme => ({
4 | sectionSpaceStyle: {
5 | marginTop: theme.spacing(8),
6 | marginBottom: theme.spacing(8),
7 | },
8 | containerStyles: {
9 | margin: theme.spacing(15),
10 | [theme.breakpoints.down("lg")]: {
11 | margin: theme.spacing(8),
12 | },
13 | [theme.breakpoints.down("md")]: {
14 | margin: theme.spacing(5),
15 | },
16 | },
17 | containerStylesAlt: {
18 | margin: theme.spacing(15),
19 | [theme.breakpoints.down("lg")]: {
20 | margin: theme.spacing(8),
21 | },
22 | [theme.breakpoints.down("md")]: {
23 | margin: theme.spacing(5),
24 | },
25 | },
26 | title: {
27 | margin: theme.spacing(2),
28 | },
29 | contentText: {
30 | margin: theme.spacing(2),
31 | },
32 | lightBlueSectionBackground: {
33 | backgroundColor: theme.palette.primary.main,
34 | color: "white",
35 | },
36 | darkBlueSectionBackground: {
37 | backgroundColor: theme.palette.primary.dark,
38 | color: "white",
39 | },
40 | spacer: {
41 | padding: theme.spacing(3),
42 | },
43 | emphasizedText: {
44 | color: theme.palette.secondary.main,
45 | fontFamily: "lora",
46 | margin: theme.spacing(4),
47 | textAlign: "center",
48 | },
49 | regularText: {
50 | margin: theme.spacing(2),
51 | textAlign: "center",
52 | fontSize: 18,
53 | lineHeight: 1.25,
54 | },
55 | citeText: {
56 | margin: theme.spacing(2),
57 | textAlign: "center",
58 | fontSize: 12,
59 | },
60 | linkStyle: {
61 | color: "white",
62 | textDecoration: "underline",
63 | },
64 | }));
65 |
--------------------------------------------------------------------------------
/src/Components/ToolTipModal.jsx:
--------------------------------------------------------------------------------
1 | import { useState } from "react";
2 | import { Modal, Box, Button, Typography } from "@mui/material";
3 | import { trackClick } from "../trackingUtils";
4 |
5 | const boxStyle = {
6 | position: "absolute",
7 | top: "50%",
8 | left: "50%",
9 | transform: "translate(-50%, -50%)",
10 | width: "90%",
11 | maxWidth: "24em",
12 | backgroundColor: "var(--white)",
13 | border: "2px solid #000",
14 | boxShadow: 24,
15 | padding: 4,
16 | };
17 |
18 | const ToolTipModal = ({ text }) => {
19 | const [open, setOpen] = useState(false);
20 |
21 | const handleClose = () => setOpen(false);
22 | const handleOpen = () => {
23 | setOpen(true);
24 | trackClick(text);
25 | };
26 |
27 | return (
28 |
29 |
32 |
39 |
40 |
41 | If you don't know the answer, you may check your criminal record{" "}
42 |
43 | here
44 |
45 | .
46 |
47 |
48 |
49 |
50 | );
51 | };
52 |
53 | export default ToolTipModal;
54 |
--------------------------------------------------------------------------------
/src/Subpages/WhyVacate/TwoParagraphTextWithHeader.jsx:
--------------------------------------------------------------------------------
1 | import { Grid, Typography, Container, Box } from "@mui/material";
2 | import { makeStyles } from "@mui/styles";
3 |
4 | const useStyles = makeStyles(theme => ({
5 | lightBlueSectionBackground: {
6 | backgroundColor: theme.palette.primary.main,
7 | color: "white",
8 | },
9 | containerStyles: {
10 | margin: theme.spacing(2),
11 | marginTop: theme.spacing(5),
12 | marginBottom: theme.spacing(5),
13 | [theme.breakpoints.down("md")]: {
14 | padding: theme.spacing(3),
15 | },
16 | },
17 | title: {
18 | margin: theme.spacing(2),
19 | },
20 | text: {
21 | margin: theme.spacing(2),
22 | },
23 | }));
24 |
25 | export const TwoParagraphTextWithHeader = props => {
26 | const classes = useStyles();
27 | const { header, text } = props;
28 | const textItems = text.map((t, idx) => (
29 |
30 |
31 | {t}
32 |
33 |
34 | ));
35 |
36 | return (
37 |
38 |
46 |
47 |
48 |
49 | {header}
50 |
51 |
52 | {textItems}
53 |
54 |
55 |
56 | );
57 | };
58 |
--------------------------------------------------------------------------------
/src/Pages/ContactSuccessPage.jsx:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import { Container, Typography, Box, Grid } from "@mui/material";
3 | import { useContactStyles } from "../Styles/useContactStyles";
4 | import sending_emails from "../Assets/sending_emails.svg";
5 | import { useDocumentTitle } from "../Components/customHooks/useDocumentTitle";
6 | import { RedesignButtonPrimary } from "../ui-kit/RedesignButtonPrimary";
7 |
8 | const ContactSuccessPage = () => {
9 | const classes = useContactStyles();
10 | useDocumentTitle("Contact Success - ");
11 |
12 | return (
13 |
14 |
15 |
16 | Thank You!
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 | Email sent successfully.
26 |
27 |
28 | We'll be in touch soon.
29 |
30 |
31 |
32 | return to home
33 |
34 |
35 |
36 |
37 |
38 | );
39 | };
40 |
41 | export default ContactSuccessPage;
42 |
--------------------------------------------------------------------------------
/src/Assets/Onboarding/bug.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/Assets/Onboarding/group.svg:
--------------------------------------------------------------------------------
1 |
11 |
--------------------------------------------------------------------------------
/src/ui-kit/NavButtonMobile.jsx:
--------------------------------------------------------------------------------
1 | import { Typography, ListItem, Button, Collapse } from "@mui/material";
2 | import { ExpandMore } from "@mui/icons-material";
3 | import { useState } from "react";
4 |
5 | const NavButtonMobile = ({ page, classes }) => {
6 | const [expandSubMenu, setExpandSubMenu] = useState(false);
7 |
8 | const handleExpandClick = () => {
9 | setExpandSubMenu(!expandSubMenu);
10 | };
11 | return (
12 | <>
13 | {!page.subpages && (
14 |
15 |
20 |
21 | )}
22 | {page.subpages && (
23 | <>
24 |
30 | {page.name}
31 |
32 |
33 |
34 | {page.subpages.map((subpage, idx) => (
35 | // eslint-disable-next-line react/no-array-index-key
36 |
39 | ))}
40 |
41 | >
42 | )}
43 | >
44 | );
45 | };
46 |
47 | export default NavButtonMobile;
48 |
--------------------------------------------------------------------------------
/src/Components/DonateDialog.jsx:
--------------------------------------------------------------------------------
1 | import {
2 | Button,
3 | Dialog,
4 | DialogActions,
5 | DialogContent,
6 | DialogTitle,
7 | Grid,
8 | List,
9 | ListItem,
10 | Typography,
11 | } from "@mui/material";
12 | import { makeStyles } from "@mui/styles";
13 |
14 | import venmo from "../Assets/venmo.png";
15 |
16 | const useStyles = makeStyles(theme => ({
17 | closeButtonStyle: {
18 | color: theme.palette.secondary.main,
19 | margin: theme.spacing(2),
20 | },
21 | }));
22 |
23 | const DonateDialog = ({ onClose, open }) => {
24 | const classes = useStyles();
25 | return (
26 |
52 | );
53 | };
54 |
55 | export default DonateDialog;
56 |
--------------------------------------------------------------------------------
/src/Styles/useWhyVacateStyles.js:
--------------------------------------------------------------------------------
1 | import { makeStyles } from "@mui/styles";
2 |
3 | export const useWhyVacateStyles = makeStyles(theme => ({
4 | dividerStyle: {
5 | marginTop: theme.spacing(8),
6 | marginBottom: theme.spacing(8),
7 | },
8 | regularContainerStyle: {
9 | marginTop: theme.spacing(8),
10 | marginBottom: theme.spacing(8),
11 | scrollMarginTop: "4em",
12 | },
13 | headingStyle: {
14 | marginTop: theme.spacing(5),
15 | marginBottom: theme.spacing(5),
16 | },
17 | colorfulHeadingStyle: {
18 | marginTop: theme.spacing(2),
19 | marginBottom: theme.spacing(2),
20 | color: theme.palette.primary.main,
21 | },
22 | highlightHeadingStyle: {
23 | marginTop: theme.spacing(2),
24 | marginBottom: theme.spacing(2),
25 | color: theme.palette.secondary.main,
26 | },
27 | contentTextStyle: {
28 | marginTop: theme.spacing(5),
29 | marginBottom: theme.spacing(5),
30 | },
31 | listItemsStyle: {
32 | margin: theme.spacing(2),
33 | },
34 | buttonBoxStyle: {
35 | display: "flex",
36 | justifyContent: "center",
37 | margin: theme.spacing(5),
38 | },
39 | shelterIcon: {
40 | color: theme.palette.success.main,
41 | margin: theme.spacing(1),
42 | },
43 | publicHousingListStyle: {
44 | width: "100%",
45 | },
46 | titleLinkStyle: {
47 | paddingTop: theme.spacing(3),
48 | paddingBottom: theme.spacing(3),
49 | color: "white",
50 | fontWeight: "bold",
51 | textDecoration: "underline",
52 | "&:hover": {
53 | color: "white",
54 | fontWeight: "bold",
55 | textDecoration: "underline",
56 | },
57 | },
58 | reportStyle: {
59 | padding: theme.spacing(3),
60 | [theme.breakpoints.down("sm")]: {
61 | padding: theme.spacing(0),
62 | },
63 | },
64 | reportHeading: {
65 | marginBottom: theme.spacing(3),
66 | },
67 | }));
68 |
--------------------------------------------------------------------------------
/src/Components/PublicHousingList.jsx:
--------------------------------------------------------------------------------
1 | import { List, ListItem, Grid, Typography, ListItemText } from "@mui/material";
2 | import { HomeWorkOutlined, Call } from "@mui/icons-material";
3 | import { useWhyVacateStyles } from "../Styles/useWhyVacateStyles";
4 | import { ListItemLink } from "../ui-kit/ListItemLink";
5 |
6 | const PublicHousingList = ({ publicAssociations }) => {
7 | const classes = useWhyVacateStyles();
8 | return (
9 |
10 | {publicAssociations.map((association, idx) => (
11 |
12 |
13 |
14 | {association.area}
15 |
16 |
17 |
18 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | ))}
39 |
40 | );
41 | };
42 |
43 | export default PublicHousingList;
44 |
--------------------------------------------------------------------------------
/src/Components/ShelterList.jsx:
--------------------------------------------------------------------------------
1 | import { List, ListItem, Grid, Typography, ListItemIcon, ListItemText } from "@mui/material";
2 | import { HomeWorkOutlined, Call } from "@mui/icons-material";
3 | import { useWhyVacateStyles } from "../Styles/useWhyVacateStyles";
4 | import { ListItemLink } from "../ui-kit/ListItemLink";
5 |
6 | const ShelterList = ({ shelters }) => {
7 | const classes = useWhyVacateStyles();
8 | return (
9 |
10 | {shelters.map((shelter, idx) => (
11 |
12 |
13 |
14 | {shelter.name}
15 |
16 |
17 |
18 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 | ))}
39 |
40 | );
41 | };
42 |
43 | export default ShelterList;
44 |
--------------------------------------------------------------------------------
/404.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | Single Page Apps for GitHub Pages
6 |
43 |
44 |
45 |
46 |
--------------------------------------------------------------------------------
/src/Subpages/WhyVacate/HousingBarriers.jsx:
--------------------------------------------------------------------------------
1 | import { Box, Grid } from "@mui/material";
2 |
3 | import pha from "../../Assets/city.svg";
4 | import supportiveHousing from "../../Assets/diversity.svg";
5 | import privateHousing from "../../Assets/process.svg";
6 | import transitionalHousing from "../../Assets/dream.svg";
7 | import { TextWithImage } from "./TextWithImage";
8 |
9 | export const HousingBarriers = () => {
10 | return (
11 |
12 |
13 |
23 |
32 |
41 |
50 |
51 |
52 | );
53 | };
54 |
--------------------------------------------------------------------------------
/src/Styles/Onboarding/useButtonStyles.js:
--------------------------------------------------------------------------------
1 | import { makeStyles } from "@mui/styles";
2 |
3 | export const useButtonStyles = makeStyles(theme => ({
4 | button: {
5 | backgroundColor: theme.palette.primary.main,
6 | color: "white",
7 | textTransform: "capitalize",
8 | minWidth: "248px",
9 | maxWidth: "300px",
10 | height: "48px",
11 | textAlign: "center",
12 | verticalAlign: "middle",
13 | padding: "auto",
14 | boxShadow: "0 2px 4px rgba(0, 0, 0, 0.2)",
15 | borderRadius: "50px",
16 | margin: "auto",
17 | fontSize: "18px",
18 | fontWeight: "bold",
19 | lineHeight: 2.7,
20 | transition:
21 | "background-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,border 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms",
22 | "&:hover": {
23 | color: "#000",
24 | backgroundColor: "#ffd200",
25 | },
26 | [theme.breakpoints.down("md")]: {
27 | marginBottom: theme.spacing(4),
28 | },
29 | [theme.breakpoints.down("sm")]: {
30 | marginBottom: theme.spacing(2),
31 | minWidth: "175px",
32 | maxWidth: "175px",
33 | },
34 | },
35 | buttonSecondary: {
36 | backgroundColor: "white",
37 | borderWidth: 3,
38 | borderStyle: "solid",
39 | color: theme.palette.primary.main,
40 | textTransform: "capitalize",
41 | minWidth: "248px",
42 | maxWidth: "300px",
43 | height: "48px",
44 | textAlign: "center",
45 | verticalAlign: "middle",
46 | padding: "auto",
47 | boxShadow: "0 2px 4px rgba(0, 0, 0, 0.2)",
48 | borderRadius: "50px",
49 | margin: "auto",
50 | fontSize: "18px",
51 | fontWeight: "bold",
52 | lineHeight: 2.7,
53 | transition:
54 | "background-color 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,box-shadow 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms,border 250ms cubic-bezier(0.4, 0, 0.2, 1) 0ms",
55 | "&:hover": {
56 | color: "#000",
57 | backgroundColor: "#ffd200",
58 | },
59 | [theme.breakpoints.down("md")]: {
60 | marginBottom: theme.spacing(4),
61 | },
62 | },
63 | }));
64 |
--------------------------------------------------------------------------------
/src/CSS/Calculator.css:
--------------------------------------------------------------------------------
1 | .calculator {
2 | margin: 0 2rem;
3 | display: flex;
4 | flex-direction: column;
5 | align-items: center;
6 | }
7 |
8 | .calculator-body {
9 | font-family: "Lora", serif;
10 | text-align: left;
11 | display: flex;
12 | flex-direction: column;
13 | }
14 |
15 | .calcBodyText {
16 | margin-top: 20px;
17 | padding-left: 2px;
18 | }
19 |
20 | .calcHeaderText {
21 | margin-bottom: 20px;
22 | }
23 |
24 | .calculator-subheader {
25 | font-weight: bold;
26 | font-size: 1.2rem;
27 | }
28 |
29 | .calculator-numbered-item {
30 | text-indent: -1em;
31 | margin-left: 1em;
32 | }
33 |
34 | .calc-grid {
35 | display: flex;
36 | flex-direction: column;
37 | align-items: center;
38 | margin: 1rem auto 0;
39 | padding-bottom: 1vh;
40 | max-height: calc(100vh- 10em);
41 | }
42 |
43 | ul {
44 | list-style-type: disc;
45 | text-align: left;
46 | }
47 |
48 | a {
49 | text-decoration: underline;
50 | color: #000;
51 | }
52 |
53 | .calc-col.disclaimer {
54 | text-align: center;
55 | font-size: 1.46vh;
56 | padding-bottom: 15vh;
57 | margin-top: 0;
58 | }
59 |
60 | a.survey {
61 | font-size: 3.17vh;
62 | text-align: center;
63 | margin: 10vh auto 5vh;
64 | }
65 |
66 | .calc-col.disclaimer.result-no {
67 | margin-top: 10vh;
68 | }
69 |
70 | /* ! This section is for mobile */
71 | @media only screen and (max-width: 600px) {
72 | .calc-col {
73 | flex: 0;
74 | }
75 | .calc-col.results {
76 | flex: 0.25;
77 | }
78 | .calc-grid {
79 | padding: 0 3.17vh;
80 | }
81 | }
82 |
83 | /* ! This section is for desktop */
84 | @media only screen and (min-width: 601px) {
85 | .calc-grid {
86 | max-width: 552px;
87 | }
88 | .calc-col {
89 | width: 100%;
90 | max-width: 552px;
91 | display: flex;
92 | flex-wrap: wrap;
93 | flex-direction: column;
94 | }
95 |
96 | .calc-col.results {
97 | text-align: left;
98 | }
99 |
100 | .calc-col {
101 | flex: 0;
102 | }
103 | .calc-grid {
104 | margin-top: 75px;
105 | }
106 | .calc-col.body ul {
107 | margin-bottom: 0;
108 | }
109 | }
110 |
--------------------------------------------------------------------------------
/src/Styles/Onboarding/useHomeStyles.js:
--------------------------------------------------------------------------------
1 | import { makeStyles } from "@mui/styles";
2 |
3 | export const useHomeStyles = makeStyles(theme => ({
4 | body: {
5 | padding: theme.spacing(5),
6 | margin: theme.spacing(3, "auto"),
7 | width: "60%",
8 | color: "#1d1c1c",
9 | [theme.breakpoints.down("md")]: {
10 | width: "80%",
11 | padding: theme.spacing(1),
12 | },
13 | },
14 | bodyPara: {
15 | marginBottom: theme.spacing(3),
16 | [theme.breakpoints.down("sm")]: {
17 | fontSize: "18px",
18 | marginBottom: theme.spacing(2),
19 | },
20 | },
21 | cardSubheading: {
22 | marginBottom: theme.spacing(3),
23 | },
24 | cardBody: {
25 | paddingBottom: theme.spacing(5),
26 | paddingLeft: theme.spacing(5),
27 | paddingRight: theme.spacing(3),
28 | paddingTop: theme.spacing(2),
29 | color: "#2b2929",
30 | },
31 | stepper: {
32 | padding: theme.spacing(0),
33 | margin: theme.spacing(3, "auto"),
34 | width: "100%",
35 | color: "#1d1c1c",
36 | },
37 | connectorLine: {
38 | // borderLeft: "1px",
39 | borderLeftWidth: "3px",
40 | borderLeftStyle: "solid",
41 | borderLeftColor: "#4E6C99",
42 | height: "12em",
43 | marginLeft: "0.95em",
44 | marginTop: "-3px",
45 | [theme.breakpoints.down("md")]: {
46 | height: "15em",
47 | },
48 | },
49 | spacerLine: {
50 | borderLeftWidth: "1px",
51 | borderLeftStyle: "solid",
52 | borderLeftColor: "#fafafa",
53 | height: "12em",
54 | marginLeft: "1em",
55 | [theme.breakpoints.down("md")]: {
56 | height: "15em",
57 | },
58 | },
59 | openCircle: {
60 | height: "30px",
61 | width: "30px",
62 | borderRadius: "50%",
63 | borderWidth: "4px",
64 | borderColor: "#4E6C99",
65 | borderStyle: "solid",
66 | },
67 | mobileHeader: {
68 | fontSize: "28px",
69 | marginBottom: theme.spacing(3),
70 | textAlign: "center",
71 | color: "#4E6C99",
72 | [theme.breakpoints.up("sm")]: {
73 | display: "none",
74 | },
75 | },
76 | gridContainer: {
77 | maxWidth: "80%",
78 | },
79 | }));
80 |
--------------------------------------------------------------------------------
/src/Components/FactExpandMoreCard.jsx:
--------------------------------------------------------------------------------
1 | import { Card, CardActionArea, CardActions, CardContent, Collapse, Typography, Grid } from "@mui/material";
2 | import { makeStyles } from "@mui/styles";
3 | import { ExpandMore } from "@mui/icons-material";
4 | import { useState } from "react";
5 |
6 | const useStyles = makeStyles(() => ({
7 | rootStyle: {
8 | margin: 8,
9 | },
10 | contentStyle: {
11 | height: "8em",
12 | },
13 | summaryDetails: {
14 | marginTop: "1.2em",
15 | justifyContent: "space-between",
16 | },
17 | }));
18 |
19 | const FactExpandMoreCard = ({ summary, content, ariaLabel, contentID, summaryID, price, turnaround }) => {
20 | const [expanded, setExpanded] = useState(false);
21 |
22 | const handleExpandClick = () => {
23 | setExpanded(!expanded);
24 | };
25 |
26 | const classes = useStyles();
27 | return (
28 |
29 |
35 |
36 |
37 |
38 | {summary}
39 |
40 |
41 |
42 | {" "}
43 | {price} {" "}
44 |
45 |
46 | {" "}
47 | {turnaround} {" "}
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 | {content}
57 |
58 |
59 | );
60 | };
61 |
62 | export default FactExpandMoreCard;
63 |
--------------------------------------------------------------------------------
/src/Subpages/WhyVacate/GovBarriers.jsx:
--------------------------------------------------------------------------------
1 | import { Container, Typography, Box, List } from "@mui/material";
2 | import { WhyVacateHousingStyles } from "../../Styles/WhyVacateHousingStyles.ts";
3 | import ListItemMobileSnap from "../../ui-kit/ListItemMobileSnap";
4 | import snap from "../../Assets/chicken.svg";
5 | import tanf from "../../Assets/family.svg";
6 |
7 | // eslint-disable-next-line import/prefer-default-export
8 | export const GovBarriers = () => {
9 | const classes = WhyVacateHousingStyles();
10 | return (
11 |
12 |
13 |
14 | }
17 | header="Temporary Assistance for Needy Families"
18 | text={
19 |
20 | If you are a Washington state resident who is responsible for the care of a child or are
21 | pregnant, you may qualify for TANF. You cannot receive TANF if you are convicted of a
22 | felony or if you have violated your probation or parole.
23 |
24 | }
25 | />
26 | }
29 | header="Supplemental Nutrition Assistance Program"
30 | text={
31 |
32 | SNAP helps low income people by providing Electronic Benefits Card (EBT Card) to buy
33 | food on a monthly basis. You cannot receive Basic Food if you are convicted of a felony
34 | or if have violated your probation or parole.
35 |
36 | }
37 | textLeft
38 | />
39 |
40 |
41 |
42 | );
43 | };
44 |
--------------------------------------------------------------------------------
/src/Assets/Onboarding/question.svg:
--------------------------------------------------------------------------------
1 |
4 |
--------------------------------------------------------------------------------
/src/data/calculatorPagesTypes.ts:
--------------------------------------------------------------------------------
1 | type NonEmptyList = {
2 | 0: T;
3 | } & T[];
4 |
5 | interface Button {
6 | text: string;
7 | href: string;
8 | color?: string;
9 | target?: string;
10 | }
11 |
12 | export enum BodyType {
13 | PARAGRAPH = "paragraph",
14 | LINK = "link",
15 | LIST = "list",
16 | HEADING = "heading",
17 | // temporary placeholders for the Blake eligibilty -- sprint 26, 6/27/22
18 | BLAKELINK = "span",
19 | }
20 |
21 | interface BaseBody {
22 | type: BodyType;
23 | }
24 |
25 | interface ParagraphBody extends BaseBody {
26 | text: string;
27 | }
28 |
29 | interface LinkBody extends BaseBody {
30 | textBeforeLink?: string;
31 | linkText: string;
32 | textAfterLink?: string;
33 | href: string;
34 | }
35 |
36 | interface ListBody extends BaseBody {
37 | items: NonEmptyList;
38 | }
39 |
40 | export enum PageType {
41 | GUIDE = "guide",
42 | MAIN = "main",
43 | SPECIAL = "special",
44 | QUESTION = "question",
45 | END = "end",
46 | }
47 |
48 | export enum SectionName {
49 | OFF = "Your Offense",
50 | CIRC = "Surrounding Circumstances",
51 | TER = "Terms of Offense",
52 | ELIGIBLE = "",
53 | }
54 |
55 | export enum TooltipType {
56 | NOT_SURE = "I'm not sure.",
57 | NOT_A_MISDEMEANOR = "My conviction is not a misdemeanor or I'm not sure.",
58 | }
59 |
60 | interface ProgressBar {
61 | currentSectionName: SectionName;
62 | }
63 |
64 | type Body = ParagraphBody | LinkBody | ListBody;
65 | interface PageData {
66 | header?: string;
67 | body?: NonEmptyList;
68 | buttons?: NonEmptyList