Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

New feature update #21

Merged
merged 4 commits into from
Sep 28, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/clean-vans-push.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"antd-multi-dashboard": minor
---

Added mobile responsiveness to both layouts and existing pages
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ jobs:
run: yarn install --frozen-lockfile

- name: Build application
run: yarn run build --if-present
run: yarn run build

- name: Test
run: yarn test
6 changes: 6 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,12 @@ function App() {
token: {
colorPrimary: '#925368',
borderRadius: 6,
},
components: {
Breadcrumb: {
linkColor: 'rgba(0,0,0,.8)',
itemColor: 'rgba(0,0,0,.8)'
}
}
}}
>
Expand Down
26 changes: 26 additions & 0 deletions src/components/PageHeader/PageHeader.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import {Breadcrumb, BreadcrumbProps, Divider, Space, Typography} from "antd";

import "./styles.css"

type Props = {
title: string
breadcrumbs: BreadcrumbProps["items"]
}

const PageHeader = ({breadcrumbs, title}: Props) => {
return (
<div>
<Space direction="vertical" size="small">
<Typography.Title level={4} style={{padding: 0, margin: 0, textTransform: "capitalize"}}>
{title}
</Typography.Title>
<Breadcrumb items={breadcrumbs} className="page-header-breadcrumbs"/>
</Space>
<Divider orientation="right" plain>
<span style={{textTransform: "capitalize"}}>{title}</span>
</Divider>
</div>
);
};

export default PageHeader;
7 changes: 7 additions & 0 deletions src/components/PageHeader/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.page-header-breadcrumbs .ant-breadcrumb-link {
text-transform: capitalize !important;
}

.ant-dropdown .ant-dropdown-menu-item .ant-dropdown-menu-title-content {
text-transform: capitalize !important;
}
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,33 @@ const CoursesCarousel = ({data, ...others}: Props) => {
slidesToShow: 3,
slidesToScroll: 1,
infinite: true,
dots: false
dots: false,
responsive: [
{
breakpoint: 1024,
settings: {
slidesToShow: 3,
slidesToScroll: 3,
infinite: true,
dots: true
}
},
{
breakpoint: 769,
settings: {
slidesToShow: 2,
slidesToScroll: 2,
initialSlide: 2
}
},
{
breakpoint: 480,
settings: {
slidesToShow: 1,
slidesToScroll: 1
}
}
]
};

const handlePrevious = (): void => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Card as AntdCard, Button, CardProps, Space, Tag, Typography, theme} from "antd";
import {Card as AntdCard, Button, CardProps, Space, Tag, Typography, theme, List} from "antd";
import {
FacebookOutlined,
InstagramOutlined,
Expand Down Expand Up @@ -62,22 +62,34 @@ const SocialStatsCard = ({...others}: Props) => {
]}
{...others}
>
{SOCIALS_DATA.map((_, i) =>
<AntdCard.Grid
key={`${_.title}-${i}`}
hoverable={false}
style={{borderRadius, ...gridStyle}}
>
<Space>
<Typography.Text>{_.title}</Typography.Text>
<Tag color={_.diff < 0 ? 'error' : 'success'}>{_.diff}</Tag>
</Space>
<Space>
<Typography.Title level={4} style={{margin: 0}}>{_.value}</Typography.Title>
<Typography.Text color="secondary">visitors</Typography.Text>
</Space>
</AntdCard.Grid>
)}
<List
grid={{
gutter: 16,
xs: 1,
sm: 2,
md: 4,
lg: 4,
xl: 6,
xxl: 3,
}}
dataSource={SOCIALS_DATA}
renderItem={(item, i ) => (
<AntdCard.Grid
key={`${item.title}-${i}`}
hoverable={false}
style={{borderRadius, ...gridStyle}}
>
<Space>
<Typography.Text>{item.title}</Typography.Text>
<Tag color={item.diff < 0 ? 'error' : 'success'}>{item.diff}</Tag>
</Space>
<Space>
<Typography.Title level={4} style={{margin: 0}}>{item.value}</Typography.Title>
<Typography.Text color="secondary">visitors</Typography.Text>
</Space>
</AntdCard.Grid>
)}
/>
</Card>
);
};
Expand Down
4 changes: 3 additions & 1 deletion src/components/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ import UserAvatar from "./UserAvatar/UserAvatar.tsx";
import NotificationsItem from "./NotificationsItem/NotificationsItem.tsx";
import NotificationsCard from "./NotificationsCard/NotificationsCard.tsx";
import Card from "./Card/Card.tsx";
import PageHeader from "./PageHeader/PageHeader.tsx";

export {
Logo,
Expand Down Expand Up @@ -109,5 +110,6 @@ export {
TasksListCard,
NotificationsItem,
NotificationsCard,
Card
Card,
PageHeader
}
11 changes: 11 additions & 0 deletions src/constants/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,17 @@ import {
PATH_LANDING
} from "./routes.ts"

export const DASHBOARD_ITEMS = [
{title: 'default', path: PATH_DASHBOARD.default},
{title: 'projects', path: PATH_DASHBOARD.projects},
{title: 'ecommerce', path: PATH_DASHBOARD.ecommerce},
{title: 'marketing', path: PATH_DASHBOARD.marketing},
{title: 'social', path: PATH_DASHBOARD.social},
{title: 'bidding', path: PATH_DASHBOARD.bidding},
{title: 'learning', path: PATH_DASHBOARD.learning},
{title: 'logistics', path: PATH_DASHBOARD.logistics},
]

export {
PATH_CALENDAR,
PATH_USER_MGMT,
Expand Down
98 changes: 74 additions & 24 deletions src/layouts/app/App.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,49 @@
import {Button, Input, Layout, Space, theme, Tooltip} from "antd";
import {Affix, Button, Input, Layout, Space, theme, Tooltip} from "antd";
import {Outlet} from "react-router-dom";
import {ReactNode, useState} from "react";
import {AppstoreOutlined, MenuFoldOutlined, MenuUnfoldOutlined, MessageOutlined} from "@ant-design/icons";
import {useEffect, useState} from "react";
import {AppstoreOutlined, MenuFoldOutlined, MenuUnfoldOutlined, MessageOutlined, UpOutlined} from "@ant-design/icons";
import SideNav from "./SideNav.tsx";
import HeaderNav from "./HeaderNav.tsx";
import FooterNav from "./FooterNav.tsx";
import {useMediaQuery} from "react-responsive";

const {Content} = Layout

type AppLayoutProps = {
headerContent: ReactNode
}

const AppLayout = ({headerContent}: AppLayoutProps) => {
const AppLayout = () => {
const {
token: {borderRadius},
} = theme.useToken();
const [collapsed, setCollapsed] = useState(false);
const isMobile = useMediaQuery({maxWidth: 769})
const [collapsed, setCollapsed] = useState(true);
const [showTopBtn, setShowTopBtn] = useState(false);
const [navFill, setNavFill] = useState(false)

const goToTop = () => {
window.scrollTo({
top: 0,
behavior: 'smooth',
});
};

useEffect(() => {
setCollapsed(isMobile)
}, [isMobile]);

useEffect(() => {
window.addEventListener('scroll', () => {
if (window.scrollY > 400) {
setShowTopBtn(true);
} else {
setShowTopBtn(false);
}

if (window.scrollY > 10) {
setNavFill(true)
} else {
setNavFill(false)
}
});
}, []);

return (
<Layout
Expand Down Expand Up @@ -50,32 +77,41 @@ const AppLayout = ({headerContent}: AppLayoutProps) => {
style={{
marginLeft: collapsed ? 0 : '200px',
padding: '0 1rem 0 0',
background: "none",
background: navFill ? "rgb(211, 215, 231)" : "none",
backdropFilter: navFill ? "blur(8px)" : "none",
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
// boxShadow: '0px 4px 4px 0px rgba(0,0,0,0.1)',
position: 'sticky',
top: 0,
zIndex: 1
zIndex: 1,
gap: 8,
transition: "width 2s"
}}>
<Space align="center">
<Button
type="text"
icon={collapsed ? <MenuUnfoldOutlined/> : <MenuFoldOutlined/>}
onClick={() => setCollapsed(!collapsed)}
<Space align="center" style={{width: "100%"}}>
<Tooltip title={`${collapsed ? "Expand" : "Collapse"} Sidebar`}>
<Button
type="text"
icon={collapsed ? <MenuUnfoldOutlined/> : <MenuFoldOutlined/>}
onClick={() => setCollapsed(!collapsed)}
style={{
fontSize: '16px',
width: 64,
height: 64,
}}
/>
</Tooltip>
<Input.Search
placeholder="search"
style={{
fontSize: '16px',
width: 64,
height: 64,
width: isMobile ? "100%" : "400px",
marginTop: "10px"
}}
size="large"
/>
<div style={{marginBottom: '1.2rem'}}>
{headerContent}
</div>
</Space>
<Space align="center">
<Input.Search placeholder="search" style={{display: 'inline'}}></Input.Search>
<Tooltip title="Apps">
<Button icon={<AppstoreOutlined/>}/>
</Tooltip>
Expand All @@ -91,9 +127,23 @@ const AppLayout = ({headerContent}: AppLayoutProps) => {
borderRadius
}}
>
<div style={{padding: 24, minHeight: 360, background: ''}}>
<div style={{padding: 24, minHeight: 360, background: 'none'}}>
<Outlet/>
</div>
{showTopBtn &&
<Affix offsetBottom={10} style={{textAlign: 'end', transition: "width 2s"}}>
<Tooltip title="Scroll to top of the screen">
<Button
type="primary"
onClick={goToTop}
icon={<UpOutlined/>}
shape={isMobile ? "circle" : "default"}
size={isMobile ? "large" : "middle"}>
{!isMobile && "Scroll to top"}
</Button>
</Tooltip>
</Affix>
}
</Content>
<FooterNav
style={{
Expand Down
24 changes: 1 addition & 23 deletions src/layouts/dashboards/index.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,8 @@
import {AppLayout} from "../app";
import {Breadcrumb, Space, Typography} from "antd";
import {Link} from "react-router-dom";
import {PATH_DASHBOARD} from "../../constants";


const DashboardLayout = () => {
return (
<AppLayout
headerContent={
<Space direction="vertical" size={0}>
<Typography.Title level={5} style={{padding: 0, margin: 0}}>
Dashboard
</Typography.Title>
<Breadcrumb
items={[
{
title: <Link to={PATH_DASHBOARD.root}>Home</Link>,
},
{
title: 'Page title',
},
]}
/>
</Space>
}
/>
<AppLayout />
);
};

Expand Down
Loading
Loading