Skip to content

Commit

Permalink
Merge pull request #121 from bettersg/SPA-state-logic
Browse files Browse the repository at this point in the history
SPA Page Logic using useState
  • Loading branch information
neozhixuan authored Mar 30, 2023
2 parents f9f90b7 + 8779ce0 commit 2cec11c
Show file tree
Hide file tree
Showing 8 changed files with 132 additions and 51 deletions.
10 changes: 8 additions & 2 deletions client/components/footer/StickyFooter.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import { QuestionIcon } from "@chakra-ui/icons";
import { Button, Container, Flex, Link, useBreakpointValue } from "@chakra-ui/react";
import { forwardRef } from "react";
import { Pages } from "spa-pages/pageEnums";
import { COLORS } from "theme";
import { Tooltip } from "./Tooltip";

type Props = {
disabled: boolean;
setPage: (pageNumber: number) => void;
};

export const StickyFooter = forwardRef<HTMLDivElement, Props>(({ disabled }, ref) => {
export const StickyFooter = forwardRef<HTMLDivElement, Props>(({ disabled, setPage }, ref) => {
const isMobile = useBreakpointValue({ base: true, md: false });
return (
<Container
Expand All @@ -30,12 +32,15 @@ export const StickyFooter = forwardRef<HTMLDivElement, Props>(({ disabled }, ref
</Flex>
<Flex w="100%" align="center" justify="center">
<Flex gap="1.5rem">
<Button flex="1">How to recycle?</Button>
<Button flex="1" onClick={() => setPage(Pages.INSTRUCTIONS)}>
How to recycle?
</Button>
<Button
bg={COLORS.Button.primary}
color={COLORS.white}
flex="1"
disabled={disabled}
onClick={() => setPage(Pages.MAP)}
>
Where to recycle
</Button>
Expand All @@ -47,6 +52,7 @@ export const StickyFooter = forwardRef<HTMLDivElement, Props>(({ disabled }, ref
textDecor={isMobile ? "none" : "underline"}
fontSize="sm"
fontWeight="medium"
onClick={() => setPage(Pages.HOMEPICKUP)}
>
I prefer someone to collect from me
</Link>
Expand Down
69 changes: 20 additions & 49 deletions client/pages/index.tsx
Original file line number Diff line number Diff line change
@@ -1,56 +1,27 @@
import { Container, VStack } from "@chakra-ui/react";
import { StickyFooter } from "components/footer/StickyFooter";
import { Banner, UserInput } from "components/home";
import styles from "components/home/hideScrollbar.module.css";
import { NAVBAR_HEIGHT } from "components/nav/NavHeader";
import { useSheetyData } from "hooks/useRecyclableItemList";
import { useWindowDimensions } from "hooks/useWindowDimensions";
import { BasePage } from "layouts/BasePage";
import type { NextPage } from "next";
import { useEffect, useRef, useState } from "react";
import { useState } from "react";
import { HomePage, HomePickupPage, InstructionsPage, MapPage } from "spa-pages";
import { Pages } from "spa-pages/pageEnums";

const Home: NextPage = () => {
const [stickyHeight, setStickyHeight] = useState<number>(0);
const [readyToSubmit, setReadyToSubmit] = useState(false);
const { height } = useWindowDimensions();
const { isLoaded } = useSheetyData();
const [page, setPage] = useState<Pages>(Pages.HOME);

const stickyRef = useRef<HTMLDivElement>(null);
const scrollableContainerRef = useRef<HTMLObjectElement>(null);

useEffect(() => {
setStickyHeight(stickyRef.current?.clientHeight || 0);
}, [stickyRef.current?.clientHeight, height]);

return (
<BasePage title="Home" description="Singapore's first recycling planner">
<VStack p={0} m={0} height={`${height - NAVBAR_HEIGHT}px`}>
<Container
className={styles.hideScrollbar}
maxW={{
base: "full",
sm: "container.md",
}}
p={0}
pb={5}
overflow="auto"
height={height - stickyHeight - NAVBAR_HEIGHT}
ref={scrollableContainerRef}
>
<VStack align="initial" mx={25} spacing={30}>
<Banner />
{isLoaded && (
<UserInput
scrollableContainerRef={scrollableContainerRef}
setReadyToSubmit={setReadyToSubmit}
/>
)}
</VStack>
</Container>
<StickyFooter ref={stickyRef} disabled={!readyToSubmit} />
</VStack>
</BasePage>
);
let PageComponent: JSX.Element;
switch (page) {
case Pages.HOME:
PageComponent = <HomePage setPage={setPage} />;
break;
case Pages.HOMEPICKUP:
PageComponent = <HomePickupPage />;
break;
case Pages.INSTRUCTIONS:
PageComponent = <InstructionsPage />;
break;
case Pages.MAP:
PageComponent = <MapPage />;
break;
}
return PageComponent;
};

export default Home;
58 changes: 58 additions & 0 deletions client/spa-pages/components/HomePage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import { Container, VStack } from "@chakra-ui/react";
import { StickyFooter } from "components/footer/StickyFooter";
import { Banner, UserInput } from "components/home";
import styles from "components/home/hideScrollbar.module.css";
import { NAVBAR_HEIGHT } from "components/nav/NavHeader";
import { useSheetyData } from "hooks/useRecyclableItemList";
import { useWindowDimensions } from "hooks/useWindowDimensions";
import { BasePage } from "layouts/BasePage";
import { Dispatch, SetStateAction, useEffect, useRef, useState } from "react";
import { Pages } from "spa-pages/pageEnums";

type Props = {
setPage: Dispatch<SetStateAction<Pages>>;
};
export const HomePage = ({ setPage }: Props) => {
const [stickyHeight, setStickyHeight] = useState<number>(0);
const [readyToSubmit, setReadyToSubmit] = useState(false);

const { height } = useWindowDimensions();
const { isLoaded } = useSheetyData();

const stickyRef = useRef<HTMLDivElement>(null);
const scrollableContainerRef = useRef<HTMLObjectElement>(null);

useEffect(() => {
setStickyHeight(stickyRef.current?.clientHeight || 0);
}, [stickyRef.current?.clientHeight, height]);

return (
<BasePage title="Home" description="Singapore's first recycling planner">
<VStack p={0} m={0} height={`${height - NAVBAR_HEIGHT}px`}>
<Container
className={styles.hideScrollbar}
maxW={{
base: "full",
sm: "container.md",
}}
p={0}
pb={5}
overflow="auto"
height={height - stickyHeight - NAVBAR_HEIGHT}
ref={scrollableContainerRef}
>
<VStack align="initial" mx={25} spacing={30}>
<Banner />
{isLoaded && (
<UserInput
scrollableContainerRef={scrollableContainerRef}
setReadyToSubmit={setReadyToSubmit}
/>
)}
</VStack>
</Container>
<StickyFooter ref={stickyRef} disabled={!readyToSubmit} setPage={setPage} />
</VStack>
</BasePage>
);
};
12 changes: 12 additions & 0 deletions client/spa-pages/components/HomePickupPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Flex, Text } from "@chakra-ui/react";
import { BasePage } from "layouts/BasePage";

export const HomePickupPage = () => {
return (
<BasePage title="Home Pickup" description="Singapore's first recycling planner">
<Flex direction="column" align="center" my={23}>
<Text>Home Pickup Page</Text>
</Flex>
</BasePage>
);
};
12 changes: 12 additions & 0 deletions client/spa-pages/components/InstructionsPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Flex, Text } from "@chakra-ui/react";
import { BasePage } from "layouts/BasePage";

export const InstructionsPage = () => {
return (
<BasePage title="Instructions" description="Singapore's first recycling planner">
<Flex direction="column" align="center" my={23}>
<Text>Instructions</Text>
</Flex>
</BasePage>
);
};
12 changes: 12 additions & 0 deletions client/spa-pages/components/MapPage.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { Flex, Text } from "@chakra-ui/react";
import { BasePage } from "layouts/BasePage";

export const MapPage = () => {
return (
<BasePage title="Map" description="Singapore's first recycling planner">
<Flex direction="column" align="center" my={23}>
<Text>Map Page</Text>
</Flex>
</BasePage>
);
};
4 changes: 4 additions & 0 deletions client/spa-pages/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
export * from "./components/HomePage";
export * from "./components/HomePickupPage";
export * from "./components/InstructionsPage";
export * from "./components/MapPage";
6 changes: 6 additions & 0 deletions client/spa-pages/pageEnums.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export enum Pages {
HOME,
HOMEPICKUP,
INSTRUCTIONS,
MAP,
}

0 comments on commit 2cec11c

Please sign in to comment.