add some css to the mix, add search functionality #3

Open
flynn wants to merge 2 commits from feature/ui into master
14 changed files with 10834 additions and 62 deletions
Showing only changes of commit 0a570aa2c6 - Show all commits

23
app.py
View file

@ -1,6 +1,25 @@
from flask import Flask import os
from flask import Flask, send_from_directory
from flask_sqlalchemy import SQLAlchemy from flask_sqlalchemy import SQLAlchemy
app = Flask(__name__) app = Flask(__name__, static_url_path='/public')
app.config.from_object('config.Configuration') app.config.from_object('config.Configuration')
db = SQLAlchemy(app) db = SQLAlchemy(app)
@app.route('/js/<path:path>')
def send_js(path):
return send_from_directory('public/js', path)
@app.route('/css/<path:path>')
def send_css(path):
return send_from_directory('public/css', path)
@app.route('/favicon.ico')
def favicon():
return send_from_directory(os.path.join(app.root_path, 'public', 'img'),
'favicon.ico',
mimetype='image/vnd.microsoft.icon')

10599
public/css/bulma.css vendored Normal file

File diff suppressed because it is too large Load diff

1
public/css/bulma.css.map Normal file

File diff suppressed because one or more lines are too long

1
public/css/bulma.min.css vendored Normal file

File diff suppressed because one or more lines are too long

3
public/css/index.css Normal file
View file

@ -0,0 +1,3 @@
a {
color: #ff9f00;
}

BIN
public/img/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 361 KiB

27
public/js/users.js Normal file
View file

@ -0,0 +1,27 @@
function searchUser(search) {
matches = [];
users.forEach(user => {
if (user.id.toLowerCase().includes(search.toLowerCase())) {
matches.push(user);
}
});
if (matches.length === 0) {
document.getElementById("users-parent").innerHTML = "<p>No matches found</p>";
} else {
var html = "";
matches.forEach(match => {
html += `
<a href="/users/${match.id}" class="tile is-child box is-4">
<!-- The magical tile element! -->
<p class="title">${ match.id }</p>
<div class="content">
${ match.achievements.length } achievement${(match.achievements.length != 1) ? "s" : "" }
</div>
</a>
`
});
document.getElementById("users-parent").innerHTML = html;
}
}

View file

@ -1,3 +1,3 @@
#!/bin/bash #!/bin/bash
FLASK_APP="endorsement.py" flask run FLASK_APP="endorsement.py" FLASK_DEBUG=true flask run

View file

@ -1,21 +1,36 @@
<html> {% extends 'base.html' %}
<body>
<h2>{{data.name}} by <a href="{{url_for('get_user', id=data.achieved_by)}}">{{ data.achieved_by }} </a></h2>
<ul> {% block content %}
{% for endorser in data.endorsed_by -%}
<div class="section">
<div class="container">
<h2 class="title is-2">Achievement: {{data.name}}</h2>
<h4 class="subtitle is-4">by <a href="{{url_for('get_user', id=data.achieved_by)}}">{{ data.achieved_by }} </a></h4>
<div class="menu">
<p></p>
<ul>
<li>
{% if endorsed -%}
<a href="{{url_for('unendorse_achievement', id=data.id)}}" class="has-text-danger">Unendorse</a>
{% else -%}
<a href="{{url_for('endorse_achievement', id=data.id)}}" class="has-text-success">Endorse</a>
{% endif -%}
</li>
</ul>
<p class="menu-label">Endorsed by</p>
<ul class="menu-list">
{% for endorser in data.endorsed_by -%}
<li> <li>
<a href="{{url_for('get_user', id=endorser.id)}}">{{ endorser.id }} </a> <a href="{{url_for('get_user', id=endorser.id)}}">{{ endorser.id }} </a>
</li> </li>
{% endfor -%} {% endfor -%}
{% if endorsed -%} </ul>
<li> </div>
<a href="{{url_for('unendorse_achievement', id=data.id)}}">Unendorse</a> </div>
</li> </div>
{% else -%}
<li> {% endblock %}
<a href="{{url_for('endorse_achievement', id=data.id)}}">Endorse</a>
</li>
{% endif -%}
</ul>
</body>
</html>

View file

@ -1,12 +1,42 @@
<html> {% extends 'base.html' %}
<body>
<h2>Insert cool name here</h2>
<ul> {% block head %}
{% for user in data -%} <script src="/js/users.js"></script>
<li> {% endblock %}
<a href="{{url_for('get_user', id=user.id)}}">{{ user.id }}</a>: {{ user.achievements|length }} achievement{{ "s" if (user.achievements|length != 1) else "" }}
</li> {% block content %}
{% endfor -%} <div class="section">
</ul> <div class="container">
</body> <h1 class="title is-2">Endorsements</h1>
</html>
<div class="field">
<p class="control has-icons-left has-icons-right">
<input oninput="searchUser(this.value)" class="input" type="text" placeholder="Search">
<span class="icon is-small is-left">
<i class="fas fa-search"></i>
</span>
</p>
</div>
<div class="tile is-ancestor">
<div id="users-parent" class="tile is-parent is-vertical">
{% for user in data -%}
<!-- If you update this block, update it also in the js search function -->
<a href="{{url_for('get_user', id=user.id)}}" class="tile is-child box is-4">
<!-- The magical tile element! -->
<p class="title">{{ user.id }}</p>
<div class="content">
{{ user.achievements|length }} achievement{{ "s" if (user.achievements|length != 1) else "" }}
</div>
</a>
{% endfor -%}
</div>
</div>
</div>
</div>
<script>
var users = {{ data|safe }};
</script>
{% endblock %}

23
templates/base.html Normal file
View file

@ -0,0 +1,23 @@
<html>
<head>
<link rel="stylesheet" href="/css/bulma.css" type="text/css">
<link rel="stylesheet" href="/css/index.css" type="text/css">
{% block head %}
{% endblock %}
</head>
<body>
{% block content %}
No content yet.
{% endblock %}
</body>
</html>

View file

@ -1,15 +1,34 @@
<html> {% extends 'base.html' %}
<body>
<form action="" method="post">
{{ form.csrf }}
<div class="input text">
{{ form.name.label }} {{ form.name }}
</div>
<div class="input submit"> {% block content %}
<input type="submit" value="Add" />
</div> <div class="section"><div class="container">
</form>
</body> <h1 class="title">New achievement</h1>
</html> <form action="" method="post">
{{ form.csrf }}
<div class="field">
<label class="label" for="{{form.name.label.for}}">Name</label>
<div class="control has-icons-left has-icons-right">
<input id="{{form.name.id}}" name="{{form.name.name}}" type="{{form.name.type}}" value="{{form.name.value}}" required="{{form.name.required}}" class="input" placeholder="the bestest boi" >
<span class="icon is-small is-left">
<i class="fas fa-user"></i>
</span>
<span class="icon is-small is-right">
<i class="fas fa-check"></i>
</span>
</div>
</div>
<div class="field">
<div class="control">
<button class="button is-link">Add</button>
</div>
</div>
</form>
</div></div>
{% endblock %}

View file

@ -1,13 +1,29 @@
<html> {% extends 'base.html' %}
<body>
<h2>{{data.id}}</h2>
<ul> {% block content %}
{% for achievement in data.achievements -%} <div class="section">
<li> <div class="container">
<a href="{{url_for('get_achievement', id=achievement.id)}}">{{ achievement.name }}</a>: {{ achievement.endorsed_by|length }} endorsement{{ "s" if (achievement.endorsed_by|length != 1) else "" }}
</li> <h1 class="title is-1">User: {{data.id}}</h1>
{% endfor -%} <h3 class="subtitle is-3">Achievements</h3>
<li> <a href="{{url_for('add_achievement', id=data.id)}}">Add achievement</a></li> <div class="tile is-ancestor">
</ul> <div class="tile is-parent is-vertical">
</body> {% for achievement in data.achievements -%}
</html> <a href="{{url_for('get_achievement', id=achievement.id)}}" class="tile is-child box is-4">
<!-- The magical tile element! -->
<p class="title">{{ achievement.name }}</p>
<div class="content">
{{ achievement.endorsed_by|length }} endorsement{{ "s" if (achievement.endorsed_by|length != 1) else "" }}
</div>
</a>
{% else %}
<h5 class="subtitle is-5">No achievements</h5>
{% endfor -%}
</div>
</div>
<a class="button" href="{{url_for('add_achievement', id=data.id)}}">Add achievement</a>
</div>
</div>
{% endblock %}

21
test.py
View file

@ -1,5 +1,8 @@
from models import User, Achievement import random
import string
from app import db from app import db
from models import Achievement, User
db.drop_all() db.drop_all()
db.create_all() db.create_all()
@ -13,6 +16,22 @@ achievementB = Achievement(name="BB", achieved_by=persoonB.id)
achievementA.endorsed_by.append(persoonC) achievementA.endorsed_by.append(persoonC)
# Long generated lists
for i in range(30):
achievement = Achievement(name=''.join(
random.choices(string.ascii_uppercase + string.digits, k=6)),
achieved_by=persoonA.id)
db.session.add(achievement)
people = [
User(id=''.join(random.choices(string.ascii_uppercase +
string.digits, k=6))) for i in range(30)
]
for person in people:
db.session.add(person)
achievementA.endorsed_by.append(person)
db.session.add(persoonA) db.session.add(persoonA)
db.session.add(persoonB) db.session.add(persoonB)
db.session.add(persoonC) db.session.add(persoonC)