Browse Source

Login & Register Pages

master
Nuno Martinho 5 years ago
parent
commit
93ba1053e5
9 changed files with 229 additions and 338 deletions
  1. BIN
      dbs/myapp.mv.db
  2. +30
    -41
      website/src/App.js
  3. +3
    -297
      website/src/App.less
  4. +81
    -0
      website/src/pages/Login/index.js
  5. +3
    -0
      website/src/pages/Login/index.less
  6. +112
    -0
      website/src/pages/Register/index.js
  7. +0
    -0
      website/src/pages/Register/index.less
  8. +0
    -0
      website/src/pages/dashboard/index.js
  9. +0
    -0
      website/src/pages/dashboard/index.less

BIN
dbs/myapp.mv.db View File


+ 30
- 41
website/src/App.js View File

@ -18,54 +18,43 @@ import {
} from "react-router-dom"; } from "react-router-dom";
import Home from './pages/Home'; import Home from './pages/Home';
import About from './pages/About';
import Login from './pages/Login';
import Register from './pages/Register';
import NotFound from './pages/NotFound'; import NotFound from './pages/NotFound';
const { Header, Content, Footer } = Layout; const { Header, Content, Footer } = Layout;
const { SubMenu } = Menu; const { SubMenu } = Menu;
function App() {
export default () => {
return ( return (
<Router> <Router>
<div className="page">
<Layout>
<Header style={{ position: 'fixed', zIndex: 1, width: '100%' }}>
<div className="logo" >
<Link to="/pt/">
<img src="/images/logo.svg" />
</Link>
</div>
<Menu mode="horizontal">
<Menu.Item key="home" icon={<HomeOutlined />}>
<Link to="/pt/">Home</Link>
</Menu.Item>
<Menu.Item key="about" icon={<ReadOutlined />}>
<Link to="/pt/about">About</Link>
</Menu.Item>
<Menu.Item key="login" >
<Button type="primary">Login</Button>
</Menu.Item>
</Menu>
</Header>
<Content>
<Switch>
<Route path="/pt/" exact={true} component={Home} />
<Route path="/pt/about" component={About} />
<Route path="*" component={NotFound} />
</Switch>
</Content>
<Footer>
<p>Copyright nuno kappa</p>
</Footer>
</Layout>
</div>
<Layout>
<Header>
<Menu mode="horizontal" theme="dark">
<Menu.Item><Link to="/">Home</Link></Menu.Item>
<Menu.Item><Link to="/login">Login</Link></Menu.Item>
<Menu.Item><Link to="/register">Register</Link></Menu.Item>
</Menu>
</Header>
<Content>
<Switch>
<Route path="/login">
<Login />
</Route>
<Route path="/register">
<Register />
</Route>
<Route path="/">
<Home />
</Route>
</Switch>
</Content>
<Footer>
<h2>Plataforma Social</h2>
Desenvolvimento de demonstração.
</Footer>
</Layout>
</Router> </Router>
); );
}
export default App;
};

+ 3
- 297
website/src/App.less View File

@ -1,298 +1,4 @@
@import '../node_modules/sal.js/dist/sal.css';
@import "./defaults.less";
html,
body {
background-color: @site-background;
font-family: @primaryFont;
}
.ant-layout {
padding-top: @header-size;
background-color: @page-background;
min-height: 100vh;
@media only screen and (max-width: @header-mobile-width) {
padding-top: @header-size-mobile;
}
}
.ant-layout-header {
padding: 0 calc((100% - @header-desktop-width) / 2);
position: fixed;
display: flex;
flex-direction: row;
z-index: 1000;
top: 0;
width: 100%;
height: @header-size;
line-height: @header-size;
background: transparent;
&:before {
background: @header-background;
content: "";
position: absolute;
left: 0;
top: 0;
z-index: 2;
width: 100%;
height: 100%;
}
&:after {
width: 100%;
height: 20px;
content: "";
position: absolute;
z-index: 1;
left: 0;
bottom: 0;
box-shadow: 0 0px 10px 7px rgba(0, 0, 0, 0.35);
border-radius: 50%;
}
>*:not(.menu-burger-open) {
z-index: 3;
}
&.header-burger-open .menu {
z-index: 0;
}
.logo {
padding: 0 10px;
display: block;
width: @logo-width;
height: auto;
a {
img {
width: auto;
height: 50px;
}
}
@media only screen and (max-width: @header-mobile-width) {
width: 55%;
max-width: 400px;
}
}
.menu-languages {
line-height: @header-line-height;
background-color: transparent;
color: @header-menu-color;
border-bottom: none;
display: flex;
.ant-menu-submenu-title:hover {
color: @header-menu-color-hover !important;
}
li {
margin-bottom: 20px !important;
display: inline;
&:hover {
border-color: @header-menu-color-hover !important;
}
}
}
.menu {
display: flex;
width: 100%;
line-height: @header-line-height;
@media only screen and (max-width: @header-mobile-width) {
display: none;
}
ul {
background-color: transparent;
margin-left: auto;
border-bottom: none;
border-right: none;
li {
display: inline;
&:hover {
a {
color: @header-menu-color-hover;
}
border-color: @header-menu-color-hover !important;
}
a {
color: @header-menu-color;
font-size: 1.2em;
}
&.ant-menu-submenu-horizontal::after {
content: '>';
color: rgba(0, 0, 0, 0.65);
transform: rotate(90deg);
position: absolute;
right: -20px;
top: 2px;
font-weight: 600;
}
}
}
&-languages {
margin-left: 0 !important;
@media screen and (max-width: @header-mobile-width) {
margin-right: 85px;
margin-left: auto !important;
}
}
}
.menu-burger-button {
position: absolute;
width: auto;
height: auto;
top: 18px;
right: calc(@header-size / 4);
@media only screen and (min-width: @header-mobile-width) {
display: none;
}
.burger {
height: calc(@header-size-mobile / 2);
}
}
.menu-burger {
@media only screen and (min-width: @header-mobile-width) {
display: none;
}
}
}
.ant-menu-sub,
.ant-menu-submenu-popup {
border-radius: 2px !important;
}
.header-burger-open {
.menu {
display: block;
position: fixed;
width: 100%;
height: calc(100% - @header-size);
top: @header-size;
left: 0;
right: 0;
z-index: 9998;
background-color: @mobile-menu-background;
padding: @mobile-menu-padding-vertical @mobile-menu-padding-horizontal;
overflow: auto;
margin-top: 0;
@media only screen and (max-width: @header-mobile-width) {
height: calc(100% - @header-size-mobile);
top: @header-size-mobile;
}
}
}
.burger .burger-lines,
.burger .burger-lines:after,
.burger .burger-lines:before {
background-color: @header-menu-color;
}
.ant-layout-content {
background-color: @page-background;
z-index: 2;
}
.ant-layout-footer {
z-index: 1;
width: 100%;
padding: 40px 0 20px;
box-shadow: 0 1px 3px 0 rgba(0, 0, 0, .2),
0 1px 1px 0 rgba(0, 0, 0, .14),
0 2px 1px -1px rgba(0, 0, 0, .12);
background: @footer-background;
@media only screen and (max-width: 800px) {
text-align: center;
padding: 30px 0 10px;
}
h1 {
color: @footer-color;
font-size: 25px;
padding: 0 10px;
margin: 0 calc((100% - 1200px) / 2);
@media only screen and (max-width: 800px) {
width: 100%;
margin: 0 auto;
font-size: 20px;
}
}
.line {
height: 20px;
opacity: .5;
border: 0;
border-radius: 50%;
border-bottom: 2px solid @primary-color;
width: 100%;
}
.links-bar,
.copyright {
padding: 0 10px;
display: inline-block;
width: 50%;
font-size: .875em;
a {
color: @footer-color;
text-decoration: underline;
}
@media screen and (min-width: 1200px) {
width: calc(50% - calc((100% - 1200px) / 2));
}
@media only screen and (max-width: 800px) {
display: block;
width: 100%;
margin: 20px auto !important;
font-size: 12px;
text-align: center;
}
}
.links-bar {
margin: 20px auto;
@media screen and (min-width: 1200px) {
margin-left: calc((100% - 1200px) / 2);
}
}
.copyright {
color: @footer-color;
text-align: right;
@media screen and (min-width: 1200px) {
margin-right: calc((100% - 1200px) / 2);
}
}
main {
padding: 50px;
min-height: calc(100vh - 150px) !important;
} }

+ 81
- 0
website/src/pages/Login/index.js View File

@ -0,0 +1,81 @@
import React, { useState, useEffect } from "react";
import { Form, Input, Button, Checkbox } from 'antd';
import { UserOutlined, LockOutlined } from '@ant-design/icons';
import './index.less';
const layout = {
labelCol: { span: 8 },
wrapperCol: { span: 16 },
};
const tailLayout = {
wrapperCol: { offset: 8, span: 16 },
};
export default () => {
const onFinish = (values) => {
console.log('Received values of form: ', values);
};
return (
<div>
<h1>Login</h1>
<div className="login">
<Form
name="normal_login"
className="login-form"
initialValues={{
remember: true,
}}
onFinish={onFinish}
>
<Form.Item
name="username"
rules={[
{
required: true,
message: 'Please input your Username!',
},
]}
>
<Input prefix={<UserOutlined className="site-form-item-icon" />} placeholder="Username" />
</Form.Item>
<Form.Item
name="password"
rules={[
{
required: true,
message: 'Please input your Password!',
},
]}
>
<Input.Password
prefix={<LockOutlined className="site-form-item-icon" />}
type="password"
placeholder="Password"
/>
</Form.Item>
<Form.Item>
<Form.Item name="remember" valuePropName="checked" noStyle>
<Checkbox>Remember me</Checkbox>
</Form.Item>
<a className="login-form-forgot" href="">
Forgot password
</a>
</Form.Item>
<Form.Item>
<Button type="primary" htmlType="submit" className="login-form-button">
Log in
</Button>
Or <a href="">register now!</a>
</Form.Item>
</Form>
</div>
</div>
);
};

+ 3
- 0
website/src/pages/Login/index.less View File

@ -0,0 +1,3 @@
.login {
max-width: 400px;
}

+ 112
- 0
website/src/pages/Register/index.js View File

@ -0,0 +1,112 @@
import { Form, Input, InputNumber, Button } from 'antd';
const layout = {
labelCol: {
span: 8,
},
wrapperCol: {
span: 16,
},
};
/* eslint-disable no-template-curly-in-string */
const validateMessages = {
required: '${label} is required!',
types: {
email: '${label} is not a valid email!',
number: '${label} is not a valid number!',
},
number: {
range: '${label} must be between ${min} and ${max}',
},
};
export default () => {
const onFinish = (values) => {
console.log(values);
};
return (
<div>
<div className="register">
<Form {...layout} name="nest-messages" onFinish={onFinish} validateMessages={validateMessages}>
<Form.Item
name="name"
label="Name"
rules={[
{
required: true,
},
]}
>
<Input />
</Form.Item>
<Form.Item
name="username"
label="Username"
rules={[
{
required: true,
},
]}
>
<Input />
</Form.Item>
<Form.Item
name="email"
label="Email"
rules={[
{ type: 'email', message: 'Invalid email.' },
{ required: true, message: 'Please input your email.' },
]}
>
<Input />
</Form.Item>
<Form.Item
name="password"
label="Password"
rules={[
{
required: true,
message: 'Please input your password!',
},
]}
hasFeedback
>
<Input.Password />
</Form.Item>
<Form.Item
name="confirm"
label="Confirm Password"
dependencies={['password']}
hasFeedback
rules={[
{
required: true,
message: 'Please confirm your password!',
},
({ getFieldValue }) => ({
validator(_, value) {
if (!value || getFieldValue('password') === value) {
return Promise.resolve();
}
return Promise.reject(new Error('The two passwords that you entered do not match!'));
},
}),
]}
>
<Input.Password />
</Form.Item>
<Form.Item wrapperCol={{ ...layout.wrapperCol, offset: 8 }}>
<Button type="primary" htmlType="submit">
Submit
</Button>
</Form.Item>
</Form>
</div>
</div>
);
}

+ 0
- 0
website/src/pages/Register/index.less View File


+ 0
- 0
website/src/pages/dashboard/index.js View File


+ 0
- 0
website/src/pages/dashboard/index.less View File


Loading…
Cancel
Save