diff --git a/src/app/(dashboard)/dashboard/configurations/page.tsx b/src/app/(dashboard)/dashboard/configurations/page.tsx
index 01bec97..bc9a2c8 100644
--- a/src/app/(dashboard)/dashboard/configurations/page.tsx
+++ b/src/app/(dashboard)/dashboard/configurations/page.tsx
@@ -1,7 +1,6 @@
import Breadcrumb from "@/components/breadcrumb";
import ToolsTable from "@/components/configurations-table/tools-table";
-import { dummyAccounts, dummyConfigurations } from "@/constants/data";
-import { Account } from "@/types/account";
+import { dummyConfigurations } from "@/constants/data";
import { Configuration } from "@/types/configuration";
import React from "react";
diff --git a/src/app/(dashboard)/dashboard/course-admin/page.tsx b/src/app/(dashboard)/dashboard/course-admin/page.tsx
new file mode 100644
index 0000000..2d9775b
--- /dev/null
+++ b/src/app/(dashboard)/dashboard/course-admin/page.tsx
@@ -0,0 +1,20 @@
+import Breadcrumb from "@/components/breadcrumb";
+import ToolsTable from "@/components/course-admin-table/tools-table";
+import { dummyCourseAdmin } from "@/constants/data";
+import { CourseAdmin } from "@/types/course-admin";
+import React from "react";
+
+const breadcrumbItems = [
+ { title: "Dashboard", link: "#" },
+ { title: "Course Admin" },
+];
+const Page = () => {
+ return (
+
+
+
+
+ );
+};
+
+export default Page;
diff --git a/src/app/layout.tsx b/src/app/layout.tsx
index a0926fb..3ccc44d 100644
--- a/src/app/layout.tsx
+++ b/src/app/layout.tsx
@@ -8,7 +8,7 @@ import { cn } from "@/lib/utils";
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
- title: "Skilld Admin Dashboard",
+ title: "Dashboard | Skilld Admin",
description: "Skilld Admin Dashboard",
};
diff --git a/src/components/course-admin-table/cell-action.tsx b/src/components/course-admin-table/cell-action.tsx
new file mode 100644
index 0000000..e2c49d9
--- /dev/null
+++ b/src/components/course-admin-table/cell-action.tsx
@@ -0,0 +1,68 @@
+"use client";
+import { AlertModal } from "@/components/alert-modal";
+import { Button } from "@/components/ui/button";
+import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuLabel,
+ DropdownMenuTrigger,
+} from "@/components/ui/dropdown-menu";
+import { useToast } from "@/components/ui/use-toast";
+import { CourseAdmin } from "@/types/course-admin";
+
+import { Edit, MoreHorizontal, Trash } from "lucide-react";
+import { useRouter } from "next/navigation";
+import { useState } from "react";
+
+interface CellActionProps {
+ data: CourseAdmin;
+}
+
+export const CellAction: React.FC = ({ data }) => {
+ const [loading, setLoading] = useState(false);
+ const [isDeleteModalOpen, setIsDeleteModalOpen] = useState(false);
+ const router = useRouter();
+ const { toast } = useToast();
+
+ const onDeleteConfirm = async () => {};
+
+ const handleUpdateStatus = async () => {};
+
+ return (
+ <>
+ setIsDeleteModalOpen(false)}
+ onConfirm={onDeleteConfirm}
+ loading={loading}
+ />
+
+
+
+
+
+ Actions
+
+
+ // router.push(`#`)
+ // }
+ >
+ Update
+
+ setIsDeleteModalOpen(true)}
+ >
+ Delete
+
+
+
+ >
+ );
+};
diff --git a/src/components/course-admin-table/columns.tsx b/src/components/course-admin-table/columns.tsx
new file mode 100644
index 0000000..27ffd69
--- /dev/null
+++ b/src/components/course-admin-table/columns.tsx
@@ -0,0 +1,116 @@
+"use client";
+import { DataTableColumnHeader } from "./data-table-column-header";
+import { CellAction } from "./cell-action";
+import { ColumnDef } from "@tanstack/react-table";
+import {
+ HoverCard,
+ HoverCardContent,
+ HoverCardTrigger,
+} from "@/components/ui/hover-card";
+import { Checkbox } from "@/components/ui/checkbox";
+import { formatDate } from "@/lib/format-date";
+import { CourseAdmin } from "@/types/course-admin";
+
+export const columns: ColumnDef[] = [
+ {
+ id: "select",
+ header: ({ table }) => (
+ table.toggleAllPageRowsSelected(!!value)}
+ aria-label="Select all"
+ className="translate-y-[2px]"
+ />
+ ),
+ cell: ({ row }) => (
+ row.toggleSelected(!!value)}
+ aria-label="Select row"
+ className="translate-y-[2px]"
+ />
+ ),
+ enableSorting: false,
+ enableHiding: false,
+ },
+
+ {
+ accessorKey: "title",
+ header: ({ column }) => (
+
+ ),
+ cell: ({ row }) => {
+ return (
+
+
+
+ {row.getValue("title")}
+ {/*
+ {row.getValue("title")}
+
*/}
+
+
+ {/* */}
+ {row.getValue("title")}
+ {/* */}
+ {/* */}
+
+
+
+ );
+ },
+ },
+
+ {
+ accessorKey: "skill",
+ header: ({ column }) => (
+
+ ),
+ cell: ({ row }) => {
+ return (
+
+
+
+ {/*
+ {row.getValue("email")}
+
*/}
+ {row.getValue("skill")}
+
+
+ {/* */}
+ {row.getValue("skill")}
+ {/* */}
+ {/* */}
+
+
+
+ );
+ },
+ },
+
+ {
+ accessorKey: "created_at",
+ header: ({ column }) => (
+
+ ),
+ cell: ({ row }) => {
+ return {formatDate(row.getValue("created_at"))}
;
+ },
+ filterFn: (row, id, value) => {
+ return value.includes(row.getValue(id));
+ },
+ },
+
+ {
+ id: "actions",
+ header: ({ column }) => (
+
+ ),
+ cell: ({ row }) => ,
+ },
+];
diff --git a/src/components/course-admin-table/data-table-column-header.tsx b/src/components/course-admin-table/data-table-column-header.tsx
new file mode 100644
index 0000000..85df45e
--- /dev/null
+++ b/src/components/course-admin-table/data-table-column-header.tsx
@@ -0,0 +1,72 @@
+import {
+ ArrowDownIcon,
+ ArrowUpIcon,
+ CaretSortIcon,
+ EyeNoneIcon,
+ } from "@radix-ui/react-icons"
+ import { Column } from "@tanstack/react-table"
+
+ import { cn } from "@/lib/utils"
+ import { Button } from "@/components/ui/button"
+ import {
+ DropdownMenu,
+ DropdownMenuContent,
+ DropdownMenuItem,
+ DropdownMenuSeparator,
+ DropdownMenuTrigger,
+ } from "@/components/ui/dropdown-menu"
+
+ interface DataTableColumnHeaderProps
+ extends React.HTMLAttributes {
+ column: Column
+ title: string
+ }
+
+ export function DataTableColumnHeader({
+ column,
+ title,
+ className,
+ }: DataTableColumnHeaderProps) {
+ if (!column.getCanSort()) {
+ return {title}
+ }
+
+
+ return (
+
+
+
+
+
+
+ column.toggleSorting(false)}>
+
+ Asc
+
+ column.toggleSorting(true)}>
+
+ Desc
+
+
+ column.toggleVisibility(false)}>
+
+ Hide
+
+
+
+
+ )
+ }
\ No newline at end of file
diff --git a/src/components/course-admin-table/data-table-faceted-filter.tsx b/src/components/course-admin-table/data-table-faceted-filter.tsx
new file mode 100644
index 0000000..a5efee2
--- /dev/null
+++ b/src/components/course-admin-table/data-table-faceted-filter.tsx
@@ -0,0 +1,147 @@
+import * as React from "react"
+import { CheckIcon, PlusCircledIcon } from "@radix-ui/react-icons"
+import { Column } from "@tanstack/react-table"
+
+import { cn } from "@/lib/utils"
+import { Badge } from "@/components/ui/badge"
+import { Button } from "@/components/ui/button"
+import {
+ Command,
+ CommandEmpty,
+ CommandGroup,
+ CommandInput,
+ CommandItem,
+ CommandList,
+ CommandSeparator,
+} from "@/components/ui/command"
+import {
+ Popover,
+ PopoverContent,
+ PopoverTrigger,
+} from "@/components/ui/popover"
+import { Separator } from "@/components/ui/separator"
+
+interface DataTableFacetedFilterProps {
+ column?: Column
+ title?: string
+ options: {
+ label: string
+ value: string
+ icon?: React.ComponentType<{ className?: string }>
+ }[]
+}
+
+export function DataTableFacetedFilter({
+ column,
+ title,
+ options,
+}: DataTableFacetedFilterProps) {
+ const facets = column?.getFacetedUniqueValues()
+ const selectedValues = new Set(column?.getFilterValue() as string[])
+
+ return (
+
+
+
+
+
+
+
+
+ No results found.
+
+ {options.map((option) => {
+ const isSelected = selectedValues.has(option.value)
+ return (
+ {
+ if (isSelected) {
+ selectedValues.delete(option.value)
+ } else {
+ selectedValues.add(option.value)
+ }
+ const filterValues = Array.from(selectedValues)
+ column?.setFilterValue(
+ filterValues.length ? filterValues : undefined
+ )
+ }}
+ >
+
+
+
+ {option.icon && (
+
+ )}
+ {option.label}
+ {facets?.get(option.value) && (
+
+ {facets.get(option.value)}
+
+ )}
+
+ )
+ })}
+
+ {selectedValues.size > 0 && (
+ <>
+
+
+ column?.setFilterValue(undefined)}
+ className="justify-center text-center"
+ >
+ Clear filters
+
+
+ >
+ )}
+
+
+
+
+ )
+}
\ No newline at end of file
diff --git a/src/components/course-admin-table/data-table-pagination.tsx b/src/components/course-admin-table/data-table-pagination.tsx
new file mode 100644
index 0000000..3c5a1d9
--- /dev/null
+++ b/src/components/course-admin-table/data-table-pagination.tsx
@@ -0,0 +1,97 @@
+import {
+ ChevronLeftIcon,
+ ChevronRightIcon,
+ DoubleArrowLeftIcon,
+ DoubleArrowRightIcon,
+} from "@radix-ui/react-icons";
+import { Table } from "@tanstack/react-table";
+
+import { Button } from "@/components/ui/button";
+import {
+ Select,
+ SelectContent,
+ SelectItem,
+ SelectTrigger,
+ SelectValue,
+} from "@/components/ui/select";
+
+interface DataTablePaginationProps {
+ table: Table;
+}
+
+export function DataTablePagination({
+ table,
+}: DataTablePaginationProps) {
+ return (
+
+
+ {table.getFilteredSelectedRowModel().rows.length} of{" "}
+ {table.getFilteredRowModel().rows.length} row(s) selected.
+
+
+
Rows per page
+
+
+
+
+ Page {table.getState().pagination.pageIndex + 1} of{" "}
+ {table.getPageCount()}
+
+
+
+
+
+
+
+
+
+ );
+}
diff --git a/src/components/course-admin-table/data-table-toolbar.tsx b/src/components/course-admin-table/data-table-toolbar.tsx
new file mode 100644
index 0000000..1fe9853
--- /dev/null
+++ b/src/components/course-admin-table/data-table-toolbar.tsx
@@ -0,0 +1,76 @@
+"use client";
+
+import { Cross2Icon } from "@radix-ui/react-icons";
+import { Table } from "@tanstack/react-table";
+
+import { Button } from "@/components/ui/button";
+import { Input } from "@/components/ui/input";
+// import { DataTableViewOptions } from "./components/data-table-view-options"
+
+import { DataTableFacetedFilter } from "./data-table-faceted-filter";
+import { DataTableViewOptions } from "./data-table-view-options";
+import { userFilterLabels } from "@/constants/data";
+import { Organization } from "@/types/organization";
+
+interface DataTableToolbarProps {
+ table: Table;
+ data: Organization[];
+}
+
+export function DataTableToolbar({
+ table,
+ data,
+}: DataTableToolbarProps) {
+ const isFiltered = table.getState().columnFilters.length > 0;
+
+ // const industryFilterOptions = Array.from(
+ // new Set(data.map((d) => d.industry.toLocaleLowerCase()))
+ // ).map((v) => ({
+ // label: v.slice(0, 1).toLocaleUpperCase() + v.slice(1),
+ // value: v.slice(0, 1).toLocaleUpperCase() + v.slice(1),
+ // }));
+
+ return (
+
+ );
+}
diff --git a/src/components/course-admin-table/data-table-view-options.tsx b/src/components/course-admin-table/data-table-view-options.tsx
new file mode 100644
index 0000000..6d56347
--- /dev/null
+++ b/src/components/course-admin-table/data-table-view-options.tsx
@@ -0,0 +1,59 @@
+"use client"
+
+import { DropdownMenuTrigger } from "@radix-ui/react-dropdown-menu"
+import { MixerHorizontalIcon } from "@radix-ui/react-icons"
+import { Table } from "@tanstack/react-table"
+
+import { Button } from "@/components/ui/button"
+import {
+ DropdownMenu,
+ DropdownMenuCheckboxItem,
+ DropdownMenuContent,
+ DropdownMenuLabel,
+ DropdownMenuSeparator,
+} from "@/components/ui/dropdown-menu"
+
+interface DataTableViewOptionsProps {
+ table: Table
+}
+
+export function DataTableViewOptions({
+ table,
+}: DataTableViewOptionsProps) {
+ return (
+
+
+
+
+
+ Toggle columns
+
+ {table
+ .getAllColumns()
+ .filter(
+ (column) =>
+ typeof column.accessorFn !== "undefined" && column.getCanHide()
+ )
+ .map((column) => {
+ return (
+ column.toggleVisibility(!!value)}
+ >
+ {column.id}
+
+ )
+ })}
+
+
+ )
+}
\ No newline at end of file
diff --git a/src/components/course-admin-table/data-table.tsx b/src/components/course-admin-table/data-table.tsx
new file mode 100644
index 0000000..5879ceb
--- /dev/null
+++ b/src/components/course-admin-table/data-table.tsx
@@ -0,0 +1,131 @@
+"use client";
+
+import * as React from "react";
+import {
+ ColumnDef,
+ ColumnFiltersState,
+ SortingState,
+ VisibilityState,
+ flexRender,
+ getCoreRowModel,
+ getFacetedRowModel,
+ getFacetedUniqueValues,
+ getFilteredRowModel,
+ getPaginationRowModel,
+ getSortedRowModel,
+ useReactTable,
+} from "@tanstack/react-table";
+
+import {
+ Table,
+ TableBody,
+ TableCell,
+ TableHead,
+ TableHeader,
+ TableRow,
+} from "@/components/ui/table";
+
+import { DataTablePagination } from "./data-table-pagination";
+import { DataTableToolbar } from "./data-table-toolbar";
+import { ScrollArea, ScrollBar } from "@/components/ui/scroll-area";
+import { Organization } from "@/types/organization";
+
+interface DataTableProps {
+ columns: ColumnDef[];
+ data: TData[];
+}
+
+export function DataTable({
+ columns,
+ data,
+}: DataTableProps) {
+ const [rowSelection, setRowSelection] = React.useState({});
+ const [columnVisibility, setColumnVisibility] =
+ React.useState({});
+ const [columnFilters, setColumnFilters] = React.useState(
+ []
+ );
+ const [sorting, setSorting] = React.useState([]);
+
+ const table = useReactTable({
+ data,
+ columns,
+ state: {
+ sorting,
+ columnVisibility,
+ rowSelection,
+ columnFilters,
+ },
+ enableRowSelection: true,
+ onRowSelectionChange: setRowSelection,
+ onSortingChange: setSorting,
+ onColumnFiltersChange: setColumnFilters,
+ onColumnVisibilityChange: setColumnVisibility,
+ getCoreRowModel: getCoreRowModel(),
+ getFilteredRowModel: getFilteredRowModel(),
+ getPaginationRowModel: getPaginationRowModel(),
+ getSortedRowModel: getSortedRowModel(),
+ getFacetedRowModel: getFacetedRowModel(),
+ getFacetedUniqueValues: getFacetedUniqueValues(),
+ });
+
+ return (
+
+
+ {/*
*/}
+
+
+
+ {table.getHeaderGroups().map((headerGroup) => (
+
+ {headerGroup.headers.map((header) => {
+ return (
+
+ {header.isPlaceholder
+ ? null
+ : flexRender(
+ header.column.columnDef.header,
+ header.getContext()
+ )}
+
+ );
+ })}
+
+ ))}
+
+
+ {table.getRowModel().rows?.length ? (
+ table.getRowModel().rows.map((row) => (
+
+ {row.getVisibleCells().map((cell) => (
+
+ {flexRender(
+ cell.column.columnDef.cell,
+ cell.getContext()
+ )}
+
+ ))}
+
+ ))
+ ) : (
+
+
+ No results.
+
+
+ )}
+
+
+
+
+ {/*
*/}
+
+
+ );
+}
diff --git a/src/components/course-admin-table/tools-table.tsx b/src/components/course-admin-table/tools-table.tsx
new file mode 100644
index 0000000..c5104ad
--- /dev/null
+++ b/src/components/course-admin-table/tools-table.tsx
@@ -0,0 +1,45 @@
+"use client";
+
+import { Heading } from "@/components/ui/heading";
+import { Separator } from "@/components/ui/separator";
+import React from "react";
+import { DataTable } from "./data-table";
+import { columns } from "./columns";
+import Link from "next/link";
+import { Plus } from "lucide-react";
+import { buttonVariants } from "@/components/ui/button";
+import { Account } from "@/types/account";
+import { Configuration } from "@/types/configuration";
+import { CourseAdmin } from "@/types/course-admin";
+
+const ToolsTable = ({
+ courseAdmin,
+}: {
+ courseAdmin: CourseAdmin[];
+}) => {
+ return (
+ <>
+
+
+
router.push(`/admin-dashboard/tools/add`)}
+ >
+
Add Course
+
+
+
+
+ >
+ );
+};
+
+export default ToolsTable;
diff --git a/src/constants/data.ts b/src/constants/data.ts
index eb6fd8a..5bc2ef3 100644
--- a/src/constants/data.ts
+++ b/src/constants/data.ts
@@ -163,3 +163,18 @@ export const dummyApiCommunications: ApiCommunication[] = [
created_at: new Date().toISOString(),
},
];
+
+export const dummyCourseAdmin = [
+ {
+ id: 1,
+ title: "How to use the gitextractor",
+ skill: "git (3)",
+ created_at: new Date().toISOString(),
+ },
+ {
+ id: 1,
+ title: "Develop a Blogging System in Symfony 6",
+ skill: "PHP (7), Symfony (7)",
+ created_at: new Date().toISOString(),
+ },
+];
diff --git a/src/types/course-admin.ts b/src/types/course-admin.ts
new file mode 100644
index 0000000..0118264
--- /dev/null
+++ b/src/types/course-admin.ts
@@ -0,0 +1,6 @@
+export interface CourseAdmin {
+ id: number;
+ title: string;
+ skill: string;
+ created_at: string;
+}
\ No newline at end of file