From 6f08b6036433e2f3bd2c90d02ecec5640e17fd64 Mon Sep 17 00:00:00 2001 From: bombies Date: Fri, 27 Oct 2023 19:00:01 -0500 Subject: [PATCH] Add previous dreams display --- .../dreams/CurrentDreamsContainer.tsx | 49 ------- .../components/dreams/card/DreamCard.tsx | 4 +- .../containers/CurrentDreamsContainer.tsx | 48 +++++++ .../dreams/containers/DreamContainer.tsx | 25 ++++ .../dreams/containers/PastDreamItem.tsx | 26 ++++ .../dreams/containers/PastDreamsContainer.tsx | 123 ++++++++++++++++++ src/app/(site)/(internal)/dashboard/page.tsx | 6 +- .../(site)/components/icons/PillowIcon.tsx | 18 +++ src/app/(site)/hooks/time-hooks.tsx | 48 +++++++ src/app/(site)/hooks/useTodayTimeRange.tsx | 24 ---- .../(site)/signin/components/LogInForm.tsx | 1 - src/app/(site)/signin/page.tsx | 1 - src/app/globals.scss | 2 +- 13 files changed, 295 insertions(+), 80 deletions(-) delete mode 100644 src/app/(site)/(internal)/dashboard/components/dreams/CurrentDreamsContainer.tsx create mode 100644 src/app/(site)/(internal)/dashboard/components/dreams/containers/CurrentDreamsContainer.tsx create mode 100644 src/app/(site)/(internal)/dashboard/components/dreams/containers/DreamContainer.tsx create mode 100644 src/app/(site)/(internal)/dashboard/components/dreams/containers/PastDreamItem.tsx create mode 100644 src/app/(site)/(internal)/dashboard/components/dreams/containers/PastDreamsContainer.tsx create mode 100644 src/app/(site)/components/icons/PillowIcon.tsx create mode 100644 src/app/(site)/hooks/time-hooks.tsx delete mode 100644 src/app/(site)/hooks/useTodayTimeRange.tsx diff --git a/src/app/(site)/(internal)/dashboard/components/dreams/CurrentDreamsContainer.tsx b/src/app/(site)/(internal)/dashboard/components/dreams/CurrentDreamsContainer.tsx deleted file mode 100644 index 408a68f..0000000 --- a/src/app/(site)/(internal)/dashboard/components/dreams/CurrentDreamsContainer.tsx +++ /dev/null @@ -1,49 +0,0 @@ -import {FC, Fragment, useMemo} from "react"; -import {useDreamsData} from "@/app/(site)/(internal)/dashboard/components/dreams/DreamsProvider"; -import DreamCard from "@/app/(site)/(internal)/dashboard/components/dreams/card/DreamCard"; -import LogDreamCard from "@/app/(site)/(internal)/dashboard/components/dreams/LogDreamCard"; -import useTodayTimeRange from "@/app/(site)/hooks/useTodayTimeRange"; -import {Spinner} from "@nextui-org/react"; -import DreamCardSkeleton from "@/app/(site)/(internal)/dashboard/components/dreams/card/DreamCardSkeleton"; - -const CurrentDreamsContainer: FC = () => { - const [startOfToday, endOfToday] = useTodayTimeRange() - const {dreams} = useDreamsData() - const dreamCards = useMemo(() => dreams.data - .filter(dream => { - const creationDate = new Date(dream.createdAt.toString()); - return creationDate.getTime() >= startOfToday.getTime() && creationDate.getTime() <= endOfToday.getTime() - }) - .sort((a, b) => new Date(b.createdAt.toString()).getTime() - new Date(a.createdAt.toString()).getTime()) - .map(dream => ( - - )), [dreams.data, dreams.optimisticData.removeOptimisticData, endOfToday, startOfToday]) - - return ( -
-

Today - - {startOfToday.toLocaleDateString("en-US", { - dateStyle: "medium" - })} -

-
- - {dreams.loading ? ( - - - - - - ) : dreamCards.length ? dreamCards :

You have no dreams today...

} -
-
- - ) -} - -export default CurrentDreamsContainer \ No newline at end of file diff --git a/src/app/(site)/(internal)/dashboard/components/dreams/card/DreamCard.tsx b/src/app/(site)/(internal)/dashboard/components/dreams/card/DreamCard.tsx index 86871f4..68a090a 100644 --- a/src/app/(site)/(internal)/dashboard/components/dreams/card/DreamCard.tsx +++ b/src/app/(site)/(internal)/dashboard/components/dreams/card/DreamCard.tsx @@ -38,7 +38,7 @@ const DreamCard: FC = ({dream, optimisticRemove}) => { onDelete={() => { if (optimisticRemove) optimisticRemove( - doDelete, // TODO: Replace with API call + doDelete, dream ) .then(() => { @@ -57,7 +57,7 @@ const DreamCard: FC = ({dream, optimisticRemove}) => { footer: "bg-[#0C0015] px-8", }}> -

{dream.title}

+

{dream.title}

{new Date(dream.createdAt.toString()).toLocaleTimeString("en-US", { timeStyle: 'short' diff --git a/src/app/(site)/(internal)/dashboard/components/dreams/containers/CurrentDreamsContainer.tsx b/src/app/(site)/(internal)/dashboard/components/dreams/containers/CurrentDreamsContainer.tsx new file mode 100644 index 0000000..4cee2f8 --- /dev/null +++ b/src/app/(site)/(internal)/dashboard/components/dreams/containers/CurrentDreamsContainer.tsx @@ -0,0 +1,48 @@ +import {FC, Fragment, useMemo} from "react"; +import {useDreamsData} from "@/app/(site)/(internal)/dashboard/components/dreams/DreamsProvider"; +import DreamCard from "@/app/(site)/(internal)/dashboard/components/dreams/card/DreamCard"; +import LogDreamCard from "@/app/(site)/(internal)/dashboard/components/dreams/LogDreamCard"; +import useTodayTimeRange from "@/app/(site)/hooks/time-hooks"; +import DreamCardSkeleton from "@/app/(site)/(internal)/dashboard/components/dreams/card/DreamCardSkeleton"; +import DreamContainer from "@/app/(site)/(internal)/dashboard/components/dreams/containers/DreamContainer"; + +const CurrentDreamsContainer: FC = () => { + const [startOfToday, endOfToday] = useTodayTimeRange() + const {dreams} = useDreamsData() + const dreamCards = useMemo(() => dreams.data + .filter(dream => { + const creationDate = new Date(dream.createdAt.toString()); + return creationDate >= startOfToday && creationDate <= endOfToday + }) + .sort((a, b) => new Date(b.createdAt.toString()).getTime() - new Date(a.createdAt.toString()).getTime()) + .map(dream => ( + + )), [dreams.data, dreams.optimisticData.removeOptimisticData, endOfToday, startOfToday]) + + return ( + + + {dreams.loading ? ( + + + + + + ) : (dreamCards.length ? dreamCards : +

You have no + dreams today...

) + } + + ) +} + +export default CurrentDreamsContainer \ No newline at end of file diff --git a/src/app/(site)/(internal)/dashboard/components/dreams/containers/DreamContainer.tsx b/src/app/(site)/(internal)/dashboard/components/dreams/containers/DreamContainer.tsx new file mode 100644 index 0000000..475edd3 --- /dev/null +++ b/src/app/(site)/(internal)/dashboard/components/dreams/containers/DreamContainer.tsx @@ -0,0 +1,25 @@ +import {FC, PropsWithChildren} from "react"; +import clsx from "clsx"; + +type Props = { + title: string, + className?: string, + containerClassName?: string, +} & PropsWithChildren + +const DreamContainer: FC = ({title, children, className, containerClassName}) => { + return ( +
+

{title}

+
+ {children} +
+
+ ) +} + +export default DreamContainer \ No newline at end of file diff --git a/src/app/(site)/(internal)/dashboard/components/dreams/containers/PastDreamItem.tsx b/src/app/(site)/(internal)/dashboard/components/dreams/containers/PastDreamItem.tsx new file mode 100644 index 0000000..f0a7660 --- /dev/null +++ b/src/app/(site)/(internal)/dashboard/components/dreams/containers/PastDreamItem.tsx @@ -0,0 +1,26 @@ +"use client" + +import {FC, Fragment, useMemo} from "react"; +import {PastDream} from "@/app/(site)/(internal)/dashboard/components/dreams/containers/PastDreamsContainer"; +import DreamCard from "@/app/(site)/(internal)/dashboard/components/dreams/card/DreamCard"; + +type Props = { + dream: PastDream +} + +const PastDreamItem: FC = ({dream}) => { + const cards = useMemo(() => dream.dreams.map(pastDream => ( + + )), [dream.dreams]) + + return ( + +

{new Date(dream.timestamp).toLocaleString("en-US", { + dateStyle: "full" + })}

+ {cards} +
+ ) +} + +export default PastDreamItem \ No newline at end of file diff --git a/src/app/(site)/(internal)/dashboard/components/dreams/containers/PastDreamsContainer.tsx b/src/app/(site)/(internal)/dashboard/components/dreams/containers/PastDreamsContainer.tsx new file mode 100644 index 0000000..0ee3652 --- /dev/null +++ b/src/app/(site)/(internal)/dashboard/components/dreams/containers/PastDreamsContainer.tsx @@ -0,0 +1,123 @@ +"use client" + +import {FC, Fragment, useMemo} from "react"; +import DreamContainer from "@/app/(site)/(internal)/dashboard/components/dreams/containers/DreamContainer"; +import {useDreamsData} from "@/app/(site)/(internal)/dashboard/components/dreams/DreamsProvider"; +import {Dream} from "@prisma/client"; +import {useStartOfDay} from "@/app/(site)/hooks/time-hooks"; +import PastDreamItem from "@/app/(site)/(internal)/dashboard/components/dreams/containers/PastDreamItem"; +import DreamCardSkeleton from "@/app/(site)/(internal)/dashboard/components/dreams/card/DreamCardSkeleton"; +import {Divider} from "@nextui-org/divider"; +import Card from "@/app/(site)/components/Card"; +import Link from "next/link"; +import {CardBody} from "@nextui-org/card"; +import {useRouter} from "next/navigation"; +import PillowIcon from "@/app/(site)/components/icons/PillowIcon"; +import CloudIcon from "@/app/(site)/components/icons/CloudIcon"; + +type GroupedDreams = { + [K: string]: Dream[] +} + +export type PastDream = { + timestamp: number, + dreams: Dream[] +} + +const NUMBER_OF_DAYS = 7 + +const PastDreamsContainer: FC = () => { + const router = useRouter() + const {dreams} = useDreamsData() + const earliestDate = useStartOfDay({ + dayOffset: -NUMBER_OF_DAYS, // A week ago @ 12:00 AM + }) + + const pastDreams = useMemo(() => { + const filteredDreams = dreams.data.filter(dream => new Date(dream.createdAt.toString()).getTime() >= earliestDate.getTime()) + const dayTimes = [earliestDate] + for (let i = 1; i < NUMBER_OF_DAYS; i++) { + const d = new Date(dayTimes[dayTimes.length - 1]) + d.setTime(d.getTime() + (24 * 60 * 60 * 1000)) + dayTimes.push(d) + } + + const groupedDreams = dayTimes.reduce((previousValue, currentValue, i, arr) => { + const endDate = new Date(arr[i]) + endDate.setHours(11, 59, 59, 999) + + const dreams = filteredDreams.filter(dream => { + const dreamDate = new Date(dream.createdAt) + return dreamDate >= currentValue && dreamDate <= endDate + }) + + return ({ + ...previousValue, + [currentValue.getTime()]: dreams + }) + }, {}) + + const pastDreamsArr: PastDream[] = [] + for (let timestamp in groupedDreams) { + const dreamsForDay = groupedDreams[timestamp] + if (dreamsForDay.length === 0) + continue + pastDreamsArr.push({ + timestamp: Number(timestamp), + dreams: dreamsForDay + }) + } + + return pastDreamsArr.sort((a, b) => b.timestamp - a.timestamp) + }, [dreams.data, earliestDate]) + + + const dreamItems = useMemo(() => pastDreams.map(dream => ( + + )), [pastDreams]) + + + return ( + + {dreams.loading ? ( + + + + + + ) : (dreamItems.length ? + + {dreamItems} + + router.push("/dashboard/calendar")} + isPressable + isBlurred + classNames={{ + base: "hover:scale-105", + body: "bg-secondary py-8" + }} + > + +
+ +

View All Dreams

+
+
+
+
+ : +

You have no + dreams today...

) + } +
+ ) +} + +export default PastDreamsContainer \ No newline at end of file diff --git a/src/app/(site)/(internal)/dashboard/page.tsx b/src/app/(site)/(internal)/dashboard/page.tsx index a5550fe..3995ac8 100644 --- a/src/app/(site)/(internal)/dashboard/page.tsx +++ b/src/app/(site)/(internal)/dashboard/page.tsx @@ -1,14 +1,16 @@ "use client" import {FC, Fragment} from "react"; -import CurrentDreamsContainer from "@/app/(site)/(internal)/dashboard/components/dreams/CurrentDreamsContainer"; +import CurrentDreamsContainer from "@/app/(site)/(internal)/dashboard/components/dreams/containers/CurrentDreamsContainer"; +import PastDreamsContainer from "@/app/(site)/(internal)/dashboard/components/dreams/containers/PastDreamsContainer"; const DashboardHomePage: FC = () => { return (

Your Dreams

- + +
) diff --git a/src/app/(site)/components/icons/PillowIcon.tsx b/src/app/(site)/components/icons/PillowIcon.tsx new file mode 100644 index 0000000..4e73334 --- /dev/null +++ b/src/app/(site)/components/icons/PillowIcon.tsx @@ -0,0 +1,18 @@ +import * as React from "react" +import {IconProps} from "@/app/(site)/components/icons/icon-utils"; +import clsx from "clsx"; + +const PillowIcon = ({ className, fill, width, height }: IconProps) => ( + + + +) +export default PillowIcon diff --git a/src/app/(site)/hooks/time-hooks.tsx b/src/app/(site)/hooks/time-hooks.tsx new file mode 100644 index 0000000..db6242b --- /dev/null +++ b/src/app/(site)/hooks/time-hooks.tsx @@ -0,0 +1,48 @@ +"use client" + +import {useMemo} from "react"; + +const useTodayTimeRange = () => { + return useDayTimeRange() +} + +type DayTimeArgs = { + date?: Date, + dayOffset?: number +} + +export const useStartOfDay = (options?: DayTimeArgs) => { + return useMemo(() => { + const d = options?.date ? new Date(options.date) : new Date() + d.setHours(0, 0, 0, 0) + + if (options?.dayOffset) + d.setTime(d.getTime() + (options.dayOffset * 24 * 60 * 60 * 1000)) + return d; + }, [options?.date, options?.dayOffset]) +} + +export const useEndOfDay = (options?: DayTimeArgs) => { + return useMemo(() => { + const d = options?.date ? new Date(options.date) : new Date() + d.setHours(23, 59, 59, 999) + + if (options?.dayOffset) + d.setTime(d.getTime() + (options.dayOffset * 24 * 60 * 60 * 1000)) + return d; + }, [options?.date, options?.dayOffset]) +} + +type DayTimeRangeArgs = Partial<{ + date: Date, + startDayOffset: number + endDayOffset: number +}> + +export const useDayTimeRange = (options?: DayTimeRangeArgs): [Date, Date] => { + const startOfDay = useStartOfDay({date: options?.date, dayOffset: options?.startDayOffset}) + const endOfDay = useEndOfDay({date: options?.date, dayOffset: options?.endDayOffset}) + return [startOfDay, endOfDay] +} + +export default useTodayTimeRange \ No newline at end of file diff --git a/src/app/(site)/hooks/useTodayTimeRange.tsx b/src/app/(site)/hooks/useTodayTimeRange.tsx deleted file mode 100644 index e831f07..0000000 --- a/src/app/(site)/hooks/useTodayTimeRange.tsx +++ /dev/null @@ -1,24 +0,0 @@ -"use client" - -import {useMemo} from "react"; - -const useTodayTimeRange = () => { - return useTimeRange(new Date()) -} - -export const useTimeRange = (date: Date): [Date, Date] => { - const startOfDay = useMemo(() => { - const today = new Date(date) - today.setHours(0, 0, 0, 0) - return today; - }, [date]) - const endOfDay = useMemo(() => { - const today = new Date(date) - today.setHours(23, 59, 59, 999) - return today; - }, [date]) - - return [startOfDay, endOfDay] -} - -export default useTodayTimeRange \ No newline at end of file diff --git a/src/app/(site)/signin/components/LogInForm.tsx b/src/app/(site)/signin/components/LogInForm.tsx index a8c0439..5198b3b 100644 --- a/src/app/(site)/signin/components/LogInForm.tsx +++ b/src/app/(site)/signin/components/LogInForm.tsx @@ -26,7 +26,6 @@ const LogInForm: FC = () => { redirect: false }) .then((cb) => { - console.log(cb) if (cb?.error) toast.error("Invalid credentials! Please check your details and try again.") else if (cb?.ok) { diff --git a/src/app/(site)/signin/page.tsx b/src/app/(site)/signin/page.tsx index 64c7a9f..1cd2d8e 100644 --- a/src/app/(site)/signin/page.tsx +++ b/src/app/(site)/signin/page.tsx @@ -20,7 +20,6 @@ const SignInPage: FC = () => { const [selectedTab, setSelectedTab] = useState(searchParams.get("tab")?.toLowerCase() === "register" ? "register" : "signin") useEffect(() => { - console.log(sessionStatus, sessionData) if (sessionStatus !== 'loading' && sessionData !== null) router.push("/dashboard") }, [router, sessionData, sessionStatus]) diff --git a/src/app/globals.scss b/src/app/globals.scss index c54ac4a..18313e0 100644 --- a/src/app/globals.scss +++ b/src/app/globals.scss @@ -17,7 +17,7 @@ $background-color: #0C0015; body { background-color: $background-color; - color: $foreground-color; + color: $foreground-color !important; } ::-webkit-scrollbar {