From 4518a556ad0a8ab4f1cf125707b9abac66363669 Mon Sep 17 00:00:00 2001 From: euxzy Date: Mon, 18 Aug 2025 15:51:25 +0700 Subject: [PATCH] feat(backoffice): slicing backoffice dimentorin - modal detail user management --- .../_components/modal/delete/index.tsx | 55 +++++++++ .../modal/detail/account-profile.tsx | 86 ++++++++++++++ .../_components/modal/detail/activity-log.tsx | 110 ++++++++++++++++++ .../modal/detail/detail-profile.tsx | 89 ++++++++++++++ .../_components/modal/detail/index.tsx | 68 +++++++++++ .../_components/modal/detail/type.d.ts | 5 + .../modal/suspend-or-ban/index.tsx | 42 +++++++ .../_components/modal/type.d.ts | 4 + .../app/(protected)/users-dimentorin/page.tsx | 25 ++-- libs/ui/src/organisms/datatable/datatable.tsx | 8 +- libs/ui/src/organisms/datatable/index.ts | 1 + libs/ui/src/organisms/datatable/type.d.ts | 8 ++ package-lock.json | 2 +- package.json | 1 + 14 files changed, 493 insertions(+), 11 deletions(-) create mode 100644 apps/backoffice/src/app/(protected)/users-dimentorin/_components/modal/delete/index.tsx create mode 100644 apps/backoffice/src/app/(protected)/users-dimentorin/_components/modal/detail/account-profile.tsx create mode 100644 apps/backoffice/src/app/(protected)/users-dimentorin/_components/modal/detail/activity-log.tsx create mode 100644 apps/backoffice/src/app/(protected)/users-dimentorin/_components/modal/detail/detail-profile.tsx create mode 100644 apps/backoffice/src/app/(protected)/users-dimentorin/_components/modal/detail/index.tsx create mode 100644 apps/backoffice/src/app/(protected)/users-dimentorin/_components/modal/detail/type.d.ts create mode 100644 apps/backoffice/src/app/(protected)/users-dimentorin/_components/modal/suspend-or-ban/index.tsx create mode 100644 apps/backoffice/src/app/(protected)/users-dimentorin/_components/modal/type.d.ts create mode 100644 libs/ui/src/organisms/datatable/type.d.ts diff --git a/apps/backoffice/src/app/(protected)/users-dimentorin/_components/modal/delete/index.tsx b/apps/backoffice/src/app/(protected)/users-dimentorin/_components/modal/delete/index.tsx new file mode 100644 index 0000000..5a905e2 --- /dev/null +++ b/apps/backoffice/src/app/(protected)/users-dimentorin/_components/modal/delete/index.tsx @@ -0,0 +1,55 @@ +import { Button } from "@imphnen-frontend-service/ui/atoms"; +import { Modal } from "@imphnen-frontend-service/ui/molecules"; +import { FC } from "react"; + +type ModalDeleteProps = { + open: boolean + setOpen: (open: boolean) => void + hadnleDelete?: () => void +} + +export const ModalDelete: FC = ({ open, setOpen, hadnleDelete }) => { + return ( + setOpen(false)} + closeButtonClassName="hidden" + > + + Delete item? +
+

+ Hapus Akun +

+

+ Apakah kamu yakin untuk menghapus akun ini? +

+
+
+ + + + +
+ ) +} diff --git a/apps/backoffice/src/app/(protected)/users-dimentorin/_components/modal/detail/account-profile.tsx b/apps/backoffice/src/app/(protected)/users-dimentorin/_components/modal/detail/account-profile.tsx new file mode 100644 index 0000000..e5a91bc --- /dev/null +++ b/apps/backoffice/src/app/(protected)/users-dimentorin/_components/modal/detail/account-profile.tsx @@ -0,0 +1,86 @@ +import { Button, Input } from "@imphnen-frontend-service/ui/atoms"; +import { cn } from "@imphnen-frontend-service/utils"; +import { FC, useState } from "react"; +import { ModalDelete } from "../delete"; +import { ModalProps } from "../type"; +import { ModalSuspendOrBan } from "../suspend-or-ban"; + +const labelClass = cn('text-neutral-800 text-[10px] font-semibold mb-1.5 inline-block md:text-xs md:mb-2 xl:text-[15px]') + +export const AccountProfile: FC = ({ setOpen }) => { + const [openDelete, setOpenDelete] = useState(false) + const [openSuspendOrBan, setOpenSuspendOrBan] = useState(false) + + return ( +
+
+
+ Profile +
+
+ +

+ Setidaknya rekomendasi ukuran 240x240 px.
+ .jpg, .jpeg, .png diperbolehkan +

+
+
+ +
+
+

Informasi Pribadi

+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ +
+

Status Akun

+
+ + +
+
+ +
+ + +
+
+ + + +
+ ) +} diff --git a/apps/backoffice/src/app/(protected)/users-dimentorin/_components/modal/detail/activity-log.tsx b/apps/backoffice/src/app/(protected)/users-dimentorin/_components/modal/detail/activity-log.tsx new file mode 100644 index 0000000..5f0de58 --- /dev/null +++ b/apps/backoffice/src/app/(protected)/users-dimentorin/_components/modal/detail/activity-log.tsx @@ -0,0 +1,110 @@ +import { SearchOutlined } from "@ant-design/icons" +import { Input, Select } from "@imphnen-frontend-service/ui/atoms" +import { DataTable } from "@imphnen-frontend-service/ui/organisms" +import { cn } from "@imphnen-frontend-service/utils" +import { ColumnDef, getCoreRowModel, getPaginationRowModel, PaginationState, RowSelectionState, useReactTable } from "@tanstack/react-table" +import { FC, useState } from "react" +import dayjs from "dayjs" + +interface ActivityLogType { + id: number + date: string + menu: string + activity: string +} + +const mockData: ActivityLogType[] = Array.from({ length: 90 }, (_, i) => ({ + id: i + 1, + date: new Date().toISOString(), + menu: 'Mentoring', + activity: 'Mentoring Session', +})) + +export const ActivityLog: FC = () => { + const [rowSelection, setRowSelection] = useState({}) + const [pagination, setPagination] = useState({ + pageIndex: 0, + pageSize: 9, + }) + + const columns: ColumnDef[] = [ + { + id: 'select', + meta: { cellClassName: cn("w-16") }, + header: ({ table }) => ( + + ), + cell: ({ row }) => ( + + ), + }, + { + id: 'date', + header: 'Waktu', + accessorKey: 'date', + cell: (info) => dayjs(info.row.original.date).format('DD MMMM YYYY, HH:mm WIB'), + }, + { + id: 'menu', + header: 'Menu', + accessorKey: 'menu', + }, + { + id: 'activity', + header: 'Activity', + accessorKey: 'activity', + } + ] + + 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 ( +
+
+
+ +
+ +
+
+
+ +
+ +
+ + +
+ ) +} diff --git a/apps/backoffice/src/app/(protected)/users-dimentorin/_components/modal/detail/detail-profile.tsx b/apps/backoffice/src/app/(protected)/users-dimentorin/_components/modal/detail/detail-profile.tsx new file mode 100644 index 0000000..4f753f6 --- /dev/null +++ b/apps/backoffice/src/app/(protected)/users-dimentorin/_components/modal/detail/detail-profile.tsx @@ -0,0 +1,89 @@ +import { Icon } from "@iconify/react" +import { Button } from "@imphnen-frontend-service/ui/atoms" +import { For } from "@imphnen-frontend-service/utils" +import { FC } from "react" + +const SOCIAL_LINKS = [ + { icon: , url: "https://linkedin.com", label: "LinkedIn" }, + { icon: , url: "https://github.com", label: "Github" }, + { icon: , url: "https://facebook.com", label: "Facebook (Meta)" }, + { icon: , url: "https://stackoverflow.com", label: "Stack Overflow" } +] + +export const DetailProfile: FC = () => { + return ( +
+
+
+
+
+ Profile +
+
+

Muhammad Firdaus Oiwobo

+

Mentor

+
+
+ +
+ +
+ + {({ icon, url, label }) => ( + + + + )} + +
+ +
+ +
+
+

Description

+

+ Lorem ipsum dolor sit amet, consectetur adipiscing elit. Ut et massa mi. Aliquam in hendrerit urna. Pellentesque sit amet sapien fringilla, mattis ligula consectetur, ultrices mauris. Maecenas vitae mattis tellus. Nullam quis imperdiet augue. Vestibulum auctor ornare leo, non suscipit magna interdum eu. Curabitur pellentesque nibh nibh, at maximus ante fermentum sit amet. Pellentesque commodo lacus at sodales sodales. Quisque sagittis orci ut diam condimentum, vel euismod erat placerat. In iaculis arcu eros, eget tempus orci facilisis id. +

+
+
+

Personal Informations

+
+
+
+ +
+
+

rzalaxib23@gmail.com

+

Email Address

+
+
+
+
+ +
+
+

+62 888 8888 8888

+

Phone Number

+
+
+
+
+ +
+
+

Jl. Mergosari, Kec. Suryakencana, Banjaran

+

Location

+
+
+
+
+
+
+ ) +} diff --git a/apps/backoffice/src/app/(protected)/users-dimentorin/_components/modal/detail/index.tsx b/apps/backoffice/src/app/(protected)/users-dimentorin/_components/modal/detail/index.tsx new file mode 100644 index 0000000..82279b8 --- /dev/null +++ b/apps/backoffice/src/app/(protected)/users-dimentorin/_components/modal/detail/index.tsx @@ -0,0 +1,68 @@ +import { Button } from "@imphnen-frontend-service/ui/atoms" +import { Modal } from "@imphnen-frontend-service/ui/molecules" +import { cn, For, Show } from "@imphnen-frontend-service/utils" +import { FC, useEffect, useState } from "react" +import { AccountProfile } from "./account-profile" +import { DetailProfile } from "./detail-profile" +import { ActivityLog } from "./activity-log" +import { ModalDetailUserProps } from "./type" + +const TABS = { + account: 'account profile', + detail: 'detail profile', + activity: 'activity logs', +} as const +type TabType = typeof TABS[keyof typeof TABS] + +export const ModalDetailUser: FC = ({ + open, + setOpen, +}) => { + const [activeTab, setActiveTab] = useState(TABS.account) + + useEffect(() => { + if (!open) setActiveTab(TABS.account) + }, [open]) + + return ( + setOpen(false)} + className="xl:max-w-[84rem] bg-white px-10 py-9" + closeButtonClassName="hidden" + > +
+

+ Detail - Muhammad Firdaus Oiwobo +

+ +
+ + {(tab) => ( + + )} + +
+ +
+ + + + + + + + + +
+
+
+ ) +} diff --git a/apps/backoffice/src/app/(protected)/users-dimentorin/_components/modal/detail/type.d.ts b/apps/backoffice/src/app/(protected)/users-dimentorin/_components/modal/detail/type.d.ts new file mode 100644 index 0000000..b443959 --- /dev/null +++ b/apps/backoffice/src/app/(protected)/users-dimentorin/_components/modal/detail/type.d.ts @@ -0,0 +1,5 @@ +import { ModalProps } from "../type"; + +export interface ModalDetailUserProps extends ModalProps { + userId?: number | null +} diff --git a/apps/backoffice/src/app/(protected)/users-dimentorin/_components/modal/suspend-or-ban/index.tsx b/apps/backoffice/src/app/(protected)/users-dimentorin/_components/modal/suspend-or-ban/index.tsx new file mode 100644 index 0000000..11843e1 --- /dev/null +++ b/apps/backoffice/src/app/(protected)/users-dimentorin/_components/modal/suspend-or-ban/index.tsx @@ -0,0 +1,42 @@ +import { FC } from "react"; +import { ModalProps } from "../type"; +import { Modal } from "@imphnen-frontend-service/ui/molecules"; +import { cn } from "@imphnen-frontend-service/utils"; +import { Button, Select, Textarea } from "@imphnen-frontend-service/ui/atoms"; + +const labelClass = cn('text-neutral-800 text-[10px] font-semibold mb-1.5 inline-block md:text-xs md:mb-2 xl:text-[15px]') + +export const ModalSuspendOrBan: FC = ({ open, setOpen }) => { + return ( + setOpen(false)} + className="bg-white px-10 py-9 xl:max-w-[32rem]" + closeButtonClassName="hidden" + > +
+

+ Suspend/Ban +

+ +
+
+ + +
+
+ +