@@ -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:
|
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
|
### Upgrading Packages
|
||||||
|
|||||||
@@ -1,42 +1,12 @@
|
|||||||
import React from "react";
|
import React, { useContext } from "react";
|
||||||
import { Box, HStack, SimpleGrid, Text, VStack } from "@chakra-ui/react";
|
import { Box, HStack, SimpleGrid, Text, VStack } from "@chakra-ui/react";
|
||||||
import { endOfMonth, getDate } from "date-fns";
|
|
||||||
import CalenderNav from "./CalenderNav";
|
import CalenderNav from "./CalenderNav";
|
||||||
|
import { CalenderContext } from "../../contexts/CalenderContext";
|
||||||
|
|
||||||
const Calender = (): JSX.Element => {
|
const Calender = (): JSX.Element => {
|
||||||
const today = new Date();
|
const { daysOfMonth, daysOfWeek } = useContext(CalenderContext);
|
||||||
|
|
||||||
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",
|
|
||||||
],
|
|
||||||
};
|
|
||||||
|
|
||||||
|
// Simulated user settings context
|
||||||
const userSettings = {
|
const userSettings = {
|
||||||
theme: "default",
|
theme: "default",
|
||||||
startOfWeek: "Sunday",
|
startOfWeek: "Sunday",
|
||||||
@@ -54,7 +24,7 @@ const Calender = (): JSX.Element => {
|
|||||||
alignContent="center"
|
alignContent="center"
|
||||||
alignItems="center"
|
alignItems="center"
|
||||||
>
|
>
|
||||||
{daysOfWeek[userSettings.startOfWeek].map((weekDay) => {
|
{daysOfWeek.startOfWeek[userSettings.startOfWeek].map((weekDay) => {
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
d="flex"
|
d="flex"
|
||||||
|
|||||||
@@ -1,25 +1,34 @@
|
|||||||
import React from "react";
|
import React, { useContext } from "react";
|
||||||
import { Heading, HStack, IconButton } from "@chakra-ui/react";
|
import { Heading, HStack, IconButton } from "@chakra-ui/react";
|
||||||
import { Icon } from "@iconify/react";
|
import { Icon } from "@iconify/react";
|
||||||
import { format } from "date-fns";
|
import { format } from "date-fns";
|
||||||
|
import { CalenderContext } from "../../contexts/CalenderContext";
|
||||||
|
|
||||||
const CalenderNav = (): JSX.Element => {
|
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 (
|
return (
|
||||||
<HStack spacing={10} as="nav" w="auto" h="10vh" textAlign="center">
|
<HStack spacing={10} as="nav" w="auto" h="10vh" textAlign="center">
|
||||||
<IconButton
|
<IconButton
|
||||||
aria-label="Previous Month"
|
aria-label="Previous Month"
|
||||||
icon={<Icon icon="akar-icons:chevron-left" />}
|
icon={<Icon icon="akar-icons:chevron-left" />}
|
||||||
|
onClick={() => prevMonth()}
|
||||||
/>
|
/>
|
||||||
<Heading w="100%" h="auto">
|
<Heading
|
||||||
|
w="100%"
|
||||||
|
h="auto"
|
||||||
|
_hover={{
|
||||||
|
cursor: "default",
|
||||||
|
}}
|
||||||
|
>
|
||||||
{currentMonth}
|
{currentMonth}
|
||||||
</Heading>
|
</Heading>
|
||||||
<IconButton
|
<IconButton
|
||||||
aria-label="Next Month"
|
aria-label="Next Month"
|
||||||
icon={<Icon icon="akar-icons:chevron-right" />}
|
icon={<Icon icon="akar-icons:chevron-right" />}
|
||||||
|
onClick={() => nextMonth()}
|
||||||
/>
|
/>
|
||||||
</HStack>
|
</HStack>
|
||||||
);
|
);
|
||||||
|
|||||||
144
contexts/CalenderContext.tsx
Normal file
144
contexts/CalenderContext.tsx
Normal 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 };
|
||||||
@@ -17,10 +17,10 @@
|
|||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@chakra-ui/react": "^1.7.2",
|
"@chakra-ui/react": "^1.7.2",
|
||||||
"@emotion/react": "^11.6.0",
|
"@emotion/react": "^11.7.0",
|
||||||
"@emotion/styled": "^11.6.0",
|
"@emotion/styled": "^11.6.0",
|
||||||
"@types/react": "^17.0.37",
|
"@types/react": "^17.0.37",
|
||||||
"date-fns": "^2.26.0",
|
"date-fns": "^2.27.0",
|
||||||
"framer-motion": "^5.3.3",
|
"framer-motion": "^5.3.3",
|
||||||
"next": "12.0.4",
|
"next": "12.0.4",
|
||||||
"react": "17.0.2",
|
"react": "17.0.2",
|
||||||
|
|||||||
@@ -1,11 +1,14 @@
|
|||||||
import React from "react";
|
import React from "react";
|
||||||
import { Box } from "@chakra-ui/react";
|
import { Box } from "@chakra-ui/react";
|
||||||
import Calender from "../components/calender/Calender";
|
import Calender from "../components/calender/Calender";
|
||||||
|
import { CalenderContextProvider } from "../contexts/CalenderContext";
|
||||||
|
|
||||||
const IndexPage = (): JSX.Element => {
|
const IndexPage = (): JSX.Element => {
|
||||||
return (
|
return (
|
||||||
<Box textAlign="center" w="100%" h="auto" pt="50px" pb="10vh">
|
<Box textAlign="center" w="100%" h="auto" pt="50px" pb="10vh">
|
||||||
|
<CalenderContextProvider>
|
||||||
<Calender />
|
<Calender />
|
||||||
|
</CalenderContextProvider>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -74,10 +74,7 @@ const Footer = (): JSX.Element => {
|
|||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noopener"
|
rel="noopener"
|
||||||
>
|
>
|
||||||
<Button
|
<Button color="whiteAlpha" variant="credits">
|
||||||
color="whiteAlpha"
|
|
||||||
variant="credits"
|
|
||||||
>
|
|
||||||
More About This App
|
More About This App
|
||||||
</Button>
|
</Button>
|
||||||
</Link>
|
</Link>
|
||||||
@@ -101,8 +98,7 @@ const Footer = (): JSX.Element => {
|
|||||||
<Text color="brand.footerText" fontSize="xs">
|
<Text color="brand.footerText" fontSize="xs">
|
||||||
©
|
©
|
||||||
{" 2021 - "}
|
{" 2021 - "}
|
||||||
{new Date().getFullYear()}
|
{new Date().getFullYear()}{" "}
|
||||||
{" "}
|
|
||||||
<Link
|
<Link
|
||||||
href="https://lucidcreations.media"
|
href="https://lucidcreations.media"
|
||||||
rel="noopener"
|
rel="noopener"
|
||||||
|
|||||||
@@ -4,19 +4,16 @@ import {
|
|||||||
HStack,
|
HStack,
|
||||||
Box,
|
Box,
|
||||||
IconButton,
|
IconButton,
|
||||||
Flex,
|
|
||||||
Menu,
|
Menu,
|
||||||
MenuButton,
|
MenuButton,
|
||||||
VStack,
|
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import { Icon } from "@iconify/react";
|
import { Icon } from "@iconify/react";
|
||||||
import DesktopNav from "./DesktopNav";
|
import DesktopNav from "./DesktopNav";
|
||||||
import MobileNav from "./MobileNav";
|
import MobileNav from "./MobileNav";
|
||||||
|
|
||||||
const Header = (): JSX.Element => {
|
const Header = (): JSX.Element => {
|
||||||
const appName = "LCM Potty Chart"
|
const appName = "LCM Potty Chart";
|
||||||
const appVersion = "v0.0.2.5-pre-alpha"
|
const appVersion = "v0.0.3.0-pre-alpha";
|
||||||
|
|
||||||
|
|
||||||
// Add transparency while not at the top of the page.
|
// Add transparency while not at the top of the page.
|
||||||
const [transparentNavbar, setTransparentNavbar] = useState<boolean>(false);
|
const [transparentNavbar, setTransparentNavbar] = useState<boolean>(false);
|
||||||
@@ -109,6 +106,9 @@ const Header = (): JSX.Element => {
|
|||||||
ml={4}
|
ml={4}
|
||||||
d={{ base: "flex", lg: "none" }}
|
d={{ base: "flex", lg: "none" }}
|
||||||
spacing="5px"
|
spacing="5px"
|
||||||
|
_hover={{
|
||||||
|
cursor: "default",
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Heading as="h1" size="md">
|
<Heading as="h1" size="md">
|
||||||
{appName}
|
{appName}
|
||||||
@@ -119,7 +119,13 @@ const Header = (): JSX.Element => {
|
|||||||
</HStack>
|
</HStack>
|
||||||
|
|
||||||
{/* Desktop Nav Items and Mobile Menu Button */}
|
{/* 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
|
<HStack
|
||||||
w="100%"
|
w="100%"
|
||||||
h="auto"
|
h="auto"
|
||||||
@@ -133,6 +139,9 @@ const Header = (): JSX.Element => {
|
|||||||
alignItems="center"
|
alignItems="center"
|
||||||
height="auto"
|
height="auto"
|
||||||
spacing="5px"
|
spacing="5px"
|
||||||
|
_hover={{
|
||||||
|
cursor: "default",
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Heading as="h1" size="md">
|
<Heading as="h1" size="md">
|
||||||
{appName}
|
{appName}
|
||||||
@@ -154,9 +163,7 @@ const Header = (): JSX.Element => {
|
|||||||
onMouseLeave={() => setHover(false)}
|
onMouseLeave={() => setHover(false)}
|
||||||
d={{ base: "inline-flex", lg: "none" }}
|
d={{ base: "inline-flex", lg: "none" }}
|
||||||
variant="mobileNav"
|
variant="mobileNav"
|
||||||
bg={
|
bg={transparentNavbar ? "transparent" : "rgba(255, 255, 255, .15)"}
|
||||||
transparentNavbar ? "transparent" : "rgba(255, 255, 255, .15)"
|
|
||||||
}
|
|
||||||
type="button"
|
type="button"
|
||||||
border={transparentNavbar ? "1px solid #0068ff" : "none"}
|
border={transparentNavbar ? "1px solid #0068ff" : "none"}
|
||||||
id="mobile-menu-button"
|
id="mobile-menu-button"
|
||||||
|
|||||||
20
yarn.lock
20
yarn.lock
@@ -1031,9 +1031,9 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"@emotion/react@npm:^11.6.0":
|
"@emotion/react@npm:^11.7.0":
|
||||||
version: 11.6.0
|
version: 11.7.0
|
||||||
resolution: "@emotion/react@npm:11.6.0"
|
resolution: "@emotion/react@npm:11.7.0"
|
||||||
dependencies:
|
dependencies:
|
||||||
"@babel/runtime": ^7.13.10
|
"@babel/runtime": ^7.13.10
|
||||||
"@emotion/cache": ^11.6.0
|
"@emotion/cache": ^11.6.0
|
||||||
@@ -1050,7 +1050,7 @@ __metadata:
|
|||||||
optional: true
|
optional: true
|
||||||
"@types/react":
|
"@types/react":
|
||||||
optional: true
|
optional: true
|
||||||
checksum: 4fb2d108dc32716d1f162026ac5fdbd0662e3b435a34fb324629d72bb6bff61b18ac8975b51457c16ffa41543bade5d07558566ab76420b3926fbb9159441232
|
checksum: 8b50d61caabe04ae413ae23b98c170da643754ec89f25eb001464095685686585d0f88988bc36432f231e6de6abdbee73308c42ba427de9eaaf5a54d7f2f6ae5
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -2637,10 +2637,10 @@ __metadata:
|
|||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
"date-fns@npm:^2.26.0":
|
"date-fns@npm:^2.27.0":
|
||||||
version: 2.26.0
|
version: 2.27.0
|
||||||
resolution: "date-fns@npm:2.26.0"
|
resolution: "date-fns@npm:2.27.0"
|
||||||
checksum: 49ad59bc788134a6552ef4e4af0d18792001c1ca0070d543de4f36aba5761058b6e6a57b8ca51dd3b0f07f3bd55376b8bc69602bd7940648ba3869c5253c6ae8
|
checksum: db62036b3816eb0322c9532b353beac7f660a91e1a55dbd21c14893c621ebb8509f21c66ba287844dabd34dee0207edd54a9537bce6bb7cab9383dedc6b8bc90
|
||||||
languageName: node
|
languageName: node
|
||||||
linkType: hard
|
linkType: hard
|
||||||
|
|
||||||
@@ -4402,12 +4402,12 @@ __metadata:
|
|||||||
resolution: "lucid-creations-media-potty-chart@workspace:."
|
resolution: "lucid-creations-media-potty-chart@workspace:."
|
||||||
dependencies:
|
dependencies:
|
||||||
"@chakra-ui/react": ^1.7.2
|
"@chakra-ui/react": ^1.7.2
|
||||||
"@emotion/react": ^11.6.0
|
"@emotion/react": ^11.7.0
|
||||||
"@emotion/styled": ^11.6.0
|
"@emotion/styled": ^11.6.0
|
||||||
"@iconify/react": ^3.1.0
|
"@iconify/react": ^3.1.0
|
||||||
"@types/react": ^17.0.37
|
"@types/react": ^17.0.37
|
||||||
"@typescript-eslint/eslint-plugin": ^5.4.0
|
"@typescript-eslint/eslint-plugin": ^5.4.0
|
||||||
date-fns: ^2.26.0
|
date-fns: ^2.27.0
|
||||||
eslint: <8.0.0
|
eslint: <8.0.0
|
||||||
eslint-config-next: 12.0.3
|
eslint-config-next: 12.0.3
|
||||||
eslint-config-prettier: ^8.3.0
|
eslint-config-prettier: ^8.3.0
|
||||||
|
|||||||
Reference in New Issue
Block a user