From f04ad1a8f809412bd2afbb95608aec3eba5ca191 Mon Sep 17 00:00:00 2001 From: Ardeman Date: Fri, 14 Mar 2025 12:47:43 +0800 Subject: [PATCH] feat: add start_date and end_date fields to advertisements with transformation and display in forms --- app/apis/admin/create-ads.ts | 7 ++- app/apis/admin/update-ads.ts | 34 +++++++++++ app/pages/dashboard-advertisements/index.tsx | 17 +++++- app/pages/form-advertisements/index.tsx | 32 ++++++++++ .../actions.admin.advertisements.update.ts | 61 +++++++++++++++++++ app/utils/formatter.ts | 1 + 6 files changed, 150 insertions(+), 2 deletions(-) create mode 100644 app/apis/admin/update-ads.ts create mode 100644 app/routes/actions.admin.advertisements.update.ts diff --git a/app/apis/admin/create-ads.ts b/app/apis/admin/create-ads.ts index 6907d04..a856dfd 100644 --- a/app/apis/admin/create-ads.ts +++ b/app/apis/admin/create-ads.ts @@ -15,10 +15,15 @@ type TParameters = { export const createAdsRequest = async (parameters: TParameters) => { const { payload, ...restParameters } = parameters + const transformedPayload = { + ...payload, + start_date: new Date(payload.start_date).toISOString(), + end_date: new Date(payload.end_date).toISOString(), + } try { const { data } = await HttpServer(restParameters).post( '/api/ads/create', - payload, + transformedPayload, ) return advertisementsResponseSchema.parse(data) } catch (error) { diff --git a/app/apis/admin/update-ads.ts b/app/apis/admin/update-ads.ts new file mode 100644 index 0000000..76c9a8a --- /dev/null +++ b/app/apis/admin/update-ads.ts @@ -0,0 +1,34 @@ +import { z } from 'zod' + +import { HttpServer, type THttpServer } from '~/libs/http-server' +import type { TAdsSchema } from '~/pages/form-advertisements' + +const advertisementsResponseSchema = z.object({ + data: z.object({ + Message: z.string(), + }), +}) + +type TParameters = { + payload: TAdsSchema +} & THttpServer + +export const updateAdsRequest = async (parameters: TParameters) => { + const { payload, ...restParameters } = parameters + const { id, ...restPayload } = payload + const transformedPayload = { + ...restPayload, + start_date: new Date(payload.start_date).toISOString(), + end_date: new Date(payload.end_date).toISOString(), + } + try { + const { data } = await HttpServer(restParameters).put( + `/api/ads/${id}/update`, + transformedPayload, + ) + return advertisementsResponseSchema.parse(data) + } catch (error) { + // eslint-disable-next-line unicorn/no-useless-promise-resolve-reject + return Promise.reject(error) + } +} diff --git a/app/pages/dashboard-advertisements/index.tsx b/app/pages/dashboard-advertisements/index.tsx index e42cd53..6e036f6 100644 --- a/app/pages/dashboard-advertisements/index.tsx +++ b/app/pages/dashboard-advertisements/index.tsx @@ -14,6 +14,7 @@ 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.advertisements._index' +import { formatDate } from '~/utils/formatter' export const AdvertisementsPage = () => { const loaderData = useRouteLoaderData( @@ -36,6 +37,20 @@ export const AdvertisementsPage = () => { }, { title: 'Banner', data: 'image_url' }, { title: 'Link', data: 'url' }, + { + title: 'Tanggal Mulai', + data: 'start_date', + render: (data: string) => { + return formatDate(data) + }, + }, + { + title: 'Tanggal Berakhir', + data: 'end_date', + render: (data: string) => { + return formatDate(data) + }, + }, { title: 'Action', data: 'id', @@ -51,7 +66,7 @@ export const AdvertisementsPage = () => { /> ) }, - 3: (value: string, _type: unknown, data: TAdResponse) => ( + 5: (value: string, _type: unknown, data: TAdResponse) => (
+
+ + +
diff --git a/app/routes/actions.admin.advertisements.update.ts b/app/routes/actions.admin.advertisements.update.ts new file mode 100644 index 0000000..094a35c --- /dev/null +++ b/app/routes/actions.admin.advertisements.update.ts @@ -0,0 +1,61 @@ +import { zodResolver } from '@hookform/resolvers/zod' +import { data } from 'react-router' +import { getValidatedFormData } from 'remix-hook-form' +import { XiorError } from 'xior' + +import { updateAdsRequest } from '~/apis/admin/update-ads' +import { handleCookie } from '~/libs/cookies' +import { adsSchema, type TAdsSchema } from '~/pages/form-advertisements' + +import type { Route } from './+types/actions.admin.advertisements.create' + +export const action = async ({ request }: Route.ActionArgs) => { + const { staffToken: accessToken } = await handleCookie(request) + try { + const { + errors, + data: payload, + receivedValues: defaultValues, + } = await getValidatedFormData( + request, + zodResolver(adsSchema), + false, + ) + + if (errors) { + return data({ success: false, errors, defaultValues }, { status: 400 }) + } + + const { data: adsData } = await updateAdsRequest({ accessToken, payload }) + + return data( + { + success: true, + adsData, + }, + { + status: 200, + statusText: 'OK', + }, + ) + } catch (error) { + if (error instanceof XiorError) { + return data( + { + success: false, + message: error?.response?.data?.error?.message || error.message, + }, + { + status: error?.response?.status || 500, + }, + ) + } + return data( + { + success: false, + message: 'Internal server error', + }, + { status: 500 }, + ) + } +} diff --git a/app/utils/formatter.ts b/app/utils/formatter.ts index 2463f49..3a1ecba 100644 --- a/app/utils/formatter.ts +++ b/app/utils/formatter.ts @@ -2,6 +2,7 @@ export const formatNumberWithPeriods = (number: number) => { return new Intl.NumberFormat('id-ID').format(number) } export const formatDate = (isoDate: string): string => { + if (!isoDate) return '-' const date = new Date(isoDate) return new Intl.DateTimeFormat('id-ID', { day: '2-digit',