upload audio and video

This commit is contained in:
hamid zarghami
2025-08-31 14:34:17 +03:30
parent 0ee4ca5de4
commit 860f7c446f
6 changed files with 145 additions and 5 deletions
+4
View File
@@ -195,6 +195,10 @@
"upload_icon_service": "آیکون سرویس مورد نظر را آپلود کنید", "upload_icon_service": "آیکون سرویس مورد نظر را آپلود کنید",
"service_images": "تصاویر سرویس", "service_images": "تصاویر سرویس",
"upload_images_service": "تصاویر سرویس مورد نظر را آپلود کنید", "upload_images_service": "تصاویر سرویس مورد نظر را آپلود کنید",
"service_audios": "فایل‌های صوتی سرویس",
"upload_audios_service": "فایل‌های صوتی سرویس مورد نظر را آپلود کنید",
"service_videos": "فایل‌های ویدیویی سرویس",
"upload_videos_service": "فایل‌های ویدیویی سرویس مورد نظر را آپلود کنید",
"submit_service": "ثبت سرویس", "submit_service": "ثبت سرویس",
"new_service": "سرویس جدید", "new_service": "سرویس جدید",
"list_service": "لیست سرویس ها", "list_service": "لیست سرویس ها",
+43 -1
View File
@@ -28,6 +28,8 @@ const AddService: FC = () => {
const createService = useCreateService() const createService = useCreateService()
const [iconFile, setIconFile] = useState<File>() const [iconFile, setIconFile] = useState<File>()
const [imagesFile, setImagesFile] = useState<File[]>() const [imagesFile, setImagesFile] = useState<File[]>()
const [audioFiles, setAudioFiles] = useState<File[]>()
const [videoFiles, setVideoFiles] = useState<File[]>()
useEffect(() => { useEffect(() => {
const quill = new Quill('#editor', { const quill = new Quill('#editor', {
@@ -68,7 +70,9 @@ const AddService: FC = () => {
createDate: '', createDate: '',
slug: '', slug: '',
pageTitle: '', pageTitle: '',
pageDescription: '' pageDescription: '',
audios: [],
videos: []
}, },
validationSchema: Yup.object({ validationSchema: Yup.object({
name: Yup.string().required(t('errors.required')), name: Yup.string().required(t('errors.required')),
@@ -111,6 +115,42 @@ const AddService: FC = () => {
} }
}) })
// آپلود فایل‌های صوتی
if (audioFiles && audioFiles.length > 0) {
const audios = new FormData()
audioFiles.forEach((file: File) => {
audios.append('files', file)
})
await multiUpload.mutateAsync(audios, {
onSuccess: async (data) => {
values.audios = await data.data.map((item: { url: string }) => item?.url)
},
onError: (error: ErrorType) => {
toast.error(error.response?.data?.error?.message[0])
}
})
} else {
values.audios = undefined
}
// آپلود فایل‌های ویدیویی
if (videoFiles && videoFiles.length > 0) {
const videos = new FormData()
videoFiles.forEach((file: File) => {
videos.append('files', file)
})
await multiUpload.mutateAsync(videos, {
onSuccess: async (data) => {
values.videos = await data.data.map((item: { url: string }) => item?.url)
},
onError: (error: ErrorType) => {
toast.error(error.response?.data?.error?.message[0])
}
})
} else {
values.videos = undefined
}
const params = { const params = {
...values, ...values,
userCount: +values.userCount, userCount: +values.userCount,
@@ -247,6 +287,8 @@ const AddService: FC = () => {
formik={formik} formik={formik}
onChangeIconFile={(file: File) => setIconFile(file)} onChangeIconFile={(file: File) => setIconFile(file)}
onChangeImagesFile={(file: File[]) => setImagesFile(file)} onChangeImagesFile={(file: File[]) => setImagesFile(file)}
onChangeAudioFile={(file: File[]) => setAudioFiles(file)}
onChangeVideoFile={(file: File[]) => setVideoFiles(file)}
/> />
</div> </div>
</div> </div>
+46 -2
View File
@@ -28,6 +28,8 @@ const UpdateService: FC = () => {
const createService = useUpdateService(id ? id : '') const createService = useUpdateService(id ? id : '')
const [iconFile, setIconFile] = useState<File>() const [iconFile, setIconFile] = useState<File>()
const [imagesFile, setImagesFile] = useState<File[]>() const [imagesFile, setImagesFile] = useState<File[]>()
const [audioFiles, setAudioFiles] = useState<File[]>()
const [videoFiles, setVideoFiles] = useState<File[]>()
const getDetailService = useGetDetailService(id) const getDetailService = useGetDetailService(id)
useEffect(() => { useEffect(() => {
@@ -72,7 +74,9 @@ const UpdateService: FC = () => {
coverUrl: '', coverUrl: '',
slug: '', slug: '',
pageTitle: '', pageTitle: '',
pageDescription: '' pageDescription: '',
audios: [],
videos: []
}, },
validationSchema: Yup.object({ validationSchema: Yup.object({
name: Yup.string().required(t('errors.required')), name: Yup.string().required(t('errors.required')),
@@ -119,6 +123,42 @@ const UpdateService: FC = () => {
}) })
} }
// آپلود فایل‌های صوتی
if (audioFiles && audioFiles.length > 0) {
const audios = new FormData()
audioFiles.forEach((file: File) => {
audios.append('files', file)
})
await multiUpload.mutateAsync(audios, {
onSuccess: async (data) => {
values.audios = [...(values.audios || []), ...data.data.map((item: { url: string }) => item?.url)]
},
onError: (error: ErrorType) => {
toast.error(error.response?.data?.error?.message[0])
}
})
} else {
values.audios = undefined
}
// آپلود فایل‌های ویدیویی
if (videoFiles && videoFiles.length > 0) {
const videos = new FormData()
videoFiles.forEach((file: File) => {
videos.append('files', file)
})
await multiUpload.mutateAsync(videos, {
onSuccess: async (data) => {
values.videos = [...(values.videos || []), ...data.data.map((item: { url: string }) => item?.url)]
},
onError: (error: ErrorType) => {
toast.error(error.response?.data?.error?.message[0])
}
})
} else {
values.videos = undefined
}
const params = { const params = {
...values, ...values,
userCount: +values.userCount, userCount: +values.userCount,
@@ -159,7 +199,9 @@ const UpdateService: FC = () => {
coverUrl: data?.coverUrl, coverUrl: data?.coverUrl,
slug: data?.slug, slug: data?.slug,
pageTitle: data?.pageTitle, pageTitle: data?.pageTitle,
pageDescription: data?.pageDescription pageDescription: data?.pageDescription,
audios: data?.audios || [],
videos: data?.videos || []
}); });
const editorElement = editorRef.current?.querySelector('.ql-editor'); const editorElement = editorRef.current?.querySelector('.ql-editor');
if (editorElement) { if (editorElement) {
@@ -281,6 +323,8 @@ const UpdateService: FC = () => {
formik={formik} formik={formik}
onChangeIconFile={(file: File) => setIconFile(file)} onChangeIconFile={(file: File) => setIconFile(file)}
onChangeImagesFile={(file: File[]) => setImagesFile(file)} onChangeImagesFile={(file: File[]) => setImagesFile(file)}
onChangeAudioFile={(file: File[]) => setAudioFiles(file)}
onChangeVideoFile={(file: File[]) => setVideoFiles(file)}
/> />
) )
} }
@@ -11,7 +11,9 @@ import Textarea from '../../../components/Textarea'
type Props = { type Props = {
formik: FormikProps<CreateServiceType>, formik: FormikProps<CreateServiceType>,
onChangeIconFile: (file: File) => void, onChangeIconFile: (file: File) => void,
onChangeImagesFile: (file: File[]) => void onChangeImagesFile: (file: File[]) => void,
onChangeAudioFile: (file: File[]) => void,
onChangeVideoFile: (file: File[]) => void
} }
const AddServiceSidebar: FC<Props> = (props: Props) => { const AddServiceSidebar: FC<Props> = (props: Props) => {
@@ -115,6 +117,26 @@ const AddServiceSidebar: FC<Props> = (props: Props) => {
/> />
</div> </div>
</div> </div>
<div className='mt-8'>
<div>{t('service.service_audios')}</div>
<div className='mt-2'>
<UploadBoxDraggble
label={t('service.upload_audios_service')}
onChange={props.onChangeAudioFile}
isMultiple
/>
</div>
</div>
<div className='mt-8'>
<div>{t('service.service_videos')}</div>
<div className='mt-2'>
<UploadBoxDraggble
label={t('service.upload_videos_service')}
onChange={props.onChangeVideoFile}
isMultiple
/>
</div>
</div>
</div> </div>
) )
} }
@@ -12,7 +12,9 @@ import Textarea from '../../../components/Textarea'
type Props = { type Props = {
formik: FormikProps<CreateServiceType>, formik: FormikProps<CreateServiceType>,
onChangeIconFile: (file: File) => void, onChangeIconFile: (file: File) => void,
onChangeImagesFile: (file: File[]) => void onChangeImagesFile: (file: File[]) => void,
onChangeAudioFile: (file: File[]) => void,
onChangeVideoFile: (file: File[]) => void
} }
const UpdateServiceSidebar: FC<Props> = (props: Props) => { const UpdateServiceSidebar: FC<Props> = (props: Props) => {
@@ -124,6 +126,30 @@ const UpdateServiceSidebar: FC<Props> = (props: Props) => {
/> />
</div> </div>
</div> </div>
<div className='mt-8'>
<div>{t('service.service_audios')}</div>
<div className='mt-2'>
<UploadBoxDraggble
label={t('service.upload_audios_service')}
onChange={props.onChangeAudioFile}
isMultiple
preview={data?.data?.danakService?.audios || []}
onChangePreview={(audios: string[]) => formik.setFieldValue('audios', audios)}
/>
</div>
</div>
<div className='mt-8'>
<div>{t('service.service_videos')}</div>
<div className='mt-2'>
<UploadBoxDraggble
label={t('service.upload_videos_service')}
onChange={props.onChangeVideoFile}
isMultiple
preview={data?.data?.danakService?.videos || []}
onChangePreview={(videos: string[]) => formik.setFieldValue('videos', videos)}
/>
</div>
</div>
</div> </div>
) )
} }
+2
View File
@@ -47,6 +47,8 @@ export type CreateServiceType = {
slug: string; slug: string;
pageTitle: string; pageTitle: string;
pageDescription: string; pageDescription: string;
audios?: string[];
videos?: string[];
}; };
export type ServiceItemType = { export type ServiceItemType = {