feat: update API endpoint for ad creation and enhance InputFile component with category prop

This commit is contained in:
Ardeman 2025-03-12 10:57:48 +08:00
parent 56c31d7a20
commit 930d4b8459
5 changed files with 16 additions and 27 deletions

View File

@ -17,7 +17,7 @@ export const createAdsRequest = async (parameters: TParameters) => {
const { payload, ...restParameters } = parameters const { payload, ...restParameters } = parameters
try { try {
const { data } = await HttpServer(restParameters).post( const { data } = await HttpServer(restParameters).post(
'/api/advertisements/create', '/api/ads/create',
payload, payload,
) )
return advertisementsResponseSchema.parse(data) return advertisementsResponseSchema.parse(data)

View File

@ -1,13 +1,7 @@
import { Field, Label, Input as HeadlessInput } from '@headlessui/react' import { Field, Label, Input as HeadlessInput } from '@headlessui/react'
import { CloudArrowUpIcon } from '@heroicons/react/20/solid' import { CloudArrowUpIcon } from '@heroicons/react/20/solid'
import { useEffect, type ComponentProps, type ReactNode } from 'react' import { useEffect, type ComponentProps, type ReactNode } from 'react'
import { import { get, type FieldError, type RegisterOptions } from 'react-hook-form'
get,
type FieldError,
type FieldValues,
type Path,
type RegisterOptions,
} from 'react-hook-form'
import { useRemixFormContext } from 'remix-hook-form' import { useRemixFormContext } from 'remix-hook-form'
import { twMerge } from 'tailwind-merge' import { twMerge } from 'tailwind-merge'
@ -15,22 +9,17 @@ import { useAdminContext, type TUpload } from '~/contexts/admin'
import { Button } from './button' import { Button } from './button'
type TInputProperties<T extends FieldValues> = Omit< type TInputProperties = Omit<ComponentProps<'input'>, 'size'> & {
ComponentProps<'input'>,
'size'
> & {
id: string id: string
label?: ReactNode label?: ReactNode
name: Path<T> name: string
rules?: RegisterOptions rules?: RegisterOptions
containerClassName?: string containerClassName?: string
labelClassName?: string labelClassName?: string
category?: string category: TUpload
} }
export const InputFile = <TFormValues extends Record<string, unknown>>( export const InputFile = (properties: TInputProperties) => {
properties: TInputProperties<TFormValues>,
) => {
const { const {
id, id,
label, label,
@ -56,8 +45,8 @@ export const InputFile = <TFormValues extends Record<string, unknown>>(
const error: FieldError = get(errors, name) const error: FieldError = get(errors, name)
useEffect(() => { useEffect(() => {
if (uploadedFile && isUploadOpen === name) { if (uploadedFile && isUploadOpen === (category || name)) {
setValue(name as string, uploadedFile) setValue(name, uploadedFile)
setUploadedFile(undefined) setUploadedFile(undefined)
setIsUploadOpen(undefined) setIsUploadOpen(undefined)
} }
@ -88,7 +77,7 @@ export const InputFile = <TFormValues extends Record<string, unknown>>(
size="fit" size="fit"
className="absolute right-3 h-[42px]" className="absolute right-3 h-[42px]"
onClick={() => { onClick={() => {
setIsUploadOpen((category || name) as TUpload) setIsUploadOpen(category)
}} }}
> >
<CloudArrowUpIcon className="h-4 w-4 text-gray-500/50" /> <CloudArrowUpIcon className="h-4 w-4 text-gray-500/50" />

View File

@ -35,13 +35,11 @@ export const AdvertisementsPage = () => {
const dataSlot: DataTableSlots = { const dataSlot: DataTableSlots = {
1: (value: string) => { 1: (value: string) => {
return ( return (
<div>
<img <img
src={value} src={value}
alt={value} alt={value}
className="aspect-[15/1] h-[50px] max-h-[100px] min-h-[65px] rounded object-cover" className="aspect-[150/1] h-[50px] rounded object-contain"
/> />
</div>
) )
}, },
3: (value: string) => ( 3: (value: string) => (

View File

@ -75,6 +75,7 @@ export const FormAdvertisementsPage = (properties: TProperties) => {
className="border-0 bg-white shadow read-only:bg-gray-100 focus:ring-1 focus:ring-[#2E2F7C] focus:outline-none disabled:bg-gray-100" className="border-0 bg-white shadow read-only:bg-gray-100 focus:ring-1 focus:ring-[#2E2F7C] focus:outline-none disabled:bg-gray-100"
labelClassName="text-sm font-medium text-[#363636]" labelClassName="text-sm font-medium text-[#363636]"
containerClassName="flex-1" containerClassName="flex-1"
category="ads"
/> />
<Input <Input
id="url" id="url"

View File

@ -139,6 +139,7 @@ export const FormContentsPage = (properties: TProperties) => {
className="border-0 bg-white shadow read-only:bg-gray-100 focus:ring-1 focus:ring-[#2E2F7C] focus:outline-none disabled:bg-gray-100" className="border-0 bg-white shadow read-only:bg-gray-100 focus:ring-1 focus:ring-[#2E2F7C] focus:outline-none disabled:bg-gray-100"
labelClassName="text-sm font-medium text-[#363636]" labelClassName="text-sm font-medium text-[#363636]"
containerClassName="flex-1" containerClassName="flex-1"
category="featured_image"
/> />
<Button <Button
isLoading={fetcher.state !== 'idle'} isLoading={fetcher.state !== 'idle'}