crud slider + fix footer
This commit is contained in:
@@ -0,0 +1,217 @@
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user