Redux #60
@@ -1,262 +0,0 @@
|
|||||||
import React, { createContext, useState, ReactNode } from "react";
|
|
||||||
import {
|
|
||||||
format,
|
|
||||||
startOfMonth,
|
|
||||||
endOfMonth,
|
|
||||||
getDate,
|
|
||||||
add,
|
|
||||||
sub,
|
|
||||||
set,
|
|
||||||
isAfter,
|
|
||||||
isBefore,
|
|
||||||
compareAsc
|
|
||||||
} from "date-fns";
|
|
||||||
|
|
||||||
const CalenderContext = createContext({} as CalenderContextState);
|
|
||||||
|
|
||||||
const CalenderContextProvider = ({
|
|
||||||
children
|
|
||||||
}: {
|
|
||||||
children: ReactNode;
|
|
||||||
}): JSX.Element => {
|
|
||||||
const weekDays: WeekDays = {
|
|
||||||
sunday: [
|
|
||||||
"Sunday",
|
|
||||||
"Monday",
|
|
||||||
"Tuesday",
|
|
||||||
"Wednesday",
|
|
||||||
"Thursday",
|
|
||||||
"Friday",
|
|
||||||
"Saturday"
|
|
||||||
],
|
|
||||||
monday: [
|
|
||||||
"Monday",
|
|
||||||
"Tuesday",
|
|
||||||
"Wednesday",
|
|
||||||
"Thursday",
|
|
||||||
"Friday",
|
|
||||||
"Saturday",
|
|
||||||
"Sunday"
|
|
||||||
]
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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;
|
|
||||||
|
|
||||||
const start = startOfMonth(selectedDate);
|
|
||||||
const end = endOfMonth(selectedDate);
|
|
||||||
|
|
||||||
if (isBefore(currDate, start)) {
|
|
||||||
flag = true;
|
|
||||||
direction = "prev";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isAfter(currDate, end)) {
|
|
||||||
flag = true;
|
|
||||||
direction = "next";
|
|
||||||
}
|
|
||||||
|
|
||||||
return { isOverflow: flag, overflowDirection: direction };
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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");
|
|
||||||
|
|
||||||
const ISOToIndex = {
|
|
||||||
sunday: {
|
|
||||||
Sun: 0,
|
|
||||||
Mon: 1,
|
|
||||||
Tue: 2,
|
|
||||||
Wed: 3,
|
|
||||||
Thu: 4,
|
|
||||||
Fri: 5,
|
|
||||||
Sat: 6
|
|
||||||
},
|
|
||||||
monday: {
|
|
||||||
Mon: -1,
|
|
||||||
Tue: 0,
|
|
||||||
Wed: 1,
|
|
||||||
Thu: 2,
|
|
||||||
Fri: 3,
|
|
||||||
Sat: 4,
|
|
||||||
Sun: 5
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const sundays = {
|
|
||||||
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 sunStartDay =
|
|
||||||
endLastMonth - (ISOToIndex.sunday[startOfSelectedMonth] - 1);
|
|
||||||
|
|
||||||
let sunCurrDate = set(sub(selectedDate, { months: 1 }), {
|
|
||||||
date: sunStartDay
|
|
||||||
});
|
|
||||||
|
|
||||||
for (const week in sundays) {
|
|
||||||
const thisWeek = sundays[week];
|
|
||||||
|
|
||||||
thisWeek.forEach((e, i) => {
|
|
||||||
const overflowInfo = isOverflow(selectedDate, sunCurrDate);
|
|
||||||
|
|
||||||
const day: MonthDay = {
|
|
||||||
...overflowInfo,
|
|
||||||
date: sunCurrDate
|
|
||||||
};
|
|
||||||
|
|
||||||
sunCurrDate = add(sunCurrDate, {
|
|
||||||
days: 1
|
|
||||||
});
|
|
||||||
|
|
||||||
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, monCurrDate);
|
|
||||||
|
|
||||||
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
const [selectedDate, setSelectedDate] = useState<Date>(new Date());
|
|
||||||
const [selectedDateInfo, setSelectedMonthInfo] = useState<MonthContext>({
|
|
||||||
date: selectedDate,
|
|
||||||
title: format(selectedDate, "LLLL uuuu"),
|
|
||||||
layout: populateMonth(selectedDate)
|
|
||||||
});
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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 function that validated if a date has at least one sticker in it. Use that within the nav function (when filter is enabled).
|
|
||||||
|
|
||||||
// TODO: Add a function that will give the closest date, if available, when the nav func detects an empty month.
|
|
||||||
// Use the chart creation date to aid with this. (When filter is enabled)
|
|
||||||
|
|
||||||
/**
|
|
||||||
* TODO: Add logic that prevents navigation to the future and too far in the past. (Use chart creation date)
|
|
||||||
* Update to use a promise and return appropriate errors. Display those errors on the front end.
|
|
||||||
* Update the use of this function on the front to handle the fails of the promise.
|
|
||||||
*/
|
|
||||||
|
|
||||||
// TODO: (When filter is enabled) Update the calender update function that will take in a direction so that the the navigation buttons will take the user to the next month with stickers. Assuming there was a gap with empty months.
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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;
|
|
||||||
|
|
||||||
if (!year || !inputMonth || day < 0 || day > 31) {
|
|
||||||
return false;
|
|
||||||
} else {
|
|
||||||
const month = inputMonth - 1;
|
|
||||||
const customDate: Date = new Date(year, month, day);
|
|
||||||
|
|
||||||
if (compareAsc(customDate, selectedDate) !== 0) {
|
|
||||||
setSelectedDate(customDate);
|
|
||||||
updateDateInfo(customDate);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// * Attempting to fix an issue with static generation where the date does not appear to be updating after initial generation.
|
|
||||||
const [currDate, setCurrDate] = useState<Date>(new Date());
|
|
||||||
|
|
||||||
const calenderContextValues: CalenderContextState = {
|
|
||||||
currDate,
|
|
||||||
setCurrDate,
|
|
||||||
selectedDate,
|
|
||||||
title: selectedDateInfo.title,
|
|
||||||
layout: selectedDateInfo.layout,
|
|
||||||
updateDate
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<CalenderContext.Provider value={calenderContextValues}>
|
|
||||||
{children}
|
|
||||||
</CalenderContext.Provider>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export { CalenderContextProvider, CalenderContext };
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
import React, { createContext, useState, ReactNode } from "react";
|
|
||||||
import { format, getDate, isSameDay } from "date-fns";
|
|
||||||
import stickersSeeder from "../data/stickerSeeder";
|
|
||||||
|
|
||||||
const StickersContext = createContext({} as StickersContextState);
|
|
||||||
|
|
||||||
const StickersContextProvider = ({
|
|
||||||
children
|
|
||||||
}: {
|
|
||||||
children: ReactNode;
|
|
||||||
}): JSX.Element => {
|
|
||||||
const [stickersMonth, setStickersMonth] = useState<StickerDays>(
|
|
||||||
stickersSeeder()
|
|
||||||
);
|
|
||||||
|
|
||||||
// TODO: Add stickers functions here. (Add and edit stickers).
|
|
||||||
const addEditSticker = (date: Date, sticker: ValidStickerVal): Sticker => {
|
|
||||||
const newStickersMonth = stickersMonth.slice();
|
|
||||||
const index = getDate(date) - 1;
|
|
||||||
const currDate = newStickersMonth[index];
|
|
||||||
|
|
||||||
const edited = currDate.edited
|
|
||||||
? true
|
|
||||||
: isSameDay(currDate.date, new Date())
|
|
||||||
? false
|
|
||||||
: true;
|
|
||||||
currDate.edited = edited;
|
|
||||||
// Add manual here when necessary.
|
|
||||||
|
|
||||||
const id = format(date, "yyyyddLL") + sticker;
|
|
||||||
|
|
||||||
const newSticker: Sticker = {
|
|
||||||
id: id,
|
|
||||||
date: date,
|
|
||||||
sticker: sticker,
|
|
||||||
edited: edited,
|
|
||||||
manual: false
|
|
||||||
};
|
|
||||||
|
|
||||||
newStickersMonth[index] = newSticker;
|
|
||||||
|
|
||||||
setStickersMonth(newStickersMonth.slice());
|
|
||||||
|
|
||||||
return newSticker;
|
|
||||||
};
|
|
||||||
|
|
||||||
// TODO: Add stickers validation function here.
|
|
||||||
|
|
||||||
const stickersContextValues = {
|
|
||||||
stickersMonth,
|
|
||||||
addEditSticker
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<StickersContext.Provider value={stickersContextValues}>
|
|
||||||
{children}
|
|
||||||
</StickersContext.Provider>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export { StickersContextProvider, StickersContext };
|
|
||||||
@@ -1,11 +1,15 @@
|
|||||||
import { format, getDaysInMonth, isBefore, setDate } from "date-fns";
|
import {
|
||||||
|
format,
|
||||||
|
getDaysInMonth,
|
||||||
|
isBefore,
|
||||||
|
setDate,
|
||||||
|
startOfDay
|
||||||
|
} from "date-fns";
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This seeder is to simulate the date and sticker info from the database.
|
* Generated a valid sticker value for use when generating a sticker obj.
|
||||||
* Filling up an array for the current month with sticker from ths first to
|
* @returns {ValidStickerVal} a number that will represent a valid sticker value.
|
||||||
* the day before the current date, leaving the rest of the month empty.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const generateSticker = (): -2 | -1 | 0 | 1 | 2 => {
|
const generateSticker = (): -2 | -1 | 0 | 1 | 2 => {
|
||||||
const sticker = Math.floor(Math.random() * (2 - -2 + 1)) + -2;
|
const sticker = Math.floor(Math.random() * (2 - -2 + 1)) + -2;
|
||||||
|
|
||||||
@@ -20,10 +24,16 @@ const generateSticker = (): -2 | -1 | 0 | 1 | 2 => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This seeder is to simulate the date and sticker info from the database.
|
||||||
|
* Filling up an array for the current month with sticker from ths first to
|
||||||
|
* the day before the current date, leaving the rest of the month empty.
|
||||||
|
* @returns {StickerDays} an array with populated sticker objects that correspond to the current month's info.
|
||||||
|
*/
|
||||||
const stickersSeeder = (): StickerDays => {
|
const stickersSeeder = (): StickerDays => {
|
||||||
const stickers = [] as Sticker[];
|
const stickers = [] as Sticker[];
|
||||||
|
|
||||||
const now = new Date();
|
const now = startOfDay(new Date());
|
||||||
const daysOfThisMonth = getDaysInMonth(now);
|
const daysOfThisMonth = getDaysInMonth(now);
|
||||||
|
|
||||||
for (let i = 1; i <= daysOfThisMonth; i++) {
|
for (let i = 1; i <= daysOfThisMonth; i++) {
|
||||||
@@ -36,7 +46,7 @@ const stickersSeeder = (): StickerDays => {
|
|||||||
|
|
||||||
const newSticker: Sticker = {
|
const newSticker: Sticker = {
|
||||||
id: id,
|
id: id,
|
||||||
date: currDate,
|
date: currDate.toJSON(),
|
||||||
sticker: sticker,
|
sticker: sticker,
|
||||||
edited: false,
|
edited: false,
|
||||||
manual: false
|
manual: false
|
||||||
|
|||||||
179
lib/populateMonth.ts
Normal file
179
lib/populateMonth.ts
Normal file
@@ -0,0 +1,179 @@
|
|||||||
|
import {
|
||||||
|
getDate,
|
||||||
|
endOfMonth,
|
||||||
|
format,
|
||||||
|
startOfMonth,
|
||||||
|
set,
|
||||||
|
isAfter,
|
||||||
|
isBefore,
|
||||||
|
subMonths,
|
||||||
|
addDays
|
||||||
|
} from "date-fns";
|
||||||
|
|
||||||
|
const weekDays: WeekDays = {
|
||||||
|
sunday: [
|
||||||
|
"Sunday",
|
||||||
|
"Monday",
|
||||||
|
"Tuesday",
|
||||||
|
"Wednesday",
|
||||||
|
"Thursday",
|
||||||
|
"Friday",
|
||||||
|
"Saturday"
|
||||||
|
],
|
||||||
|
monday: [
|
||||||
|
"Monday",
|
||||||
|
"Tuesday",
|
||||||
|
"Wednesday",
|
||||||
|
"Thursday",
|
||||||
|
"Friday",
|
||||||
|
"Saturday",
|
||||||
|
"Sunday"
|
||||||
|
]
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
const start = startOfMonth(selectedDate);
|
||||||
|
const end = endOfMonth(selectedDate);
|
||||||
|
|
||||||
|
if (isBefore(currDate, start)) {
|
||||||
|
flag = true;
|
||||||
|
direction = "prev";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isAfter(currDate, end)) {
|
||||||
|
flag = true;
|
||||||
|
direction = "next";
|
||||||
|
}
|
||||||
|
|
||||||
|
return { isOverflow: flag, overflowDirection: direction };
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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.
|
||||||
|
* @returns The month layout object for the provided month.
|
||||||
|
*/
|
||||||
|
const populateMonth = (selectedDate: Date): MonthLayout => {
|
||||||
|
const endLastMonth = getDate(endOfMonth(subMonths(selectedDate, 1)));
|
||||||
|
const startOfSelectedMonth = format(startOfMonth(selectedDate), "iii");
|
||||||
|
|
||||||
|
const ISOToIndex = {
|
||||||
|
sunday: {
|
||||||
|
Sun: 0,
|
||||||
|
Mon: 1,
|
||||||
|
Tue: 2,
|
||||||
|
Wed: 3,
|
||||||
|
Thu: 4,
|
||||||
|
Fri: 5,
|
||||||
|
Sat: 6
|
||||||
|
},
|
||||||
|
monday: {
|
||||||
|
Mon: -1,
|
||||||
|
Tue: 0,
|
||||||
|
Wed: 1,
|
||||||
|
Thu: 2,
|
||||||
|
Fri: 3,
|
||||||
|
Sat: 4,
|
||||||
|
Sun: 5
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const sundays = {
|
||||||
|
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)
|
||||||
|
};
|
||||||
|
|
||||||
|
// The date of the first day in the overflow
|
||||||
|
const sunStartDay =
|
||||||
|
endLastMonth - (ISOToIndex.sunday[startOfSelectedMonth] - 1);
|
||||||
|
|
||||||
|
let sunCurrDate = set(subMonths(selectedDate, 1), {
|
||||||
|
date: sunStartDay
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const week in sundays) {
|
||||||
|
const thisWeek = sundays[week];
|
||||||
|
|
||||||
|
thisWeek.forEach((e, i) => {
|
||||||
|
const overflowInfo = isOverflow(selectedDate, sunCurrDate);
|
||||||
|
|
||||||
|
const day: MonthDay = {
|
||||||
|
...overflowInfo,
|
||||||
|
date: sunCurrDate.toJSON()
|
||||||
|
};
|
||||||
|
|
||||||
|
sunCurrDate = addDays(sunCurrDate, 1);
|
||||||
|
|
||||||
|
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)
|
||||||
|
};
|
||||||
|
|
||||||
|
// The date of the first day in the overflow
|
||||||
|
const monStartDay = endLastMonth - ISOToIndex.monday[startOfSelectedMonth];
|
||||||
|
|
||||||
|
let monCurrDate = set(subMonths(selectedDate, 1), {
|
||||||
|
date: monStartDay
|
||||||
|
});
|
||||||
|
|
||||||
|
for (const week in mondays) {
|
||||||
|
const thisWeek = mondays[week];
|
||||||
|
|
||||||
|
thisWeek.forEach((e, i) => {
|
||||||
|
const overflowInfo = isOverflow(selectedDate, monCurrDate);
|
||||||
|
|
||||||
|
const day: MonthDay = {
|
||||||
|
...overflowInfo,
|
||||||
|
date: monCurrDate.toJSON()
|
||||||
|
};
|
||||||
|
|
||||||
|
monCurrDate = addDays(monCurrDate, 1);
|
||||||
|
|
||||||
|
mondays[week][i] = day;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
const output = {
|
||||||
|
sunday: {
|
||||||
|
weekdays: weekDays.sunday,
|
||||||
|
month: sundays
|
||||||
|
},
|
||||||
|
monday: {
|
||||||
|
weekdays: weekDays.monday,
|
||||||
|
month: mondays
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return output;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default populateMonth;
|
||||||
25
package.json
25
package.json
@@ -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.9.11-alpha",
|
"version": "v0.0.10-alpha",
|
||||||
"author": {
|
"author": {
|
||||||
"name": "Lucid Creations Media",
|
"name": "Lucid Creations Media",
|
||||||
"url": "https://lucidcreations.media",
|
"url": "https://lucidcreations.media",
|
||||||
@@ -16,29 +16,32 @@
|
|||||||
"pretty": "prettier --write ."
|
"pretty": "prettier --write ."
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@chakra-ui/react": "^2.1.2",
|
"@chakra-ui/react": "^2.2.1",
|
||||||
"@emotion/react": "^11.9.0",
|
"@emotion/react": "^11.9.3",
|
||||||
"@emotion/styled": "^11.8.1",
|
"@emotion/styled": "^11.9.3",
|
||||||
"@iconify/react": "^3.2.2",
|
"@iconify/react": "^3.2.2",
|
||||||
|
"@reduxjs/toolkit": "^1.8.2",
|
||||||
"date-fns": "^2.28.0",
|
"date-fns": "^2.28.0",
|
||||||
"formik": "^2.2.9",
|
"formik": "^2.2.9",
|
||||||
"framer-motion": "^6.3.10",
|
"framer-motion": "^6.3.11",
|
||||||
"next": "12.1.6",
|
"next": "12.1.6",
|
||||||
"react": "^18.1.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.1.0",
|
"react-dom": "^18.2.0",
|
||||||
|
"react-redux": "^8.0.2",
|
||||||
"sharp": "^0.30.6"
|
"sharp": "^0.30.6"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/node": "^17.0.40",
|
"@types/node": "^17.0.42",
|
||||||
"@types/react": "^18.0.12",
|
"@types/react": "^18.0.12",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.27.0",
|
"@types/react-redux": "^7.1.24",
|
||||||
|
"@typescript-eslint/eslint-plugin": "<5.28.0",
|
||||||
"eslint": "^8.17.0",
|
"eslint": "^8.17.0",
|
||||||
"eslint-config-next": "^12.1.6",
|
"eslint-config-next": "^12.1.6",
|
||||||
"eslint-config-prettier": "^8.5.0",
|
"eslint-config-prettier": "^8.5.0",
|
||||||
"eslint-plugin-jsx-a11y": "^6.5.1",
|
"eslint-plugin-jsx-a11y": "^6.5.1",
|
||||||
"eslint-plugin-react": "^7.30.0",
|
"eslint-plugin-react": "^7.30.0",
|
||||||
"eslint-plugin-react-hooks": "^4.5.0",
|
"eslint-plugin-react-hooks": "<4.6.0",
|
||||||
"prettier": "^2.6.2",
|
"prettier": "^2.7.0",
|
||||||
"typescript": "^4.7.3"
|
"typescript": "^4.7.3"
|
||||||
},
|
},
|
||||||
"resolutions": {
|
"resolutions": {
|
||||||
|
|||||||
5
src/app/hooks.ts
Normal file
5
src/app/hooks.ts
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
import { TypedUseSelectorHook, useDispatch, useSelector } from "react-redux";
|
||||||
|
import { RootState, AppDispatch } from "./store";
|
||||||
|
|
||||||
|
export const useAppDispatch = () => useDispatch<AppDispatch>();
|
||||||
|
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
|
||||||
13
src/app/store.ts
Normal file
13
src/app/store.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import { configureStore } from "@reduxjs/toolkit";
|
||||||
|
import calenderReducer from "../features/calender/calender";
|
||||||
|
import stickersReducer from "../features/calender/stickers";
|
||||||
|
|
||||||
|
export const store = configureStore({
|
||||||
|
reducer: {
|
||||||
|
calender: calenderReducer,
|
||||||
|
stickers: stickersReducer
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export type AppDispatch = typeof store.dispatch;
|
||||||
|
export type RootState = ReturnType<typeof store.getState>;
|
||||||
@@ -1,14 +1,19 @@
|
|||||||
import React, { useContext } from "react";
|
import React from "react";
|
||||||
import { useRouter } from "next/router";
|
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 { format, isSameMonth, addMonths, subMonths } from "date-fns";
|
import { format, isSameMonth, addMonths, subMonths } from "date-fns";
|
||||||
import findValidDateRange from "../../../lib/findValidDateRange";
|
import findValidDateRange from "../../../lib/findValidDateRange";
|
||||||
import DatePicker from "./DatePicker";
|
import DatePicker from "./DatePicker";
|
||||||
import { CalenderContext } from "../../../contexts/CalenderContext";
|
import { useAppSelector } from "../../app/hooks";
|
||||||
|
|
||||||
const CalenderNav = (): JSX.Element => {
|
const CalenderNav = (): JSX.Element => {
|
||||||
const { selectedDate } = useContext(CalenderContext);
|
const selectedDate = useAppSelector(
|
||||||
|
(state) => state.calender.selectedDateInfo
|
||||||
|
);
|
||||||
|
const { date } = selectedDate;
|
||||||
|
|
||||||
|
const selectedDateObj = new Date(date);
|
||||||
|
|
||||||
const validDateRange = findValidDateRange();
|
const validDateRange = findValidDateRange();
|
||||||
const { start: validStart, end: validEnd } = validDateRange;
|
const { start: validStart, end: validEnd } = validDateRange;
|
||||||
@@ -17,14 +22,14 @@ const CalenderNav = (): JSX.Element => {
|
|||||||
|
|
||||||
const handleNavButtons = (direction: "next" | "prev") => {
|
const handleNavButtons = (direction: "next" | "prev") => {
|
||||||
if (direction === "next") {
|
if (direction === "next") {
|
||||||
const newMonth = addMonths(selectedDate, 1);
|
const newMonth = addMonths(selectedDateObj, 1);
|
||||||
|
|
||||||
const year = format(newMonth, "y");
|
const year = format(newMonth, "y");
|
||||||
const month = format(newMonth, "L");
|
const month = format(newMonth, "L");
|
||||||
|
|
||||||
router.push(`/calendar/${year}/${month}`);
|
router.push(`/calendar/${year}/${month}`);
|
||||||
} else if (direction === "prev") {
|
} else if (direction === "prev") {
|
||||||
const newMonth = subMonths(selectedDate, 1);
|
const newMonth = subMonths(selectedDateObj, 1);
|
||||||
|
|
||||||
const year = format(newMonth, "y");
|
const year = format(newMonth, "y");
|
||||||
const month = format(newMonth, "L");
|
const month = format(newMonth, "L");
|
||||||
@@ -36,14 +41,14 @@ const CalenderNav = (): JSX.Element => {
|
|||||||
return (
|
return (
|
||||||
<HStack spacing={10} as="nav" w="auto" h="10vh" textAlign="center">
|
<HStack spacing={10} as="nav" w="auto" h="10vh" textAlign="center">
|
||||||
<IconButton
|
<IconButton
|
||||||
isDisabled={isSameMonth(selectedDate, validStart)}
|
isDisabled={isSameMonth(selectedDateObj, validStart)}
|
||||||
aria-label="Previous Month"
|
aria-label="Previous Month"
|
||||||
icon={<Icon icon="akar-icons:chevron-left" />}
|
icon={<Icon icon="akar-icons:chevron-left" />}
|
||||||
onClick={() => handleNavButtons("prev")}
|
onClick={() => handleNavButtons("prev")}
|
||||||
/>
|
/>
|
||||||
<DatePicker />
|
<DatePicker />
|
||||||
<IconButton
|
<IconButton
|
||||||
isDisabled={isSameMonth(selectedDate, validEnd)}
|
isDisabled={isSameMonth(selectedDateObj, validEnd)}
|
||||||
aria-label="Next Month"
|
aria-label="Next Month"
|
||||||
icon={<Icon icon="akar-icons:chevron-right" />}
|
icon={<Icon icon="akar-icons:chevron-right" />}
|
||||||
onClick={() => handleNavButtons("next")}
|
onClick={() => handleNavButtons("next")}
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
import React, { useContext, useRef, useState } from "react";
|
import React, { useRef, useState } from "react";
|
||||||
import { useRouter } from "next/router";
|
import { useRouter } from "next/router";
|
||||||
import {
|
import {
|
||||||
Button,
|
Button,
|
||||||
@@ -27,10 +27,12 @@ import {
|
|||||||
import { format } from "date-fns";
|
import { format } from "date-fns";
|
||||||
import findValidDateRange from "../../../lib/findValidDateRange";
|
import findValidDateRange from "../../../lib/findValidDateRange";
|
||||||
import FormValidateEmoji from "./FormValidateEmoji";
|
import FormValidateEmoji from "./FormValidateEmoji";
|
||||||
import { CalenderContext } from "../../../contexts/CalenderContext";
|
import { useAppSelector } from "../../app/hooks";
|
||||||
|
|
||||||
const DatePicker = (): JSX.Element => {
|
const DatePicker = (): JSX.Element => {
|
||||||
const { title } = useContext(CalenderContext);
|
const selectedDate = useAppSelector(
|
||||||
|
(state) => state.calender.selectedDateInfo
|
||||||
|
);
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
|
|
||||||
@@ -129,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">
|
||||||
{title}
|
{selectedDate.title}
|
||||||
</Heading>
|
</Heading>
|
||||||
</Button>
|
</Button>
|
||||||
</PopoverTrigger>
|
</PopoverTrigger>
|
||||||
|
|||||||
@@ -10,49 +10,54 @@ import {
|
|||||||
} from "date-fns";
|
} from "date-fns";
|
||||||
import router from "next/router";
|
import router from "next/router";
|
||||||
import React, { Fragment, useState } from "react";
|
import React, { Fragment, useState } from "react";
|
||||||
import { StickersContextProvider } from "../../../contexts/StickerContext";
|
|
||||||
import AddUpdateSticker from "./modals/AddUpdateSticker";
|
import AddUpdateSticker from "./modals/AddUpdateSticker";
|
||||||
import DemoStickers from "./stickers/DemoStickers";
|
import DemoStickers from "./stickers/DemoStickers";
|
||||||
|
import { Provider } from "react-redux";
|
||||||
|
import { store } from "../../app/store";
|
||||||
|
|
||||||
interface DayProps {
|
interface DayProps {
|
||||||
isOverflow?: boolean;
|
isOverflow?: boolean;
|
||||||
overflowDirection?: "next" | "prev" | null;
|
overflowDirection?: "next" | "prev" | null;
|
||||||
sticker: StickerVal;
|
currSticker: StickerVal;
|
||||||
date: Date;
|
date: string;
|
||||||
selectedDate: Date;
|
selectedDate: string;
|
||||||
currDate: Date;
|
currDate: Date;
|
||||||
isToday: boolean;
|
isToday: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The individual days in the calender component.
|
* The individual days in the calender component.
|
||||||
* @param props the props for this component.
|
* @param {boolean} isOverflow is the current date being given before or after the current month.
|
||||||
* @param {boolean} props.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} props.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} props.sticker the sticker for this date.
|
* @param {date} date the date for this day.
|
||||||
* @param {date} props.date the date for this day.
|
* @param {date} selectedDate the date for the selected month.
|
||||||
* @param {date} props.selectedDate the date for the selected month.
|
* @param {Date} currDate today's date.
|
||||||
|
* @param {boolean} isToday is the current iteration of this component in today's date.
|
||||||
*/
|
*/
|
||||||
const Day = ({
|
const Day = ({
|
||||||
isOverflow,
|
isOverflow,
|
||||||
overflowDirection,
|
overflowDirection,
|
||||||
sticker,
|
currSticker,
|
||||||
date,
|
date,
|
||||||
selectedDate,
|
selectedDate,
|
||||||
currDate,
|
currDate,
|
||||||
isToday
|
isToday
|
||||||
}: DayProps): JSX.Element => {
|
}: DayProps): JSX.Element => {
|
||||||
|
const selectedDateObj = new Date(selectedDate);
|
||||||
|
const currDateObj = new Date(date);
|
||||||
|
|
||||||
const handleNav = (direction: "next" | "prev") => {
|
const handleNav = (direction: "next" | "prev") => {
|
||||||
if (direction === "next") {
|
if (direction === "next") {
|
||||||
console.log(overflowDirection);
|
console.log(overflowDirection);
|
||||||
const newMonth = add(selectedDate, { months: 1 });
|
const newMonth = add(selectedDateObj, { months: 1 });
|
||||||
|
|
||||||
const year = getYear(newMonth);
|
const year = getYear(newMonth);
|
||||||
const month = getMonth(newMonth) + 1;
|
const month = getMonth(newMonth) + 1;
|
||||||
|
|
||||||
router.push(`/calendar/${year}/${month}`);
|
router.push(`/calendar/${year}/${month}`);
|
||||||
} else if (direction === "prev") {
|
} else if (direction === "prev") {
|
||||||
const newMonth = sub(selectedDate, { months: 1 });
|
const newMonth = sub(selectedDateObj, { months: 1 });
|
||||||
|
|
||||||
const year = getYear(newMonth);
|
const year = getYear(newMonth);
|
||||||
const month = getMonth(newMonth) + 1;
|
const month = getMonth(newMonth) + 1;
|
||||||
@@ -64,10 +69,6 @@ const Day = ({
|
|||||||
// This handles the modal for the day.
|
// This handles the modal for the day.
|
||||||
const [isOpen, setIsOpen] = useState<boolean>(false);
|
const [isOpen, setIsOpen] = useState<boolean>(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<StickerVal>(sticker);
|
|
||||||
|
|
||||||
// The step the modal is at.
|
// The step the modal is at.
|
||||||
const [step, setStep] = useState<number>(0);
|
const [step, setStep] = useState<number>(0);
|
||||||
|
|
||||||
@@ -93,7 +94,9 @@ const Day = ({
|
|||||||
w="100%"
|
w="100%"
|
||||||
h="100%"
|
h="100%"
|
||||||
_hover={{
|
_hover={{
|
||||||
cursor: isBefore(date, endOfDay(currDate)) ? "pointer" : "default",
|
cursor: isBefore(currDateObj, endOfDay(currDate))
|
||||||
|
? "pointer"
|
||||||
|
: "default",
|
||||||
background: "gray.700",
|
background: "gray.700",
|
||||||
border: "1px solid #FFF",
|
border: "1px solid #FFF",
|
||||||
color: "whiteAlpha.900"
|
color: "whiteAlpha.900"
|
||||||
@@ -105,15 +108,10 @@ const Day = ({
|
|||||||
pt={2}
|
pt={2}
|
||||||
>
|
>
|
||||||
<Text w="auto" h="auto">
|
<Text w="auto" h="auto">
|
||||||
{`${getDate(date)}`}
|
{`${getDate(currDateObj)}`}
|
||||||
</Text>
|
</Text>
|
||||||
<Box
|
<Box key={currSticker} fontSize="1.5rem">
|
||||||
key={stickerState === null ? Math.random() : stickerState}
|
<DemoStickers stickerVal={currSticker} />
|
||||||
fontSize="1.5rem"
|
|
||||||
>
|
|
||||||
<DemoStickers
|
|
||||||
stickerVal={stickerState === null ? null : stickerState}
|
|
||||||
/>
|
|
||||||
</Box>
|
</Box>
|
||||||
</VStack>
|
</VStack>
|
||||||
)}
|
)}
|
||||||
@@ -132,7 +130,9 @@ const Day = ({
|
|||||||
justifyContent="flex-start"
|
justifyContent="flex-start"
|
||||||
pt={2}
|
pt={2}
|
||||||
_hover={{
|
_hover={{
|
||||||
cursor: isBefore(date, endOfDay(currDate)) ? "pointer" : "default",
|
cursor: isBefore(currDateObj, endOfDay(currDate))
|
||||||
|
? "pointer"
|
||||||
|
: "default",
|
||||||
background: "gray.700",
|
background: "gray.700",
|
||||||
border: "1px solid #FFF"
|
border: "1px solid #FFF"
|
||||||
}}
|
}}
|
||||||
@@ -140,7 +140,7 @@ const Day = ({
|
|||||||
<Text
|
<Text
|
||||||
p={
|
p={
|
||||||
isToday
|
isToday
|
||||||
? getDate(date) > 10
|
? getDate(currDateObj) > 10
|
||||||
? "0px 6px 3px 6px"
|
? "0px 6px 3px 6px"
|
||||||
: "0px 9px 3px 9px"
|
: "0px 9px 3px 9px"
|
||||||
: "auto"
|
: "auto"
|
||||||
@@ -150,24 +150,18 @@ const Day = ({
|
|||||||
border={isToday ? "1px solid #0068ff" : "0px"}
|
border={isToday ? "1px solid #0068ff" : "0px"}
|
||||||
borderRadius={isToday ? "100px" : "0px"}
|
borderRadius={isToday ? "100px" : "0px"}
|
||||||
>
|
>
|
||||||
{`${getDate(date)}`}
|
{`${getDate(currDateObj)}`}
|
||||||
</Text>
|
</Text>
|
||||||
<Box
|
<Box key={currSticker} fontSize="1.5rem">
|
||||||
key={stickerState === null ? Math.random() : stickerState}
|
<DemoStickers stickerVal={currSticker} />
|
||||||
fontSize="1.5rem"
|
|
||||||
>
|
|
||||||
<DemoStickers
|
|
||||||
stickerVal={stickerState === null ? null : stickerState}
|
|
||||||
/>
|
|
||||||
</Box>
|
</Box>
|
||||||
<StickersContextProvider>
|
<Provider store={store}>
|
||||||
{isBefore(date, endOfDay(currDate)) && (
|
{isBefore(currDateObj, endOfDay(currDate)) && (
|
||||||
<AddUpdateSticker
|
<AddUpdateSticker
|
||||||
date={date}
|
stickerDate={date}
|
||||||
isOpen={isOpen}
|
isOpen={isOpen}
|
||||||
updateIsOpen={setIsOpen}
|
updateIsOpen={setIsOpen}
|
||||||
updateSticker={setStickerState}
|
currSticker={currSticker}
|
||||||
currSticker={stickerState}
|
|
||||||
step={step}
|
step={step}
|
||||||
updateStep={setStep}
|
updateStep={setStep}
|
||||||
selectedSticker={selectedSticker}
|
selectedSticker={selectedSticker}
|
||||||
@@ -175,7 +169,7 @@ const Day = ({
|
|||||||
currDate={currDate}
|
currDate={currDate}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</StickersContextProvider>
|
</Provider>
|
||||||
</VStack>
|
</VStack>
|
||||||
)}
|
)}
|
||||||
</Fragment>
|
</Fragment>
|
||||||
|
|||||||
@@ -1,37 +1,56 @@
|
|||||||
import React, { useContext, useEffect } from "react";
|
import React, { useEffect } from "react";
|
||||||
import { Box, HStack, SimpleGrid, Text, VStack } from "@chakra-ui/react";
|
import { Box, HStack, SimpleGrid, Text, VStack } from "@chakra-ui/react";
|
||||||
import { isSameDay, format } from "date-fns";
|
import { isSameDay, format } from "date-fns";
|
||||||
import { CalenderContext } from "../../../contexts/CalenderContext";
|
import { useAppDispatch, useAppSelector } from "../../app/hooks";
|
||||||
import { StickersContext } from "../../../contexts/StickerContext";
|
import { updateCurrDate, updateMonth } from "../../features/calender/calender";
|
||||||
import CalenderNav from "./CalenderNav";
|
import CalenderNav from "./CalenderNav";
|
||||||
import Day from "./Day";
|
import Day from "./Day";
|
||||||
|
|
||||||
const Calender = (newDate?: UpdateCalendarProps): JSX.Element => {
|
const Calender = (newDate?: UpdateCalendarProps): JSX.Element => {
|
||||||
const { selectedDate, layout, updateDate, currDate, setCurrDate } =
|
// * Month * //
|
||||||
useContext(CalenderContext);
|
const currDate: string = useAppSelector((state) => state.calender.currDate);
|
||||||
const { stickersMonth } = useContext(StickersContext);
|
const selectedDate: SelectedDateInfo = useAppSelector(
|
||||||
|
(state) => state.calender.selectedDateInfo
|
||||||
|
);
|
||||||
|
const { layout } = selectedDate;
|
||||||
|
|
||||||
|
const currDateObj = new Date(currDate);
|
||||||
|
|
||||||
|
// * Stickers * //
|
||||||
|
|
||||||
|
const stickersMonth: StickerDays = useAppSelector(
|
||||||
|
(state) => state.stickers.stickersMonth
|
||||||
|
);
|
||||||
|
|
||||||
|
const dispatch = useAppDispatch();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (newDate && newDate.year && newDate.month && newDate.day) {
|
if (newDate && newDate.year && newDate.month && newDate.day) {
|
||||||
const { year, month, day } = newDate;
|
const { year, month, day } = newDate;
|
||||||
|
|
||||||
if (year > 0 && month > 0 && day > 0) {
|
if (year > 0 && month > 0 && day > 0) {
|
||||||
updateDate(newDate);
|
const generatedDate: Date = new Date(year, month - 1, day);
|
||||||
|
const dateString: string = generatedDate.toJSON();
|
||||||
|
|
||||||
|
dispatch(updateMonth(dateString));
|
||||||
} else {
|
} else {
|
||||||
console.warn("Invalid date format: ", newDate);
|
console.warn("Invalid date format: ", newDate);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [newDate, updateDate]);
|
}, [dispatch, newDate]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.info("Check to update date.");
|
console.info("Check to update date.");
|
||||||
if (!isSameDay(currDate, new Date())) {
|
|
||||||
console.info("Updated date.");
|
|
||||||
setCurrDate(new Date());
|
|
||||||
}
|
|
||||||
}, [currDate, setCurrDate]);
|
|
||||||
|
|
||||||
// Simulated user settings context
|
const currDateObj = new Date(currDate);
|
||||||
|
|
||||||
|
if (!isSameDay(currDateObj, new Date())) {
|
||||||
|
console.info("Updated date.");
|
||||||
|
dispatch(updateCurrDate());
|
||||||
|
}
|
||||||
|
}, [currDate, dispatch]);
|
||||||
|
|
||||||
|
// Simulated user settings.
|
||||||
const userSettings = {
|
const userSettings = {
|
||||||
theme: "default",
|
theme: "default",
|
||||||
startOfWeek: "Sunday"
|
startOfWeek: "Sunday"
|
||||||
@@ -81,12 +100,16 @@ const Calender = (newDate?: UpdateCalendarProps): JSX.Element => {
|
|||||||
return thisWeek.map((day: MonthDay) => {
|
return thisWeek.map((day: MonthDay) => {
|
||||||
const { date, isOverflow, overflowDirection } = day;
|
const { date, isOverflow, overflowDirection } = day;
|
||||||
|
|
||||||
|
const toDateObj: Date = new Date(date);
|
||||||
|
|
||||||
let sticker = null;
|
let sticker = null;
|
||||||
|
|
||||||
let id = "";
|
let id = "";
|
||||||
|
|
||||||
stickersMonth.map((stickerDay) => {
|
stickersMonth.map((stickerDay) => {
|
||||||
if (isSameDay(stickerDay.date, date)) {
|
const { date: stickerDate } = stickerDay;
|
||||||
|
|
||||||
|
if (isSameDay(new Date(stickerDate), toDateObj)) {
|
||||||
sticker = stickerDay.sticker;
|
sticker = stickerDay.sticker;
|
||||||
|
|
||||||
id = stickerDay.id;
|
id = stickerDay.id;
|
||||||
@@ -97,15 +120,15 @@ const Calender = (newDate?: UpdateCalendarProps): JSX.Element => {
|
|||||||
<Day
|
<Day
|
||||||
isOverflow={isOverflow}
|
isOverflow={isOverflow}
|
||||||
overflowDirection={overflowDirection}
|
overflowDirection={overflowDirection}
|
||||||
sticker={sticker}
|
currSticker={sticker}
|
||||||
date={date}
|
date={date}
|
||||||
selectedDate={selectedDate}
|
selectedDate={selectedDate.date}
|
||||||
currDate={currDate}
|
currDate={currDateObj}
|
||||||
isToday={isSameDay(currDate, date)}
|
isToday={isSameDay(currDateObj, toDateObj)}
|
||||||
key={
|
key={
|
||||||
id.length
|
id.length
|
||||||
? id
|
? id
|
||||||
: format(date, "yyyyddLL") +
|
: format(toDateObj, "yyyyddLL") +
|
||||||
`/${sticker === null ? 0 : sticker}`
|
`/${sticker === null ? 0 : sticker}`
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -13,18 +13,18 @@ import {
|
|||||||
SimpleGrid,
|
SimpleGrid,
|
||||||
Box
|
Box
|
||||||
} from "@chakra-ui/react";
|
} from "@chakra-ui/react";
|
||||||
import React, { useState, useContext, useRef } from "react";
|
import React, { useState, useRef } from "react";
|
||||||
import { format, isSameDay } from "date-fns";
|
import { format, isSameDay } from "date-fns";
|
||||||
import { Icon } from "@iconify/react";
|
import { Icon } from "@iconify/react";
|
||||||
import { StickersContext } from "../../../../contexts/StickerContext";
|
|
||||||
import StickerSelector from "./StickerSelector";
|
import StickerSelector from "./StickerSelector";
|
||||||
import DemoStickers from "../stickers/DemoStickers";
|
import DemoStickers from "../stickers/DemoStickers";
|
||||||
|
import { useAppDispatch } from "../../../app/hooks";
|
||||||
|
import { addEditSticker } from "../../../features/calender/stickers";
|
||||||
|
|
||||||
interface AddStickerProps {
|
interface AddStickerProps {
|
||||||
isOpen: boolean;
|
isOpen: boolean;
|
||||||
updateIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
updateIsOpen: React.Dispatch<React.SetStateAction<boolean>>;
|
||||||
date: Date;
|
stickerDate: string;
|
||||||
updateSticker: React.Dispatch<React.SetStateAction<StickerVal>>;
|
|
||||||
currSticker: StickerVal;
|
currSticker: StickerVal;
|
||||||
step: number;
|
step: number;
|
||||||
updateStep: React.Dispatch<React.SetStateAction<number>>;
|
updateStep: React.Dispatch<React.SetStateAction<number>>;
|
||||||
@@ -37,18 +37,18 @@ interface AddStickerProps {
|
|||||||
* Handles adding and modifying the stickers for the given month.
|
* Handles adding and modifying the stickers for the given month.
|
||||||
* @param {boolean} isOpen Tells the component when the modal should be open.
|
* @param {boolean} isOpen Tells the component when the modal should be open.
|
||||||
* @param {React.Dispatch<React.SetStateAction<boolean>>} updateIsOpen Used to close the modal.
|
* @param {React.Dispatch<React.SetStateAction<boolean>>} updateIsOpen Used to close the modal.
|
||||||
* @param {date} date The date for which the sticker will be added or modified.
|
* @param {date} stickerDate The date for which the sticker will be added or modified.
|
||||||
* @param {React.Dispatch<React.SetStateAction<StickerVal>>} updateSticker The react state function to update the sticker.
|
|
||||||
* @param {StickerVal} currSticker The current sticker for the date.
|
* @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 {number} step A numerical variable that represents the page the modal should be at.
|
||||||
* @param {React.Dispatch<React.SetStateAction<number>>} updateStep Used to navigate the pages of the modal by updating the step the modal is on.
|
* @param {React.Dispatch<React.SetStateAction<number>>} updateStep Used to navigate the pages of the modal by updating the step the modal is on.
|
||||||
* @param {React.Dispatch<React.SetStateAction<StickerVal>>} updateSticker The react state function to update the selected sticker that will be added or updated.
|
* @param {StickerVal} selectedSticker the value of the selected sticker.
|
||||||
|
* @param {React.Dispatch<React.SetStateAction<StickerVal>>} updateSelectedSticker The react state function to update the selected sticker that will be added or updated.
|
||||||
|
* @param {Date} currDate the current date.
|
||||||
*/
|
*/
|
||||||
const AddUpdateSticker = ({
|
const AddUpdateSticker = ({
|
||||||
isOpen,
|
isOpen,
|
||||||
updateIsOpen,
|
updateIsOpen,
|
||||||
date,
|
stickerDate,
|
||||||
updateSticker,
|
|
||||||
currSticker,
|
currSticker,
|
||||||
step,
|
step,
|
||||||
updateStep,
|
updateStep,
|
||||||
@@ -56,14 +56,11 @@ const AddUpdateSticker = ({
|
|||||||
updateSelectedSticker,
|
updateSelectedSticker,
|
||||||
currDate
|
currDate
|
||||||
}: AddStickerProps): JSX.Element => {
|
}: AddStickerProps): JSX.Element => {
|
||||||
// TODO: Import the stickers array from the calender context.
|
const dispatch = useAppDispatch();
|
||||||
|
const stickerDateObj = new Date(stickerDate);
|
||||||
|
|
||||||
const { addEditSticker } = useContext(StickersContext);
|
const [modalVariant] = useState<"add" | "edit">(
|
||||||
|
isSameDay(stickerDateObj, currDate) ? "add" : "edit"
|
||||||
// ! Update these states to say "add" and "edit" for easier reading.
|
|
||||||
|
|
||||||
const [modalVariant] = useState<"currDate" | "notCurrDate">(
|
|
||||||
isSameDay(date, currDate) ? "currDate" : "notCurrDate"
|
|
||||||
);
|
);
|
||||||
|
|
||||||
const handleClose = () => {
|
const handleClose = () => {
|
||||||
@@ -71,9 +68,8 @@ const AddUpdateSticker = ({
|
|||||||
};
|
};
|
||||||
|
|
||||||
// TODO: Validate that the provided sticker is not the current sticker. Throw an error if the same sticker is attempted.
|
// TODO: Validate that the provided sticker is not the current sticker. Throw an error if the same sticker is attempted.
|
||||||
const handleSubmit = (sticker) => {
|
const handleSubmit = (sticker: StickerVal) => {
|
||||||
const newSticker: Sticker = addEditSticker(date, sticker);
|
dispatch(addEditSticker({ stickerDate, sticker }));
|
||||||
updateSticker(newSticker.sticker);
|
|
||||||
handleClose();
|
handleClose();
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -83,9 +79,12 @@ const AddUpdateSticker = ({
|
|||||||
// * Double check that the submit button is disabled if the selected sticker is the same as the current sticker.
|
// * Double check that the submit button is disabled if the selected sticker is the same as the current sticker.
|
||||||
|
|
||||||
const variants = {
|
const variants = {
|
||||||
currDate: [
|
add: [
|
||||||
{
|
{
|
||||||
header: `Which sticker did you earn for ${format(date, "LLL d, y")}?`,
|
header: `Which sticker did you earn for ${format(
|
||||||
|
stickerDateObj,
|
||||||
|
"LLL d, y"
|
||||||
|
)}?`,
|
||||||
body: (
|
body: (
|
||||||
<VStack
|
<VStack
|
||||||
w="100%"
|
w="100%"
|
||||||
@@ -119,10 +118,10 @@ const AddUpdateSticker = ({
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
notCurrDate: [
|
edit: [
|
||||||
{
|
{
|
||||||
header: `Which sticker did you want to update for ${format(
|
header: `Which sticker did you want to update for ${format(
|
||||||
date,
|
stickerDateObj,
|
||||||
"LLL d, y"
|
"LLL d, y"
|
||||||
)}?`,
|
)}?`,
|
||||||
body: (
|
body: (
|
||||||
@@ -164,7 +163,7 @@ const AddUpdateSticker = ({
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
header: `Are you sure you want to change the sticker for ${format(
|
header: `Are you sure you want to change the sticker for ${format(
|
||||||
date,
|
stickerDateObj,
|
||||||
"M/d/y"
|
"M/d/y"
|
||||||
)}?`,
|
)}?`,
|
||||||
body: (
|
body: (
|
||||||
@@ -235,7 +234,7 @@ const AddUpdateSticker = ({
|
|||||||
onClose={() => handleClose()}
|
onClose={() => handleClose()}
|
||||||
motionPreset="slideInBottom"
|
motionPreset="slideInBottom"
|
||||||
scrollBehavior="inside"
|
scrollBehavior="inside"
|
||||||
size={modalVariant === "currDate" ? "xl" : "2xl"}
|
size={modalVariant === "add" ? "xl" : "2xl"}
|
||||||
>
|
>
|
||||||
<ModalOverlay />
|
<ModalOverlay />
|
||||||
<ModalContent>
|
<ModalContent>
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ interface StickerSelectorProps {
|
|||||||
* @param {StickerVal} currSticker The current sticker for the date.
|
* @param {StickerVal} currSticker The current sticker for the date.
|
||||||
* @param {StickerVal} selectedSticker The selected sticker for the current. date
|
* @param {StickerVal} selectedSticker The selected sticker for the current. date
|
||||||
* @param {React.Dispatch<React.SetStateAction<StickerVal>>} updateSelectedSticker TThe react state function to update the selected sticker that will be added or updated.
|
* @param {React.Dispatch<React.SetStateAction<StickerVal>>} updateSelectedSticker TThe react state function to update the selected sticker that will be added or updated.
|
||||||
|
* @param {React.MutableRefObject<undefined>} initialSticker the sticker that should have be in focus when the modal opens.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const StickerSelector = ({
|
const StickerSelector = ({
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import React, { FC } from "react";
|
import React, { FC } from "react";
|
||||||
|
|
||||||
// TODO: When themes are made import the theme from user settings context. Refactor to use whatever those SVGs are.
|
// TODO: When themes are made import the theme from user settings store. Refactor to use whatever those SVGs are.
|
||||||
|
|
||||||
interface DemoStickersProps {
|
interface DemoStickersProps {
|
||||||
stickerVal: StickerVal;
|
stickerVal: StickerVal;
|
||||||
@@ -9,13 +9,19 @@ interface DemoStickersProps {
|
|||||||
const DemoStickers: FC<DemoStickersProps> = ({
|
const DemoStickers: FC<DemoStickersProps> = ({
|
||||||
stickerVal
|
stickerVal
|
||||||
}: DemoStickersProps) => {
|
}: DemoStickersProps) => {
|
||||||
|
// If sticker is null return an empty space.
|
||||||
if (stickerVal === null) {
|
if (stickerVal === null) {
|
||||||
return <span aria-label="spacer"> </span>;
|
return <span aria-label="spacer"> </span>;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface StickerToEmoji {
|
interface StickerToEmoji {
|
||||||
[key: string]: JSX.Element;
|
[key: string]: JSX.Element;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* ? Temporarily using values -1 to 1.
|
||||||
|
* ? In the full app the values will be between -2 and 2.
|
||||||
|
*/
|
||||||
let key = "0";
|
let key = "0";
|
||||||
|
|
||||||
if (stickerVal > 0) {
|
if (stickerVal > 0) {
|
||||||
@@ -24,6 +30,7 @@ const DemoStickers: FC<DemoStickersProps> = ({
|
|||||||
key = "-1";
|
key = "-1";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Link value to an emoji representing a sticker.
|
||||||
const stickerToEmoji: StickerToEmoji = {
|
const stickerToEmoji: StickerToEmoji = {
|
||||||
"1": (
|
"1": (
|
||||||
<span role="img" aria-label="Sun">
|
<span role="img" aria-label="Sun">
|
||||||
@@ -42,6 +49,7 @@ const DemoStickers: FC<DemoStickersProps> = ({
|
|||||||
)
|
)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Return the appropriate sticker.
|
||||||
return stickerToEmoji[`${key}`];
|
return stickerToEmoji[`${key}`];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
58
src/features/calender/calender.ts
Normal file
58
src/features/calender/calender.ts
Normal file
@@ -0,0 +1,58 @@
|
|||||||
|
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
||||||
|
import { format } from "date-fns";
|
||||||
|
import populate from "../../../lib/populateMonth";
|
||||||
|
|
||||||
|
interface CalenderSlice {
|
||||||
|
currDate: string;
|
||||||
|
selectedDateInfo: SelectedDateInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
const getCurrDate = (): Date => new Date();
|
||||||
|
const dateParse = (date: Date) => date.toJSON();
|
||||||
|
const dateFormatter = (date: Date): string => format(date, "LLLL uuuu");
|
||||||
|
|
||||||
|
const initialState: CalenderSlice = {
|
||||||
|
currDate: dateParse(getCurrDate()),
|
||||||
|
selectedDateInfo: {
|
||||||
|
date: dateParse(getCurrDate()),
|
||||||
|
title: dateFormatter(getCurrDate()),
|
||||||
|
layout: populate(getCurrDate())
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// TODO: Add a function that validated if a month has at least one sticker in it. Use that within the nav function (when filter is enabled).
|
||||||
|
|
||||||
|
// TODO: Add a function that will give the closest date, if available, when the nav func detects an empty month.
|
||||||
|
// Use the chart creation date to aid with this. (When filter is enabled)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO: Add logic that prevents navigation to the future and too far in the past. (Use chart creation date)
|
||||||
|
* Update to use a promise and return appropriate errors. Display those errors on the front end.
|
||||||
|
* Update the use of this function on the front to handle the fails of the promise.
|
||||||
|
*/
|
||||||
|
|
||||||
|
// TODO: (When filter is enabled) Update the calender update function that will take in a direction so that the the navigation buttons will take the user to the next month with stickers. Assuming there was a gap with empty months.
|
||||||
|
|
||||||
|
const calenderSlice = createSlice({
|
||||||
|
name: "Calender",
|
||||||
|
initialState,
|
||||||
|
reducers: {
|
||||||
|
// Update month info
|
||||||
|
updateMonth(state: CalenderSlice, action: PayloadAction<string>) {
|
||||||
|
const { payload } = action;
|
||||||
|
|
||||||
|
const toDateObj: Date = new Date(payload);
|
||||||
|
|
||||||
|
state.selectedDateInfo.date = payload;
|
||||||
|
state.selectedDateInfo.title = dateFormatter(toDateObj);
|
||||||
|
state.selectedDateInfo.layout = populate(toDateObj);
|
||||||
|
},
|
||||||
|
// Update current date
|
||||||
|
updateCurrDate(state: CalenderSlice) {
|
||||||
|
state.currDate = dateParse(new Date());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export const { updateMonth, updateCurrDate } = calenderSlice.actions;
|
||||||
|
export default calenderSlice.reducer;
|
||||||
62
src/features/calender/stickers.ts
Normal file
62
src/features/calender/stickers.ts
Normal file
@@ -0,0 +1,62 @@
|
|||||||
|
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
||||||
|
import { format, getDate, isSameDay } from "date-fns";
|
||||||
|
import stickersSeeder from "../../../data/stickerSeeder";
|
||||||
|
|
||||||
|
interface StickersSlice {
|
||||||
|
stickersMonth: StickerDays;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface UpdateStickerSlicePayload {
|
||||||
|
stickerDate: string;
|
||||||
|
sticker: StickerVal;
|
||||||
|
}
|
||||||
|
|
||||||
|
const initialState: StickersSlice = {
|
||||||
|
stickersMonth: stickersSeeder()
|
||||||
|
};
|
||||||
|
|
||||||
|
const stickersSlice = createSlice({
|
||||||
|
name: "Stickers",
|
||||||
|
initialState,
|
||||||
|
reducers: {
|
||||||
|
addEditSticker(
|
||||||
|
state: StickersSlice,
|
||||||
|
actions: PayloadAction<UpdateStickerSlicePayload>
|
||||||
|
) {
|
||||||
|
const { stickerDate, sticker } = actions.payload;
|
||||||
|
|
||||||
|
const dateObj = new Date(stickerDate);
|
||||||
|
|
||||||
|
// Getting index for the stickers array, sticker from the stickers array, and the date from the sticker.
|
||||||
|
const index: number = getDate(dateObj) - 1;
|
||||||
|
const currSticker: Sticker = state.stickersMonth[index];
|
||||||
|
|
||||||
|
// Updating the edited status by checking if the sticker date is today's date.
|
||||||
|
const edited = currSticker.edited
|
||||||
|
? true
|
||||||
|
: isSameDay(new Date(stickerDate), new Date())
|
||||||
|
? false
|
||||||
|
: true;
|
||||||
|
currSticker.edited = edited;
|
||||||
|
|
||||||
|
// TODO: Add manually added here.
|
||||||
|
|
||||||
|
// Updating the id of the sticker.
|
||||||
|
const id = format(dateObj, "yyyyddLL") + sticker;
|
||||||
|
|
||||||
|
// Updating the information of the sticker.
|
||||||
|
const newSticker: Sticker = {
|
||||||
|
id: id,
|
||||||
|
date: stickerDate,
|
||||||
|
sticker: sticker,
|
||||||
|
edited: edited,
|
||||||
|
manual: false
|
||||||
|
};
|
||||||
|
|
||||||
|
state.stickersMonth[index] = newSticker;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
export const { addEditSticker } = stickersSlice.actions;
|
||||||
|
export default stickersSlice.reducer;
|
||||||
@@ -13,8 +13,8 @@ import {
|
|||||||
// import findValidDateRange from "../../lib/findValidDateRange";
|
// import findValidDateRange from "../../lib/findValidDateRange";
|
||||||
import ErrorPage from "next/error";
|
import ErrorPage from "next/error";
|
||||||
import Calender from "../../components/calender";
|
import Calender from "../../components/calender";
|
||||||
import { CalenderContextProvider } from "../../../contexts/CalenderContext";
|
import { Provider } from "react-redux";
|
||||||
import { StickersContextProvider } from "../../../contexts/StickerContext";
|
import { store } from "../../app/store";
|
||||||
|
|
||||||
const DateRoute: React.FC<unknown> = () => {
|
const DateRoute: React.FC<unknown> = () => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
@@ -59,8 +59,6 @@ const DateRoute: React.FC<unknown> = () => {
|
|||||||
} else if (!dateArr[2]) {
|
} else if (!dateArr[2]) {
|
||||||
date.day = 1;
|
date.day = 1;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
return date;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return date;
|
return date;
|
||||||
@@ -199,11 +197,9 @@ const DateRoute: React.FC<unknown> = () => {
|
|||||||
<ErrorPage statusCode={404} />
|
<ErrorPage statusCode={404} />
|
||||||
) : (
|
) : (
|
||||||
<Box textAlign="center" w="100%" h="auto" pt="50px" pb="10vh">
|
<Box textAlign="center" w="100%" h="auto" pt="50px" pb="10vh">
|
||||||
<CalenderContextProvider>
|
<Provider store={store}>
|
||||||
<StickersContextProvider>
|
<Calender {...date} />
|
||||||
<Calender {...date} />
|
</Provider>
|
||||||
</StickersContextProvider>
|
|
||||||
</CalenderContextProvider>
|
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
import React, { useRef } from "react";
|
import React, { useRef } from "react";
|
||||||
import { Box } from "@chakra-ui/react";
|
import { Box } from "@chakra-ui/react";
|
||||||
import Calender from "../components/calender";
|
|
||||||
import { StickersContextProvider } from "../../contexts/StickerContext";
|
|
||||||
import { CalenderContextProvider } from "../../contexts/CalenderContext";
|
|
||||||
import { format } from "date-fns";
|
import { format } from "date-fns";
|
||||||
|
import { Provider } from "react-redux";
|
||||||
|
import { store } from "../app/store";
|
||||||
|
import Calender from "../components/calender";
|
||||||
|
|
||||||
const IndexPage = (): JSX.Element => {
|
const IndexPage = (): JSX.Element => {
|
||||||
const date = useRef<UpdateCalendarProps>({
|
const date = useRef<UpdateCalendarProps>({
|
||||||
@@ -14,11 +14,9 @@ const IndexPage = (): JSX.Element => {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Box textAlign="center" w="100%" h="auto" pt="50px" pb="10vh">
|
<Box textAlign="center" w="100%" h="auto" pt="50px" pb="10vh">
|
||||||
<StickersContextProvider>
|
<Provider store={store}>
|
||||||
<CalenderContextProvider>
|
<Calender {...date.current} />
|
||||||
<Calender {...date.current} />
|
</Provider>
|
||||||
</CalenderContextProvider>
|
|
||||||
</StickersContextProvider>
|
|
||||||
</Box>
|
</Box>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ 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.9.11-alpha";
|
const appVersion = "v0.0.10-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);
|
||||||
|
|||||||
18
types/CalenderContext.d.ts → types/Calender.d.ts
vendored
18
types/CalenderContext.d.ts → types/Calender.d.ts
vendored
@@ -15,7 +15,7 @@ interface WeekDays {
|
|||||||
}
|
}
|
||||||
|
|
||||||
interface MonthDay {
|
interface MonthDay {
|
||||||
date: Date;
|
date: string;
|
||||||
isOverflow: boolean;
|
isOverflow: boolean;
|
||||||
overflowDirection: "prev" | "next" | null;
|
overflowDirection: "prev" | "next" | null;
|
||||||
}
|
}
|
||||||
@@ -29,11 +29,6 @@ interface Month {
|
|||||||
week6: MonthDay[];
|
week6: MonthDay[];
|
||||||
}
|
}
|
||||||
|
|
||||||
interface MonthInfo {
|
|
||||||
date: Date;
|
|
||||||
title: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface WeekLayout {
|
interface WeekLayout {
|
||||||
weekdays: DaysOfWeek;
|
weekdays: DaysOfWeek;
|
||||||
month: Month;
|
month: Month;
|
||||||
@@ -44,21 +39,14 @@ interface MonthLayout {
|
|||||||
monday: WeekLayout;
|
monday: WeekLayout;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface MonthContext extends MonthInfo {
|
|
||||||
layout: MonthLayout;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface UpdateCalendarProps {
|
interface UpdateCalendarProps {
|
||||||
year: number;
|
year: number;
|
||||||
month: number;
|
month: number;
|
||||||
day: number;
|
day: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CalenderContextState {
|
interface SelectedDateInfo {
|
||||||
currDate: Date;
|
date: string;
|
||||||
setCurrDate: React.Dispatch<React.SetStateAction<Date>>;
|
|
||||||
selectedDate: Date;
|
|
||||||
title: string;
|
title: string;
|
||||||
layout: MonthLayout;
|
layout: MonthLayout;
|
||||||
updateDate: (input: UpdateCalendarProps) => void;
|
|
||||||
}
|
}
|
||||||
14
types/StickerContext.d.ts → types/Stickers.d.ts
vendored
14
types/StickerContext.d.ts → types/Stickers.d.ts
vendored
@@ -1,8 +1,3 @@
|
|||||||
interface StickersContextState {
|
|
||||||
stickersMonth: StickerDays;
|
|
||||||
addEditSticker: (date: Date, sticker: ValidStickerVal) => Sticker;
|
|
||||||
}
|
|
||||||
|
|
||||||
type StickerVal = -2 | -1 | 0 | 1 | 2 | null;
|
type StickerVal = -2 | -1 | 0 | 1 | 2 | null;
|
||||||
|
|
||||||
type ValidStickerVal = -2 | -1 | 0 | 1 | 2;
|
type ValidStickerVal = -2 | -1 | 0 | 1 | 2;
|
||||||
@@ -14,7 +9,7 @@ interface AddEditStickerProps {
|
|||||||
|
|
||||||
interface Sticker {
|
interface Sticker {
|
||||||
id: string;
|
id: string;
|
||||||
date: Date;
|
date: string;
|
||||||
sticker: StickerVal;
|
sticker: StickerVal;
|
||||||
edited: boolean;
|
edited: boolean;
|
||||||
manual: boolean;
|
manual: boolean;
|
||||||
@@ -22,7 +17,8 @@ interface Sticker {
|
|||||||
|
|
||||||
type StickerDays = Sticker[];
|
type StickerDays = Sticker[];
|
||||||
|
|
||||||
interface MonthSticker {
|
interface StickerModal {
|
||||||
date: Date;
|
isOpen: boolean;
|
||||||
month: Sticker[];
|
selectedSticker: StickerVal;
|
||||||
|
step: number;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user