Files
shop-admin/src/pages/setting/components/EditSliderModal.tsx
T
2025-10-25 14:58:06 +03:30

218 lines
7.7 KiB
TypeScript

import React, { useState, useEffect } from 'react'
import { type FC } from 'react'
import Button from '@/components/Button'
import Input from '@/components/Input'
import DefaulModal from '@/components/DefaulModal'
import Select from '@/components/Select'
import { useUpdateSlider } from '../hooks/useSettingData'
import { useUploadSingle } from '@/pages/uploader/hooks/useUploaderData'
import { type SliderItem, type UpdateSliderType } from '../types/Types'
import { toast } from 'react-toastify'
import { extractErrorMessage } from '@/helpers/utils'
import UploadBox from '@/components/UploadBox'
import Switch from '@/components/Switch'
interface EditSliderModalProps {
slider: SliderItem
isOpen: boolean
onClose: () => void
onSuccess: () => void
}
const EditSliderModal: FC<EditSliderModalProps> = ({ slider, isOpen, onClose, onSuccess }) => {
const [formData, setFormData] = useState<UpdateSliderType>({
displayLocation: 'desktop',
imageUrl: '',
altText: '',
title: '',
linkUrl: '',
isActive: true,
})
const [imageFile, setImageFile] = useState<File[]>([])
const updateSliderMutation = useUpdateSlider()
const uploadSingle = useUploadSingle()
useEffect(() => {
if (slider) {
setFormData({
displayLocation: slider.displayLocation,
imageUrl: slider.imageUrl,
altText: slider.altText,
title: slider.title,
linkUrl: slider.linkUrl,
isActive: slider.isActive,
})
}
}, [slider])
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault()
if (!formData.title || !formData.altText || !formData.linkUrl) {
toast.error('لطفا تمام فیلدهای الزامی را پر کنید')
return
}
try {
let finalImageUrl = formData.imageUrl
// Upload new image if selected
if (imageFile.length > 0) {
const uploadResponse = await uploadSingle.mutateAsync(imageFile[0])
finalImageUrl = uploadResponse.results?.url?.url
if (!finalImageUrl) {
toast.error('خطا در آپلود تصویر')
return
}
}
// Update slider
await updateSliderMutation.mutateAsync({
id: slider._id,
params: {
displayLocation: formData.displayLocation,
imageUrl: finalImageUrl,
altText: formData.altText,
title: formData.title,
linkUrl: formData.linkUrl,
isActive: formData.isActive,
}
}, {
onError: (error) => {
toast.error(extractErrorMessage(error))
}
})
toast.success('اسلایدر با موفقیت بروزرسانی شد')
handleClose()
onSuccess()
} catch (error) {
toast.error('خطا در آپلود تصویر')
}
}
const handleClose = () => {
setFormData({
displayLocation: 'desktop',
imageUrl: '',
altText: '',
title: '',
linkUrl: '',
isActive: true,
})
setImageFile([])
onClose()
}
const displayLocationOptions = [
{ value: 'desktop', label: 'دسکتاپ' },
{ value: 'mobile', label: 'موبایل' },
]
return (
<DefaulModal open={isOpen} close={handleClose} isHeader={true} title_header="ویرایش اسلایدر">
<form onSubmit={handleSubmit} className="w-[500px] mt-4 space-y-6">
{/* محل نمایش */}
<div>
<Select
label='محل نمایش'
value={formData.displayLocation}
onChange={(e) => setFormData(prev => ({ ...prev, displayLocation: e.target.value as 'desktop' | 'mobile' }))}
items={displayLocationOptions}
required
/>
</div>
{/* تصویر اسلایدر */}
<div>
<div className="mb-4">
<img
src={formData.imageUrl}
alt={formData.altText}
className="w-full h-32 object-cover rounded border"
onError={(e) => {
const target = e.target as HTMLImageElement
target.src = '/placeholder-image.png'
}}
/>
</div>
<UploadBox
label='تصویر جدید اسلایدر (اختیاری)'
isMultiple={false}
onChange={(files) => setImageFile(files)}
/>
</div>
{/* عنوان */}
<div>
<Input
label='عنوان اسلایدر'
value={formData.title}
onChange={(e) => setFormData(prev => ({ ...prev, title: e.target.value }))}
placeholder="عنوان اسلایدر را وارد کنید"
required
/>
</div>
{/* متن جایگزین */}
<div>
<Input
label='متن جایگزین (Alt Text)'
value={formData.altText}
onChange={(e) => setFormData(prev => ({ ...prev, altText: e.target.value }))}
placeholder="توضیح تصویر برای دسترسی"
required
/>
</div>
{/* لینک */}
<div>
<Input
label='لینک مقصد'
value={formData.linkUrl}
onChange={(e) => setFormData(prev => ({ ...prev, linkUrl: e.target.value }))}
placeholder="/summer-sale"
required
/>
</div>
{/* وضعیت */}
<div>
<Switch
active={formData.isActive}
onChange={(value) => setFormData(prev => ({ ...prev, isActive: value }))}
label="فعال"
/>
</div>
<div className="flex gap-3 pt-4">
<Button
type="submit"
variant="primary"
className="flex-1"
disabled={updateSliderMutation.isPending || uploadSingle.isPending}
isLoading={updateSliderMutation.isPending || uploadSingle.isPending}
>
{(updateSliderMutation.isPending || uploadSingle.isPending) ? 'در حال بروزرسانی...' : 'بروزرسانی'}
</Button>
<Button
type="button"
variant="outline"
className="flex-1"
onClick={handleClose}
disabled={updateSliderMutation.isPending || uploadSingle.isPending}
>
لغو
</Button>
</div>
</form>
</DefaulModal>
)
}
export default EditSliderModal