Browse Source

Registo e login.

master
eduveks 5 years ago
parent
commit
0543a55654
20 changed files with 449 additions and 144 deletions
  1. +8
    -1
      config/_development.json
  2. BIN
      dbs/social_ests.mv.db
  3. +7
    -0
      server/services/cities/get.js
  4. +1
    -0
      server/services/cities/options.js
  5. +1
    -0
      server/services/register.options.js
  6. +56
    -0
      server/services/register.post.js
  7. +5
    -0
      server/setup/_end.js
  8. +24
    -24
      server/setup/_schema-form-3-pessoa.js
  9. +1
    -0
      website/package.json
  10. +0
    -38
      website/src/App.css
  11. +48
    -81
      website/src/App.js
  12. +5
    -0
      website/src/App.less
  13. +9
    -0
      website/src/pages/Home/index.js
  14. +0
    -0
      website/src/pages/Home/index.less
  15. +94
    -0
      website/src/pages/Login/index.js
  16. +4
    -0
      website/src/pages/Login/index.less
  17. +24
    -0
      website/src/pages/Main/index.js
  18. +0
    -0
      website/src/pages/Main/index.less
  19. +158
    -0
      website/src/pages/Register/index.js
  20. +4
    -0
      website/src/pages/Register/index.less

+ 8
- 1
config/_development.json View File

@ -42,5 +42,12 @@
"enabled": true,
"origins": [ "http://eduardo-velasques.dev.netuno.org:10030" ]
}
]
],
"jwt": {
"enabled": true,
"secret": "NN,NvyQTB!ZMHc7*",
"access_expires": 60,
"refresh_expires": 1440,
"algorithm": "HS512"
}
}

BIN
dbs/social_ests.mv.db View File


+ 7
- 0
server/services/cities/get.js View File

@ -0,0 +1,7 @@
_out.json(
_db.query(
`
SELECT uid, nome as name FROM cidade
`
)
)

+ 1
- 0
server/services/cities/options.js View File

@ -0,0 +1 @@
_out.json(_val.map().set("result", true))

+ 1
- 0
server/services/register.options.js View File

@ -0,0 +1 @@
_out.json(_val.map().set("result", true))

+ 56
- 0
server/services/register.post.js View File

@ -0,0 +1,56 @@
const name = _req.getString("name")
const surname = _req.getString("surname")
const cityUid = _req.getString("city_uid")
const email = _req.getString("email")
const username = _req.getString("username")
const password = _req.getString("password")
const dbCidade = _db.get("cidade", cityUid)
const emailExists = _user.firstByMail(email)
const usernameExists = _user.firstByUser(username)
if (dbCidade == null) {
_header.status(409)
_out.json(
_val.map()
.set("error", true)
.set("message", "city-not-found")
)
} else if (emailExists != null) {
_header.status(409)
_out.json(
_val.map()
.set("error", true)
.set("message", "email-exists")
)
} else if (usernameExists != null) {
_header.status(409)
_out.json(
_val.map()
.set("error", true)
.set("message", "user-exists")
)
} else {
const group = _group.firstByCode("user")
const user_id = _user.create(
_val.map()
.set("name", `${name} ${surname}`)
.set("mail", email)
.set("user", username)
.set("pass", password)
.set("group_id", group.getInt("id"))
)
_db.insert(
'pessoa',
_val.map()
.set("nome", name)
.set("apelido", surname)
.set("email", email)
.set("utilizador_id", user_id)
.set("cidade_id", dbCidade.getInt("id"))
)
_log.info("Novo utilizador criado com o id: "+ user_id)
_out.json(_val.map().set("result", true))
}

+ 5
- 0
server/setup/_end.js View File

@ -0,0 +1,5 @@
_group.createIfNotExists(
_val.map()
.set("name", "Utilizador Genérico")
.set("code", "user")
)

+ 24
- 24
server/setup/_schema-form-3-pessoa.js View File

@ -89,51 +89,51 @@ _form.createComponentIfNotExists(
"83b4bbd5-a9cb-40a4-9769-13c03029462f",
_val.init()
.set("colspan", 0)
.set("displayname", "Comunidades")
.set("displayname", "E-mail")
.set("firebase", "")
.set("group_id", 0)
.set("height", 0)
.set("max", 0)
.set("min", 0)
.set("name", "comunidades")
.set("notnull", false)
.set("primarykey", false)
.set("properties", "{\"ITEM_SEPARATOR\":{\"default\":\" # \",\"type\":\"STRING\",\"value\":\" # \"},\"MAX_COLUMN_LENGTH\":{\"default\":\"0\",\"type\":\"INTEGER\",\"value\":\"0\"},\"COLUMN_SEPARATOR\":{\"default\":\" - \",\"type\":\"LINK_SEPARATOR\",\"value\":\" - \"},\"REFERENCE\":{\"default\":\"\",\"type\":\"LINK\",\"value\":\"pessoa_comunidade:pessoa_id\"},\"LINK\":{\"default\":\"\",\"type\":\"LINK\",\"value\":\"pessoa_comunidade:comunidade_id\"},\"SERVICE\":{\"default\":\"com/MultiSelect.netuno\",\"type\":\"STRING\",\"value\":\"com/MultiSelect.netuno\"},\"ONLY_ACTIVES\":{\"default\":\"false\",\"type\":\"BOOLEAN\",\"value\":\"false\"}}")
.set("name", "email")
.set("notnull", true)
.set("primarykey", true)
.set("properties", "{}")
.set("rowspan", 0)
.set("tdheight", 0)
.set("tdwidth", 0)
.set("type", "multiselect")
.set("uid", "f3c9f8ef-154a-49e8-b209-cfee9694fb51")
.set("type", "email")
.set("uid", "e99477e6-1a12-4d75-a334-13aeb222eda7")
.set("user_id", 0)
.set("whenedit", true)
.set("whenexport", true)
.set("whenfilter", false)
.set("whenfilter", true)
.set("whennew", true)
.set("whenresult", false)
.set("whenresult", true)
.set("whenview", true)
.set("width", 0)
.set("x", 1)
.set("y", 5)
.set("y", 4)
)
_form.createComponentIfNotExists(
"83b4bbd5-a9cb-40a4-9769-13c03029462f",
_val.init()
.set("colspan", 0)
.set("displayname", "E-mail")
.set("displayname", "Nome")
.set("firebase", "")
.set("group_id", 0)
.set("height", 0)
.set("max", 0)
.set("min", 0)
.set("name", "email")
.set("name", "nome")
.set("notnull", true)
.set("primarykey", true)
.set("properties", "{}")
.set("primarykey", false)
.set("properties", "{\"MASK_REVERSE\":{\"default\":\"false\",\"type\":\"BOOLEAN\",\"value\":\"false\"},\"MASK_SELECTONFOCUS\":{\"default\":\"false\",\"type\":\"BOOLEAN\",\"value\":\"false\"},\"MASK\":{\"default\":\"\",\"type\":\"STRING\",\"value\":\"\"}}")
.set("rowspan", 0)
.set("tdheight", 0)
.set("tdwidth", 0)
.set("type", "email")
.set("uid", "e99477e6-1a12-4d75-a334-13aeb222eda7")
.set("type", "text")
.set("uid", "e38af13b-db5a-4eab-8bfa-05de641f1f5b")
.set("user_id", 0)
.set("whenedit", true)
.set("whenexport", true)
@ -143,27 +143,27 @@ _form.createComponentIfNotExists(
.set("whenview", true)
.set("width", 0)
.set("x", 1)
.set("y", 4)
.set("y", 1)
)
_form.createComponentIfNotExists(
"83b4bbd5-a9cb-40a4-9769-13c03029462f",
_val.init()
.set("colspan", 0)
.set("displayname", "Nome")
.set("displayname", "Utilizador")
.set("firebase", "")
.set("group_id", 0)
.set("height", 0)
.set("max", 0)
.set("min", 0)
.set("name", "nome")
.set("notnull", true)
.set("name", "utilizador_id")
.set("notnull", false)
.set("primarykey", false)
.set("properties", "{\"MASK_REVERSE\":{\"default\":\"false\",\"type\":\"BOOLEAN\",\"value\":\"false\"},\"MASK_SELECTONFOCUS\":{\"default\":\"false\",\"type\":\"BOOLEAN\",\"value\":\"false\"},\"MASK\":{\"default\":\"\",\"type\":\"STRING\",\"value\":\"\"}}")
.set("properties", "{\"ALLOW_USER_LOGGED\":{\"default\":\"false\",\"type\":\"BOOLEAN\",\"value\":\"false\"},\"GROUPS\":{\"default\":\"\",\"type\":\"STRING\",\"value\":\"\"},\"GROUPS_MODE\":{\"default\":\"all|exclude|only\",\"type\":\"CHOICE\",\"value\":\"all\"},\"USERS_MODE\":{\"default\":\"all|exclude|only\",\"type\":\"CHOICE\",\"value\":\"all\"},\"USERS\":{\"default\":\"\",\"type\":\"STRING\",\"value\":\"\"}}")
.set("rowspan", 0)
.set("tdheight", 0)
.set("tdwidth", 0)
.set("type", "text")
.set("uid", "e38af13b-db5a-4eab-8bfa-05de641f1f5b")
.set("type", "user")
.set("uid", "86e1c717-56ac-45a9-bfcd-502a81ab2de9")
.set("user_id", 0)
.set("whenedit", true)
.set("whenexport", true)
@ -173,5 +173,5 @@ _form.createComponentIfNotExists(
.set("whenview", true)
.set("width", 0)
.set("x", 1)
.set("y", 1)
.set("y", 6)
)

+ 1
- 0
website/package.json View File

@ -3,6 +3,7 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@netuno/auth-client": "^1.0.3",
"@netuno/service-client": "^1.0.7",
"@testing-library/jest-dom": "^5.11.10",
"@testing-library/react": "^11.2.5",


+ 0
- 38
website/src/App.css View File

@ -1,38 +0,0 @@
.App {
text-align: center;
}
.App-logo {
height: 40vmin;
pointer-events: none;
}
@media (prefers-reduced-motion: no-preference) {
.App-logo {
animation: App-logo-spin infinite 20s linear;
}
}
.App-header {
background-color: #282c34;
min-height: 100vh;
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
font-size: calc(10px + 2vmin);
color: white;
}
.App-link {
color: #61dafb;
}
@keyframes App-logo-spin {
from {
transform: rotate(0deg);
}
to {
transform: rotate(360deg);
}
}

+ 48
- 81
website/src/App.js View File

@ -1,20 +1,26 @@
import React, { useState, useEffect } from "react";
import _service from '@netuno/service-client';
import { Form, Input, Button, Checkbox } from 'antd';
import { Layout, Menu } from 'antd';
import {
BrowserRouter as Router,
Switch,
Route,
Link
} from "react-router-dom";
import Home from './pages/Home';
import Login from './pages/Login';
import Register from './pages/Register';
import Main from './pages/Main';
import logo from './logo.svg';
import './App.css';
import './App.less';
const layout = {
labelCol: { span: 8 },
wrapperCol: { span: 16 },
};
const tailLayout = {
wrapperCol: { offset: 8, span: 16 },
};
const { Header, Footer, Content } = Layout;
function App() {
export default () => {
const [ data, setData ] = useState([]);
useEffect(()=> {
_service({
@ -27,77 +33,38 @@ function App() {
}
});
}, []);
const onFinish = (values) => {
console.log('Success:', values);
};
const onFinishFailed = (errorInfo) => {
console.log('Failed:', errorInfo);
};
return (
<div className="App">
<header className="App-header">
<img src={logo} className="App-logo" alt="logo" />
<p>
Edit <code>src/App.js</code> and save to reload.
</p>
<a
className="App-link"
href="https://reactjs.org"
target="_blank"
rel="noopener noreferrer"
>
Learn React
</a>
{ JSON.stringify(data) }
</header>
<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>
</div>
<Router>
<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="/main">
<Main/>
</Route>
<Route path="/">
<Home/>
</Route>
</Switch>
</Content>
<Footer>
<h2>Plataforma Social</h2>
Desenvolvimento de demonstração.
</Footer>
</Layout>
</Router>
);
}
export default App;
};

+ 5
- 0
website/src/App.less View File

@ -0,0 +1,5 @@
main {
padding: 50px;
min-height: calc(100vh - 150px) !important;
}

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

@ -0,0 +1,9 @@
import React, { useState, useEffect } from "react";
export default () => {
return (
<div>
<h1>Home</h1>
</div>
);
};

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


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

@ -0,0 +1,94 @@
import React, { useState, useEffect } from "react";
import { Form, Input, Button, Checkbox } from 'antd';
import _auth from '@netuno/auth-client';
import { Redirect } from "react-router-dom";
import './index.less';
const layout = {
labelCol: { span: 8 },
wrapperCol: { span: 16 },
};
const tailLayout = {
wrapperCol: { offset: 8, span: 16 },
};
export default () => {
const [ loading, setLoading ] = useState(false);
const onFinish = (values) => {
setLoading(true);
_auth.login({
username: values.username,
password: values.password,
success: ()=> {
setLoading(false);
},
fail: ()=> {
alert("Fail.");
}
});
};
const onFinishFailed = (errorInfo) => {
console.log('Failed:', errorInfo);
};
if (_auth.isLogged()) {
return <Redirect to="/main"/>;
}
return (
<div>
<h1>Login</h1>
<div className="login">
<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>Relembrar o acesso.</Checkbox>
</Form.Item>
<Form.Item {...tailLayout}>
<Button type="primary" htmlType="submit" loading={loading}>
Entrar
</Button>
</Form.Item>
</Form>
</div>
</div>
);
};

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

@ -0,0 +1,4 @@
.login {
max-width: 600px;
}

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

@ -0,0 +1,24 @@
import React, { useState, useEffect } from "react";
import { Redirect } from "react-router-dom";
import { Button } from 'antd';
import _auth from '@netuno/auth-client';
export default () => {
const [ loading, setLoading ] = useState(false);
if (!_auth.isLogged()) {
return <Redirect to="/login"/>;
}
const onLogout = ()=> {
_auth.logout();
setLoading(true);
}
return (
<div>
<h1>Olá...</h1>
<Button onClick={onLogout} loading={loading}>Sair</Button>
</div>
);
};

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


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

@ -0,0 +1,158 @@
import React, { useState, useEffect } from "react";
import { Form, Input, Button, Select } from 'antd';
import _service from '@netuno/service-client';
import './index.less';
const layout = {
labelCol: { span: 8 },
wrapperCol: { span: 16 },
};
const tailLayout = {
wrapperCol: { offset: 8, span: 16 },
};
export default () => {
const [ loading, setLoading ] = useState(false);
const [ cities, setCities ] = useState([]);
useEffect(()=> {
_service({
url: 'cities',
success: (response) => {
setCities(response.json);
},
fail: (e) => {
console.log("Service Error", e);
}
})
}, []);
const onFinish = (values) => {
setLoading(true);
_service({
method: 'POST',
url: "register",
data: values,
success: (response) => {
setLoading(false);
},
fail: (e) => {
console.log("Service Error", e);
}
});
};
const onFinishFailed = (errorInfo) => {
console.log('Failed:', errorInfo);
};
return (
<div>
<h1>Register</h1>
<div className="register">
<Form
{...layout}
name="basic"
initialValues={{
remember: true,
}}
onFinish={onFinish}
onFinishFailed={onFinishFailed}
>
<Form.Item
label="Nome"
name="name"
rules={[
{
required: true,
message: 'Por favor preencha o seu nome.',
},
]}
>
<Input />
</Form.Item>
<Form.Item
label="Apelido"
name="surname"
rules={[
{
required: true,
message: 'Por favor preencha o seu apelido.',
},
]}
>
<Input />
</Form.Item>
<Form.Item
label="Cidade"
name="city_uid"
rules={[
{
required: true,
message: 'Por favor preencha a seu cidade.',
},
]}
>
<Select>
{
cities.map(({uid, name})=>
<Select.Option value={uid}>{name}</Select.Option>
)
}
</Select>
</Form.Item>
<Form.Item
label="E-mail"
name="email"
rules={[
{
type: 'email',
message: 'Preencha um e-mail válido.'
},
{
required: true,
message: 'Por favor preencha o seu e-mail.',
},
]}
>
<Input />
</Form.Item>
<Form.Item
label="Utilizador"
name="username"
rules={[
{
required: true,
message: 'Por favor preencha o seu utilizador.',
},
]}
>
<Input />
</Form.Item>
<Form.Item
label="Palavra-passe"
name="password"
rules={[
{
required: true,
message: 'Por favor preencha o seu palavra-passe.',
},
]}
>
<Input.Password />
</Form.Item>
<Form.Item {...tailLayout}>
<Button type="primary" htmlType="submit" loading={loading}>
Enviar
</Button>
</Form.Item>
</Form>
</div>
</div>
);
};

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

@ -0,0 +1,4 @@
.register {
max-width: 600px;
}

Loading…
Cancel
Save