announcement and criticisms and wallet and learning and setting

This commit is contained in:
hamid zarghami
2024-12-31 15:55:30 +03:30
parent 7a5d9d6447
commit bdeb5a11d3
21 changed files with 1303 additions and 9 deletions
+198
View File
@@ -8,6 +8,7 @@
"name": "danak_dsc",
"version": "0.0.0",
"dependencies": {
"@headlessui/react": "^2.2.0",
"@tanstack/react-query": "^5.62.8",
"formik": "^2.4.6",
"i18next": "^24.2.0",
@@ -911,6 +912,78 @@
"node": "^18.18.0 || ^20.9.0 || >=21.1.0"
}
},
"node_modules/@floating-ui/core": {
"version": "1.6.8",
"resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.8.tgz",
"integrity": "sha512-7XJ9cPU+yI2QeLS+FCSlqNFZJq8arvswefkZrYI1yQBbftw6FyrZOxYSh+9S7z7TpeWlRt9zJ5IhM1WIL334jA==",
"license": "MIT",
"dependencies": {
"@floating-ui/utils": "^0.2.8"
}
},
"node_modules/@floating-ui/dom": {
"version": "1.6.12",
"resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.12.tgz",
"integrity": "sha512-NP83c0HjokcGVEMeoStg317VD9W7eDlGK7457dMBANbKA6GJZdc7rjujdgqzTaz93jkGgc5P/jeWbaCHnMNc+w==",
"license": "MIT",
"dependencies": {
"@floating-ui/core": "^1.6.0",
"@floating-ui/utils": "^0.2.8"
}
},
"node_modules/@floating-ui/react": {
"version": "0.26.28",
"resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.28.tgz",
"integrity": "sha512-yORQuuAtVpiRjpMhdc0wJj06b9JFjrYF4qp96j++v2NBpbi6SEGF7donUJ3TMieerQ6qVkAv1tgr7L4r5roTqw==",
"license": "MIT",
"dependencies": {
"@floating-ui/react-dom": "^2.1.2",
"@floating-ui/utils": "^0.2.8",
"tabbable": "^6.0.0"
},
"peerDependencies": {
"react": ">=16.8.0",
"react-dom": ">=16.8.0"
}
},
"node_modules/@floating-ui/react-dom": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.2.tgz",
"integrity": "sha512-06okr5cgPzMNBy+Ycse2A6udMi4bqwW/zgBF/rwjcNqWkyr82Mcg8b0vjX8OJpZFy/FKjJmw6wV7t44kK6kW7A==",
"license": "MIT",
"dependencies": {
"@floating-ui/dom": "^1.0.0"
},
"peerDependencies": {
"react": ">=16.8.0",
"react-dom": ">=16.8.0"
}
},
"node_modules/@floating-ui/utils": {
"version": "0.2.8",
"resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.8.tgz",
"integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==",
"license": "MIT"
},
"node_modules/@headlessui/react": {
"version": "2.2.0",
"resolved": "https://registry.npmjs.org/@headlessui/react/-/react-2.2.0.tgz",
"integrity": "sha512-RzCEg+LXsuI7mHiSomsu/gBJSjpupm6A1qIZ5sWjd7JhARNlMiSA4kKfJpCKwU9tE+zMRterhhrP74PvfJrpXQ==",
"license": "MIT",
"dependencies": {
"@floating-ui/react": "^0.26.16",
"@react-aria/focus": "^3.17.1",
"@react-aria/interactions": "^3.21.3",
"@tanstack/react-virtual": "^3.8.1"
},
"engines": {
"node": ">=10"
},
"peerDependencies": {
"react": "^18 || ^19 || ^19.0.0-rc",
"react-dom": "^18 || ^19 || ^19.0.0-rc"
}
},
"node_modules/@humanfs/core": {
"version": "0.19.1",
"resolved": "https://registry.npmjs.org/@humanfs/core/-/core-0.19.1.tgz",
@@ -1097,6 +1170,89 @@
"node": ">=14"
}
},
"node_modules/@react-aria/focus": {
"version": "3.19.0",
"resolved": "https://registry.npmjs.org/@react-aria/focus/-/focus-3.19.0.tgz",
"integrity": "sha512-hPF9EXoUQeQl1Y21/rbV2H4FdUR2v+4/I0/vB+8U3bT1CJ+1AFj1hc/rqx2DqEwDlEwOHN+E4+mRahQmlybq0A==",
"license": "Apache-2.0",
"dependencies": {
"@react-aria/interactions": "^3.22.5",
"@react-aria/utils": "^3.26.0",
"@react-types/shared": "^3.26.0",
"@swc/helpers": "^0.5.0",
"clsx": "^2.0.0"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/interactions": {
"version": "3.22.5",
"resolved": "https://registry.npmjs.org/@react-aria/interactions/-/interactions-3.22.5.tgz",
"integrity": "sha512-kMwiAD9E0TQp+XNnOs13yVJghiy8ET8L0cbkeuTgNI96sOAp/63EJ1FSrDf17iD8sdjt41LafwX/dKXW9nCcLQ==",
"license": "Apache-2.0",
"dependencies": {
"@react-aria/ssr": "^3.9.7",
"@react-aria/utils": "^3.26.0",
"@react-types/shared": "^3.26.0",
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/ssr": {
"version": "3.9.7",
"resolved": "https://registry.npmjs.org/@react-aria/ssr/-/ssr-3.9.7.tgz",
"integrity": "sha512-GQygZaGlmYjmYM+tiNBA5C6acmiDWF52Nqd40bBp0Znk4M4hP+LTmI0lpI1BuKMw45T8RIhrAsICIfKwZvi2Gg==",
"license": "Apache-2.0",
"dependencies": {
"@swc/helpers": "^0.5.0"
},
"engines": {
"node": ">= 12"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-aria/utils": {
"version": "3.26.0",
"resolved": "https://registry.npmjs.org/@react-aria/utils/-/utils-3.26.0.tgz",
"integrity": "sha512-LkZouGSjjQ0rEqo4XJosS4L3YC/zzQkfRM3KoqK6fUOmUJ9t0jQ09WjiF+uOoG9u+p30AVg3TrZRUWmoTS+koQ==",
"license": "Apache-2.0",
"dependencies": {
"@react-aria/ssr": "^3.9.7",
"@react-stately/utils": "^3.10.5",
"@react-types/shared": "^3.26.0",
"@swc/helpers": "^0.5.0",
"clsx": "^2.0.0"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-stately/utils": {
"version": "3.10.5",
"resolved": "https://registry.npmjs.org/@react-stately/utils/-/utils-3.10.5.tgz",
"integrity": "sha512-iMQSGcpaecghDIh3mZEpZfoFH3ExBwTtuBEcvZ2XnGzCgQjeYXcMdIUwAfVQLXFTdHUHGF6Gu6/dFrYsCzySBQ==",
"license": "Apache-2.0",
"dependencies": {
"@swc/helpers": "^0.5.0"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@react-types/shared": {
"version": "3.26.0",
"resolved": "https://registry.npmjs.org/@react-types/shared/-/shared-3.26.0.tgz",
"integrity": "sha512-6FuPqvhmjjlpEDLTiYx29IJCbCNWPlsyO+ZUmCUXzhUv2ttShOXfw8CmeHWHftT/b2KweAWuzqSlfeXPR76jpw==",
"license": "Apache-2.0",
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0-rc.1 || ^18.0.0 || ^19.0.0-rc.1"
}
},
"node_modules/@rollup/rollup-android-arm-eabi": {
"version": "4.29.1",
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.29.1.tgz",
@@ -1363,6 +1519,15 @@
"win32"
]
},
"node_modules/@swc/helpers": {
"version": "0.5.15",
"resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.15.tgz",
"integrity": "sha512-JQ5TuMi45Owi4/BIMAJBoSQoOJu12oOk/gADqlcUL9JEdHB8vyjUSsxqeNXnmXHjYKMi2WcYtezGEEhqUI/E2g==",
"license": "Apache-2.0",
"dependencies": {
"tslib": "^2.8.0"
}
},
"node_modules/@tanstack/query-core": {
"version": "5.62.8",
"resolved": "https://registry.npmjs.org/@tanstack/query-core/-/query-core-5.62.8.tgz",
@@ -1389,6 +1554,33 @@
"react": "^18 || ^19"
}
},
"node_modules/@tanstack/react-virtual": {
"version": "3.11.2",
"resolved": "https://registry.npmjs.org/@tanstack/react-virtual/-/react-virtual-3.11.2.tgz",
"integrity": "sha512-OuFzMXPF4+xZgx8UzJha0AieuMihhhaWG0tCqpp6tDzlFwOmNBPYMuLOtMJ1Tr4pXLHmgjcWhG6RlknY2oNTdQ==",
"license": "MIT",
"dependencies": {
"@tanstack/virtual-core": "3.11.2"
},
"funding": {
"type": "github",
"url": "https://github.com/sponsors/tannerlinsley"
},
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0",
"react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
}
},
"node_modules/@tanstack/virtual-core": {
"version": "3.11.2",
"resolved": "https://registry.npmjs.org/@tanstack/virtual-core/-/virtual-core-3.11.2.tgz",
"integrity": "sha512-vTtpNt7mKCiZ1pwU9hfKPhpdVO2sVzFQsxoVBGtOSHxlrRRzYr8iQ2TlwbAcRYCcEiZ9ECAM8kBzH0v2+VzfKw==",
"license": "MIT",
"funding": {
"type": "github",
"url": "https://github.com/sponsors/tannerlinsley"
}
},
"node_modules/@types/babel__core": {
"version": "7.20.5",
"resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.20.5.tgz",
@@ -4219,6 +4411,12 @@
"url": "https://github.com/sponsors/ljharb"
}
},
"node_modules/tabbable": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz",
"integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew==",
"license": "MIT"
},
"node_modules/tailwind-merge": {
"version": "2.5.5",
"resolved": "https://registry.npmjs.org/tailwind-merge/-/tailwind-merge-2.5.5.tgz",
+1
View File
@@ -10,6 +10,7 @@
"preview": "vite preview"
},
"dependencies": {
"@headlessui/react": "^2.2.0",
"@tanstack/react-query": "^5.62.8",
"formik": "^2.4.6",
"i18next": "^24.2.0",
Binary file not shown.

After

Width:  |  Height:  |  Size: 209 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.8 KiB

+6 -3
View File
@@ -16,9 +16,12 @@ type Props = {
const Select: FC<Props> = (props: Props) => {
return (
<div className='w-full relative'>
<label className='text-sm'>
{props.label}
</label>
{
props.label &&
<label className='text-sm'>
{props.label}
</label>
}
<select {...props} className={clx(
'w-full text-black block border-border px-2.5 h-10 text-sm rounded-2.5 bg-gray',
props.className,
+22
View File
@@ -0,0 +1,22 @@
import { FC } from 'react'
import { clx } from '../helpers/utils'
type Props = {
variant: 'success' | 'error' | 'warning',
text: string,
}
const StatusWithText: FC<Props> = (props: Props) => {
return (
<div className={clx(
'w-fit py-1 px-2 text-xs h-fit rounded-full',
props.variant === 'success' && 'bg-green-100 text-success',
props.variant === 'error' && 'bg-red-100 text-red-400',
props.variant === 'warning' && 'bg-yellow-100 text-yellow-400',
)}>
{props.text}
</div>
)
}
export default StatusWithText
+50
View File
@@ -0,0 +1,50 @@
import { Fragment } from 'react'
import { Switch } from '@headlessui/react'
import ReactLoading from 'react-loading'
interface Props {
active: boolean,
onChange: (value: boolean) => void,
isLoading?: boolean,
label?: string,
}
const SwitchComponent = (props: Props) => {
const handleChange = (value: boolean) => {
props.onChange(value)
}
if (props.isLoading) {
return (
<ReactLoading type='spin' color='black' width={20} height={20} className='ml-4' />
)
}
return (
<div className='dltr w-fit flex gap-2 items-center'>
<Switch checked={props.active} onChange={handleChange} as={Fragment}>
{({ checked }) => (
<button
className={`${checked ? 'bg-primary' : 'bg-gray-200'
} relative inline-flex h-6 w-11 items-center rounded-full`}
>
<span className="sr-only">Enable notifications</span>
<span
className={`${checked ? 'translate-x-6' : 'translate-x-1'
} inline-block h-4 w-4 transform rounded-full bg-white transition`}
/>
</button>
)}
</Switch>
{
props.label &&
<div className='text-sm'>
: {props.label}
</div>
}
</div>
)
}
export default SwitchComponent
+1
View File
@@ -20,4 +20,5 @@ export const Pages = {
criticisms: "/criticisms",
learning: "/learning",
setting: "/setting",
wallet: "/wallet",
};
+62 -1
View File
@@ -126,6 +126,67 @@
"its_time": "سررسیده شده",
"archive": "بایگانی شده"
},
"transaction": {
"transaction": "تراکنش ها",
"totao_deposit": "مجموع واریز ها",
"total_withdrawal": "مجموع برداشت ها",
"balance": "موجودی کیف پول"
},
"announcement": {
"announcements": "اطلاعیه ها",
"search": "جستجو در اطلاعیه ها",
"new": "جدید",
"important": "مهم"
},
"criticisms": {
"criticisms": "انتقادات",
"submit_your_criticisms": "ثبت انتقاد شما",
"description_criticisms": "با انتقاد خود راهگشای ما باشید.",
"subject": "موضوع",
"enter_your_subject": "موضوع انتقاد خودرا وارد کنید",
"description": "توضیحات",
"enter_description": "توضیحات شما"
},
"select_file": "انتخاب فایل",
"no_select_file": "هیچ فایلی انتخاب نشده است"
"no_select_file": "هیچ فایلی انتخاب نشده است",
"attachment": "فایل های ضمیمه",
"learning": {
"learning": "آموزش"
},
"setting": {
"setting": "تنظیمات",
"notification": "پیام و ایمیل",
"password": "رمز عبور",
"setting_email_message": "تنظیمات ارسال پیام و ایمیل",
"notification_announcement": "اعلانات و اطلاعیه ها",
"email": "ایمیل",
"sms": "پیامک",
"change_password": "تغییر رمز عبور",
"current_password": "رمز عبور فعلی",
"new_password": "رمز عبور جدید",
"reapeat_password": "تکرار رمز عبور",
"save_change": "ذخیره تغییرات",
"password_is": "رمز عبور می‌بایست:",
"min-8": "حداقل 8 کاراکتر باشد",
"mix_charachter_number": "ترکیبی از حروف کوچک و بزرگ باشد",
"exsist_number": "شامل اعداد باشد",
"exsist_special_character": "شامل کاراکتر های خاص (نماد ها) باشد"
},
"wallet": {
"increese_wallet": "افزایش موجودی حساب اعتباری",
"online_pay": "پرداخت آنلاین",
"card_to_card": "کارت به کارت",
"select_price": "انتخاب مبلغ",
"optional_price": "مبلغ دلخواه‌ (به ریال وارد کنید)",
"enter_your_price": "مبلغ دلخواه خودرا وارد کنید",
"select_payment": "انتخاب درگاه پرداخت",
"pay": "پرداخت",
"amount": "مبلغ",
"enter_amount_card": "مبلغ کارت به کارت شده را وارد کنید",
"upload_deposit_slip": "آپلود فیش واریزی",
"submit_slip": "ثبت فیش",
"sheba": "شبا",
"pay_sheba": "پرداخت شبا",
"enter_sheba_deposit": "مبلغ شبا شده شده را وارد کنید"
}
}
+129
View File
@@ -0,0 +1,129 @@
import { FC } from 'react'
import { useTranslation } from 'react-i18next'
import Input from '../../components/Input'
import Select from '../../components/Select'
import StatusWithText from '../../components/StatusWithText'
import { clx } from '../../helpers/utils'
const AnnouncementtList: FC = () => {
const { t } = useTranslation('global')
return (
<div className='mt-4 text-sm'>
<div className='text-base'>
{t('announcement.announcements')}
</div>
<div className='mt-10 flex gap-8'>
<div className='bg-white w-[400px] rounded-2xl p-6'>
<div className='flex gap-3 items-center'>
<div className='flex-1'>
<Input
variant='search'
placeholder={t('announcement.search')}
className='-mt-1'
/>
</div>
<div>
<Select
items={[
{ value: '1', label: 'همه' },
{ value: '2', label: 'فعال' },
{ value: '3', label: 'غیر فعال' },
]}
className='bg-[#EEF0F7] w-[68px]'
/>
</div>
</div>
<div className='mt-8'>
<div className={clx(
'p-4 rounded-2xl',
'bg-[#F8F9FB]'
)}>
<div className='flex justify-between'>
<div className='leading-6 max-w-[70%]'>
لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ
</div>
<div className='flex gap-1'>
<StatusWithText
variant='error'
text={t('announcement.important')}
/>
<StatusWithText
variant='success'
text={t('announcement.new')}
/>
</div>
</div>
<div className='m-2 flex justify-between items-center text-[11px]'>
<div className='max-w-[70%] truncate '>
لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ
</div>
<div className='text-description'>
۱۴۰۳/۰۹/۲۴
</div>
</div>
</div>
<div className={clx(
'p-4 rounded-2xl',
)}>
<div className='flex justify-between'>
<div className='leading-6 max-w-[70%]'>
لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ
</div>
<div className='flex gap-1'>
<StatusWithText
variant='error'
text={t('announcement.important')}
/>
<StatusWithText
variant='success'
text={t('announcement.new')}
/>
</div>
</div>
<div className='m-2 flex justify-between items-center text-[11px]'>
<div className='max-w-[70%] truncate '>
لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ
</div>
<div className='text-description'>
۱۴۰۳/۰۹/۲۴
</div>
</div>
</div>
</div>
</div>
<div className='flex-1 bg-white py-7 px-5 rounded-2xl'>
<div className='flex justify-between items-center'>
<div className='text-lg'>
متن اطلاعیه
</div>
<StatusWithText
variant='success'
text={t('announcement.new')}
/>
</div>
<div className='mt-8'>
لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ
</div>
<div className='mt-5 leading-7 text-xs font-light'>
لورم ایپسوم متن ساختگی با تولید سادگی نامفهوم از صنعت چاپ، و با استفاده از طراحان گرافیک است، چاپگرها و متون بلکه روزنامه و مجله در ستون و سطرآنچنان که لازم است، و برای شرایط فعلی تکنولوژی مورد نیاز، و کاربردهای متنوع با هدف بهبود ابزارهای کاربردی می باشد، کتابهای زیادی در شصت و سه درصد گذشته حال و آینده، شناخت فراوان جامعه و متخصصان را می طلبد، تا با نرم افزارها شناخت بیشتری را برای طراحان رایانه ای علی الخصوص طراحان خلاقی، و فرهنگ پیشرو در زبان فارسی ایجاد کرد، در این صورت می توان امید داشت که تمام و دشواری موجود در ارائه راهکارها، و شرایط سخت تایپ به پایان رسد و زمان مورد نیاز شامل حروفچینی دستاوردهای اصلی، و جوابگوی سوالات پیوسته اهل دنیای موجود طراحی اساسا مورد استفاده قرار گیرد.
</div>
</div>
</div>
</div>
)
}
export default AnnouncementtList
+97
View File
@@ -0,0 +1,97 @@
import { FC } from 'react'
import { useTranslation } from 'react-i18next'
import { SIDEBAR_SIZE_LEFT } from '../../config/Const'
import Input from '../../components/Input'
import Textarea from '../../components/Textarea'
import UploadBox from '../../components/UploadBox'
import Button from '../../components/Button'
import { TickSquare } from 'iconsax-react'
const AddCriticisms: FC = () => {
const { t } = useTranslation('global')
return (
<div className='mt-4 text-sm'>
<div>
{t('criticisms.criticisms')}
</div>
<div className='flex gap-6 mt-8'>
<div className='flex-1 bg-white py-8 px-10 rounded-3xl'>
<div>
{t('criticisms.submit_your_criticisms')}
</div>
<div className='mt-3 text-xs text-description'>
{t('criticisms.description_criticisms')}
</div>
<div className='mt-10'>
<Input
label={t('criticisms.subject')}
placeholder={t('criticisms.enter_your_subject')}
/>
</div>
<div className='mt-7'>
<Textarea
label={t('criticisms.description')}
placeholder={t('criticisms.enter_description')}
/>
</div>
<div className='mt-7'>
<UploadBox
label={t('attachment')}
/>
</div>
<div className='mt-20 flex justify-end'>
<Button
label={t('ticket.send')}
className='max-w-[100px]'
/>
</div>
</div>
<div style={{ width: SIDEBAR_SIZE_LEFT }} className='bg-white py-10 px-5 h-fit rounded-3xl'>
<div className='text-sm'>
{t('ticket.title_hint')}
</div>
<div className='mt-6'>
<div className='flex items-start gap-2 border-b pb-5'>
<div>
<TickSquare size={20} color='black' variant='Bold' />
</div>
<div className='text-description text-xs leading-5'>
سوالات - مشکلاتی که به یک موضوع مربوط میشوند را در یک درخواست پشتیبانی پیگیر باشید و چند درخواست برای یک موضوع باز نکنید.
</div>
</div>
<div className='flex items-start gap-2 mt-6 border-b pb-5'>
<div>
<TickSquare size={20} color='black' variant='Bold' />
</div>
<div className='text-description text-xs leading-5'>
لطفاً برای بررسی و رفع مشکلات احتمالی صبور باشید بررسی و رفع مشکلات در برخی موارد زمان گیر است.
</div>
</div>
<div className='flex items-start gap-2 mt-6'>
<div>
<TickSquare size={20} color='black' variant='Bold' />
</div>
<div className='text-description text-xs leading-5'>
پاسخگویی 24 ساعته تلفنی را تنها از میهن وب هاست می توانید انتظار داشته باشید .بخش پشتیبانی در هر ساعتی حتی در روز های تعطیل آماده پیگیری سریع مشکلات کاربران است.
</div>
</div>
</div>
</div>
</div>
</div>
)
}
export default AddCriticisms
+121
View File
@@ -0,0 +1,121 @@
import { FC } from 'react'
import { useTranslation } from 'react-i18next'
import { SIDEBAR_SIZE_LEFT } from '../../config/Const'
import BannerImage from '../../assets/images/banner.png'
import Select from '../../components/Select'
import Input from '../../components/Input'
import LearningImage from '../../assets/images/learning.png'
const LearningList: FC = () => {
const { t } = useTranslation('global')
return (
<div className='w-full flex gap-6 mt-4'>
<div className='flex-1'>
<div>
{t('learning.learning')}
</div>
<div className='mt-8 flex gap-6 items-center'>
<div className='w-[300px]'>
<Input
variant='search'
placeholder={t('service.search')}
className='bg-white w-full'
/>
</div>
<Select
items={[
{ label: t('all'), value: 'all' },
{ label: 'Active', value: 'active' },
{ label: 'Inactive', value: 'inactive' },
]}
className='max-w-[100px]'
/>
</div>
<div className='mt-9 flex flex-wrap gap-8 text-sm'>
<div className='bg-white p-4 rounded-3xl min-w-[30%] flex-1'>
<img src={LearningImage} className='w-full rounded-[20px]' />
<div className='mt-4'>
لورم ایپسوم متن ساختگی با تولید سادگی
</div>
<div className='flex gap-1 text-xs text-description mt-2'>
<div>دیزاین ,</div>
<div>۲۴ دقیقه</div>
</div>
<div className='mt-3 text-xs text-description'>
آذر ماه 1403
</div>
</div>
<div className='bg-white p-4 rounded-3xl min-w-[30%] flex-1'>
<img src={LearningImage} className='w-full rounded-[20px]' />
<div className='mt-4'>
لورم ایپسوم متن ساختگی با تولید سادگی
</div>
<div className='flex gap-1 text-xs text-description mt-2'>
<div>دیزاین ,</div>
<div>۲۴ دقیقه</div>
</div>
<div className='mt-3 text-xs text-description'>
آذر ماه 1403
</div>
</div>
<div className='bg-white p-4 rounded-3xl min-w-[30%] flex-1'>
<img src={LearningImage} className='w-full rounded-[20px]' />
<div className='mt-4'>
لورم ایپسوم متن ساختگی با تولید سادگی
</div>
<div className='flex gap-1 text-xs text-description mt-2'>
<div>دیزاین ,</div>
<div>۲۴ دقیقه</div>
</div>
<div className='mt-3 text-xs text-description'>
آذر ماه 1403
</div>
</div>
<div className='bg-white p-4 rounded-3xl min-w-[30%] flex-1'>
<img src={LearningImage} className='w-full rounded-[20px]' />
<div className='mt-4'>
لورم ایپسوم متن ساختگی با تولید سادگی
</div>
<div className='flex gap-1 text-xs text-description mt-2'>
<div>دیزاین ,</div>
<div>۲۴ دقیقه</div>
</div>
<div className='mt-3 text-xs text-description'>
آذر ماه 1403
</div>
</div>
<div className='min-w-[30%] flex-1 px-4'></div>
<div className='min-w-[30%] flex-1 px-4'></div>
</div>
</div>
<div style={{ width: SIDEBAR_SIZE_LEFT }} className='bg-white h-fit rounded-3xl overflow-hidden relative'>
<img
src={BannerImage}
className='w-full backdrop-blur-[100px] h-[550px] object-cover'
/>
<div className='absolute flex items-center px-4 w-full bottom-0 h-[86px] bg-black bg-opacity-5 backdrop-blur-[14px]'>
<div className='max-w-[80%] text-sm leading-6 text-white'>
سفارش نرمافزار اختصاصی: سرمایه‌ای برای آینده یا فقط هزینهای برای امروز؟
</div>
</div>
</div>
</div>
)
}
export default LearningList
+210
View File
@@ -0,0 +1,210 @@
import { FC, useState } from 'react'
import { useTranslation } from 'react-i18next'
import Tabs from '../../components/Tabs'
import { KeySquare, Notification1 } from 'iconsax-react'
import SwitchComponent from '../../components/Switch'
import Input from '../../components/Input'
import Button from '../../components/Button'
const Setting: FC = () => {
const { t } = useTranslation('global')
const [activeTab, setActiveTab] = useState<string>('notification')
return (
<div className='mt-4'>
<div>
{t('setting.setting')}
</div>
<div className='mt-10'>
<Tabs
items={[
{
icon: <Notification1 color={activeTab === 'notification' ? 'black' : '#8C90A3'} size={22} />,
label: t('setting.notification'),
value: 'notification'
},
{
icon: <KeySquare color={activeTab === 'password' ? 'black' : '#8C90A3'} size={22} />,
label: t('setting.password'),
value: 'password'
},
]}
active={activeTab}
onChange={setActiveTab}
/>
</div>
{
activeTab === 'notification' ?
<div className='mt-10 bg-white p-8 rounded-3xl'>
<div>
{t('setting.setting_email_message')}
</div>
<div className='flex gap-6 text-sm mt-8'>
<div className='flex-1 border border-border px-4 rounded-2xl h-14 items-center flex justify-between'>
<div>
{t('setting.notification_announcement')}
</div>
<div className='flex gap-4'>
<div className='flex gap-1 text-xs items-center text-description'>
<SwitchComponent
active={true}
onChange={() => { }}
/>
<div>
{t('setting.email')}
</div>
</div>
<div className='flex gap-1 text-xs items-center text-description'>
<SwitchComponent
active={false}
onChange={() => { }}
/>
<div>
{t('setting.sms')}
</div>
</div>
</div>
</div>
<div className='flex-1 border border-border px-4 rounded-2xl h-14 items-center flex justify-between'>
<div>
{t('setting.notification_announcement')}
</div>
<div className='flex gap-4'>
<div className='flex gap-1 text-xs items-center text-description'>
<SwitchComponent
active={true}
onChange={() => { }}
/>
<div>
{t('setting.email')}
</div>
</div>
<div className='flex gap-1 text-xs items-center text-description'>
<SwitchComponent
active={false}
onChange={() => { }}
/>
<div>
{t('setting.sms')}
</div>
</div>
</div>
</div>
</div>
<div className='flex gap-6 text-sm mt-6'>
<div className='flex-1 border border-border px-4 rounded-2xl h-14 items-center flex justify-between'>
<div>
{t('setting.notification_announcement')}
</div>
<div className='flex gap-4'>
<div className='flex gap-1 text-xs items-center text-description'>
<SwitchComponent
active={true}
onChange={() => { }}
/>
<div>
{t('setting.email')}
</div>
</div>
<div className='flex gap-1 text-xs items-center text-description'>
<SwitchComponent
active={false}
onChange={() => { }}
/>
<div>
{t('setting.sms')}
</div>
</div>
</div>
</div>
<div className='flex-1 border border-border px-4 rounded-2xl h-14 items-center flex justify-between'>
<div>
{t('setting.notification_announcement')}
</div>
<div className='flex gap-4'>
<div className='flex gap-1 text-xs items-center text-description'>
<SwitchComponent
active={true}
onChange={() => { }}
/>
<div>
{t('setting.email')}
</div>
</div>
<div className='flex gap-1 text-xs items-center text-description'>
<SwitchComponent
active={false}
onChange={() => { }}
/>
<div>
{t('setting.sms')}
</div>
</div>
</div>
</div>
</div>
</div>
:
<div className='mt-10 bg-white p-8 rounded-3xl'>
<div>
{t('setting.change_password')}
</div>
<div className='flex gap-10'>
<div className='flex-1'>
<Input
type='password'
className='mt-6'
placeholder={t('setting.current_password')}
/>
<Input
type='password'
className='mt-6'
placeholder={t('setting.new_password')}
/>
<Input
type='password'
className='mt-6'
placeholder={t('setting.reapeat_password')}
/>
<div className='mt-9'>
<Button
label={t('setting.save_change')}
className='w-32'
/>
</div>
</div>
<div className='flex-1 p-8 bg-[#EEF0F7] rounded-3xl text-sm'>
<div>
{t('setting.password_is')}
</div>
<ul className='list-disc ps-4 flex flex-col gap-2 text-xs mt-4'>
<li>
{t('setting.min-8')}
</li>
<li>
{t('setting.mix_charachter_number')}
</li>
<li>
{t('setting.exsist_number')}
</li>
<li>
{t('setting.exsist_special_character')}
</li>
</ul>
</div>
</div>
</div>
}
</div>
)
}
export default Setting
+3 -3
View File
@@ -96,7 +96,7 @@ const CreateTicket: FC = () => {
</div>
<div className='mt-6'>
<div className='flex items-start gap-2'>
<div className='flex items-start gap-2 border-b pb-5'>
<div>
<TickSquare size={20} color='black' variant='Bold' />
</div>
@@ -104,7 +104,7 @@ const CreateTicket: FC = () => {
سوالات - مشکلاتی که به یک موضوع مربوط میشوند را در یک درخواست پشتیبانی پیگیر باشید و چند درخواست برای یک موضوع باز نکنید.
</div>
</div>
<div className='flex items-start gap-2'>
<div className='flex items-start gap-2 mt-6 border-b pb-5'>
<div>
<TickSquare size={20} color='black' variant='Bold' />
</div>
@@ -112,7 +112,7 @@ const CreateTicket: FC = () => {
لطفاً برای بررسی و رفع مشکلات احتمالی صبور باشید بررسی و رفع مشکلات در برخی موارد زمان گیر است.
</div>
</div>
<div className='flex items-start gap-2'>
<div className='flex items-start gap-2 mt-6'>
<div>
<TickSquare size={20} color='black' variant='Bold' />
</div>
+102 -1
View File
@@ -1,5 +1,7 @@
import { ArrowRight, MoneyRecive, MoneySend } from 'iconsax-react'
import { FC } from 'react'
import { useTranslation } from 'react-i18next'
import Td from '../../components/Td'
const TransactionList: FC = () => {
@@ -8,7 +10,106 @@ const TransactionList: FC = () => {
return (
<div className='mt-4'>
<div>
{t('receip.receip_list')}
{t('transaction.transaction')}
</div>
<div className='mt-6 flex gap-6 justify-center'>
<div className='bg-white rounded-2xl p-6 w-[253px]'>
<div className='flex gap-2 items-center'>
<div className='size-8 bg-[#EEF0F7] rounded-full flex justify-center items-center'>
<MoneySend size={18} color='black' />
</div>
<div className='text-xs text-[#101828]'>
{t('transaction.totao_deposit')}
</div>
</div>
<div className='mt-2 flex gap-2 items-center'>
<div className='text-[#101828] text-xs'>
۱۴۰,۰۰۰,۰۰۰ ریال
</div>
<div className='flex gap gap-0.5 px-2 py-1 bg-green-100 rounded-lg text-[10px] text-success'>
<ArrowRight size={12} color='#00BA4B' className='-rotate-45' />
<div>۳۰٪</div>
</div>
</div>
</div>
<div className='bg-white rounded-2xl p-6 w-[253px]'>
<div className='flex gap-2 items-center'>
<div className='size-8 bg-[#EEF0F7] rounded-full flex justify-center items-center'>
<MoneyRecive size={18} color='black' />
</div>
<div className='text-xs text-[#101828]'>
{t('transaction.total_withdrawal')}
</div>
</div>
<div className='mt-2 flex gap-2 items-center'>
<div className='text-[#101828] text-xs'>
۱۴۰,۰۰۰,۰۰۰ ریال
</div>
<div className='flex gap gap-0.5 px-2 py-1 bg-green-100 rounded-lg text-[10px] text-success'>
<ArrowRight size={12} color='#00BA4B' className='-rotate-45' />
<div>۳۰٪</div>
</div>
</div>
</div>
<div className='bg-white rounded-2xl p-6 w-[253px]'>
<div className='flex gap-2 items-center'>
<div className='size-8 bg-[#EEF0F7] rounded-full flex justify-center items-center'>
<MoneyRecive size={18} color='black' />
</div>
<div className='text-xs text-[#101828]'>
{t('transaction.balance')}
</div>
</div>
<div className='mt-2 flex gap-2 items-center'>
<div className='text-[#101828] text-xs'>
۱۴۰,۰۰۰,۰۰۰ ریال
</div>
<div className='flex gap gap-0.5 px-2 py-1 text-red-400 rounded-lg text-[10px] bg-red-100'>
<ArrowRight size={12} color='red' className='rotate-45' />
<div>۳۰٪</div>
</div>
</div>
</div>
</div>
<div className='relative overflow-x-auto rounded-3xl mt-9 w-full'>
<table className='w-full text-sm '>
<thead className='thead'>
<tr>
<Td text={t('ticket.number')} />
<Td text={t('ticket.title')} />
<Td text={t('ticket.team')} />
<Td text={t('ticket.date')} />
<Td text={t('ticket.status')} />
<Td text={t('ticket.priority')} />
<Td text={t('ticket.detail')} />
<Td text={''} />
</tr>
</thead>
<tbody>
<tr className='tr'>
<Td text={t('ticket.number')} />
<Td text={t('ticket.title')} />
<Td text={t('ticket.team')} />
<Td text={t('ticket.date')} />
<Td text={t('ticket.status')} />
<Td text={t('ticket.priority')} />
<Td text={t('ticket.detail')} />
<Td text={''} />
</tr>
<tr className='tr'>
<Td text={t('ticket.number')} />
<Td text={t('ticket.title')} />
<Td text={t('ticket.team')} />
<Td text={t('ticket.date')} />
<Td text={t('ticket.status')} />
<Td text={t('ticket.priority')} />
<Td text={t('ticket.detail')} />
<Td text={''} />
</tr>
</tbody>
</table>
</div>
</div>
+93
View File
@@ -0,0 +1,93 @@
import { Cards, Money3, MoneyRecive, TickSquare } from 'iconsax-react'
import { FC, useState } from 'react'
import { useTranslation } from 'react-i18next'
import { SIDEBAR_SIZE_LEFT } from '../../config/Const'
import Tabs from '../../components/Tabs'
import Online from './components/Online'
import CardtoCard from './components/CardtoCard'
import Sheba from './components/Sheba'
const Wallet: FC = () => {
const { t } = useTranslation('global')
const [activeTab, setActiveTab] = useState<string>('online')
return (
<div className='mt-4'>
<div>
{t('wallet.increese_wallet')}
</div>
<div className='mt-8 flex gap-6'>
<div className='flex-1'>
<Tabs
active={activeTab}
items={[
{
label: t('wallet.online_pay'),
value: 'online',
icon: <MoneyRecive color={activeTab === 'online' ? 'black' : '#8C90A3'} size={22} />
},
{
icon: <Cards color={activeTab === 'card' ? 'black' : '#8C90A3'} size={22} />,
label: t('wallet.card_to_card'),
value: 'card'
},
{
icon: <Money3 color={activeTab === 'sheba' ? 'black' : '#8C90A3'} size={22} />,
label: t('wallet.sheba'),
value: 'sheba'
},
]}
onChange={setActiveTab}
/>
{
activeTab === 'online' ?
<Online />
: activeTab === 'card' ?
<CardtoCard />
: <Sheba />
}
</div>
<div style={{ width: SIDEBAR_SIZE_LEFT }} className='bg-white py-10 px-5 h-fit rounded-3xl'>
<div className='text-sm'>
{t('ticket.title_hint')}
</div>
<div className='mt-6'>
<div className='flex items-start gap-2 border-b pb-5'>
<div>
<TickSquare size={20} color='black' variant='Bold' />
</div>
<div className='text-description text-xs leading-5'>
سوالات - مشکلاتی که به یک موضوع مربوط میشوند را در یک درخواست پشتیبانی پیگیر باشید و چند درخواست برای یک موضوع باز نکنید.
</div>
</div>
<div className='flex items-start gap-2 mt-6 border-b pb-5'>
<div>
<TickSquare size={20} color='black' variant='Bold' />
</div>
<div className='text-description text-xs leading-5'>
لطفاً برای بررسی و رفع مشکلات احتمالی صبور باشید بررسی و رفع مشکلات در برخی موارد زمان گیر است.
</div>
</div>
<div className='flex items-start gap-2 mt-6'>
<div>
<TickSquare size={20} color='black' variant='Bold' />
</div>
<div className='text-description text-xs leading-5'>
پاسخگویی 24 ساعته تلفنی را تنها از میهن وب هاست می توانید انتظار داشته باشید .بخش پشتیبانی در هر ساعتی حتی در روز های تعطیل آماده پیگیری سریع مشکلات کاربران است.
</div>
</div>
</div>
</div>
</div>
</div>
)
}
export default Wallet
@@ -0,0 +1,41 @@
import { FC } from 'react'
import { useTranslation } from 'react-i18next'
import Input from '../../../components/Input'
import UploadBox from '../../../components/UploadBox'
import Button from '../../../components/Button'
const CardtoCard: FC = () => {
const { t } = useTranslation('global')
return (
<div className='mt-8 bg-white p-8 rounded-3xl'>
<div>
{t('wallet.card_to_card')}
</div>
<div className='mt-8'>
<Input
label={t('wallet.amount')}
placeholder={t('wallet.enter_amount_card')}
/>
</div>
<div className='mt-8'>
<UploadBox
label={t('wallet.upload_deposit_slip')}
/>
</div>
<div className='mt-10 flex justify-end'>
<Button
label={t('wallet.submit_slip')}
className='w-[180px]'
/>
</div>
</div>
)
}
export default CardtoCard
+111
View File
@@ -0,0 +1,111 @@
import { FC, useState } from 'react'
import Button from '../../../components/Button'
import { useTranslation } from 'react-i18next'
import { clx } from '../../../helpers/utils'
import SamanImage from '../../../assets/images/saman.png'
import Input from '../../../components/Input'
const Online: FC = () => {
const { t } = useTranslation('global')
const [priceSelect, setPriceSelect] = useState<number>(1)
const [bankSelected, setBankSelected] = useState<number>(1)
return (
<div className='mt-8 bg-white p-8 rounded-3xl'>
<div>
{t('wallet.online_pay')}
</div>
<div className='mt-8 text-sm'>
{t('wallet.select_price')}
</div>
<div className='mt-4 flex gap-4 flex-wrap'>
<div onClick={() => setPriceSelect(1)} className={clx(
'bg-[#EBEDF5] border border-[#EBEDF5] cursor-pointer flex items-center text-xs h-10 px-6 rounded-lg',
priceSelect === 1 && 'border-black'
)}>
۱۰,۰۰۰,۰۰۰ تومان
</div>
<div onClick={() => setPriceSelect(2)} className={clx(
'bg-[#EBEDF5] border border-[#EBEDF5] cursor-pointer flex items-center text-xs h-10 px-6 rounded-lg',
priceSelect === 2 && 'border-black'
)}>
۱۰,۰۰۰,۰۰۰ تومان
</div>
<div onClick={() => setPriceSelect(3)} className={clx(
'bg-[#EBEDF5] border border-[#EBEDF5] cursor-pointer flex items-center text-xs h-10 px-6 rounded-lg',
priceSelect === 3 && 'border-black'
)}>
۱۰,۰۰۰,۰۰۰ تومان
</div>
<div onClick={() => setPriceSelect(4)} className={clx(
'bg-[#EBEDF5] border border-[#EBEDF5] cursor-pointer flex items-center text-xs h-10 px-6 rounded-lg',
priceSelect === 4 && 'border-black'
)}>
۱۰,۰۰۰,۰۰۰ تومان
</div>
<div onClick={() => setPriceSelect(5)} className={clx(
'bg-[#EBEDF5] border border-[#EBEDF5] cursor-pointer flex items-center text-xs h-10 px-6 rounded-lg',
priceSelect === 5 && 'border-black'
)}>
۱۰,۰۰۰,۰۰۰ تومان
</div>
</div>
<div className='mt-9'>
<Input
label={t('wallet.optional_price')}
placeholder={t('wallet.enter_your_price')}
/>
</div>
<div className='mt-8 text-sm'>
<div>
{t('wallet.select_payment')}
</div>
<div className='mt-6 flex gap-4'>
<div onClick={() => setBankSelected(1)} className={clx(
'h-16 rounded-xl cursor-pointer flex gap-4 items-center px-4 border border-border w-[240px]',
bankSelected === 1 && 'border-black'
)}>
<img src={SamanImage} className='w-10' />
<div>
<div>
بانک پارسیان
</div>
<div className='text-xs mt-1 text-description'>
تمام کارت های عضو شتاب
</div>
</div>
</div>
<div onClick={() => setBankSelected(2)} className={clx(
'h-16 rounded-xl cursor-pointer flex gap-4 items-center px-4 border border-border w-[240px]',
bankSelected === 2 && 'border-black'
)}>
<img src={SamanImage} className='w-10' />
<div>
<div>
بانک پارسیان
</div>
<div className='text-xs mt-1 text-description'>
تمام کارت های عضو شتاب
</div>
</div>
</div>
</div>
<div className='mt-10 flex justify-end'>
<Button
label={t('wallet.pay')}
className='w-[180px]'
/>
</div>
</div>
</div>
)
}
export default Online
+41
View File
@@ -0,0 +1,41 @@
import { FC } from 'react'
import { useTranslation } from 'react-i18next'
import Input from '../../../components/Input'
import UploadBox from '../../../components/UploadBox'
import Button from '../../../components/Button'
const Sheba: FC = () => {
const { t } = useTranslation('global')
return (
<div className='mt-8 bg-white p-8 rounded-3xl'>
<div>
{t('wallet.pay_sheba')}
</div>
<div className='mt-8'>
<Input
label={t('wallet.amount')}
placeholder={t('wallet.enter_sheba_deposit')}
/>
</div>
<div className='mt-8'>
<UploadBox
label={t('wallet.upload_deposit_slip')}
/>
</div>
<div className='mt-10 flex justify-end'>
<Button
label={t('wallet.submit_slip')}
className='w-[180px]'
/>
</div>
</div>
)
}
export default Sheba
+10
View File
@@ -10,6 +10,11 @@ import CreateTicket from '../pages/ticket/CreateTicket'
import TicketDetail from '../pages/ticket/Detail'
import TransactionList from '../pages/transaction/List'
import ReceiptsList from '../pages/receipts/List'
import AnnouncementtList from '../pages/annoncement/List'
import AddCriticisms from '../pages/criticisms/Add'
import LearningList from '../pages/learning/List'
import Setting from '../pages/setting/Setting'
import Wallet from '../pages/wallet/Wallet'
const MainRouter: FC = () => {
return (
@@ -26,6 +31,11 @@ const MainRouter: FC = () => {
<Route path={Pages.ticket.detail + ':id'} element={<TicketDetail />} />
<Route path={Pages.transactions} element={<TransactionList />} />
<Route path={Pages.receipts} element={<ReceiptsList />} />
<Route path={Pages.announcement} element={<AnnouncementtList />} />
<Route path={Pages.criticisms} element={<AddCriticisms />} />
<Route path={Pages.learning} element={<LearningList />} />
<Route path={Pages.setting} element={<Setting />} />
<Route path={Pages.wallet} element={<Wallet />} />
</Routes>
</div>
</div>
+5 -1
View File
@@ -3,6 +3,8 @@ import Input from '../components/Input'
import { ArrowDown2, Element3, Notification, Wallet } from 'iconsax-react'
import AvatarImage from '../assets/images/Avatar.png'
import { useTranslation } from 'react-i18next'
import { Link } from 'react-router-dom'
import { Pages } from '../config/Pages'
const Header: FC = () => {
@@ -19,7 +21,9 @@ const Header: FC = () => {
</div>
<div className='flex gap-6 items-center'>
<Element3 size={18} color='black' />
<Wallet size={18} color='black' />
<Link to={Pages.wallet}>
<Wallet size={18} color='black' />
</Link>
<Notification size={18} color='black' />
<div className='flex gap-2 items-center'>
<div className='size-7 rounded-full bg-description overflow-hidden'>