Skip to content
This repository was archived by the owner on Jul 2, 2020. It is now read-only.

Commit 47cd9bd

Browse files
authored
Merge pull request #25 from eudangeld/master
Signup ok
2 parents 7d79517 + 212dd03 commit 47cd9bd

14 files changed

+280
-14
lines changed

Diff for: api/index.php

+4-1
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Multi;
44

55
use Firebase\JWT\JWT;
6+
67
use Firebase\JWT\SignatureInvalidException;
78
use GraphQL\Error\Debug;
89
use GraphQL\Error\FormattedError;
@@ -15,7 +16,7 @@
1516
use function Siler\Encoder\Json\decode;
1617
use function Siler\Functional\Monad\maybe;
1718
use function Siler\GraphQL\{debug, execute, schema};
18-
use function Siler\Swoole\{bearer, http, json, raw};
19+
use function Siler\Swoole\{bearer, http, json, raw,cors};
1920

2021
$base_dir = __DIR__;
2122
require_once "$base_dir/vendor/autoload.php";
@@ -54,7 +55,9 @@
5455
} catch (Throwable $exception) {
5556
Log\error($exception->getMessage());
5657
$result = FormattedError::createFromException($exception);
58+
5759
} finally {
60+
cors('*','authorization,content-type');
5861
json($result);
5962
}
6063
};

Diff for: package-lock.json

+3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: web/components/button.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import styled from "styled-components";
2-
import {darken} from "polished";
2+
import { darken } from "polished";
33

44
type Props = {
55
skin: string;

Diff for: web/components/column.tsx

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import styled from "styled-components";
2+
3+
export const Column = styled.div<{ space?: number }>`
4+
display: flex;
5+
flex-direction: column;
6+
7+
& > * {
8+
margin-bottom: ${({ space = 8 }) => space}px;
9+
10+
&:last-child {
11+
margin-bottom: 0;
12+
}
13+
}
14+
`;

Diff for: web/components/global-style.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import styled, {createGlobalStyle, css} from "styled-components";
1+
import styled, { createGlobalStyle, css } from "styled-components";
22

33
export type Theme = {
44
borderRadius: number;

Diff for: web/components/input.tsx

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import styled from "styled-components";
2+
import { darken } from "polished";
3+
4+
const Input = styled.input`
5+
padding: 0.5em;
6+
margin: 0.5em;
7+
8+
border: none;
9+
border-radius: 3px;
10+
`;
11+
12+
export default Input;

Diff for: web/pages/index.tsx

+4-6
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
import {NextPage} from "next";
1+
import { NextPage } from "next";
22
import React from "react";
33
import Link from "next/link";
44
import Button from "../components/button";
5-
import {Container, Section} from "../components/global-style";
5+
import { Container, Section } from "../components/global-style";
66
import Layout from "../components/layout";
77

88
const Index: NextPage = () => {
@@ -11,10 +11,8 @@ const Index: NextPage = () => {
1111
<Section>
1212
<Container>
1313
<header>
14-
<h1 style={{color: "red"}}>INDEX</h1>
15-
<Link href="/meeting-rooms">
16-
<Button skin="primary">Home</Button>
17-
</Link>
14+
<h1 style={{ color: "red" }}>INDEX</h1>
15+
{/* <Link href="/meeting-rooms"></Link> */}
1816
</header>
1917
</Container>
2018
</Section>

Diff for: web/pages/meeting-rooms.tsx

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
import {NextPage} from "next";
1+
import { NextPage } from "next";
22
import React from "react";
33

44
import Link from "next/link";
55
import Button from "../components/button";
6-
import {Container, Section} from "../components/global-style";
6+
import { Container, Section } from "../components/global-style";
77
import Layout from "../components/layout";
88

99
const MeetingRooms: NextPage = () => {
@@ -14,9 +14,7 @@ const MeetingRooms: NextPage = () => {
1414
<Container>
1515
<header>
1616
<h1>Meeting rooms</h1>
17-
<Link href="/">
18-
<Button skin="primary">Home</Button>
19-
</Link>
17+
<Link href="/">{/* <Button skin="primary">Home</Button> */}</Link>
2018
</header>
2119
</Container>
2220
</Section>

Diff for: web/pages/signin.tsx

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import { useMutation, useApolloClient } from "@apollo/react-hooks";
2+
import { NextPage } from "next";
3+
import React from "react";
4+
import Button from "../components/button";
5+
import { Container, Section } from "../components/global-style";
6+
import Layout from "../components/layout";
7+
import gql from "graphql-tag";
8+
import cookie from "cookie";
9+
import redirect from "../lib/redirect";
10+
import { withApollo } from "../lib/apollo";
11+
12+
const Signin: NextPage = () => {
13+
const [sigin] = useMutation(gql`
14+
mutation Siginin($email: String = "[email protected]", $password: String = "multi") {
15+
signIn(email: $email, password: $password)
16+
}
17+
`);
18+
19+
const appoloClient = useApolloClient();
20+
21+
return (
22+
<>
23+
<Layout>
24+
<Section>
25+
<Container>
26+
<Button skin="primary" onClick={onSignInClick}>
27+
Entrar
28+
</Button>
29+
</Container>
30+
</Section>
31+
</Layout>
32+
</>
33+
);
34+
35+
async function onSignInClick(event: React.MouseEvent<HTMLButtonElement>) {
36+
event.preventDefault();
37+
38+
try {
39+
const result = await sigin({});
40+
41+
if (result.data && result.data.signIn) {
42+
document.cookie = cookie.serialize("token", result.data.signIn);
43+
console.log(document.cookie);
44+
await appoloClient.cache.reset();
45+
redirect(null, "/signup");
46+
}
47+
48+
console.log(result);
49+
} catch (error) {
50+
// TODO: Handle error
51+
console.error(error);
52+
}
53+
}
54+
};
55+
56+
export default withApollo(Signin);

Diff for: web/pages/signup.tsx

+177
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,177 @@
1+
import { useApolloClient, useMutation } from "@apollo/react-hooks";
2+
import { NextPage } from "next";
3+
import React, { useRef, useState } from "react";
4+
import Button from "../components/button";
5+
import { Container, Section } from "../components/global-style";
6+
import Layout from "../components/layout";
7+
import Input from "../components/input";
8+
import { Column } from "../components/column";
9+
import { withApollo } from "../lib/apollo";
10+
import gql from "graphql-tag";
11+
12+
type User = {
13+
id: string;
14+
email: string;
15+
role: Role;
16+
};
17+
18+
enum Role {
19+
ADMINISTRATOR = "ADMINISTRATOR",
20+
COLLABORATOR = "COLLABORATOR"
21+
}
22+
23+
type UserInput = {
24+
email: string;
25+
password: string;
26+
role: Role;
27+
};
28+
29+
const Signup: NextPage = () => {
30+
var emailRegex = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
31+
const email = useRef<HTMLInputElement>(null);
32+
const pass = useRef<HTMLInputElement>(null);
33+
const confirmpass = useRef<HTMLInputElement>(null);
34+
const [validEmail, setValidEmail] = useState(false);
35+
const [passValue, setPassValue] = useState("");
36+
const [emailValue, setEmailValue] = useState("");
37+
const [validPass, setValidPass] = useState(false);
38+
const [emailErrorMessage, setEmailError] = useState("");
39+
const [passErrorMessage, setpassError] = useState("");
40+
const [createUser] = useMutation<{ createUser: User }, { input: UserInput }>(
41+
gql`
42+
mutation CreateUser($input: UserInput!) {
43+
createUser(input: $input) {
44+
id
45+
}
46+
}
47+
`
48+
);
49+
50+
return (
51+
<>
52+
<Layout>
53+
<Section>
54+
<Container>
55+
<form name="form">
56+
<Column>
57+
<div>
58+
<Input
59+
onChange={validateEmail}
60+
type="text"
61+
placeholder="Email"
62+
ref={email}
63+
/>
64+
<img
65+
src={validEmail ? "success_icon.svg" : "error_icon.svg"}
66+
/>
67+
</div>
68+
<div>
69+
<Input
70+
onChange={validatePass}
71+
type="password"
72+
placeholder="Senha"
73+
ref={pass}
74+
/>
75+
<img
76+
src={validPass ? "success_icon.svg" : "error_icon.svg"}
77+
/>
78+
</div>
79+
<div>
80+
<Input
81+
onChange={validatePass}
82+
type="password"
83+
placeholder="Confirmar senha"
84+
ref={confirmpass}
85+
/>
86+
<img
87+
src={validPass ? "success_icon.svg" : "error_icon.svg"}
88+
/>
89+
</div>
90+
<Button skin="primary" onClick={sendForm}>
91+
Cadastrar
92+
</Button>
93+
</Column>
94+
</form>
95+
{renderError()}
96+
</Container>
97+
</Section>
98+
</Layout>
99+
</>
100+
);
101+
102+
function renderError() {
103+
return (
104+
<div>
105+
<b>{emailErrorMessage} </b>
106+
<br></br>
107+
<b>{passErrorMessage}</b>
108+
</div>
109+
);
110+
}
111+
112+
function validateEmail() {
113+
if (email.current !== null) {
114+
if (emailRegex.test(String(email.current.value).toLocaleLowerCase())) {
115+
setEmailError("");
116+
setEmailValue(email.current.value);
117+
setValidEmail(true);
118+
} else {
119+
setEmailValue("");
120+
setEmailError("Email inválido");
121+
setValidEmail(false);
122+
}
123+
}
124+
}
125+
126+
function validatePass() {
127+
if (
128+
confirmpass.current !== null &&
129+
pass.current !== null &&
130+
validateMinimumPassSize()
131+
) {
132+
if (confirmpass.current.value === pass.current.value) {
133+
setpassError("");
134+
setPassValue(confirmpass.current.value);
135+
setValidPass(true);
136+
} else {
137+
setPassValue("");
138+
setpassError("As senhas não coincidem");
139+
setValidPass(false);
140+
}
141+
}
142+
}
143+
144+
function validateMinimumPassSize() {
145+
if (confirmpass.current !== null) {
146+
if (confirmpass.current.value.length < 5) {
147+
setpassError("A senha deve ter ao menos 6 caracteres");
148+
return false;
149+
} else {
150+
setpassError("");
151+
return true;
152+
}
153+
}
154+
}
155+
async function sendForm(event: React.MouseEvent<HTMLButtonElement>) {
156+
event.preventDefault();
157+
validatePass();
158+
validateEmail();
159+
validateMinimumPassSize();
160+
161+
if (validEmail && validPass) {
162+
console.log("Pass");
163+
const result = await createUser({
164+
variables: {
165+
input: {
166+
email: emailValue,
167+
password: passValue,
168+
role: Role.COLLABORATOR
169+
}
170+
}
171+
});
172+
console.log(result);
173+
}
174+
}
175+
};
176+
177+
export default withApollo(Signup);

Diff for: web/public/error_icon.svg

+1
Loading

Diff for: web/public/logo.png

3.33 KB
Loading

Diff for: web/public/success_icon.svg

+1
Loading

Diff for: web/tests/signin.gql

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
mutation Siginin($email: String = "[email protected]", $password: String = "multi") {
2+
signIn(email: $email, password: $password)
3+
}

0 commit comments

Comments
 (0)