Skip to content

Commit

Permalink
Adds Layout Components, including banner, sider menu and main layout.
Browse files Browse the repository at this point in the history
  • Loading branch information
Cemal Türkoglu committed Oct 16, 2020
1 parent 7afcd0c commit 229b776
Show file tree
Hide file tree
Showing 8 changed files with 324 additions and 16 deletions.
8 changes: 2 additions & 6 deletions package.json
Expand Up @@ -31,10 +31,6 @@
"\\.(css|scss)$": "<rootDir>/__mocks__/styleMock.js",
"\\.(jpg|gif|ttf|eot|svg)$": "<rootDir>/__mocks__/fileMock.js"
},
"transform": {
"^.+\\.(js|jsx)$": "babel-jest",
".+\\.(css|styl|less|sass|scss)$": "<rootDir>/node_modules/jest-css-modules-transform"
},
"setupTestFrameworkScriptFile": "<rootDir>/setupTests.js",
"moduleFileExtensions": [
"css",
Expand Down Expand Up @@ -101,7 +97,7 @@
"clean-webpack-plugin": "3.0.0",
"connect-history-api-fallback": "1.6.0",
"cross-env": "7.0.2",
"css-loader": "3.6.0",
"css-loader": "^5.0.0",
"enzyme": "3.11.0",
"enzyme-adapter-react-16": "1.15.4",
"eslint": "6.8.0",
Expand Down Expand Up @@ -133,7 +129,7 @@
"pretty-quick": "2.0.2",
"sass-loader": "8.0.2",
"script-ext-html-webpack-plugin": "2.1.4",
"style-loader": "1.2.1",
"style-loader": "^2.0.0",
"terser-webpack-plugin": "4.2.2",
"webpack": "4.44.2",
"webpack-cli": "3.3.12",
Expand Down
Binary file added public/icon.png
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
35 changes: 35 additions & 0 deletions src/component/UserAvatar.js
@@ -0,0 +1,35 @@
import React from 'react';
import { Avatar } from 'antd';

function getColor(username) {
const colors = [
'#ffa38a',
'#a9a7e0',
'#D686D4',
'#96CE56',
'#4A90E2',
'#62b3d0',
'#ef7676',
];
const firstChar = username.charCodeAt(0);
const secondChar = username.charCodeAt(1);
const thirdChar = username.charCodeAt(2);

return colors[(firstChar + secondChar + thirdChar) % 7];
}

export const getUsernameAvatar = (username, size = 'large') => {
return (
<div>
<Avatar
style={{
backgroundColor: getColor(username),
verticalAlign: 'middle',
}}
size={size}
>
{username ? username.charAt(0).toUpperCase() : ''}
</Avatar>
</div>
);
};
102 changes: 102 additions & 0 deletions src/page/layout/LayoutBanner.js
@@ -0,0 +1,102 @@
import React from 'react';
import {
MenuUnfoldOutlined,
MenuFoldOutlined,
QuestionCircleOutlined,
GlobalOutlined,
BellOutlined,
UserOutlined,
LogoutOutlined,
} from '@ant-design/icons';
import { Layout, Menu, Badge } from 'antd';
import './Style.less';
import { getUsernameAvatar } from '../../component/UserAvatar';

const { Header } = Layout;
const { SubMenu } = Menu;

function LayoutBanner({ collapsed, handleOnCollapse }) {
const getCollapseIcon = () => {
if (collapsed) {
return (
<MenuUnfoldOutlined onClick={handleOnCollapse} className="trigger" />
);
}
return <MenuFoldOutlined onClick={handleOnCollapse} className="trigger" />;
};

const handleLanguageMenuClick = () => {};
const handleSettingMenuClick = () => {};
const handleLogout = () => {};

return (
<Header className="header" style={{ background: '#fff', padding: 0 }}>
<div
style={{
float: 'left',
width: '100%',
alignSelf: 'center',
display: 'flex',
}}
>
{window.innerWidth > 992 && getCollapseIcon()}
</div>
<Menu
// onClick={this.handleLanguageMenuClick}
mode="horizontal"
className="menu"
>
<SubMenu title={<QuestionCircleOutlined />} />
</Menu>
<Menu
// onClick={this.handleLanguageMenuClick}
mode="horizontal"
className="menu"
>
<SubMenu
title={
<Badge dot>
<BellOutlined />
</Badge>
}
/>
</Menu>
<Menu
onClick={handleLanguageMenuClick}
mode="horizontal"
className="menu"
>
<SubMenu title={<GlobalOutlined />}>
<Menu.Item key="en">
<span role="img" aria-label="English">
🇺🇸 English
</span>
</Menu.Item>
<Menu.Item key="it">
<span role="img" aria-label="Italian">
🇮🇹 Italian
</span>
</Menu.Item>
</SubMenu>
</Menu>
<Menu onClick={handleSettingMenuClick} mode="horizontal" className="menu">
<SubMenu title={getUsernameAvatar('Cemal')}>
<Menu.Item key="setting:1">
<span>
<UserOutlined />
Profile
</span>
</Menu.Item>
<Menu.Item key="setting:2">
<span>
<LogoutOutlined onClick={handleLogout} />
Logout
</span>
</Menu.Item>
</SubMenu>
</Menu>
</Header>
);
}

export default LayoutBanner;
32 changes: 30 additions & 2 deletions src/page/layout/MainLayout.js
@@ -1,7 +1,35 @@
import React from 'react';
import React, { useState } from 'react';
import { Layout } from 'antd';
import SiderMenu from './SiderMenu';
import LayoutBanner from './LayoutBanner';
import './Style.less';
import RoutingList from '../../router/RoutingList';

const { Content } = Layout;

function MainLayout() {
return <div>Main Layout</div>;
const [collapsed, setCollapsed] = useState(false);

const handleOnCollapse = () => {
setCollapsed(prevState => !prevState);
};

return (
<Layout style={{ minHeight: '100vh' }}>
<SiderMenu collapsed={collapsed} handleOnCollapse={handleOnCollapse} />
<Layout>
<LayoutBanner
collapsed={collapsed}
handleOnCollapse={handleOnCollapse}
/>
<Content style={{ margin: '24px 16px 0' }}>
<div style={{ padding: 24, background: '#fff', minHeight: 20 }}>
<RoutingList />
</div>
</Content>
</Layout>
</Layout>
);
}

export default MainLayout;
107 changes: 107 additions & 0 deletions src/page/layout/SiderMenu.js
@@ -0,0 +1,107 @@
import React from 'react';
import { Layout, Menu } from 'antd';
import { useHistory } from 'react-router-dom';
import {
DashboardOutlined,
FundProjectionScreenOutlined,
PartitionOutlined,
SettingOutlined,
TeamOutlined,
} from '@ant-design/icons';
import './Style.less';

const { SubMenu } = Menu;

const { Sider } = Layout;

function SiderMenu({ handleOnCollapse, collapsed }) {
const theme = 'light';

const history = useHistory();

const handleSiderMenuClick = action => {
console.log('menu:', action);
switch (action.key) {
case 'dashboard':
history.push('/');
break;
case 'showProducts':
history.push('/products');
break;
case 'addProduct':
history.push('/add-product');
break;
case 'showCustomers':
history.push('/customers');
break;
case 'addCustomer':
history.push('/add-customer');
break;
default:
history.push('/');
}
};

return (
<Sider
breakpoint="lg"
collapsedWidth="80"
onCollapse={handleOnCollapse}
collapsed={collapsed}
width="256"
theme={theme}
>
<a>
<div className="menu-logo" />
</a>
<Menu mode="inline" theme={theme} onClick={handleSiderMenuClick}>
<Menu.Item key="dashboard">
<DashboardOutlined />
<span className="nav-text">Dashboard</span>
</Menu.Item>
<SubMenu
key="products"
title={
<span>
<PartitionOutlined />
<span>Products</span>
</span>
}
>
<Menu.Item key="showProducts">
<span className="nav-text">Show Products</span>
</Menu.Item>
<Menu.Item key="addProduct">
<span className="nav-text">Add Product</span>
</Menu.Item>
</SubMenu>
<SubMenu
key="customers"
title={
<span>
<TeamOutlined />
<span>Customers</span>
</span>
}
>
<Menu.Item key="showCustomers">
<span className="nav-text">Show Customers</span>
</Menu.Item>
<Menu.Item key="addCustomer">
<span className="nav-text">Add Customer</span>
</Menu.Item>
</SubMenu>
<Menu.Item key="settings">
<SettingOutlined />
<span className="nav-text">Settings</span>
</Menu.Item>
<Menu.Item key="reports">
<FundProjectionScreenOutlined />
<span className="nav-text">Reports</span>
</Menu.Item>
</Menu>
</Sider>
);
}

export default SiderMenu;
37 changes: 37 additions & 0 deletions src/page/layout/Style.less
@@ -0,0 +1,37 @@
.header {
display: flex;
}

.menu {
.ant-menu-horizontal {
& > .ant-menu-submenu {
float: right;
}
border: none;
}
box-shadow: #e4ecef;
position: relative;
.ant-menu-submenu-title {
width: 64px;
height: 64px;
text-align: center;
padding-top: 8px;
}
}

.trigger {
margin-left: 16px;
margin-right: 16px;
align-self: center;

}

.menu-logo {
background-image: url('../../../public/icon.png');
background-repeat: no-repeat;
background-position: center;
height: 35px;
background-size: 100%;
margin: 20px;
color: #ffffff;
}
19 changes: 11 additions & 8 deletions webpack/webpack.prod.js
Expand Up @@ -50,20 +50,23 @@ module.exports = {
module: {
rules: [
{
test: /\.(css|scss)$/,
test: /\.(css|scs)$/,
use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
},
{
test: /\.less$/,
use: [
MiniCssExtractPlugin.loader,
'style-loader',
'css-loader',
'sass-loader',
{
loader: 'css-loader',
loader: 'less-loader',
options: {
sourceMap: false,
localsConvention: 'camelCase',
modules: {
localIdentName: '[local]___[hash:base64:5]',
lessOptions: {
javascriptEnabled: true,
},
},
},
'sass-loader',
],
},
],
Expand Down

0 comments on commit 229b776

Please sign in to comment.