Merge pull request #294 from bornhack/profile_page_makeover

Profile page makeover
This commit is contained in:
Víðir Valberg Guðmundsson 2019-03-26 22:33:01 +01:00 committed by GitHub
commit 5fdf0e70e6
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
37 changed files with 611 additions and 467 deletions

View file

@ -19,10 +19,9 @@ from villages.views import *
admin.site.login = login_required(admin.site.login)
urlpatterns = [
path(
'profile/',
include('profiles.urls', namespace='profiles')
),
path('profile/', include('allauth.urls')),
path('profile/', include('allauth_2fa.urls')),
path('profile/', include('profiles.urls', namespace='profiles')),
path(
'tickets/',
include('tickets.urls', namespace='tickets')
@ -65,8 +64,6 @@ urlpatterns = [
TemplateView.as_view(template_name='legal/general_terms_and_conditions.html'),
name='general-terms'
),
path('accounts/', include('allauth.urls')),
path('accounts/', include('allauth_2fa.urls')),
path('admin/', admin.site.urls),
# We don't need CSRF checks for the API

View file

@ -1,12 +1,7 @@
from django.contrib.auth.models import User
from django.db import models
from django.conf import settings
from django.utils import timezone
from django.dispatch import receiver
from django.utils.translation import ugettext_lazy as _
from datetime import timedelta
from utils.models import UUIDModel, CreatedUpdatedModel

View file

@ -1,76 +1,105 @@
{% extends 'profile_base.html' %}
{% load i18n %}
{% load bootstrap3 %}
{% block head_title %}{% trans "Account" %}{% endblock %}
{% block profile_content %}
<div class="row">
<div class="col-md-12">
<div class="row">
<div class="col-md-12">
<h1>{% trans "E-mail Addresses" %}</h1>
{% if user.emailaddress_set.all %}
<p>{% trans 'The following e-mail addresses are associated with your account:' %}</p>
<div class="panel panel-default">
<div class="panel-heading">
<h4>E-mail Addresses</h4>
</div>
<div class="panel-body">
<form action="{% url 'account_email' %}" class="email_list" method="post">
{% csrf_token %}
<fieldset class="blockLabels">
{% if user.emailaddress_set.all %}
<p>The following e-mail addresses are associated with your account:</p>
<form action="{% url 'account_email' %}" class="email_list" method="post">
{% csrf_token %}
<fieldset class="blockLabels">
{% for emailaddress in user.emailaddress_set.all %}
<div class="ctrlHolder">
<label for="email_radio_{{forloop.counter}}" class="{% if emailaddress.primary %}primary_email{%endif%}">
<table class="table">
<thead>
<tr>
<th></th>
<th>Address</th>
<th>Status</th>
<th>Primary?</th>
</tr>
</thead>
<tbody>
<input
id="email_radio_{{forloop.counter}}"
type="radio"
name="email"
value="{{emailaddress.email}}"
{% if emailaddress.primary or user.emailaddress_set.count == 1 %}
checked="checked"
{%endif %}
/>
{% for emailaddress in user.emailaddress_set.all %}
<tr class="ctrlHolder">
<label for="email_radio_{{forloop.counter}}" class="{% if emailaddress.primary %}primary_email{%endif%}">
<td>
<input
id="email_radio_{{forloop.counter}}"
type="radio"
name="email"
value="{{emailaddress.email}}"
{% if emailaddress.primary or user.emailaddress_set.count == 1 %}
checked="checked"
{%endif %}
/>
</td>
<td>
{{ emailaddress.email }}
</td>
<td>
{% if emailaddress.verified %}
<span class="label label-success">Verified</span>
{% else %}
<span class="label label-danger">Unverified</span>
{% endif %}
</td>
<td>
{% if emailaddress.primary %}<span class="label label-primary">Primary</span>{% endif %}
</td>
</label>
</tr>
{% endfor %}
{{ emailaddress.email }}
{% if emailaddress.verified %}
<span class="badge">{% trans "Verified" %}</span>
{% else %}
<span class="badge">{% trans "Unverified" %}</span>
{% endif %}
{% if emailaddress.primary %}<span class="badge">{% trans "Primary" %}</span>{% endif %}
</label>
</div>
{% endfor %}
</tbody>
</table>
<div class="buttonHolder">
<button class="btn btn-black" type="submit" name="action_primary" >{% trans 'Make Primary' %}</button>
<button class="btn btn-black" type="submit" name="action_send" >{% trans 'Re-send Verification' %}</button>
<button class="btn btn-black" type="submit" name="action_remove" >{% trans 'Remove' %}</button>
</div>
<div class="buttonHolder">
<button class="btn btn-success" type="submit" name="action_primary" >Make Primary</button>
<button class="btn btn-primary" type="submit" name="action_send" >Re-send Verification</button>
<button class="btn btn-danger" type="submit" name="action_remove" >Remove</button>
</div>
</fieldset>
</form>
</fieldset>
</form>
{% else %}
<p>
<strong>Warning:</strong> You currently do not have any e-mail address set up. You should really add an e-mail address so you can receive notifications, reset your password, etc.
</p>
{% endif %}
</div>
</div>
{% else %}
<p><strong>{% trans 'Warning:'%}</strong> {% trans "You currently do not have any e-mail address set up. You should really add an e-mail address so you can receive notifications, reset your password, etc." %}</p>
<div class="panel panel-default">
<div class="panel-heading">
<h4>Add E-mail Address</h4>
</div>
<div class="panel-body">
<form method="post" action="{% url 'account_email' %}" class="add_email">
{% csrf_token %}
{% bootstrap_form form %}
<button name="action_add" class="btn btn-success" type="submit">Add E-mail</button>
</form>
</div>
</div>
{% endif %}
<h2>{% trans "Add E-mail Address" %}</h2>
<form method="post" action="{% url 'account_email' %}" class="add_email">
{% csrf_token %}
{% bootstrap_form form %}
<button name="action_add" class="btn btn-black" type="submit">{% trans "Add E-mail" %}</button>
</form>
</div>
</div>
<script type="text/javascript">
(function() {
var message = "{% trans 'Do you really want to remove the selected e-mail address?' %}";
var message = "Do you really want to remove the selected e-mail address?";
var actions = document.getElementsByName('action_remove');
if (actions.length) {
actions[0].addEventListener("click", function(e) {

View file

@ -16,7 +16,7 @@
<form class="login" method="POST">
{% csrf_token %}
{% bootstrap_form form %}
<button class="form-control btn btn-black" type="submit">{% trans "Login" %}</button>
<button class="form-control btn btn-primary" type="submit">{% trans "Login" %}</button>
{% if redirect_field_value %}
<input type="hidden" name="{{ redirect_field_name }}" value="{{ redirect_field_value }}" />
{% endif %}

View file

@ -10,7 +10,7 @@
<form method="post">
{% csrf_token %}
<button type="submit"
class="btn btn-black form-control">
class="btn btn-danger form-control">
Logout
</button>
</form>

View file

@ -7,13 +7,18 @@
<div class="row">
<div class="col-md-12">
<h1>Change password</h1>
<div class="panel panel-default">
<div class="panel-heading">
<h4>Change Password</h4>
</div>
<div class="panel-body">
<form class="login" method="POST">
{% csrf_token %}
{% bootstrap_form form %}
<button class="form-control btn btn-black" type="submit">Save</button>
</form>
<form class="login" method="POST">
{% csrf_token %}
{% bootstrap_form form %}
<button class="form-control btn btn-primary" type="submit">Save</button>
</form>
</div>
</div>
</div>

View file

@ -16,7 +16,7 @@
<form class="login" method="POST">
{% csrf_token %}
{% bootstrap_form form %}
<button class="form-control btn btn-black" type="submit">Send e-mail</button>
<button class="form-control btn btn-primary" type="submit">Send e-mail</button>
</form>
</div>
{% endblock %}

View file

@ -13,7 +13,7 @@
<form class="login" method="POST">
{% csrf_token %}
{% bootstrap_form form %}
<button class="form-control btn btn-black" type="submit">{% trans "Sign Up" %}</button>
<button class="form-control btn btn-success" type="submit">{% trans "Sign Up" %}</button>
</form>
</div>
</div>

View file

@ -15,7 +15,7 @@
{% bootstrap_form form %}
<button type="submit"
class="btn btn-black form-control">
class="btn btn-primary form-control">
{% trans 'Authenticate' %}
</button>
</form>

View file

@ -2,34 +2,60 @@
{% load account %}
{% load bootstrap3 %}
{% load i18n %}
{% block profile_content %}
<div class="row">
<div class="col-md-12">
<h1>
{% trans "Two-Factor Authentication Backup Tokens" %}
</h1>
<ul>
{% for token in backup_tokens %}
<li>{{ token.token }}</li>
<div class="alert alert-danger">
<h4><strong>Attention!</strong></h4>
<p >
Backup Tokens are important if you for some reason <strong>lose access</strong> to your two-factor authentication device (ie. misplace your phone).<br />
If this happens you will <strong>not be able to login to BornHack.dk</strong> without using a backup token.<br />
So generate some tokens and <strong>keep them safe</strong> for a rainy day ;)
</p>
</div>
{% empty %}
{% trans 'No tokens. Press the button below to generate some.' %}
{% endfor %}
</ul>
<form method="post">
{% csrf_token %}
<div class="buttonHolder">
<button class="btn btn-black" type="submit">
{% trans 'Generate backup tokens' %}
</button>
<a class="btn btn-warning" href="{% url 'two-factor-remove' %}">Disable Two-Factor</a>
<div class="panel panel-default">
<div class="panel-heading">
<h4>Two-Factor Authentication Backup Tokens</h4>
</div>
</form>
<div class="panel-body">
{% if backup_tokens %}
<ul>
{% for token in backup_tokens %}
<li><h4>{{ token.token }}</h4></li>
{% endfor %}
</ul>
{% else %}
<p>No tokens. Press the button below to generate some.</p>
{% endif %}
</div>
<div class="panel-footer">
<form method="post">
{% csrf_token %}
<div class="buttonHolder">
<button class="btn btn-success" type="submit">
{% if backup_tokens %}
Generate new backup tokens
{% else %}
Generate backup tokens
{% endif %}
</button>
</div>
</form>
</div>
</div>
<div class="panel panel-danger">
<div class="panel-heading">
<h4>Disable Two-Factor Authenticatoin</h4>
</div>
<div class="panel-body">
<a class="btn btn-danger" href="{% url 'two-factor-remove' %}">Disable Two-Factor</a>
</div>
</div>
</div>
</div>
{% endblock %}

View file

@ -2,23 +2,26 @@
{% load account %}
{% load bootstrap3 %}
{% load i18n %}
{% block profile_content %}
<div class="row">
<div class="col-md-12">
<h1>
{% trans "Disable Two-Factor Authentication" %}
</h1>
<div class="panel panel-danger">
<div class="panel-heading">
<h4>Disable Two-Factor Authentication</h4>
</div>
<div class="panel-body">
<p>Are you sure you want to disable two-factor authentication?</p>
<p>{% trans "Are you sure?" %}</p>
<form method="post">
{% csrf_token %}
<button class="btn btn-danger" type="submit">
{% trans 'Disable Two-Factor' %}
</button>
</form>
<form method="post">
{% csrf_token %}
<button class="btn btn-danger" type="submit">
Yes, I'm sure
</button>
<a href="{% url 'two-factor-backup-tokens' %}" class="btn btn-success">No, I've changed my mind.</a>
</form>
</div>
</div>
</div>
</div>
{% endblock %}

View file

@ -7,35 +7,38 @@
{% block profile_content %}
<div class="row">
<div class="col-md-12">
<h1>
{% trans "Setup Two-Factor Authentication" %}
</h1>
<div class="panel panel-default">
<div class="panel-heading">
<h4>Setup Two-Factor Authentication</h4>
</div>
<div class="panel-body">
<h4>
{% trans 'Step 1' %}:
</h4>
<h4>
{% trans 'Step 1' %}:
</h4>
<p>
{% trans 'Scan the QR code below with a token generator of your choice (for instance Google Authenticator).' %}
</p>
<p>
{% trans 'Scan the QR code below with a token generator of your choice (for instance Google Authenticator).' %}
</p>
<img src="{% url 'two-factor-qr-code' %}" />
<img src="{% url 'two-factor-qr-code' %}" />
<h4>
{% trans 'Step 2' %}:
</h4>
<h4>
{% trans 'Step 2' %}:
</h4>
<p>
{% trans 'Input a token generated by the app:' %}
</p>
<p>
{% trans 'Input a token generated by the app:' %}
</p>
<form method="post">
{% csrf_token %}
{% bootstrap_form form %}
<button class="btn btn-black" type="submit">
{% trans 'Verify' %}
</button>
</form>
<form method="post">
{% csrf_token %}
{% bootstrap_form form %}
<button class="btn btn-success" type="submit">
{% trans 'Verify' %}
</button>
</form>
</div>
</div>
</div>
</div>
{% endblock %}

View file

@ -4,20 +4,92 @@
{% load bootstrap3 %}
{% block content %}
<div class="page-header">
<h2>Your BornHack Profile</h2>
</div>
<div class="row">
<div class="btn-group btn-group-justified hidden-xs">
{% include 'profile_base_buttons.html' %}
<div class="col-md-2">
<ul class="nav nav-pills nav-stacked">
<li><b>Profile settings</b></li>
{% url 'profiles:detail' as profile_detail_url %}
<li {% if request.path == profile_detail_url %}class="active"{% endif %}>
<a href="{{ profile_detail_url }}">
Profile
</a>
</li>
{% url 'account_change_password' as password_url %}
<li {% if request.path == password_url %}class="active"{% endif %}>
<a href="{{ password_url }}">
Password
</a>
</li>
{% url 'account_email' as email_url %}
<li {% if request.path == email_url %}class="active"{% endif %}>
<a href="{{ email_url }}">
Manage emails
</a>
</li>
{% url 'two-factor-setup' as two_factor_url %}
<li {% if "two_factor" in request.path %}class="active"{% endif %}>
<a href="{{ two_factor_url }}">
Two-Factor settings
</a>
</li>
{% if user.orders.exists %}
<li><b>Shop</b></li>
{% url 'shop:order_list' as orders_list_url %}
<li {% if "shop/order" in request.path %}class="active"{% endif %}>
<a href="{{ orders_list_url }}">
Orders
</a>
</li>
{% url 'tickets:shopticket_list' as ticket_list_url %}
<li {% if "tickets" in request.path %}class="active"{% endif %}>
<a href="{{ ticket_list_url }}">
Tickets
</a>
</li>
{% if user.creditnotes.exists %}
{% url 'shop:creditnote_list' as creditnote_list_url %}
<li {% if 'creditnotes' in request.path %}class="active"{% endif %}>
<a href="{{ creditnote_list_url }}">
Credit Notes
</a>
</li>
{% endif %}
{% endif %}
<li><b>Misc.</b></li>
{% url 'tokens:tokenfind_list' as tokenfind_list_url %}
<li {% if request.path == tokenfind_list_url %}class="active"{% endif %}>
<a href="{{ tokenfind_list_url }}">
Secret Tokens
</a>
</li>
<hr />
<p><b>You are logged in as {{ request.user.email }}</b></p>
</ul>
</div>
<div class="btn-group-vertical visible-xs">
{% include 'profile_base_buttons.html' %}
<div class="col-md-10">
{% block profile_content %}{% endblock %}
</div>
</div>
<br>
<p><i><b>You are logged in as {{ request.user.email }}</b></i></p>
<hr />
{% block profile_content %}{% endblock %}
{% endblock %}

View file

@ -1,32 +0,0 @@
<a href="{% url 'profiles:detail' %}" class="btn btn-black">
Profile
</a>
<a href="{% url 'account_change_password' %}" class="btn btn-black">
Password
</a>
<a href="{% url 'two-factor-setup' %}" class="btn btn-black">
Two-Factor settings
</a>
<a href="{% url 'account_email' %}" class="btn btn-black">
Manage emails
</a>
{% if user.orders.exists %}
<a href="{% url 'shop:order_list' %}" class="btn btn-black">
Orders
</a>
<a href="{% url 'tickets:shopticket_list' %}" class="btn btn-black">
Tickets
</a>
{% if user.creditnotes.exists %}
<a href="{% url 'shop:creditnote_list' %}" class="btn btn-black">
Credit Notes
</a>
{% endif %}
{% endif %}
<a href="{% url 'tokens:tokenfind_list' %}" class="btn btn-black">
Secret Tokens
</a>
<a href="{% url 'account_logout' %}" class="btn btn-black">
Logout
</a>

View file

@ -1,26 +1,63 @@
{% extends 'profile_base.html' %}
{% block profile_content %}
<p class="lead">If you intend to join one or more teams you can use the profile to help the team responsible understand who you are and what you have to offer. Please also include availability if you are not joining us for the entire week.</p>
<p class="lead">Apart from Public Credit Name the information in your profile is only visible to team responsible and organisers.</p>
<h3>Your Profile</h3>
<table class="table table-horisontal">
<tr>
<td><b>Name (not visible to the public)</b></td>
<td>{{ profile.name|default:"N/A" }}</td>
</tr>
<tr>
<td><b>Description (not visible to the public)</b></td>
<td>{{ profile.description|default:"N/A" }}</td>
</tr>
<tr>
<td><b>Public Credit Name (visible to the public, leave empty if you want no credits on this website)</b></td>
<td>{{ profile.public_credit_name|default:"N/A" }} {% if profile.public_credit_name %}({% if profile.public_credit_name_approved %}<span class="text-success">approved</span>{% else %}<span class="text-danger">pending approval</span>{% endif %}){% endif %}</td>
</tr>
<tr>
<td><b>NickServ username (visible to the public on IRC, used to handle team channel ACLs)</b></td>
<td>{{ profile.nickserv_username|default:"N/A" }}</td>
</tr>
</table>
<a href="{% url 'profiles:update' %}" class="btn btn-black"><i class="fas fa-edit"></i> Edit Profile</a>
{% if not profile.description %}
<div class="alert alert-danger">
<h4><strong>Attention!</strong></h4>
<p>
You have not written anything in your "description".
</p>
<p>
If you intend to join one or more teams you can use the profile to help the team responsible understand who you are and what you have to offer. Please also include availability if you are not joining us for the entire week.
</p>
</div>
{% endif %}
<div class="panel panel-default">
<div class="panel-heading">
<a href="{% url 'profiles:update' %}" class="btn btn-primary pull-right clearfix"><i class="fas fa-edit"></i> Edit Profile</a>
<h4>Your information</h4>
</div>
<div class="panel-body">
<table class="table table-striped">
<tr>
<td width="30%">
<b>Name</b><br />
<small>Not visible to the public.</small></td>
<td width="70%">
{{ profile.name|default:"N/A" }}
</td>
</tr>
<tr>
<td>
<b>Description</b><br />
<small>Not visible to the public.</small>
</td>
<td>{{ profile.description|default:"N/A" }}</td>
</tr>
<tr>
<td>
<b>Public Credit Name</b><br />
<small>Visible to the public, leave empty if you want no credits on this website.</small>
</td>
<td>
{{ profile.public_credit_name|default:"N/A" }} {% if profile.public_credit_name %}({% if profile.public_credit_name_approved %}<span class="text-success">approved</span>{% else %}<span class="text-danger">pending approval</span>{% endif %}){% endif %}</td>
</tr>
<tr>
<td>
<b>NickServ username</b><br />
<small>Visible to the public on IRC, used to handle team channel ACLs.</small>
</td>
<td>
{{ profile.nickserv_username|default:"N/A" }}
</td>
</tr>
</table>
</div>
</div>
{% endblock profile_content %}

View file

@ -2,11 +2,17 @@
{% load bootstrap3 %}
{% block profile_content %}
<h4>Update Profile</h4>
<form method="POST">
{% csrf_token %}
{% bootstrap_form form %}
<button type="submit" class="btn btn-black"><i class="fas fa-save"></i> Submit</button>
<a href="{% url 'profiles:detail' %}" class="btn btn-black"><i class="fas fa-times"></i> Cancel</a>
</form>
<div class="panel panel-default">
<div class="panel-heading">
<h4>Update Profile</h4>
</div>
<div class="panel-body">
<form method="POST">
{% csrf_token %}
{% bootstrap_form form %}
<button type="submit" class="btn btn-success"><i class="fas fa-save"></i> Submit</button>
<a href="{% url 'profiles:detail' %}" class="btn btn-danger"><i class="fas fa-times"></i> Cancel</a>
</form>
</div>
</div>
{% endblock profile_content %}

View file

@ -0,0 +1,43 @@
{% extends 'profile_base.html' %}
{% load bootstrap3 %}
{% load shop_tags %}
{% load bornhack %}
{% block profile_content %}
<div class="panel panel-default">
<div class="panel-heading">
<h4>Credit Notes</h4>
</div>
<div class="panel-body">
<table class="table table-hover">
<thead>
<tr>
<th>Credit Note ID</th>
<th>Text</th>
<th class="text-right">Amount</th>
<th>Paid?</th>
<th>PDF</th>
</tr>
</thead>
<tbody>
{% for creditnote in creditnotes %}
<tr>
<td>{{ creditnote.id }}</td>
<td>{{ creditnote.text }}</td>
<td class="text-right">{{ creditnote.amount|currency }}</td>
<td class="text-center">{{ creditnote.paid|truefalseicon }}</td>
<td>
{% if creditnote.pdf %}
{% url 'shop:download_creditnote' pk=creditnote.pk as creditnote_download_url %}
{% bootstrap_button "PDF" icon="save-file" href=creditnote_download_url button_class="btn-primary btn-xs" %}
{% else %}
N/A
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endblock %}

View file

@ -1,8 +1,9 @@
{% extends 'shop_base.html' %}
{% extends 'profile_base.html' %}
{% load bootstrap3 %}
{% load shop_tags %}
{% block shop_content %}
{% block profile_content %}
<div class="panel-group">
<div class="panel panel-default">
<div class="panel panel-heading">
@ -125,8 +126,8 @@
<div class="alert alert-info" style="margin-top: 5px; margin-bottom: -10px;">* Please consider the alternatives before choosing credit card. Credit cards are expensive and difficult for us to handle. Thank you!</div>
</div>
<div class="panel panel-footer">
<i>Bank transfers take up to a week to get registered, but the other
payment methods should be more or less instant. Please
<i>Bank transfers take up to a week to get registered, but the other
payment methods should be more or less instant. Please
<a href="{% url 'contact' %}">contact us</a> if your have questions.</i>
</div>
</div>

View file

@ -0,0 +1,55 @@
{% extends 'profile_base.html' %}
{% load bootstrap3 %}
{% load shop_tags %}
{% load bornhack %}
{% block profile_content %}
<div class="panel panel-default">
<div class="panel-heading">
<h4>Orders</h4>
</div>
<div class="panel-body">
<table class="table table-hover">
<thead>
<tr>
<th>Order ID</th>
<th>Items</th>
<th>Total amount</th>
<th>Open?</th>
<th>Paid?</th>
<th>Delivered?</th>
<th>Invoice</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for order in orders %}
{% if order.products.exists %}
<tr {% if not order.open and order.paid and order.is_fully_handed_out %}style="color: lightgrey"{% endif %}>
<td>{{ order.id }}</td>
<td>{{ order.get_number_of_items }}</td>
<td>{{ order.total|currency }}</td>
<td class="text-center">{{ order.open|truefalseicon }}</td>
<td class="text-center">{{ order.paid|truefalseicon }}</td>
<td class="text-center">{{ order.handed_out_status }}</td>
<td>
{% if order.invoice.pdf %}
{% url 'shop:download_invoice' pk=order.pk as invoice_download_url %}
{% bootstrap_button "PDF" icon="save-file" href=invoice_download_url button_class="btn-primary btn-xs" %}
{% else %}
N/A
{% endif %}
</td>
<td>
{% url 'shop:order_detail' pk=order.pk as order_detail_url %}
{% bootstrap_button "Order details" icon="th-list" href=order_detail_url button_class="btn-primary btn-xs" %}
</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
</div>
</div>
{% endblock %}

View file

@ -0,0 +1,24 @@
{% extends 'profile_base.html' %}
{% load bootstrap3 %}
{% load tickets_tags %}
{% block profile_content %}
<div class="panel panel-default">
<div class="panel-heading">
<h4>Your Tickets</h4>
</div>
<div class="panel-body">
<h2>{% if ticket.checked_in %}This ticket has been used{% else %}This ticket is unused{% endif %}</h2>
<form method="POST" class="form">
{% csrf_token %}
{% bootstrap_field form.name %}
{% bootstrap_field form.email %}
<button class="btn btn-primary form-control" type="submit"><i class="glyphicon glyphicon-check"></i> Save</button>
</form>
</div>
</div>
{% endblock %}

View file

@ -0,0 +1,60 @@
{% extends 'profile_base.html' %}
{% load bootstrap3 %}
{% load tickets_tags %}
{% block profile_content %}
<div class="panel panel-default">
<div class="panel-heading">
<h4>Your Tickets</h4>
</div>
<div class="panel-body">
{% if tickets %}
<table class="table table-hover">
<thead>
<tr>
<th>
Ticket owner
<th>
Product name
<th>
Price
<th>
Checked in
<th>
Actions
<tbody>
{% for ticket in tickets %}
<tr>
<td>
{% if ticket.name %}
{{ ticket.name }}
{% else %}
Anonymous
{% endif %}
<td>
{{ ticket.product.name }}
<td>
{{ ticket.product.price|currency }}
<td>
{% if ticket.checked_in %}
Yes
{% else %}
Not yet
{% endif %}
<td>
<a href="{% url 'tickets:shopticket_download' pk=ticket.pk %}" class="btn btn-primary"><i class="fas fa-download" aria-hidden="true"></i> Download PDF</a>
{% if not ticket.name %}
<a href="{% url 'tickets:shopticket_edit' pk=ticket.pk %}" class="btn btn-primary"><i class="fas fa-edit" aria-hidden="true"></i> Set name</a>
{% else %}
<a href="{% url 'tickets:shopticket_edit' pk=ticket.pk %}" class="btn btn-primary"><i class="fas fa-edit" aria-hidden="true"></i> Edit name</a>
{% endif %}
{% endfor %}
</table>
{% else %}
<h3> You don't have any tickets yet. We hope to see you at the next BornHack!</h3>
{% endif %}
</div>
{% endblock %}

View file

@ -0,0 +1,55 @@
{% extends 'profile_base.html' %}
{% load static from staticfiles %}
{% load commonmark %}$
{% block title %}
Your Secret Tokens | {{ block.super }}
{% endblock %}
{% block profile_content %}
<div class="panel panel-default">
<div class="panel-heading">
<h4>Your Secret Tokens</h4>
</div>
<div class="panel-body">
<p class="lead">You have found the following secret tokens in the BornHack Secret Token Game:</p>
<table class="table">
<thead>
<tr>
<th>Camp</th>
<th>Category</th>
<th>Token</th>
<th>Description</th>
<th>Found</th>
</tr>
</thead>
<tbody>
{% for tokenfind in object_list %}
<tr>
<td>{{ tokenfind.token.camp.title }}</td>
<td>{{ tokenfind.token.category }}</td>
<td>{{ tokenfind.token.token }}</td>
<td>{{ tokenfind.token.description }}</td>
<td>{{ tokenfind.created }}</td>
</tr>
{% endfor %}
{% for unfound in unfound_list %}
<tr>
<td>{{ unfound.camp.title }}</td>
<td>{{ unfound.category }}</td>
<td>-</td>
<td>-</td>
<td>-</td>
</tr>
{% endfor %}
</tbody>
</table>
{% if not unfound_list %}
<p class="lead">Congratulations! You've found all tokens we have created right now.</p>
{% endif %}
</div>
{% endblock %}

View file

@ -1,7 +1,9 @@
from django.urls import path
from .views import ProfileDetail, ProfileUpdate
from .views import (
ProfileDetail,
ProfileUpdate,
)
app_name = 'profiles'
urlpatterns = [

View file

@ -9,6 +9,7 @@ from . import models
class ProfileDetail(LoginRequiredMixin, DetailView):
model = models.Profile
template_name = 'profile_detail.html'
active_menu = 'profile'
def get_object(self, queryset=None):
return models.Profile.objects.get(user=self.request.user)
@ -30,4 +31,3 @@ class ProfileUpdate(LoginRequiredMixin, UpdateView):
form.instance.save()
messages.success(self.request, 'Your profile has been updated.')
return super().form_valid(form, **kwargs)

View file

@ -1,37 +0,0 @@
{% extends 'shop_base.html' %}
{% load bootstrap3 %}
{% load shop_tags %}
{% load bornhack %}
{% block shop_content %}
<h3>Credit Notes</h3>
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>Credit Note ID</th>
<th>Text</th>
<th class="text-right">Amount</th>
<th>Paid?</th>
<th>PDF</th>
</tr>
</thead>
<tbody>
{% for creditnote in creditnotes %}
<tr>
<td>{{ creditnote.id }}</td>
<td>{{ creditnote.text }}</td>
<td class="text-right">{{ creditnote.amount|currency }}</td>
<td class="text-center">{{ creditnote.paid|truefalseicon }}</td>
<td>
{% if creditnote.pdf %}
{% url 'shop:download_creditnote' pk=creditnote.pk as creditnote_download_url %}
{% bootstrap_button "PDF" icon="save-file" href=creditnote_download_url button_class="btn-primary btn-xs" %}
{% else %}
N/A
{% endif %}
</td>
</tr>
{% endfor %}
</tbody>
</table>
{% endblock %}

View file

@ -1,49 +0,0 @@
{% extends 'shop_base.html' %}
{% load bootstrap3 %}
{% load shop_tags %}
{% load bornhack %}
{% block shop_content %}
<h3>Orders</h3>
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>Order ID</th>
<th>Items</th>
<th>Total amount</th>
<th>Open?</th>
<th>Paid?</th>
<th>Delivered?</th>
<th>Invoice</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{% for order in orders %}
{% if order.products.exists %}
<tr {% if not order.open and order.paid and order.is_fully_handed_out %}style="color: lightgrey"{% endif %}>
<td>{{ order.id }}</td>
<td>{{ order.get_number_of_items }}</td>
<td>{{ order.total|currency }}</td>
<td class="text-center">{{ order.open|truefalseicon }}</td>
<td class="text-center">{{ order.paid|truefalseicon }}</td>
<td class="text-center">{{ order.handed_out_status }}</td>
<td>
{% if order.invoice.pdf %}
{% url 'shop:download_invoice' pk=order.pk as invoice_download_url %}
{% bootstrap_button "PDF" icon="save-file" href=invoice_download_url button_class="btn-primary btn-xs" %}
{% else %}
N/A
{% endif %}
</td>
<td>
{% url 'shop:order_detail' pk=order.pk as order_detail_url %}
{% bootstrap_button "Order details" icon="th-list" href=order_detail_url button_class="btn-primary btn-xs" %}
</td>
</tr>
{% endif %}
{% endfor %}
</tbody>
</table>
{% endblock %}

View file

@ -16,9 +16,6 @@
{% if user.creditnotes.exists %}
<li class="pull-right"><a href="{% url 'shop:creditnote_list' %}">Credit Notes</a></li>
{% endif %}
{% if has_tickets %}
<li class="pull-right"><a href="{% url 'tickets:shopticket_list' %}">Tickets</a></li>
{% endif %}
<li class="pull-right"><a href="{% url 'shop:order_list' %}">Orders</a></li>
<li class="pull-right no-before">

View file

@ -278,7 +278,7 @@ class ProductDetailView(FormView, DetailView):
class OrderListView(LoginRequiredMixin, ListView):
model = Order
template_name = "order_list.html"
template_name = "shop/order_list.html"
context_object_name = 'orders'
def get_queryset(self):
@ -288,7 +288,7 @@ class OrderListView(LoginRequiredMixin, ListView):
class OrderDetailView(LoginRequiredMixin, EnsureUserOwnsOrderMixin, EnsureOrderHasProductsMixin, EnsureOrderIsNotCancelledMixin, DetailView):
model = Order
template_name = 'order_detail.html'
template_name = 'shop/order_detail.html'
context_object_name = 'order'
def post(self, request, *args, **kwargs):
@ -369,7 +369,7 @@ class DownloadInvoiceView(LoginRequiredMixin, EnsureUserOwnsOrderMixin, EnsurePa
class CreditNoteListView(LoginRequiredMixin, ListView):
model = CreditNote
template_name = "creditnote_list.html"
template_name = "shop/creditnote_list.html"
context_object_name = 'creditnotes'
def get_queryset(self):

View file

@ -81,7 +81,12 @@
</ul>
<ul class="nav navbar-nav navbar-right">
{% if user.is_authenticated %}
<li><a href="{% url 'profiles:detail' %}">Account</a></li>
<li><a href="{% url 'profiles:detail' %}">Profile</a></li>
<li>
<a href="{% url 'account_logout' %}">
Logout
</a>
</li>
{% else %}
<li><a href="{% url 'account_login' %}">Login</a></li>
{% endif %}

View file

@ -1,30 +0,0 @@
{% extends 'tickets_base.html' %}
{% load bootstrap3 %}
{% load tickets_tags %}
{% block tickets_content %}
<div class="well">
<div class="row">
<div class="col-md-7">
<div class="pull-right">
<h2>{% if ticket.checked_in %}This ticket has been used{% else %}This ticket is unused{% endif %}</h2>
<form method="POST" class="form">
{% csrf_token %}
{% bootstrap_field form.name %}
{% bootstrap_field form.email %}
<button class="btn btn-primary form-control" type="submit"><i class="glyphicon glyphicon-check"></i> Save</button>
</form>
<hr />
</div>
</div>
</div>
</div>
{% endblock %}

View file

@ -1,55 +0,0 @@
{% extends 'tickets_base.html' %}
{% load bootstrap3 %}
{% load tickets_tags %}
{% block tickets_content %}
{% if tickets %}
<h3>Tickets</h3>
<table class="table table-bordered table-hover">
<thead>
<tr>
<th>
Ticket owner
<th>
Product name
<th>
Price
<th>
Checked in
<th>
Actions
<tbody>
{% for ticket in tickets %}
<tr>
<td>
{% if ticket.name %}
{{ ticket.name }}
{% else %}
Anonymous
{% endif %}
<td>
{{ ticket.product.name }}
<td>
{{ ticket.product.price|currency }}
<td>
{% if ticket.checked_in %}
Yes
{% else %}
Not yet
{% endif %}
<td>
<a href="{% url 'tickets:shopticket_download' pk=ticket.pk %}" class="btn btn-primary"><i class="fas fa-download" aria-hidden="true"></i> Download PDF</a>
{% if not ticket.name %}
<a href="{% url 'tickets:shopticket_edit' pk=ticket.pk %}" class="btn btn-primary"><i class="fas fa-edit" aria-hidden="true"></i> Set name</a>
{% else %}
<a href="{% url 'tickets:shopticket_edit' pk=ticket.pk %}" class="btn btn-primary"><i class="fas fa-edit" aria-hidden="true"></i> Edit name</a>
{% endif %}
{% endfor %}
</table>
{% else %}
<h3> You dont have any tickets yet. We hope to see you at the next BornHack!</h3>
{% endif %}
{% endblock %}

View file

@ -1,21 +0,0 @@
{% extends 'base.html' %}
{% block content %}
<div class="row">
<div class="col-md-12">
<ol class="breadcrumb">
<li><a href="{% url 'tickets:shopticket_list' %}">Tickets</a></li>
<li class="pull-right no-before">
</li>
</ol>
</div>
</div>
{% block tickets_content %}
{% endblock %}
{% endblock %}

View file

@ -20,7 +20,7 @@ logger = logging.getLogger("bornhack.%s" % __name__)
class ShopTicketListView(LoginRequiredMixin, ListView):
model = ShopTicket
template_name = 'ticket_list.html'
template_name = 'tickets/ticket_list.html'
context_object_name = 'tickets'
def get_queryset(self):
@ -50,7 +50,7 @@ class ShopTicketDownloadView(LoginRequiredMixin, SingleObjectMixin, View):
class ShopTicketDetailView(LoginRequiredMixin, UpdateView, DetailView):
model = ShopTicket
template_name = 'ticket_detail.html'
template_name = 'tickets/ticket_detail.html'
context_object_name = 'ticket'
fields = ['name', 'email']

View file

@ -11,6 +11,6 @@ Secret Token Found! | {{ block.super }}
<p class="lead text-center">You found a secret token:</p>
<p class="lead text-center"><span class="badge">{{ token.description }}</span></p>
<p class="lead text-center">Your visit has been registered! Keep hunting, there might be more tokens out there.</p>
<p class="lead text-center"><a href="{% url 'tokens:tokenfind_list' %}">List All Tokens</a></p>
<p class="lead text-center"><a href="{% url 'tokens:tokenfind_list' %}">List All Found Tokens</a></p>
{% endblock %}

View file

@ -1,47 +0,0 @@
{% extends 'base.html' %}
{% load static from staticfiles %}
{% load commonmark %}$
{% block title %}
Your Secret Tokens | {{ block.super }}
{% endblock %}
{% block content %}
<h3>Your Secret Tokens</h3>
<p class="lead">You have found the following secret tokens in the BornHack Secret Token Game:</p>
<table class="table">
<thead>
<tr>
<th>Camp</th>
<th>Category</th>
<th>Token</th>
<th>Description</th>
<th>Found</th>
</tr>
</thead>
<tbody>
{% for tokenfind in object_list %}
<tr>
<td>{{ tokenfind.token.camp.title }}</td>
<td>{{ tokenfind.token.category }}</td>
<td>{{ tokenfind.token.token }}</td>
<td>{{ tokenfind.token.description }}</td>
<td>{{ tokenfind.created }}</td>
</tr>
{% endfor %}
{% for unfound in unfound_list %}
<tr>
<td>{{ unfound.camp.title }}</td>
<td>{{ unfound.category }}</td>
<td>-</td>
<td>-</td>
<td>-</td>
</tr>
{% endfor %}
</tbody>
</table>
{% if not unfound_list %}
<p class="lead">Congratulations! You've found all tokens we have created right now.</p>
{% endif %}
{% endblock %}

View file

@ -1,14 +1,10 @@
from django.urls import path, re_path, include
from django.urls import re_path, path
from .views import TokenDetailView, TokenFindListView
app_name = 'tokens'
urlpatterns = [
path(
'',
TokenFindListView.as_view(),
name='tokenfind_list'
),
path('', TokenFindListView.as_view(), name='tokenfind_list'),
re_path(
'(?P<token>[0-9a-zA-Z\.@]+)/$',
TokenDetailView.as_view(),

View file

@ -3,6 +3,7 @@ from django.views.generic import ListView, DetailView
from .models import Token, TokenFind
class TokenDetailView(LoginRequiredMixin, DetailView):
template_name = "token_detail.html"
model = Token
@ -19,8 +20,11 @@ class TokenDetailView(LoginRequiredMixin, DetailView):
class TokenFindListView(LoginRequiredMixin, ListView):
template_name = "tokenfind_list.html"
"""
This class is meant to be extended in other apps like `profiles`.
"""
model = TokenFind
template_name = "tokens/tokenfind_list.html"
def get_queryset(self):
return TokenFind.objects.filter(user=self.request.user)