domain
This commit is contained in:
@@ -0,0 +1,45 @@
|
||||
import Button from '@/components/Button'
|
||||
import { ArrowRight, InfoCircle, SmsNotification, Star, VolumeMute, More, DocumentDownload, ArchiveTick, Printer, Trash } from 'iconsax-react'
|
||||
import { FC } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
const Header: FC = () => {
|
||||
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
<div className='flex justify-between items-center border-b border-border pb-6'>
|
||||
<div className='flex gap-6'>
|
||||
<ArrowRight size={24} color='#8C90A3' />
|
||||
<SmsNotification size={24} color='black' />
|
||||
<ArchiveTick size={24} color='black' />
|
||||
<InfoCircle size={24} color='black' />
|
||||
<Star size={24} color='black' />
|
||||
<VolumeMute size={24} color='black' />
|
||||
<Trash size={24} color='#CD0000' />
|
||||
<More size={24} color='black' className='rotate-90' />
|
||||
</div>
|
||||
|
||||
<div className='flex gap-2'>
|
||||
<Button
|
||||
variant='secondary'
|
||||
>
|
||||
<div className='flex gap-2 items-center px-5'>
|
||||
<DocumentDownload size={20} color='black' />
|
||||
<span className='pt-0.5'>{t('mail.download')}</span>
|
||||
</div>
|
||||
</Button>
|
||||
<Button
|
||||
variant='secondary'
|
||||
>
|
||||
<div className='flex gap-2 items-center px-5'>
|
||||
<Printer size={20} color='black' />
|
||||
<span className='pt-0.5'>{t('mail.print')}</span>
|
||||
</div>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Header
|
||||
@@ -0,0 +1,135 @@
|
||||
import Button from '@/components/Button'
|
||||
import { FC, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import AvatarImage from '@/assets/images/avatar.svg'
|
||||
import { DocumentDownload, EmojiHappy } from 'iconsax-react'
|
||||
import ForwardIcon from '@/assets/images/forward.svg'
|
||||
import AnswerIcon from '@/assets/images/answer.svg'
|
||||
import Header from './Components/Header'
|
||||
import ReactQuill from 'react-quill-new';
|
||||
import Select from '@/components/Select'
|
||||
|
||||
const DetailEmail: FC = () => {
|
||||
|
||||
const { t } = useTranslation()
|
||||
const [showAnswer, setShowAnswer] = useState<boolean>(false)
|
||||
const [value, setValue] = useState<string>('')
|
||||
|
||||
return (
|
||||
<div className='bg-white rounded-4xl p-8'>
|
||||
<Header />
|
||||
|
||||
<div className='mt-6 flex justify-between items-center'>
|
||||
<div className='flex gap-4 items-center'>
|
||||
<div className='flex gap-1 items-center'>
|
||||
<div className='font-extralight '>{t('mail.subject')}</div>
|
||||
<div>لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ</div>
|
||||
</div>
|
||||
<Button
|
||||
label='دریافتی ها'
|
||||
className='bg-[#ECEFF6] text-description w-fit px-6 rounded-full'
|
||||
/>
|
||||
<Button
|
||||
label='الویت زیاد'
|
||||
className='bg-[#FFE9E9] text-[#CD0000] w-fit px-6 rounded-full'
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className='flex text-description text-sm'>
|
||||
۵ اسفندماه ۱۴۰۳، ساعت ۱۲:۰۰
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='mt-6 flex gap-4 items-center'>
|
||||
<img src={AvatarImage} className='size-10' />
|
||||
<div>مهرداد مظفری</div>
|
||||
</div>
|
||||
|
||||
<p className='mt-8 text-sm leading-7 font-light'>
|
||||
لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد کتابهای زیادی در شصت و سه درصد گذشته حال و آیندهلورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ و با استفاده از طراحان گرافیک است چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است و برای شرایط فعلی تکنولوژی مورد نیاز و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد کتابهای زیادی در شصت و سه درصد گذشته حال و آینده
|
||||
</p>
|
||||
|
||||
<div className='mt-10 text-sm font-bold'>
|
||||
{t('mail.attachments')}
|
||||
</div>
|
||||
|
||||
<div className='flex border-b border-border pb-10 mt-4 flex-wrap gap-2.5 items-center'>
|
||||
<div className='bg-[#EBEDF5] text-sm flex gap-2 h-10 rounded-full items-center px-4'>
|
||||
<span>Lorem Ipsum.pdf</span>
|
||||
<DocumentDownload size={20} color='#0038FF' />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{
|
||||
!showAnswer ?
|
||||
<div className='flex mt-9 justify-end'>
|
||||
<div className='flex gap-5 text-sm'>
|
||||
<EmojiHappy size={24} color='black' />
|
||||
|
||||
<div onClick={() => setShowAnswer(true)} className='flex gap-2 cursor-pointer items-center border-r border-border pr-5'>
|
||||
<img src={AnswerIcon} className='w-[17px]' />
|
||||
<div>{t('mail.answer')}</div>
|
||||
</div>
|
||||
|
||||
<div className='flex gap-2 cursor-pointer items-center border-r border-border pr-5'>
|
||||
<img src={ForwardIcon} className='w-[17px]' />
|
||||
<div>{t('mail.forward')}</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
:
|
||||
<div className='mt-9 flex gap-4'>
|
||||
<img src={AvatarImage} className='size-10' />
|
||||
<div className='w-full'>
|
||||
<div className='mb-2 text-sm'>
|
||||
{t('mail.message')}
|
||||
</div>
|
||||
<ReactQuill
|
||||
modules={{
|
||||
toolbar: [
|
||||
[{ header: '1' }, { header: '2' }, { font: [] }],
|
||||
[{ list: 'ordered' }, { list: 'bullet' }],
|
||||
['bold', 'italic', 'underline'],
|
||||
['link', 'image'],
|
||||
[{ align: [] }],
|
||||
['clean']
|
||||
]
|
||||
}}
|
||||
theme="snow"
|
||||
value={value}
|
||||
onChange={setValue}
|
||||
style={{ minHeight: '120px', width: '100%' }}
|
||||
className='text-sm'
|
||||
/>
|
||||
|
||||
<div>
|
||||
<div className='flex flex-col gap-4 sm:flex-row pt-4'>
|
||||
<div>
|
||||
<Select
|
||||
items={[]}
|
||||
placeholder={t('new_message.select_priority')}
|
||||
className='xl:w-[190px]'
|
||||
/>
|
||||
</div>
|
||||
<div className='flex-1 justify-end flex gap-3'>
|
||||
<Button
|
||||
className='!w-full sm:!w-fit px-6 md:px-10 bg-white text-black border border-primary order-2 sm:order-1'
|
||||
label={t('new_message.draft')}
|
||||
/>
|
||||
<Button
|
||||
className='w-full sm:w-fit px-6 md:px-10 order-1 sm:order-2'
|
||||
label={t('new_message.send')}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default DetailEmail
|
||||
@@ -1,123 +1,74 @@
|
||||
import { FC, useState } from 'react'
|
||||
import Input from '@/components/Input'
|
||||
import RadioGroup from '@/components/RadioGroup'
|
||||
import { FC } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { Add, CloseCircle } from 'iconsax-react'
|
||||
|
||||
const Domain: FC = () => {
|
||||
const { t } = useTranslation()
|
||||
const [domains, setDomains] = useState<string[]>(['example.com'])
|
||||
const [newDomain, setNewDomain] = useState('')
|
||||
const [error, setError] = useState('')
|
||||
|
||||
const handleAddDomain = () => {
|
||||
if (!newDomain) {
|
||||
setError(t('setting.domain_required'))
|
||||
return
|
||||
}
|
||||
|
||||
// Simple domain validation
|
||||
const domainRegex = /^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9]\.[a-zA-Z]{2,}$/
|
||||
if (!domainRegex.test(newDomain)) {
|
||||
setError(t('setting.invalid_domain'))
|
||||
return
|
||||
}
|
||||
|
||||
if (domains.includes(newDomain)) {
|
||||
setError(t('setting.domain_exists'))
|
||||
return
|
||||
}
|
||||
|
||||
setDomains([...domains, newDomain])
|
||||
setNewDomain('')
|
||||
setError('')
|
||||
}
|
||||
|
||||
const handleRemoveDomain = (domain: string) => {
|
||||
setDomains(domains.filter(d => d !== domain))
|
||||
}
|
||||
|
||||
return (
|
||||
<div className='bg-white rounded-4xl p-8'>
|
||||
<div className='flex justify-between mb-8'>
|
||||
<h2 className='text-xl font-semibold'>{t('setting.domain')}</h2>
|
||||
<button className='bg-primary text-white px-6 py-2 rounded-lg'>{t('common.save')}</button>
|
||||
</div>
|
||||
|
||||
<div className='mb-6'>
|
||||
<label className='block text-sm font-medium text-gray-700 mb-1'>{t('setting.add_domain')}</label>
|
||||
<div className='flex gap-2'>
|
||||
<input
|
||||
type="text"
|
||||
value={newDomain}
|
||||
onChange={(e) => {
|
||||
setNewDomain(e.target.value)
|
||||
setError('')
|
||||
}}
|
||||
className={`flex-1 px-4 py-2 border ${error ? 'border-red-500' : 'border-gray-300'} rounded-lg focus:outline-none focus:ring-2 focus:ring-primary focus:border-transparent`}
|
||||
placeholder='domain.com'
|
||||
/>
|
||||
<button
|
||||
onClick={handleAddDomain}
|
||||
className='bg-primary text-white px-4 py-2 rounded-lg'
|
||||
>
|
||||
<Add size={20} />
|
||||
</button>
|
||||
</div>
|
||||
{error && <p className='text-red-500 text-sm mt-1'>{error}</p>}
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<h3 className='text-md font-medium mb-4'>{t('setting.your_domains')}</h3>
|
||||
<div className='space-y-3'>
|
||||
{domains.map((domain, index) => (
|
||||
<div key={index} className='flex items-center justify-between p-4 bg-gray-50 rounded-lg'>
|
||||
<div>
|
||||
<p className='font-medium'>{domain}</p>
|
||||
<p className='text-sm text-gray-500'>
|
||||
{index === 0 ? t('setting.primary_domain') : t('setting.additional_domain')}
|
||||
</p>
|
||||
</div>
|
||||
<div className='flex items-center gap-3'>
|
||||
<div className={`px-2 py-1 rounded-full text-xs ${index === 0 ? 'bg-green-100 text-green-600' : 'bg-blue-100 text-blue-600'}`}>
|
||||
{index === 0 ? t('setting.verified') : t('setting.pending')}
|
||||
</div>
|
||||
{index !== 0 && (
|
||||
<button
|
||||
onClick={() => handleRemoveDomain(domain)}
|
||||
className='text-gray-400 hover:text-red-500'
|
||||
>
|
||||
<CloseCircle size={20} />
|
||||
</button>
|
||||
)}
|
||||
</div>
|
||||
<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='mt-8 p-4 bg-blue-50 rounded-lg'>
|
||||
<h3 className='text-md font-medium text-blue-700 mb-2'>{t('setting.dns_records')}</h3>
|
||||
<p className='text-sm text-blue-600 mb-4'>{t('setting.dns_instructions')}</p>
|
||||
|
||||
<div className='bg-white p-4 rounded-lg border border-blue-100'>
|
||||
<div className='grid grid-cols-3 gap-4 text-sm font-medium text-gray-500 pb-2 border-b'>
|
||||
<div>{t('setting.type')}</div>
|
||||
<div>{t('setting.hostname')}</div>
|
||||
<div>{t('setting.value')}</div>
|
||||
</div>
|
||||
<div className='grid grid-cols-3 gap-4 text-sm py-4 border-b'>
|
||||
<div>MX</div>
|
||||
<div>@</div>
|
||||
<div>mail.example.com</div>
|
||||
</div>
|
||||
<div className='grid grid-cols-3 gap-4 text-sm py-4 border-b'>
|
||||
<div>TXT</div>
|
||||
<div>@</div>
|
||||
<div className='break-all'>v=spf1 include:spf.example.com ~all</div>
|
||||
</div>
|
||||
<div className='grid grid-cols-3 gap-4 text-sm py-4'>
|
||||
<div>CNAME</div>
|
||||
<div>mail</div>
|
||||
<div>mailserver.example.com</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>
|
||||
@@ -125,4 +76,4 @@ const Domain: FC = () => {
|
||||
)
|
||||
}
|
||||
|
||||
export default Domain
|
||||
export default Domain
|
||||
Reference in New Issue
Block a user