domain and mail server
This commit is contained in:
@@ -125,7 +125,7 @@ const Table = <T extends RowDataType>({
|
||||
<thead className={`h-[60px] md:h-[69px] bg-white text-sm text-[#8C90A3] ${headerClassName}`}>
|
||||
<tr>
|
||||
{selectable && (
|
||||
<th className="px-3 md:px-6 py-3 md:py-4 w-8 md:w-10 relative z-[5]">
|
||||
<th className="px-3 md:px-6 py-3 md:py-4 w-8 md:w-10 relative z-[5] first:rounded-tr-2xl md:first:rounded-tr-3xl">
|
||||
<Checkbox
|
||||
checked={data.length > 0 && selectedRows.length === data.length}
|
||||
onCheckedChange={handleSelectAll}
|
||||
@@ -133,19 +133,13 @@ const Table = <T extends RowDataType>({
|
||||
</th>
|
||||
)}
|
||||
{columns.map((col) => (
|
||||
<th
|
||||
key={col.key}
|
||||
className={getCellClassName(col)}
|
||||
style={{ width: col.width }}
|
||||
>
|
||||
<Td text={col.title} />
|
||||
</th>
|
||||
<Td key={col.key} text={col.title} />
|
||||
))}
|
||||
{rowActions && (
|
||||
<th className="px-3 md:px-6 py-3 md:py-4 w-8 md:w-10"></th>
|
||||
<th className="px-3 md:px-6 py-3 md:py-4 w-8 md:w-10 rounded-tl-2xl md:rounded-tl-3xl"></th>
|
||||
)}
|
||||
</tr>
|
||||
</thead>
|
||||
</thead >
|
||||
);
|
||||
};
|
||||
|
||||
@@ -166,7 +160,7 @@ const Table = <T extends RowDataType>({
|
||||
<div className={`relative mt-6 md:mt-9 w-full ${className}`}>
|
||||
{(actionsPosition === 'top' || actionsPosition === 'above-header') && renderActions()}
|
||||
|
||||
<div className="overflow-x-auto overflow-hidden rounded-b-2xl md:rounded-b-3xl bg-white shadow-sm">
|
||||
<div className="overflow-x-auto overflow-hidden rounded-2xl md:rounded-3xl bg-white shadow-sm">
|
||||
<table className="w-full text-sm border-collapse min-w-[600px]">
|
||||
{renderHeader()}
|
||||
{actionsPosition === 'header-replace' && (
|
||||
|
||||
@@ -4,11 +4,12 @@ interface Props {
|
||||
text: string | number | ReactNode,
|
||||
children?: ReactNode,
|
||||
dir?: string,
|
||||
className?: string,
|
||||
}
|
||||
|
||||
const Td: FC<Props> = (props: Props) => {
|
||||
return (
|
||||
<td className='px-3 md:px-6 py-3 md:py-4 whitespace-nowrap text-xs' style={{ direction: props.dir === "ltr" ? "ltr" : "rtl" }}>
|
||||
<td className={`px-3 md:px-6 py-3 md:py-4 whitespace-nowrap text-xs ${props.className}`} style={{ direction: props.dir === "ltr" ? "ltr" : "rtl" }}>
|
||||
{
|
||||
props.text ?
|
||||
props.text
|
||||
|
||||
+5
-1
@@ -92,7 +92,11 @@
|
||||
"smtp_server": "SMTP سرور",
|
||||
"smtp_port": "SMTP پورت",
|
||||
"username": "نام کاربری",
|
||||
"password": "پسورد"
|
||||
"password": "پسورد",
|
||||
"record_dns": "رکوردهای DNS",
|
||||
"record_dns_description": "در این قسمت میتوانید وضعیت رکوردهای DNS سرویس ایمیل خود را بررسی کنید.",
|
||||
"your_domain": "دامنه شما",
|
||||
"submit": "ثبت"
|
||||
},
|
||||
"upload": "آپلود",
|
||||
"new_message": {
|
||||
|
||||
@@ -1,79 +1,147 @@
|
||||
import Button from '@/components/Button'
|
||||
import Input from '@/components/Input'
|
||||
import RadioGroup from '@/components/RadioGroup'
|
||||
import Table from '@/components/Table'
|
||||
import { FC } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { TickCircle } from 'iconsax-react'
|
||||
import { Copy } from 'iconsax-react'
|
||||
|
||||
interface DNSRecord extends Record<string, unknown> {
|
||||
id: number
|
||||
status: 'verified' | 'pending'
|
||||
type: string
|
||||
name: string
|
||||
value: string
|
||||
number: number
|
||||
}
|
||||
|
||||
const Domain: FC = () => {
|
||||
const { t } = useTranslation()
|
||||
return (
|
||||
<div className='bg-white rounded-4xl p-8 mt-9'>
|
||||
<div className=''>
|
||||
<div className='flex justify-between items-end border-b pb-10 broder-border'>
|
||||
<div className='flex-1'>
|
||||
<div className='text-lg'>
|
||||
{t('setting.setting_fetch')}
|
||||
</div>
|
||||
<div className='text-sm text-description mt-1.5'>
|
||||
{t('setting.setting_fetch_description')}
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex-1'>
|
||||
<RadioGroup
|
||||
items={[
|
||||
{
|
||||
label: '۱ دقیقه',
|
||||
value: '1'
|
||||
},
|
||||
{
|
||||
label: '۲ دقیقه',
|
||||
value: '2'
|
||||
},
|
||||
{
|
||||
label: '۳ دقیقه',
|
||||
value: '3'
|
||||
}
|
||||
]}
|
||||
onChange={() => null}
|
||||
selected='1'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='mt-9'>
|
||||
<div className='flex justify-between items-start pb-10'>
|
||||
<div className='flex-1'>
|
||||
<div className='text-lg'>
|
||||
{t('setting.setting_smtp')}
|
||||
</div>
|
||||
<div className='text-sm text-description mt-1.5'>
|
||||
{t('setting.setting_smtp_description')}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='flex-1'>
|
||||
<Input
|
||||
label={t('setting.smtp_server')}
|
||||
/>
|
||||
<div className='mt-8'>
|
||||
<Input
|
||||
label={t('setting.smtp_port')}
|
||||
/>
|
||||
</div>
|
||||
<div className='mt-8'>
|
||||
<Input
|
||||
label={t('setting.username')}
|
||||
/>
|
||||
</div>
|
||||
<div className='mt-8'>
|
||||
<Input
|
||||
label={t('setting.password')}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
const { t } = useTranslation()
|
||||
|
||||
// نمونه دادههای DNS records طبق تصویر
|
||||
const dnsRecords: DNSRecord[] = [
|
||||
{
|
||||
id: 1,
|
||||
status: 'verified',
|
||||
type: 'TXT',
|
||||
name: 'example.com',
|
||||
value: 'v=spf1 include:_spf.example.com ~all',
|
||||
number: 1
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
status: 'verified',
|
||||
type: 'MX | Priority:10',
|
||||
name: 'example.com',
|
||||
value: '10 mail.example.com',
|
||||
number: 1
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
status: 'verified',
|
||||
type: 'Cname | No CDN',
|
||||
name: 'example.com',
|
||||
value: 'v=spf1 include:_spf.example.com ~all',
|
||||
number: 1
|
||||
},
|
||||
{
|
||||
id: 4,
|
||||
status: 'verified',
|
||||
type: 'TXT',
|
||||
name: 'example.com',
|
||||
value: 'v=spf1 include:_spf.example.com ~all',
|
||||
number: 1
|
||||
}
|
||||
]
|
||||
|
||||
const columns = [
|
||||
{
|
||||
title: 'شماره',
|
||||
key: 'number',
|
||||
width: '80px',
|
||||
align: 'center' as const,
|
||||
},
|
||||
{
|
||||
title: 'مقدار رکورد',
|
||||
key: 'value',
|
||||
render: (record: DNSRecord) => (
|
||||
<div className="flex items-center gap-2">
|
||||
|
||||
<span className="truncate max-w-[300px]">{record.value}</span>
|
||||
</div>
|
||||
)
|
||||
)
|
||||
},
|
||||
{
|
||||
title: 'نام رکورد',
|
||||
key: 'name',
|
||||
render: (record: DNSRecord) => (
|
||||
<div className="flex items-center gap-2">
|
||||
<button className="text-blue-500 hover:text-blue-700">
|
||||
<Copy size={16} color='#0038FF' />
|
||||
</button>
|
||||
<span>{record.name}</span>
|
||||
</div>
|
||||
)
|
||||
},
|
||||
{
|
||||
title: 'نوع رکورد',
|
||||
key: 'type',
|
||||
},
|
||||
{
|
||||
title: 'وضعیت',
|
||||
key: 'status',
|
||||
render: (record: DNSRecord) => (
|
||||
<div className="flex items-center gap-2">
|
||||
{record.status === 'verified' && (
|
||||
<>
|
||||
<TickCircle size={20} color="#22C55E" variant="Bold" />
|
||||
<span className="text-green-500 text-xs">ثبت شده</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
},
|
||||
]
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div className='flex justify-between'>
|
||||
<div>
|
||||
<div className='text-lg'>
|
||||
{t('setting.record_dns')}
|
||||
</div>
|
||||
<p className='mt-2 text-sm font-extralight'>
|
||||
{t('setting.record_dns_description')}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className='flex gap-2'>
|
||||
<Input
|
||||
placeholder={t('setting.your_domain')}
|
||||
className='w-[300px]'
|
||||
/>
|
||||
|
||||
<Button
|
||||
variant='secondary'
|
||||
className='w-fit px-14 border border-black'
|
||||
label={t('setting.submit')}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div className='mt-9'>
|
||||
<Table
|
||||
columns={columns}
|
||||
data={dnsRecords}
|
||||
className="!mt-0"
|
||||
/>
|
||||
</div>
|
||||
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Domain
|
||||
@@ -1,134 +1,79 @@
|
||||
import { FC, useState } from 'react'
|
||||
import Input from '@/components/Input'
|
||||
import RadioGroup from '@/components/RadioGroup'
|
||||
import { FC } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
const MailServer: FC = () => {
|
||||
const Domain: FC = () => {
|
||||
const { t } = useTranslation()
|
||||
const [serverType, setServerType] = useState('smtp')
|
||||
const [host, setHost] = useState('')
|
||||
const [port, setPort] = useState('')
|
||||
const [username, setUsername] = useState('')
|
||||
const [password, setPassword] = useState('')
|
||||
const [encryption, setEncryption] = useState('tls')
|
||||
|
||||
return (
|
||||
<div className='bg-white rounded-4xl p-8'>
|
||||
<div className='flex justify-between mb-8'>
|
||||
<h2 className='text-xl font-semibold'>{t('setting.mail_server')}</h2>
|
||||
<button className='bg-primary text-white px-6 py-2 rounded-lg'>{t('common.save')}</button>
|
||||
</div>
|
||||
|
||||
<div className='grid grid-cols-1 gap-6'>
|
||||
<div>
|
||||
<label className='block text-sm font-medium text-gray-700 mb-1'>{t('setting.server_type')}</label>
|
||||
<div className='flex gap-4 mb-4'>
|
||||
<label className='flex items-center gap-2 cursor-pointer'>
|
||||
<input
|
||||
type="radio"
|
||||
checked={serverType === 'smtp'}
|
||||
onChange={() => setServerType('smtp')}
|
||||
className='h-4 w-4 accent-primary'
|
||||
/>
|
||||
<span>SMTP</span>
|
||||
</label>
|
||||
<label className='flex items-center gap-2 cursor-pointer'>
|
||||
<input
|
||||
type="radio"
|
||||
checked={serverType === 'api'}
|
||||
onChange={() => setServerType('api')}
|
||||
className='h-4 w-4 accent-primary'
|
||||
/>
|
||||
<span>API</span>
|
||||
</label>
|
||||
<div className='bg-white rounded-4xl p-8 mt-9'>
|
||||
<div className=''>
|
||||
<div className='flex justify-between items-end border-b pb-10 broder-border'>
|
||||
<div className='flex-1'>
|
||||
<div className='text-lg'>
|
||||
{t('setting.setting_fetch')}
|
||||
</div>
|
||||
<div className='text-sm text-description mt-1.5'>
|
||||
{t('setting.setting_fetch_description')}
|
||||
</div>
|
||||
</div>
|
||||
<div className='flex-1'>
|
||||
<RadioGroup
|
||||
items={[
|
||||
{
|
||||
label: '۱ دقیقه',
|
||||
value: '1'
|
||||
},
|
||||
{
|
||||
label: '۲ دقیقه',
|
||||
value: '2'
|
||||
},
|
||||
{
|
||||
label: '۳ دقیقه',
|
||||
value: '3'
|
||||
}
|
||||
]}
|
||||
onChange={() => null}
|
||||
selected='1'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{serverType === 'smtp' && (
|
||||
<>
|
||||
<div className='grid grid-cols-2 gap-4'>
|
||||
<div>
|
||||
<label className='block text-sm font-medium text-gray-700 mb-1'>{t('setting.host')}</label>
|
||||
<input
|
||||
type="text"
|
||||
value={host}
|
||||
onChange={(e) => setHost(e.target.value)}
|
||||
className='w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent'
|
||||
placeholder='mail.example.com'
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className='block text-sm font-medium text-gray-700 mb-1'>{t('setting.port')}</label>
|
||||
<input
|
||||
type="text"
|
||||
value={port}
|
||||
onChange={(e) => setPort(e.target.value)}
|
||||
className='w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent'
|
||||
placeholder='587'
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className='mt-9'>
|
||||
<div className='flex justify-between items-start pb-10'>
|
||||
<div className='flex-1'>
|
||||
<div className='text-lg'>
|
||||
{t('setting.setting_smtp')}
|
||||
</div>
|
||||
<div className='text-sm text-description mt-1.5'>
|
||||
{t('setting.setting_smtp_description')}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className='block text-sm font-medium text-gray-700 mb-1'>{t('setting.username')}</label>
|
||||
<input
|
||||
type="text"
|
||||
value={username}
|
||||
onChange={(e) => setUsername(e.target.value)}
|
||||
className='w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent'
|
||||
placeholder='username@example.com'
|
||||
<div className='flex-1'>
|
||||
<Input
|
||||
label={t('setting.smtp_server')}
|
||||
/>
|
||||
<div className='mt-8'>
|
||||
<Input
|
||||
label={t('setting.smtp_port')}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className='block text-sm font-medium text-gray-700 mb-1'>{t('setting.password')}</label>
|
||||
<input
|
||||
type="password"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
className='w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent'
|
||||
<div className='mt-8'>
|
||||
<Input
|
||||
label={t('setting.username')}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<label className='block text-sm font-medium text-gray-700 mb-1'>{t('setting.encryption')}</label>
|
||||
<select
|
||||
value={encryption}
|
||||
onChange={(e) => setEncryption(e.target.value)}
|
||||
className='w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent'
|
||||
>
|
||||
<option value="none">{t('setting.none')}</option>
|
||||
<option value="ssl">SSL</option>
|
||||
<option value="tls">TLS</option>
|
||||
</select>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<button className='bg-blue-50 text-blue-600 px-4 py-2 rounded-lg mt-4'>{t('setting.test_connection')}</button>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
|
||||
{serverType === 'api' && (
|
||||
<>
|
||||
<div>
|
||||
<label className='block text-sm font-medium text-gray-700 mb-1'>{t('setting.api_key')}</label>
|
||||
<input
|
||||
type="password"
|
||||
className='w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent'
|
||||
<div className='mt-8'>
|
||||
<Input
|
||||
label={t('setting.password')}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className='block text-sm font-medium text-gray-700 mb-1'>{t('setting.api_url')}</label>
|
||||
<input
|
||||
type="text"
|
||||
className='w-full px-4 py-2 border border-gray-300 rounded-lg focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent'
|
||||
placeholder='https://api.example.com/send'
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default MailServer
|
||||
export default Domain
|
||||
Reference in New Issue
Block a user