feat: add file upload section for cover image and article content in create article form

This commit is contained in:
2026-04-10 00:07:11 -03:00
parent 534d206f0e
commit fb8c07d32e
4 changed files with 24 additions and 50 deletions

View File

@@ -15,11 +15,14 @@ import {
InputGroupTextarea,
} from '@/ui/components/shadcn/input-group';
import { zodResolver } from '@hookform/resolvers/zod';
import Image from 'next/image';
import { useCallback, useEffect, useRef, useState } from 'react';
import { Controller, useForm, useWatch } from 'react-hook-form';
import slugify from 'slugify';
import { toast } from 'sonner';
import { z } from 'zod';
import ImageLogo from '~/public/img/icons/cover-image.svg';
import MarkdownLogo from '~/public/img/icons/markdown-content.svg';
function isImageFile(file: File): boolean {
return file.type.startsWith('image/');
@@ -37,11 +40,15 @@ function isContentFile(file: File): boolean {
}
function validateImageFile(file: File): string | null {
return isImageFile(file) ? null : 'Only image files are allowed for cover image';
return isImageFile(file)
? null
: 'Only image files are allowed for cover image';
}
function validateContentFile(file: File): string | null {
return isContentFile(file) ? null : 'Only markdown or text files are allowed';
return isContentFile(file)
? null
: 'Only markdown or text files are allowed';
}
export const CreateArticleForm = () => {
@@ -159,6 +166,7 @@ export const CreateArticleForm = () => {
return (
<form
id='form-create-article'
// eslint-disable-next-line react-hooks/refs
onSubmit={form.handleSubmit(handleFormSubmit)}
>
<FieldGroup className='gap-7'>
@@ -239,19 +247,12 @@ export const CreateArticleForm = () => {
description='PNG, JPG, GIF, WebP accepted'
error={form.formState.errors.coverImageUrl?.message}
icon={
<svg
className='size-6 shrink-0 text-muted-foreground'
fill='none'
stroke='currentColor'
viewBox='0 0 24 24'
>
<path
strokeLinecap='round'
strokeLinejoin='round'
strokeWidth={2}
d='M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z'
/>
</svg>
<Image
src={ImageLogo}
alt=''
aria-hidden='true'
className='size-6 shrink-0 opacity-60'
/>
}
/>
<FileUploadField
@@ -264,19 +265,12 @@ export const CreateArticleForm = () => {
description='.md / .markdown / .txt accepted'
error={form.formState.errors.content?.message}
icon={
<svg
className='size-6 shrink-0 text-muted-foreground'
fill='none'
stroke='currentColor'
viewBox='0 0 24 24'
>
<path
strokeLinecap='round'
strokeLinejoin='round'
strokeWidth={2}
d='M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z'
/>
</svg>
<Image
src={MarkdownLogo}
alt=''
aria-hidden='true'
className='size-6 shrink-0 opacity-60'
/>
}
/>
</div>