mirror of https://github.com/sunface/rust-course
commit
1773661f92
@ -0,0 +1,11 @@
|
|||||||
|
{
|
||||||
|
"presets": ["next/babel"],
|
||||||
|
"plugins": [
|
||||||
|
[
|
||||||
|
"import", {
|
||||||
|
"libraryName": "antd",
|
||||||
|
"style": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
/node_modules
|
||||||
|
/.pnp
|
||||||
|
.pnp.js
|
||||||
|
|
||||||
|
# testing
|
||||||
|
/coverage
|
||||||
|
|
||||||
|
# next.js
|
||||||
|
/.next/
|
||||||
|
/out/
|
||||||
|
|
||||||
|
# production
|
||||||
|
/build
|
||||||
|
|
||||||
|
# misc
|
||||||
|
.DS_Store
|
||||||
|
.env*
|
||||||
|
|
||||||
|
# debug
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
<p align="center">
|
||||||
|
<img alt="Sloan, the sloth mascot" width="250px" src="https://thepracticaldev.s3.amazonaws.com/uploads/user/profile_image/31047/af153cd6-9994-4a68-83f4-8ddf3e13f0bf.jpg">
|
||||||
|
<br>
|
||||||
|
<strong>Be A Happy Dev</strong> ❤️
|
||||||
|
</p>
|
@ -0,0 +1,230 @@
|
|||||||
|
import React, { useState, useEffect } from "react";
|
||||||
|
//
|
||||||
|
import Link from "next/link";
|
||||||
|
import { useRouter } from "next/router";
|
||||||
|
//
|
||||||
|
import {
|
||||||
|
useWindowSize,
|
||||||
|
useWindowWidth,
|
||||||
|
useWindowHeight
|
||||||
|
} from "@react-hook/window-size";
|
||||||
|
//
|
||||||
|
import { Layout, Menu, Switch } from "antd";
|
||||||
|
import {
|
||||||
|
HomeOutlined,
|
||||||
|
AppstoreOutlined,
|
||||||
|
BarChartOutlined,
|
||||||
|
CloudOutlined,
|
||||||
|
ShopOutlined,
|
||||||
|
TeamOutlined,
|
||||||
|
UserOutlined,
|
||||||
|
UploadOutlined,
|
||||||
|
VideoCameraOutlined
|
||||||
|
} from "@ant-design/icons";
|
||||||
|
//
|
||||||
|
import { Input } from "antd";
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
const { Search } = Input;
|
||||||
|
//
|
||||||
|
|
||||||
|
const { Header, Content, Footer, Sider } = Layout;
|
||||||
|
|
||||||
|
const AppLayout = props => {
|
||||||
|
const [siderKey, setSiderKey] = useState("");
|
||||||
|
const [isSiderCollapsed, setSiderCollapsed] = useState(false);
|
||||||
|
const [window, setWindow] = useState({ width: -1, height: -1 });
|
||||||
|
|
||||||
|
const [width, height] = useWindowSize();
|
||||||
|
useEffect(() => {
|
||||||
|
setWindow({ width: width, height: height });
|
||||||
|
|
||||||
|
return () => {
|
||||||
|
// cleanup
|
||||||
|
};
|
||||||
|
}, [width, height]);
|
||||||
|
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
console.log(siderKey);
|
||||||
|
return () => {
|
||||||
|
// cleanup
|
||||||
|
};
|
||||||
|
}, [siderKey]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
console.log("useEffect fired by useRouter");
|
||||||
|
const urlPath = router.pathname;
|
||||||
|
|
||||||
|
switch (urlPath) {
|
||||||
|
case "/":
|
||||||
|
setSiderKey(0);
|
||||||
|
break;
|
||||||
|
case "/profile":
|
||||||
|
setSiderKey(1);
|
||||||
|
break;
|
||||||
|
case "/videos":
|
||||||
|
setSiderKey(2);
|
||||||
|
break;
|
||||||
|
case "/backup":
|
||||||
|
setSiderKey(3);
|
||||||
|
break;
|
||||||
|
case "/analytics":
|
||||||
|
setSiderKey(4);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
return () => {
|
||||||
|
// cleanup
|
||||||
|
};
|
||||||
|
}, [router]);
|
||||||
|
|
||||||
|
const contentStyleWidth =
|
||||||
|
// responsive design
|
||||||
|
window.width < 480 ? { width: "calc(100vw - 32px)" } : {};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Layout>
|
||||||
|
<Sider
|
||||||
|
collapsible
|
||||||
|
breakpoint="lg"
|
||||||
|
collapsedWidth={window.width > 480 ? "80" : "0"} // enable responsive hidden sider for mobile only
|
||||||
|
onBreakpoint={broken => {
|
||||||
|
console.log(broken);
|
||||||
|
}}
|
||||||
|
collapsed={isSiderCollapsed}
|
||||||
|
onCollapse={(collapsed, type) => {
|
||||||
|
setSiderCollapsed(collapsed);
|
||||||
|
console.log(collapsed, type);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="logo"
|
||||||
|
style={{
|
||||||
|
height: 64,
|
||||||
|
width: "100%",
|
||||||
|
display: "flex",
|
||||||
|
justifyContent: "center",
|
||||||
|
alignItems: "center",
|
||||||
|
color: "white",
|
||||||
|
whiteSpace: "nowrap"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Sider Logo
|
||||||
|
</div>
|
||||||
|
<Menu theme="dark" mode="inline" selectedKeys={[siderKey.toString()]}>
|
||||||
|
<Menu.Item key="0">
|
||||||
|
<Link href="/">
|
||||||
|
<div>
|
||||||
|
<HomeOutlined />
|
||||||
|
<span className="nav-text">Home</span>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
</Menu.Item>
|
||||||
|
|
||||||
|
<Menu.Item key="1">
|
||||||
|
<Link href="/profile">
|
||||||
|
<div>
|
||||||
|
<UserOutlined />
|
||||||
|
<span className="nav-text">Profile</span>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
</Menu.Item>
|
||||||
|
|
||||||
|
<Menu.Item key="2">
|
||||||
|
<Link href="/videos">
|
||||||
|
<div>
|
||||||
|
<VideoCameraOutlined />
|
||||||
|
<span className="nav-text">Videos</span>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
</Menu.Item>
|
||||||
|
|
||||||
|
<Menu.Item key="3">
|
||||||
|
<Link href="/backup">
|
||||||
|
<div>
|
||||||
|
<UploadOutlined />
|
||||||
|
<span className="nav-text">Backup</span>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
</Menu.Item>
|
||||||
|
|
||||||
|
<Menu.Item key="4">
|
||||||
|
<Link href="/analytics">
|
||||||
|
<div>
|
||||||
|
<BarChartOutlined />
|
||||||
|
<span className="nav-text">Analytics</span>
|
||||||
|
</div>
|
||||||
|
</Link>
|
||||||
|
</Menu.Item>
|
||||||
|
|
||||||
|
<Menu.Item key="5">
|
||||||
|
<CloudOutlined />
|
||||||
|
<span className="nav-text">Cloud</span>
|
||||||
|
</Menu.Item>
|
||||||
|
|
||||||
|
<Menu.Item key="6">
|
||||||
|
<AppstoreOutlined />
|
||||||
|
<span className="nav-text">Apps</span>
|
||||||
|
</Menu.Item>
|
||||||
|
|
||||||
|
<Menu.Item key="7">
|
||||||
|
<TeamOutlined />
|
||||||
|
<span className="nav-text">Collaborate</span>
|
||||||
|
</Menu.Item>
|
||||||
|
|
||||||
|
<Menu.Item key="8">
|
||||||
|
<ShopOutlined />
|
||||||
|
<span className="nav-text">Shop</span>
|
||||||
|
</Menu.Item>
|
||||||
|
</Menu>
|
||||||
|
</Sider>
|
||||||
|
<Layout className="site-layout">
|
||||||
|
<Header
|
||||||
|
className={"site-layout-sub-header-background"}
|
||||||
|
style={{ padding: 0 }}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="logo"
|
||||||
|
style={{
|
||||||
|
height: 64,
|
||||||
|
color: "white",
|
||||||
|
textAlign: "center"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
Main Logo
|
||||||
|
</div>
|
||||||
|
</Header>
|
||||||
|
<Content // you may want to change these
|
||||||
|
style={{
|
||||||
|
...contentStyleWidth,
|
||||||
|
margin: "24px 16px 0",
|
||||||
|
overflow: "initial"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
className="site-layout-background"
|
||||||
|
style={{
|
||||||
|
padding: 24,
|
||||||
|
textAlign: "center",
|
||||||
|
minHeight: "calc(100vh - 158px)"
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{props.children}
|
||||||
|
</div>
|
||||||
|
</Content>
|
||||||
|
<Footer style={{ ...contentStyleWidth, textAlign: "center" }}>
|
||||||
|
Footer Text
|
||||||
|
{/* <p>
|
||||||
|
width: {window.width}, height: {window.height}
|
||||||
|
</p> */}
|
||||||
|
</Footer>
|
||||||
|
</Layout>
|
||||||
|
</Layout>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default AppLayout;
|
@ -0,0 +1,2 @@
|
|||||||
|
/// <reference types="next" />
|
||||||
|
/// <reference types="next/types/global" />
|
@ -0,0 +1,40 @@
|
|||||||
|
/* eslint-disable */
|
||||||
|
const withLess = require('@zeit/next-less')
|
||||||
|
const lessToJS = require('less-vars-to-js')
|
||||||
|
const fs = require('fs')
|
||||||
|
const path = require('path')
|
||||||
|
|
||||||
|
// Where your antd-custom.less file lives
|
||||||
|
const themeVariables = lessToJS(
|
||||||
|
fs.readFileSync(path.resolve(__dirname, './styles/antd-override.less'), 'utf8')
|
||||||
|
)
|
||||||
|
|
||||||
|
module.exports = withLess({
|
||||||
|
lessLoaderOptions: {
|
||||||
|
javascriptEnabled: true,
|
||||||
|
modifyVars: themeVariables, // make your antd custom effective
|
||||||
|
},
|
||||||
|
webpack: (config, { isServer }) => {
|
||||||
|
if (isServer) {
|
||||||
|
const antStyles = /antd\/.*?\/style.*?/
|
||||||
|
const origExternals = [...config.externals]
|
||||||
|
config.externals = [
|
||||||
|
(context, request, callback) => {
|
||||||
|
if (request.match(antStyles)) return callback()
|
||||||
|
if (typeof origExternals[0] === 'function') {
|
||||||
|
origExternals[0](context, request, callback)
|
||||||
|
} else {
|
||||||
|
callback()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
...(typeof origExternals[0] === 'function' ? [] : origExternals),
|
||||||
|
]
|
||||||
|
|
||||||
|
config.module.rules.unshift({
|
||||||
|
test: antStyles,
|
||||||
|
use: 'null-loader',
|
||||||
|
})
|
||||||
|
}
|
||||||
|
return config
|
||||||
|
},
|
||||||
|
})
|
@ -0,0 +1,27 @@
|
|||||||
|
{
|
||||||
|
"name": "next-with-ant-design-less",
|
||||||
|
"version": "1.0.0",
|
||||||
|
"scripts": {
|
||||||
|
"dev": "next",
|
||||||
|
"build": "next build",
|
||||||
|
"start": "next start"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@react-hook/window-size": "^1.0.13",
|
||||||
|
"@zeit/next-less": "^1.0.1",
|
||||||
|
"antd": "4.6.5",
|
||||||
|
"babel-plugin-import": "^1.13.0",
|
||||||
|
"less": "3.11.1",
|
||||||
|
"less-vars-to-js": "1.3.0",
|
||||||
|
"next": "9.5.3",
|
||||||
|
"null-loader": "3.0.0",
|
||||||
|
"react": "^16.13.1",
|
||||||
|
"react-dom": "^16.13.1"
|
||||||
|
},
|
||||||
|
"license": "ISC",
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^14.11.1",
|
||||||
|
"@types/react": "^16.9.49",
|
||||||
|
"typescript": "^4.0.3"
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,13 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
import AppLayout from "../components/AppLayout";
|
||||||
|
|
||||||
|
const analytics = props => {
|
||||||
|
return (
|
||||||
|
<AppLayout>
|
||||||
|
<div>Analytics Page</div>
|
||||||
|
</AppLayout>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default analytics;
|
@ -0,0 +1,13 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
import AppLayout from "../components/AppLayout";
|
||||||
|
|
||||||
|
const backup = props => {
|
||||||
|
return (
|
||||||
|
<AppLayout>
|
||||||
|
<div>Backup Page</div>
|
||||||
|
</AppLayout>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default backup;
|
@ -0,0 +1,3 @@
|
|||||||
|
.main-card {
|
||||||
|
margin-left: 100px
|
||||||
|
}
|
@ -0,0 +1,73 @@
|
|||||||
|
// core
|
||||||
|
import React from "react";
|
||||||
|
// antd
|
||||||
|
import { Typography, Divider, Button, Card } from "antd";
|
||||||
|
const { Title, Text } = Typography;
|
||||||
|
// components
|
||||||
|
import AppLayout from "../components/AppLayout";
|
||||||
|
import { T } from "antd/lib/upload/utils";
|
||||||
|
import './index.less'
|
||||||
|
|
||||||
|
const App = () => (
|
||||||
|
<AppLayout>
|
||||||
|
<div>Home Page</div>
|
||||||
|
<Title>Nextjs with Ant Design & Less</Title>
|
||||||
|
<Text>
|
||||||
|
Go ahead and edit <code>/pages/index.js</code>, and see your changes here
|
||||||
|
</Text>
|
||||||
|
<Divider />
|
||||||
|
<Title level={2}>Useful Links</Title>
|
||||||
|
<Button
|
||||||
|
href="https://nextjs.org/learn/basics/getting-started"
|
||||||
|
target="__blank"
|
||||||
|
>
|
||||||
|
Next.js Learn
|
||||||
|
</Button>
|
||||||
|
<Button href="https://nextjs.org/docs/getting-started" target="__blank">
|
||||||
|
Next.js Docs
|
||||||
|
</Button>
|
||||||
|
<Button href="https://ant.design/components/button/" target="__blank">
|
||||||
|
antd Docs
|
||||||
|
</Button>
|
||||||
|
|
||||||
|
<Divider />
|
||||||
|
<div style={{ textAlign: "start" }}>
|
||||||
|
<Card className="main-card">
|
||||||
|
<Title level={2}>Quick Recap:</Title>
|
||||||
|
<Title level={4}>Shared App Layout</Title>
|
||||||
|
<Text>
|
||||||
|
Shared/Common App Layout is located at{" "}
|
||||||
|
<code>/components/AppLayout</code>
|
||||||
|
</Text>
|
||||||
|
<br />
|
||||||
|
<Text>Sider/sidebar, header and footer are all in this file.</Text>
|
||||||
|
|
||||||
|
<br />
|
||||||
|
<br />
|
||||||
|
|
||||||
|
<Title level={4}>antd Less</Title>
|
||||||
|
<Text>
|
||||||
|
antd's Less file is present at <code>/assets/antd-custom.less</code>
|
||||||
|
</Text>
|
||||||
|
<br />
|
||||||
|
<Text>
|
||||||
|
Head over to{" "}
|
||||||
|
<a
|
||||||
|
href="https://github.com/ant-design/ant-design/blob/master/components/style/themes/default.less"
|
||||||
|
target="__blank"
|
||||||
|
>
|
||||||
|
antd's theming docs
|
||||||
|
</a>{" "}
|
||||||
|
for a list of less variables.
|
||||||
|
</Text>
|
||||||
|
<br />
|
||||||
|
<Text>
|
||||||
|
If you dont wish to mess around with Less, just delete everything in
|
||||||
|
the less file.
|
||||||
|
</Text>
|
||||||
|
</Card>
|
||||||
|
</div>
|
||||||
|
</AppLayout>
|
||||||
|
);
|
||||||
|
|
||||||
|
export default App;
|
@ -0,0 +1,15 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
import AppLayout from "../components/AppLayout";
|
||||||
|
|
||||||
|
import { Switch } from "antd";
|
||||||
|
|
||||||
|
const profile = props => {
|
||||||
|
return (
|
||||||
|
<AppLayout>
|
||||||
|
<div>Profile Page</div>
|
||||||
|
</AppLayout>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default profile;
|
@ -0,0 +1,13 @@
|
|||||||
|
import React from "react";
|
||||||
|
|
||||||
|
import AppLayout from "../components/AppLayout";
|
||||||
|
|
||||||
|
const videos = props => {
|
||||||
|
return (
|
||||||
|
<AppLayout>
|
||||||
|
<div>Videos Page</div>
|
||||||
|
</AppLayout>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default videos;
|
After Width: | Height: | Size: 15 KiB |
After Width: | Height: | Size: 1.1 KiB |
@ -0,0 +1,5 @@
|
|||||||
|
@import "../color/colors";
|
||||||
|
|
||||||
|
@primary-color: #1da57a;
|
||||||
|
|
||||||
|
@layout-header-height: 64px;
|
@ -0,0 +1,29 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"target": "es5",
|
||||||
|
"lib": [
|
||||||
|
"dom",
|
||||||
|
"dom.iterable",
|
||||||
|
"esnext"
|
||||||
|
],
|
||||||
|
"allowJs": true,
|
||||||
|
"skipLibCheck": true,
|
||||||
|
"strict": false,
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"noEmit": true,
|
||||||
|
"esModuleInterop": true,
|
||||||
|
"module": "esnext",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"resolveJsonModule": true,
|
||||||
|
"isolatedModules": true,
|
||||||
|
"jsx": "preserve"
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"next-env.d.ts",
|
||||||
|
"**/*.ts",
|
||||||
|
"**/*.tsx"
|
||||||
|
],
|
||||||
|
"exclude": [
|
||||||
|
"node_modules"
|
||||||
|
]
|
||||||
|
}
|
Loading…
Reference in new issue