From 0cf98ee67c176d3d829e8cc7d7174785a8127fcb Mon Sep 17 00:00:00 2001 From: hamid zarghami Date: Sat, 12 Jul 2025 10:09:11 +0330 Subject: [PATCH] show storage --- src/App.tsx | 2 + src/components/DefaulModal.tsx | 57 +++++++++++++++++++ src/components/HeaderModal.tsx | 21 +++++++ src/components/ProgressBar.tsx | 17 ++++++ src/index.css | 20 +++++++ src/langs/fa.json | 7 ++- .../address/components/ProgressBarEmail.tsx | 11 +--- .../setting/domain/hooks/useDomainData.ts | 7 +++ .../setting/domain/service/DomainService.ts | 5 ++ src/shared/Main.tsx | 11 +--- src/shared/SideBar.tsx | 2 + src/shared/components/BuySpace.tsx | 26 +++++++++ src/shared/components/Storage.tsx | 52 +++++++++++++++++ src/shared/store/sharedStore.ts | 2 + src/shared/types/SharedTypes.ts | 2 + 15 files changed, 223 insertions(+), 19 deletions(-) create mode 100644 src/components/DefaulModal.tsx create mode 100644 src/components/HeaderModal.tsx create mode 100644 src/components/ProgressBar.tsx create mode 100644 src/shared/components/BuySpace.tsx create mode 100644 src/shared/components/Storage.tsx diff --git a/src/App.tsx b/src/App.tsx index 195e5f0..323d264 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -13,6 +13,7 @@ import { IApiErrorRepsonse } from './types/error.types'; import ToastContainer from './components/Toast'; import { getRefreshToken, removeRefreshToken, removeToken, setRefreshToken, setToken } from './config/func'; import { refreshToken } from './pages/auth/service/Service'; +import BuySpace from './shared/components/BuySpace' declare global { interface Window { @@ -102,6 +103,7 @@ const App: FC = () => {
+ diff --git a/src/components/DefaulModal.tsx b/src/components/DefaulModal.tsx new file mode 100644 index 0000000..bc298d1 --- /dev/null +++ b/src/components/DefaulModal.tsx @@ -0,0 +1,57 @@ +import { FC, Fragment, ReactNode, useEffect } from 'react' +import HeaderModal from './HeaderModal' + +interface Props { + open: boolean, + close: () => void, + children: ReactNode, + isHeader?: boolean, + title_header?: string, + width?: number +} + +const DefaulModal: FC = (props: Props) => { + + useEffect(() => { + if (props.open) { + document.body.style.overflow = 'hidden' + } else { + document.body.style.overflow = 'auto' + } + }, [props.open]) + + + return ( + + { + props.open && ( + +
+
+
+ + + { + props.isHeader && props.title_header && +
+
+ +
+ } + + {props.children} + + +
+
+
+ +
+
+ ) + } +
+ ) +} + +export default DefaulModal \ No newline at end of file diff --git a/src/components/HeaderModal.tsx b/src/components/HeaderModal.tsx new file mode 100644 index 0000000..955020f --- /dev/null +++ b/src/components/HeaderModal.tsx @@ -0,0 +1,21 @@ +import { CloseCircle } from 'iconsax-react' +import { FC } from 'react' + + +type Props = { + label: string, + close: () => void, +} + +const HeaderModal: FC = (props: Props) => { + return ( +
+
{props.label}
+
+ +
+
+ ) +} + +export default HeaderModal \ No newline at end of file diff --git a/src/components/ProgressBar.tsx b/src/components/ProgressBar.tsx new file mode 100644 index 0000000..2657b0c --- /dev/null +++ b/src/components/ProgressBar.tsx @@ -0,0 +1,17 @@ +import { FC } from 'react' + +const ProgressBar: FC<{ percentage: number }> = ({ percentage }) => { + return ( +
+
90 ? 'bg-red-500' : + percentage > 70 ? 'bg-yellow-500' : + 'bg-green-500' + }`} + style={{ width: `${percentage}%` }} + >
+
+ ) +} + +export default ProgressBar \ No newline at end of file diff --git a/src/index.css b/src/index.css index 512fd2a..2bf995b 100644 --- a/src/index.css +++ b/src/index.css @@ -247,3 +247,23 @@ textarea::placeholder { .ql-snow .ql-picker:not(.ql-color-picker):not(.ql-icon-picker) svg { display: none; } + +.modalGlass { + background: rgba(0, 0, 0, 0.436); + background-blend-mode: multiply; + + backdrop-filter: blur(7px); +} +.modalGlass2 { + background: rgba(255, 255, 255, 0.502); + background-blend-mode: multiply; + + /* backdrop-filter: blur(5px); */ +} + +.modalGlass3 { + background: rgba(62, 61, 61, 0.2); + background-blend-mode: multiply; + + backdrop-filter: blur(44px); +} diff --git a/src/langs/fa.json b/src/langs/fa.json index c5a7860..58dc635 100644 --- a/src/langs/fa.json +++ b/src/langs/fa.json @@ -12,7 +12,12 @@ "spam": "هرزنامه ها", "setting": "تنظیمات", "logout": "خروج", - "admin_panel": "پنل مدیریت" + "admin_panel": "پنل مدیریت", + "storage": "ذخیره‌سازی", + "add_space": "اضافه کردن فضا" + }, + "space": { + "title": "خرید فضای ذخیره سازی" }, "header": { "search": "جستجو" diff --git a/src/pages/setting/address/components/ProgressBarEmail.tsx b/src/pages/setting/address/components/ProgressBarEmail.tsx index ae5d37d..1f0e259 100644 --- a/src/pages/setting/address/components/ProgressBarEmail.tsx +++ b/src/pages/setting/address/components/ProgressBarEmail.tsx @@ -1,6 +1,7 @@ import { convertToGB } from '@/config/func' import { FC } from 'react' import { AddressData } from '../types/Types' +import ProgressBar from '@/components/ProgressBar' const ProgressBarEmail: FC<{ item: AddressData }> = ({ item }) => { const usedQuota = item.emailQuotaUsed || 0; @@ -17,15 +18,7 @@ const ProgressBarEmail: FC<{ item: AddressData }> = ({ item }) => { {percentage.toFixed(1)}% */} -
-
90 ? 'bg-red-500' : - percentage > 70 ? 'bg-yellow-500' : - 'bg-green-500' - }`} - style={{ width: `${percentage}%` }} - >
-
+ ) } diff --git a/src/pages/setting/domain/hooks/useDomainData.ts b/src/pages/setting/domain/hooks/useDomainData.ts index f807910..92c246a 100644 --- a/src/pages/setting/domain/hooks/useDomainData.ts +++ b/src/pages/setting/domain/hooks/useDomainData.ts @@ -30,3 +30,10 @@ export const useVerifyDnsRecord = () => { queryFn: () => api.verifyDnsRecord(), }); }; + +export const useGetSpace = () => { + return useQuery({ + queryKey: ["space"], + queryFn: () => api.getSpace(), + }); +}; diff --git a/src/pages/setting/domain/service/DomainService.ts b/src/pages/setting/domain/service/DomainService.ts index 990f073..a006bd5 100644 --- a/src/pages/setting/domain/service/DomainService.ts +++ b/src/pages/setting/domain/service/DomainService.ts @@ -20,3 +20,8 @@ export const verifyDnsRecord = async () => { const { data } = await axios.get(`/domains/verify-dns`); return data; }; + +export const getSpace = async () => { + const { data } = await axios.get(`/business/quota`); + return data; +}; diff --git a/src/shared/Main.tsx b/src/shared/Main.tsx index 2a5f46f..76b3587 100644 --- a/src/shared/Main.tsx +++ b/src/shared/Main.tsx @@ -2,16 +2,9 @@ import { FC } from 'react' import SideBar from './SideBar' import AppRouter from '@/router/AppRouter' import Header from './Header' -import Button from '@/components/Button' -import { Add } from 'iconsax-react' -import { useTranslation } from 'react-i18next' -import { useSharedStore } from './store/sharedStore' const Main: FC = () => { - const { t } = useTranslation() - const { setOpenSidebar, setOpenNewMessage } = useSharedStore() - return (
@@ -24,7 +17,7 @@ const Main: FC = () => {
-
+ {/*
-
+ */} ) diff --git a/src/shared/SideBar.tsx b/src/shared/SideBar.tsx index d5f57d2..450958c 100644 --- a/src/shared/SideBar.tsx +++ b/src/shared/SideBar.tsx @@ -7,6 +7,7 @@ import { useSharedStore } from './store/sharedStore' import { clx } from '../helpers/utils' import { useTranslation } from 'react-i18next' import { Paths } from '@/utils/Paths' +import Storage from './components/Storage' const SideBar: FC = () => { @@ -76,6 +77,7 @@ const SideBar: FC = () => {
+
} diff --git a/src/shared/components/BuySpace.tsx b/src/shared/components/BuySpace.tsx new file mode 100644 index 0000000..e58adb5 --- /dev/null +++ b/src/shared/components/BuySpace.tsx @@ -0,0 +1,26 @@ +import DefaulModal from '@/components/DefaulModal' +import { useSharedStore } from '@/shared/store/sharedStore' +import { useTranslation } from 'react-i18next' +import { FC } from 'react' + +const BuySpace: FC = () => { + + const { t } = useTranslation() + const { openBuySpace, setOpenBuySpace } = useSharedStore() + console.log(openBuySpace); + + return ( + setOpenBuySpace(false)} + isHeader={true} + title_header={t('space.title')} + > +
+ +
+
+ ) +} + +export default BuySpace \ No newline at end of file diff --git a/src/shared/components/Storage.tsx b/src/shared/components/Storage.tsx new file mode 100644 index 0000000..cdf5623 --- /dev/null +++ b/src/shared/components/Storage.tsx @@ -0,0 +1,52 @@ +import Button from '@/components/Button' +import ProgressBar from '@/components/ProgressBar' +import { useGetSpace } from '@/pages/setting/domain/hooks/useDomainData' +import { useSharedStore } from '@/shared/store/sharedStore' +import { Cloud } from 'iconsax-react' +import { FC } from 'react' +import { useTranslation } from 'react-i18next' + +const Storage: FC = () => { + + const { t } = useTranslation() + const { setOpenBuySpace } = useSharedStore() + const { data } = useGetSpace() + return ( +
+
+ +
+ {t('sidebar.storage')} +
+
+ +
+ +
+ +
+ {data?.data?.quota?.usedInGB} گیگابایت از {data?.data?.quota?.totalInGB} گیگابایت استفاده شده است +
+ +
+
+ + +
+ ) +} + +export default Storage \ No newline at end of file diff --git a/src/shared/store/sharedStore.ts b/src/shared/store/sharedStore.ts index 566cfc4..20c0b1d 100644 --- a/src/shared/store/sharedStore.ts +++ b/src/shared/store/sharedStore.ts @@ -6,4 +6,6 @@ export const useSharedStore = create((set) => ({ setOpenSidebar: (value) => set({ openSidebar: value }), openNewMessage: false, setOpenNewMessage: (value) => set({ openNewMessage: value }), + openBuySpace: false, + setOpenBuySpace: (value) => set({ openBuySpace: value }), })); diff --git a/src/shared/types/SharedTypes.ts b/src/shared/types/SharedTypes.ts index 012e4b5..68dcc37 100644 --- a/src/shared/types/SharedTypes.ts +++ b/src/shared/types/SharedTypes.ts @@ -3,4 +3,6 @@ export type SharedStoreType = { setOpenSidebar: (value: boolean) => void; openNewMessage: boolean; setOpenNewMessage: (value: boolean) => void; + openBuySpace: boolean; + setOpenBuySpace: (value: boolean) => void; };