Broke up the tutorial component into smaller components.

This commit is contained in:
Lucid Kobold
2022-06-23 15:02:44 -05:00
parent f808f6b250
commit a6e6e11ca3
12 changed files with 393 additions and 320 deletions

View File

@@ -16,10 +16,6 @@ const CalenderExample = ({
}: CalenderExampleProps): JSX.Element => {
// TODO: Check if the current date is the start of the user's preferred start of the week and use the previous week for the edit example.
// TODO: Add highlight to the current date for the add example and highlight other dates when the edit example is used.
// TODO: Disable the days that shouldn't have a function to prevent edits on add example and add to current date on the edit example.
const currDateStr: string = useAppSelector(
(state) => state.calender.currDate
);

View File

@@ -0,0 +1,10 @@
type AboutApp = string[];
const aboutApp: AboutApp = [
"An app that mimics a potty/star chart for a potty training toddler or child.",
"It can be used to track behavior, habits, diaper training, potty training (good luck), daily chores/tasks, or anything else you might want to track in a fun and visual way.",
"The final app will have settings to disable any mention of ABDL to allow a more general audience to use, such as for a master and pet relationship.",
"This is an alpha build of the app. Some functionality may not work as intended, is fully functional, and may be missing entirely."
];
export default aboutApp;

View File

@@ -0,0 +1,9 @@
type AppFunctionality = string[];
const appFunctionality: AppFunctionality = [
"The app will generate stickers to display from the 1st of the month to the day before today. This is to simulate previous and continued use.",
"Ability to add a sticker to the current date.",
"Ability to add edit a sticker from a previous date with a confirmation prompt."
];
export default appFunctionality;

View File

@@ -0,0 +1,28 @@
export interface LinkObj {
href?: string;
name?: string;
type: "primary" | "secondary" | "twitter" | "patreon";
}
type Links = LinkObj[];
const links: Links = [
{
href: "https://docs.google.com/document/d/1hrerGKHTO3iach8A-CabtfIB4lyZWlgO8EGTyOCrI2Y",
name: "Roadmap and Progress",
type: "secondary"
},
{
href: "https://lucidcreations.media/introducing-code-name-potty-chart/",
name: "Original Announcement",
type: "secondary"
},
{
type: "patreon"
},
{
type: "twitter"
}
];
export default links;

View File

@@ -1,312 +1,40 @@
import React from "react";
import { useAppDispatch, useAppSelector } from "../../app/hooks";
import { toggleRememberCompleted } from "../../features/tutorial";
import {
Box,
Button,
Checkbox,
Divider,
Heading,
HStack,
Text,
VStack
} from "@chakra-ui/react";
import CustomButton from "../buttons/Custom";
import Patreon from "../buttons/Patreon";
import Twitter from "../buttons/Twitter";
import CalenderExample from "./CalenderExample";
import { VStack } from "@chakra-ui/react";
import TutorialCalender from "./sections/TutorialCalender";
import TutorialLinks from "./sections/TutorialLinks";
import TutorialHeading from "./sections/TutorialHeading";
import TutorialAboutApp from "./sections/TutorialAboutApp";
import TutorialSubmitButtons from "./sections/TutorialSubmitButtons";
import TutorialAppFunctionality from "./sections/TutorialAppFunctionality";
interface TutorialProps {
setTutorialComplete: () => void;
setTempTutorialComplete: () => void;
isLoading: boolean;
}
const Tutorial = ({
setTutorialComplete,
setTempTutorialComplete,
isLoading
}: TutorialProps): JSX.Element => {
const rememberComplete = useAppSelector(
(state) => state.tutorial.rememberCompleted
);
const dispatch = useAppDispatch();
const handleComplete = (): void => {
if (rememberComplete) {
setTutorialComplete();
}
if (!rememberComplete) {
setTempTutorialComplete();
}
};
const handleSkip = (): void => {
setTempTutorialComplete();
};
const handleUpdateCheck = (): void => {
dispatch(toggleRememberCompleted());
};
const Tutorial = ({ isLoading }: TutorialProps): JSX.Element => {
// TODO: Add an expiration validator.
// TODO: Add a version validator that removed the completed tutorial storages when there were major changes to the tutorial.
// * The changes are tracked via env variables. The last version that user saw the tutorial is saved in storage.
// TODO: Break up this component into reusable components that will generate headers and the content section.
// * Pass in if the component to be generated is the last component so the dividers can be conditionally rendered.
// * Pass in the type of component: text, calender, type of calender.
return (
<Box>
<VStack
h="auto"
w="auto"
justifyContent="center"
alignContent="center"
my={8}
mx={{ base: 0, sm: 2, md: 4 }}
py={4}
px={{ base: 0, sm: 2, md: 4 }}
bg="gray.700"
>
<VStack
h="auto"
w="100%"
justifyContent="center"
alignContent="center"
spacing={2}
>
{/* The Heading Container */}
<VStack
h="auto"
w="100%"
justifyContent="center"
alignContent="center"
spacing={4}
>
<Heading as="h2">{"Welcome to Code Name: LCM Potty Chart"}</Heading>
<Heading as="h3" size="md">
{"A Lucid Creations Media Project"}
</Heading>
<Divider orientation="horizontal" />
</VStack>
{/* About the app container */}
<VStack
h="auto"
w="100%"
justifyContent="center"
alignContent="center"
spacing={4}
>
<Heading as="h3" size="lg">
{"About the App"}
</Heading>
<VStack
h="auto"
w="100%"
justifyContent="start"
alignContent="center"
spacing={1}
>
<Text>
{
"An app that mimics a potty/star chart for a potty training toddler or child."
}
</Text>
<Text>
{
"It can be used to track behavior, habits, diaper training, potty training (good luck), daily chores/tasks, or anything else you might want to track in a fun and visual way."
}
</Text>
<Text>
{
"The final app will have settings to disable any mention of ABDL to allow a more general audience to use, such as for a master and pet relationship."
}
</Text>
<Text>
{
"This is an alpha build of the app. Some functionality may not work as intended, is fully functional, and may be missing entirely."
}
</Text>
</VStack>
</VStack>
<Divider orientation="horizontal" />
</VStack>
{/* Functionality of the app */}
<VStack
h="auto"
w="100%"
justifyContent="center"
alignContent="center"
spacing={4}
>
<Heading as="h3" size="lg">
{"Current Functionality"}
</Heading>
<VStack
h="auto"
w="100%"
justifyContent="center"
alignItems="center"
alignContent="center"
spacing={1}
>
<Text>
{
"The app will generate stickers to display from the 1st of the month to the day before today. This is to simulate previous and continued use."
}
</Text>
<Text>{"Ability to add a sticker to the current date."}</Text>
<Text>
{
"Ability to add edit a sticker from a previous date with a confirmation prompt."
}
</Text>
</VStack>
<Divider orientation="horizontal" />
</VStack>
{/* Calender Demos */}
<VStack
h="auto"
w="100%"
justifyContent="center"
alignContent="center"
spacing={4}
>
<Heading as="h3" size="lg">
{"How to Use The Calender"}
</Heading>
<VStack
h="auto"
w="100%"
justifyContent="center"
alignItems="center"
alignContent="center"
spacing={4}
>
<Heading as="h4" size="md">
{"Add a Sticker to Today's Date"}
</Heading>
<HStack
w="100%"
h="auto"
alignContent="center"
justifyContent="center"
spacing={1}
>
<Text>{"Select the date with a"}</Text>
<Text color="#00ff3c">{" green "}</Text>
<Text>{"border."}</Text>
</HStack>
<CalenderExample type={"add"} />
</VStack>
<VStack
h="auto"
w="100%"
justifyContent="center"
alignItems="center"
alignContent="center"
spacing={4}
>
<Heading as="h4" size="md">
{"Add a Sticker to Previous Dates"}
</Heading>
<HStack
w="100%"
h="auto"
alignContent="center"
justifyContent="center"
spacing={1}
>
<Text>{"Select a date with a"}</Text>
<Text color="#00ff3c">{" green "}</Text>
<Text>{"border."}</Text>
</HStack>
<CalenderExample type={"edit"} />
</VStack>
<Divider orientation="horizontal" />
</VStack>
{/* Links */}
<VStack
h="auto"
w="100%"
justifyContent="center"
alignContent="center"
spacing={4}
>
<Heading as="h3" size="lg">
{"More Info"}
</Heading>
<HStack
h="auto"
w="100%"
justifyContent="center"
alignContent="center"
spacing={4}
>
<CustomButton
link={
"https://docs.google.com/document/d/1hrerGKHTO3iach8A-CabtfIB4lyZWlgO8EGTyOCrI2Y"
}
text="Roadmap and Progress"
type="secondary"
/>
<CustomButton
link={
"https://lucidcreations.media/introducing-code-name-potty-chart/"
}
text="Original Announcement"
type="secondary"
/>
<Patreon />
<Twitter />
</HStack>
<Divider orientation="horizontal" />
</VStack>
{/* Complete tutorial */}
<HStack
h="auto"
w="80%"
justifyContent="space-between"
alignItems="flex-start"
pt={8}
>
<Button
type="button"
isDisabled={isLoading}
onClick={() => handleSkip()}
variant="skip"
>
{"Skip"}
</Button>
<VStack
h="auto"
w="auto"
justifyContent="center"
alignItems="center"
spacing={2}
>
<Button
type="button"
isDisabled={isLoading}
onClick={() => handleComplete()}
variant="primary"
>
{"Complete Tutorial"}
</Button>
<Checkbox
isChecked={rememberComplete}
isDisabled={isLoading}
onChange={() => handleUpdateCheck()}
>
{"Remember completed?"}
</Checkbox>
</VStack>
</HStack>
</VStack>
</Box>
<VStack
h="auto"
w="auto"
justifyContent="center"
alignContent="center"
my={8}
mx={{ base: 0, sm: 2, md: 4 }}
py={4}
px={{ base: 0, sm: 2, md: 4 }}
bg="gray.700"
>
<TutorialHeading />
<TutorialAboutApp />
<TutorialAppFunctionality />
<TutorialCalender isLoading={isLoading} />
<TutorialLinks />
<TutorialSubmitButtons isLoading={isLoading} />
</VStack>
);
};

View File

@@ -0,0 +1,33 @@
import React from "react";
import { VStack, Heading, Divider, Text } from "@chakra-ui/react";
import aboutApp from "../data/aboutApp";
const TutorialAboutApp = (): JSX.Element => {
return (
<VStack
h="auto"
w="100%"
justifyContent="center"
alignContent="center"
spacing={4}
>
<Heading as="h3" size="lg">
{"About the App"}
</Heading>
<VStack
h="auto"
w="100%"
justifyContent="start"
alignContent="center"
spacing={1}
>
{aboutApp.map((string: string) => {
return <Text key={string.replaceAll(" ", "-")}>{string}</Text>;
})}
</VStack>
<Divider orientation="horizontal" />
</VStack>
);
};
export default TutorialAboutApp;

View File

@@ -0,0 +1,33 @@
import React from "react";
import { VStack, Heading, Divider, Text } from "@chakra-ui/react";
import appFunctionality from "../data/appFunctionality";
const TutorialAppFunctionality = (): JSX.Element => {
return (
<VStack
h="auto"
w="100%"
justifyContent="center"
alignContent="center"
spacing={4}
>
<Heading as="h3" size="lg">
{"About the App"}
</Heading>
<VStack
h="auto"
w="100%"
justifyContent="start"
alignContent="center"
spacing={1}
>
{appFunctionality.map((string: string) => {
return <Text key={string.replaceAll(" ", "-")}>{string}</Text>;
})}
</VStack>
<Divider orientation="horizontal" />
</VStack>
);
};
export default TutorialAppFunctionality;

View File

@@ -0,0 +1,74 @@
import React from "react";
import { Divider, Heading, HStack, Text, VStack } from "@chakra-ui/react";
import CalenderExample from "../CalenderExample";
interface CalenderExampleProps {
isLoading: boolean;
}
const TutorialCalender = ({ isLoading }: CalenderExampleProps): JSX.Element => {
return (
<VStack
h="auto"
w="100%"
justifyContent="center"
alignContent="center"
spacing={4}
>
<Heading as="h3" size="lg">
{"How to Use The Calender"}
</Heading>
<VStack
h="auto"
w="100%"
justifyContent="center"
alignItems="center"
alignContent="center"
spacing={4}
>
<Heading as="h4" size="md">
{"Add a Sticker to Today's Date"}
</Heading>
<HStack
w="100%"
h="auto"
alignContent="center"
justifyContent="center"
spacing={1}
>
<Text>{"Select the date with a"}</Text>
<Text color="#00ff3c">{" green "}</Text>
<Text>{"border."}</Text>
</HStack>
<CalenderExample type={"add"} isLoading={isLoading} />
</VStack>
<VStack
h="auto"
w="100%"
justifyContent="center"
alignItems="center"
alignContent="center"
spacing={4}
>
<Heading as="h4" size="md">
{"Add a Sticker to Previous Dates"}
</Heading>
<HStack
w="100%"
h="auto"
alignContent="center"
justifyContent="center"
spacing={1}
>
<Text>{"Select a date with a"}</Text>
<Text color="#00ff3c">{" green "}</Text>
<Text>{"border."}</Text>
</HStack>
<CalenderExample type={"edit"} isLoading={isLoading} />
</VStack>
<Divider orientation="horizontal" />
</VStack>
);
};
export default TutorialCalender;

View File

@@ -0,0 +1,22 @@
import React from "react";
import { VStack, Heading, Divider } from "@chakra-ui/react";
const TutorialHeading = (): JSX.Element => {
return (
<VStack
h="auto"
w="100%"
justifyContent="center"
alignContent="center"
spacing={4}
>
<Heading as="h2">{"Welcome to Code Name: LCM Potty Chart"}</Heading>
<Heading as="h3" size="md">
{"A Lucid Creations Media Project"}
</Heading>
<Divider orientation="horizontal" />
</VStack>
);
};
export default TutorialHeading;

View File

@@ -0,0 +1,73 @@
import React from "react";
import { Divider, Heading, HStack, VStack } from "@chakra-ui/react";
import CustomButton from "../../buttons/Custom";
import Patreon from "../../buttons/Patreon";
import Twitter from "../../buttons/Twitter";
import links, { LinkObj } from "../data/links";
const TutorialLinks = (): JSX.Element => {
return (
<VStack
h="auto"
w="100%"
justifyContent="center"
alignContent="center"
spacing={4}
>
<Heading as="h3" size="lg">
{"More Info"}
</Heading>
<HStack
h="auto"
w="100%"
display={{ base: "none", lg: "flex" }}
justifyContent="center"
alignContent="center"
spacing={4}
>
{links.map((link: LinkObj) => {
const { href, name, type } = link;
if (type === "primary" || type === "secondary") {
return <CustomButton link={href} text={name} type={type} />;
}
if (type === "patreon") {
return <Patreon />;
}
if (type === "twitter") {
return <Twitter />;
}
})}
</HStack>
<VStack
h="auto"
w="100%"
display={{ base: "flex", lg: "none" }}
justifyContent="center"
alignContent="center"
spacing={4}
>
{links.map((link: LinkObj) => {
const { href, name, type } = link;
if (type === "primary" || type === "secondary") {
return <CustomButton link={href} text={name} type={type} />;
}
if (type === "patreon") {
return <Patreon />;
}
if (type === "twitter") {
return <Twitter />;
}
})}
</VStack>
<Divider orientation="horizontal" />
</VStack>
);
};
export default TutorialLinks;

View File

@@ -0,0 +1,83 @@
import { HStack, Button, VStack, Checkbox } from "@chakra-ui/react";
import React from "react";
import { useAppDispatch, useAppSelector } from "../../../app/hooks";
import {
setTutorialCompleted,
setTempTutorialComplete,
toggleRememberCompleted
} from "../../../features/tutorial";
interface TutorialSubmitButtonsProps {
isLoading: boolean;
}
const TutorialSubmitButtons = ({
isLoading
}: TutorialSubmitButtonsProps): JSX.Element => {
const rememberComplete: boolean = useAppSelector(
(state) => state.tutorial.rememberCompleted
);
const dispatch = useAppDispatch();
const handleComplete = (): void => {
if (rememberComplete) {
dispatch(setTutorialCompleted());
}
if (!rememberComplete) {
dispatch(setTempTutorialComplete());
}
};
const handleSkip = (): void => {
dispatch(setTempTutorialComplete());
};
const handleUpdateCheck = (): void => {
dispatch(toggleRememberCompleted());
};
return (
<HStack
h="auto"
w="80%"
justifyContent="space-between"
alignItems="flex-start"
pt={8}
>
<Button
type="button"
isDisabled={isLoading}
onClick={() => handleSkip()}
variant="skip"
>
{"Skip"}
</Button>
<VStack
h="auto"
w="auto"
justifyContent="center"
alignItems="center"
spacing={2}
>
<Button
type="button"
isDisabled={isLoading}
onClick={() => handleComplete()}
variant="primary"
>
{"Complete Tutorial"}
</Button>
<Checkbox
isChecked={rememberComplete}
isDisabled={isLoading}
onChange={() => handleUpdateCheck()}
>
{"Remember completed?"}
</Checkbox>
</VStack>
</HStack>
);
};
export default TutorialSubmitButtons;