Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -129,5 +129,4 @@ yarn-debug.log*
yarn-error.log*
node_modules
frontend/node_modules

www
www/
1 change: 0 additions & 1 deletion backend/PyMatcha/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,6 @@
"DB_PASSWORD",
"MAIL_PASSWORD",
"APP_URL",
"REACT_APP_API_URL",
]

for item in REQUIRED_ENV_VARS:
Expand Down
4 changes: 4 additions & 0 deletions frontend/public/awesome.css

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions frontend/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<head>
<meta charset="utf-8" />
<link rel="stylesheet" type="text/css" href="/bulma.css">
<link rel="stylesheet" type="text/css" href="/awesome.css">
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
Expand Down
66 changes: 66 additions & 0 deletions frontend/src/App.css
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,69 @@
transform: rotate(360deg);
}
}

.lds-heart {
display: inline-block;
position: relative;
width: 80px;
height: 80px;
/* transform: rotate(45deg) translateY(50%); */
transform: rotate(45deg);
transform-origin: 40px 40px;
}
.lds-heart div {
top: 32px;
left: 32px;
position: absolute;
width: 32px;
height: 32px;
background: #fff;
animation: lds-heart 1.2s infinite cubic-bezier(0.215, 0.61, 0.355, 1);
}
.lds-heart div:after,
.lds-heart div:before {
content: " ";
position: absolute;
display: block;
width: 32px;
height: 32px;
background: #fff;
}
.lds-heart div:before {
left: -24px;
border-radius: 50% 0 0 50%;
}
.lds-heart div:after {
top: -24px;
border-radius: 50% 50% 0 0;
}
@keyframes lds-heart {
0% {
transform: scale(0.95);
}
5% {
transform: scale(1.1);
}
39% {
transform: scale(0.85);
}
45% {
transform: scale(1);
}
60% {
transform: scale(0.95);
}
100% {
transform: scale(0.9);
}
}


.horizTranslate {
-webkit-transition: 0.5s;
-moz-transition: 0.5s;
-ms-transition: 0.5s;
-o-transition: 0.5s;
transition: 0.5s;
margin-left: 100% !important;
}
4 changes: 2 additions & 2 deletions frontend/src/App.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import { BrowserRouter, Switch, Route, Redirect } from 'react-router-dom';
import Home from "./pages/home";
import Login from "./pages/login";
import Landing from "./pages/landing";
import NotFound from "./pages/not_found"
import { getToken } from './utils'
import './App.css';
Expand All @@ -10,7 +10,7 @@ const App = () => (
<BrowserRouter>
<Switch>
<PrivateRoute exact path="/" component={Home} />
<Route exact path="/login" component={Login} />
<Route exact path="/login" component={Landing} />
<Route component={NotFound} />
</Switch>
</BrowserRouter>
Expand Down
21 changes: 21 additions & 0 deletions frontend/src/components/input.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react';

const onChange = (setValue) => e => {
setValue(e.nativeEvent.target.value)
}

const Input = ({placeholder = '', outerStyle = {}, innerStyle = {}, OuterClass = '', InnerClass = '', icon, type = 'text', value, setValue}) => (
<div className={`field ${OuterClass}`} style={outerStyle}>
{ !!icon ?
<p className='control has-icons-left'>
<input className={`input ${InnerClass}`} type={type} placeholder={placeholder} style={innerStyle} value={value} onChange={onChange(setValue)} />
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like there's a label missing for this input. That makes it hard for people using screen readers or voice control to use the input.

<span className='icon is-small is-left'>
<i className={icon} />
</span>
</p> :
<input className={`input ${InnerClass}`} type={type} placeholder={placeholder} style={innerStyle} />
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like there's a label missing for this input. That makes it hard for people using screen readers or voice control to use the input.

}
</div>
)

export default Input
9 changes: 9 additions & 0 deletions frontend/src/components/loadings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import React from 'react';

const Loading = ({ style = {} }) => (
<div style={{ transform: "translateY(-50%) translateX(-50%)", ...style}}>
<div className="lds-heart"><div></div></div>
</div>
)

export default Loading;
64 changes: 64 additions & 0 deletions frontend/src/components/login_card.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import React, { useState } from 'react';
import { effectDuration, discard, apiCall } from '../utils';
import Loading from '../components/loadings';
import Input from './input';

const logMe = (history, setState, username, password, from) => async () => {
setState('loading');
let ret = await apiCall({uri: '/auth/login', method: 'POST', body: {username, password}})
if (!!ret.is_error) {
setState(ret.error.message)
} else {
const token = ret.access_token;
sessionStorage.setItem("token", token);
history.push('/');
}
// API call /auth/login
// sessionStorage.setItem('token', 'api call result');
}

const usernameInput = (value, setValue, state) => ({
placeholder: 'Username',
outerStyle: state === 'loading' ? discard('left') : {},
innerStyle: { backgroundColor: 'deepskyblue' },
InnerClass: 'is-info',
icon: 'fas fa-user',
value,
setValue
})

const passwordInput = (value, setValue, state) => ({
placeholder: 'password',
outerStyle: state === 'loading' ? discard('right') : {},
innerStyle: { backgroundColor: 'deepskyblue' },
InnerClass: 'is-info',
icon: 'fas fa-lock',
type: 'password',
value,
setValue
})

const LoginCard = ({ history, from }) => {
const [state, setState] = useState('default');
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');

return (
<div style={{ height: '100%', display: 'flex', flexDirection: 'column', overflow: 'hidden' }}>
{ state != 'default' && state != 'loading' &&
<div className="notification is-danger" style={{paddingTop: '0.5em', paddingBottom: '0.5em'}} > { state } </div>
}
<Loading style={{ position: 'absolute', left: '50%', top: '50%', opacity: state === 'loading' ? '1' : '0', ...effectDuration(1) }} />
<Input {...usernameInput(username, setUsername, state)} />
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like there's a label missing for this input. That makes it hard for people using screen readers or voice control to use the input.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like there's a label missing for this input. That makes it hard for people using screen readers or voice control to use the input.

<Input {...passwordInput(password, setPassword, state)} />
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like there's a label missing for this input. That makes it hard for people using screen readers or voice control to use the input.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like there's a label missing for this input. That makes it hard for people using screen readers or voice control to use the input.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like there's a label missing for this input. That makes it hard for people using screen readers or voice control to use the input.

<div className='field' style={state === 'loading' ? discard('left') : {}}>
<button className='button is-info is-light is-rounded' onClick={logMe(history, setState, username, password, from)} {...(!!username && !!password ? {} : { disabled: true })}> Log in </button>
</div>
<div className='field' style={state === 'loading' ? discard('right') : {}}>
<button className='button is-outlined is-warning is-rounded' > mot de passe oublier </button>
</div>
</div>
)
}

export default LoginCard;
79 changes: 79 additions & 0 deletions frontend/src/components/register_card.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import React, { useState } from 'react';
import { effectDuration, discard, apiCall, sleep } from '../utils';
import Loading from '../components/loadings';
import Input from './input';

const logMe = (history, setState, email, username, password, from) => async () => {
setState('loading');
let ret = {}
ret = await apiCall({uri: '/auth/register', method: 'POST', body: {email, password, username}})
if (!!ret.error) {
setState(ret.error.message);
} else {
setState('ok')
}
}

const emailInput = (value, setValue, state) => ({
placeholder: 'email',
outerStyle: { ...(state === 'loading' ? discard('left') : {}), marginTop: '1em' },
innerStyle: { backgroundColor: 'greenyellow' },
InnerClass: 'is-success',
icon: 'fas fa-envelope',
value,
setValue
})

const usernameInput = (value, setValue, state) => ({
placeholder: 'username',
outerStyle: state === 'loading' ? discard('right') : {},
innerStyle: { backgroundColor: 'greenyellow' },
InnerClass: 'is-success',
icon: 'fas fa-user',
value,
setValue
})

const passwordInput = (value, setValue) => ({
innerStyle: { backgroundColor: 'greenyellow'},
InnerClass: 'is-success',
icon: 'fas fa-lock',
type: 'password',
value,
setValue
})

const registerButton = ({history, password_ok, password1, email, setState, from, username}) => ({
className: 'button is-info is-light is-rounded',
onClick: logMe(history, setState, email, username, password1, from),
...(!password_ok ? { disabled: true } : {})
})

const RegisterCard = ({ history, from }) => {
const [state, setState] = useState('default');
const [email, setEmail] = useState('');
const [username, setUsername] = useState('');
const [password1, setPassword1] = useState('');
const [password2, setPassword2] = useState('');
const password_ok = !!password1 && password1 === password2;

if (state === 'ok') return <p>You will soon receive an confimration email</p>
return (
<div style={{ height: '100%', display: 'flex', flexDirection: 'column' }}>
{ state != 'default' && state != 'loading' &&
<div className="notification is-danger" style={{paddingTop: '0.5em', paddingBottom: '0.5em'}}> { state } </div>
}
< Loading style={{ position: 'absolute', left: '50%', top: '50%', opacity: state === 'loading' ? '1' : '0', ...effectDuration(1) }} />
<Input {...emailInput(email, setEmail, state)} />
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like there's a label missing for this input. That makes it hard for people using screen readers or voice control to use the input.

<Input {...usernameInput(username, setUsername, state)} />
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like there's a label missing for this input. That makes it hard for people using screen readers or voice control to use the input.

<Input {...passwordInput(password1, setPassword1, state)} placeholder="password" outerStyle={state === 'loading' ? discard('left') : {}} />
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like there's a label missing for this input. That makes it hard for people using screen readers or voice control to use the input.

<span style={ !password_ok && !!email ? {boxShadow: "red 0px 0px 1px 1px"} : {}}>
<Input {...passwordInput(password2, setPassword2, state)} placeholder="Password verification" outerStyle={state === 'loading' ? discard('right') : {}} />
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like there's a label missing for this input. That makes it hard for people using screen readers or voice control to use the input.

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like there's a label missing for this input. That makes it hard for people using screen readers or voice control to use the input.

</span>
<div className='field' style={{ ...(state === 'loading' ? discard('bottom') : {}), marginTop: '2em' }}>
<button {...registerButton({history, password_ok, password1, email, setState, from, username})}> Register </button>
</div>
</div>
)
}
export default RegisterCard;
6 changes: 4 additions & 2 deletions frontend/src/hooks/fetch_data.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ const onLoad = async (url, options, setState) => {
}
}

// TODO call id for chained call
const useFetchData = (url, options = {}) => {
const defaultOptions = {} ;

// TODO call_id for chained call
const useFetchData = (url, options = defaultOptions) => {
const [state, setState] = useState({
loading: true,
error: undefined,
Expand Down
50 changes: 50 additions & 0 deletions frontend/src/pages/landing.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import React from 'react';
import { getToken } from '../utils';
import { useHistory } from 'react-router-dom';
import LoginCard from '../components/login_card';
import RegisterCard from '../components/register_card';

// If oldPath is set, maybe a blur effect
const Landing = ({ from }) => {
const history = useHistory();
if (!!getToken())
history.push('/');
return (
<div className='container' style={{ textAlign: 'center', padding: '1.5em' }}>
<p className='title is-1' style={{ margin: '1em' }} >Matcha</p>
<div className='tile is-ancestor'>
<div className='tile is-vertical is-8'>
<div className='tile'>
<div className='tile is-parent is-vertical'>
<article className='tile is-child notification is-primary'>
<p className='subtitle'>Guilhem 22 ans j'ai trouver l'ame soeur grace a ce site</p>
</article>
<article className='tile is-child notification is-warning'>
<p className='subtitle'>Lea 34 ans, apres ma rupture avec mon copain matcha m'a redonne espoir</p>
</article>
</div>
<div className='tile is-parent' style={{overflow: 'hidden'}}>
<article className='tile is-child notification is-info'>
<LoginCard history={history} from={from} />
</article>
</div>
</div>
<div className='tile is-parent'>
<article className='tile is-child notification is-danger'>
<p className='subtitle'>Matcha est plus qu'une page web c'est un lieu de magie, de rencontre, grace a nos algorythme pas du tout intrusif nous vous faisons rencontrer la personne dont vous revez la nuit</p>
<div className='content'>
</div>
</article>
</div>
</div>
<div className='tile is-parent' style={{overflow: 'hidden'}}>
<article className='tile is-child notification is-success'>
<RegisterCard history={history} from={from} />
</article>
</div>
</div>
</div>
)
}

export default Landing;
25 changes: 0 additions & 25 deletions frontend/src/pages/login.js

This file was deleted.

Loading