diff --git a/src/__tests__/contexts/rewards-context.spec.tsx b/src/__tests__/contexts/rewards-context.spec.tsx new file mode 100644 index 0000000..1add78e --- /dev/null +++ b/src/__tests__/contexts/rewards-context.spec.tsx @@ -0,0 +1,25 @@ +import { RewardsContext, RewardsContextProvider } from '@/contexts/rewards-context'; +import '@testing-library/jest-dom'; +import { cleanup, render, screen } from '@testing-library/react'; +import { useContext } from 'react'; + +function MockChildComponent() { + const {rewards} = useContext(RewardsContext); + return ( +
{rewards.length > 0 ? rewards[0].name : "your friend"}
+ ); +} + +describe('RewardsContextProvider', () => { + afterEach(cleanup); + + it('defaults to an rewardsInfo value of an empty array.', () => { + render( + + + + ); + const noRewards = screen.queryByTestId('test'); + expect(noRewards).toHaveTextContent('your friend'); + }); +}); \ No newline at end of file diff --git a/src/__tests__/pages/challenger-welcome/__snapshots__/challenger-welcome.snapshot.tsx.snap b/src/__tests__/pages/challenger-welcome/__snapshots__/challenger-welcome.snapshot.tsx.snap new file mode 100644 index 0000000..0896d3f --- /dev/null +++ b/src/__tests__/pages/challenger-welcome/__snapshots__/challenger-welcome.snapshot.tsx.snap @@ -0,0 +1,198 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`ChallengerWelcome renders challenger-welcome page unchanged 1`] = ` +
+
+
+
+ background +
+ +
+
+
+

+ Welcome! +

+

+ Closing the voter registration gap has to be a community effort, so we're asking everyone to join us in taking the #8by8Challenge—register 8 friends to register to vote in 8 days! +

+ + + + See why others are doing it + +
+
+

+ Here's How it Works +

+

+ 1. Sign Up +

+

+ Sign up with your name and email address to get started. +

+ sign up +

+ 2. Invite your friends +

+

+ Get 8 friends via social media or messaging apps to join your challenge. +

+ invite your friends +

+ 3. Friends take action +

+

+ Your friends can support your challenge by taking 1 of 3 actions: register to vote, set up election reminders, or take the challenge themselves. You'll earn 1 badge per friend who takes action! +

+ friends take action +

+ 4. Win the challenge, get a reward! +

+

+ When you get 8 badges in 8 days, you win the challenge! Most importantly, you helped the community move closer to greater AAPI representation! +

+ earn 8 badges in 8 days + + +
+
+
+
+`; diff --git a/src/__tests__/pages/challenger-welcome/challenger-welcome.snapshot.tsx b/src/__tests__/pages/challenger-welcome/challenger-welcome.snapshot.tsx new file mode 100644 index 0000000..197099e --- /dev/null +++ b/src/__tests__/pages/challenger-welcome/challenger-welcome.snapshot.tsx @@ -0,0 +1,17 @@ +import ChallengerWelcome from '@/pages/challenger-welcome'; +import { cleanup, render } from '@testing-library/react'; + +import { useRouter } from 'next/router'; + +jest.mock('next/router', () => ({ + useRouter: jest.fn() +})) + +describe('ChallengerWelcome', () => { + afterEach(cleanup); + + it('renders challenger-welcome page unchanged', () => { + const { container } = render(); + expect(container).toMatchSnapshot(); + }); +}); \ No newline at end of file diff --git a/src/__tests__/pages/challenger-welcome/challenger-welcome.spec.tsx b/src/__tests__/pages/challenger-welcome/challenger-welcome.spec.tsx new file mode 100644 index 0000000..4f6cb0f --- /dev/null +++ b/src/__tests__/pages/challenger-welcome/challenger-welcome.spec.tsx @@ -0,0 +1,71 @@ +import { RewardsContext, RewardsContextType } from '@/contexts/rewards-context'; +import { RewardInfo } from "@/models/RewardInfo"; +import ChallengerWelcome from '@/pages/challenger-welcome'; +import '@testing-library/jest-dom'; +import { cleanup, render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import { Builder } from 'builder-pattern'; +import mockRouter from 'next-router-mock'; +import { useRouter } from 'next/router'; + +jest.mock('next/router', () => require('next-router-mock')); + +describe('ChallengerWelcome', () => { + afterEach(cleanup); + it('opens the signup page when the first button is clicked', async () => { + mockRouter.push("/initial-path"); + const user = userEvent.setup(); + + render ( + + ); + + const fgetStartedbtn = screen.getAllByRole('button')[0]; + await user.click(fgetStartedbtn); + expect(mockRouter).toMatchObject({asPath: "/signup"}); + }); + + it('opens the signup page when the second button is clicked', async () => { + mockRouter.push("/initial-path"); + const user = userEvent.setup(); + + render ( + + ); + + const sgetStartedbtn = screen.getAllByRole('button')[1]; + await user.click(sgetStartedbtn); + expect(mockRouter).toMatchObject({asPath: "/signup"}); + }); + + it("Displays different text for step four if there are rewards available", async () => { + const rewardsArray: Array = [{ + businessDescription:"At Chefus, everything we do is to bring a chef-made meal with fresh ingredients to your table at an incredible price.", + businessLink:"https://www.chefus.com/", + businessType:"Online deliveries", + locationDescription:"Online", + locationType:"Online", + logo:"/assets/partner-logos/chefus.png", + name:"Chefus", + redemptionDescription:"Use code CHEFUS8BY8 at checkout.", + rewardAvailable:true, + rewardConditions:"CHEFUS8BY8", + rewardDescription:"Get $10 off on orders of $20+.", + rewardEndDate: new Date("2050-09-01"), + rewardLink:"https://www.chefus.com/", + rewardStartDate:new Date("2022-08-01"), + rewardType:"Online", + }]; + const rewardsCtxValue = Builder().rewards(rewardsArray).build(); + + render( + + + + ); + + const stepFourInstruction = screen.queryByText("When all 8 of your friends took action in your challenge within 8 days, and you win! Then select and enjoy a reward from one of our amazing partners."); + expect(stepFourInstruction).toBeInTheDocument(); + }); + + }); \ No newline at end of file diff --git a/src/contexts/rewards-context.tsx b/src/contexts/rewards-context.tsx new file mode 100644 index 0000000..1c59905 --- /dev/null +++ b/src/contexts/rewards-context.tsx @@ -0,0 +1,14 @@ +import { RewardInfo } from "@/models/RewardInfo"; +import { createContext, PropsWithChildren, useState } from "react"; + +export type RewardsContextType = { + rewards: Array; +} + +export const RewardsContext = createContext({rewards: []}); + +export function RewardsContextProvider({children}:PropsWithChildren) { + const [rewardsArray,setRewardsArray] = useState>([]); + + return {children} +} \ No newline at end of file diff --git a/src/models/RewardInfo.ts b/src/models/RewardInfo.ts new file mode 100644 index 0000000..c8498b9 --- /dev/null +++ b/src/models/RewardInfo.ts @@ -0,0 +1,17 @@ +export interface RewardInfo { + businessDescription:string; + businessLink:string; + businessType:string; + locationDescription:"Online" | "In Person"; + locationType:"Online" | "In Person"; + logo:string; + name:string; + redemptionDescription:string; + rewardAvailable:boolean; + rewardConditions:string; + rewardDescription:string; + rewardEndDate:Date | undefined; + rewardLink:string; + rewardStartDate:Date; + rewardType:"Online" | "In Person"; + } \ No newline at end of file diff --git a/src/pages/challenger-welcome.tsx b/src/pages/challenger-welcome.tsx new file mode 100644 index 0000000..3b1db1e --- /dev/null +++ b/src/pages/challenger-welcome.tsx @@ -0,0 +1,118 @@ +import PageContainer from "@/components/utils/page-container"; +import { RewardsContext } from "@/contexts/rewards-context"; +import { UserContext } from "@/contexts/user-context"; +import Image from "next/image"; +import Link from "next/link"; +import { useRouter } from 'next/router'; +import { useContext, useState } from "react"; +import StepFour from "../../public/assets/images/ChallengerWelcome/StepFour.png"; +import StepOne from "../../public/assets/images/ChallengerWelcome/StepOne.png"; +import StepThree from "../../public/assets/images/ChallengerWelcome/StepThree.png"; +import StepTwo from "../../public/assets/images/ChallengerWelcome/StepTwo.png"; +import Top from "../../public/assets/images/ChallengerWelcome/Top.png"; +import Logo from "../../public/assets/logos/white-logo.svg"; +import styles from "../styles/modules/pages/challengerwelcome.module.scss"; + +function ChallengerWelcome() { + const router = useRouter(); + sessionStorage.setItem("UserType", "Challenger"); + + const { activeUser } = useContext(UserContext); + const { rewards } = useContext(RewardsContext); + const [rewardsAvailable, setRewardsAvailable] = useState(rewards.some(r => r.rewardAvailable)); + + return ( + +
+ background + +
+ 8by8 Logo +
+
+ +
+

Welcome!

+ +

+ Closing the voter registration gap has to be a community effort, so + we're asking everyone to join us in taking the + #8by8Challenge—register 8 friends to register to vote in 8 days! +

+ + + + {!activeUser && ( +

+ Already have an account?{" "} + + Sign in + +

+ )} + + + See why others are doing it + +
+ +
+

Here's How it Works

+ +

1. Sign Up

+

+ Sign up with your name and email address to get started. +

+ sign up + +

2. Invite your friends

+

+ Get 8 friends via social media or messaging apps to join your + challenge. +

+ invite your friends + +

3. Friends take action

+

+ Your friends can support your challenge by taking 1 of 3 actions: + register to vote, set up election reminders, or take the challenge + themselves. You'll earn 1 badge per friend who takes action! +

+ friends take action + +

4. Win the challenge, get a reward!

+

+ {rewardsAvailable ? + "When all 8 of your friends took action in your challenge within 8 days, and you win! Then select and enjoy a reward from one of our amazing partners." : + "When you get 8 badges in 8 days, you win the challenge! Most importantly, you helped the community move closer to greater AAPI representation!"} +

+ earn 8 badges in 8 days + + + + {!activeUser && ( +

+ Already have an account?{" "} + + Sign in + +

+ )} +
+
+ ); +} + +export default ChallengerWelcome; diff --git a/src/styles/modules/pages/challengerwelcome.module.scss b/src/styles/modules/pages/challengerwelcome.module.scss new file mode 100644 index 0000000..021639b --- /dev/null +++ b/src/styles/modules/pages/challengerwelcome.module.scss @@ -0,0 +1,94 @@ +@use "../../partials"; + +.get_started_btn { + @extend .btn_gradient; + @extend .btn_lg; + width: 70%; + margin: 30px 0px; +} + +.signin_line { + @extend .b6; + letter-spacing: 0.28px; + margin-bottom: 24px; + a { + padding-left: 2px; + @extend .link; + } +} + +.section_1 { + display: flex; + justify-content: center; + align-items: center; + flex-direction: column; + + .background { + width: 100%; + height: 300px; + } + + .container { + height: 0; + width: 100%; + display: flex; + align-items: center; + justify-content: center; + + .logo { + position: relative; + bottom: 170px; + } + } +} + +.section_2 { + padding: 35px 30px 0px; + text-align: center; + + .content { + margin-top: 20px; + text-align: left; + @extend .b2; + } + + .teal_link { + @extend .link; + @extend .b5; + width: -moz-fit-content; + width: fit-content; + letter-spacing: 0.28px; + } +} + +.content_3 { + background-color: partials.$color-white; + color: partials.$color-black-text; + display: flex; + flex-direction: column; + align-items: center; + text-align: left; + padding: 50px 30px; + + + h2 { + margin-bottom: 24px; + line-height: normal; + letter-spacing: 1.08px; + } + + .step_header { + align-self: flex-start; + line-height: normal; + letter-spacing: 0.72px; + } + + .step_text { + @extend .b2; + letter-spacing: 0.36px; + } + + .image { + margin: 20px 0px; + } +}