From f744227f6b4e5f61933b5ed9141e00bde96341fd Mon Sep 17 00:00:00 2001 From: pro-minhaj Date: Sun, 4 Aug 2024 09:13:59 +0600 Subject: [PATCH] Implement Admin Dashboard Instructors Page Active Instructor Table --- .../_components/ActiveInstructor.jsx | 34 ++++ .../_components/PendingInstructor.jsx | 10 + .../admin/instructors/_components/columns.jsx | 181 ++++++++++++++++++ app/(admin)/admin/instructors/page.js | 14 +- .../courses/_components/data-table.jsx | 20 +- queries/admin.js | 16 ++ 6 files changed, 255 insertions(+), 20 deletions(-) create mode 100644 app/(admin)/admin/instructors/_components/ActiveInstructor.jsx create mode 100644 app/(admin)/admin/instructors/_components/PendingInstructor.jsx create mode 100644 app/(admin)/admin/instructors/_components/columns.jsx diff --git a/app/(admin)/admin/instructors/_components/ActiveInstructor.jsx b/app/(admin)/admin/instructors/_components/ActiveInstructor.jsx new file mode 100644 index 0000000..0666212 --- /dev/null +++ b/app/(admin)/admin/instructors/_components/ActiveInstructor.jsx @@ -0,0 +1,34 @@ +import { DataTable } from "@/app/dashboard/courses/_components/data-table"; +import { getAdminInstructors } from "@/queries/admin"; +import { columns } from "./columns"; +import { getCourseDetailsByInstructor } from "@/queries/courses"; + +const ActiveInstructor = async () => { + const activeInstructors = await getAdminInstructors("Teacher"); + + const modifiedInstructors = await Promise.all(activeInstructors.map(async instructor => { + const { courses, enrollments, ratings } = await getCourseDetailsByInstructor(instructor?.id); + + return { + id: instructor.id, + role: instructor.role, + image: instructor?.profilePicture?.url, + name: instructor?.firstName + " " + instructor?.lastName, + email: instructor.email, + status: "Active", + courses, + enrollments, + ratings + } + })) + + console.log(modifiedInstructors); + + return ( +
+ +
+ ); +}; + +export default ActiveInstructor; \ No newline at end of file diff --git a/app/(admin)/admin/instructors/_components/PendingInstructor.jsx b/app/(admin)/admin/instructors/_components/PendingInstructor.jsx new file mode 100644 index 0000000..d6db707 --- /dev/null +++ b/app/(admin)/admin/instructors/_components/PendingInstructor.jsx @@ -0,0 +1,10 @@ + +const PendingInstructor = () => { + return ( +
+ +
+ ); +}; + +export default PendingInstructor; \ No newline at end of file diff --git a/app/(admin)/admin/instructors/_components/columns.jsx b/app/(admin)/admin/instructors/_components/columns.jsx new file mode 100644 index 0000000..ced330e --- /dev/null +++ b/app/(admin)/admin/instructors/_components/columns.jsx @@ -0,0 +1,181 @@ +"use client"; + +import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar"; +import { Badge } from "@/components/ui/badge"; +import { Button } from "@/components/ui/button"; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, +} from "@/components/ui/dropdown-menu"; +import { cn } from "@/lib/utils"; +import { GraduationCap, Trash } from "lucide-react"; +import { Star } from "lucide-react"; +import { ArrowUpDown, MoreHorizontal, Pencil } from "lucide-react"; +import Link from "next/link"; + +export const columns = [ + { + accessorKey: "image", + header: ({ column }) => { + return ( + + ); + }, + cell: ({ row }) => { + const photo = row?.original?.image; + const name = row?.original?.name; + + return
+ + + {name.slice(0, 2)} + +
; + }, + }, + { + accessorKey: "name", + header: ({ column }) => { + return ( + + ); + } + }, + { + accessorKey: "email", + header: ({ column }) => { + return ( + + ); + } + }, + { + accessorKey: "courses", + header: ({ column }) => { + return ( + + ); + }, + cell: ({ row }) => { + const courses = row.original.courses; + + return ( +
+ {courses} +
+ ); + }, + }, + { + accessorKey: "enrollments", + header: ({ column }) => { + return ( + + ); + }, + cell: ({ row }) => { + const enrollments = row.original.enrollments; + + return ( +
+ {enrollments} +
+ ); + }, + }, + { + accessorKey: "ratings", + header: ({ column }) => { + return ( + + ); + }, + cell: ({ row }) => { + const ratings = row.original.ratings; + + return ( +
+ {ratings} +
+ ); + }, + }, + { + accessorKey: "status", + header: ({ column }) => { + return ( + + ); + }, + cell: ({ row }) => { + const status = row.original.status; + + return ( + + {status === "Active" && "Active"} + + ); + }, + }, + { + id: "actions", + cell: ({ row }) => { + const { id } = row.original; + + return ( + + + + + + + + + ); + }, + }, +]; diff --git a/app/(admin)/admin/instructors/page.js b/app/(admin)/admin/instructors/page.js index 724fc3b..82988ff 100644 --- a/app/(admin)/admin/instructors/page.js +++ b/app/(admin)/admin/instructors/page.js @@ -1,6 +1,8 @@ import BreadcrumbSection from '@/components/globals/Breadcrumb/BreadcrumbSection'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'; import { cookies } from 'next/headers'; +import ActiveInstructor from './_components/ActiveInstructor'; +import PendingInstructor from './_components/PendingInstructor'; // items const items = [ @@ -20,13 +22,17 @@ const AdminDashboardInstructorPage = () => { <>
- - + + Active Pending - - + + + + + +
diff --git a/app/dashboard/courses/_components/data-table.jsx b/app/dashboard/courses/_components/data-table.jsx index 5b04afe..ef4178d 100644 --- a/app/dashboard/courses/_components/data-table.jsx +++ b/app/dashboard/courses/_components/data-table.jsx @@ -18,11 +18,9 @@ import { } from "@/components/ui/table"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; -import Link from "next/link"; -import { PlusCircle } from "lucide-react"; import { useState } from "react"; -export function DataTable({ columns, data, isAdmin }) { +export function DataTable({ columns, data }) { const [sorting, setSorting] = useState([]); const [columnFilters, setColumnFilters] = useState([]); @@ -45,23 +43,13 @@ export function DataTable({ columns, data, isAdmin }) {
- table.getColumn("title")?.setFilterValue(event.target.value) + table.getColumn("name")?.setFilterValue(event.target.value) } className="max-w-sm" /> - { - !isAdmin && ( - - - - ) - }
diff --git a/queries/admin.js b/queries/admin.js index 0b8a47a..46e5dc7 100644 --- a/queries/admin.js +++ b/queries/admin.js @@ -1,4 +1,6 @@ +import { replaceMongoIdInArray } from '@/lib/convertData'; import Enrollment from '@/modals/enrollment-model'; +import User from '@/modals/users-modal'; export const calculateSales = async () => { const now = new Date(); @@ -95,3 +97,17 @@ export const calculateSales = async () => { percentChange: parseFloat(percentChange.toFixed(2)) }; }; + +export const getAdminInstructors = async (type) => { + try { + const adminInstructors = await User.find({ + role: type + }) + .select('-password') + .lean(); + + return replaceMongoIdInArray(adminInstructors); + } catch (error) { + throw new Error(error); + } +};