diff --git a/projects/tentacles/config.toml b/projects/tentacles/config.toml index afb4f9b..5313bbb 100644 --- a/projects/tentacles/config.toml +++ b/projects/tentacles/config.toml @@ -1,2 +1,4 @@ +SECRET_KEY = "SgvzxsO5oPBGInmqsyyGQWAJXkS9" + [db] uri = "tentacles.sqlite3" diff --git a/projects/tentacles/src/python/tentacles/__main__.py b/projects/tentacles/src/python/tentacles/__main__.py index e0ba654..0eaa5ef 100644 --- a/projects/tentacles/src/python/tentacles/__main__.py +++ b/projects/tentacles/src/python/tentacles/__main__.py @@ -37,8 +37,13 @@ def user_session(): _, gid, name, _ = current_app.db.fetch_user(uid) request.gid = gid request.username = name + request.is_admin = gid == 0 else: - request.sid = request.uid = request.gid = request.username = None + request.sid = None + request.uid = None + request.gid = None + request.username = None + request.is_admin = False @cli.command() diff --git a/projects/tentacles/src/python/tentacles/blueprints/ui.py b/projects/tentacles/src/python/tentacles/blueprints/ui.py index 6cc1565..a73190a 100644 --- a/projects/tentacles/src/python/tentacles/blueprints/ui.py +++ b/projects/tentacles/src/python/tentacles/blueprints/ui.py @@ -14,6 +14,7 @@ from flask import ( render_template, session, url_for, + flash, ) BLUEPRINT = Blueprint("ui", __name__) @@ -41,14 +42,18 @@ def login(): elif request.method == "POST": if sid := current_app.db.try_login( - request.form["username"], request.form["password"], timedelta(days=1) + username := request.form["username"], + request.form["password"], + timedelta(days=1), ): resp = redirect("/") resp.set_cookie("sid", sid) + flash(f"Welcome, {username}", category="success") return resp else: - return render_template("login.html.j2", error="Incorrect username/password") + flash("Incorrect username/password", category="error") + return render_template("login.html.j2") else: return render_template("login.html.j2") @@ -63,18 +68,19 @@ def register(): if uid := current_app.db.try_create_user( request.form["username"], request.form["password"] ): - return render_template( - "login.html.j2", message="Success, please log in" + flash( + "Please check your email for a verification request", + category="success", ) + return render_template("register.html.j2") except: pass - return render_template( - "login.html.j2", error="Unable to register that username" - ) + flash("Unable to register that username", category="error") + return render_template("register.html.j2") else: - return render_template("login.html.j2") + return render_template("register.html.j2") @BLUEPRINT.route("/logout") diff --git a/projects/tentacles/src/python/tentacles/static/css/style.scss b/projects/tentacles/src/python/tentacles/static/css/style.scss index 89f0add..0fea28a 100644 --- a/projects/tentacles/src/python/tentacles/static/css/style.scss +++ b/projects/tentacles/src/python/tentacles/static/css/style.scss @@ -10,7 +10,7 @@ $secondary_blue: #288BC2; $secondary_green: #A5C426; $secondary_light_grey: #CACBCA; $secondary_dark_grey: #9A9A9A; - +$clear: rgba(255, 255, 255, 255); @font-face { font-family: 'Aaux Next'; @@ -37,6 +37,12 @@ $secondary_dark_grey: #9A9A9A; src: local('Aaux Next'), url('https://fonts.cdnfonts.com/s/60597/aauxnextmdwebfont.woff') format('woff'); } +@import url(https://fonts.googleapis.com/css?family=Raleway); + +.color-yellow { + color: $yellow; +} + html { font-family: 'Aaux Next', sans-serif; background-color: $beige; @@ -44,21 +50,41 @@ html { display: flex; } -body { - width: 100vw; +html, body { + margin: 0; + height: 100%; + width: 100%; + min-width: 400px; +} + +a { + color: $secondary_blue; + text-decoration: none; } *, *::before, *::after { - box-sizing: inherit; margin: 0; padding: 0; } nav { - width: 100%; - border-bottom: $orange 10px solid; - padding-left: 30px; - padding-right: 10px; + background-color: $beige; + box-shadow: 0px 10px 0px $red, + 0px 12px 0px $clear, + 0px 22px 0px $orange, + 0px 24px 0px $clear, + 0px 34px 0px $yellow; + margin-bottom: 34px; + + .logo { + text-decoration: none; + font-weight: bold; + font-size: 60px; + + img { + height: 56px; + } + } } .nav-links { @@ -68,8 +94,6 @@ nav { .nav-item a { display: inline-block; padding: 10px 15px; - text-decoration: none; - color: $secondary_green; } .nav-item:hover { @@ -80,13 +104,127 @@ nav { color: $secondary_blue; } -.logo { - text-decoration: none; - font-weight: bold; - font-size: 60px; +$navbar_height: 50px; +$navbar_padding: 10px; +.navbar { + display: flex; + flex-direction: row; + align-items: center; + justify-content: space-between; + color: #FFF; + padding-left: $navbar_padding; + padding-right: $navbar_padding; + margin-top: $navbar_padding; +} - img { - width: 60px; - height: 60px; +.menu { + display: flex; + flex-direction: row; + list-style-type: none; + margin: 0; + padding: 0; +} + +.menu > li { + margin: 0 1rem; + overflow: hidden; +} + +.menu-button-container { + display: none; + height: 100%; + width: 30px; + cursor: pointer; + flex-direction: column; + justify-content: center; + align-items: center; +} + +#menu-toggle { + display: none; +} + +.menu-button, +.menu-button::before, +.menu-button::after { + display: block; + background-color: $red; + position: absolute; + height: 4px; + width: 30px; + transition: transform 400ms cubic-bezier(0.23, 1, 0.32, 1); + border-radius: 2px; +} + +.menu-button::before { + content: ''; + margin-top: -8px; +} + +.menu-button::after { + content: ''; + margin-top: 8px; +} + +#menu-toggle:checked + .menu-button-container .menu-button::before { + margin-top: 0px; + transform: rotate(405deg); +} + +#menu-toggle:checked + .menu-button-container .menu-button { + background: rgba(255, 255, 255, 0); +} + +#menu-toggle:checked + .menu-button-container .menu-button::after { + margin-top: 0px; + transform: rotate(-405deg); +} + +@media (max-width: 700px) { + .menu-button-container { + display: flex; + } + .menu { + position: absolute; + top: 0; + margin-top: $navbar_height + ($navbar_padding * 3); + left: 0; + flex-direction: column; + width: 100%; + justify-content: left; + align-items: center; + } + #menu-toggle ~ .menu li { + height: 0; + margin: 0; + padding: 0; + border: 0; + transition: height 400ms cubic-bezier(0.23, 1, 0.32, 1); + } + #menu-toggle:checked ~ .menu li { + height: 2.5em; + padding: 0.5em; + transition: height 400ms cubic-bezier(0.23, 1, 0.32, 1); + } + .menu > li { + display: flex; + justify-content: center; + margin: 0; + padding: 0.5em 0; + width: 100%; + color: $secondary_blue; + background-color: $beige; + } + #menu-toggle:checked ~ .menu > li { + border-top: 1px solid #444; + } + #menu-toggle:checked ~ .menu > li:last-child { + border-bottom: 1px solid #444; } } + +.content { + padding-top: 1em; + padding-left: 10%; + padding-right: 10%; +} diff --git a/projects/tentacles/src/python/tentacles/static/tentacles.svg b/projects/tentacles/src/python/tentacles/static/tentacles.svg index de66e96..69cb6ab 100644 --- a/projects/tentacles/src/python/tentacles/static/tentacles.svg +++ b/projects/tentacles/src/python/tentacles/static/tentacles.svg @@ -1,8 +1,8 @@ + fill="#ca4f1f" /> + fill="#edb822" /> + fill="#bb2d2e" /> + fill="#edb822" /> + fill="#edb822" /> + fill="#ca4f1f" /> diff --git a/projects/tentacles/src/python/tentacles/templates/base.html.j2 b/projects/tentacles/src/python/tentacles/templates/base.html.j2 index c706196..1f77969 100644 --- a/projects/tentacles/src/python/tentacles/templates/base.html.j2 +++ b/projects/tentacles/src/python/tentacles/templates/base.html.j2 @@ -1,38 +1,54 @@ + + {% block head %} + Tentacles{% block title %}{% endblock %} {% endblock %} - {% with messages = get_flashed_messages() %} + {% with messages = get_flashed_messages(with_categories=True) %} {% if messages %} -
-
    - {% for message in messages %} -
  • {{ message }}
  • - {% endfor %} -
+
+ {% for category, message in messages %} +
{{ message }}
+ {% endfor %}
{% endif %} {% endwith %} -
+
{% block content %}Oops, an empty page :/{% endblock %}
-