From 84451f1fd4b264e57c6281bac51e9e4ed6e63fd1 Mon Sep 17 00:00:00 2001 From: Ardeman Date: Tue, 25 Mar 2025 19:07:29 +0800 Subject: [PATCH] feat: add API endpoints for fetching staff profiles and staff list --- .../admin/{get-staff.ts => get-profile.ts} | 2 +- app/apis/admin/get-staffs.ts | 25 +++++ app/pages/dashboard-staffs/index.tsx | 103 ++++++++---------- app/pages/dashboard-subscribe-plan/index.tsx | 2 +- app/pages/dashboard-users/index.tsx | 2 +- ...dmin.lg-admin._dashboard.staffs._index.tsx | 12 +- app/routes/_admin.lg-admin.tsx | 4 +- app/routes/actions.admin.login.ts | 4 +- 8 files changed, 82 insertions(+), 72 deletions(-) rename app/apis/admin/{get-staff.ts => get-profile.ts} (89%) create mode 100644 app/apis/admin/get-staffs.ts diff --git a/app/apis/admin/get-staff.ts b/app/apis/admin/get-profile.ts similarity index 89% rename from app/apis/admin/get-staff.ts rename to app/apis/admin/get-profile.ts index 90db341..6ca1140 100644 --- a/app/apis/admin/get-staff.ts +++ b/app/apis/admin/get-profile.ts @@ -11,7 +11,7 @@ const staffResponseSchema = z.object({ }), }) -export const getStaff = async (parameters: THttpServer) => { +export const getProfile = async (parameters: THttpServer) => { try { const { data } = await HttpServer(parameters).get(`/api/staff/profile`) return staffResponseSchema.parse(data) diff --git a/app/apis/admin/get-staffs.ts b/app/apis/admin/get-staffs.ts new file mode 100644 index 0000000..659382b --- /dev/null +++ b/app/apis/admin/get-staffs.ts @@ -0,0 +1,25 @@ +import { z } from 'zod' + +import { HttpServer, type THttpServer } from '~/libs/http-server' + +const staffResponseSchema = z.object({ + id: z.string(), + email: z.string(), + name: z.string(), + profile_picture: z.string(), +}) +const staffsResponseSchema = z.object({ + data: z.array(staffResponseSchema), +}) + +export type TStaffResponse = z.infer + +export const getStaffs = async (parameters: THttpServer) => { + try { + const { data } = await HttpServer(parameters).get(`/api/staff/get-all`) + return staffsResponseSchema.parse(data) + } catch (error) { + // eslint-disable-next-line unicorn/no-useless-promise-resolve-reject + return Promise.reject(error) + } +} diff --git a/app/pages/dashboard-staffs/index.tsx b/app/pages/dashboard-staffs/index.tsx index 2aed5cd..98a7313 100644 --- a/app/pages/dashboard-staffs/index.tsx +++ b/app/pages/dashboard-staffs/index.tsx @@ -1,67 +1,50 @@ import { PlusIcon } from '@heroicons/react/24/solid' -import { Link } from 'react-router' +import DT, { type ConfigColumns } from 'datatables.net-dt' +import DataTable, { type DataTableSlots } from 'datatables.net-react' +import { Link, useRouteLoaderData } from 'react-router' +import type { TStaffResponse } from '~/apis/admin/get-staffs' import { Button } from '~/components/ui/button' +import { UiTable } from '~/components/ui/table' import { TitleDashboard } from '~/components/ui/title-dashboard' +import type { loader } from '~/routes/_admin.lg-admin._dashboard.staffs._index' export const StaffsPage = () => { - // const loaderData = useRouteLoaderData( - // 'routes/_admin.lg-admin._dashboard.staffs._index', - // ) + const loaderData = useRouteLoaderData( + 'routes/_admin.lg-admin._dashboard.staffs._index', + ) - // DataTable.use(DT) - // const dataTable = - // loaderData?.usersData?.sort( - // (a, b) => - // new Date(b.subscribe.start_date).getTime() - - // new Date(a.subscribe.start_date).getTime(), - // ) || [] + DataTable.use(DT) + const { staffsData: dataTable } = loaderData || {} - // const dataColumns: ConfigColumns[] = [ - // { - // title: 'No', - // render: ( - // _data: unknown, - // _type: unknown, - // _row: unknown, - // meta: { row: number }, - // ) => { - // return meta.row + 1 - // }, - // }, - // { - // title: 'Tanggal Daftar', - // data: 'created_at', - // }, - // { - // title: 'User', - // }, - // { - // title: 'Phone', - // data: 'phone', - // }, - // { - // title: 'Status', - // data: 'subscribe.subscribe_plan.name', - // }, - // ] - // const dataSlot: DataTableSlots = { - // 1: (value: string) => formatDate(value), - // 2: (_value: unknown, _type: unknown, data: TUserResponse) => ( - //
- //
{data.email}
- //
ID: {data.id.slice(0, 8)}
- //
- // ), - // 3: (value: string) => {value}, - // 4: (value: TColorBadge, _type: unknown, data: TUserResponse) => ( - // - // {value} - // - // ), - // } + const dataColumns: ConfigColumns[] = [ + { + title: 'No', + render: ( + _data: unknown, + _type: unknown, + _row: unknown, + meta: { row: number }, + ) => { + return meta.row + 1 + }, + }, + { + title: 'Staf', + }, + { + title: 'Email', + data: 'email', + }, + ] + const dataSlot: DataTableSlots = { + 1: (_value: unknown, _type: unknown, data: TStaffResponse) => ( +
+
{data.name}
+
ID: {data.id.slice(0, 8)}
+
+ ), + } return (
@@ -78,12 +61,12 @@ export const StaffsPage = () => {
- {/* */} + title="Daftar Staf" + /> ) } diff --git a/app/pages/dashboard-subscribe-plan/index.tsx b/app/pages/dashboard-subscribe-plan/index.tsx index 9aa8d2c..6d48dc3 100644 --- a/app/pages/dashboard-subscribe-plan/index.tsx +++ b/app/pages/dashboard-subscribe-plan/index.tsx @@ -115,7 +115,7 @@ export const SubscribePlanPage = () => { { { -// const { staffToken: accessToken } = await handleCookie(request) -// const { data: usersData } = await getUsers({ accessToken }) +export const loader = async ({ request }: Route.LoaderArgs) => { + const { staffToken: accessToken } = await handleCookie(request) + const { data: staffsData } = await getStaffs({ accessToken }) -// return { usersData } -// } + return { staffsData } +} export const ErrorBoundary = ({ error }: Route.ErrorBoundaryProps) => { let message = 'Oops!' diff --git a/app/routes/_admin.lg-admin.tsx b/app/routes/_admin.lg-admin.tsx index ad7a2e5..3c36ef2 100644 --- a/app/routes/_admin.lg-admin.tsx +++ b/app/routes/_admin.lg-admin.tsx @@ -1,6 +1,6 @@ import { isRouteErrorResponse, Outlet, redirect } from 'react-router' -import { getStaff } from '~/apis/admin/get-staff' +import { getProfile } from '~/apis/admin/get-profile' import { AUTH_PAGES } from '~/configs/pages' import { AdminDefaultLayout } from '~/layouts/admin/default' import { handleCookie } from '~/libs/cookies' @@ -14,7 +14,7 @@ export const loader = async ({ request }: Route.LoaderArgs) => { let staffData if (accessToken) { - const { data } = await getStaff({ accessToken }) + const { data } = await getProfile({ accessToken }) staffData = data } diff --git a/app/routes/actions.admin.login.ts b/app/routes/actions.admin.login.ts index b10ce17..e1eb953 100644 --- a/app/routes/actions.admin.login.ts +++ b/app/routes/actions.admin.login.ts @@ -3,7 +3,7 @@ import { data } from 'react-router' import { getValidatedFormData } from 'remix-hook-form' import { XiorError } from 'xior' -import { getStaff } from '~/apis/admin/get-staff' +import { getProfile } from '~/apis/admin/get-profile' import { staffLoginRequest } from '~/apis/admin/login-staff' import { loginSchema, type TLoginSchema } from '~/pages/staff-login' import { generateStaffTokenCookie } from '~/utils/token' @@ -28,7 +28,7 @@ export const action = async ({ request }: Route.ActionArgs) => { const { data: loginData } = await staffLoginRequest(payload) const { token: accessToken } = loginData - const { data: staffData } = await getStaff({ accessToken }) + const { data: staffData } = await getProfile({ accessToken }) const tokenCookie = generateStaffTokenCookie({ accessToken }) const headers = new Headers()