feat: add file upload section for cover image and article content in create article form
This commit is contained in:
@@ -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>
|
||||
|
||||
Reference in New Issue
Block a user