uploader template
This commit is contained in:
@@ -4,7 +4,7 @@ import Button from '@/components/Button'
|
||||
import { TickCircle } from 'iconsax-react'
|
||||
import { useForm } from 'react-hook-form'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { FC, useEffect } from 'react'
|
||||
import { FC, useEffect, useState } from 'react'
|
||||
import { AddressData, CreateAddressType, UpdateAddressType } from '../types/Types'
|
||||
import { useGetDomains } from '../../domain/hooks/useDomainData'
|
||||
import { useCreateAddress, useUpdateAddress } from '../hooks/useAddressData'
|
||||
@@ -12,6 +12,7 @@ import { useGetSpace } from '../../domain/hooks/useDomainData'
|
||||
import { useGetTemplates } from '../../personality/hooks/usePersonalityData'
|
||||
import { toast } from '@/components/Toast'
|
||||
import { ErrorType } from '@/helpers/types'
|
||||
import ForwarderManager from './ForwarderManager'
|
||||
|
||||
interface AddressFormProps {
|
||||
selectedAddress: AddressData | null
|
||||
@@ -27,6 +28,7 @@ const AddressForm: FC<AddressFormProps> = ({ selectedAddress, isEditMode, onCanc
|
||||
const { data: spaceData } = useGetSpace()
|
||||
const { mutate: createAddress, isPending } = useCreateAddress()
|
||||
const { mutate: updateAddress, isPending: isUpdating } = useUpdateAddress()
|
||||
const [forwarders, setForwarders] = useState<string[]>([])
|
||||
|
||||
type FormData = CreateAddressType & { password?: string; quotaMB?: number }
|
||||
|
||||
@@ -85,6 +87,7 @@ const AddressForm: FC<AddressFormProps> = ({ selectedAddress, isEditMode, onCanc
|
||||
title: params.title,
|
||||
password: params.password || undefined,
|
||||
quota: params.quotaMB ? params.quotaMB * 1024 * 1024 : undefined,
|
||||
forwarders: forwarders,
|
||||
}
|
||||
updateAddress({ id: selectedAddress.id, params: updateParams }, {
|
||||
onSuccess: (data) => {
|
||||
@@ -99,11 +102,13 @@ const AddressForm: FC<AddressFormProps> = ({ selectedAddress, isEditMode, onCanc
|
||||
const createParams: CreateAddressType = {
|
||||
...params,
|
||||
quota: params.quotaMB ? params.quotaMB * 1024 * 1024 : undefined,
|
||||
forwarders: forwarders,
|
||||
}
|
||||
createAddress(createParams, {
|
||||
onSuccess: (data) => {
|
||||
toast(data?.data?.message, 'success')
|
||||
reset()
|
||||
setForwarders([])
|
||||
onSuccess()
|
||||
},
|
||||
onError: (error: ErrorType) => {
|
||||
@@ -130,6 +135,7 @@ const AddressForm: FC<AddressFormProps> = ({ selectedAddress, isEditMode, onCanc
|
||||
quotaMB: selectedAddress.emailQuota ? Math.round(selectedAddress.emailQuota / (1024 * 1024)) : undefined,
|
||||
templateId: selectedAddress.template || undefined,
|
||||
})
|
||||
setForwarders(selectedAddress.forwarders || [])
|
||||
} else if (!isEditMode) {
|
||||
reset({
|
||||
title: '',
|
||||
@@ -139,6 +145,7 @@ const AddressForm: FC<AddressFormProps> = ({ selectedAddress, isEditMode, onCanc
|
||||
quotaMB: undefined,
|
||||
templateId: domain?.data?.template,
|
||||
})
|
||||
setForwarders([])
|
||||
}
|
||||
}, [selectedAddress, isEditMode, reset, domain])
|
||||
|
||||
@@ -219,6 +226,13 @@ const AddressForm: FC<AddressFormProps> = ({ selectedAddress, isEditMode, onCanc
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='mt-6'>
|
||||
<ForwarderManager
|
||||
forwarders={forwarders}
|
||||
onChange={setForwarders}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className='mt-6'>
|
||||
<Input
|
||||
label={isEditMode ? 'رمز عبور جدید' : t('setting.password')}
|
||||
@@ -241,6 +255,8 @@ const AddressForm: FC<AddressFormProps> = ({ selectedAddress, isEditMode, onCanc
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
|
||||
<div className='mt-9 flex justify-end'>
|
||||
<Button
|
||||
className='w-fit px-20'
|
||||
|
||||
@@ -0,0 +1,111 @@
|
||||
import { FC, useState } from 'react'
|
||||
import Input from '@/components/Input'
|
||||
import Button from '@/components/Button'
|
||||
import { Add, Trash } from 'iconsax-react'
|
||||
import { toast } from '@/components/Toast'
|
||||
|
||||
interface ForwarderManagerProps {
|
||||
forwarders: string[]
|
||||
onChange: (forwarders: string[]) => void
|
||||
error?: string
|
||||
}
|
||||
|
||||
const ForwarderManager: FC<ForwarderManagerProps> = ({ forwarders, onChange, error }) => {
|
||||
const [newForwarder, setNewForwarder] = useState('')
|
||||
|
||||
const validateEmail = (email: string): boolean => {
|
||||
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/
|
||||
return emailRegex.test(email)
|
||||
}
|
||||
|
||||
const addForwarder = () => {
|
||||
if (!newForwarder.trim()) return
|
||||
|
||||
if (!validateEmail(newForwarder)) {
|
||||
toast('لطفاً یک ایمیل معتبر وارد کنید', 'error')
|
||||
return
|
||||
}
|
||||
|
||||
if (forwarders.includes(newForwarder)) {
|
||||
toast('این ایمیل قبلاً اضافه شده است', 'error')
|
||||
return
|
||||
}
|
||||
|
||||
onChange([...forwarders, newForwarder])
|
||||
setNewForwarder('')
|
||||
}
|
||||
|
||||
const removeForwarder = (index: number) => {
|
||||
const newForwarders = forwarders.filter((_, i) => i !== index)
|
||||
onChange(newForwarders)
|
||||
}
|
||||
|
||||
const handleKeyPress = (e: React.KeyboardEvent) => {
|
||||
if (e.key === 'Enter') {
|
||||
e.preventDefault()
|
||||
addForwarder()
|
||||
}
|
||||
}
|
||||
|
||||
return (
|
||||
<div>
|
||||
<label className='block text-sm font-medium text-gray-700 mb-2'>
|
||||
Forwarders
|
||||
</label>
|
||||
|
||||
{/* Add new forwarder */}
|
||||
<div className='flex gap-2 mb-3'>
|
||||
<div className='flex-1'>
|
||||
<Input
|
||||
placeholder='example@domain.com'
|
||||
value={newForwarder}
|
||||
onChange={(e) => setNewForwarder(e.target.value)}
|
||||
onKeyPress={handleKeyPress}
|
||||
className='text-left'
|
||||
dir='ltr'
|
||||
/>
|
||||
</div>
|
||||
<Button
|
||||
type='button'
|
||||
variant='primary'
|
||||
onClick={addForwarder}
|
||||
className='w-fit'
|
||||
disabled={!newForwarder.trim()}
|
||||
>
|
||||
<Add size={16} color='white' />
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{/* List of existing forwarders */}
|
||||
{forwarders.length > 0 && (
|
||||
<div className='space-y-2'>
|
||||
{forwarders.map((forwarder, index) => (
|
||||
<div key={index} className='flex items-center justify-between bg-gray-50 px-2 py-1 rounded-lg'>
|
||||
<span className='text-sm text-right flex-1 ' dir='ltr'>{forwarder}</span>
|
||||
<Button
|
||||
type='button'
|
||||
variant='secondary'
|
||||
onClick={() => removeForwarder(index)}
|
||||
className='w-fit h-9 text-red-500 hover:bg-red-50'
|
||||
>
|
||||
<Trash size={16} color='red' />
|
||||
</Button>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
|
||||
|
||||
|
||||
{error && (
|
||||
<div className='text-red-500 text-sm mt-1'>{error}</div>
|
||||
)}
|
||||
|
||||
<div className='text-[10px] text-gray-500 mt-2 leading-4'>
|
||||
ایمیلهایی که به این آدرس ارسال میشوند به آدرسهای فوق نیز فرستاده خواهند شد
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default ForwarderManager
|
||||
@@ -5,6 +5,7 @@ export type CreateAddressType = {
|
||||
title: string;
|
||||
quota?: number;
|
||||
templateId?: string;
|
||||
forwarders?: string[];
|
||||
};
|
||||
|
||||
export type UpdateAddressType = {
|
||||
@@ -13,6 +14,7 @@ export type UpdateAddressType = {
|
||||
quota?: number;
|
||||
aliases?: string[];
|
||||
title?: string;
|
||||
forwarders?: string[];
|
||||
};
|
||||
|
||||
export interface AddressData extends Record<string, unknown> {
|
||||
@@ -32,6 +34,7 @@ export interface AddressData extends Record<string, unknown> {
|
||||
isActive: boolean;
|
||||
emailSignature: string | null;
|
||||
role: string;
|
||||
forwarders?: string[];
|
||||
business: {
|
||||
id: string;
|
||||
createdAt: string;
|
||||
|
||||
Reference in New Issue
Block a user