Getting and setting completed tutorial cookie. Working on properly setting and updating a loading state.
This commit is contained in:
@@ -7,7 +7,17 @@ import findValidDateRange from "../../../lib/findValidDateRange";
|
|||||||
import DatePicker from "./DatePicker";
|
import DatePicker from "./DatePicker";
|
||||||
import { useAppSelector } from "../../app/hooks";
|
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(
|
const selectedDate = useAppSelector(
|
||||||
(state) => state.calender.selectedDateInfo
|
(state) => state.calender.selectedDateInfo
|
||||||
);
|
);
|
||||||
@@ -46,7 +56,7 @@ const CalenderNav = (): JSX.Element => {
|
|||||||
icon={<Icon icon="akar-icons:chevron-left" />}
|
icon={<Icon icon="akar-icons:chevron-left" />}
|
||||||
onClick={() => handleNavButtons("prev")}
|
onClick={() => handleNavButtons("prev")}
|
||||||
/>
|
/>
|
||||||
<DatePicker />
|
<DatePicker isLoading={isLoading} title={title} />
|
||||||
<IconButton
|
<IconButton
|
||||||
isDisabled={isSameMonth(selectedDateObj, validEnd)}
|
isDisabled={isSameMonth(selectedDateObj, validEnd)}
|
||||||
aria-label="Next Month"
|
aria-label="Next Month"
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import {
|
|||||||
PopoverContent,
|
PopoverContent,
|
||||||
PopoverHeader,
|
PopoverHeader,
|
||||||
PopoverTrigger,
|
PopoverTrigger,
|
||||||
|
Skeleton,
|
||||||
VStack
|
VStack
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import {
|
import {
|
||||||
@@ -29,11 +30,17 @@ import findValidDateRange from "../../../lib/findValidDateRange";
|
|||||||
import FormValidateEmoji from "./FormValidateEmoji";
|
import FormValidateEmoji from "./FormValidateEmoji";
|
||||||
import { useAppSelector } from "../../app/hooks";
|
import { useAppSelector } from "../../app/hooks";
|
||||||
|
|
||||||
const DatePicker = (): JSX.Element => {
|
interface DatePickerProps {
|
||||||
const selectedDate = useAppSelector(
|
isLoading: boolean;
|
||||||
(state) => state.calender.selectedDateInfo
|
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 router = useRouter();
|
||||||
|
|
||||||
const [valid, setValid] = useState<boolean>(false);
|
const [valid, setValid] = useState<boolean>(false);
|
||||||
@@ -130,9 +137,17 @@ const DatePicker = (): JSX.Element => {
|
|||||||
<Popover placement="bottom" initialFocusRef={initRef}>
|
<Popover placement="bottom" initialFocusRef={initRef}>
|
||||||
<PopoverTrigger>
|
<PopoverTrigger>
|
||||||
<Button border="none" variant="outline">
|
<Button border="none" variant="outline">
|
||||||
|
{isLoading ? (
|
||||||
|
<Skeleton>
|
||||||
<Heading w="100%" h="auto">
|
<Heading w="100%" h="auto">
|
||||||
{selectedDate.title}
|
{title}
|
||||||
</Heading>
|
</Heading>
|
||||||
|
</Skeleton>
|
||||||
|
) : (
|
||||||
|
<Heading w="100%" h="auto">
|
||||||
|
{title}
|
||||||
|
</Heading>
|
||||||
|
)}
|
||||||
</Button>
|
</Button>
|
||||||
</PopoverTrigger>
|
</PopoverTrigger>
|
||||||
<PopoverContent>
|
<PopoverContent>
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import { Box, Text, VStack } from "@chakra-ui/react";
|
import { Box, Skeleton, Text, VStack } from "@chakra-ui/react";
|
||||||
import {
|
import {
|
||||||
add,
|
add,
|
||||||
getYear,
|
getYear,
|
||||||
@@ -16,6 +16,7 @@ import { Provider } from "react-redux";
|
|||||||
import { store } from "../../app/store";
|
import { store } from "../../app/store";
|
||||||
|
|
||||||
interface DayProps {
|
interface DayProps {
|
||||||
|
isLoading: boolean;
|
||||||
isOverflow?: boolean;
|
isOverflow?: boolean;
|
||||||
overflowDirection?: "next" | "prev" | null;
|
overflowDirection?: "next" | "prev" | null;
|
||||||
currSticker: StickerVal;
|
currSticker: StickerVal;
|
||||||
@@ -27,6 +28,7 @@ interface DayProps {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* The individual days in the calender component.
|
* 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 {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 {"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.
|
* @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.
|
* @param {boolean} isToday is the current iteration of this component in today's date.
|
||||||
*/
|
*/
|
||||||
const Day = ({
|
const Day = ({
|
||||||
|
isLoading,
|
||||||
isOverflow,
|
isOverflow,
|
||||||
overflowDirection,
|
overflowDirection,
|
||||||
currSticker,
|
currSticker,
|
||||||
@@ -110,9 +113,17 @@ const Day = ({
|
|||||||
<Text w="auto" h="auto">
|
<Text w="auto" h="auto">
|
||||||
{`${getDate(currDateObj)}`}
|
{`${getDate(currDateObj)}`}
|
||||||
</Text>
|
</Text>
|
||||||
|
{isLoading ? (
|
||||||
|
<Skeleton key={currSticker}>
|
||||||
|
<Box fontSize="1.5rem">
|
||||||
|
<DemoStickers stickerVal={0} />
|
||||||
|
</Box>
|
||||||
|
</Skeleton>
|
||||||
|
) : (
|
||||||
<Box key={currSticker} fontSize="1.5rem">
|
<Box key={currSticker} fontSize="1.5rem">
|
||||||
<DemoStickers stickerVal={currSticker} />
|
<DemoStickers stickerVal={currSticker} />
|
||||||
</Box>
|
</Box>
|
||||||
|
)}
|
||||||
</VStack>
|
</VStack>
|
||||||
)}
|
)}
|
||||||
{!isOverflow && (
|
{!isOverflow && (
|
||||||
@@ -152,11 +163,19 @@ const Day = ({
|
|||||||
>
|
>
|
||||||
{`${getDate(currDateObj)}`}
|
{`${getDate(currDateObj)}`}
|
||||||
</Text>
|
</Text>
|
||||||
|
{isLoading ? (
|
||||||
|
<Skeleton key={currSticker}>
|
||||||
|
<Box fontSize="1.5rem">
|
||||||
|
<DemoStickers stickerVal={0} />
|
||||||
|
</Box>
|
||||||
|
</Skeleton>
|
||||||
|
) : (
|
||||||
<Box key={currSticker} fontSize="1.5rem">
|
<Box key={currSticker} fontSize="1.5rem">
|
||||||
<DemoStickers stickerVal={currSticker} />
|
<DemoStickers stickerVal={currSticker} />
|
||||||
</Box>
|
</Box>
|
||||||
|
)}
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
{isBefore(currDateObj, endOfDay(currDate)) && (
|
{isBefore(currDateObj, endOfDay(currDate)) && !isLoading && (
|
||||||
<AddUpdateSticker
|
<AddUpdateSticker
|
||||||
stickerDate={date}
|
stickerDate={date}
|
||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ const Calender = (newDate?: UpdateCalendarProps): JSX.Element => {
|
|||||||
const selectedDate: SelectedDateInfo = useAppSelector(
|
const selectedDate: SelectedDateInfo = useAppSelector(
|
||||||
(state) => state.calender.selectedDateInfo
|
(state) => state.calender.selectedDateInfo
|
||||||
);
|
);
|
||||||
const { layout } = selectedDate;
|
const { layout, title } = selectedDate;
|
||||||
|
|
||||||
const currDateObj = new Date(currDate);
|
const currDateObj = new Date(currDate);
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ const Calender = (newDate?: UpdateCalendarProps): JSX.Element => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<VStack h="91vh" w="100%">
|
<VStack h="91vh" w="100%">
|
||||||
<CalenderNav />
|
<CalenderNav title={title} isLoading={false} />
|
||||||
<VStack h="100%" w="100%" spacing={0}>
|
<VStack h="100%" w="100%" spacing={0}>
|
||||||
<HStack
|
<HStack
|
||||||
px={6}
|
px={6}
|
||||||
@@ -128,6 +128,7 @@ const Calender = (newDate?: UpdateCalendarProps): JSX.Element => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Day
|
<Day
|
||||||
|
isLoading={false}
|
||||||
isOverflow={isOverflow}
|
isOverflow={isOverflow}
|
||||||
overflowDirection={overflowDirection}
|
overflowDirection={overflowDirection}
|
||||||
currSticker={sticker}
|
currSticker={sticker}
|
||||||
|
|||||||
22
src/components/tutorial/index.tsx
Normal file
22
src/components/tutorial/index.tsx
Normal 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;
|
||||||
@@ -1,21 +1,81 @@
|
|||||||
import React, { useRef } from "react";
|
import React, { Fragment, useEffect, useRef, useState } from "react";
|
||||||
import { Box } from "@chakra-ui/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 { Provider } from "react-redux";
|
||||||
import { store } from "../app/store";
|
import { store } from "../app/store";
|
||||||
import Calender from "../components/calender";
|
|
||||||
|
|
||||||
const IndexPage = (): JSX.Element => {
|
const IndexPage = (): JSX.Element => {
|
||||||
const date = useRef<UpdateCalendarProps>({
|
const calenderProps = useRef<UpdateCalendarProps>({
|
||||||
year: parseInt(format(new Date(), "y")),
|
year: parseInt(format(new Date(), "y")),
|
||||||
month: parseInt(format(new Date(), "M")),
|
month: parseInt(format(new Date(), "M")),
|
||||||
day: parseInt(format(new Date(), "d"))
|
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 (
|
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}>
|
<Provider store={store}>
|
||||||
<Calender {...date.current} />
|
{completedTutorial === null ? (
|
||||||
|
<Fragment>
|
||||||
|
<LoadingOverlay />
|
||||||
|
<Calender {...calenderProps.current} />
|
||||||
|
</Fragment>
|
||||||
|
) : completedTutorial ? (
|
||||||
|
<Calender {...calenderProps.current} />
|
||||||
|
) : (
|
||||||
|
<Tutorial setTutorialCookie={setTutorialCookie} />
|
||||||
|
)}
|
||||||
</Provider>
|
</Provider>
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user