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'],
}),
],
immediatelyRender: false,
content: watchContent,
onUpdate: ({ editor }) => {
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 { zodResolver } from '@hookform/resolvers/zod'
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 { z } from 'zod'
@ -27,16 +27,18 @@ export const contentSchema = z.object({
.refine((data) => !!data, {
message: 'Please select a category',
}),
tags: z.array(
z
.object({
id: z.string(),
code: z.string(),
name: z.string(),
})
.optional()
.nullable(),
),
tags: z
.array(
z
.object({
id: z.string(),
code: z.string(),
name: z.string(),
})
.optional()
.nullable(),
)
.optional(),
title: z.string().min(1, {
message: 'Judul is required',
}),
@ -54,6 +56,7 @@ export type TContentSchema = z.infer<typeof contentSchema>
export const CreateContentsPage = () => {
const fetcher = useFetcher()
const navigate = useNavigate()
const loaderData = useRouteLoaderData<typeof loader>('routes/_admin.lg-admin')
const categories = loaderData?.categoriesData
const tags = loaderData?.tagsData
@ -77,6 +80,7 @@ export const CreateContentsPage = () => {
return
}
navigate('/lg-admin/contents')
setDisabled(true)
setError(undefined)
// 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 { XiorError } from 'xior'
import { createNewsRequest } from '~/apis/admin/create-news'
import { handleCookie } from '~/libs/cookies'
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 })
}
// TODO: implement subscribe
console.log('payload', payload) // eslint-disable-line no-console
console.log('staffToken', staffToken) // eslint-disable-line no-console
// const { data: userData } = await getUser({
// accessToken: userToken,
// })
const { data: newsData } = await createNewsRequest({
accessToken: staffToken,
payload,
})
return data(
{
success: true,
newsData,
},
{
status: 200,