Skip to content

Commit

Permalink
최상단 메뉴 라우트 로직 추가 및 로그인 폼 적용
Browse files Browse the repository at this point in the history
  • Loading branch information
gongdongho12 committed Jul 15, 2020
1 parent 3c9bbd8 commit d0f02a4
Show file tree
Hide file tree
Showing 16 changed files with 156 additions and 21 deletions.
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
"react": "^16.13.1",
"react-dom": "^16.13.1",
"react-intl": "^5.0.2",
"react-router": "^5.2.0",
"react-router-dom": "^5.2.0",
"react-scripts": "3.4.1",
"recoil": "0.0.10",
Expand Down
22 changes: 18 additions & 4 deletions src/CommonRouter.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,31 @@
import React, { Suspense, lazy, FunctionComponent } from 'react';
import { Route, Switch } from 'react-router-dom';
import { routerMeta } from 'meta';
import { assignRouteProps } from 'utils';

interface ICustomRotuerProps {
}

const Home = lazy(() => import('containers/Home'));
const About = lazy(() => import('containers/About'));
const lazyImport = (containerName: string) => lazy(() => import(`containers/${containerName}`));

interface AssignRoute {
component: any,
props: any
}

const assignRouter: AssignRoute[] = Object.keys(routerMeta).map((componentKey: string) => {
const props: any = assignRouteProps(routerMeta[componentKey])

return {
component: lazyImport(componentKey),
props
}
})

const CustomRotuer: FunctionComponent<ICustomRotuerProps> = (props) => {
return <Suspense fallback={<div>Loading...</div>}>
<Switch>
<Route exact path="/" component={Home}/>
<Route path="/about" component={About}/>
{assignRouter.map(({ component, props }) => <Route key={props.path} component={component} {...props} />)}
</Switch>
</Suspense>;
};
Expand Down
45 changes: 31 additions & 14 deletions src/components/DefaultLayout/DefaultLayout.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
import React, { FunctionComponent } from "react";

import React, { FunctionComponent, useEffect, useMemo } from "react";
import { Layout, Menu, Breadcrumb } from "antd";

import { useIntl } from "react-intl";
import { routerMeta } from 'meta';

import {
UserOutlined,
LaptopOutlined,
NotificationOutlined,
} from "@ant-design/icons";
import { Link } from "react-router-dom";
import { Link, useLocation } from "react-router-dom";
import LanguageSelector from "components/LanguageSelector";
import { assignRouteProps } from "utils";

const { SubMenu } = Menu;
const { Header, Content, Sider } = Layout;
Expand All @@ -27,9 +27,31 @@ const menuStyle = {
display: 'flex'
}

const defaultMenus = Object.keys(routerMeta).reduce((prev: any[], componentKey: string) => {
const { path } = assignRouteProps(routerMeta[componentKey])
const slashLength: number = (path.match(/\//gi) || []).length
if (slashLength === 1) {
return [ ...prev, { componentKey, path } ]
} else {
return prev
}
}, [])

const DefaultLayout: FunctionComponent<IDefaultLayoutProps> = (props) => {
const { children } = props;
const { formatMessage: fm } = useIntl();
const location = useLocation();

useEffect(() => {
console.log('location', location)
}, [location])

const pathDom = useMemo(() => {
const { pathname } = location
const pathArray = pathname.split('/')
const emptyToSpace = (text: string) => text === '' ? ' ' : text
return pathArray.map(path => <Breadcrumb.Item key={path}>{emptyToSpace(path)}</Breadcrumb.Item>)
}, [location])

return (
<Layout style={defaultStyle}>
Expand All @@ -38,14 +60,11 @@ const DefaultLayout: FunctionComponent<IDefaultLayoutProps> = (props) => {
{fm({ id: "title" })}
</div>
<Menu theme="dark" mode="horizontal" style={menuStyle} defaultSelectedKeys={["1"]}>
<Menu.Item key="1">
<Link to="/">Home</Link>
</Menu.Item>
<Menu.Item key="2">
<Link to="/about">About</Link>
</Menu.Item>
{defaultMenus.map(({ componentKey, path }) => <Menu.Item key={componentKey}>
<Link to={path}>{componentKey}</Link>
</Menu.Item>)}

<Menu.Item key="3" disabled style={{ opacity: 1, marginLeft: 'auto' }}>
<Menu.Item key="language-selector" disabled style={{ opacity: 1, marginLeft: 'auto' }}>
<LanguageSelector />
</Menu.Item>
</Menu>
Expand Down Expand Up @@ -84,9 +103,7 @@ const DefaultLayout: FunctionComponent<IDefaultLayoutProps> = (props) => {
</Sider>
<Layout style={{ padding: "0 24px 24px" }}>
<Breadcrumb style={{ margin: "16px 0" }}>
<Breadcrumb.Item>Home</Breadcrumb.Item>
<Breadcrumb.Item>List</Breadcrumb.Item>
<Breadcrumb.Item>App</Breadcrumb.Item>
{pathDom}
</Breadcrumb>
<Content
className="site-layout-background"
Expand Down
2 changes: 1 addition & 1 deletion src/components/LanguageSelector/LanguageSelector.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ const LanguageSelector: FunctionComponent = () => {

const dom = useMemo<ReactElement[]>(() => {
const languages: Lang[] = Object.keys(messages) as Lang[]
return languages.map((lang: Lang) => <Option value={lang}>{fm({ id: lang })}</Option>)
return languages.map((lang: Lang) => <Option key={lang} value={lang}>{fm({ id: lang })}</Option>)
}, [fm])

return <Select
Expand Down
62 changes: 62 additions & 0 deletions src/components/LoginForm/LoginForm.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import React, { FunctionComponent, useCallback } from "react";

import { Form, Input, Button, Checkbox } from "antd";

interface ILoginFormProps {}

const layout = {
labelCol: { span: 6 },
wrapperCol: { span: 18 },
};

const tailLayout = {
wrapperCol: { offset: 6, span: 18 },
};

const LoginForm: FunctionComponent<ILoginFormProps> = (props) => {
const onFinish = useCallback((values: any) => {
console.log("Success:", values);
}, []);

const onFinishFailed = useCallback((errorInfo: any) => {
console.log("Failed:", errorInfo);
}, []);

return (
<Form
{...layout}
name="basic"
initialValues={{ remember: true }}
onFinish={onFinish}
onFinishFailed={onFinishFailed}
>
<Form.Item
label="Username"
name="username"
rules={[{ required: true, message: "Please input your username!" }]}
>
<Input />
</Form.Item>

<Form.Item
label="Password"
name="password"
rules={[{ required: true, message: "Please input your password!" }]}
>
<Input.Password />
</Form.Item>

<Form.Item {...tailLayout} name="remember" valuePropName="checked">
<Checkbox>Remember me</Checkbox>
</Form.Item>

<Form.Item {...tailLayout}>
<Button type="primary" htmlType="submit">
Submit
</Button>
</Form.Item>
</Form>
);
};

export default LoginForm;
2 changes: 2 additions & 0 deletions src/components/LoginForm/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import LoginForm from './LoginForm'
export default LoginForm
11 changes: 11 additions & 0 deletions src/containers/Login/Login.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import React, { FunctionComponent } from 'react';
import LoginForm from 'components/LoginForm';

interface ILoginProps {
}

const Login: FunctionComponent<ILoginProps> = (props) => {
return <LoginForm />;
};

export default Login;
2 changes: 2 additions & 0 deletions src/containers/Login/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import Login from './Login'
export default Login
1 change: 1 addition & 0 deletions src/meta/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default as routerMeta } from './routerMeta'
11 changes: 11 additions & 0 deletions src/meta/routerMeta.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { RouteProps } from "react-router"

export type RouterMetaType = { [key: string] : (string | Omit<RouteProps, 'component'>) }

const routerMeta: RouterMetaType = {
Home: { path: '/', exact: true },
About: '/about',
Login: '/login'
}

export default routerMeta
3 changes: 3 additions & 0 deletions src/utils/assignRouteProps/assignRouteProps.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const assignRouteProps = (props: any) => typeof props === 'object' ? props : ({ path: props })

export default assignRouteProps
2 changes: 2 additions & 0 deletions src/utils/assignRouteProps/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import assignRouteProps from './assignRouteProps'
export default assignRouteProps
2 changes: 2 additions & 0 deletions src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export { default as assignRouteProps } from './assignRouteProps'
export { default as range } from './range'
2 changes: 2 additions & 0 deletions src/utils/range/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import range from './range'
export default range
5 changes: 5 additions & 0 deletions src/utils/range/range.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const range = (x: number, y: number) => Array.from((function *() {
while (x <= y) yield x++;
})());

export default range
4 changes: 3 additions & 1 deletion tsconfig.paths.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,9 @@
"meta/*": ["meta/*"],
"state/*": ["state/*"],
"locale/*": ["locale/*"],
"interface/*": ["interface/*"]
"interface/*": ["interface/*"],
"utils/*": ["utils/*"],
"utils": ["utils"]
}
}
}

0 comments on commit d0f02a4

Please sign in to comment.