Skip to content

Commit

Permalink
Add dedicated dream draft page
Browse files Browse the repository at this point in the history
  • Loading branch information
bombies committed Nov 11, 2023
1 parent 7f0f7c2 commit 8de795d
Show file tree
Hide file tree
Showing 4 changed files with 116 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,19 @@ import useSWRMutation from "swr/mutation";
import {handleAxiosError, postMutatorWithoutArgs} from "@/utils/client/client-utils";
import {Dream} from "@prisma/client";
import DreamLogFormProvider from "./forms/log/DreamLogFormProvider";
import clsx from "clsx";

type Props = {
isDisabled?: boolean
isDisabled?: boolean,
content?: string,
className?: string,
}

const CreateDraftDream = () => (
useSWRMutation(`/api/me/dreams/drafts`, postMutatorWithoutArgs<Dream | null>())
)

const LogDreamCard: FC<Props> = ({isDisabled}) => {
const LogDreamCard: FC<Props> = ({isDisabled, content, className}) => {
const {dreams: {data: dreams, optimisticData: {addOptimisticData: addOptimisticDream}}} = useDreamsData()
const {trigger: createDraft} = CreateDraftDream()
const [modalOpen, setModalOpen] = useState(false)
Expand Down Expand Up @@ -74,14 +77,14 @@ const LogDreamCard: FC<Props> = ({isDisabled}) => {
}}
isPressable={!isDisabled}
classNames={{
base: "bg-primary rounded-3xl text-light hover:scale-105",
base: clsx("bg-primary rounded-3xl text-light hover:scale-105", className),
body: "py-8"
}}
>
<CardBody>
<div className="flex gap-4">
<CloudIcon width={36}/>
<h3 className="font-semibold text-2xl phone:text-medium self-center">Log A New Dream</h3>
<h3 className="font-semibold text-2xl phone:text-medium self-center">{content ?? "Log A New Dream"}</h3>
</div>
</CardBody>
</Card>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import SearchFilledIcon from "@/app/(site)/components/icons/SearchFilledIcon";
import StatisticsIcon from "@/app/(site)/components/icons/StatisticsIcon";
import TagIcon from "@/app/(site)/components/icons/TagIcon";
import SidebarSection from "@/app/(site)/components/sidebar/SidebarSection";
import PencilIcon from "@/app/(site)/components/icons/PencilIcon";

const DashboardSidebar: FC = () => {
return (
Expand All @@ -21,6 +22,11 @@ const DashboardSidebar: FC = () => {
title="Your Dreams"
href="/dashboard"
/>
<SidebarItem
title="Dream Drafts"
href="/dashboard/drafts"
startContent={<PencilIcon width={20}/>}
/>
<SidebarItem
startContent={<CalendarIcon width={20}/>}
title="Dream Calendar"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
"use client"

import {FC, Fragment, useMemo, useState} from "react";
import Card from "@/app/(site)/components/Card";
import {CardBody, CardFooter} from "@nextui-org/card";
import {useDreamsData} from "@/app/(site)/(internal)/dashboard/(your-dreams)/components/dreams/DreamsProvider";
import DreamCard from "@/app/(site)/(internal)/dashboard/(your-dreams)/components/dreams/card/DreamCard";
import usePagination from "@/app/(site)/hooks/usePagination";
import Pagination from "@/app/(site)/components/Pagination";
import Input from "@/app/(site)/components/inputs/Input";
import {SearchIcon} from "@nextui-org/shared-icons";
import {Spacer} from "@nextui-org/react";
import DreamCardSkeleton
from "@/app/(site)/(internal)/dashboard/(your-dreams)/components/dreams/card/DreamCardSkeleton";

const MAX_PER_PAGE = 10;

const DraftDreamContainer: FC = () => {
const {dreams} = useDreamsData()
const draftDreams = useMemo(() => dreams.data.filter(dream => dream.isDraft), [dreams.data])
const [dreamSearch, setDreamSearch] = useState<string>()
const {paginatedData, currentPage, totalPages, setCurrentPage} = usePagination(draftDreams, MAX_PER_PAGE, {
filter(draft) {
if (!dreamSearch || dreamSearch.length === 0)
return true;
return draft.title.toLowerCase().includes(dreamSearch.toLowerCase())
},
sort(a, b) {
return new Date(b.createdAt.toString()).getTime() - new Date(a.createdAt.toString()).getTime()
}
})

const draftCards = useMemo(() => paginatedData
.map(dream => (
<DreamCard
key={dream.id}
dream={dream}
hideTime
showCreatedAt
/>
)), [paginatedData])

return (
<div className="w-5/6 phone:w-[85%]">
<Card className="p-12 tablet:py-6 tablet:px-0 phone:px-0">
<CardBody>
<Input
className="w-96 phone:w-full"
label="Search"
placeholder="Search for a draft..."
startContent={<SearchIcon/>}
value={dreamSearch}
onValueChange={setDreamSearch}
/>
<Spacer y={6}/>
<div className="grid grid-cols-3 tablet:grid-cols-2 phone:grid-cols-1 gap-4">
{dreams.loading ? (
<Fragment>
<DreamCardSkeleton/>
<DreamCardSkeleton/>
<DreamCardSkeleton/>
</Fragment>
) : (draftCards.length > 0 ? draftCards :
<p className="text-subtext text-3xl phone:text-medium text-center col-span-2 tablet:col-span-3">You
have no drafts...</p>)}
</div>
</CardBody>
{draftDreams.length > MAX_PER_PAGE && (
<CardFooter>
<Pagination
total={totalPages}
initialPage={0}
page={currentPage}
onChange={setCurrentPage}
/>
</CardFooter>
)}
</Card>
</div>
)
}

export default DraftDreamContainer
20 changes: 20 additions & 0 deletions src/app/(site)/(internal)/dashboard/drafts/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import {FC, Fragment} from "react";
import LogDreamCard from "@/app/(site)/(internal)/dashboard/(your-dreams)/components/dreams/LogDreamCard";
import DraftDreamContainer from "@/app/(site)/(internal)/dashboard/drafts/components/DraftDreamContainer";
import {Spacer} from "@nextui-org/react";

const DreamDraftsPage: FC = () => {
return (
<Fragment>
<h1 id="dash_drafts_title" className="font-bold w-fit text-7xl phone:text-5xl mb-24 phone:mb-10">Your
Drafts</h1>
<LogDreamCard content="New Draft"
className="w-1/4 laptop:w-1/2 tablet:w-3/4 phone:w-[85%] hover:scale-100"/>
<Spacer y={12} />
<DraftDreamContainer/>
</Fragment>

)
}

export default DreamDraftsPage

0 comments on commit 8de795d

Please sign in to comment.