feat: implement createNews API and integrate with content creation flow

This commit is contained in:
Ardeman 2025-03-06 05:46:25 +08:00
parent 894698c5d6
commit 414806734d
4 changed files with 61 additions and 18 deletions

View File

@ -0,0 +1,39 @@
import { z } from 'zod'
import { HttpServer } from '~/libs/http-server'
import type { TContentSchema } from '~/pages/contents-create'
const newsResponseSchema = z.object({
data: z.object({
Message: z.string(),
}),
})
type TParameter = {
accessToken: string
payload: TContentSchema
}
export const createNewsRequest = async (parameters: TParameter) => {
const { accessToken, payload } = parameters
try {
const { categories, tags, ...restPayload } = payload
const transformedPayload = {
...restPayload,
categories: categories.map((category) => category?.code),
tags: tags?.map((tag) => tag?.code),
live_at: new Date(payload?.live_at).toISOString(),
}
if (transformedPayload.tags?.length === 0) {
delete transformedPayload.tags
}
const { data } = await HttpServer({ accessToken }).post(
'/api/news/create',
transformedPayload,
)
return newsResponseSchema.parse(data)
} catch (error) {
// eslint-disable-next-line unicorn/no-useless-promise-resolve-reject
return Promise.reject(error)
}
}

View File

@ -84,6 +84,7 @@ export const TextEditor = <TFormValues extends Record<string, unknown>>(
types: ['heading', 'paragraph'], types: ['heading', 'paragraph'],
}), }),
], ],
immediatelyRender: false,
content: watchContent, content: watchContent,
onUpdate: ({ editor }) => { onUpdate: ({ editor }) => {
setValue(name, editor.getHTML() as any) // eslint-disable-line @typescript-eslint/no-explicit-any setValue(name, editor.getHTML() as any) // eslint-disable-line @typescript-eslint/no-explicit-any

View File

@ -1,7 +1,7 @@
import { DevTool } from '@hookform/devtools' import { DevTool } from '@hookform/devtools'
import { zodResolver } from '@hookform/resolvers/zod' import { zodResolver } from '@hookform/resolvers/zod'
import { useEffect, useState } from 'react' import { useEffect, useState } from 'react'
import { useFetcher, useRouteLoaderData } from 'react-router' import { useFetcher, useNavigate, useRouteLoaderData } from 'react-router'
import { RemixFormProvider, useRemixForm } from 'remix-hook-form' import { RemixFormProvider, useRemixForm } from 'remix-hook-form'
import { z } from 'zod' import { z } from 'zod'
@ -27,16 +27,18 @@ export const contentSchema = z.object({
.refine((data) => !!data, { .refine((data) => !!data, {
message: 'Please select a category', message: 'Please select a category',
}), }),
tags: z.array( tags: z
z .array(
.object({ z
id: z.string(), .object({
code: z.string(), id: z.string(),
name: z.string(), code: z.string(),
}) name: z.string(),
.optional() })
.nullable(), .optional()
), .nullable(),
)
.optional(),
title: z.string().min(1, { title: z.string().min(1, {
message: 'Judul is required', message: 'Judul is required',
}), }),
@ -54,6 +56,7 @@ export type TContentSchema = z.infer<typeof contentSchema>
export const CreateContentsPage = () => { export const CreateContentsPage = () => {
const fetcher = useFetcher() const fetcher = useFetcher()
const navigate = useNavigate()
const loaderData = useRouteLoaderData<typeof loader>('routes/_admin.lg-admin') const loaderData = useRouteLoaderData<typeof loader>('routes/_admin.lg-admin')
const categories = loaderData?.categoriesData const categories = loaderData?.categoriesData
const tags = loaderData?.tagsData const tags = loaderData?.tagsData
@ -77,6 +80,7 @@ export const CreateContentsPage = () => {
return return
} }
navigate('/lg-admin/contents')
setDisabled(true) setDisabled(true)
setError(undefined) setError(undefined)
// eslint-disable-next-line react-hooks/exhaustive-deps // eslint-disable-next-line react-hooks/exhaustive-deps

View File

@ -3,6 +3,7 @@ import { data } from 'react-router'
import { getValidatedFormData } from 'remix-hook-form' import { getValidatedFormData } from 'remix-hook-form'
import { XiorError } from 'xior' import { XiorError } from 'xior'
import { createNewsRequest } from '~/apis/admin/create-news'
import { handleCookie } from '~/libs/cookies' import { handleCookie } from '~/libs/cookies'
import { contentSchema, type TContentSchema } from '~/pages/contents-create' import { contentSchema, type TContentSchema } from '~/pages/contents-create'
@ -25,17 +26,15 @@ export const action = async ({ request }: Route.ActionArgs) => {
return data({ success: false, errors, defaultValues }, { status: 400 }) return data({ success: false, errors, defaultValues }, { status: 400 })
} }
// TODO: implement subscribe const { data: newsData } = await createNewsRequest({
console.log('payload', payload) // eslint-disable-line no-console accessToken: staffToken,
console.log('staffToken', staffToken) // eslint-disable-line no-console payload,
})
// const { data: userData } = await getUser({
// accessToken: userToken,
// })
return data( return data(
{ {
success: true, success: true,
newsData,
}, },
{ {
status: 200, status: 200,