Move login/create account into a modal.
Some redundancy floating around. Error handling is probably wonky. Modal should have a bit more detail in the future.
This commit is contained in:
parent
069873de02
commit
2ee23bb33e
|
@ -78,10 +78,8 @@ class CLForm(Form):
|
||||||
)
|
)
|
||||||
|
|
||||||
def to_cl_data(self) -> CLData:
|
def to_cl_data(self) -> CLData:
|
||||||
selected_letter = self.letterName.data or '1'
|
|
||||||
|
|
||||||
return CLData(
|
return CLData(
|
||||||
selectedLetter=int(selected_letter) - 1,
|
selectedLetter=int(self.letterName.data or '1') - 1,
|
||||||
username=self.username.data,
|
username=self.username.data,
|
||||||
company=self.company.data,
|
company=self.company.data,
|
||||||
jobAndPronoun=self.jobAndPronoun.data,
|
jobAndPronoun=self.jobAndPronoun.data,
|
||||||
|
@ -110,6 +108,8 @@ def render_index(
|
||||||
|
|
||||||
@writing_blueprint.route('/login', methods=['POST', 'GET'])
|
@writing_blueprint.route('/login', methods=['POST', 'GET'])
|
||||||
def login() -> Response | str:
|
def login() -> Response | str:
|
||||||
|
if request.form.get('confirm-password'):
|
||||||
|
return create_account()
|
||||||
if request.method == 'POST':
|
if request.method == 'POST':
|
||||||
username = request.form['login']
|
username = request.form['login']
|
||||||
if db.login(username, request.form['password']):
|
if db.login(username, request.form['password']):
|
||||||
|
@ -117,13 +117,7 @@ def login() -> Response | str:
|
||||||
return redirect('/')
|
return redirect('/')
|
||||||
return render_index(error="Invalid username or password", status=401)
|
return render_index(error="Invalid username or password", status=401)
|
||||||
|
|
||||||
return '''
|
return render_index(status=404)
|
||||||
<form method="post">
|
|
||||||
<p><input type=text name=username></p>
|
|
||||||
<p><input type=password name=password></p>
|
|
||||||
<p><input type=submit value=Login></p>
|
|
||||||
</form>
|
|
||||||
'''
|
|
||||||
|
|
||||||
|
|
||||||
@writing_blueprint.route('/logout', methods=['POST', 'GET'])
|
@writing_blueprint.route('/logout', methods=['POST', 'GET'])
|
||||||
|
@ -191,11 +185,6 @@ def index_get() -> Response:
|
||||||
return render_index(form=form)
|
return render_index(form=form)
|
||||||
|
|
||||||
|
|
||||||
@writing_blueprint.route('/create_account', methods=['GET'])
|
|
||||||
def create_account_page() -> str:
|
|
||||||
return render_template('create_account.jinja2')
|
|
||||||
|
|
||||||
|
|
||||||
@writing_blueprint.route('/create_account', methods=['POST'])
|
@writing_blueprint.route('/create_account', methods=['POST'])
|
||||||
def create_account() -> Response:
|
def create_account() -> Response:
|
||||||
email_address = request.form['login']
|
email_address = request.form['login']
|
||||||
|
|
|
@ -124,8 +124,9 @@ div.user {
|
||||||
|
|
||||||
div.user form {
|
div.user form {
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: row;
|
||||||
font-size: 70%;
|
font-size: 70%;
|
||||||
|
justify-content: end;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.user form div {
|
div.user form div {
|
||||||
|
@ -170,6 +171,8 @@ div.user form input {
|
||||||
transition-property: color, background-color;
|
transition-property: color, background-color;
|
||||||
transition-duration: 135ms;
|
transition-duration: 135ms;
|
||||||
transition-timing-function: ease-out;
|
transition-timing-function: ease-out;
|
||||||
|
width: min-content;
|
||||||
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
.black-white-button:hover {
|
.black-white-button:hover {
|
||||||
|
@ -187,6 +190,9 @@ div.user form input {
|
||||||
.user.logged-in {
|
.user.logged-in {
|
||||||
margin-bottom: 1em;
|
margin-bottom: 1em;
|
||||||
}
|
}
|
||||||
|
.user.logged-out {
|
||||||
|
font-size: 110%;
|
||||||
|
}
|
||||||
|
|
||||||
dl {
|
dl {
|
||||||
display: flex;
|
display: flex;
|
||||||
|
@ -263,8 +269,49 @@ textarea {
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.modal {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
scroll-behavior: unset;
|
||||||
|
background-color: white;/*rgba(0, 0, 0, 0.4);*/
|
||||||
|
transition-property: opacity;
|
||||||
|
transition-duration: 300ms;
|
||||||
|
transition-timing-function: ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-background {
|
||||||
|
background: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-content input {
|
||||||
|
margin-bottom: 2em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-close-button {
|
||||||
|
position: absolute;
|
||||||
|
background: none;
|
||||||
|
border: none;
|
||||||
|
font-size: 2rem;
|
||||||
|
font-weight: bold;
|
||||||
|
color: #444;
|
||||||
|
margin: 0.25em;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.modal-close-button:hover {
|
||||||
|
color: #000;
|
||||||
|
}
|
||||||
|
|
||||||
/* Small screens */
|
/* Small screens */
|
||||||
@media only screen and (max-width: 1080px) {
|
@media only screen and (max-width: 720px) {
|
||||||
body {
|
body {
|
||||||
width: 85vw;
|
width: 85vw;
|
||||||
}
|
}
|
||||||
|
@ -305,7 +352,7 @@ textarea {
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Big screens */
|
/* Big screens */
|
||||||
@media only screen and (min-width: 1081px) {
|
@media only screen and (min-width: 721px) {
|
||||||
body {
|
body {
|
||||||
min-height: 98%;
|
min-height: 98%;
|
||||||
width: 40vw;
|
width: 40vw;
|
||||||
|
@ -329,9 +376,6 @@ textarea {
|
||||||
#closingText {
|
#closingText {
|
||||||
width: 50%;
|
width: 50%;
|
||||||
}
|
}
|
||||||
div.user form {
|
|
||||||
flex-direction: row;
|
|
||||||
}
|
|
||||||
div.user form input {
|
div.user form input {
|
||||||
font-size: 110%;
|
font-size: 110%;
|
||||||
padding: 0.5em;
|
padding: 0.5em;
|
||||||
|
@ -340,9 +384,32 @@ textarea {
|
||||||
.login-button {
|
.login-button {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
.logged-in {
|
.user {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0.5em;
|
top: 0.5em;
|
||||||
right: 1em;
|
right: 1em;
|
||||||
}
|
}
|
||||||
|
.modal-background {
|
||||||
|
background-color: rgba(0, 0, 0, 0.3)
|
||||||
|
}
|
||||||
|
.modal-content {
|
||||||
|
width: 40%;
|
||||||
|
height: 75%;
|
||||||
|
position: relative;
|
||||||
|
border-radius: 3px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.transparent {
|
||||||
|
pointer-events: none;
|
||||||
|
opacity: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#create-account-form div {
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hidden {
|
||||||
|
display: none;
|
||||||
}
|
}
|
|
@ -22,3 +22,46 @@
|
||||||
{{ render_input(field, extra, **kwargs) }}
|
{{ render_input(field, extra, **kwargs) }}
|
||||||
</div>
|
</div>
|
||||||
{% endmacro %}
|
{% endmacro %}
|
||||||
|
|
||||||
|
{% macro modal() %}
|
||||||
|
<div id='modal' class='modal modal-background transparent' onclick="event.target.id === 'modal' && closeModal()">
|
||||||
|
<div class='modal modal-content'>
|
||||||
|
<button class='modal-close-button' onclick="closeModal()">X</button>
|
||||||
|
<form action="/login" method="post" id="create-account-form">
|
||||||
|
<div>
|
||||||
|
<label for="login">Email: </label>
|
||||||
|
<input id="login" maxlength="32" minlength="4" name="login" type="text" placeholder="sage@sagev.space">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<label for="password">Password: </label>
|
||||||
|
<input id="password" maxlength="32" minlength="4" name="password" type="password">
|
||||||
|
</div>
|
||||||
|
<div id="confirm-password-div">
|
||||||
|
<label id='confirm-password-label' for="confirm-password">Confirm Password: </label>
|
||||||
|
<input id="confirm-password" maxlength="32" minlength="4" name="confirm-password" type="password">
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<a href="javascript:void(0)"
|
||||||
|
id="create-account-form-button"
|
||||||
|
class="wipe up-wipe"
|
||||||
|
{% if errors %}
|
||||||
|
onclick="/*clearErrors();*/document.getElementById('create-account-form').submit()"
|
||||||
|
{% else %}
|
||||||
|
onclick="document.getElementById('create-account-form').submit()"
|
||||||
|
{% endif %}
|
||||||
|
>Create Account</a>
|
||||||
|
|
||||||
|
<a href="javascript:void(0)"
|
||||||
|
id="log-in-form-button"
|
||||||
|
class="wipe up-wipe"
|
||||||
|
{% if errors %}
|
||||||
|
onclick="/*clearErrors();*/document.getElementById('create-account-form').submit()"
|
||||||
|
{% else %}
|
||||||
|
onclick="document.getElementById('create-account-form').submit()"
|
||||||
|
{% endif %}
|
||||||
|
>Log in</a>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{% endmacro %}
|
||||||
|
|
|
@ -6,10 +6,32 @@
|
||||||
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='styles.css') }}">
|
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='styles.css') }}">
|
||||||
<link rel="icon" href="{{ url_for('static', filename='favicon.png') }}" />
|
<link rel="icon" href="{{ url_for('static', filename='favicon.png') }}" />
|
||||||
<meta name="viewport" content="user-scalable=no; width=device-width">
|
<meta name="viewport" content="user-scalable=no; width=device-width">
|
||||||
|
<script type="text/javascript">
|
||||||
|
function closeModal() {
|
||||||
|
document.getElementById('modal').classList.add('transparent')
|
||||||
|
}
|
||||||
|
function showModal(login) {
|
||||||
|
document.getElementById('modal').classList.remove('transparent')
|
||||||
|
const createAccountElements = [
|
||||||
|
'confirm-password',
|
||||||
|
'confirm-password-label',
|
||||||
|
'create-account-form-button'
|
||||||
|
]
|
||||||
|
const loginElements = [
|
||||||
|
'log-in-form-button'
|
||||||
|
]
|
||||||
|
const visibleElements = login ? loginElements : createAccountElements
|
||||||
|
visibleElements.forEach(element => document.getElementById(element).classList.remove('hidden'))
|
||||||
|
|
||||||
|
const hiddenElements = login ? createAccountElements : loginElements
|
||||||
|
hiddenElements.forEach(element => document.getElementById(element).classList.add('hidden'))
|
||||||
|
}
|
||||||
|
</script>
|
||||||
{% block head %}{{ head }}{% endblock head %}
|
{% block head %}{{ head }}{% endblock head %}
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
|
{{ modal() }}
|
||||||
{% if username %}
|
{% if username %}
|
||||||
<div class="user logged-in">
|
<div class="user logged-in">
|
||||||
<p style="margin: 0 1em 0 0;">{{ username }}</p>
|
<p style="margin: 0 1em 0 0;">{{ username }}</p>
|
||||||
|
@ -17,6 +39,13 @@
|
||||||
<input class="black-white-button" style="margin: 0; padding: 0.4em;" type="submit" value="Logout">
|
<input class="black-white-button" style="margin: 0; padding: 0.4em;" type="submit" value="Logout">
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="user logged-out">
|
||||||
|
<form action="/create_account">
|
||||||
|
<div class="black-white-button" style="margin-right: 1em; padding: 0.4em;" onclick="showModal(false)">Create account</div>
|
||||||
|
<div class="white-black-button" style="margin: 0; padding: 0.4em;" onclick="showModal(true)">Log in</div>
|
||||||
|
</form>
|
||||||
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
<a href="/" style="text-decoration: none;">
|
<a href="/" style="text-decoration: none;">
|
||||||
<h1><span class="logo left">Under</span><span class="logo right">Cover</span></h1>
|
<h1><span class="logo left">Under</span><span class="logo right">Cover</span></h1>
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
{% extends "base.jinja2" %}
|
{% extends "base.jinja2" %}
|
||||||
{% from "_formhelpers.jinja2" import render_field, render_label, render_input %}
|
{% from "_formhelpers.jinja2" import render_field, render_label, render_input, modal %}
|
||||||
|
|
||||||
{% block title %}UnderCover{% endblock %}
|
{% block title %}UnderCover{% endblock %}
|
||||||
|
|
||||||
|
@ -38,24 +38,6 @@
|
||||||
{% endblock head %}
|
{% endblock head %}
|
||||||
|
|
||||||
{% block content %}
|
{% block content %}
|
||||||
{% if not username %}
|
|
||||||
<div class="user logged-out">
|
|
||||||
<p>You are working as a <strong>Guest</strong>.</p>
|
|
||||||
<form action="/login" method="post">
|
|
||||||
<div>
|
|
||||||
<input id="login" maxlength="32" minlength="4" name="login" type="text" placeholder="email">
|
|
||||||
<input id="password" maxlength="32" minlength="4" name="password" type="password" placeholder="password">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div>
|
|
||||||
<input class="black-white-button" type="submit" value="Create Account" formaction="/create_account">
|
|
||||||
<input class="black-white-button" type="submit" value="Forgot Password" formaction="/reset">
|
|
||||||
<input class="white-black-button login-button" type="submit" value="Login">
|
|
||||||
</div>
|
|
||||||
</form>
|
|
||||||
</div>
|
|
||||||
{% endif %}
|
|
||||||
|
|
||||||
<form method=post id="letter-form">
|
<form method=post id="letter-form">
|
||||||
<dl>
|
<dl>
|
||||||
{% if username %}
|
{% if username %}
|
||||||
|
@ -67,7 +49,11 @@
|
||||||
onchange="window.location = '/?letter_name=' + this.options[this.value - 1].label"
|
onchange="window.location = '/?letter_name=' + this.options[this.value - 1].label"
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
<a href="/add_letter" class="black-white-button" style="aspect-ratio: 1 / 1; text-decoration: none; margin-left: 1em; text-align: center;">+</a>
|
<a
|
||||||
|
href="/add_letter"
|
||||||
|
class="white-black-button"
|
||||||
|
style="padding-left: 0.75em; padding-right: 0.75em; text-decoration: none; margin-left: 0.5em; text-align: center;"
|
||||||
|
> + </a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
Loading…
Reference in New Issue