From d1f16746eac93edb0b527e9cd0969f0a671146e0 Mon Sep 17 00:00:00 2001 From: hamid zarghami Date: Mon, 20 Jan 2025 15:37:16 +0330 Subject: [PATCH 1/3] sidebar --- src/config/SideBarSubMenu.ts | 7 ++ src/langs/fa.json | 3 + src/router/Main.tsx | 14 +++- src/shared/Header.tsx | 8 ++- src/shared/SideBar.tsx | 70 +++++++++++++++++-- src/shared/SideBarItem.tsx | 23 +++++- src/shared/components/ServicesSubMenu.tsx | 41 +++++++++++ src/shared/components/SubMenuItem.tsx | 33 +++++++++ src/shared/components/TransactionsSubMenu.tsx | 38 ++++++++++ src/shared/store/sharedStore.ts | 4 ++ src/shared/types/SharedTypes.ts | 4 ++ 11 files changed, 231 insertions(+), 14 deletions(-) create mode 100644 src/config/SideBarSubMenu.ts create mode 100644 src/shared/components/ServicesSubMenu.tsx create mode 100644 src/shared/components/SubMenuItem.tsx create mode 100644 src/shared/components/TransactionsSubMenu.tsx diff --git a/src/config/SideBarSubMenu.ts b/src/config/SideBarSubMenu.ts new file mode 100644 index 0000000..3084413 --- /dev/null +++ b/src/config/SideBarSubMenu.ts @@ -0,0 +1,7 @@ +export const SideBarItemHasSubMenu = [ + "services", + "customers", + "receipt", + "users", + "transactions", +]; diff --git a/src/langs/fa.json b/src/langs/fa.json index 3dcf200..dff8bfb 100644 --- a/src/langs/fa.json +++ b/src/langs/fa.json @@ -68,6 +68,9 @@ "setting": "تنظیمات", "logout": "خروج" }, + "submenu": { + "services_list": "لیست سرویس ها" + }, "header": { "search": "جستجو" }, diff --git a/src/router/Main.tsx b/src/router/Main.tsx index 2685135..e31375a 100644 --- a/src/router/Main.tsx +++ b/src/router/Main.tsx @@ -21,14 +21,24 @@ import OtherServices from '../pages/service/OtherServices' import Footer from '../shared/Footer' import AnnouncementDetail from '../pages/annoncement/Detail' import DetailService from '../pages/service/DetailService' +import { clx } from '../helpers/utils' +import { useSharedStore } from '../shared/store/sharedStore' const MainRouter: FC = () => { + + const { hasSubMenu } = useSharedStore() + return (
-
-
+
+
} /> diff --git a/src/shared/Header.tsx b/src/shared/Header.tsx index e7e73fe..5617e7c 100644 --- a/src/shared/Header.tsx +++ b/src/shared/Header.tsx @@ -7,14 +7,18 @@ import { Link } from 'react-router-dom' import { Pages } from '../config/Pages' import Notifications from '../pages/notification/Notification' import { useSharedStore } from './store/sharedStore' +import { clx } from '../helpers/utils' const Header: FC = () => { const { t } = useTranslation('global') - const { setOpenSidebar, openSidebar } = useSharedStore() + const { setOpenSidebar, openSidebar, hasSubMenu } = useSharedStore() return ( -
+
{ const { t } = useTranslation('global') - const { openSidebar, setOpenSidebar } = useSharedStore() + const { openSidebar, setOpenSidebar, hasSubMenu, setSubMenuName, setSubtMenu, subMenuName } = useSharedStore() const location = useLocation() const isActive = (name: string) => { return location.pathname.includes(name) } + useEffect(() => { + + const split = location.pathname.split('/') + console.log('split', split); + + + if (SideBarItemHasSubMenu.includes(split[1])) { + setSubMenuName(split[1]) + setSubtMenu(true) + } else { + setSubMenuName('') + setSubtMenu(false) + } + + + // eslint-disable-next-line react-hooks/exhaustive-deps + }, [location.pathname]) + + const iconSizeSideBar = 20 + console.log(openSidebar); + + return ( <> { @@ -28,15 +54,24 @@ const SideBar: FC = () => {
- + { + !hasSubMenu ? + + : + + }
-
+
{t('sidebar.menu')}
@@ -52,6 +87,7 @@ const SideBar: FC = () => { title={t('sidebar.services')} isActive={isActive('services')} link={Pages.services.mine} + name='services' /> } @@ -105,7 +141,10 @@ const SideBar: FC = () => { />
-
+
{t('sidebar.other')}
@@ -129,7 +168,10 @@ const SideBar: FC = () => {
-
+
{t('sidebar.mnage_content')}
@@ -200,6 +242,20 @@ const SideBar: FC = () => {
+ + { + hasSubMenu && (openSidebar || window.innerWidth > 1000) && +
+ { + subMenuName === 'services' ? + + : + subMenuName === 'transactions' ? + + : null + } +
+ } ) } diff --git a/src/shared/SideBarItem.tsx b/src/shared/SideBarItem.tsx index 271c00e..fd22bce 100644 --- a/src/shared/SideBarItem.tsx +++ b/src/shared/SideBarItem.tsx @@ -2,6 +2,7 @@ import { FC, ReactNode } from 'react' import { Link } from 'react-router-dom' import { clx } from '../helpers/utils' import { Pages } from '../config/Pages' +import { useSharedStore } from './store/sharedStore' type Props = { icon: ReactNode, @@ -9,22 +10,38 @@ type Props = { isActive: boolean, link: string, isLogout?: boolean, + name?: string } const SideBarItem: FC = (props: Props) => { + const { hasSubMenu, setSubMenuName, setSubtMenu } = useSharedStore() const handleLogout = () => { localStorage.removeItem(import.meta.env.VITE_TOKEN_NAME) window.location.href = Pages.auth.login } + const handleClick = () => { + if (props.name) { + setSubMenuName(props.name) + setSubtMenu(true) + } + } + return ( - +
-
+
{props.icon}
{props.title} diff --git a/src/shared/components/ServicesSubMenu.tsx b/src/shared/components/ServicesSubMenu.tsx new file mode 100644 index 0000000..70a999c --- /dev/null +++ b/src/shared/components/ServicesSubMenu.tsx @@ -0,0 +1,41 @@ +import { Element3 } from 'iconsax-react' +import { FC } from 'react' +import { useTranslation } from 'react-i18next' +import SubMenuItem from './SubMenuItem' +import { useLocation } from 'react-router-dom' + +const ServicesSubMenu: FC = () => { + + const location = useLocation() + const { t } = useTranslation('global') + + + const isActive = (name: string) => { + return location.pathname.includes(name) + } + + return ( +
+
+ +
+ {t('sidebar.services')} +
+
+ +
+ +
+
+ ) +} + +export default ServicesSubMenu \ No newline at end of file diff --git a/src/shared/components/SubMenuItem.tsx b/src/shared/components/SubMenuItem.tsx new file mode 100644 index 0000000..3a81f45 --- /dev/null +++ b/src/shared/components/SubMenuItem.tsx @@ -0,0 +1,33 @@ +import { FC } from 'react' +import { Link } from 'react-router-dom' +import { clx } from '../../helpers/utils' + +type Props = { + title: string, + isActive: boolean, + link: string, + isLogout?: boolean, +} + +const SubMenuItem: FC = (props: Props) => { + return ( + +
+
+
+ {props.title} +
+
+ + + ) +} + +export default SubMenuItem \ No newline at end of file diff --git a/src/shared/components/TransactionsSubMenu.tsx b/src/shared/components/TransactionsSubMenu.tsx new file mode 100644 index 0000000..20e3f23 --- /dev/null +++ b/src/shared/components/TransactionsSubMenu.tsx @@ -0,0 +1,38 @@ +import { Card } from 'iconsax-react' +import { FC } from 'react' +import { useTranslation } from 'react-i18next' +import SubMenuItem from './SubMenuItem' + +const TransactionsSubMenu: FC = () => { + + const { t } = useTranslation('global') + + const isActive = (name: string) => { + return location.pathname.includes(name) + } + + return ( +
+
+ +
+ {t('sidebar.transactions')} +
+
+ +
+ +
+
+ ) +} + +export default TransactionsSubMenu \ No newline at end of file diff --git a/src/shared/store/sharedStore.ts b/src/shared/store/sharedStore.ts index 731c65a..d5c810c 100644 --- a/src/shared/store/sharedStore.ts +++ b/src/shared/store/sharedStore.ts @@ -4,4 +4,8 @@ import { SharedStoreType } from "../types/SharedTypes"; export const useSharedStore = create((set) => ({ openSidebar: false, setOpenSidebar: (value) => set({ openSidebar: value }), + hasSubMenu: false, + setSubtMenu: (value: boolean) => set({ hasSubMenu: value }), + subMenuName: "", + setSubMenuName: (value: string) => set({ subMenuName: value }), })); diff --git a/src/shared/types/SharedTypes.ts b/src/shared/types/SharedTypes.ts index b681e51..1b7e445 100644 --- a/src/shared/types/SharedTypes.ts +++ b/src/shared/types/SharedTypes.ts @@ -1,4 +1,8 @@ export type SharedStoreType = { openSidebar: boolean; setOpenSidebar: (value: boolean) => void; + hasSubMenu: boolean; + setSubtMenu: (value: boolean) => void; + subMenuName: string; + setSubMenuName: (value: string) => void; }; From 88245257e420d6297833010241a9adab3e1da99c Mon Sep 17 00:00:00 2001 From: hamid zarghami Date: Mon, 20 Jan 2025 16:30:36 +0330 Subject: [PATCH 2/3] transger dsc to admin --- src/components/Select.tsx | 4 +- src/pages/annoncement/Detail.tsx | 4 +- src/pages/home/components/DanakLearning.tsx | 6 +- src/pages/service/MyServices.tsx | 74 ++++++++++----------- src/pages/setting/Setting.tsx | 72 ++++++++++---------- src/shared/Header.tsx | 16 ++--- 6 files changed, 86 insertions(+), 90 deletions(-) diff --git a/src/components/Select.tsx b/src/components/Select.tsx index 4d0a614..7a03b4c 100644 --- a/src/components/Select.tsx +++ b/src/components/Select.tsx @@ -1,5 +1,6 @@ import { FC, SelectHTMLAttributes } from 'react' import { clx } from '../helpers/utils' +import { ArrowDown2 } from 'iconsax-react' export type ItemsSelectType = { value: string, @@ -23,7 +24,7 @@ const Select: FC = (props: Props) => { } + { props.error_text && props.error_text !== '' ?
diff --git a/src/pages/annoncement/Detail.tsx b/src/pages/annoncement/Detail.tsx index 1c32e7b..60ea2e4 100644 --- a/src/pages/annoncement/Detail.tsx +++ b/src/pages/annoncement/Detail.tsx @@ -2,6 +2,7 @@ import { FC } from 'react' import { useTranslation } from 'react-i18next' import StatusWithText from '../../components/StatusWithText' import { useNavigate } from 'react-router-dom' +import { ArrowLeft2 } from 'iconsax-react' const AnnouncementDetail: FC = () => { @@ -14,8 +15,9 @@ const AnnouncementDetail: FC = () => {
{t('announcement.text_announcement')}
-
navigate(-1)} className='text-xs font-extralight'> +
navigate(-1)} className='text-xs flex gap-0.5 items-center font-extralight'> {t('back')} +
diff --git a/src/pages/home/components/DanakLearning.tsx b/src/pages/home/components/DanakLearning.tsx index 580f1b2..e87affa 100644 --- a/src/pages/home/components/DanakLearning.tsx +++ b/src/pages/home/components/DanakLearning.tsx @@ -26,14 +26,14 @@ const DanakLearning: FC = () => {
-
+
لورم ایپسوم متن ساختگی با تولید سادگی
-
+
دیزاین ,
۲۴ دقیقه
-
+
آذر ماه 1403
diff --git a/src/pages/service/MyServices.tsx b/src/pages/service/MyServices.tsx index 4313184..340330c 100644 --- a/src/pages/service/MyServices.tsx +++ b/src/pages/service/MyServices.tsx @@ -41,53 +41,49 @@ const MyServices: FC = () => {
- -
- + +
+ -
- -
1 {t('service.active_menu')}
-
+
1 {t('service.active_menu')}
+
+ + + + +
+ +
1 {t('service.active_menu')}
- -
- + +
+ -
- -
1 {t('service.active_menu')}
-
+
1 {t('service.active_menu')}
- -
- + +
+ -
- -
1 {t('service.active_menu')}
-
-
- - -
- -
- -
1 {t('service.active_menu')}
-
+
1 {t('service.active_menu')}
+
diff --git a/src/pages/setting/Setting.tsx b/src/pages/setting/Setting.tsx index 990f707..3f0c88f 100644 --- a/src/pages/setting/Setting.tsx +++ b/src/pages/setting/Setting.tsx @@ -45,104 +45,104 @@ const Setting: FC = () => {
-
+
{t('setting.notification_announcement')}
-
+
+
+ {t('setting.email')} +
{ }} /> -
- {t('setting.email')} -
-
+
+
+ {t('setting.sms')} +
{ }} /> -
- {t('setting.sms')} -
-
+
{t('setting.notification_announcement')}
-
+
+
+ {t('setting.email')} +
{ }} /> -
- {t('setting.email')} -
-
+
+
+ {t('setting.sms')} +
{ }} /> -
- {t('setting.sms')} -
-
+
{t('setting.notification_announcement')}
-
+
+
+ {t('setting.email')} +
{ }} /> -
- {t('setting.email')} -
-
+
+
+ {t('setting.sms')} +
{ }} /> -
- {t('setting.sms')} -
-
+
{t('setting.notification_announcement')}
-
+
+
+ {t('setting.email')} +
{ }} /> -
- {t('setting.email')} -
-
+
+
+ {t('setting.sms')} +
{ }} /> -
- {t('setting.sms')} -
diff --git a/src/shared/Header.tsx b/src/shared/Header.tsx index 5617e7c..78848b1 100644 --- a/src/shared/Header.tsx +++ b/src/shared/Header.tsx @@ -7,18 +7,14 @@ import { Link } from 'react-router-dom' import { Pages } from '../config/Pages' import Notifications from '../pages/notification/Notification' import { useSharedStore } from './store/sharedStore' -import { clx } from '../helpers/utils' const Header: FC = () => { const { t } = useTranslation('global') - const { setOpenSidebar, openSidebar, hasSubMenu } = useSharedStore() + const { setOpenSidebar, openSidebar } = useSharedStore() return ( -
+
{
{/* */} -
- +
+ - +
-
+
From 73a385a031ebc07931ef5f034c6f5041bad8e3a5 Mon Sep 17 00:00:00 2001 From: hamid zarghami Date: Tue, 21 Jan 2025 11:42:34 +0330 Subject: [PATCH 3/3] add receipt --- src/components/Select.tsx | 5 +- src/config/Pages.ts | 5 +- src/config/SideBarSubMenu.ts | 2 +- src/langs/fa.json | 16 +- src/pages/receipts/Create.tsx | 224 +++++++++++++++++++++++ src/router/Main.tsx | 2 + src/shared/Header.tsx | 2 +- src/shared/SideBar.tsx | 7 +- src/shared/components/ReceiptSubMenu.tsx | 46 +++++ src/shared/components/SubMenuItem.tsx | 4 +- 10 files changed, 302 insertions(+), 11 deletions(-) create mode 100644 src/pages/receipts/Create.tsx create mode 100644 src/shared/components/ReceiptSubMenu.tsx diff --git a/src/components/Select.tsx b/src/components/Select.tsx index 7a03b4c..d42a569 100644 --- a/src/components/Select.tsx +++ b/src/components/Select.tsx @@ -42,7 +42,10 @@ const Select: FC = (props: Props) => { }) } - + { props.error_text && props.error_text !== '' ?
diff --git a/src/config/Pages.ts b/src/config/Pages.ts index de2c9be..debb072 100644 --- a/src/config/Pages.ts +++ b/src/config/Pages.ts @@ -12,8 +12,9 @@ export const Pages = { }, transactions: "/transactions", receipts: { - index: "/receipts", - detail: "/receipts/", + index: "/receipts/list", + detail: "/receipts/detail/", + create: "/receipts/create", }, ticket: { list: "/tickets", diff --git a/src/config/SideBarSubMenu.ts b/src/config/SideBarSubMenu.ts index 3084413..8f4557a 100644 --- a/src/config/SideBarSubMenu.ts +++ b/src/config/SideBarSubMenu.ts @@ -1,7 +1,7 @@ export const SideBarItemHasSubMenu = [ "services", "customers", - "receipt", + "receipts", "users", "transactions", ]; diff --git a/src/langs/fa.json b/src/langs/fa.json index dff8bfb..db70e0b 100644 --- a/src/langs/fa.json +++ b/src/langs/fa.json @@ -162,7 +162,9 @@ "update_sms": "به روزرسانی این تیکت از طریق پیامک اطلاع داده میشود" }, "receip": { + "receips": "صورتحساب ها", "receip_list": "لیست صورتحساب ها", + "add_receip": "افزودن صورتحساب", "dont_pay": "پرداخت نشده", "dont_confrim": "تایید نشده", "paid": "پرداخت شده", @@ -191,7 +193,19 @@ "date_factor": "تاریخ صدور فاکتور", "due_date": "تاریخ سررسید فاکتور", "factor_number": "شماره فاکتور", - "status_factor": "وضعیت فاکتور" + "status_factor": "وضعیت فاکتور", + "submit_receip": "ثبت صورتحساب", + "customer_information": "اطلاعات مشتری", + "customer": "مشتری", + "receipt_information": "اطلاعات صورتحساب", + "number": "شماره", + "product_name": "نام کالا", + "count": "تعداد", + "unit_amount": "مبلغ واحد", + "discount": "تخفیف(٪)", + "total_amount": "مبلغ کل(ریال)", + "tax": "مالیات بر ارزش افزوده (۰.۹ درصد)", + "total": "جمع" }, "edit": "ویرایش", "transaction": { diff --git a/src/pages/receipts/Create.tsx b/src/pages/receipts/Create.tsx new file mode 100644 index 0000000..d3cb775 --- /dev/null +++ b/src/pages/receipts/Create.tsx @@ -0,0 +1,224 @@ +import { FC } from 'react' +import { useTranslation } from 'react-i18next' +import Button from '../../components/Button' +import { Add, TickCircle, TickSquare } from 'iconsax-react' +import Select from '../../components/Select' +import Input from '../../components/Input' + +const CreateReceipt: FC = () => { + + const { t } = useTranslation('global') + + return ( +
+
+
+ {t('receip.add_receip')} +
+
+ +
+
+ +
+
+
+ {t('receip.customer_information')} +
+ +
+
+ +
+ +
+
+ {t('receip.count')} +
+ +
+ +
+
+ {t('receip.unit_amount')} +
+ +
+ +
+
+ {t('receip.discount')} +
+ +
+ +
+
+ {t('receip.total_amount')} +
+ +
+ +
+ +
+
+ +
+
+
+ {t('receip.tax')} +
+
+ 100,000 +
+
+
+
+ {t('receip.total')} +
+
+ 100,000 +
+
+
+ +
+ +
+
+ {t('ticket.title_hint')} +
+ +
+
+
+ +
+
+ سوالات - مشکلاتی که به یک موضوع مربوط میشوند را در یک درخواست پشتیبانی پیگیر باشید و چند درخواست برای یک موضوع باز نکنید. +
+
+
+
+ +
+
+ لطفاً برای بررسی و رفع مشکلات احتمالی صبور باشید بررسی و رفع مشکلات در برخی موارد زمان گیر است. +
+
+
+
+ +
+
+ پاسخگویی 24 ساعته تلفنی را تنها از میهن وب هاست می توانید انتظار داشته باشید .بخش پشتیبانی در هر ساعتی حتی در روز های تعطیل آماده پیگیری سریع مشکلات کاربران است. +
+
+
+
+
+
+ ) +} + +export default CreateReceipt \ No newline at end of file diff --git a/src/router/Main.tsx b/src/router/Main.tsx index e31375a..6a2c2dc 100644 --- a/src/router/Main.tsx +++ b/src/router/Main.tsx @@ -23,6 +23,7 @@ import AnnouncementDetail from '../pages/annoncement/Detail' import DetailService from '../pages/service/DetailService' import { clx } from '../helpers/utils' import { useSharedStore } from '../shared/store/sharedStore' +import CreateReceipt from '../pages/receipts/Create' const MainRouter: FC = () => { @@ -51,6 +52,7 @@ const MainRouter: FC = () => { } /> } /> } /> + } /> } /> } /> } /> diff --git a/src/shared/Header.tsx b/src/shared/Header.tsx index 78848b1..e1e404c 100644 --- a/src/shared/Header.tsx +++ b/src/shared/Header.tsx @@ -14,7 +14,7 @@ const Header: FC = () => { const { setOpenSidebar, openSidebar } = useSharedStore() return ( -
+
{ @@ -43,8 +44,6 @@ const SideBar: FC = () => { const iconSizeSideBar = 20 - console.log(openSidebar); - return ( <> @@ -252,7 +251,9 @@ const SideBar: FC = () => { : subMenuName === 'transactions' ? - : null + : subMenuName === 'receipts' ? + + : null }
} diff --git a/src/shared/components/ReceiptSubMenu.tsx b/src/shared/components/ReceiptSubMenu.tsx new file mode 100644 index 0000000..d86c205 --- /dev/null +++ b/src/shared/components/ReceiptSubMenu.tsx @@ -0,0 +1,46 @@ +import { Receipt21 } from 'iconsax-react' +import { FC } from 'react' +import { useTranslation } from 'react-i18next' +import SubMenuItem from './SubMenuItem' +import { useLocation } from 'react-router-dom' +import { Pages } from '../../config/Pages' + +const ReceiptSubMenu: FC = () => { + + const location = useLocation() + const { t } = useTranslation('global') + + const isActive = (name: string) => { + return location.pathname.includes(name) + } + + return ( +
+
+ +
+ {t('receip.receips')} +
+
+ +
+ + +
+
+ ) +} + +export default ReceiptSubMenu \ No newline at end of file diff --git a/src/shared/components/SubMenuItem.tsx b/src/shared/components/SubMenuItem.tsx index 3a81f45..59451f4 100644 --- a/src/shared/components/SubMenuItem.tsx +++ b/src/shared/components/SubMenuItem.tsx @@ -12,14 +12,14 @@ type Props = { const SubMenuItem: FC = (props: Props) => { return (
{props.title}