feat: design system added
This commit is contained in:
parent
f05fdaa293
commit
cfc05083fd
13 changed files with 80 additions and 40 deletions
|
|
@ -4,6 +4,8 @@ import type { ReactNode } from "react";
|
||||||
import { useNavigate, useLocation } from "react-router-dom";
|
import { useNavigate, useLocation } from "react-router-dom";
|
||||||
import winsooLogo from "../../assets/images/winsoo.svg";
|
import winsooLogo from "../../assets/images/winsoo.svg";
|
||||||
import { getSidebarMenuItems } from "../../constants/navigation";
|
import { getSidebarMenuItems } from "../../constants/navigation";
|
||||||
|
import { colors } from "../../design/tokens/colors";
|
||||||
|
import { spacing } from "../../design/tokens/spacing";
|
||||||
|
|
||||||
const { Header, Content, Sider } = Layout;
|
const { Header, Content, Sider } = Layout;
|
||||||
const { Title } = Typography;
|
const { Title } = Typography;
|
||||||
|
|
@ -46,8 +48,8 @@ const AdminLayout = ({ children }: AdminLayoutProps) => {
|
||||||
style={{
|
style={{
|
||||||
height: 64,
|
height: 64,
|
||||||
padding: "0 16px",
|
padding: "0 16px",
|
||||||
borderBottom: "1px solid #ECF2F8",
|
borderBottom: `1px solid ${colors.primaryLight}`,
|
||||||
background: "#233E5F",
|
background: colors.primary,
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
justifyContent: "flex-start",
|
justifyContent: "flex-start",
|
||||||
|
|
@ -67,8 +69,8 @@ const AdminLayout = ({ children }: AdminLayoutProps) => {
|
||||||
style={{
|
style={{
|
||||||
borderInlineEnd: 0,
|
borderInlineEnd: 0,
|
||||||
paddingTop: 12,
|
paddingTop: 12,
|
||||||
background: "#ffffff",
|
background: colors.background,
|
||||||
color: "#000000",
|
color: colors.text,
|
||||||
}}
|
}}
|
||||||
theme="light"
|
theme="light"
|
||||||
className="sidebar-menu"
|
className="sidebar-menu"
|
||||||
|
|
@ -84,7 +86,7 @@ const AdminLayout = ({ children }: AdminLayoutProps) => {
|
||||||
open={mobileOpen}
|
open={mobileOpen}
|
||||||
onClose={() => setMobileOpen(false)}
|
onClose={() => setMobileOpen(false)}
|
||||||
width={260}
|
width={260}
|
||||||
bodyStyle={{ padding: 0, background: "#ffffff" }}
|
bodyStyle={{ padding: 0, background: colors.background }}
|
||||||
closeIcon={null}
|
closeIcon={null}
|
||||||
>
|
>
|
||||||
{sidebarContent}
|
{sidebarContent}
|
||||||
|
|
@ -98,13 +100,13 @@ const AdminLayout = ({ children }: AdminLayoutProps) => {
|
||||||
<Layout>
|
<Layout>
|
||||||
<Header
|
<Header
|
||||||
style={{
|
style={{
|
||||||
background: "#233E5F",
|
background: colors.primary,
|
||||||
height: 64,
|
height: 64,
|
||||||
padding: "0 24px",
|
padding: `0 ${spacing.lg}px`,
|
||||||
display: "flex",
|
display: "flex",
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
justifyContent: "space-between",
|
justifyContent: "space-between",
|
||||||
borderBottom: "1px solid #ECF2F8",
|
borderBottom: `1px solid ${colors.primaryLight}`,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{isMobile ? (
|
{isMobile ? (
|
||||||
|
|
@ -118,7 +120,7 @@ const AdminLayout = ({ children }: AdminLayoutProps) => {
|
||||||
alignItems: "center",
|
alignItems: "center",
|
||||||
justifyContent: "center",
|
justifyContent: "center",
|
||||||
cursor: "pointer",
|
cursor: "pointer",
|
||||||
color: "#ffffff",
|
color: colors.background,
|
||||||
}}
|
}}
|
||||||
onClick={() => setMobileOpen(true)}
|
onClick={() => setMobileOpen(true)}
|
||||||
role="button"
|
role="button"
|
||||||
|
|
@ -132,7 +134,7 @@ const AdminLayout = ({ children }: AdminLayoutProps) => {
|
||||||
☰
|
☰
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
<Title level={4} style={{ margin: 0, color: "#ffffff", flex: 1, textAlign: "center" }}>
|
<Title level={4} style={{ margin: 0, color: colors.background, flex: 1, textAlign: "center" }}>
|
||||||
پنل ادمین وینسو
|
پنل ادمین وینسو
|
||||||
</Title>
|
</Title>
|
||||||
</Header>
|
</Header>
|
||||||
|
|
@ -140,11 +142,11 @@ const AdminLayout = ({ children }: AdminLayoutProps) => {
|
||||||
<Content style={{ margin: 24 }}>
|
<Content style={{ margin: 24 }}>
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
background: "#ffffff",
|
background: colors.background,
|
||||||
minHeight: 280,
|
minHeight: 280,
|
||||||
borderRadius: borderRadiusLG,
|
borderRadius: borderRadiusLG,
|
||||||
padding: 24,
|
padding: spacing.lg,
|
||||||
border: "1px solid #ECF2F8",
|
border: `1px solid ${colors.primaryLight}`,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{children}
|
{children}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
import { Menu } from 'antd';
|
import { Menu } from 'antd';
|
||||||
import { useNavigate, useLocation } from 'react-router-dom';
|
import { useNavigate, useLocation } from 'react-router-dom';
|
||||||
import { getSidebarMenuItems } from '../../constants/navigation';
|
import { getSidebarMenuItems } from '../../constants/navigation';
|
||||||
|
import { colors } from '../../design/tokens/colors';
|
||||||
|
import { spacing } from '../../design/tokens/spacing';
|
||||||
|
|
||||||
const Sidebar = () => {
|
const Sidebar = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
@ -12,7 +14,7 @@ const Sidebar = () => {
|
||||||
selectedKeys={[location.pathname]}
|
selectedKeys={[location.pathname]}
|
||||||
items={getSidebarMenuItems()}
|
items={getSidebarMenuItems()}
|
||||||
onClick={({ key }) => navigate(key)}
|
onClick={({ key }) => navigate(key)}
|
||||||
style={{ height: '100%', borderInlineEnd: 0, paddingTop: 12, background: '#ffffff', color: '#000000' }}
|
style={{ height: '100%', borderInlineEnd: 0, paddingTop: spacing.sm, background: colors.background, color: colors.text }}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
14
src/design/theme/antdTheme.ts
Normal file
14
src/design/theme/antdTheme.ts
Normal file
|
|
@ -0,0 +1,14 @@
|
||||||
|
import type { ThemeConfig } from 'antd';
|
||||||
|
import { colors } from '../tokens/colors';
|
||||||
|
import { typography } from '../tokens/typography';
|
||||||
|
|
||||||
|
export const antdTheme: ThemeConfig = {
|
||||||
|
token: {
|
||||||
|
colorPrimary: colors.primary,
|
||||||
|
colorText: colors.text,
|
||||||
|
colorTextSecondary: colors.textSecondary,
|
||||||
|
colorBgContainer: colors.background,
|
||||||
|
borderRadius: 12,
|
||||||
|
fontFamily: typography.fontFamily,
|
||||||
|
},
|
||||||
|
};
|
||||||
8
src/design/tokens/colors.ts
Normal file
8
src/design/tokens/colors.ts
Normal file
|
|
@ -0,0 +1,8 @@
|
||||||
|
export const colors = {
|
||||||
|
primary: '#233E5F',
|
||||||
|
primaryLight: '#ECF2F8',
|
||||||
|
accent: '#F0642D',
|
||||||
|
background: '#FFFFFF',
|
||||||
|
text: '#000000',
|
||||||
|
textSecondary: '#B3B3B3',
|
||||||
|
} as const;
|
||||||
3
src/design/tokens/index.ts
Normal file
3
src/design/tokens/index.ts
Normal file
|
|
@ -0,0 +1,3 @@
|
||||||
|
export { colors } from './colors';
|
||||||
|
export { spacing } from './spacing';
|
||||||
|
export { typography } from './typography';
|
||||||
7
src/design/tokens/spacing.ts
Normal file
7
src/design/tokens/spacing.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
export const spacing = {
|
||||||
|
xs: 4,
|
||||||
|
sm: 8,
|
||||||
|
md: 16,
|
||||||
|
lg: 24,
|
||||||
|
xl: 32,
|
||||||
|
} as const;
|
||||||
7
src/design/tokens/typography.ts
Normal file
7
src/design/tokens/typography.ts
Normal file
|
|
@ -0,0 +1,7 @@
|
||||||
|
export const typography = {
|
||||||
|
fontFamily: 'IRANSans, sans-serif',
|
||||||
|
fontSize: 14,
|
||||||
|
fontWeightRegular: 400,
|
||||||
|
fontWeightBold: 700,
|
||||||
|
lineHeight: 1.5,
|
||||||
|
} as const;
|
||||||
17
src/main.tsx
17
src/main.tsx
|
|
@ -7,26 +7,13 @@ import 'antd/dist/reset.css';
|
||||||
import faIR from 'antd/locale/fa_IR';
|
import faIR from 'antd/locale/fa_IR';
|
||||||
import { store } from './app/store';
|
import { store } from './app/store';
|
||||||
import { router } from './routes/router';
|
import { router } from './routes/router';
|
||||||
|
import { antdTheme } from './design/theme/antdTheme';
|
||||||
import './index.css';
|
import './index.css';
|
||||||
|
|
||||||
createRoot(document.getElementById('root')!).render(
|
createRoot(document.getElementById('root')!).render(
|
||||||
<StrictMode>
|
<StrictMode>
|
||||||
<Provider store={store}>
|
<Provider store={store}>
|
||||||
<ConfigProvider
|
<ConfigProvider direction="rtl" locale={faIR} theme={antdTheme}>
|
||||||
direction="rtl"
|
|
||||||
locale={faIR}
|
|
||||||
theme={{
|
|
||||||
token: {
|
|
||||||
colorPrimary: '#233E5F',
|
|
||||||
colorInfo: '#233E5F',
|
|
||||||
colorSuccess: '#233E5F',
|
|
||||||
borderRadius: 12,
|
|
||||||
fontFamily: 'IRANSans, sans-serif',
|
|
||||||
colorText: '#000000',
|
|
||||||
colorTextSecondary: '#B3B3B3',
|
|
||||||
},
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<RouterProvider router={router} />
|
<RouterProvider router={router} />
|
||||||
</ConfigProvider>
|
</ConfigProvider>
|
||||||
</Provider>
|
</Provider>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
import { Card, Typography } from 'antd';
|
import { Card, Typography } from 'antd';
|
||||||
|
import { colors } from '../../design/tokens/colors';
|
||||||
|
import { spacing } from '../../design/tokens/spacing';
|
||||||
|
|
||||||
const { Title, Paragraph } = Typography;
|
const { Title, Paragraph } = Typography;
|
||||||
|
|
||||||
|
|
@ -6,7 +8,7 @@ const Billboards = () => {
|
||||||
return (
|
return (
|
||||||
<Card bordered={false} style={{ boxShadow: 'none', padding: 0 }}>
|
<Card bordered={false} style={{ boxShadow: 'none', padding: 0 }}>
|
||||||
<Title level={2}>بیلبوردها</Title>
|
<Title level={2}>بیلبوردها</Title>
|
||||||
<Paragraph style={{ color: '#B3B3B3', marginTop: 8 }}>
|
<Paragraph style={{ color: colors.textSecondary, marginTop: spacing.sm }}>
|
||||||
مدیریت جدول بیلبوردها بهزودی اضافه خواهد شد.
|
مدیریت جدول بیلبوردها بهزودی اضافه خواهد شد.
|
||||||
</Paragraph>
|
</Paragraph>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
import { Card, Typography } from 'antd';
|
import { Card, Typography } from 'antd';
|
||||||
|
import { colors } from '../../design/tokens/colors';
|
||||||
|
import { spacing } from '../../design/tokens/spacing';
|
||||||
|
|
||||||
const { Title, Paragraph } = Typography;
|
const { Title, Paragraph } = Typography;
|
||||||
|
|
||||||
|
|
@ -6,7 +8,7 @@ const Home = () => {
|
||||||
return (
|
return (
|
||||||
<Card bordered={false} style={{ boxShadow: 'none', padding: 0 }}>
|
<Card bordered={false} style={{ boxShadow: 'none', padding: 0 }}>
|
||||||
<Title level={2}>خوش آمدید</Title>
|
<Title level={2}>خوش آمدید</Title>
|
||||||
<Paragraph style={{ color: '#B3B3B3', marginTop: 8 }}>
|
<Paragraph style={{ color: colors.textSecondary, marginTop: spacing.sm }}>
|
||||||
به پنل ادمین وینسو خوش آمدید.
|
به پنل ادمین وینسو خوش آمدید.
|
||||||
</Paragraph>
|
</Paragraph>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,8 @@
|
||||||
import { Button, Card, Form, Input, Typography, message } from 'antd';
|
import { Button, Card, Form, Input, Typography, message } from 'antd';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import { authService } from '../../features/auth/authService';
|
import { authService } from '../../features/auth/authService';
|
||||||
|
import { colors } from '../../design/tokens/colors';
|
||||||
|
import { spacing } from '../../design/tokens/spacing';
|
||||||
|
|
||||||
const { Title, Paragraph } = Typography;
|
const { Title, Paragraph } = Typography;
|
||||||
|
|
||||||
|
|
@ -24,12 +26,12 @@ const Login = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ minHeight: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center', background: '#ECF2F8', direction: 'rtl' }}>
|
<div style={{ minHeight: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center', background: colors.primaryLight, direction: 'rtl' }}>
|
||||||
<Card style={{ width: 420, boxShadow: '0 12px 32px rgba(35, 62, 95, 0.12)', border: '1px solid #ECF2F8' }}>
|
<Card style={{ width: 420, boxShadow: '0 12px 32px rgba(35, 62, 95, 0.12)', border: `1px solid ${colors.primaryLight}` }}>
|
||||||
<Title level={3} style={{ marginBottom: 8, color: '#233E5F' }}>
|
<Title level={3} style={{ marginBottom: spacing.sm, color: colors.primary }}>
|
||||||
ورود به پنل ادمین
|
ورود به پنل ادمین
|
||||||
</Title>
|
</Title>
|
||||||
<Paragraph style={{ color: '#B3B3B3' }}>
|
<Paragraph style={{ color: colors.textSecondary }}>
|
||||||
برای ادامه شماره موبایل خود را وارد کنید.
|
برای ادامه شماره موبایل خود را وارد کنید.
|
||||||
</Paragraph>
|
</Paragraph>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,6 @@
|
||||||
import { Card, Typography } from 'antd';
|
import { Card, Typography } from 'antd';
|
||||||
|
import { colors } from '../../design/tokens/colors';
|
||||||
|
import { spacing } from '../../design/tokens/spacing';
|
||||||
|
|
||||||
const { Title, Paragraph } = Typography;
|
const { Title, Paragraph } = Typography;
|
||||||
|
|
||||||
|
|
@ -6,7 +8,7 @@ const Profile = () => {
|
||||||
return (
|
return (
|
||||||
<Card bordered={false} style={{ boxShadow: 'none', padding: 0 }}>
|
<Card bordered={false} style={{ boxShadow: 'none', padding: 0 }}>
|
||||||
<Title level={2}>پروفایل کاربر</Title>
|
<Title level={2}>پروفایل کاربر</Title>
|
||||||
<Paragraph style={{ color: '#B3B3B3', marginTop: 8 }}>
|
<Paragraph style={{ color: colors.textSecondary, marginTop: spacing.sm }}>
|
||||||
جدول اطلاعات کاربر بهزودی اضافه خواهد شد.
|
جدول اطلاعات کاربر بهزودی اضافه خواهد شد.
|
||||||
</Paragraph>
|
</Paragraph>
|
||||||
</Card>
|
</Card>
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,8 @@ import { useNavigate } from 'react-router-dom';
|
||||||
import { useAppDispatch } from '../../utils/hooks';
|
import { useAppDispatch } from '../../utils/hooks';
|
||||||
import { loginSuccess } from '../../features/auth/authSlice';
|
import { loginSuccess } from '../../features/auth/authSlice';
|
||||||
import { authService } from '../../features/auth/authService';
|
import { authService } from '../../features/auth/authService';
|
||||||
|
import { colors } from '../../design/tokens/colors';
|
||||||
|
import { spacing } from '../../design/tokens/spacing';
|
||||||
|
|
||||||
const { Title, Paragraph } = Typography;
|
const { Title, Paragraph } = Typography;
|
||||||
|
|
||||||
|
|
@ -37,12 +39,12 @@ const VerifyOtp = () => {
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div style={{ minHeight: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center', background: '#ECF2F8', direction: 'rtl' }}>
|
<div style={{ minHeight: '100vh', display: 'flex', alignItems: 'center', justifyContent: 'center', background: colors.primaryLight, direction: 'rtl' }}>
|
||||||
<Card style={{ width: 420, boxShadow: '0 12px 32px rgba(35, 62, 95, 0.12)', border: '1px solid #ECF2F8' }}>
|
<Card style={{ width: 420, boxShadow: '0 12px 32px rgba(35, 62, 95, 0.12)', border: `1px solid ${colors.primaryLight}` }}>
|
||||||
<Title level={3} style={{ marginBottom: 8, color: '#233E5F' }}>
|
<Title level={3} style={{ marginBottom: spacing.sm, color: colors.primary }}>
|
||||||
تایید کد یکبار مصرف
|
تایید کد یکبار مصرف
|
||||||
</Title>
|
</Title>
|
||||||
<Paragraph style={{ color: '#B3B3B3' }}>
|
<Paragraph style={{ color: colors.textSecondary }}>
|
||||||
کد تایید: 77501
|
کد تایید: 77501
|
||||||
</Paragraph>
|
</Paragraph>
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue