diff --git a/components/calender/Day.tsx b/components/calender/Day.tsx index 8a71e32..ca19e4f 100644 --- a/components/calender/Day.tsx +++ b/components/calender/Day.tsx @@ -12,7 +12,7 @@ import { import router from "next/router"; import React, { Fragment, useState } from "react"; import { StickersContextProvider } from "../../contexts/StickerContext"; -import AddSticker from "./modals/AddSticker"; +import AddUpdateSticker from "./modals/AddUpdateSticker"; import DemoStickers from "./stickers/DemoStickers"; interface DayProps { @@ -58,11 +58,19 @@ const Day = ({ } }; - // This handles the modal for this date. + // This handles the modal for the day. const [isOpen, setIsOpen] = useState(false); + // The current sticker to be displayed on the current date. + // * This is temporary. There should be no need for this once persistent storage is used. This is being used as a workaround to a bug. const [stickerState, setStickerState] = useState(sticker); + // The step the modal is at. + const [step, setStep] = useState(0); + + // The current selected sticker. (To be added or updated) + const [selectedSticker, setSelectedSticker] = useState(null); + /** * TODO: Add logic to remove the onClick within overflow dates. * Do not give dates for the next month an onClick. @@ -114,7 +122,11 @@ const Day = ({ border="1px solid #0068ff" w="100%" h="100%" - onClick={() => setIsOpen(true)} + onClick={() => { + setStep(0); + setSelectedSticker(null); + setIsOpen(true); + }} alignContent="center" justifyContent="flex-start" pt={2} @@ -151,11 +163,16 @@ const Day = ({ {isBefore(date, endOfDay(new Date())) && ( - )} diff --git a/components/calender/modals/AddSticker.tsx b/components/calender/modals/AddSticker.tsx deleted file mode 100644 index b835278..0000000 --- a/components/calender/modals/AddSticker.tsx +++ /dev/null @@ -1,145 +0,0 @@ -import { - Button, - Modal, - ModalOverlay, - ModalContent, - ModalHeader, - ModalCloseButton, - ModalBody, - ModalFooter, - Heading, - HStack, - VStack -} from "@chakra-ui/react"; -import React, { Fragment, useState, useContext } from "react"; -import { format } from "date-fns"; -import DemoStickers from "../stickers/DemoStickers"; -import { StickersContext } from "../../../contexts/StickerContext"; - -interface AddStickerProps { - isOpen: boolean; - updateIsOpen: React.Dispatch>; - date: Date; - updateSticker: React.Dispatch>; -} - -/** - * Handles adding and modifying the stickers for the given month. - * @param props the props for this component. - * @param {boolean} props.isOpen tells the component when the modal should be open. - * @param {React.Dispatch>} props.updateIsOpen used to close the modal. - * @param {date} props.date the date for which the sticker will be added or modified. - * @param {React.Dispatch>} updateSticker the react state function to update the sticker. - */ -const AddSticker = ({ - isOpen, - updateIsOpen, - date, - updateSticker -}: AddStickerProps): JSX.Element => { - // TODO: Import the stickers array from the calender context. - - // TODO: Add a function that will add or update the sticker for the current date. - - /** - * TODO: Add logic into the contents of the modal to show messages if the selected date is out of range. - * Show a message when a date in the future is selected. - * Show a message when a date before the current date is selected. - */ - - const [selectedSticker, setSelectedSticker] = useState(null); - - const { addEditSticker } = useContext(StickersContext); - - const handleClose = () => { - setSelectedSticker(null); - updateIsOpen(false); - }; - - const handleSubmit = (sticker) => { - const newSticker: Sticker = addEditSticker(date, sticker); - updateSticker(newSticker.sticker); - handleClose(); - }; - - // TODO: Invalidate submit button if the selected sticker is the same as the current sticker. - - // TODO: Display the current sticker above the selection screen if a current sticker exists. - - // TODO: Invalidate the button for the current sticker and gray it out. - - // TODO: Trigger a warning if the date is in the past showing the sticker change. - // ! DO NOT update the sticker state or trigger the edd/edit function until that new warning is accepted. - - return ( - - handleClose()} - motionPreset="slideInBottom" - scrollBehavior="inside" - size="lg" - > - - - - - {`Which sticker did you earn for ${format(date, "LLL d, y")}?`} - - - - - - - - - - - - - - - {/* */} - - - - - ); -}; - -export default AddSticker; diff --git a/components/calender/modals/AddUpdateSticker.tsx b/components/calender/modals/AddUpdateSticker.tsx new file mode 100644 index 0000000..5691816 --- /dev/null +++ b/components/calender/modals/AddUpdateSticker.tsx @@ -0,0 +1,245 @@ +import { + Button, + Modal, + ModalOverlay, + ModalContent, + ModalHeader, + ModalBody, + ModalFooter, + Heading, + HStack, + Text, + VStack, + SimpleGrid, + Box +} from "@chakra-ui/react"; +import React, { useState, useContext } from "react"; +import { format, isSameDay } from "date-fns"; +import { Icon } from "@iconify/react"; +import { StickersContext } from "../../../contexts/StickerContext"; +import StickerSelector from "./StickerSelector"; +import DemoStickers from "../stickers/DemoStickers"; + +interface AddStickerProps { + isOpen: boolean; + updateIsOpen: React.Dispatch>; + date: Date; + updateSticker: React.Dispatch>; + currSticker: StickerVal; + step: number; + updateStep: React.Dispatch>; + selectedSticker: StickerVal; + updateSelectedSticker: React.Dispatch>; +} + +/** + * Handles adding and modifying the stickers for the given month. + * @param {boolean} isOpen Tells the component when the modal should be open. + * @param {React.Dispatch>} updateIsOpen Used to close the modal. + * @param {date} date The date for which the sticker will be added or modified. + * @param {React.Dispatch>} updateSticker The react state function to update the sticker. + * @param {StickerVal} currSticker The current sticker for the date. + * @param {number} step A numerical variable that represents the page the modal should be at. + * @param {React.Dispatch>} updateStep Used to navigate the pages of the modal by updating the step the modal is on. + * @param {React.Dispatch>} updateSticker The react state function to update the selected sticker that will be added or updated. + */ +const AddUpdateSticker = ({ + isOpen, + updateIsOpen, + date, + updateSticker, + currSticker, + step, + updateStep, + selectedSticker, + updateSelectedSticker +}: AddStickerProps): JSX.Element => { + // TODO: Import the stickers array from the calender context. + + const { addEditSticker } = useContext(StickersContext); + + const [modalVariant] = useState<"currDate" | "notCurrDate">( + isSameDay(date, new Date()) ? "currDate" : "notCurrDate" + ); + + const handleClose = () => { + updateIsOpen(false); + }; + + // TODO: Validate that the provided sticker is not the current sticker. Throw an error if the same sticker is attempted. + const handleSubmit = (sticker) => { + const newSticker: Sticker = addEditSticker(date, sticker); + updateSticker(newSticker.sticker); + handleClose(); + }; + + // * Double check that the submit button is disabled if the selected sticker is the same as the current sticker. + + const variants = { + currDate: [ + { + header: `Which sticker did you earn for ${format(date, "LLL d, y")}?`, + body: ( + + ), + footer: ( + + ) + } + ], + notCurrDate: [ + { + header: `Which sticker did you want to update for ${format( + date, + "LLL d, y" + )}?`, + body: ( + + + {"Current Sticker"} + + + + + + {"Select your new sticker"} + + + + ), + footer: ( + + ) + }, + { + header: `Are you sure you want to change the sticker for ${format( + date, + "M/d/y" + )}?`, + body: ( + + + {"Previous Sticker"} + + + + {"New Sticker"} + + + + + + + + + + + + ), + footer: ( + + + + + + + + ) + } + ] + }; + + return ( + handleClose()} + motionPreset="slideInBottom" + scrollBehavior="inside" + size={modalVariant === "currDate" ? "xl" : "2xl"} + > + + + + + + {modalVariant && variants[modalVariant][step].header} + + + + + + {modalVariant && variants[modalVariant][step].body} + + + {modalVariant && variants[modalVariant][step].footer} + + + + ); +}; + +export default AddUpdateSticker; diff --git a/components/calender/modals/StickerSelector.tsx b/components/calender/modals/StickerSelector.tsx new file mode 100644 index 0000000..200f9b0 --- /dev/null +++ b/components/calender/modals/StickerSelector.tsx @@ -0,0 +1,69 @@ +import { HStack, Button } from "@chakra-ui/react"; +import React from "react"; +import DemoStickers from "../stickers/DemoStickers"; + +interface StickerSelectorProps { + stickerSet: "Demo"; + currSticker: StickerVal; + selectedSticker: StickerVal; + updateSelectedSticker: React.Dispatch>; +} + +/** + * Handles displaying a list of dynamic stickers to be selected. + * @param {string} stickerSet The name of the stickers that should be displayed. + * @param {StickerVal} currSticker The current sticker for the date. + * @param {StickerVal} selectedSticker The selected sticker for the current. date + * @param {React.Dispatch>} updateSelectedSticker TThe react state function to update the selected sticker that will be added or updated. + */ + +const StickerSelector = ({ + stickerSet, + currSticker, + selectedSticker, + updateSelectedSticker +}: StickerSelectorProps): JSX.Element => { + const stickers = { + Demo: ( + + + + + + ) + }; + + return stickers[stickerSet]; +}; + +export default StickerSelector; diff --git a/package.json b/package.json index 54a757d..3766517 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "private": true, "name": "lucid-creations-media-potty-chart", "homepage": "https://lucidcreations.media/introducing-code-name-potty-chart/", - "version": "v0.0.8.1-alpha", + "version": "v0.0.9.0-alpha", "author": { "name": "Lucid Creations Media", "url": "https://lucidcreations.media", @@ -25,8 +25,8 @@ "formik": "^2.2.9", "framer-motion": "^6.2.8", "next": "12.1.4", - "react": "18.0.0", - "react-dom": "18.0.0", + "react": "<=17.0.2", + "react-dom": "<=17.0.2", "sharp": "^0.30.3" }, "devDependencies": { diff --git a/pages/calendar/index.tsx b/pages/calendar/index.tsx index 7db5a70..ad0dc52 100644 --- a/pages/calendar/index.tsx +++ b/pages/calendar/index.tsx @@ -2,7 +2,7 @@ import React, { useEffect } from "react"; import { useRouter } from "next/router"; import { Box, Heading } from "@chakra-ui/react"; -const DateRoute = () => { +const DateIndex = () => { const router = useRouter(); useEffect(() => { @@ -20,4 +20,4 @@ const DateRoute = () => { ); }; -export default DateRoute; +export default DateIndex; diff --git a/theme/layout/Header.tsx b/theme/layout/Header.tsx index dfe3787..c280d51 100644 --- a/theme/layout/Header.tsx +++ b/theme/layout/Header.tsx @@ -15,7 +15,7 @@ import appLogo from "../../public/images/logo.svg"; const Header = (): JSX.Element => { const appName = "LCM Potty Chart"; - const appVersion = "v0.0.8.1-alpha"; + const appVersion = "v0.0.9.0-alpha"; // Add transparency while not at the top of the page. const [transparentNavbar, setTransparentNavbar] = useState(false); diff --git a/yarn.lock b/yarn.lock index c4d8fdd..dfffb45 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3644,8 +3644,8 @@ __metadata: framer-motion: ^6.2.8 next: 12.1.4 prettier: ^2.6.1 - react: 18.0.0 - react-dom: 18.0.0 + react: <=17.0.2 + react-dom: <=17.0.2 sharp: ^0.30.3 typescript: <4.6.0 languageName: unknown @@ -4365,15 +4365,16 @@ __metadata: languageName: node linkType: hard -"react-dom@npm:18.0.0": - version: 18.0.0 - resolution: "react-dom@npm:18.0.0" +"react-dom@npm:<=17.0.2": + version: 17.0.2 + resolution: "react-dom@npm:17.0.2" dependencies: loose-envify: ^1.1.0 - scheduler: ^0.21.0 + object-assign: ^4.1.1 + scheduler: ^0.20.2 peerDependencies: - react: ^18.0.0 - checksum: dd0ba9f2f31dd728076c892a95b2f5a8dfe79136431b0289afb46eec39d0ca6b6f0f40a60fd8aa6ef702c98ce7c26100d3d4dbc35c7c9e87429cd04f84cb58bd + react: 17.0.2 + checksum: 1c1eaa3bca7c7228d24b70932e3d7c99e70d1d04e13bb0843bbf321582bc25d7961d6b8a6978a58a598af2af496d1cedcfb1bf65f6b0960a0a8161cb8dab743c languageName: node linkType: hard @@ -4466,12 +4467,13 @@ __metadata: languageName: node linkType: hard -"react@npm:18.0.0": - version: 18.0.0 - resolution: "react@npm:18.0.0" +"react@npm:<=17.0.2": + version: 17.0.2 + resolution: "react@npm:17.0.2" dependencies: loose-envify: ^1.1.0 - checksum: 293020b96536b3c7113ee57ca5c990a3f25649d1751b1c7a3aabd16dff0691fe9f1eed1206616d0906d05933536052037340a0c8d0941ff870b0eb469a2f975b + object-assign: ^4.1.1 + checksum: b254cc17ce3011788330f7bbf383ab653c6848902d7936a87b09d835d091e3f295f7e9dd1597c6daac5dc80f90e778c8230218ba8ad599f74adcc11e33b9d61b languageName: node linkType: hard @@ -4653,12 +4655,13 @@ __metadata: languageName: node linkType: hard -"scheduler@npm:^0.21.0": - version: 0.21.0 - resolution: "scheduler@npm:0.21.0" +"scheduler@npm:^0.20.2": + version: 0.20.2 + resolution: "scheduler@npm:0.20.2" dependencies: loose-envify: ^1.1.0 - checksum: 4f8285076041ed2c81acdd1faa987f1655fdbd30554bc667c1ea64743fc74fb3a04ca7d27454b3d678735df5a230137a3b84756061b43dc5796e80701b66d124 + object-assign: ^4.1.1 + checksum: c4b35cf967c8f0d3e65753252d0f260271f81a81e427241295c5a7b783abf4ea9e905f22f815ab66676f5313be0a25f47be582254db8f9241b259213e999b8fc languageName: node linkType: hard