Tutorial #62

Merged
LucidKobold merged 32 commits from tutorial into main 2022-06-24 15:51:02 -04:00
6 changed files with 152 additions and 25 deletions
Showing only changes of commit 099c71876b - Show all commits

View File

@@ -7,7 +7,17 @@ import findValidDateRange from "../../../lib/findValidDateRange";
import DatePicker from "./DatePicker";
import { useAppSelector } from "../../app/hooks";
const CalenderNav = (): JSX.Element => {
interface CalenderNavProps {
isLoading: boolean;
title: string;
}
/**
* @param {boolean} isLoading is the component loading?
* @param {string} title the title for the current date.
*/
const CalenderNav = ({ title, isLoading }: CalenderNavProps): JSX.Element => {
const selectedDate = useAppSelector(
(state) => state.calender.selectedDateInfo
);
@@ -46,7 +56,7 @@ const CalenderNav = (): JSX.Element => {
icon={<Icon icon="akar-icons:chevron-left" />}
onClick={() => handleNavButtons("prev")}
/>
<DatePicker />
<DatePicker isLoading={isLoading} title={title} />
<IconButton
isDisabled={isSameMonth(selectedDateObj, validEnd)}
aria-label="Next Month"

View File

@@ -14,6 +14,7 @@ import {
PopoverContent,
PopoverHeader,
PopoverTrigger,
Skeleton,
VStack
} from "@chakra-ui/react";
import {
@@ -29,11 +30,17 @@ import findValidDateRange from "../../../lib/findValidDateRange";
import FormValidateEmoji from "./FormValidateEmoji";
import { useAppSelector } from "../../app/hooks";
const DatePicker = (): JSX.Element => {
const selectedDate = useAppSelector(
(state) => state.calender.selectedDateInfo
);
interface DatePickerProps {
isLoading: boolean;
title: string;
}
/**
* @param {boolean} isLoading is the component loading?
* @param {string} title the title for the current date.
*/
const DatePicker = ({ title, isLoading }: DatePickerProps): JSX.Element => {
const router = useRouter();
const [valid, setValid] = useState<boolean>(false);
@@ -130,9 +137,17 @@ const DatePicker = (): JSX.Element => {
<Popover placement="bottom" initialFocusRef={initRef}>
<PopoverTrigger>
<Button border="none" variant="outline">
<Heading w="100%" h="auto">
{selectedDate.title}
</Heading>
{isLoading ? (
<Skeleton>
<Heading w="100%" h="auto">
{title}
</Heading>
</Skeleton>
) : (
<Heading w="100%" h="auto">
{title}
</Heading>
)}
</Button>
</PopoverTrigger>
<PopoverContent>

View File

@@ -1,4 +1,4 @@
import { Box, Text, VStack } from "@chakra-ui/react";
import { Box, Skeleton, Text, VStack } from "@chakra-ui/react";
import {
add,
getYear,
@@ -16,6 +16,7 @@ import { Provider } from "react-redux";
import { store } from "../../app/store";
interface DayProps {
isLoading: boolean;
isOverflow?: boolean;
overflowDirection?: "next" | "prev" | null;
currSticker: StickerVal;
@@ -27,6 +28,7 @@ interface DayProps {
/**
* The individual days in the calender component.
* @param {boolean} isLoading is the component loading?
* @param {boolean} isOverflow is the current date being given before or after the current month.
* @param {"next" | "prev" | null} overflowDirection the direction the overflow is. This will navigate the calender forward or backwards 1 month.
* @param {StickerVal} currSticker the sticker for this date.
@@ -36,6 +38,7 @@ interface DayProps {
* @param {boolean} isToday is the current iteration of this component in today's date.
*/
const Day = ({
isLoading,
isOverflow,
overflowDirection,
currSticker,
@@ -110,9 +113,17 @@ const Day = ({
<Text w="auto" h="auto">
{`${getDate(currDateObj)}`}
</Text>
<Box key={currSticker} fontSize="1.5rem">
<DemoStickers stickerVal={currSticker} />
</Box>
{isLoading ? (
<Skeleton key={currSticker}>
<Box fontSize="1.5rem">
<DemoStickers stickerVal={0} />
</Box>
</Skeleton>
) : (
<Box key={currSticker} fontSize="1.5rem">
<DemoStickers stickerVal={currSticker} />
</Box>
)}
</VStack>
)}
{!isOverflow && (
@@ -152,11 +163,19 @@ const Day = ({
>
{`${getDate(currDateObj)}`}
</Text>
<Box key={currSticker} fontSize="1.5rem">
<DemoStickers stickerVal={currSticker} />
</Box>
{isLoading ? (
<Skeleton key={currSticker}>
<Box fontSize="1.5rem">
<DemoStickers stickerVal={0} />
</Box>
</Skeleton>
) : (
<Box key={currSticker} fontSize="1.5rem">
<DemoStickers stickerVal={currSticker} />
</Box>
)}
<Provider store={store}>
{isBefore(currDateObj, endOfDay(currDate)) && (
{isBefore(currDateObj, endOfDay(currDate)) && !isLoading && (
<AddUpdateSticker
stickerDate={date}
isOpen={isOpen}

View File

@@ -12,7 +12,7 @@ const Calender = (newDate?: UpdateCalendarProps): JSX.Element => {
const selectedDate: SelectedDateInfo = useAppSelector(
(state) => state.calender.selectedDateInfo
);
const { layout } = selectedDate;
const { layout, title } = selectedDate;
const currDateObj = new Date(currDate);
@@ -64,7 +64,7 @@ const Calender = (newDate?: UpdateCalendarProps): JSX.Element => {
return (
<VStack h="91vh" w="100%">
<CalenderNav />
<CalenderNav title={title} isLoading={false} />
<VStack h="100%" w="100%" spacing={0}>
<HStack
px={6}
@@ -128,6 +128,7 @@ const Calender = (newDate?: UpdateCalendarProps): JSX.Element => {
return (
<Day
isLoading={false}
isOverflow={isOverflow}
overflowDirection={overflowDirection}
currSticker={sticker}

View File

@@ -0,0 +1,22 @@
import { Box, Button, Heading } from "@chakra-ui/react";
import React from "react";
interface TutorialProps {
setTutorialCookie: (bool: boolean) => void;
}
const Tutorial = ({ setTutorialCookie }: TutorialProps): JSX.Element => {
const handleSetCookieButton = (): void => {
setTutorialCookie(true);
};
return (
<Box>
<Heading>{"Tutorial Component"}</Heading>
<Button type="button" onClick={() => handleSetCookieButton()}>
{"Complete Tutorial"}
</Button>
</Box>
);
};
export default Tutorial;

View File

@@ -1,21 +1,81 @@
import React, { useRef } from "react";
import React, { Fragment, useEffect, useRef, useState } from "react";
import { Box } from "@chakra-ui/react";
import { format } from "date-fns";
import { addMonths, format } from "date-fns";
import Calender from "../components/calender";
import Tutorial from "../components/tutorial";
import LoadingOverlay from "../components/loading/LoadingOverlay";
import { Provider } from "react-redux";
import { store } from "../app/store";
import Calender from "../components/calender";
const IndexPage = (): JSX.Element => {
const date = useRef<UpdateCalendarProps>({
const calenderProps = useRef<UpdateCalendarProps>({
year: parseInt(format(new Date(), "y")),
month: parseInt(format(new Date(), "M")),
day: parseInt(format(new Date(), "d"))
});
const [completedTutorial, setCompletedTutorial] = useState<boolean | null>(
null
);
const getTutorialCookie = (): boolean => {
let flag = false;
const decodedCookie = decodeURIComponent(document.cookie);
const cookies = decodedCookie.split(";");
cookies.map((val) => {
const cookie = val.split("=");
if (cookie.length > 1) {
const cName = cookie[0].toLowerCase();
const cVal = JSON.parse(cookie[1]) || cookie[1];
if (
cName === "tutorialCompleted".toLowerCase() &&
cName &&
cVal &&
typeof cVal === "boolean"
) {
flag = cVal;
}
}
});
return flag;
};
const setTutorialCookie = (bool: boolean): void => {
const name = "tutorialCompleted";
const exp = addMonths(new Date(), 1).toUTCString();
document.cookie = `${name}=${bool};expires=${exp}'path=/`;
setCompletedTutorial(bool);
};
useEffect(() => {
setCompletedTutorial(getTutorialCookie());
}, [completedTutorial]);
return (
<Box textAlign="center" w="100%" h="auto" pt="50px" pb="10vh" minWidth="min-content">
<Box
textAlign="center"
w="100%"
h="auto"
pt="50px"
pb="10vh"
minWidth="min-content"
>
<Provider store={store}>
<Calender {...date.current} />
{completedTutorial === null ? (
<Fragment>
<LoadingOverlay />
<Calender {...calenderProps.current} />
</Fragment>
) : completedTutorial ? (
<Calender {...calenderProps.current} />
) : (
<Tutorial setTutorialCookie={setTutorialCookie} />
)}
</Provider>
</Box>
);