diff --git a/apps/backoffice/public/images/asd687hwq6nds4dfjj2983.webp b/apps/backoffice/public/images/asd687hwq6nds4dfjj2983.webp new file mode 100644 index 0000000..b4555c9 Binary files /dev/null and b/apps/backoffice/public/images/asd687hwq6nds4dfjj2983.webp differ diff --git a/apps/backoffice/src/app/(protected)/dashboard-dimentorin/_components/chart/session-status.tsx b/apps/backoffice/src/app/(protected)/dashboard-dimentorin/_components/chart/session-status.tsx new file mode 100644 index 0000000..e0bfcd0 --- /dev/null +++ b/apps/backoffice/src/app/(protected)/dashboard-dimentorin/_components/chart/session-status.tsx @@ -0,0 +1,52 @@ +import { Cell, Pie, PieChart, ResponsiveContainer, Tooltip } from "recharts" +import { PieLabelProps } from "recharts/types/polar/Pie" + +type ChartProps = { + name: string + value: number + color: string +} + +const chartData: ChartProps[] = [ + { name: "Active", value: 49, color: "#23A1EB" }, + { name: "Done", value: 24, color: "#81CBF8" }, + { name: "Canceled", value: 27, color: "#BCE1FB" }, +] + +const RADIAN = Math.PI / 180; +const renderCustomizedLabel = ({ cx, cy, midAngle, innerRadius, outerRadius, percent }: PieLabelProps) => { + const radius = innerRadius + (outerRadius - innerRadius) * 0.5; + const x = cx + radius * Math.cos(-(midAngle ?? 0) * RADIAN); + const y = cy + radius * Math.sin(-(midAngle ?? 0) * RADIAN); + + return ( + cx ? 'start' : 'end'} dominantBaseline="central"> + {`${((percent ?? 1) * 100).toFixed(0)}%`} + + ); +}; + +export const SessionStatusChart = () => { + return ( + + + + {chartData.map((entry, index) => ( + + ))} + + + + + ) +} diff --git a/apps/backoffice/src/app/(protected)/dashboard-dimentorin/_components/chart/user-growth.tsx b/apps/backoffice/src/app/(protected)/dashboard-dimentorin/_components/chart/user-growth.tsx new file mode 100644 index 0000000..2f6dd71 --- /dev/null +++ b/apps/backoffice/src/app/(protected)/dashboard-dimentorin/_components/chart/user-growth.tsx @@ -0,0 +1,36 @@ +import { CartesianGrid, Legend, Line, LineChart, ResponsiveContainer, Tooltip, XAxis, YAxis } from "recharts" + +type ChartProps = { + name: string + activeUser: number + activeSession: number +} + +const chartData: ChartProps[] = [ + { name: "2014", activeUser: 0, activeSession: 0 }, + { name: "2015", activeUser: 15, activeSession: 25 }, + { name: "2016", activeUser: 30, activeSession: 40 }, + { name: "2017", activeUser: 45, activeSession: 55 }, + { name: "2018", activeUser: 60, activeSession: 70 }, + { name: "2019", activeUser: 75, activeSession: 85 }, + { name: "2020", activeUser: 90, activeSession: 95 }, + { name: "2021", activeUser: 85, activeSession: 80 }, + { name: "2022", activeUser: 95, activeSession: 90 }, + { name: "2023", activeUser: 100, activeSession: 100 }, +] + +export const UserGrowthChart = () => { + return ( + + + + + + + + + + + + ) +} \ No newline at end of file diff --git a/apps/backoffice/src/app/(protected)/dashboard-dimentorin/page.tsx b/apps/backoffice/src/app/(protected)/dashboard-dimentorin/page.tsx new file mode 100644 index 0000000..e22b1d4 --- /dev/null +++ b/apps/backoffice/src/app/(protected)/dashboard-dimentorin/page.tsx @@ -0,0 +1,115 @@ +import { Button } from "@imphnen-frontend-service/ui/atoms"; +import { BackofficeWrapper } from "@imphnen-frontend-service/ui/organisms"; +import { For } from "@imphnen-frontend-service/utils"; +import { ReactElement } from "react"; +import { UserGrowthChart } from "./_components/chart/user-growth"; +import { SessionStatusChart } from "./_components/chart/session-status"; + +const Overview = () => { + return ( +
+

0

+

Total Users

+
+ ) +} + +export default function Components(): ReactElement { + return ( + +

Overview

+ +
+
+ + +
+ + {(_, index) => } + +
+
+ +
+ + +
+
+
+

User Growth

+
+
+ +
+
+

Session Status

+ +
+
+
+ +
+
+

Top 5 Mentors

+ +
+ + + + + + + + + + + + {(_, index) => ( + + + + + + )} + + +
No.Nama LengkapAvg Rating
{index + 1}Mursid Al-Catraz4.9
+
+
+ +
+

Top Booked Mentoring Topics

+ +
+ + + + + + + + + + + + {(_, index) => ( + + + + + + )} + + +
No.Nama LengkapTotal Sesi
{index + 1}Mursid Al-Catraz1000
+
+
+
+
+
+ ) +} \ No newline at end of file diff --git a/apps/backoffice/src/app/(protected)/feedback-review-dimentorin/page.tsx b/apps/backoffice/src/app/(protected)/feedback-review-dimentorin/page.tsx new file mode 100644 index 0000000..6fc556a --- /dev/null +++ b/apps/backoffice/src/app/(protected)/feedback-review-dimentorin/page.tsx @@ -0,0 +1,181 @@ +import { SearchOutlined } from "@ant-design/icons"; +import { Button, Input, Select } from "@imphnen-frontend-service/ui/atoms"; +import { BackofficeWrapper, DataTable } from "@imphnen-frontend-service/ui/organisms"; +import { cn, For } from "@imphnen-frontend-service/utils"; +import { ColumnDef, getCoreRowModel, getPaginationRowModel, PaginationState, RowSelectionState, useReactTable } from "@tanstack/react-table"; +import { ReactElement, useState } from "react" + +const TABS = { + MENTORING: 'Mentoring', + PLATFORM: 'Platform' +} as const +type Tabs = typeof TABS[keyof typeof TABS] + +type FeedbackStatus = 'done' | 'todo'; + +interface FeedbackType { + id: number + name: string + email: string + rating: number + status: FeedbackStatus +} + +const mockData: FeedbackType[] = Array.from({ length: 90 }, (_, i) => ({ + id: i + 1, + name: i % 3 === 0 ? 'Ahmad Wijuana' : 'Sofia Wijuana', + email: 'fullname23@gmail.com', + rating: 4.5, + status: i % 2 === 0 ? 'done' : 'todo', +})) + +export default function Components(): ReactElement { + const [activeTab, setActiveTab] = useState(TABS.MENTORING) + + const [rowSelection, setRowSelection] = useState({}) + const [pagination, setPagination] = useState({ + pageIndex: 0, + pageSize: 9, + }); + + const columns: ColumnDef[] = [ + { + id: 'select', + meta: { cellClassName: cn("w-20") }, + header: ({ table }) => ( + + ), + cell: ({ row }) => ( + + ), + }, + { + id: 'name', + header: 'Name', + accessorKey: 'name', + }, + { + id: 'email', + header: 'Email', + accessorKey: 'email', + }, + { + id: 'rating', + header: 'Rating', + accessorKey: 'rating', + }, + { + id: 'status', + header: 'Status', + accessorKey: 'status', + cell: ({ row }) => { + const status = row.original.status; + const statusColors: Record = { + done: 'bg-success-200 text-success-500', + todo: 'bg-primary-200 text-primary-500', + }; + const statusText: Record = { + done: 'Done', + todo: 'To Do', + }; + return ( +
+ {statusText[status]} +
+ ); + }, + }, + { + header: 'Action', + meta: { cellClassName: cn("w-72") }, + cell: ({ row }) => ( + + ), + }, + ] + + const table = useReactTable({ + data: mockData, + columns, + state: { + pagination, + rowSelection, + }, + enableRowSelection: true, + onRowSelectionChange: setRowSelection, + getCoreRowModel: getCoreRowModel(), + getPaginationRowModel: getPaginationRowModel(), + onPaginationChange: setPagination, + pageCount: Math.ceil(mockData.length / pagination.pageSize), + manualPagination: false, + }); + + return ( + +
+

Feedback

+
+ + {(tab) => ( + + )} + +
+
+ +
+
+
+ +
+ +
+
+ + +
+ + +
+
+ ); +} diff --git a/apps/backoffice/src/app/(protected)/layout.tsx b/apps/backoffice/src/app/(protected)/layout.tsx index a770c99..bc53fd2 100644 --- a/apps/backoffice/src/app/(protected)/layout.tsx +++ b/apps/backoffice/src/app/(protected)/layout.tsx @@ -7,7 +7,7 @@ export const AppLayout: FC = (): ReactElement => {
-
+
diff --git a/apps/backoffice/src/app/(protected)/roadmap-dimentorin/_components/modal/create-roadmap/index.tsx b/apps/backoffice/src/app/(protected)/roadmap-dimentorin/_components/modal/create-roadmap/index.tsx new file mode 100644 index 0000000..0c4e3f1 --- /dev/null +++ b/apps/backoffice/src/app/(protected)/roadmap-dimentorin/_components/modal/create-roadmap/index.tsx @@ -0,0 +1,85 @@ +import { ArrowRightOutlined } from "@ant-design/icons"; +import { Button, Input, Select, Textarea } from "@imphnen-frontend-service/ui/atoms"; +import { Accordion, Modal, ModalProps } from "@imphnen-frontend-service/ui/molecules"; +import { cn, For } from "@imphnen-frontend-service/utils"; +import { FC } from "react"; + +const labelClass = cn('text-neutral-800 text-[10px] font-medium mb-1.5 inline-block md:text-xs md:mb-2 xl:text-p3') + +export const ModalCreateRoadmap: FC> = ({ isOpen, onClose }) => { + return ( + +
+

+ Create Roadmaps +

+ +
+
+ +