Merge branch 'index_page' into 'development'

Index page



See merge request !10
This commit is contained in:
Joachim Lusiardi 2016-05-24 07:02:33 +02:00
commit a6c5abfd88
17 changed files with 408 additions and 207 deletions

View File

@ -9,6 +9,7 @@ from flask.ext.security import Security, SQLAlchemyUserDatastore, \
from flask.ext.security import user_registered from flask.ext.security import user_registered
from flask_security.core import current_user from flask_security.core import current_user
from flask_sqlalchemy import SQLAlchemy from flask_sqlalchemy import SQLAlchemy
from flask.ext.security.forms import LoginForm
app = Flask(__name__) app = Flask(__name__)
app.config['SECURITY_PASSWORD_HASH'] = 'pbkdf2_sha512' app.config['SECURITY_PASSWORD_HASH'] = 'pbkdf2_sha512'
@ -72,9 +73,28 @@ def before_request():
@app.route('/') @app.route('/')
@login_required
def index(): def index():
if current_user.is_authenticated:
return redirect(url_for('get_pit_stops')) return redirect(url_for('get_pit_stops'))
else:
user_count = len(User.query.all())
vehicles = Vehicle.query.all()
litres = 0
kilometers = 0
for vehicle in vehicles:
stats = tools.VehicleStats(vehicle)
litres += stats.overall_litres
kilometers += stats.overall_distance
vehicle_count = len(vehicles)
pitstop_count = len(Pitstop.query.all())
data = {
'users':user_count,
'vehicles': vehicle_count,
'pitstops': pitstop_count,
'litres': litres,
'kilometers': kilometers
}
return render_template('index.html', login_user_form=LoginForm(), data=data)
@app.route('/account/edit_vehicle/<int:vid>', methods=['GET', 'POST']) @app.route('/account/edit_vehicle/<int:vid>', methods=['GET', 'POST'])

View File

@ -1,8 +1,10 @@
body { body {
padding-top: 50px; padding-top: 50px;
} }
.starter-template { .starter-template {
padding: 40px 15px; padding-top: 30px;
padding-bottom: 60px;
text-align: center; text-align: center;
} }
@ -22,9 +24,55 @@ td {
color: #a94442; color: #a94442;
} }
.pitstop {
}
.nav-pills > li > a { .nav-pills > li > a {
border: 1px solid; border: 1px solid;
} }
h1 {
margin-top: 0px;
}
h2 {
margin-top: 0px;
}
h3 {
margin-top: 0px;
text-align: center;
}
h3:before{
content:"― ";
}
h3:after{
content:" ―";
}
.tab-content > .active {
border-left: 1px solid #ddd;
border-right: 1px solid #ddd;
border-bottom: 1px solid #ddd;
padding: 1px;
padding-top: 15px;
}
.panel-body > p, .panel-body > ul {
text-align: left;
}
// for small devices
@media only screen
and (min-device-width : 320px)
and (max-device-width : 568px) {
h3:before{
content:"";
}
h3:after{
content:"";
}
#charts_tabs {
display:none;
}
#charts_tabs-content {
display:none;
}
}

View File

@ -5,7 +5,7 @@
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading">Password</div> <div class="panel-heading">Password</div>
<div class="panel-body"> <div class="panel-body">
<a href='{{ url_for('security.change_password') }}'> <a href='{{ url_for('security.change_password') }}' class="btn btn-primary " role="button">
<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Change <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> Change
</a> </a>
</div> </div>
@ -13,11 +13,12 @@
<div class="panel panel-default"> <div class="panel panel-default">
<div class="panel-heading">Vehicles</div> <div class="panel-heading">Vehicles</div>
<div class="panel-body"> <div class="panel-body">
<a href="{{ url_for('create_vehicle') }}"> <a href="{{ url_for('create_vehicle') }}" class="btn btn-primary " role="button">
<span class="glyphicon glyphicon-plus" aria-hidden="true"></span> create <span class="glyphicon glyphicon-plus" aria-hidden="true"></span> create
</a> </a>
</div> </div>
<table class="table table-striped table-bordered"> <table class="table table-striped table-bordered">
<tbody>
<tr> <tr>
<th> <th>
Vehicle Vehicle
@ -31,18 +32,18 @@
</tr> </tr>
{% for vehicle in current_user.vehicles %} {% for vehicle in current_user.vehicles %}
<tr> <tr>
<td style="text-align:center"> <td>
{{ vehicle.name }} {{ vehicle.name }}
</td> </td>
<td style="text-align:center"> <td>
{{ vehicle.pitstops | length }} pitstops {{ vehicle.pitstops | length }} pitstops
</td> </td>
<td style="text-align:center"> <td>
<a href="{{ url_for('edit_vehicle', vid=vehicle.id) }}"> <a href="{{ url_for('edit_vehicle', vid=vehicle.id) }}" class="btn btn-primary " role="button">
<span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> edit <span class="glyphicon glyphicon-pencil" aria-hidden="true"></span> edit
</a> </a>
{% if current_user.vehicles | length > 1 %} {% if current_user.vehicles | length > 1 %}
<a href="{{ url_for('delete_vehicle', vid=vehicle.id) }}"> <a href="{{ url_for('delete_vehicle', vid=vehicle.id) }}" class="btn btn-primary btn-warning " role="button">
<span class="glyphicon glyphicon-trash" aria-hidden="true"></span> delete <span class="glyphicon glyphicon-trash" aria-hidden="true"></span> delete
</a> </a>
{% else %} {% else %}
@ -51,6 +52,7 @@
</td> </td>
</tr> </tr>
{% endfor %} {% endfor %}
</tbody>
</table> </table>
</div> </div>
{% endblock %} {% endblock %}

View File

@ -1,6 +1,10 @@
{% extends "layout.html" %} {% extends "layout.html" %}
{% block body %} {% block body %}
<div class="col-md-2" ></div>
<div class="col-md-8">
<div class="panel panel-default">
<div class="panel-body">
<h3>Admin</h3> <h3>Admin</h3>
We have {{ data.users|length }} users so far: We have {{ data.users|length }} users so far:
<ul> <ul>
@ -8,5 +12,7 @@
<li>{{user.email}}</li> <li>{{user.email}}</li>
{% endfor %} {% endfor %}
</ul> </ul>
<a href='{{ url_for('security.login', _external=True) }}'>Login</a> </div>
</div>
</div>
{% endblock %} {% endblock %}

View File

@ -1,12 +1,18 @@
{% extends "layout.html" %} {% extends "layout.html" %}
{% block body %} {% block body %}
<div class="col-md-2" ></div>
<div class="col-md-8">
<div class="panel panel-default">
<div class="panel-body">
<h3>Create vehicle</h3> <h3>Create vehicle</h3>
<form class='form-horizontal' method="POST"> <form class='form-horizontal' method="POST">
{{ form.hidden_tag() }} {{ form.hidden_tag() }}
{{ render_field_with_errors(form.name) }} {{ render_field_with_errors(form.name) }}
{{ render_field_with_errors(form.submit) }} {{ render_field_with_errors(form.submit) }}
</form> </form>
</div>
</div>
</div>
<div class="col-md-2" ></div>
{% endblock %} {% endblock %}

View File

@ -1,11 +1,18 @@
{% extends "layout.html" %} {% extends "layout.html" %}
{% block body %} {% block body %}
<h3>Delete vehicle '{{vehicle.name}}'</h3> <div class="col-md-2" ></div>
<div class="col-md-8">
<div class="panel panel-default">
<div class="panel-body">
<h3>Delete vehicle '{{vehicle.name}}'?</h3>
<form class='form-horizontal' method="POST"> <form class='form-horizontal' method="POST">
{{ form.hidden_tag() }} {{ form.hidden_tag() }}
{{ render_field_with_errors(form.submit) }} {{ render_field_with_errors(form.submit) }}
</form> </form>
</div>
</div>
</div>
<div class="col-md-2" ></div>
{% endblock %} {% endblock %}

View File

@ -1,12 +1,18 @@
{% extends "layout.html" %} {% extends "layout.html" %}
{% block body %} {% block body %}
<div class="col-md-2" ></div>
<div class="col-md-8">
<div class="panel panel-default">
<div class="panel-body">
<h3>Edit vehicle</h3> <h3>Edit vehicle</h3>
<form class='form-horizontal' method="POST"> <form class='form-horizontal' method="POST">
{{ form.hidden_tag() }} {{ form.hidden_tag() }}
{{ render_field_with_errors(form.name) }} {{ render_field_with_errors(form.name) }}
{{ render_field_with_errors(form.submit) }} {{ render_field_with_errors(form.submit) }}
</form> </form>
</div>
</div>
</div>
{% endblock %} {% endblock %}

View File

@ -0,0 +1,28 @@
{% extends "layout.html" %}
{% from "security/_macros.html" import render_field_with_errors, render_field %}
{% block body %}
<div class="row">
<div class="col-md-4">
{{ render_login_form() }}
</div>
<div class="col-md-8">
<div class="panel panel-default">
<div class="panel-body" >
<h1>Join the pitstop community!</h1>
<p>There are already {{ data.users}} members with {{ data.vehicles }} vehicles who have logged {{ data.pitstops }} pitstops fuelling {{ data.litres }}l for {{ data.kilometers }}km.</p>
<p>With pitstop community you can:</p>
<ul>
<li>manage multiple vehicles</li>
<li>track each pitstop</li>
<li>get statistics about the fuel consumption</li>
</ul>
<p><a href='{{ url_for('security.register') }}'>Register your account now</a> or <a href='{{ url_for('security.login') }}'>log into your account</a>.</p>
</div>
</div>
</div>
</div>
{% endblock %}

View File

@ -16,14 +16,22 @@
{% macro render_field_with_errors(field) %} {% macro render_field_with_errors(field) %}
<div class="form-group"> <div class="form-group">
{% if field.type == 'SubmitField' %} {% if field.type == 'SubmitField' %}
<div class="col-sm-12" style="align:center"> <div class="col-md-4" ></div>
<div class="col-sm-4" style="align:center">
<input id="{{ field.id }}" name="{{ field.id }}" class="btn btn-default" type="submit" value="{{ field.label.text }}"> <input id="{{ field.id }}" name="{{ field.id }}" class="btn btn-default" type="submit" value="{{ field.label.text }}">
</div> </div>
<!--
<div class="col-sm-3" style="align:center">
<a class="btn btn-default" href="{{ g.data['back'] }}" role="button">Cancel</a>
</div>
-->
<div class="col-md-4" ></div>
{% else %} {% else %}
<label class="col-sm-6 control-label"> <label class="col-sm-6 control-label">
{{ field.label }} {{ field.label }}
</label> </label>
<div class="col-sm-2"> <div class="col-sm-6">
{% if field.type == 'SelectField' %} {% if field.type == 'SelectField' %}
<select id="{{ field.id }}" name="{{ field.id }}" class="form-control"> <select id="{{ field.id }}" name="{{ field.id }}" class="form-control">
{% for choice in field.choices %} {% for choice in field.choices %}
@ -54,7 +62,25 @@
{% endif %} {% endif %}
</div> </div>
{% endif %} {% endif %}
</div>
{% endmacro %}
{% macro render_login_form() %}
<div class="panel panel-default">
<div class="panel-body">
<h3>Login</h3>
<form class='form-horizontal' action="{{ url_for_security('login') }}" method="POST" name="login_user_form">
{{ login_user_form.hidden_tag() }}
{{ render_field_with_errors(login_user_form.email) }}
{{ render_field_with_errors(login_user_form.password) }}
{{ render_field_with_errors(login_user_form.remember) }}
{{ render_field(login_user_form.next) }}
{{ render_field_with_errors(login_user_form.submit) }}
{% if security.recoverable %}
<a href="{{ url_for_security('forgot_password') }}">Forgot password</a>
{% endif %}
</form>
</div>
</div> </div>
{% endmacro %} {% endmacro %}
@ -134,7 +160,7 @@
<span class="icon-bar"></span> <span class="icon-bar"></span>
<span class="icon-bar"></span> <span class="icon-bar"></span>
</button> </button>
<a class="navbar-brand" href="{{ url_for('get_pit_stops') }}">refuel journal</a> <a class="navbar-brand" href="{{ url_for('index') }}">refuel journal</a>
</div> </div>
<div id="navbar" class="collapse navbar-collapse"> <div id="navbar" class="collapse navbar-collapse">
<ul class="nav navbar-nav"> <ul class="nav navbar-nav">
@ -150,6 +176,14 @@
{% endblock %} {% endblock %}
</div> </div>
</div> </div>
{#
<nav class="navbar navbar-inverse navbar-fixed-bottom">
<div class="container">
<div class="navbar-footer">
<a class="navbar-brand" href="">Imprint</a>
</div>
</div>
</nav>
#}
</body> </body>
</html> </html>

View File

@ -1,6 +1,10 @@
{% extends "layout.html" %} {% extends "layout.html" %}
{% block body %} {% block body %}
<div class="col-md-2" ></div>
<div class="col-md-8">
<div class="panel panel-default">
<div class="panel-body">
<h3>New Pitstop for '{{ vehicle.name }}'</h3> <h3>New Pitstop for '{{ vehicle.name }}'</h3>
<form class='form-horizontal' method="POST"> <form class='form-horizontal' method="POST">
{{ form.hidden_tag() }} {{ form.hidden_tag() }}
@ -15,6 +19,7 @@
{{ render_field_with_errors(form.litres) }} {{ render_field_with_errors(form.litres) }}
{{ render_field_with_errors(form.submit) }} {{ render_field_with_errors(form.submit) }}
</form> </form>
</div>
</div>
</div>
{% endblock %} {% endblock %}

View File

@ -14,6 +14,7 @@
{% for vehicle in current_user.vehicles %} {% for vehicle in current_user.vehicles %}
<div class="tab-pane {% if loop.first %}active{% endif %}" id="v{{vehicle.id}}"> <div class="tab-pane {% if loop.first %}active{% endif %}" id="v{{vehicle.id}}">
<h3>{{vehicle.name}}</h3> <h3>{{vehicle.name}}</h3>
{% if vehicle.pitstops %}
<div class="table-responsive"> <div class="table-responsive">
<table class="table table-striped table-bordered table-condensed"> <table class="table table-striped table-bordered table-condensed">
<tr> <tr>
@ -68,6 +69,11 @@
{% endfor %} {% endfor %}
</table> </table>
</div> </div>
{% else %}
<div class="alert alert-warning" role="alert">
not enough data: <a href="{{ url_for('create_pit_stop_form', vid=vehicle.id) }}">log a pitstop</a>?
</div>
{% endif %}
</div> </div>
{% endfor %} {% endfor %}
</div> </div>

View File

@ -2,7 +2,11 @@
{% from "security/_macros.html" import render_field_with_errors, render_field %} {% from "security/_macros.html" import render_field_with_errors, render_field %}
{% block body %} {% block body %}
<h1>Change password</h1> <div class="col-md-2" ></div>
<div class="col-md-8">
<div class="panel panel-default">
<div class="panel-body">
<h3>Change password</h3>
<form class='form-horizontal' action="{{ url_for_security('change_password') }}" method="POST" name="change_password_form"> <form class='form-horizontal' action="{{ url_for_security('change_password') }}" method="POST" name="change_password_form">
{{ change_password_form.hidden_tag() }} {{ change_password_form.hidden_tag() }}
{{ render_field_with_errors(change_password_form.password) }} {{ render_field_with_errors(change_password_form.password) }}
@ -10,4 +14,7 @@
{{ render_field_with_errors(change_password_form.new_password_confirm) }} {{ render_field_with_errors(change_password_form.new_password_confirm) }}
{{ render_field_with_errors(change_password_form.submit) }} {{ render_field_with_errors(change_password_form.submit) }}
</form> </form>
</div>
</div>
</div>
{% endblock %} {% endblock %}

View File

@ -2,10 +2,18 @@
{% from "security/_macros.html" import render_field_with_errors, render_field %} {% from "security/_macros.html" import render_field_with_errors, render_field %}
{% block body %} {% block body %}
<h1>Send password reset instructions</h1> <div class="col-md-2" ></div>
<div class="col-md-8">
<div class="panel panel-default">
<div class="panel-body">
<h3>Reset password</h3>
<form class='form-horizontal' action="{{ url_for_security('forgot_password') }}" method="POST" name="forgot_password_form"> <form class='form-horizontal' action="{{ url_for_security('forgot_password') }}" method="POST" name="forgot_password_form">
{{ forgot_password_form.hidden_tag() }} {{ forgot_password_form.hidden_tag() }}
{{ render_field_with_errors(forgot_password_form.email) }} {{ render_field_with_errors(forgot_password_form.email) }}
{{ render_field_with_errors(forgot_password_form.submit) }} {{ render_field_with_errors(forgot_password_form.submit) }}
</form> </form>
</div>
</div>
<div class="col-md-2" ></div>
</div>
{% endblock %} {% endblock %}

View File

@ -2,16 +2,12 @@
{% from "security/_macros.html" import render_field_with_errors, render_field %} {% from "security/_macros.html" import render_field_with_errors, render_field %}
{% block body %} {% block body %}
<h1>Login</h1> <div class="row">
<form class='form-horizontal' action="{{ url_for_security('login') }}" method="POST" name="login_user_form"> <div class="col-md-2" ></div>
{{ login_user_form.hidden_tag() }} <div class="col-md-8">
{{ render_field_with_errors(login_user_form.email) }} {{ render_login_form() }}
{{ render_field_with_errors(login_user_form.password) }} </div>
{{ render_field_with_errors(login_user_form.remember) }} <div class="col-md-2" ></div>
{{ render_field(login_user_form.next) }} </div>
{{ render_field_with_errors(login_user_form.submit) }}
{% if security.recoverable %}
<a href="{{ url_for_security('forgot_password') }}">Forgot password</a>
{% endif %}
</form>
{% endblock %} {% endblock %}

View File

@ -2,7 +2,11 @@
{% from "security/_macros.html" import render_field_with_errors, render_field %} {% from "security/_macros.html" import render_field_with_errors, render_field %}
{% block body %} {% block body %}
<h1>Register User</h1> <div class="col-md-2" ></div>
<div class="col-md-8">
<div class="panel panel-default">
<div class="panel-body">
<h3>Register</h3>
<form class='form-horizontal' action="{{ url_for_security('register') }}" method="POST" name="register_user_form"> <form class='form-horizontal' action="{{ url_for_security('register') }}" method="POST" name="register_user_form">
{{ register_user_form.hidden_tag() }} {{ register_user_form.hidden_tag() }}
{{ render_field_with_errors(register_user_form.email) }} {{ render_field_with_errors(register_user_form.email) }}
@ -12,4 +16,8 @@
{% endif %} {% endif %}
{{ render_field_with_errors(register_user_form.submit) }} {{ render_field_with_errors(register_user_form.submit) }}
</form> </form>
</div>
</div>
</div>
<div class="col-md-2" ></div>
{% endblock %} {% endblock %}

View File

@ -1,11 +1,19 @@
{% extends "layout.html" %} {% extends "layout.html" %}
{% block body %} {% block body %}
<div class="col-md-2" ></div>
<div class="col-md-8">
<div class="panel panel-default">
<div class="panel-body">
<h3>Select Vehicle</h3> <h3>Select Vehicle</h3>
<form class='form-horizontal' method="POST"> <form class='form-horizontal' method="POST">
{{ form.hidden_tag() }} {{ form.hidden_tag() }}
{{ render_field_with_errors(form.vehicle) }} {{ render_field_with_errors(form.vehicle) }}
{{ render_field_with_errors(form.submit) }} {{ render_field_with_errors(form.submit) }}
</form> </form>
</div>
</div>
</div>
<div class="col-md-2" ></div>
{% endblock %} {% endblock %}

View File

@ -11,7 +11,7 @@
</li> </li>
{% endfor %} {% endfor %}
</ul> </ul>
<div id="vehicle_contetn" class="tab-content"> <div id="vehicle_content" class="tab-content ">
{% for vehicle in data %} {% for vehicle in data %}
<div class="tab-pane {% if loop.first %}active{% endif %}" id="v{{vehicle.id}}"> <div class="tab-pane {% if loop.first %}active{% endif %}" id="v{{vehicle.id}}">
<h3>{{vehicle.name}}</h3> <h3>{{vehicle.name}}</h3>
@ -45,6 +45,11 @@
</div> </div>
<ul id="charts_tabs" class="nav nav-tabs" data-tabs="tabs"> <ul id="charts_tabs" class="nav nav-tabs" data-tabs="tabs">
<li class="active"> <li class="active">
<a href="#v{{vehicle.id}}_c3" id="i{{vehicle.id}}_c3" data-toggle="tab">
Consumption
</a>
</li>
<li>
<a href="#v{{vehicle.id}}_c1" id="i{{vehicle.id}}_c1" data-toggle="tab"> <a href="#v{{vehicle.id}}_c1" id="i{{vehicle.id}}_c1" data-toggle="tab">
Fuelled litres Fuelled litres
</a> </a>
@ -54,21 +59,30 @@
Odometer Odometer
</a> </a>
</li> </li>
<li>
<a href="#v{{vehicle.id}}_c3" id="i{{vehicle.id}}_c3" data-toggle="tab">
Consumption
</a>
</li>
</ul> </ul>
<div id="my-tab-content" class="tab-content"> <div id="charts_tabs-content" class="tab-content">
<div class="tab-pane active" id="v{{vehicle.id}}_c1"> <div class="tab-pane active" id="v{{vehicle.id}}_c3">
{% if vehicle.pitstop_count > 1 %}
<div id="averageUsageDiv{{vehicle.id}}" style="width:100%; height:500px;"></div>
<script type="text/javascript">
{{ chartScript('averageUsageDiv'+vehicle.id|str, vehicle.average_litres, 'l/100 km') }}
</script>
{% else %}
<div class="alert alert-warning" role="alert">
not enough data: <a href="{{ url_for('create_pit_stop_form', vid=vehicle.id) }}">log a pitstop</a>?
</div>
{% endif %}
</div>
<div class="tab-pane " id="v{{vehicle.id}}_c1">
{% if vehicle.pitstop_count > 0 %} {% if vehicle.pitstop_count > 0 %}
<div id="fuelledChartDiv{{vehicle.id}}" style="width:100%; height:500px;"></div> <div id="fuelledChartDiv{{vehicle.id}}" style="width:100%; height:500px;"></div>
<script type="text/javascript"> <script type="text/javascript">
{{ chartScript('fuelledChartDiv'+vehicle.id|str, vehicle.litres, 'l') }} {{ chartScript('fuelledChartDiv'+vehicle.id|str, vehicle.litres, 'l') }}
</script> </script>
{% else %} {% else %}
not enough data. <div class="alert alert-warning" role="alert">
not enough data: <a href="{{ url_for('create_pit_stop_form', vid=vehicle.id) }}">log a pitstop</a>?
</div>
{% endif %} {% endif %}
</div> </div>
<div class="tab-pane " id="v{{vehicle.id}}_c2"> <div class="tab-pane " id="v{{vehicle.id}}_c2">
@ -78,17 +92,9 @@
{{ chartScript('odometerChartDiv'+vehicle.id|str, vehicle.odometers, 'km') }} {{ chartScript('odometerChartDiv'+vehicle.id|str, vehicle.odometers, 'km') }}
</script> </script>
{% else %} {% else %}
not enough data. <div class="alert alert-warning" role="alert">
{% endif %} not enough data: <a href="{{ url_for('create_pit_stop_form', vid=vehicle.id) }}">log a pitstop</a>?
</div> </div>
<div class="tab-pane " id="v{{vehicle.id}}_c3">
{% if vehicle.pitstop_count > 1 %}
<div id="averageUsageDiv{{vehicle.id}}" style="width:100%; height:500px;"></div>
<script type="text/javascript">
{{ chartScript('averageUsageDiv'+vehicle.id|str, vehicle.average_litres, 'l/100 km') }}
</script>
{% else %}
not enough data.
{% endif %} {% endif %}
</div> </div>
</div> </div>