218 lines
7.7 KiB
TypeScript
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
|
|
|