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:
Sage Vaillancourt 2022-10-02 02:27:23 -04:00
parent 069873de02
commit 2ee23bb33e
5 changed files with 156 additions and 42 deletions

View File

@ -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']

View File

@ -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;
} }

View File

@ -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 %}

View File

@ -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>

View File

@ -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 %}