Date align #23
@@ -1,4 +1,16 @@
|
|||||||
{
|
{
|
||||||
|
"rules": {
|
||||||
|
"comma-dangle": [
|
||||||
|
"error",
|
||||||
|
{
|
||||||
|
"arrays": "never",
|
||||||
|
"objects": "never",
|
||||||
|
"imports": "never",
|
||||||
|
"exports": "never",
|
||||||
|
"functions": "never"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
"extends": [
|
"extends": [
|
||||||
"next",
|
"next",
|
||||||
"next/core-web-vitals",
|
"next/core-web-vitals",
|
||||||
|
|||||||
5
.prettierrc
Normal file
5
.prettierrc
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"trailingComma": "none",
|
||||||
|
"tabWidth": 2,
|
||||||
|
"bracketSameLine": false
|
||||||
|
}
|
||||||
@@ -3,8 +3,8 @@ import { useRouter } from "next/router";
|
|||||||
import { HStack, IconButton } from "@chakra-ui/react";
|
import { HStack, IconButton } from "@chakra-ui/react";
|
||||||
import { Icon } from "@iconify/react";
|
import { Icon } from "@iconify/react";
|
||||||
import { sub, add, format } from "date-fns";
|
import { sub, add, format } from "date-fns";
|
||||||
import { CalenderContext } from "../../contexts/CalenderContext";
|
|
||||||
import DatePicker from "./DatePicker";
|
import DatePicker from "./DatePicker";
|
||||||
|
import { CalenderContext } from "../../contexts/CalenderContext";
|
||||||
|
|
||||||
const CalenderNav = (): JSX.Element => {
|
const CalenderNav = (): JSX.Element => {
|
||||||
const { selectedDate } = useContext(CalenderContext);
|
const { selectedDate } = useContext(CalenderContext);
|
||||||
@@ -14,7 +14,7 @@ const CalenderNav = (): JSX.Element => {
|
|||||||
const handleNavButtons = (direction: "next" | "prev") => {
|
const handleNavButtons = (direction: "next" | "prev") => {
|
||||||
if (direction === "next") {
|
if (direction === "next") {
|
||||||
const newMonth = add(selectedDate, {
|
const newMonth = add(selectedDate, {
|
||||||
months: 1,
|
months: 1
|
||||||
});
|
});
|
||||||
|
|
||||||
const year = format(newMonth, "y");
|
const year = format(newMonth, "y");
|
||||||
@@ -23,7 +23,7 @@ const CalenderNav = (): JSX.Element => {
|
|||||||
router.push(`/calendar/${year}/${month}`);
|
router.push(`/calendar/${year}/${month}`);
|
||||||
} else if (direction === "prev") {
|
} else if (direction === "prev") {
|
||||||
const newMonth = sub(selectedDate, {
|
const newMonth = sub(selectedDate, {
|
||||||
months: 1,
|
months: 1
|
||||||
});
|
});
|
||||||
|
|
||||||
const year = format(newMonth, "y");
|
const year = format(newMonth, "y");
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import {
|
|||||||
PopoverContent,
|
PopoverContent,
|
||||||
PopoverHeader,
|
PopoverHeader,
|
||||||
PopoverTrigger,
|
PopoverTrigger,
|
||||||
VStack,
|
VStack
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import {
|
import {
|
||||||
Formik,
|
Formik,
|
||||||
@@ -22,11 +22,10 @@ import {
|
|||||||
FormikProps,
|
FormikProps,
|
||||||
Form,
|
Form,
|
||||||
Field,
|
Field,
|
||||||
FieldProps,
|
FieldProps
|
||||||
} from "formik";
|
} from "formik";
|
||||||
import { format } from "date-fns";
|
|
||||||
import { CalenderContext } from "../../contexts/CalenderContext";
|
|
||||||
import FormValidateEmoji from "./FormValidateEmoji";
|
import FormValidateEmoji from "./FormValidateEmoji";
|
||||||
|
import { CalenderContext } from "../../contexts/CalenderContext";
|
||||||
|
|
||||||
interface UpdateCalendarProps {
|
interface UpdateCalendarProps {
|
||||||
year: number;
|
year: number;
|
||||||
@@ -35,9 +34,7 @@ interface UpdateCalendarProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const DatePicker = (): JSX.Element => {
|
const DatePicker = (): JSX.Element => {
|
||||||
const { selectedDate } = useContext(CalenderContext);
|
const { title } = useContext(CalenderContext);
|
||||||
|
|
||||||
const currentMonth = format(selectedDate, "LLLL uuuu");
|
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
@@ -57,7 +54,7 @@ const DatePicker = (): JSX.Element => {
|
|||||||
const date: UpdateCalendarProps = {
|
const date: UpdateCalendarProps = {
|
||||||
year: parseInt(dateArr[0]),
|
year: parseInt(dateArr[0]),
|
||||||
month: parseInt(dateArr[1]),
|
month: parseInt(dateArr[1]),
|
||||||
day: parseInt(dateArr[2]),
|
day: parseInt(dateArr[2])
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!/^(19|20)\d{2}$/.test(`${date.year}`)) {
|
if (!/^(19|20)\d{2}$/.test(`${date.year}`)) {
|
||||||
@@ -97,7 +94,7 @@ const DatePicker = (): JSX.Element => {
|
|||||||
const date: UpdateCalendarProps = {
|
const date: UpdateCalendarProps = {
|
||||||
year: parseInt(dateArr[0]),
|
year: parseInt(dateArr[0]),
|
||||||
month: parseInt(dateArr[1]),
|
month: parseInt(dateArr[1]),
|
||||||
day: parseInt(dateArr[2]),
|
day: parseInt(dateArr[2])
|
||||||
};
|
};
|
||||||
|
|
||||||
return resolve(router.push(`/calendar/${date.year}/${date.month}`));
|
return resolve(router.push(`/calendar/${date.year}/${date.month}`));
|
||||||
@@ -116,15 +113,15 @@ const DatePicker = (): JSX.Element => {
|
|||||||
bg: "gray.900",
|
bg: "gray.900",
|
||||||
borderColor: "white",
|
borderColor: "white",
|
||||||
_placeholder: {
|
_placeholder: {
|
||||||
color: "white",
|
color: "white"
|
||||||
},
|
},
|
||||||
_focus: {
|
_focus: {
|
||||||
bg: "#000",
|
bg: "#000",
|
||||||
color: "#FFF",
|
color: "#FFF",
|
||||||
borderColor: "#63b3ed",
|
borderColor: "#63b3ed",
|
||||||
boxShadow: "0 0 0 1px #63b3ed",
|
boxShadow: "0 0 0 1px #63b3ed",
|
||||||
zIndex: "1",
|
zIndex: "1"
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const initRef = useRef();
|
const initRef = useRef();
|
||||||
@@ -134,7 +131,7 @@ const DatePicker = (): JSX.Element => {
|
|||||||
<PopoverTrigger>
|
<PopoverTrigger>
|
||||||
<Button border="none" variant="outline">
|
<Button border="none" variant="outline">
|
||||||
<Heading w="100%" h="auto">
|
<Heading w="100%" h="auto">
|
||||||
{currentMonth}
|
{title}
|
||||||
</Heading>
|
</Heading>
|
||||||
</Button>
|
</Button>
|
||||||
</PopoverTrigger>
|
</PopoverTrigger>
|
||||||
@@ -148,7 +145,7 @@ const DatePicker = (): JSX.Element => {
|
|||||||
<PopoverBody textAlign="center">
|
<PopoverBody textAlign="center">
|
||||||
<Formik
|
<Formik
|
||||||
initialValues={{
|
initialValues={{
|
||||||
date: "",
|
date: ""
|
||||||
}}
|
}}
|
||||||
onSubmit={(data, actions) => {
|
onSubmit={(data, actions) => {
|
||||||
handleSubmit(data)
|
handleSubmit(data)
|
||||||
@@ -156,8 +153,8 @@ const DatePicker = (): JSX.Element => {
|
|||||||
actions.setSubmitting(false);
|
actions.setSubmitting(false);
|
||||||
actions.resetForm({
|
actions.resetForm({
|
||||||
values: {
|
values: {
|
||||||
date: "",
|
date: ""
|
||||||
},
|
}
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
@@ -165,11 +162,15 @@ const DatePicker = (): JSX.Element => {
|
|||||||
});
|
});
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{(formProps: FormikProps<{ date: string }>) => (
|
{(
|
||||||
|
formProps: FormikProps<{
|
||||||
|
date: string;
|
||||||
|
}>
|
||||||
|
) => (
|
||||||
<Form
|
<Form
|
||||||
style={{
|
style={{
|
||||||
width: "100%",
|
width: "100%",
|
||||||
height: "auto",
|
height: "auto"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<VStack
|
<VStack
|
||||||
@@ -223,8 +224,8 @@ const DatePicker = (): JSX.Element => {
|
|||||||
boxShadow: "0 0 0 1px #00c17c",
|
boxShadow: "0 0 0 1px #00c17c",
|
||||||
_hover: {
|
_hover: {
|
||||||
borderColor: "brand.valid",
|
borderColor: "brand.valid",
|
||||||
boxShadow: "0 0 0 1px #00c17c",
|
boxShadow: "0 0 0 1px #00c17c"
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
: "")}
|
: "")}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ interface FormValidateEmojiProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const FormValidateEmoji: FC<FormValidateEmojiProps> = ({
|
const FormValidateEmoji: FC<FormValidateEmojiProps> = ({
|
||||||
type,
|
type
|
||||||
}: FormValidateEmojiProps) => {
|
}: FormValidateEmojiProps) => {
|
||||||
interface Validations {
|
interface Validations {
|
||||||
[key: string]: JSX.Element;
|
[key: string]: JSX.Element;
|
||||||
@@ -26,7 +26,7 @@ const FormValidateEmoji: FC<FormValidateEmojiProps> = ({
|
|||||||
<span role="img" aria-label="Check">
|
<span role="img" aria-label="Check">
|
||||||
✔
|
✔
|
||||||
</span>
|
</span>
|
||||||
),
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
return validations[`${type}`];
|
return validations[`${type}`];
|
||||||
|
|||||||
@@ -2,6 +2,9 @@ import React, { useContext, useEffect } from "react";
|
|||||||
import { Box, HStack, SimpleGrid, Text, VStack } from "@chakra-ui/react";
|
import { Box, HStack, SimpleGrid, Text, VStack } from "@chakra-ui/react";
|
||||||
import CalenderNav from "./CalenderNav";
|
import CalenderNav from "./CalenderNav";
|
||||||
import { CalenderContext } from "../../contexts/CalenderContext";
|
import { CalenderContext } from "../../contexts/CalenderContext";
|
||||||
|
import { getDate, sub, add, getYear, getMonth } from "date-fns";
|
||||||
|
import { useRouter } from "next/router";
|
||||||
|
// TODO: import types
|
||||||
|
|
||||||
interface UpdateCalendarProps {
|
interface UpdateCalendarProps {
|
||||||
year: number;
|
year: number;
|
||||||
@@ -10,28 +13,32 @@ interface UpdateCalendarProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Calender = (newDate?: UpdateCalendarProps): JSX.Element => {
|
const Calender = (newDate?: UpdateCalendarProps): JSX.Element => {
|
||||||
const { daysOfMonth, daysOfWeek, setDate } = useContext(CalenderContext);
|
const { selectedDate, layout, updateDate } = useContext(CalenderContext);
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (newDate) {
|
if (newDate) {
|
||||||
const { year, month, day } = newDate;
|
const { year, month, day } = newDate;
|
||||||
|
|
||||||
if (year > 0 && month > 0 && day > 0) {
|
if (year > 0 && month > 0 && day > 0) {
|
||||||
setDate(newDate);
|
updateDate(newDate);
|
||||||
} else {
|
} else {
|
||||||
console.warn("Invalid date format: ", newDate);
|
console.warn("Invalid date format: ", newDate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [daysOfMonth, daysOfWeek, newDate, setDate]);
|
}, [newDate, updateDate]);
|
||||||
|
|
||||||
// Simulated user settings context
|
// Simulated user settings context
|
||||||
const userSettings = {
|
const userSettings = {
|
||||||
theme: "default",
|
theme: "default",
|
||||||
startOfWeek: "Sunday",
|
startOfWeek: "Sunday"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const currMonth = layout[`${userSettings.startOfWeek.toLowerCase()}`];
|
||||||
|
const { month, weekdays } = currMonth;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<VStack h="100vh" w="100%">
|
<VStack h="91vh" w="100%">
|
||||||
<CalenderNav />
|
<CalenderNav />
|
||||||
<HStack
|
<HStack
|
||||||
px={6}
|
px={6}
|
||||||
@@ -42,7 +49,7 @@ const Calender = (newDate?: UpdateCalendarProps): JSX.Element => {
|
|||||||
alignContent="center"
|
alignContent="center"
|
||||||
alignItems="center"
|
alignItems="center"
|
||||||
>
|
>
|
||||||
{daysOfWeek.startOfWeek[userSettings.startOfWeek].map((weekDay) => {
|
{weekdays.map((weekDay) => {
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
d="flex"
|
d="flex"
|
||||||
@@ -71,20 +78,52 @@ const Calender = (newDate?: UpdateCalendarProps): JSX.Element => {
|
|||||||
// alignContent="center"
|
// alignContent="center"
|
||||||
alignItems="center"
|
alignItems="center"
|
||||||
>
|
>
|
||||||
{daysOfMonth.map((monthDay) => {
|
{Object.keys(month).map((week) => {
|
||||||
return (
|
const thisWeek = month[week];
|
||||||
<Box
|
|
||||||
bg="transparent"
|
return thisWeek.map((day) => {
|
||||||
border="2px solid #0068ff"
|
const { date, isOverflow, overflowDirection } = day;
|
||||||
w="100%"
|
|
||||||
h="100%"
|
return (
|
||||||
key={monthDay}
|
<Box
|
||||||
>
|
bg="transparent"
|
||||||
<Text w="100%" h="100%">
|
color={isOverflow ? "gray.600" : "whiteAlpha"}
|
||||||
{`Day ${monthDay}`}
|
border={isOverflow ? "2px solid #181d8f" : "2px solid #0068ff"}
|
||||||
</Text>
|
w="100%"
|
||||||
</Box>
|
h="100%"
|
||||||
);
|
key={date}
|
||||||
|
{...(isOverflow && {
|
||||||
|
_hover: {
|
||||||
|
cursor: "pointer"
|
||||||
|
}
|
||||||
|
})}
|
||||||
|
{...(isOverflow && {
|
||||||
|
onClick: () => {
|
||||||
|
if (overflowDirection === "next") {
|
||||||
|
console.log(overflowDirection);
|
||||||
|
const newMonth = add(selectedDate, { months: 1 });
|
||||||
|
|
||||||
|
const year = getYear(newMonth);
|
||||||
|
const month = getMonth(newMonth) + 1;
|
||||||
|
|
||||||
|
router.push(`/calendar/${year}/${month}`);
|
||||||
|
} else if (overflowDirection === "prev") {
|
||||||
|
const newMonth = sub(selectedDate, { months: 1 });
|
||||||
|
|
||||||
|
const year = getYear(newMonth);
|
||||||
|
const month = getMonth(newMonth) + 1;
|
||||||
|
|
||||||
|
router.push(`/calendar/${year}/${month}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})}
|
||||||
|
>
|
||||||
|
<Text w="100%" h="100%">
|
||||||
|
{`Day ${getDate(date)}`}
|
||||||
|
</Text>
|
||||||
|
</Box>
|
||||||
|
);
|
||||||
|
});
|
||||||
})}
|
})}
|
||||||
</SimpleGrid>
|
</SimpleGrid>
|
||||||
</VStack>
|
</VStack>
|
||||||
|
|||||||
@@ -1,8 +1,19 @@
|
|||||||
import React, { createContext, useState, ReactNode, useEffect } from "react";
|
import React, { createContext, useState, ReactNode } from "react";
|
||||||
import { endOfMonth, getDate, sub, compareAsc } from "date-fns";
|
import {
|
||||||
|
format,
|
||||||
|
startOfMonth,
|
||||||
|
endOfMonth,
|
||||||
|
getDate,
|
||||||
|
add,
|
||||||
|
sub,
|
||||||
|
set,
|
||||||
|
isAfter,
|
||||||
|
isBefore,
|
||||||
|
compareAsc
|
||||||
|
} from "date-fns";
|
||||||
// TODO: import types
|
// TODO: import types
|
||||||
|
|
||||||
type days =
|
type Days =
|
||||||
| "Sunday"
|
| "Sunday"
|
||||||
| "Monday"
|
| "Monday"
|
||||||
| "Tuesday"
|
| "Tuesday"
|
||||||
@@ -10,11 +21,47 @@ type days =
|
|||||||
| "Thursday"
|
| "Thursday"
|
||||||
| "Friday"
|
| "Friday"
|
||||||
| "Saturday";
|
| "Saturday";
|
||||||
interface DaysOfWeek {
|
|
||||||
startOfWeek: {
|
type DaysOfWeek = Days[];
|
||||||
Sunday: days[];
|
|
||||||
Monday: days[];
|
interface WeekDays {
|
||||||
|
sunday: DaysOfWeek;
|
||||||
|
monday: DaysOfWeek;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MonthDay {
|
||||||
|
isOverflow: boolean;
|
||||||
|
overflowDirection: "prev" | "next" | null;
|
||||||
|
date: Date;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Month {
|
||||||
|
week1: MonthDay[];
|
||||||
|
week2: MonthDay[];
|
||||||
|
week3: MonthDay[];
|
||||||
|
week4: MonthDay[];
|
||||||
|
week5: MonthDay[];
|
||||||
|
week6: MonthDay[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MonthInfo {
|
||||||
|
date: Date;
|
||||||
|
title: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MonthLayout {
|
||||||
|
sunday: {
|
||||||
|
weekdays: DaysOfWeek;
|
||||||
|
month: Month;
|
||||||
};
|
};
|
||||||
|
monday: {
|
||||||
|
weekdays: DaysOfWeek;
|
||||||
|
month: Month;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
interface MonthContext extends MonthInfo {
|
||||||
|
layout: MonthLayout;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface UpdateCalendarProps {
|
interface UpdateCalendarProps {
|
||||||
@@ -23,158 +70,217 @@ interface UpdateCalendarProps {
|
|||||||
day: number;
|
day: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Month {
|
|
||||||
week1: Date[];
|
|
||||||
week2: Date[];
|
|
||||||
week3: Date[];
|
|
||||||
week4: Date[];
|
|
||||||
week5: Date[];
|
|
||||||
week6: Date[];
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Calendar {
|
|
||||||
startOfWeek: {
|
|
||||||
Sunday: Month;
|
|
||||||
Monday: Month;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// Will replace all states and be used in redis as a form of memoization.
|
|
||||||
interface MonthInfo {
|
|
||||||
date: Date;
|
|
||||||
layout: Calendar;
|
|
||||||
startWeekday: string;
|
|
||||||
endWeekday: string;
|
|
||||||
days: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface CurrentMonth {
|
|
||||||
prev: MonthInfo;
|
|
||||||
curr: MonthInfo;
|
|
||||||
next: MonthInfo;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface CalenderMemoize {
|
|
||||||
String: CurrentMonth;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface CalenderContextState {
|
interface CalenderContextState {
|
||||||
selectedDate: Date;
|
selectedDate: Date;
|
||||||
daysOfMonth: [number];
|
title: string;
|
||||||
daysOfWeek: DaysOfWeek;
|
layout: MonthLayout;
|
||||||
setDate: (date: UpdateCalendarProps) => boolean;
|
updateDate: (input: UpdateCalendarProps) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const CalenderContext = createContext({} as CalenderContextState);
|
const CalenderContext = createContext({} as CalenderContextState);
|
||||||
|
|
||||||
const CalenderContextProvider = ({
|
const CalenderContextProvider = ({
|
||||||
children,
|
children
|
||||||
}: {
|
}: {
|
||||||
children: ReactNode;
|
children: ReactNode;
|
||||||
}): JSX.Element => {
|
}): JSX.Element => {
|
||||||
const indexToDay = {
|
const weekDays: WeekDays = {
|
||||||
startOfWeek: {
|
sunday: [
|
||||||
Sunday: {
|
"Sunday",
|
||||||
0: "Sunday",
|
"Monday",
|
||||||
1: "Monday",
|
"Tuesday",
|
||||||
2: "Tuesday",
|
"Wednesday",
|
||||||
3: "Wednesday",
|
"Thursday",
|
||||||
4: "Thursday",
|
"Friday",
|
||||||
5: "Friday",
|
"Saturday"
|
||||||
6: "Saturday",
|
],
|
||||||
},
|
monday: [
|
||||||
Monday: {
|
"Monday",
|
||||||
0: "Monday",
|
"Tuesday",
|
||||||
1: "Tuesday",
|
"Wednesday",
|
||||||
2: "Wednesday",
|
"Thursday",
|
||||||
3: "Thursday",
|
"Friday",
|
||||||
4: "Friday",
|
"Saturday",
|
||||||
5: "Saturday",
|
"Sunday"
|
||||||
6: "Sunday",
|
]
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// Selected month & year
|
//TODO Add a function that will populate the "MONTH" layout for the context. It should take in the start of the week (Sunday, Monday) and output the appropriate layout based on that preference.
|
||||||
const [selectedDate, setSelectedDate] = useState<Date>(new Date());
|
|
||||||
// Update this to have the day of week and the last numerical day.
|
|
||||||
const [endOfSelectedMonth, SetEndOfSelectedDMonth] = useState<number>(
|
|
||||||
getDate(endOfMonth(selectedDate))
|
|
||||||
);
|
|
||||||
// Update this to have the day of week and the last numerical day.
|
|
||||||
const [endOfPrevMonth, setEndOfPrevMonth] = useState<number>(
|
|
||||||
getDate(endOfMonth(sub(selectedDate, { months: 1 })))
|
|
||||||
);
|
|
||||||
// Add start of selected month and start of next month, including day of week and numerical day.
|
|
||||||
|
|
||||||
// TODO: Remove this state and all referenced to it once the date alignment algorithm is complete.
|
/**
|
||||||
const [daysOfMonth, setDaysOfMonth] = useState<[number]>([1]);
|
* Using date-fns, this function checks if currDate is within the month of selectedDate or not.
|
||||||
|
* @param {Date} selectedDate The current month.
|
||||||
|
* @param {Date} currDate The date to be compared to the selected month.
|
||||||
|
* @returns True if currDate is outside of the month of selectedDate, false if otherwise.
|
||||||
|
*/
|
||||||
|
const isOverflow = (
|
||||||
|
selectedDate: Date,
|
||||||
|
currDate: Date
|
||||||
|
): {
|
||||||
|
isOverflow: boolean;
|
||||||
|
overflowDirection: "prev" | "next" | null;
|
||||||
|
} => {
|
||||||
|
let flag = false;
|
||||||
|
let direction: "next" | "prev" | null = null;
|
||||||
|
|
||||||
// TODO: Repalce this with the new date alignment algorithm.
|
const start = startOfMonth(selectedDate);
|
||||||
// Update or populate the days of the month.
|
const end = endOfMonth(selectedDate);
|
||||||
const populateDays = (): void => {
|
|
||||||
let newDaysOfMonth: [number] = [...daysOfMonth];
|
|
||||||
|
|
||||||
if (newDaysOfMonth.length > 1) {
|
if (isBefore(currDate, start)) {
|
||||||
newDaysOfMonth = [1];
|
flag = true;
|
||||||
|
direction = "prev";
|
||||||
}
|
}
|
||||||
|
|
||||||
for (let i = 1; i < endOfSelectedMonth; i++) {
|
if (isAfter(currDate, end)) {
|
||||||
newDaysOfMonth.push(i + 1);
|
flag = true;
|
||||||
|
direction = "next";
|
||||||
}
|
}
|
||||||
|
|
||||||
setDaysOfMonth(newDaysOfMonth);
|
return { isOverflow: flag, overflowDirection: direction };
|
||||||
};
|
};
|
||||||
|
|
||||||
// TODO: Update new referenced once they are added.
|
/**
|
||||||
// Update selected month sates when the selected month is updated.
|
* A function that will return a month layout when given a date. It produces
|
||||||
|
* an object with 6 weeks that include overflow from the previous and next month
|
||||||
|
* with all dates aligned with the day of the week.
|
||||||
|
* @param selectedDate The date of the month to generate a month layout for.
|
||||||
|
*/
|
||||||
|
const populateMonth = (selectedDate: Date): MonthLayout => {
|
||||||
|
const endLastMonth = getDate(endOfMonth(sub(selectedDate, { months: 1 })));
|
||||||
|
const startOfSelectedMonth = format(startOfMonth(selectedDate), "iii");
|
||||||
|
|
||||||
// Update days of month.
|
const ISOToIndex = {
|
||||||
useEffect(() => {
|
sunday: {
|
||||||
if (daysOfMonth === null) {
|
Sun: 0,
|
||||||
populateDays();
|
Mon: 1,
|
||||||
} else {
|
Tue: 2,
|
||||||
if (daysOfMonth[daysOfMonth.length - 1] !== endOfSelectedMonth) {
|
Wed: 3,
|
||||||
populateDays();
|
Thu: 4,
|
||||||
|
Fri: 5,
|
||||||
|
Sat: 6
|
||||||
|
},
|
||||||
|
monday: {
|
||||||
|
Mon: -1,
|
||||||
|
Tue: 0,
|
||||||
|
Wed: 1,
|
||||||
|
Thu: 2,
|
||||||
|
Fri: 3,
|
||||||
|
Sat: 4,
|
||||||
|
Sun: 5
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
}, [selectedDate, endOfSelectedMonth]);
|
|
||||||
|
|
||||||
// Update end of month.
|
const sundays = {
|
||||||
useEffect(() => {
|
week1: new Array(7).fill(null),
|
||||||
if (endOfSelectedMonth !== getDate(endOfMonth(selectedDate))) {
|
week2: new Array(7).fill(null),
|
||||||
SetEndOfSelectedDMonth(getDate(endOfMonth(selectedDate)));
|
week3: new Array(7).fill(null),
|
||||||
}
|
week4: new Array(7).fill(null),
|
||||||
}, [selectedDate]);
|
week5: new Array(7).fill(null),
|
||||||
|
week6: new Array(7).fill(null)
|
||||||
|
};
|
||||||
|
|
||||||
// Calender Layout
|
const sunStartDay =
|
||||||
const daysOfWeek: DaysOfWeek = {
|
endLastMonth - (ISOToIndex.sunday[startOfSelectedMonth] - 1);
|
||||||
startOfWeek: {
|
|
||||||
Sunday: [
|
let sunCurrDate = set(sub(selectedDate, { months: 1 }), {
|
||||||
"Sunday",
|
date: sunStartDay
|
||||||
"Monday",
|
});
|
||||||
"Tuesday",
|
|
||||||
"Wednesday",
|
for (const week in sundays) {
|
||||||
"Thursday",
|
const thisWeek = sundays[week];
|
||||||
"Friday",
|
|
||||||
"Saturday",
|
thisWeek.forEach((e, i) => {
|
||||||
],
|
const overflowInfo = isOverflow(selectedDate, sunCurrDate);
|
||||||
Monday: [
|
|
||||||
"Monday",
|
const day: MonthDay = {
|
||||||
"Tuesday",
|
...overflowInfo,
|
||||||
"Wednesday",
|
date: sunCurrDate
|
||||||
"Thursday",
|
};
|
||||||
"Friday",
|
sunCurrDate = add(sunCurrDate, {
|
||||||
"Saturday",
|
days: 1
|
||||||
"Sunday",
|
});
|
||||||
],
|
|
||||||
},
|
sundays[week][i] = day;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const mondays = {
|
||||||
|
week1: new Array(7).fill(null),
|
||||||
|
week2: new Array(7).fill(null),
|
||||||
|
week3: new Array(7).fill(null),
|
||||||
|
week4: new Array(7).fill(null),
|
||||||
|
week5: new Array(7).fill(null),
|
||||||
|
week6: new Array(7).fill(null)
|
||||||
|
};
|
||||||
|
|
||||||
|
const monStartDay = endLastMonth - ISOToIndex.monday[startOfSelectedMonth];
|
||||||
|
|
||||||
|
let monCurrDate = set(sub(selectedDate, { months: 1 }), {
|
||||||
|
date: monStartDay
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const week in mondays) {
|
||||||
|
const thisWeek = mondays[week];
|
||||||
|
|
||||||
|
thisWeek.forEach((e, i) => {
|
||||||
|
const overflowInfo = isOverflow(selectedDate, sunCurrDate);
|
||||||
|
|
||||||
|
const day: MonthDay = {
|
||||||
|
...overflowInfo,
|
||||||
|
date: monCurrDate
|
||||||
|
};
|
||||||
|
monCurrDate = add(monCurrDate, {
|
||||||
|
days: 1
|
||||||
|
});
|
||||||
|
|
||||||
|
mondays[week][i] = day;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const output = {
|
||||||
|
sunday: {
|
||||||
|
weekdays: weekDays.sunday,
|
||||||
|
month: sundays
|
||||||
|
},
|
||||||
|
monday: {
|
||||||
|
weekdays: weekDays.monday,
|
||||||
|
month: mondays
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return output;
|
||||||
};
|
};
|
||||||
|
|
||||||
//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.
|
const [selectedDate, setSelectedDate] = useState<Date>(new Date());
|
||||||
|
const [selectedDateInfo, setSelectedMonthInfo] = useState<MonthContext>({
|
||||||
|
date: selectedDate,
|
||||||
|
title: format(selectedDate, "LLLL uuuu"),
|
||||||
|
layout: populateMonth(selectedDate)
|
||||||
|
});
|
||||||
|
|
||||||
// Navigation
|
//TODO Update the MonthInfo to use the new month population function on first render.
|
||||||
const setDate = (input: UpdateCalendarProps): boolean => {
|
|
||||||
|
//TODO Add a function that will update the MonthInfo state when the selected month changes. This should use the populate month function that will be made above.
|
||||||
|
/**
|
||||||
|
* Updates the selectedDateInfo state when given a date.
|
||||||
|
* @param {Date} newDate The date to set the selectedDateInfo state to.
|
||||||
|
*/
|
||||||
|
const updateDateInfo = (newDate: Date) => {
|
||||||
|
const output = { ...selectedDateInfo };
|
||||||
|
output.date = newDate;
|
||||||
|
output.title = format(newDate, "LLLL uuuu");
|
||||||
|
output.layout = populateMonth(newDate);
|
||||||
|
|
||||||
|
setSelectedMonthInfo(output);
|
||||||
|
};
|
||||||
|
|
||||||
|
//TODO: Add a new navigation function that will take in either a direction (next, prev) or a date to go directly to. That will update the selected month and trigger the use effects below.
|
||||||
|
/**
|
||||||
|
* Updated the selectedDate state when given the appropriate object.
|
||||||
|
* @param {UpdateCalendarProps} input An object with year, month,
|
||||||
|
* and day keys that the selectedDate state will be updated to.
|
||||||
|
*/
|
||||||
|
const updateDate = (input: UpdateCalendarProps) => {
|
||||||
const { year, month: inputMonth, day } = input;
|
const { year, month: inputMonth, day } = input;
|
||||||
|
|
||||||
if (!year || !inputMonth || day < 0 || day > 31) {
|
if (!year || !inputMonth || day < 0 || day > 31) {
|
||||||
@@ -185,15 +291,16 @@ const CalenderContextProvider = ({
|
|||||||
|
|
||||||
if (compareAsc(customDate, selectedDate) !== 0) {
|
if (compareAsc(customDate, selectedDate) !== 0) {
|
||||||
setSelectedDate(customDate);
|
setSelectedDate(customDate);
|
||||||
|
updateDateInfo(customDate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const calenderContextValues = {
|
const calenderContextValues = {
|
||||||
selectedDate,
|
selectedDate,
|
||||||
daysOfMonth,
|
title: selectedDateInfo.title,
|
||||||
daysOfWeek,
|
layout: selectedDateInfo.layout,
|
||||||
setDate,
|
updateDate
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
"private": true,
|
"private": true,
|
||||||
"name": "lucid-creations-media-potty-chart",
|
"name": "lucid-creations-media-potty-chart",
|
||||||
"homepage": "https://lucidcreations.media/introducing-code-name-potty-chart/",
|
"homepage": "https://lucidcreations.media/introducing-code-name-potty-chart/",
|
||||||
"version": "v0.0.5.2-pre-alpha",
|
"version": "v0.0.6.0-pre-alpha",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Lucid Creations Media",
|
"name": "Lucid Creations Media",
|
||||||
"url": "https://lucidcreations.media",
|
"url": "https://lucidcreations.media",
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ class Document extends NextDocument {
|
|||||||
<Html>
|
<Html>
|
||||||
<Head>
|
<Head>
|
||||||
<meta name="theme-color" content="#3138dc" />
|
<meta name="theme-color" content="#3138dc" />
|
||||||
<link rel="icon" href="/images/favicon.svg" sizes="32x32 192x192" />
|
<link rel="icon" href="/images/logo.svg" sizes="32x32 192x192" />
|
||||||
<link rel="apple-touch-icon" href="/images/favicon.svg" />
|
<link rel="apple-touch-icon" href="/images/logo.svg" />
|
||||||
<meta property="og:title" content="LCM Potty Chart" />
|
<meta property="og:title" content="LCM Potty Chart" />
|
||||||
<meta name="og:description" content={description} />
|
<meta name="og:description" content={description} />
|
||||||
<meta property="og:type" content="Progress Tracking" />
|
<meta property="og:type" content="Progress Tracking" />
|
||||||
|
|||||||
@@ -22,14 +22,14 @@ const DateRoute: React.FC<unknown> = () => {
|
|||||||
return {
|
return {
|
||||||
year: 0,
|
year: 0,
|
||||||
month: 0,
|
month: 0,
|
||||||
day: 0,
|
day: 0
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
const date = {
|
const date = {
|
||||||
year: 0,
|
year: 0,
|
||||||
month: 0,
|
month: 0,
|
||||||
day: 0,
|
day: 0
|
||||||
};
|
};
|
||||||
|
|
||||||
if (/^(19|20)\d{2}$/.test(`${dateArr[0]}`)) {
|
if (/^(19|20)\d{2}$/.test(`${dateArr[0]}`)) {
|
||||||
@@ -58,7 +58,9 @@ const DateRoute: React.FC<unknown> = () => {
|
|||||||
const parsedSlug = slug.map((e) => {
|
const parsedSlug = slug.map((e) => {
|
||||||
return parseInt(e);
|
return parseInt(e);
|
||||||
});
|
});
|
||||||
setDate({ ...validateDateInput(parsedSlug) });
|
setDate({
|
||||||
|
...validateDateInput(parsedSlug)
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}, [slug]);
|
}, [slug]);
|
||||||
|
|
||||||
|
|||||||
@@ -14,8 +14,9 @@ const IndexPage = (): JSX.Element => {
|
|||||||
const date = useRef<UpdateCalendarProps>({
|
const date = 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"))
|
||||||
});
|
});
|
||||||
|
|
||||||
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>
|
<CalenderContextProvider>
|
||||||
|
|||||||
1
public/images/logo.svg
Normal file
1
public/images/logo.svg
Normal file
@@ -0,0 +1 @@
|
|||||||
|
<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 144.01 157.2"><defs><style>.cls-1{fill:#61a3d7;}</style></defs><path class="cls-1" d="M90.37,123A3.86,3.86,0,0,0,85,124.63q-7.68,13.26-15.31,26.55a11.53,11.53,0,0,0-.75,2,4.09,4.09,0,0,0,3,3.86,3.78,3.78,0,0,0,4.39-1.93q7.71-13.32,15.38-26.65A3.86,3.86,0,0,0,90.37,123Z"/><path class="cls-1" d="M116.26,123a3.84,3.84,0,0,0-5.34,1.59q-6.39,11-12.73,22.06a14.1,14.1,0,0,0-.8,2.11,4.26,4.26,0,0,0,2.93,3.76,3.86,3.86,0,0,0,4.54-1.89q6.4-11.07,12.79-22.16A3.84,3.84,0,0,0,116.26,123Z"/><path class="cls-1" d="M63.53,122.65a3.79,3.79,0,0,0-4.44,1.84q-6.48,11.17-12.89,22.37a4.49,4.49,0,0,0-.51,2.42,3.71,3.71,0,0,0,2.94,3.3,3.76,3.76,0,0,0,4.25-1.81q6.52-11.21,13-22.46a10,10,0,0,0,.62-1.82A4.18,4.18,0,0,0,63.53,122.65Z"/><path class="cls-1" d="M142.6,84.35C139,74,131.3,68.43,120.54,66.76c-.23-1.85-.35-3.69-.69-5.49A34.64,34.64,0,0,0,111.21,44l-5.49,5.48a27.13,27.13,0,0,1,7,20.22c-.19,3,1.76,4.82,4.68,4.78,7.72-.11,13.62,3.21,16.94,10.2a18,18,0,0,1-16.26,25.91c-10.16,0-20.32,0-30.48,0h-30a23,23,0,0,1-10.51-2.5l-5.68,5.68a30.08,30.08,0,0,0,16.13,4.63q30.14,0,60.28,0a29.86,29.86,0,0,0,4.81-.43C138.1,115.3,147.78,99.14,142.6,84.35Z"/><path class="cls-1" d="M139.83,3.83,136.54.54a1.82,1.82,0,0,0-2.59,0L.54,134a1.82,1.82,0,0,0,0,2.59l3.29,3.29a1.83,1.83,0,0,0,1.3.54,1.81,1.81,0,0,0,1.29-.54L139.83,6.42A1.82,1.82,0,0,0,139.83,3.83Z"/><path class="cls-1" d="M36.62,72.45A2.22,2.22,0,0,1,37.29,74c-.7,4.86-1.44,9.72-2.18,14.57L48.59,75.09h0l25.79-25.8h0L84,39.65a1.94,1.94,0,0,1-1.46-1.18C79.06,31.52,75.49,24.6,72,17.64c-1.34-2.68-3.35-4.34-6.35-4.35s-5,1.64-6.37,4.31c-3.5,7-7.08,14-10.59,20.94a1.84,1.84,0,0,1-1.52,1.14c-5.64.9-11.27,1.86-16.91,2.79-2.16.35-4.33.67-6.48,1a6.68,6.68,0,0,0-5.62,4.79A6.77,6.77,0,0,0,20,55.45Q28.33,63.94,36.62,72.45Z"/></svg>
|
||||||
|
After Width: | Height: | Size: 1.8 KiB |
@@ -1,10 +1,10 @@
|
|||||||
import { extendTheme, ThemeConfig } from "@chakra-ui/react";
|
import { extendTheme, ThemeConfig } from "@chakra-ui/react";
|
||||||
import { createBreakpoints } from "@chakra-ui/theme-tools";
|
// import { createBreakpoints } from "@chakra-ui/theme-tools";
|
||||||
import buttons from "./components/buttonStyles";
|
import buttons from "./components/buttonStyles";
|
||||||
|
|
||||||
const config: ThemeConfig = {
|
const config: ThemeConfig = {
|
||||||
initialColorMode: "dark",
|
initialColorMode: "dark",
|
||||||
useSystemColorMode: false,
|
useSystemColorMode: false
|
||||||
};
|
};
|
||||||
|
|
||||||
// const breakpoints = createBreakpoints({
|
// const breakpoints = createBreakpoints({
|
||||||
@@ -29,19 +29,19 @@ const AppTheme = extendTheme({
|
|||||||
footer: "#0097a7",
|
footer: "#0097a7",
|
||||||
footerText: "black",
|
footerText: "black",
|
||||||
content: "#2d3748",
|
content: "#2d3748",
|
||||||
patreon: "#FF424D",
|
patreon: "#FF424D"
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
styles: {
|
styles: {
|
||||||
global: {
|
global: {
|
||||||
body: {
|
body: {
|
||||||
bg: "gray.900",
|
bg: "gray.900"
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
components: {
|
components: {
|
||||||
Button: buttons,
|
Button: buttons
|
||||||
},
|
}
|
||||||
// breakpoints,
|
// breakpoints,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import {
|
|||||||
darken,
|
darken,
|
||||||
mode,
|
mode,
|
||||||
StyleFunctionProps,
|
StyleFunctionProps,
|
||||||
whiten,
|
whiten
|
||||||
} from "@chakra-ui/theme-tools";
|
} from "@chakra-ui/theme-tools";
|
||||||
import { Dict } from "@chakra-ui/utils";
|
import { Dict } from "@chakra-ui/utils";
|
||||||
|
|
||||||
@@ -22,8 +22,8 @@ const buttonStyles = {
|
|||||||
bg: mode(
|
bg: mode(
|
||||||
whiten("brand.primary", 20),
|
whiten("brand.primary", 20),
|
||||||
darken("brand.primary", 20)
|
darken("brand.primary", 20)
|
||||||
)(props),
|
)(props)
|
||||||
},
|
}
|
||||||
}),
|
}),
|
||||||
contactSecondary: (props: Dict<never> | StyleFunctionProps) => ({
|
contactSecondary: (props: Dict<never> | StyleFunctionProps) => ({
|
||||||
bg: "brand.primary",
|
bg: "brand.primary",
|
||||||
@@ -33,8 +33,8 @@ const buttonStyles = {
|
|||||||
bg: mode(
|
bg: mode(
|
||||||
whiten("brand.primary", 20),
|
whiten("brand.primary", 20),
|
||||||
darken("brand.primary", 20)
|
darken("brand.primary", 20)
|
||||||
)(props),
|
)(props)
|
||||||
},
|
}
|
||||||
}),
|
}),
|
||||||
project: (props: Dict<never> | StyleFunctionProps) => ({
|
project: (props: Dict<never> | StyleFunctionProps) => ({
|
||||||
bg: "transparent",
|
bg: "transparent",
|
||||||
@@ -50,8 +50,8 @@ const buttonStyles = {
|
|||||||
darken("brand.secondary", 20)
|
darken("brand.secondary", 20)
|
||||||
)(props),
|
)(props),
|
||||||
boxShadow:
|
boxShadow:
|
||||||
"rgba(0, 104, 255, 0.5) 0px 0px 15px, rgba(0, 104, 255, 0.3) 0px 0px 3px 1px",
|
"rgba(0, 104, 255, 0.5) 0px 0px 15px, rgba(0, 104, 255, 0.3) 0px 0px 3px 1px"
|
||||||
},
|
}
|
||||||
}),
|
}),
|
||||||
nav: (props: Dict<never> | StyleFunctionProps) => ({
|
nav: (props: Dict<never> | StyleFunctionProps) => ({
|
||||||
bg: "transparent",
|
bg: "transparent",
|
||||||
@@ -61,16 +61,16 @@ const buttonStyles = {
|
|||||||
bg: mode(
|
bg: mode(
|
||||||
whiten("brand.secondary", 20),
|
whiten("brand.secondary", 20),
|
||||||
darken("brand.secondary", 20)
|
darken("brand.secondary", 20)
|
||||||
)(props),
|
)(props)
|
||||||
},
|
}
|
||||||
}),
|
}),
|
||||||
stickyNav: (/* props: Dict<never> | StyleFunctionProps */) => ({
|
stickyNav: (/* props: Dict<never> | StyleFunctionProps */) => ({
|
||||||
bg: "transparent",
|
bg: "transparent",
|
||||||
fontSize: "md",
|
fontSize: "md",
|
||||||
px: "2",
|
px: "2",
|
||||||
_hover: {
|
_hover: {
|
||||||
textDecoration: "underline",
|
textDecoration: "underline"
|
||||||
},
|
}
|
||||||
}),
|
}),
|
||||||
credits: (props: Dict<never> | StyleFunctionProps) => ({
|
credits: (props: Dict<never> | StyleFunctionProps) => ({
|
||||||
bg: "brand.main",
|
bg: "brand.main",
|
||||||
@@ -78,8 +78,8 @@ const buttonStyles = {
|
|||||||
p: 3,
|
p: 3,
|
||||||
color: "whiteAlpha",
|
color: "whiteAlpha",
|
||||||
_hover: {
|
_hover: {
|
||||||
bg: mode(whiten("brand.main", 20), darken("brand.main", 20))(props),
|
bg: mode(whiten("brand.main", 20), darken("brand.main", 20))(props)
|
||||||
},
|
}
|
||||||
}),
|
}),
|
||||||
backToTop: (props: Dict<never> | StyleFunctionProps) => ({
|
backToTop: (props: Dict<never> | StyleFunctionProps) => ({
|
||||||
bg: "rgba(23, 25, 35, 0.5)",
|
bg: "rgba(23, 25, 35, 0.5)",
|
||||||
@@ -98,8 +98,8 @@ const buttonStyles = {
|
|||||||
boxShadow:
|
boxShadow:
|
||||||
"rgba(0, 104, 255, 0.5) 0px 0px 15px, rgba(0, 104, 255, 0.3) 0px 0px 3px 1px",
|
"rgba(0, 104, 255, 0.5) 0px 0px 15px, rgba(0, 104, 255, 0.3) 0px 0px 3px 1px",
|
||||||
color: "whiteAlpha.900",
|
color: "whiteAlpha.900",
|
||||||
border: "1px solid rgba(0, 134, 255, 1)",
|
border: "1px solid rgba(0, 134, 255, 1)"
|
||||||
},
|
}
|
||||||
}),
|
}),
|
||||||
collapse: (props: Dict<never> | StyleFunctionProps) => ({
|
collapse: (props: Dict<never> | StyleFunctionProps) => ({
|
||||||
bg: "transparent",
|
bg: "transparent",
|
||||||
@@ -114,8 +114,8 @@ const buttonStyles = {
|
|||||||
darken("brand.secondary", 20)
|
darken("brand.secondary", 20)
|
||||||
)(props),
|
)(props),
|
||||||
color: "whiteAlpha.900",
|
color: "whiteAlpha.900",
|
||||||
textDecoration: "none",
|
textDecoration: "none"
|
||||||
},
|
}
|
||||||
}),
|
}),
|
||||||
submit: (props: Dict<never> | StyleFunctionProps) => ({
|
submit: (props: Dict<never> | StyleFunctionProps) => ({
|
||||||
fontSize: "lg",
|
fontSize: "lg",
|
||||||
@@ -132,9 +132,9 @@ const buttonStyles = {
|
|||||||
)(props),
|
)(props),
|
||||||
boxShadow:
|
boxShadow:
|
||||||
"rgba(252, 129, 129, .95) 0px 0px 15px, rgba(252, 129, 129, 0.75) 0px 0px 3px 1px",
|
"rgba(252, 129, 129, .95) 0px 0px 15px, rgba(252, 129, 129, 0.75) 0px 0px 3px 1px",
|
||||||
border: "1px solid #FC8181",
|
border: "1px solid #FC8181"
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
}),
|
}),
|
||||||
mobileNav: (props: Dict<never> | StyleFunctionProps) => ({
|
mobileNav: (props: Dict<never> | StyleFunctionProps) => ({
|
||||||
// bg: "transparent",
|
// bg: "transparent",
|
||||||
@@ -148,14 +148,14 @@ const buttonStyles = {
|
|||||||
darken("brand.secondary", 20)
|
darken("brand.secondary", 20)
|
||||||
)(props),
|
)(props),
|
||||||
boxShadow:
|
boxShadow:
|
||||||
"rgba(0, 134, 255, 0.5) 0px 0px 15px, rgba(0, 134, 255, 0.3) 0px 0px 3px 1px",
|
"rgba(0, 134, 255, 0.5) 0px 0px 15px, rgba(0, 134, 255, 0.3) 0px 0px 3px 1px"
|
||||||
},
|
},
|
||||||
_expanded: {
|
_expanded: {
|
||||||
bg: "brand.primary",
|
bg: "brand.primary",
|
||||||
boxShadow:
|
boxShadow:
|
||||||
"rgba(0, 134, 255, 0.5) 0px 0px 15px, rgba(0, 134, 255, 0.3) 0px 0px 3px 1px",
|
"rgba(0, 134, 255, 0.5) 0px 0px 15px, rgba(0, 134, 255, 0.3) 0px 0px 3px 1px",
|
||||||
border: "1px solid #0068ff",
|
border: "1px solid #0068ff"
|
||||||
},
|
}
|
||||||
}),
|
}),
|
||||||
patreon: (props: Dict<never> | StyleFunctionProps) => ({
|
patreon: (props: Dict<never> | StyleFunctionProps) => ({
|
||||||
bg: "brand.patreon",
|
bg: "brand.patreon",
|
||||||
@@ -166,12 +166,12 @@ const buttonStyles = {
|
|||||||
bg: mode(
|
bg: mode(
|
||||||
whiten("brand.patreon", 20),
|
whiten("brand.patreon", 20),
|
||||||
darken("brand.patreon", 20)
|
darken("brand.patreon", 20)
|
||||||
)(props),
|
)(props)
|
||||||
},
|
}
|
||||||
}),
|
})
|
||||||
},
|
},
|
||||||
// default values for `size` and `variant`
|
// default values for `size` and `variant`
|
||||||
defaultProps: {},
|
defaultProps: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
export default buttonStyles;
|
export default buttonStyles;
|
||||||
|
|||||||
@@ -7,14 +7,18 @@ interface BackToTopButtonProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const BackToTopButton: FC<BackToTopButtonProps> = ({
|
const BackToTopButton: FC<BackToTopButtonProps> = ({
|
||||||
show,
|
show
|
||||||
}: BackToTopButtonProps) => {
|
}: BackToTopButtonProps) => {
|
||||||
return (
|
return (
|
||||||
<Flex
|
<Flex
|
||||||
d={show ? "flex" : "none"}
|
d={show ? "flex" : "none"}
|
||||||
pos="fixed"
|
pos="fixed"
|
||||||
top="85vh"
|
top="85vh"
|
||||||
right={{ base: "1.25rem", sm: "2rem", md: "3rem" }}
|
right={{
|
||||||
|
base: "1.25rem",
|
||||||
|
sm: "2rem",
|
||||||
|
md: "3rem"
|
||||||
|
}}
|
||||||
>
|
>
|
||||||
<Link href="/#top">
|
<Link href="/#top">
|
||||||
<Button variant="backToTop">
|
<Button variant="backToTop">
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import {
|
|||||||
HStack,
|
HStack,
|
||||||
// Image,
|
// Image,
|
||||||
Button,
|
Button,
|
||||||
BoxProps,
|
BoxProps
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import { Icon } from "@iconify/react";
|
import { Icon } from "@iconify/react";
|
||||||
// import BackToTopButton from "./BackToTopButton";
|
// import BackToTopButton from "./BackToTopButton";
|
||||||
|
|||||||
@@ -1,19 +1,21 @@
|
|||||||
import React, { useEffect, useRef, useState } from "react";
|
import React, { useEffect, useRef, useState } from "react";
|
||||||
|
import Image from "next/image";
|
||||||
import {
|
import {
|
||||||
Heading,
|
Heading,
|
||||||
HStack,
|
HStack,
|
||||||
Box,
|
Box,
|
||||||
IconButton,
|
IconButton,
|
||||||
Menu,
|
Menu,
|
||||||
MenuButton,
|
MenuButton
|
||||||
} 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";
|
||||||
|
import appLogo from "../../public/images/logo.svg";
|
||||||
|
|
||||||
const Header = (): JSX.Element => {
|
const Header = (): JSX.Element => {
|
||||||
const appName = "LCM Potty Chart";
|
const appName = "LCM Potty Chart";
|
||||||
const appVersion = "v0.0.5.2-pre-alpha";
|
const appVersion = "v0.0.6.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);
|
||||||
@@ -54,7 +56,7 @@ const Header = (): JSX.Element => {
|
|||||||
const iconType = {
|
const iconType = {
|
||||||
default: <Icon icon="bx:bx-menu-alt-right" />,
|
default: <Icon icon="bx:bx-menu-alt-right" />,
|
||||||
hover: <Icon icon="bx:bx-menu" />,
|
hover: <Icon icon="bx:bx-menu" />,
|
||||||
open: <Icon icon="bx:bx-x" />,
|
open: <Icon icon="bx:bx-x" />
|
||||||
};
|
};
|
||||||
|
|
||||||
if (open) {
|
if (open) {
|
||||||
@@ -91,14 +93,17 @@ const Header = (): JSX.Element => {
|
|||||||
bg: "brand.main",
|
bg: "brand.main",
|
||||||
boxShadow: open
|
boxShadow: open
|
||||||
? "none"
|
? "none"
|
||||||
: "rgba(0, 134, 255, 0.9) 0px 0px 15px, rgba(0, 134, 255, 0.7) 0px 0px 3px 1px",
|
: "rgba(0, 134, 255, 0.9) 0px 0px 15px, rgba(0, 134, 255, 0.7) 0px 0px 3px 1px"
|
||||||
}}
|
}}
|
||||||
h={open ? "125px" : "auto"}
|
h={open ? "125px" : "auto"}
|
||||||
>
|
>
|
||||||
{/* Logo | Site Name */}
|
{/* Logo | Site Name */}
|
||||||
<HStack
|
<HStack
|
||||||
width="100%"
|
width="100%"
|
||||||
justifyContent={{ base: "flex-start", sm: "center" }}
|
justifyContent={{
|
||||||
|
base: "flex-start",
|
||||||
|
sm: "center"
|
||||||
|
}}
|
||||||
alignItems="center"
|
alignItems="center"
|
||||||
height={12}
|
height={12}
|
||||||
top={0}
|
top={0}
|
||||||
@@ -107,9 +112,11 @@ const Header = (): JSX.Element => {
|
|||||||
d={{ base: "flex", lg: "none" }}
|
d={{ base: "flex", lg: "none" }}
|
||||||
spacing="5px"
|
spacing="5px"
|
||||||
_hover={{
|
_hover={{
|
||||||
cursor: "default",
|
cursor: "default"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
<Image height="30px" width="30px" src={appLogo} alt="App Logo" />
|
||||||
|
|
||||||
<Heading as="h1" size="md">
|
<Heading as="h1" size="md">
|
||||||
{appName}
|
{appName}
|
||||||
</Heading>
|
</Heading>
|
||||||
@@ -140,9 +147,10 @@ const Header = (): JSX.Element => {
|
|||||||
height="auto"
|
height="auto"
|
||||||
spacing="5px"
|
spacing="5px"
|
||||||
_hover={{
|
_hover={{
|
||||||
cursor: "default",
|
cursor: "default"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
<Image height="30px" width="30px" src={appLogo} alt="App Logo" />
|
||||||
<Heading as="h1" size="md">
|
<Heading as="h1" size="md">
|
||||||
{appName}
|
{appName}
|
||||||
</Heading>
|
</Heading>
|
||||||
@@ -161,7 +169,10 @@ const Header = (): JSX.Element => {
|
|||||||
onClick={() => setOpen(!open)}
|
onClick={() => setOpen(!open)}
|
||||||
onMouseEnter={() => setHover(true)}
|
onMouseEnter={() => setHover(true)}
|
||||||
onMouseLeave={() => setHover(false)}
|
onMouseLeave={() => setHover(false)}
|
||||||
d={{ base: "inline-flex", lg: "none" }}
|
d={{
|
||||||
|
base: "inline-flex",
|
||||||
|
lg: "none"
|
||||||
|
}}
|
||||||
variant="mobileNav"
|
variant="mobileNav"
|
||||||
bg={transparentNavbar ? "transparent" : "rgba(255, 255, 255, .15)"}
|
bg={transparentNavbar ? "transparent" : "rgba(255, 255, 255, .15)"}
|
||||||
type="button"
|
type="button"
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import {
|
|||||||
Link,
|
Link,
|
||||||
MenuDivider,
|
MenuDivider,
|
||||||
MenuItem,
|
MenuItem,
|
||||||
MenuList,
|
MenuList
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import navItems, { NavItem } from "./navItems";
|
import navItems, { NavItem } from "./navItems";
|
||||||
|
|
||||||
@@ -33,10 +33,10 @@ const MobileNav: FC<MobileNavProps> = ({ updateOpen }: MobileNavProps) => {
|
|||||||
h="auto"
|
h="auto"
|
||||||
p={0}
|
p={0}
|
||||||
_hover={{
|
_hover={{
|
||||||
backgroundColor: "none",
|
backgroundColor: "none"
|
||||||
}}
|
}}
|
||||||
_focus={{
|
_focus={{
|
||||||
backgroundColor: "none",
|
backgroundColor: "none"
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<Link onClick={() => updateOpen(false)} href={navItem[1]}>
|
<Link onClick={() => updateOpen(false)} href={navItem[1]}>
|
||||||
|
|||||||
Reference in New Issue
Block a user