Merge pull request #13 from LucidKobold/context

Calender Navigation
This commit is contained in:
Lucid Kobold
2021-12-01 14:34:58 -06:00
committed by GitHub
9 changed files with 200 additions and 71 deletions

View File

@@ -65,7 +65,7 @@ I cannot guarantee functionality or stability if used on other OSs Ubuntu versio
After cloning the app you will need to install the dependencies and packages. The app uses Yarn v2. Run this command to install using Yarn v2:
```
Yarn install
yarn install
```
### Upgrading Packages

View File

@@ -1,42 +1,12 @@
import React from "react";
import React, { useContext } from "react";
import { Box, HStack, SimpleGrid, Text, VStack } from "@chakra-ui/react";
import { endOfMonth, getDate } from "date-fns";
import CalenderNav from "./CalenderNav";
import { CalenderContext } from "../../contexts/CalenderContext";
const Calender = (): JSX.Element => {
const today = new Date();
const endOfCurrMonth = endOfMonth(today);
const lastDay = getDate(endOfCurrMonth);
// console.info(`This month has ${lastDay} days.`);
const daysOfMonth = [];
for (let i = daysOfMonth.length; i < lastDay; i++) {
daysOfMonth.push(daysOfMonth.length + 1);
}
const daysOfWeek = {
Sunday: [
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
],
Monday: [
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday",
],
};
const { daysOfMonth, daysOfWeek } = useContext(CalenderContext);
// Simulated user settings context
const userSettings = {
theme: "default",
startOfWeek: "Sunday",
@@ -54,7 +24,7 @@ const Calender = (): JSX.Element => {
alignContent="center"
alignItems="center"
>
{daysOfWeek[userSettings.startOfWeek].map((weekDay) => {
{daysOfWeek.startOfWeek[userSettings.startOfWeek].map((weekDay) => {
return (
<Box
d="flex"

View File

@@ -1,25 +1,34 @@
import React from "react";
import React, { useContext } from "react";
import { Heading, HStack, IconButton } from "@chakra-ui/react";
import { Icon } from "@iconify/react";
import { format } from "date-fns";
import { CalenderContext } from "../../contexts/CalenderContext";
const CalenderNav = (): JSX.Element => {
const today = new Date();
const { selectedMonth, prevMonth, nextMonth } = useContext(CalenderContext);
const currentMonth = format(today, "LLLL uuuu");
const currentMonth = format(selectedMonth, "LLLL uuuu");
return (
<HStack spacing={10} as="nav" w="auto" h="10vh" textAlign="center">
<IconButton
aria-label="Previous Month"
icon={<Icon icon="akar-icons:chevron-left" />}
onClick={() => prevMonth()}
/>
<Heading w="100%" h="auto">
<Heading
w="100%"
h="auto"
_hover={{
cursor: "default",
}}
>
{currentMonth}
</Heading>
<IconButton
aria-label="Next Month"
icon={<Icon icon="akar-icons:chevron-right" />}
onClick={() => nextMonth()}
/>
</HStack>
);

View File

@@ -0,0 +1,144 @@
import React, { createContext, useState, ReactNode, useEffect } from "react";
import { endOfMonth, getDate, sub, add } from "date-fns";
// TODO: import types
type days =
| "Sunday"
| "Monday"
| "Tuesday"
| "Wednesday"
| "Thursday"
| "Friday"
| "Saturday";
interface DaysOfWeek {
startOfWeek: {
Sunday: days[];
Monday: days[];
};
}
interface CalenderContextState {
selectedMonth: Date;
daysOfMonth: [number];
daysOfWeek: DaysOfWeek;
prevMonth: () => void;
nextMonth: () => void;
}
const CalenderContext = createContext({} as CalenderContextState);
const CalenderContextProvider = ({
children,
}: {
children: ReactNode;
}): JSX.Element => {
// Today's date
const [today] = useState<Date>(new Date());
// Selected month & year
const [selectedMonth, setSelectedMonth] = useState<Date>(today);
const [endOfSelectedMonth, SetEndOfSelectedDMonth] = useState<number>(
getDate(endOfMonth(selectedMonth))
);
const [daysOfMonth, setDaysOfMonth] = useState<[number]>([0]);
// Update or populate the days of the month.
const populateDays = (): void => {
let newDaysOfMonth: [number] = [...daysOfMonth];
if (newDaysOfMonth.length > 1) {
newDaysOfMonth = [0];
}
for (let i = 1; i < endOfSelectedMonth; i++) {
if (newDaysOfMonth[i - 1] === 0) {
newDaysOfMonth[i - 1] = i;
} else {
newDaysOfMonth.push(i + 1);
}
}
setDaysOfMonth(newDaysOfMonth);
};
// Update selected month sates when the selected month is updated.
// Update days of month.
useEffect(() => {
if (daysOfMonth === null) {
populateDays();
} else {
if (daysOfMonth[daysOfMonth.length - 1] !== endOfSelectedMonth) {
populateDays();
}
}
}, [selectedMonth, endOfSelectedMonth]);
// Update end of month.
useEffect(() => {
if (endOfSelectedMonth !== getDate(endOfMonth(selectedMonth))) {
SetEndOfSelectedDMonth(getDate(endOfMonth(selectedMonth)));
}
}, [selectedMonth]);
// Calender Layout
const daysOfWeek: DaysOfWeek = {
startOfWeek: {
Sunday: [
"Sunday",
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
],
Monday: [
"Monday",
"Tuesday",
"Wednesday",
"Thursday",
"Friday",
"Saturday",
"Sunday",
],
},
};
//TODO: Create an object of arrays that will align with the days on the week. Make two sets for each start of the week setting.
// Navigation
const prevMonth = (): void => {
const newMonth = sub(selectedMonth, {
months: 1,
});
setSelectedMonth(newMonth);
};
const nextMonth = (): void => {
const newMonth = add(selectedMonth, {
months: 1,
});
setSelectedMonth(newMonth);
};
const calenderContextValues = {
selectedMonth,
daysOfMonth,
daysOfWeek,
prevMonth,
nextMonth,
};
return (
<CalenderContext.Provider value={calenderContextValues}>
{children}
</CalenderContext.Provider>
);
};
export { CalenderContextProvider, CalenderContext };

View File

@@ -17,10 +17,10 @@
},
"dependencies": {
"@chakra-ui/react": "^1.7.2",
"@emotion/react": "^11.6.0",
"@emotion/react": "^11.7.0",
"@emotion/styled": "^11.6.0",
"@types/react": "^17.0.37",
"date-fns": "^2.26.0",
"date-fns": "^2.27.0",
"framer-motion": "^5.3.3",
"next": "12.0.4",
"react": "17.0.2",

View File

@@ -1,11 +1,14 @@
import React from "react";
import { Box } from "@chakra-ui/react";
import Calender from "../components/calender/Calender";
import { CalenderContextProvider } from "../contexts/CalenderContext";
const IndexPage = (): JSX.Element => {
return (
<Box textAlign="center" w="100%" h="auto" pt="50px" pb="10vh">
<CalenderContextProvider>
<Calender />
</CalenderContextProvider>
</Box>
);
};

View File

@@ -74,10 +74,7 @@ const Footer = (): JSX.Element => {
target="_blank"
rel="noopener"
>
<Button
color="whiteAlpha"
variant="credits"
>
<Button color="whiteAlpha" variant="credits">
More About This App
</Button>
</Link>
@@ -101,8 +98,7 @@ const Footer = (): JSX.Element => {
<Text color="brand.footerText" fontSize="xs">
&copy;
{" 2021 - "}
{new Date().getFullYear()}
{" "}
{new Date().getFullYear()}{" "}
<Link
href="https://lucidcreations.media"
rel="noopener"

View File

@@ -4,19 +4,16 @@ import {
HStack,
Box,
IconButton,
Flex,
Menu,
MenuButton,
VStack,
} from "@chakra-ui/react";
import { Icon } from "@iconify/react";
import DesktopNav from "./DesktopNav";
import MobileNav from "./MobileNav";
const Header = (): JSX.Element => {
const appName = "LCM Potty Chart"
const appVersion = "v0.0.2.5-pre-alpha"
const appName = "LCM Potty Chart";
const appVersion = "v0.0.3.0-pre-alpha";
// Add transparency while not at the top of the page.
const [transparentNavbar, setTransparentNavbar] = useState<boolean>(false);
@@ -109,6 +106,9 @@ const Header = (): JSX.Element => {
ml={4}
d={{ base: "flex", lg: "none" }}
spacing="5px"
_hover={{
cursor: "default",
}}
>
<Heading as="h1" size="md">
{appName}
@@ -119,7 +119,13 @@ const Header = (): JSX.Element => {
</HStack>
{/* Desktop Nav Items and Mobile Menu Button */}
<HStack w="100%" px={4} h={12} alignItems="center" justifyContent="space-between" >
<HStack
w="100%"
px={4}
h={12}
alignItems="center"
justifyContent="space-between"
>
<HStack
w="100%"
h="auto"
@@ -133,6 +139,9 @@ const Header = (): JSX.Element => {
alignItems="center"
height="auto"
spacing="5px"
_hover={{
cursor: "default",
}}
>
<Heading as="h1" size="md">
{appName}
@@ -154,9 +163,7 @@ const Header = (): JSX.Element => {
onMouseLeave={() => setHover(false)}
d={{ base: "inline-flex", lg: "none" }}
variant="mobileNav"
bg={
transparentNavbar ? "transparent" : "rgba(255, 255, 255, .15)"
}
bg={transparentNavbar ? "transparent" : "rgba(255, 255, 255, .15)"}
type="button"
border={transparentNavbar ? "1px solid #0068ff" : "none"}
id="mobile-menu-button"

View File

@@ -1031,9 +1031,9 @@ __metadata:
languageName: node
linkType: hard
"@emotion/react@npm:^11.6.0":
version: 11.6.0
resolution: "@emotion/react@npm:11.6.0"
"@emotion/react@npm:^11.7.0":
version: 11.7.0
resolution: "@emotion/react@npm:11.7.0"
dependencies:
"@babel/runtime": ^7.13.10
"@emotion/cache": ^11.6.0
@@ -1050,7 +1050,7 @@ __metadata:
optional: true
"@types/react":
optional: true
checksum: 4fb2d108dc32716d1f162026ac5fdbd0662e3b435a34fb324629d72bb6bff61b18ac8975b51457c16ffa41543bade5d07558566ab76420b3926fbb9159441232
checksum: 8b50d61caabe04ae413ae23b98c170da643754ec89f25eb001464095685686585d0f88988bc36432f231e6de6abdbee73308c42ba427de9eaaf5a54d7f2f6ae5
languageName: node
linkType: hard
@@ -2637,10 +2637,10 @@ __metadata:
languageName: node
linkType: hard
"date-fns@npm:^2.26.0":
version: 2.26.0
resolution: "date-fns@npm:2.26.0"
checksum: 49ad59bc788134a6552ef4e4af0d18792001c1ca0070d543de4f36aba5761058b6e6a57b8ca51dd3b0f07f3bd55376b8bc69602bd7940648ba3869c5253c6ae8
"date-fns@npm:^2.27.0":
version: 2.27.0
resolution: "date-fns@npm:2.27.0"
checksum: db62036b3816eb0322c9532b353beac7f660a91e1a55dbd21c14893c621ebb8509f21c66ba287844dabd34dee0207edd54a9537bce6bb7cab9383dedc6b8bc90
languageName: node
linkType: hard
@@ -4402,12 +4402,12 @@ __metadata:
resolution: "lucid-creations-media-potty-chart@workspace:."
dependencies:
"@chakra-ui/react": ^1.7.2
"@emotion/react": ^11.6.0
"@emotion/react": ^11.7.0
"@emotion/styled": ^11.6.0
"@iconify/react": ^3.1.0
"@types/react": ^17.0.37
"@typescript-eslint/eslint-plugin": ^5.4.0
date-fns: ^2.26.0
date-fns: ^2.27.0
eslint: <8.0.0
eslint-config-next: 12.0.3
eslint-config-prettier: ^8.3.0