diff --git a/src/app/(frontend)/[tenant]/dashboard/layout.tsx b/src/app/(frontend)/[tenant]/dashboard/layout.tsx new file mode 100644 index 0000000..57fb3d2 --- /dev/null +++ b/src/app/(frontend)/[tenant]/dashboard/layout.tsx @@ -0,0 +1,45 @@ +'use client' + +import { SidebarLeft } from '@/components/sidebar-left' +import { + Breadcrumb, + BreadcrumbItem, + BreadcrumbList, + BreadcrumbPage, +} from '@/components/ui/breadcrumb' +import { SidebarInset, SidebarProvider, SidebarTrigger } from '@/components/ui/sidebar' +import { Separator } from '@radix-ui/react-separator' +import { SidebarRight } from '@/components/sidebar-right' +import { DashboardContent } from '@/components/Dashboard' +import { ReactNode } from 'react' + +type Props = { + children: ReactNode +} +// TODO: invesigate error blocking this from being serverside +const DashboardLayout = ({ children }: Props) => { + return ( + + + +
+
+ + + + + + Dashboard + + + +
+
+ {children} +
+ +
+ ) +} + +export default DashboardLayout diff --git a/src/app/(frontend)/[tenant]/dashboard/page.client.tsx b/src/app/(frontend)/[tenant]/dashboard/page.client.tsx index a4968ec..fd7a3a9 100644 --- a/src/app/(frontend)/[tenant]/dashboard/page.client.tsx +++ b/src/app/(frontend)/[tenant]/dashboard/page.client.tsx @@ -1,21 +1,19 @@ 'use client' +import { DashboardContentSection } from '@/components/Dashboard' import { Tenant, User } from '@/payload-types' import useGlobal from '@/stores' -type Props = { - user?: User - tenant?: Tenant -} - -const DashboardPageClient = (props?: Props) => { +const DashboardPageClient = () => { const { user, tenant } = useGlobal() return ( -
-

Testing Dashboard Zustand Data Here

-

{user?.email}

-

{tenant?.name}

-
+ +

Dashboard

+

Username: {user?.username}

+

User Email: {user?.email}

+

Tenant: {tenant?.name}

+

Tenant Slug: {tenant?.slug}

+
) } diff --git a/src/app/(frontend)/[tenant]/dashboard/page.tsx b/src/app/(frontend)/[tenant]/dashboard/page.tsx index eb77a25..fddca83 100644 --- a/src/app/(frontend)/[tenant]/dashboard/page.tsx +++ b/src/app/(frontend)/[tenant]/dashboard/page.tsx @@ -1,41 +1,5 @@ -import { SidebarLeft } from '@/components/sidebar-left' -import { SidebarRight } from '@/components/sidebar-right' -import { - Breadcrumb, - BreadcrumbItem, - BreadcrumbList, - BreadcrumbPage, -} from '@/components/ui/breadcrumb' -import { Separator } from '@/components/ui/separator' -import { SidebarInset, SidebarProvider, SidebarTrigger } from '@/components/ui/sidebar' import DashboardPageClient from './page.client' export default function Page() { - return ( - - - -
-
- - - - - - Dashboard - - - -
-
-
- - -
-
-
-
- -
- ) + return } diff --git a/src/app/(frontend)/[tenant]/dashboard/workouts/layout.client.tsx b/src/app/(frontend)/[tenant]/dashboard/workouts/layout.client.tsx new file mode 100644 index 0000000..b09615d --- /dev/null +++ b/src/app/(frontend)/[tenant]/dashboard/workouts/layout.client.tsx @@ -0,0 +1,43 @@ +'use client' + +import { Exercise, ExerciseType, Workout } from '@/payload-types' +import useWorkouts from '@/stores/Workouts' +import { PaginatedDocs } from 'payload' +import { ReactNode, use, useEffect } from 'react' + +type Props = { + children: ReactNode + getTenantWorkoutsPromise: Promise> + getTenantExercisesPromise: Promise> + getTenantExerciseTypesPromise: Promise> +} +const WorkoutsLayoutSuspendedFrontend = (props: Props) => { + const { + children, + getTenantExerciseTypesPromise, + getTenantExercisesPromise, + getTenantWorkoutsPromise, + } = props + + const exerciseTypeResponse = use(getTenantExerciseTypesPromise) + const exerciseResponse = use(getTenantExercisesPromise) + const workoutResponse = use(getTenantWorkoutsPromise) + + const { setExerciseTypes, setExercises, setWorkouts } = useWorkouts() + + useEffect(() => { + if (exerciseTypeResponse?.docs?.length) setExerciseTypes(exerciseTypeResponse) + }, [exerciseTypeResponse]) + + useEffect(() => { + if (exerciseResponse?.docs?.length) setExercises(exerciseResponse) + }, [exerciseResponse]) + + useEffect(() => { + if (workoutResponse?.docs?.length) setWorkouts(workoutResponse) + }, [workoutResponse]) + + return <>{children} +} + +export default WorkoutsLayoutSuspendedFrontend diff --git a/src/app/(frontend)/[tenant]/dashboard/workouts/layout.tsx b/src/app/(frontend)/[tenant]/dashboard/workouts/layout.tsx new file mode 100644 index 0000000..e2118d0 --- /dev/null +++ b/src/app/(frontend)/[tenant]/dashboard/workouts/layout.tsx @@ -0,0 +1,84 @@ +import { ReactNode } from 'react' +import configPromise from '@payload-config' +import { getPayload, PaginatedDocs } from 'payload' +import WorkoutsLayoutSuspendedFrontend from './layout.client' +import { Exercise, ExerciseType } from '@/payload-types' + +type Props = { + params: Promise<{ + tenant?: string + }> + children: ReactNode +} +const WorkoutsLayout = async (props: Props) => { + const { params, children } = props + const { tenant: tenantSlug } = await params + + const payload = await getPayload({ config: configPromise }) + + const getExerciseTypesPromise = payload.find({ + collection: 'exerciseTypes', + limit: 50, + depth: 0, + select: { + id: true, + name: true, + }, + where: { + 'tenant.slug': { + equals: tenantSlug, + }, + }, + }) as Promise> + + const getTenantExercisesPromise = payload.find({ + collection: 'exercises', + limit: 20, + depth: 0, + select: { + id: true, + name: true, + type: true, + muscleGroup: true, + difficulty: true, + equipmentNeeded: true, + instructions: true, + }, + where: { + 'tenant.slug': { + equals: tenantSlug, + }, + }, + }) as Promise> + + const getWorkoutsPromise = payload.find({ + collection: 'workouts', + limit: 20, + depth: 0, + select: { + id: true, + name: true, + type: true, + difficulty: true, + description: true, + durationMinutes: true, + }, + where: { + 'tenant.slug': { + equals: tenantSlug, + }, + }, + }) as Promise> + + return ( + + {children} + + ) +} + +export default WorkoutsLayout diff --git a/src/app/(frontend)/[tenant]/dashboard/workouts/page.client.tsx b/src/app/(frontend)/[tenant]/dashboard/workouts/page.client.tsx new file mode 100644 index 0000000..5b5890f --- /dev/null +++ b/src/app/(frontend)/[tenant]/dashboard/workouts/page.client.tsx @@ -0,0 +1,15 @@ +'use client' + +import useWorkouts from '@/stores/Workouts' + +const WorkoutsPageClient = () => { + const { exerciseTypes, exercises, workouts } = useWorkouts() + console.log({ + exerciseTypes, + exercises, + workouts, + }) + return
Workout page client
+} + +export default WorkoutsPageClient diff --git a/src/app/(frontend)/[tenant]/dashboard/workouts/page.tsx b/src/app/(frontend)/[tenant]/dashboard/workouts/page.tsx new file mode 100644 index 0000000..60dfea2 --- /dev/null +++ b/src/app/(frontend)/[tenant]/dashboard/workouts/page.tsx @@ -0,0 +1,20 @@ +import { DashboardContent, DashboardContentSection } from '@/components/Dashboard' +// import WorkoutsPageClient from './page.client' + +const WorkoutsPage = () => { + return ( + + +

Workouts

+
+ +

Exercises

+
+ +

Clients

+
+
+ ) +} + +export default WorkoutsPage diff --git a/src/app/(frontend)/[tenant]/layout.suspense.tsx b/src/app/(frontend)/[tenant]/layout.client.tsx similarity index 100% rename from src/app/(frontend)/[tenant]/layout.suspense.tsx rename to src/app/(frontend)/[tenant]/layout.client.tsx diff --git a/src/app/(frontend)/[tenant]/layout.tsx b/src/app/(frontend)/[tenant]/layout.tsx index 2ed9a19..a91eb5e 100644 --- a/src/app/(frontend)/[tenant]/layout.tsx +++ b/src/app/(frontend)/[tenant]/layout.tsx @@ -2,12 +2,12 @@ import configPromise from '@payload-config' import { getPayload, PaginatedDocs } from 'payload' import { headers as getHeaders } from 'next/headers.js' import { ReactNode, Suspense } from 'react' -import RootLayoutSuspenseFrontend from './layout.suspense' +import RootLayoutSuspenseFrontend from './layout.client' import { Tenant } from '@/payload-types' export const metadata = { - title: 'Next.js', - description: 'Generated by Next.js', + title: 'Biotracker', + description: 'Developed by Beitzah.Tech', } type Props = { diff --git a/src/components/Dashboard/DashboardContent.tsx b/src/components/Dashboard/DashboardContent.tsx new file mode 100644 index 0000000..5db66f4 --- /dev/null +++ b/src/components/Dashboard/DashboardContent.tsx @@ -0,0 +1,18 @@ +import { cn } from '@/utilities/ui' +import { ClassValue } from 'clsx' +import { ReactNode } from 'react' + +type Props = { + children: ReactNode + className?: ClassValue +} +const DashboardContent = (props: Props) => { + const { children, className } = props + return ( +
+ {children} +
+ ) +} + +export default DashboardContent diff --git a/src/components/Dashboard/DashboardContentSection.tsx b/src/components/Dashboard/DashboardContentSection.tsx new file mode 100644 index 0000000..5af00b5 --- /dev/null +++ b/src/components/Dashboard/DashboardContentSection.tsx @@ -0,0 +1,19 @@ +import { cn } from '@/utilities/ui' +import { ClassValue } from 'clsx' +import { ReactNode } from 'react' + +type Props = { + children: ReactNode + className?: ClassValue +} +const DashboardContentSection = (props: Props) => { + const { children, className } = props + + return ( +
+ {children} +
+ ) +} + +export default DashboardContentSection diff --git a/src/components/Dashboard/index.tsx b/src/components/Dashboard/index.tsx new file mode 100644 index 0000000..2d75db3 --- /dev/null +++ b/src/components/Dashboard/index.tsx @@ -0,0 +1,4 @@ +import DashboardContent from './DashboardContent' +import DashboardContentSection from './DashboardContentSection' + +export { DashboardContent, DashboardContentSection } diff --git a/src/stores/Workouts.ts b/src/stores/Workouts.ts new file mode 100644 index 0000000..6c67c5b --- /dev/null +++ b/src/stores/Workouts.ts @@ -0,0 +1,28 @@ +import { create } from 'zustand' +import { Exercise, ExerciseType, Workout } from '@/payload-types' +import { PaginatedDocs } from 'payload' + +export type WorkoutsProps = { + exercises?: PaginatedDocs, + exerciseTypes?: PaginatedDocs, + workouts?: PaginatedDocs, +} + +export type WorkoutsMethods = { + setExercises: (exercises?: PaginatedDocs) => void, + setExerciseTypes: (exerciseTypes?: PaginatedDocs) => void, + setWorkouts: (workouts?: PaginatedDocs) => void, +} + +export type WorkoutsStore = WorkoutsProps & WorkoutsMethods + +const useWorkouts = create((set) => ({ + exercises: undefined, + exerciseTypes: undefined, + workouts: undefined, + setExercises: (exercises?: PaginatedDocs) => set(() => ({ exercises: exercises })), + setExerciseTypes: (exerciseTypes?: PaginatedDocs) => set(() => ({ exerciseTypes: exerciseTypes })), + setWorkouts: (workouts?: PaginatedDocs) => set(() => ({ workouts: workouts })), +})) + +export default useWorkouts