feat: add page to view schedule meeting for business

This commit is contained in:
Sosokker 2024-11-14 12:07:45 +07:00
parent bf1226a704
commit af351aa481
4 changed files with 246 additions and 0 deletions

View File

@ -0,0 +1,101 @@
"use client";
import React from "react";
import { Button } from "@/components/ui/button";
import {
Dialog,
DialogClose,
DialogContent,
DialogDescription,
DialogFooter,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
import { Table, TableBody, TableCell, TableFooter, TableHead, TableHeader, TableRow } from "@/components/ui/table";
import { Clock } from "lucide-react";
import { createSupabaseClient } from "@/lib/supabase/clientComponentClient";
import getMeetingLog from "./actions";
import { useQuery } from "@supabase-cache-helpers/postgrest-react-query";
import { LegacyLoader } from "@/components/loading/LegacyLoader";
interface DialogProps {
children?: React.ReactNode;
open?: boolean;
defaultOpen?: boolean;
// eslint-disable-next-line no-unused-vars
onOpenChange?(open: boolean): void;
modal?: boolean;
projectId: number;
}
export function ManageMeetDialog(props: DialogProps) {
const supabase = createSupabaseClient();
const {
data: meetingLog,
error: meetingLogError,
isLoading: isLoadingMeetingLog,
} = useQuery(getMeetingLog(supabase, props.projectId), {
enabled: !!props.projectId,
});
return (
<Dialog {...props}>
<DialogContent className="sm:max-w-md overflow-y-auto h-[80%]">
<DialogHeader>
<DialogTitle className="flex gap-2 items-center">
<Clock />
Meeting Request
</DialogTitle>
<DialogDescription>List of meeting you need to attend.</DialogDescription>
</DialogHeader>
{meetingLogError ? (
<div>Error Loading data</div>
) : isLoadingMeetingLog ? (
<LegacyLoader />
) : meetingLog && meetingLog.length > 0 ? (
<Table>
<TableHeader>
<TableRow>
<TableHead className="w-[100px]">Date</TableHead>
<TableHead>Start Time</TableHead>
<TableHead>End Time</TableHead>
<TableHead>User</TableHead>
<TableHead>Note</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{meetingLog.map((log) => (
<TableRow key={log.id}>
<TableCell className="font-medium">{log.meet_date}</TableCell>
<TableCell>{log.start_time}</TableCell>
<TableCell>{log.end_time}</TableCell>
<TableCell>{log.user_id}</TableCell>
<TableCell>{log.note || "No note provided"}</TableCell>
</TableRow>
))}
</TableBody>
<TableFooter>
<TableRow>
<TableCell colSpan={5} className="text-right">
Total Meetings: {meetingLog.length}
</TableCell>
</TableRow>
</TableFooter>
</Table>
) : (
<div>No meeting logs available</div>
)}
<DialogFooter className="sm:justify-start mt-4">
<DialogClose asChild>
<Button type="button" variant="secondary">
Close
</Button>
</DialogClose>
</DialogFooter>
</DialogContent>
</Dialog>
);
}

View File

@ -0,0 +1,63 @@
"use client";
import { useState } from "react";
import { Separator } from "@/components/ui/separator";
import { Card, CardContent, CardDescription, CardTitle, CardHeader, CardFooter } from "@/components/ui/card";
import { Tooltip, TooltipProvider, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
import { ManageMeetDialog } from "./ManageMeetDialog";
import { Button } from "@/components/ui/button";
type ProjectCardSectionProps = {
id: number;
project_name: string;
project_short_description: string;
business_id: {
user_id: string;
};
dataroom_id: number | null;
};
type ProjectCardCalendarManageSectionProps = {
projectData: ProjectCardSectionProps[] | null;
};
export default function ProjectCardCalendarManageSection({ projectData }: ProjectCardCalendarManageSectionProps) {
const [showMeetModal, setShowMeetModal] = useState<boolean>(false);
const [currentProjectId, setCurrentProjectId] = useState<number | undefined>(undefined);
return (
<div id="content" className="grid grid-cols-2 space-x-2">
{projectData != null ? (
projectData.map((project) => (
<Card key={project.id} className="mb-3">
<CardHeader className="h-[55%]">
<CardTitle>{project.project_name}</CardTitle>
<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<CardDescription className="line-clamp-1">{project.project_short_description}</CardDescription>
</TooltipTrigger>
<TooltipContent>{project.project_short_description}</TooltipContent>
</Tooltip>
</TooltipProvider>
</CardHeader>
<Separator className="mb-3" />
<CardContent>
<Button
onClick={() => {
setCurrentProjectId(project.id);
setTimeout(() => setShowMeetModal(true), 0);
}}
>
Meeting List
</Button>
</CardContent>
<CardFooter></CardFooter>
</Card>
))
) : (
<div>No data</div>
)}
<ManageMeetDialog open={showMeetModal} onOpenChange={setShowMeetModal} projectId={currentProjectId!} />
</div>
);
}

View File

@ -0,0 +1,20 @@
import { Database } from "@/types/database.types";
import { SupabaseClient } from "@supabase/supabase-js";
export default function getMeetingLog(client: SupabaseClient<Database>, projectId: number) {
return client
.from("meeting_log")
.select(
`
id,
meet_date,
start_time,
end_time,
note,
user_id,
project_id,
created_at
`
)
.eq("project_id", projectId);
}

View File

@ -0,0 +1,62 @@
import { Separator } from "@/components/ui/separator";
import { Clock } from "lucide-react";
import { createSupabaseClient } from "@/lib/supabase/serverComponentClient";
import { getProjectByUserId } from "@/lib/data/projectQuery";
import { Suspense } from "react";
import { LegacyLoader } from "@/components/loading/LegacyLoader";
import { getUserRole } from "@/lib/data/userQuery";
import { Button } from "@/components/ui/button";
import Link from "next/link";
import ProjectCardCalendarManageSection from "./ProjectCardSection";
export default async function ManageMeetingPage() {
const supabase = createSupabaseClient();
const { data: user, error: userError } = await supabase.auth.getUser();
if (userError) {
throw "Can't get user data!";
}
const userId = user.user?.id;
const { data: roleData, error: roleDataError } = await getUserRole(supabase, userId);
if (roleDataError) {
throw "Error fetching user data";
}
if (!roleData || roleData.role != "business") {
return (
<div className="container max-w-screen-xl">
<span className="flex gap-2 items-center mt-4">
<Clock />
<p className="text-2xl font-bold">Manage Meeting Request</p>
</span>
<Separator className="my-3" />
<div className="mb-3 mt-2">Please apply for business first to access functionalities of busienss account</div>
<Link href="/business/apply">
<Button>Apply for business</Button>
</Link>
</div>
);
}
const { data: projectData, error: projectDataError } = await getProjectByUserId(supabase, userId);
if (projectDataError) {
throw "Can't get project data";
}
return (
<div className="container max-w-screen-xl">
<span className="flex gap-2 items-center mt-4">
<Clock />
<p className="text-2xl font-bold">Manage Meeting Request</p>
</span>
<Separator className="my-3" />
<Suspense fallback={<LegacyLoader />}>
<ProjectCardCalendarManageSection projectData={projectData} />
</Suspense>
</div>
);
}