upload single icon
deploy to danak / build_and_deploy (push) Has been cancelled

This commit is contained in:
hamid zarghami
2026-06-14 09:34:32 +03:30
parent 934c50dc65
commit dd63abd212
+49 -3
View File
@@ -1,5 +1,6 @@
import { type FC, useState } from 'react' import { type ChangeEvent, type FC, useRef, useState } from 'react'
import { Add, Image } from 'iconsax-react' import { Add, DocumentUpload, Image } from 'iconsax-react'
import { toast } from 'react-toastify'
import Input from '@/components/Input' import Input from '@/components/Input'
import SwitchComponent from '@/components/Switch' import SwitchComponent from '@/components/Switch'
import Button from '@/components/Button' import Button from '@/components/Button'
@@ -7,6 +8,9 @@ import type { FormikProps } from 'formik'
import { useGetCategories, useGetIcons } from '../hooks/useProductData' import { useGetCategories, useGetIcons } from '../hooks/useProductData'
import IconSelectModal from './IconSelectModal' import IconSelectModal from './IconSelectModal'
import Select from '@/components/Select' import Select from '@/components/Select'
import { useSingleUpload } from '../../uploader/hooks/useUploaderData'
import { extractErrorMessage } from '@/config/func'
import type { ErrorType } from '@/helpers/types'
type CategoryFormValues = { type CategoryFormValues = {
title: string title: string
@@ -41,6 +45,8 @@ const CategoryForm: FC<Props> = ({
const { data: categories } = useGetCategories() const { data: categories } = useGetCategories()
const icons = iconsData?.data || [] const icons = iconsData?.data || []
const [isIconModalOpen, setIsIconModalOpen] = useState(false) const [isIconModalOpen, setIsIconModalOpen] = useState(false)
const fileInputRef = useRef<HTMLInputElement>(null)
const { mutate: singleUpload, isPending: isUploadingIcon } = useSingleUpload()
const handleIconSelect = (url: string) => { const handleIconSelect = (url: string) => {
if (onIconUrlChange) { if (onIconUrlChange) {
@@ -49,6 +55,30 @@ const CategoryForm: FC<Props> = ({
setIsIconModalOpen(false) setIsIconModalOpen(false)
} }
const handleUploadClick = () => {
fileInputRef.current?.click()
}
const handleFileChange = (e: ChangeEvent<HTMLInputElement>) => {
const file = e.target.files?.[0]
if (!file) return
singleUpload(file, {
onSuccess: (response) => {
const url = response?.data?.url || ''
if (url && onIconUrlChange) {
onIconUrlChange(url)
toast.success('آیکون با موفقیت آپلود شد')
}
},
onError: (error: ErrorType) => {
toast.error(extractErrorMessage(error, 'خطا در آپلود آیکون'))
}
})
e.target.value = ''
}
return ( return (
<div className="w-full lg:w-[300px] bg-white rounded-3xl p-4 lg:p-6 h-fit lg:sticky top-4 lg:top-6"> <div className="w-full lg:w-[300px] bg-white rounded-3xl p-4 lg:p-6 h-fit lg:sticky top-4 lg:top-6">
<h2 className="font-light mb-4 lg:mb-6 text-sm lg:text-base">{isEditing ? 'ویرایش دسته بندی' : 'اضافه کردن دسته بندی'}</h2> <h2 className="font-light mb-4 lg:mb-6 text-sm lg:text-base">{isEditing ? 'ویرایش دسته بندی' : 'اضافه کردن دسته بندی'}</h2>
@@ -105,6 +135,22 @@ const CategoryForm: FC<Props> = ({
<Image size={18} color="#fff" className="lg:w-5 lg:h-5" /> <Image size={18} color="#fff" className="lg:w-5 lg:h-5" />
<span>انتخاب آیکون</span> <span>انتخاب آیکون</span>
</Button> </Button>
<input
ref={fileInputRef}
type="file"
accept="image/*"
className="hidden"
onChange={handleFileChange}
/>
<Button
type="button"
onClick={handleUploadClick}
isloading={isUploadingIcon}
className="w-full max-h-10 lg:h-12 mt-2 flex items-center justify-center gap-2 text-xs lg:text-sm !bg-white border border-border !text-gray-700 hover:!bg-gray-50"
>
<DocumentUpload size={18} color="#374151" className="lg:w-5 lg:h-5" />
<span>آپلود آیکون</span>
</Button>
{selectedIconUrl && ( {selectedIconUrl && (
<div className="mt-3 flex items-center gap-2 lg:gap-3 p-2 lg:p-3 bg-gray-50 rounded-xl border border-gray-200"> <div className="mt-3 flex items-center gap-2 lg:gap-3 p-2 lg:p-3 bg-gray-50 rounded-xl border border-gray-200">
<div className="w-10 h-10 lg:w-12 lg:h-12 flex items-center justify-center bg-white rounded-lg border border-gray-200 p-1.5 lg:p-2 flex-shrink-0"> <div className="w-10 h-10 lg:w-12 lg:h-12 flex items-center justify-center bg-white rounded-lg border border-gray-200 p-1.5 lg:p-2 flex-shrink-0">
@@ -154,7 +200,7 @@ const CategoryForm: FC<Props> = ({
<Button <Button
onClick={() => formik.handleSubmit()} onClick={() => formik.handleSubmit()}
className="w-full min-h-10 lg:h-auto text-xs lg:text-sm" className="w-full min-h-10 lg:h-auto text-xs lg:text-sm"
isloading={isSubmitting} isloading={isSubmitting || isUploadingIcon}
> >
<Add color='#fff' size={18} className="ml-2 lg:w-5 lg:h-5" /> <Add color='#fff' size={18} className="ml-2 lg:w-5 lg:h-5" />
ذخیره ذخیره