From c4bb51b2712e1e390b8276dc31e3f1da6cc5d4b1 Mon Sep 17 00:00:00 2001 From: datlt4 Date: Fri, 19 Apr 2024 00:04:05 +0700 Subject: [PATCH] feat: restructure `static` and `template` directory --- fhost.py | 39 +++--- static/{ => css}/app.css | 114 ++++++++++++------ static/favicon.ico | Bin 19307 -> 0 bytes static/{ => img}/checkmark.css | 0 static/{ => img}/maintainer_avatar.jpg | Bin static/{ => img}/nullptr.svg | 0 static/{ => js}/app.js | 0 static/{ => js/auth}/activate-account.js | 4 +- .../auth/forgot-password.js} | 0 static/{ => js/auth}/login.js | 0 static/{ => js/auth}/profile.js | 0 static/{ => js/auth}/reset-password.js | 0 static/{ => js/auth}/signup.js | 0 static/{ => js}/header.js | 6 +- static/{ => js}/toast.js | 0 .../{ => auth}/activate-account-success.html | 2 +- templates/{ => auth}/activate-account.html | 4 +- .../{ => auth}/email-activate-account.html | 2 +- .../{ => auth}/email-reset-password.html | 2 +- templates/{ => auth}/forgot-password.html | 4 +- templates/{ => auth}/login.html | 4 +- templates/{ => auth}/profile.html | 4 +- templates/{ => auth}/reset-password.html | 4 +- templates/{ => auth}/signup.html | 4 +- templates/{ => common}/toast-template.html | 2 +- templates/email-welcome.html | 57 --------- templates/{ => errors}/400.html | 0 templates/{ => errors}/401.html | 0 templates/{ => errors}/403.html | 0 templates/{ => errors}/404.html | 0 templates/{ => errors}/405.html | 0 templates/{ => errors}/409.html | 0 templates/{ => errors}/411.html | 0 templates/{ => errors}/413.html | 0 templates/{ => errors}/415.html | 0 templates/{ => errors}/451.html | 0 templates/{ => errors}/500.html | 0 templates/layout.html | 11 +- templates/{ => pages}/index.html | 4 +- templates/{ => partials}/footer.html | 2 +- templates/{ => partials}/header.html | 2 +- 41 files changed, 132 insertions(+), 139 deletions(-) rename static/{ => css}/app.css (72%) delete mode 100644 static/favicon.ico rename static/{ => img}/checkmark.css (100%) rename static/{ => img}/maintainer_avatar.jpg (100%) rename static/{ => img}/nullptr.svg (100%) rename static/{ => js}/app.js (100%) rename static/{ => js/auth}/activate-account.js (96%) rename static/{forgot_password.js => js/auth/forgot-password.js} (100%) rename static/{ => js/auth}/login.js (100%) rename static/{ => js/auth}/profile.js (100%) rename static/{ => js/auth}/reset-password.js (100%) rename static/{ => js/auth}/signup.js (100%) rename static/{ => js}/header.js (70%) rename static/{ => js}/toast.js (100%) rename templates/{ => auth}/activate-account-success.html (98%) rename templates/{ => auth}/activate-account.html (92%) rename templates/{ => auth}/email-activate-account.html (99%) rename templates/{ => auth}/email-reset-password.html (99%) rename templates/{ => auth}/forgot-password.html (95%) rename templates/{ => auth}/login.html (97%) rename templates/{ => auth}/profile.html (99%) rename templates/{ => auth}/reset-password.html (96%) rename templates/{ => auth}/signup.html (98%) rename templates/{ => common}/toast-template.html (57%) delete mode 100644 templates/email-welcome.html rename templates/{ => errors}/400.html (100%) rename templates/{ => errors}/401.html (100%) rename templates/{ => errors}/403.html (100%) rename templates/{ => errors}/404.html (100%) rename templates/{ => errors}/405.html (100%) rename templates/{ => errors}/409.html (100%) rename templates/{ => errors}/411.html (100%) rename templates/{ => errors}/413.html (100%) rename templates/{ => errors}/415.html (100%) rename templates/{ => errors}/451.html (100%) rename templates/{ => errors}/500.html (100%) rename templates/{ => pages}/index.html (99%) rename templates/{ => partials}/footer.html (80%) rename templates/{ => partials}/header.html (98%) diff --git a/fhost.py b/fhost.py index 2665737..22b50cc 100755 --- a/fhost.py +++ b/fhost.py @@ -606,7 +606,7 @@ def activate_required(func): def decorated_function(*args, **kwargs): if (current_user is not None) and (current_user.is_authenticated) and (not current_user.is_confirmed): flash("Your account has not activated yet", "not-activated") - return render_template("activate-account.html") + return render_template("auth/activate-account.html") return func(*args, **kwargs) return decorated_function @@ -668,7 +668,7 @@ def request_activate_account(): send_email(subject="Activate your ZXZ account", sender=app.config["MAIL_USERNAME"], recipients=[current_user.email], text_body="HELLO", - html_body=render_template("email-activate-account.html", token=token, expires_in=app.config["ACTIVATE_EMAIL_TOKEN_EXPIRES_IN"])) + html_body=render_template("auth/email-activate-account.html", token=token, expires_in=app.config["ACTIVATE_EMAIL_TOKEN_EXPIRES_IN"])) return {"status": "OK"} except Exception as e: print(e) @@ -682,12 +682,12 @@ def activate_account(token): return redirect(url_for("fhost")) elif user.is_confirmed: flash('ACCOUNT WAS ACTIVATED SUCCESSFULLY.', 'account-activated') - return render_template("activate-account-success.html") + return render_template("auth/activate-account-success.html") else: user.confirm_email() db.session.commit() flash('ACCOUNT WAS ACTIVATED SUCCESSFULLY.', 'account-activated') - return render_template("activate-account-success.html") + return render_template("auth/activate-account-success.html") @app.route('/forgot-password', methods=["GET", "POST"]) @logout_required @@ -700,19 +700,19 @@ def forgot_password(): flash('Email address has not unregistered yet.', 'unregistered') return redirect(url_for("signup")) token = user.get_reset_password_token(app.config["RESET_PASSWORD_TOKEN_EXPIRES_IN"]*60, type_token="reset-password") - # return render_template("email-reset-password.html", token=token, expires_in=app.config["RESET_PASSWORD_TOKEN_EXPIRES_IN"]) + # return render_template("auth/email-reset-password.html", token=token, expires_in=app.config["RESET_PASSWORD_TOKEN_EXPIRES_IN"]) try: send_email(subject="Reset your ZXZ account password", sender=app.config["MAIL_USERNAME"], recipients=[email], text_body="HELLO", - html_body=render_template("email-reset-password.html", token=token, expires_in=app.config["RESET_PASSWORD_TOKEN_EXPIRES_IN"])) + html_body=render_template("auth/email-reset-password.html", token=token, expires_in=app.config["RESET_PASSWORD_TOKEN_EXPIRES_IN"])) flash('Reset password request sent. Check your email.', 'mail-sent') flash(email, 'fill-email') return redirect(url_for("login")) except Exception as e: abort(HTTPStatus.INTERNAL_SERVER_ERROR) else: - return render_template("forgot-password.html") + return render_template("auth/forgot-password.html") @app.route('/reset-password/', methods=["GET", "POST"]) @logout_required @@ -739,7 +739,7 @@ def reset_password(token:str): else: flash(user.email, 'email') flash(user.username, 'username') - return render_template("reset-password.html", token=token) + return render_template("auth/reset-password.html", token=token) @app.route('/login', methods=["GET", "POST"]) @logout_required @@ -778,7 +778,7 @@ def login(): flash("", 'first-user') return redirect(url_for('signup')) else: - return render_template("login.html") + return render_template("auth/login.html") @app.route('/signup', methods=["GET", "POST"]) @logout_required @@ -820,7 +820,7 @@ def signup(): send_email(subject="Activate your ZXZ account", sender=app.config["MAIL_USERNAME"], recipients=[email], text_body="HELLO", - html_body=render_template("email-activate-account.html", token=token, expires_in=app.config["ACTIVATE_EMAIL_TOKEN_EXPIRES_IN"])) + html_body=render_template("auth/email-activate-account.html", token=token, expires_in=app.config["ACTIVATE_EMAIL_TOKEN_EXPIRES_IN"])) flash('Activate account request sent. Check your email.', 'mail-sent') except Exception as e: print(e) @@ -833,7 +833,7 @@ def signup(): else: if db.session.query(User).count() <= 1: flash("", 'first-user') - return render_template('signup.html') + return render_template('auth/signup.html') @app.route('/logout', methods=["GET", "POST"]) @login_required @@ -845,7 +845,7 @@ def logout(): @login_required @activate_required def profile(): - return render_template("profile.html") + return render_template("auth/profile.html") @app.route('/change-password', methods=["POST"]) @login_required @@ -1014,10 +1014,19 @@ def fhost(): else: f.write(chunk) os.system(f"ls -lht {file_path}") + + # get expires and handle if if expires fields is NaN + expires = None + try: + if "expires" in request.form: + expires = int(request.form["expires"]) + except Exception as e: + print(e) + # Store the file with the requested expiration date return store_file( request.files["file"], - int(request.form["expires"]) if ("expires" in request.form) else None, + expires, request.remote_addr, request.user_agent.string, slugify(request.form["secret"]) if ("secret" in request.form) else None, @@ -1041,7 +1050,7 @@ def fhost(): abort(400) else: - return render_template("index.html") + return render_template("pages/index.html") @app.route('/fetch-content', methods=["POST"]) @activate_required @@ -1117,7 +1126,7 @@ def robots(): @app.errorhandler(500) def ehandler(e): try: - return render_template(f"{e.code}.html", id=id, request=request), e.code + return render_template(f"errors/{e.code}.html", id=id, request=request), e.code except TemplateNotFound: return "Segmentation fault\n", e.code diff --git a/static/app.css b/static/css/app.css similarity index 72% rename from static/app.css rename to static/css/app.css index d7a75d9..a400a26 100644 --- a/static/app.css +++ b/static/css/app.css @@ -12,21 +12,25 @@ } #content-wrap { - padding-bottom: 2.5rem; /* Footer height */ + padding-bottom: 2.5rem; + /* Footer height */ } .footer { - background-color: #343a40; /* Dark color similar to the header */ + background-color: #343a40; + /* Dark color similar to the header */ padding: 20px 0; text-align: center; - color: #fff; /* White text color */ + color: #fff; + /* White text color */ /* position: absolute; */ bottom: 0; width: 100%; } .footer p { - margin-bottom: 5px; /* Add some spacing between paragraphs */ + margin-bottom: 5px; + /* Add some spacing between paragraphs */ } /* Ensure content is pushed down when header and footer are fixed */ @@ -38,7 +42,8 @@ body { display: flex; flex-direction: column; margin: 0; - min-height: 100vh; /* Ensure the body takes up at least the full viewport height */ + min-height: 100vh; + /* Ensure the body takes up at least the full viewport height */ } input:disabled { @@ -46,7 +51,7 @@ input:disabled { } input:hover { - border-color: #0250b7 !important; + border-color: #0250b7 !important; } hr { @@ -64,12 +69,14 @@ hr { /* Add some margin to the bottom of the body content */ .content { - margin-bottom: 70px; /* Height of the footer */ + margin-bottom: 70px; + /* Height of the footer */ } /* Add some spacing to top of content to account for fixed header */ .content { - padding-top: 80px; /* Height of the fixed header + some extra spacing */ + padding-top: 80px; + /* Height of the fixed header + some extra spacing */ } .container { @@ -152,18 +159,24 @@ li:before { } .show { - display: block; /* Display the checkmark when it has the 'show' class */ - opacity: 1; /* Ensure the checkmark is fully visible */ - transition: opacity 0.3s linear; /* Add transition effect for opacity */ + display: block; + /* Display the checkmark when it has the 'show' class */ + opacity: 1; + /* Ensure the checkmark is fully visible */ + transition: opacity 0.3s linear; + /* Add transition effect for opacity */ } .hide { - opacity: 0; /* Set opacity to 0 when hiding */ - transition: opacity 0.2s linear; /* Add transition effect for opacity */ + opacity: 0; + /* Set opacity to 0 when hiding */ + transition: opacity 0.2s linear; + /* Add transition effect for opacity */ } .CodeMirror { - font-size: 11px; /* Adjust the font size as needed */ + font-size: 11px; + /* Adjust the font size as needed */ } .nav-btn { @@ -217,13 +230,15 @@ li:before { } .bi-person { - font-size: 18px; /* Adjust icon size as needed */ + font-size: 18px; + /* Adjust icon size as needed */ } /* Popup container - can be anything you want */ .user-avatar-container { position: relative; } + /* The actual popup */ .popup-profile { visibility: hidden; @@ -264,7 +279,8 @@ li:before { .user-profile-btn { background-color: #373b3e; - align-items: center; /* Center items vertically */ + align-items: center; + /* Center items vertically */ text-align: left; color: #ffffff; border-color: transparent; @@ -278,13 +294,23 @@ li:before { /* Add animation (fade in the popup) */ @-webkit-keyframes fadeIn { - from {opacity: 0;} - to {opacity: 1;} + from { + opacity: 0; + } + + to { + opacity: 0.5; + } } @keyframes fadeIn { - from {opacity: 0;} - to {opacity:1 ;} + from { + opacity: 0; + } + + to { + opacity: 0.5; + } } .accordion-button { @@ -319,43 +345,59 @@ input.form-control { /* Customize the button styles */ .btn-outline-primary.custom-btn { - color: #3b5482; /* Text color */ - border-color: #3b5482; /* Border color */ + color: #3b5482; + /* Text color */ + border-color: #3b5482; + /* Border color */ } .btn-outline-primary.custom-btn:hover { - color: #fff; /* Text color on hover */ - background-color: #3b5482; /* Background color on hover */ - border-color: #3b5482; /* Border color on hover */ + color: #fff; + /* Text color on hover */ + background-color: #3b5482; + /* Background color on hover */ + border-color: #3b5482; + /* Border color on hover */ } .btn-outline-primary.custom-btn { - color: #3b5482; /* Text color */ - border-color: #3b5482; /* Border color */ + color: #3b5482; + /* Text color */ + border-color: #3b5482; + /* Border color */ } .btn-outline-primary.custom-btn:hover { - color: #fff; /* Text color on hover */ - background-color: #3b5482; /* Background color on hover */ - border-color: #3b5482; /* Border color on hover */ + color: #fff; + /* Text color on hover */ + background-color: #3b5482; + /* Background color on hover */ + border-color: #3b5482; + /* Border color on hover */ } .btn-primary.custom-btn:focus { - box-shadow: 0 0 0 0.25rem rgba(59, 84, 130, 0.5); /* Custom focus shadow */ + box-shadow: 0 0 0 0.25rem rgba(59, 84, 130, 0.5); + /* Custom focus shadow */ } .btn-primary.custom-btn { - background-color: #3b5482; /* Background color */ - border-color: #3b5482; /* Border color */ + background-color: #3b5482; + /* Background color */ + border-color: #3b5482; + /* Border color */ } .btn-primary.custom-btn:hover { - background-color: #2a3e5f; /* Darker background color on hover */ - border-color: #2a3e5f; /* Darker border color on hover */ + background-color: #2a3e5f; + /* Darker background color on hover */ + border-color: #2a3e5f; + /* Darker border color on hover */ } .btn-primary.custom-btn:focus { - box-shadow: 0 0 0 0.25rem rgba(59, 84, 130, 0.5); /* Custom focus shadow */ + box-shadow: 0 0 0 0.25rem rgba(59, 84, 130, 0.5); + /* Custom focus shadow */ } .toast-header.danger { diff --git a/static/favicon.ico b/static/favicon.ico deleted file mode 100644 index 5a1bcfe7623a042285ffaa639a30ce9e4c77b698..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 19307 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 diff --git a/static/checkmark.css b/static/img/checkmark.css similarity index 100% rename from static/checkmark.css rename to static/img/checkmark.css diff --git a/static/maintainer_avatar.jpg b/static/img/maintainer_avatar.jpg similarity index 100% rename from static/maintainer_avatar.jpg rename to static/img/maintainer_avatar.jpg diff --git a/static/nullptr.svg b/static/img/nullptr.svg similarity index 100% rename from static/nullptr.svg rename to static/img/nullptr.svg diff --git a/static/app.js b/static/js/app.js similarity index 100% rename from static/app.js rename to static/js/app.js diff --git a/static/activate-account.js b/static/js/auth/activate-account.js similarity index 96% rename from static/activate-account.js rename to static/js/auth/activate-account.js index f0a0696..755494f 100644 --- a/static/activate-account.js +++ b/static/js/auth/activate-account.js @@ -90,9 +90,9 @@ function requestEmailToActivate() { fetch("/request-activate-account", { method: "POST" }) .then(response => { if (response.ok) { - console.log("request-activate-account: OKE"); + insertMessageIntoToast("", "Activation email has sent successfully", "success") } else { - console.log("request-activate-account: FAILED"); + insertMessageIntoToast("", "Got error when sent email", "danger") } }) } diff --git a/static/forgot_password.js b/static/js/auth/forgot-password.js similarity index 100% rename from static/forgot_password.js rename to static/js/auth/forgot-password.js diff --git a/static/login.js b/static/js/auth/login.js similarity index 100% rename from static/login.js rename to static/js/auth/login.js diff --git a/static/profile.js b/static/js/auth/profile.js similarity index 100% rename from static/profile.js rename to static/js/auth/profile.js diff --git a/static/reset-password.js b/static/js/auth/reset-password.js similarity index 100% rename from static/reset-password.js rename to static/js/auth/reset-password.js diff --git a/static/signup.js b/static/js/auth/signup.js similarity index 100% rename from static/signup.js rename to static/js/auth/signup.js diff --git a/static/header.js b/static/js/header.js similarity index 70% rename from static/header.js rename to static/js/header.js index 80a905a..da2ff58 100644 --- a/static/header.js +++ b/static/js/header.js @@ -1,10 +1,10 @@ -document.addEventListener("DOMContentLoaded", function() { +document.addEventListener("DOMContentLoaded", function () { // const avatar = document.getElementById('avatar'); const avatar = document.getElementById('avatar'); if (avatar) { - avatar.addEventListener('click', function() { + avatar.addEventListener('click', function () { avatar.classList.toggle('active'); document.getElementById("popup-user-profile").classList.toggle("show"); }); } -}); \ No newline at end of file +}); diff --git a/static/toast.js b/static/js/toast.js similarity index 100% rename from static/toast.js rename to static/js/toast.js diff --git a/templates/activate-account-success.html b/templates/auth/activate-account-success.html similarity index 98% rename from templates/activate-account-success.html rename to templates/auth/activate-account-success.html index fa7cbef..9fc39b4 100644 --- a/templates/activate-account-success.html +++ b/templates/auth/activate-account-success.html @@ -28,7 +28,7 @@

- {% include "toast-template.html" %} + {% include "common/toast-template.html" %} diff --git a/templates/activate-account.html b/templates/auth/activate-account.html similarity index 92% rename from templates/activate-account.html rename to templates/auth/activate-account.html index d196cdb..80f9888 100644 --- a/templates/activate-account.html +++ b/templates/auth/activate-account.html @@ -29,11 +29,11 @@

- {% include "toast-template.html" %} + {% include "common/toast-template.html" %} - + {% endblock %} diff --git a/templates/email-activate-account.html b/templates/auth/email-activate-account.html similarity index 99% rename from templates/email-activate-account.html rename to templates/auth/email-activate-account.html index 4bf85ea..be4b7df 100644 --- a/templates/email-activate-account.html +++ b/templates/auth/email-activate-account.html @@ -8,7 +8,7 @@ - + diff --git a/templates/email-reset-password.html b/templates/auth/email-reset-password.html similarity index 99% rename from templates/email-reset-password.html rename to templates/auth/email-reset-password.html index 9dda6fa..a955c3e 100644 --- a/templates/email-reset-password.html +++ b/templates/auth/email-reset-password.html @@ -8,7 +8,7 @@ - + diff --git a/templates/forgot-password.html b/templates/auth/forgot-password.html similarity index 95% rename from templates/forgot-password.html rename to templates/auth/forgot-password.html index 809d32a..218f789 100644 --- a/templates/forgot-password.html +++ b/templates/auth/forgot-password.html @@ -46,11 +46,11 @@

- {% include "toast-template.html" %} + {% include "common/toast-template.html" %} - + {% endblock %} diff --git a/templates/login.html b/templates/auth/login.html similarity index 97% rename from templates/login.html rename to templates/auth/login.html index e09cd94..bf59ecb 100644 --- a/templates/login.html +++ b/templates/auth/login.html @@ -71,11 +71,11 @@

- {% include "toast-template.html" %} + {% include "common/toast-template.html" %} - + {% endblock %} diff --git a/templates/profile.html b/templates/auth/profile.html similarity index 99% rename from templates/profile.html rename to templates/auth/profile.html index 0c5adaf..e636230 100644 --- a/templates/profile.html +++ b/templates/auth/profile.html @@ -310,11 +310,11 @@

- {% include "toast-template.html" %} + {% include "common/toast-template.html" %} - + {% endblock %} diff --git a/templates/reset-password.html b/templates/auth/reset-password.html similarity index 96% rename from templates/reset-password.html rename to templates/auth/reset-password.html index e79fc90..5309c19 100644 --- a/templates/reset-password.html +++ b/templates/auth/reset-password.html @@ -55,12 +55,12 @@

- {% include "toast-template.html" %} + {% include "common/toast-template.html" %} - + {% endblock %} \ No newline at end of file diff --git a/templates/signup.html b/templates/auth/signup.html similarity index 98% rename from templates/signup.html rename to templates/auth/signup.html index 9bbb0d9..3faa9c2 100644 --- a/templates/signup.html +++ b/templates/auth/signup.html @@ -91,7 +91,7 @@

- {% include "toast-template.html" %} + {% include "common/toast-template.html" %}
@@ -110,7 +110,7 @@

- + {% endblock %} \ No newline at end of file diff --git a/templates/toast-template.html b/templates/common/toast-template.html similarity index 57% rename from templates/toast-template.html rename to templates/common/toast-template.html index 328fc29..cd45062 100644 --- a/templates/toast-template.html +++ b/templates/common/toast-template.html @@ -1,3 +1,3 @@
- + diff --git a/templates/email-welcome.html b/templates/email-welcome.html deleted file mode 100644 index 7870197..0000000 --- a/templates/email-welcome.html +++ /dev/null @@ -1,57 +0,0 @@ - - - - - - - - - - - - - - - -
-
-
-
- - - - - - - - - - - -
-

- Password Recovery! -

-
-
-

Thank for signin up and welcome to ZXZ.

-

Please check your email inbox and follow the instructions to activate your account.

-
-
-

REGARDS,

-

nullptr team.

-
- -
- - - - -
-
-
-
-
- - - \ No newline at end of file diff --git a/templates/400.html b/templates/errors/400.html similarity index 100% rename from templates/400.html rename to templates/errors/400.html diff --git a/templates/401.html b/templates/errors/401.html similarity index 100% rename from templates/401.html rename to templates/errors/401.html diff --git a/templates/403.html b/templates/errors/403.html similarity index 100% rename from templates/403.html rename to templates/errors/403.html diff --git a/templates/404.html b/templates/errors/404.html similarity index 100% rename from templates/404.html rename to templates/errors/404.html diff --git a/templates/405.html b/templates/errors/405.html similarity index 100% rename from templates/405.html rename to templates/errors/405.html diff --git a/templates/409.html b/templates/errors/409.html similarity index 100% rename from templates/409.html rename to templates/errors/409.html diff --git a/templates/411.html b/templates/errors/411.html similarity index 100% rename from templates/411.html rename to templates/errors/411.html diff --git a/templates/413.html b/templates/errors/413.html similarity index 100% rename from templates/413.html rename to templates/errors/413.html diff --git a/templates/415.html b/templates/errors/415.html similarity index 100% rename from templates/415.html rename to templates/errors/415.html diff --git a/templates/451.html b/templates/errors/451.html similarity index 100% rename from templates/451.html rename to templates/errors/451.html diff --git a/templates/500.html b/templates/errors/500.html similarity index 100% rename from templates/500.html rename to templates/errors/500.html diff --git a/templates/layout.html b/templates/layout.html index 27dea3a..2e0e1b5 100644 --- a/templates/layout.html +++ b/templates/layout.html @@ -12,23 +12,22 @@ - - + + - - + - {% include "header.html" %} + {% include "partials/header.html" %}
{% block content %}{% endblock %}
{% if (request.path != '/login') and (request.path != '/signup') %} - {% include "footer.html" %} + {% include "partials/footer.html" %} {% endif %} diff --git a/templates/index.html b/templates/pages/index.html similarity index 99% rename from templates/index.html rename to templates/pages/index.html index e168f23..d5c9943 100644 --- a/templates/index.html +++ b/templates/pages/index.html @@ -62,7 +62,7 @@

- {% include "toast-template.html" %} + {% include "common/toast-template.html" %}

@@ -330,7 +330,7 @@

- + +