Browse Source

Improved layout & style, fixed hamburger menu in login page.

pull/193/head
Pēteris Caune 6 years ago
parent
commit
a58ce791c0
No known key found for this signature in database GPG Key ID: E28D7679E9A9EDE2
8 changed files with 204 additions and 102 deletions
  1. +3
    -1
      CHANGELOG.md
  2. +32
    -2
      hc/accounts/forms.py
  3. +3
    -4
      hc/accounts/tests/test_login.py
  4. +18
    -24
      hc/accounts/views.py
  5. +1
    -1
      hc/urls.py
  6. +74
    -0
      static/css/login.css
  7. +68
    -62
      templates/accounts/login.html
  8. +5
    -8
      templates/base.html

+ 3
- 1
CHANGELOG.md View File

@ -6,9 +6,11 @@ All notable changes to this project will be documented in this file.
### Improvements
- Content updates in the "Welcome" page.
- Added "Docs > Third-Party Resources" page.
- Improved layout and styling in "Login" page.
### Bug Fixes
- Timezones were missing in the "Change Schedule" dialog, fixed
- Timezones were missing in the "Change Schedule" dialog, fixed.
- Fix hamburger menu button in "Login" page.
## 1.1.0 - 2018-08-20


+ 32
- 2
hc/accounts/forms.py View File

@ -1,5 +1,7 @@
from datetime import timedelta as td
from django import forms
from django.conf import settings
from django.contrib.auth import authenticate
from django.contrib.auth.models import User
@ -10,9 +12,37 @@ class LowercaseEmailField(forms.EmailField):
return value.lower()
class EmailForm(forms.Form):
email = LowercaseEmailField()
def clean_email(self):
v = self.cleaned_data["email"]
# If registration is not open then validate if an user
# account with this address exists-
if not settings.REGISTRATION_OPEN:
if not User.objects.filter(email=v).exists():
raise forms.ValidationError("Incorrect email address.")
return v
class EmailPasswordForm(forms.Form):
identity = LowercaseEmailField()
password = forms.CharField(required=False)
email = LowercaseEmailField()
password = forms.CharField()
def clean(self):
username = self.cleaned_data.get('email')
password = self.cleaned_data.get('password')
if username and password:
self.user = authenticate(username=username, password=password)
if self.user is None:
raise forms.ValidationError("Incorrect email or password")
if not self.user.is_active:
raise forms.ValidationError("Account is inactive")
return self.cleaned_data
class ReportSettingsForm(forms.Form):


+ 3
- 4
hc/accounts/tests/test_login.py View File

@ -10,7 +10,7 @@ from django.conf import settings
class LoginTestCase(TestCase):
def test_it_sends_link(self):
form = {"identity": "[email protected]"}
form = {"email": "[email protected]"}
r = self.client.post("/accounts/login/", form)
assert r.status_code == 302
@ -32,10 +32,9 @@ class LoginTestCase(TestCase):
self.client.get("/accounts/login/")
assert "bad_link" not in self.client.session
@override_settings(REGISTRATION_OPEN=False)
def test_it_obeys_registration_open(self):
form = {"identity": "[email protected]"}
form = {"email": "[email protected]"}
r = self.client.post("/accounts/login/", form)
assert r.status_code == 200
@ -45,7 +44,7 @@ class LoginTestCase(TestCase):
alice = User(username="alice", email="[email protected]")
alice.save()
form = {"identity": "[email protected]"}
form = {"email": "[email protected]"}
r = self.client.post("/accounts/login/", form)
assert r.status_code == 302


+ 18
- 24
hc/accounts/views.py View File

@ -17,7 +17,7 @@ from django.views.decorators.http import require_POST
from hc.accounts.forms import (ChangeEmailForm, EmailPasswordForm,
InviteTeamMemberForm, RemoveTeamMemberForm,
ReportSettingsForm, SetPasswordForm,
TeamNameForm)
TeamNameForm, EmailForm)
from hc.accounts.models import Profile, Member
from hc.api.models import Channel, Check
from hc.lib.badges import get_badge_url
@ -57,44 +57,38 @@ def _ensure_own_team(request):
request.profile.save()
def login(request, show_password=False):
bad_credentials = False
def login(request):
form = EmailPasswordForm()
magic_form = EmailForm()
if request.method == 'POST':
form = EmailPasswordForm(request.POST)
if form.is_valid():
email = form.cleaned_data["identity"]
password = form.cleaned_data["password"]
if len(password):
user = authenticate(username=email, password=password)
if user is not None and user.is_active:
auth_login(request, user)
return redirect("hc-checks")
bad_credentials = True
show_password = True
else:
if request.POST.get("action") == "login":
form = EmailPasswordForm(request.POST)
if form.is_valid():
auth_login(request, form.user)
return redirect("hc-checks")
else:
magic_form = EmailForm(request.POST)
if magic_form.is_valid():
email = magic_form.cleaned_data["email"]
user = None
try:
user = User.objects.get(email=email)
except User.DoesNotExist:
if settings.REGISTRATION_OPEN:
user = _make_user(email)
else:
bad_credentials = True
if user:
profile = Profile.objects.for_user(user)
profile.send_instant_login_link()
return redirect("hc-login-link-sent")
else:
form = EmailPasswordForm()
bad_link = request.session.pop("bad_link", None)
ctx = {
"page": "login",
"form": form,
"bad_credentials": bad_credentials,
"bad_link": bad_link,
"show_password": show_password
"magic_form": magic_form,
"bad_link": bad_link
}
return render(request, "accounts/login.html", ctx)


+ 1
- 1
hc/urls.py View File

@ -4,7 +4,7 @@ from django.urls import include, path
from hc.accounts.views import login as hc_login
urlpatterns = [
path('admin/login/', hc_login, {"show_password": True}),
path('admin/login/', hc_login),
path('admin/', admin.site.urls),
path('accounts/', include('hc.accounts.urls')),
path('', include('hc.api.urls')),


+ 74
- 0
static/css/login.css View File

@ -0,0 +1,74 @@
.page-login h1 {
text-align: center;
margin: 40px 0;
}
.page-login .alert {
margin-bottom: 40px;
}
.page-login form p {
margin-bottom: 20px;
text-align: center;
}
.page-login form input {
margin-bottom: 20px;
}
@media (min-width: 768px) {
#magic-link-form {
margin-right: 50px;
}
#login-form {
margin-left: 50px;
}
}
#link-instruction {
color: #999;
font-style: italic;
padding: 12px 16px;
}
#login-sep {
background:#ddd;
position: absolute;
top: 10%;
right: -1px;
height: 80%;
width: 1px;
}
#login-sep div {
position: absolute;
top: 40%;
width: 40px;
left: -20px;
text-align: center;
background: #fff;
font-style: italic;
color: #666;
font-size: 12px;
padding: 8px 0;
}
#xs-login-sep {
text-align: center;
margin: 40px;
font-style: italic;
color: #666;
font-size: 12px;
height: 1px;
background: #ddd;
}
#xs-login-sep div {
position: relative;
margin: 0 auto;
width: 30px;
top: -9px;
background: #fff;
}

+ 68
- 62
templates/accounts/login.html View File

@ -3,77 +3,82 @@
{% block content %}
<div class="row">
<div class="col-sm-6 col-sm-offset-3">
<div class="hc-dialog">
{% if bad_link %}
<h1>Incorrect Login Link</h1>
<div class="dialog-body">
<p>The login link you just used is either incorrect or expired.</p>
<p>Please use the form below to request a fresh login link:</p>
</div>
{% else %}
<h1>{% site_name %}</h1>
<div class="dialog-body">
<p>
{% if show_password %}
Please enter your email address and password.
{% else %}
Please enter your email address.
Next, we'll send you an email with log-in instructions!
{% endif %}
</p>
</div>
{% endif %}
<div class="col-xs-10 col-xs-offset-1 col-sm-12 col-sm-offset-0 col-lg-8 col-lg-offset-2">
{% if bad_credentials %}
<p class="alert alert-danger">Incorrect email or password.</p>
{% endif %}
<h1>Sign In to {% site_name %}</h1>
{% if bad_link %}
<div class="alert alert-warning">
<p>The login link you just used is either incorrect or expired.</p>
<p>Please use the form below to request a fresh login link.</p>
</div>
{% endif %}
<form method="post">
{% csrf_token %}
<div class="row">
<div class="col-sm-6">
<form id="magic-link-form" method="post">
{% csrf_token %}
<div class="form-group">
<div class="input-group input-group-lg">
<div class="input-group-addon">
<span class="icon-mail"></span>
</div>
<input
type="text"
class="form-control"
name="identity"
value="{{ form.identity.value|default:"" }}"
placeholder="[email protected]">
</div>
</div>
{% if magic_form.email.errors %}
<p class="text-danger">Incorrect email address.</p>
{% else %}
<p>Enter your <strong>email address</strong>.</p>
{% endif %}
{% if not show_password %}
<div class="checkbox" id="password-toggle">
<label>
<input type="checkbox"> I want to use a password
</label>
</div>
{% endif %}
<input
type="text"
class="form-control input-lg"
name="email"
value="{{ magic_form.email.value|default:"" }}"
placeholder="[email protected]">
<p id="link-instruction">
We will email you a magic sign in link.
</p>
<button type="submit" class="btn btn-lg btn-primary btn-block">
Email Me a Link
</button>
</form>
<div id="login-sep" class="hidden-xs"><div>or</div></div>
</div>
<div id="password-block" class="form-group {% if not show_password %} hide {% endif %}">
<div class="input-group input-group-lg">
<div class="input-group-addon">
<span class="icon-dots"></span>
</div>
<input
type="password"
class="form-control"
name="password"
placeholder="password">
</div>
<div class="col-xs-12 visible-xs-block">
<div id="xs-login-sep">
<div>or</div>
</div>
</div>
<div class="col-sm-6">
<form id="login-form" method="post">
{% csrf_token %}
<input type="hidden" name="action" value="login" />
{% if form.non_field_errors %}
<p class="text-danger">Incorrect email or password.</p>
{% else %}
<p>
Enter your <strong>email address</strong> and <strong>password</strong>.
</p>
{% endif %}
<input
type="text"
class="form-control input-lg"
name="email"
value="{{ form.email.value|default:"" }}"
placeholder="[email protected]">
<div class="clearfix">
<button type="submit" class="btn btn-lg btn-primary pull-right">
Log In
<input
type="password"
class="form-control input-lg"
name="password"
placeholder="your password">
<button type="submit" class="btn btn-lg btn-primary btn-block">
Sign In
</button>
</div>
</form>
</form>
</div>
</div>
</div>
</div>
@ -82,6 +87,7 @@
{% block scripts %}
{% compress js %}
<script src="{% static 'js/jquery-2.1.4.min.js' %}"></script>
<script src="{% static 'js/bootstrap.min.js' %}"></script>
<script src="{% static 'js/login.js' %}"></script>
{% endcompress %}
{% endblock %}

+ 5
- 8
templates/base.html View File

@ -42,6 +42,7 @@
<link rel="stylesheet" href="{% static 'css/checkbox.css' %}" type="text/css">
<link rel="stylesheet" href="{% static 'css/radio.css' %}" type="text/css">
<link rel="stylesheet" href="{% static 'css/billing.css' %}" type="text/css">
<link rel="stylesheet" href="{% static 'css/login.css' %}" type="text/css">
{% endcompress %}
</head>
<body class="page-{{ page }}">
@ -109,14 +110,6 @@
</ul>
{% if request.user.is_authenticated %}
{% else %}
<ul class="nav navbar-nav navbar-right">
<li><a href="{% url 'hc-login' %}">Log In</a></li>
</ul>
{% endif %}
{% if request.user.is_authenticated %}
<ul class="nav navbar-nav navbar-right">
<li class="dropdown">
@ -148,6 +141,10 @@
</ul>
</li>
</ul>
{% elif page != "login" %}
<ul class="nav navbar-nav navbar-right">
<li><a href="{% url 'hc-login' %}">Log In</a></li>
</ul>
{% endif %}
</div>


Loading…
Cancel
Save