Pārlūkot izejas kodu

style-sheet changes, and dynamically tweaking static urls, etc.

jacob-kruger-work 2 mēneši atpakaļ
vecāks
revīzija
8a5937113f

+ 7 - 2
flask_app/app/__init__.py

@@ -9,6 +9,11 @@ from datetime import datetime, timezone, timedelta
 def create_app(config_class=Config):
     app = Flask(__name__)
     app.config.from_object(config_class)
+    
+    @app.context_processor
+    def inject_url_values():
+        return dict(static_prefix="cv_db/")
+    # end of inject_url_values
 
     # Initialize Flask extensions here
     db.init_app(app)
@@ -50,7 +55,7 @@ def create_app(config_class=Config):
         s_tb = " | ".join(l_tb)
         s_path = str(request.path)
         s_dt = datetime.now().astimezone(timezone(timedelta(hours=2))).strftime("%Y-%m-%d %H:%M:%S")
-        s_logging = f"<ul><li>date-time: {s_dt}</li>\n<li>line no.: {d_exc['i_lineno']}</li>\n<li>filename: {d_exc['s_filename']}</li>\n<li>except: {d_exc['s_except']}</li>\n<li>additional: {d_exc['s_additional']}</li>\n</ul>" if isinstance(d_exc, dict) else f"date-time: {s_dt}\n{s_path}\n" + str(d_exc["s_except"])
+        s_logging = f"<ul><li>date-time: {s_dt}</li>\n<li>filename: {d_exc['s_filename']}</li>\n<li>line no.: {d_exc['i_lineno']}</li>\n<li>except: {d_exc['s_except']}</li>\n<li>additional: {d_exc['s_additional']}</li>\n</ul>" if isinstance(d_exc, dict) else f"date-time: {s_dt}\n{s_path}\n" + str(d_exc["s_except"])
         d_out = {"url": request.url.replace(request.url_root, ""), "file": d_exc["s_filename"], "line no.": d_exc["i_lineno"], "exception": d_exc["s_except"], "traceback": s_tb}
         d_exc["traceback"] = d_exc["s_tb"].split("|")
         return render_template("errors/500.html", js=True, s_alert="", exc=d_exc, html_content=s_logging), 500
@@ -65,6 +70,6 @@ def create_app(config_class=Config):
     def my_d_format(dt_date_time):
         return dt_date_time.strftime("%Y-%m-%d")
     # end of my_d_format filter function
-
+    
     return app
 # end of create_app function

+ 2 - 1
flask_app/app/main/routes.py

@@ -83,7 +83,7 @@ def index():
                 if bl_case_sensitive:
                     sq_names = select(tbl_records.id).filter(or_(tbl_records.v_name_1.like(s_name), tbl_records.v_name_2.like(s_name), tbl_records.v_name_3.like(s_name)))
                 else:
-                    sq_names = select(tbl_records.id).filter(or_(lower(tbl_records.v_name_1).like(func.lower(s_name)), func.lower(tbl_records.v_name_2).like(func.lower(s_name)), func.lower(tbl_records.v_name_3).like(func.lower(s_name))))
+                    sq_names = select(tbl_records.id).filter(or_(func.lower(tbl_records.v_name_1).like(func.lower(s_name)), func.lower(tbl_records.v_name_2).like(func.lower(s_name)), func.lower(tbl_records.v_name_3).like(func.lower(s_name))))
                 # end of checking if case sensitivity applies
                 q_records = q_records.filter(tbl_records.id.in_(sq_names))
             # end of checking if need to check for name substrings
@@ -818,6 +818,7 @@ def user_details(i_user_id:int = 0):
 @bp.route("/css_sample", methods=["GET"])
 def css_sample():
     """CSS sample page - purely testing"""
+    return redirect(url_for("main.index"))
     s_base = "base_bs.html" if Config.BOOTSTRAP else "base.html"
     s_url = url_for("main.index")#, _external=True)
     return render_template("css_sample.html", js=True, base=s_base, url=s_url)

+ 393 - 0
flask_app/app/static/cv_db/css/alteram/combined_styles.css

@@ -0,0 +1,393 @@
+@font-face {
+font-family: CaviarDreams;
+src: local("CaviarDreams"), url(https://dev.blindza.com/static/cv_db/css/alteram/CaviarDreams.woff) format("woff"), url(https://dev.blindza.com/static/cv_db/css/alteram/CaviarDreams.ttf) format("truetype");
+font-weight: normal
+}
+@font-face {
+font-family: CaviarDreams;
+src: local("CaviarDreams"), url(https://dev.blindza.com/static/cv_db/css/alteram/CaviarDreams_Bold.woff) format("woff"), url(https://dev.blindza.com/static/cv_db/css/alteram/CaviarDreams_Bold.ttf) format("truetype");
+font-weight: bold;
+font-style: normal
+}
+body {
+font-family: CaviarDreams, Arial, sans-serif;
+background-color: var(--background-color);
+color: var(--primary-color);
+position: relative
+min-height: 100vh;
+display: flex;
+flex-direction: column
+}
+h2 {
+font-family: CaviarDreams, Arial, sans-serif;
+font-size: 14pt;
+background-color: white;
+color: rgb(39, 37, 92)
+}
+a {
+color: rgb(250, 122, 30)
+}
+a.visited {
+color: rgb(250, 122, 30)
+}
+#tbl_layout {
+border: 0px solid transparent
+}
+#tbl_layout td {
+text-align: left
+}
+.td_nav {
+width: 20%
+}
+.td_top {
+vertical-align: top
+}
+div {
+line-height: 1.2;
+margin-bottom: 10px
+}
+table.multirow {
+border: 2px solid DimGray
+}
+table.multirow tr {
+vertical-align: top
+}
+table.multirow th {
+text-align: left;
+border: 1px solid DimGray
+}
+table.multirow td {
+text-align: left;
+border: 1px solid DimGray
+}
+:root {
+--primary-color: rgb(39, 37, 92);
+--accent-color: rgb(250, 122, 30);
+--accent-light: rgba(250, 122, 30, 0.8);
+--accent-lighter: rgba(250, 122, 30, 0.1);
+--background-color: white;
+--table-header-bg: rgba(39, 37, 92, 0.9);
+--table-row-hover: rgba(250, 122, 30, 0.05);
+--table-border: rgba(39, 37, 92, 0.2)
+}
+* {
+margin: 0;
+padding: 0;
+box-sizing: border-box
+}
+.background-container {
+position: fixed;
+top: 0;
+left: 0;
+width: 120%;
+height: 100vh;
+background-image: url("https://dev.blindza.com/static/cv_db/css/alteram/alteram1_1_600x197.png");
+background-repeat: no-repeat;
+background-position: center;
+background-attachment: fixed;
+background-size: cover;
+z-index: -1;
+opacity: 0.15
+}
+header {
+background-color: rgba(255, 255, 255, 0.95);
+padding: 1rem 0;
+box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
+position: fixed;
+width: 100%;
+top: 0;
+z-index: 100
+}
+.header-container {
+display: flex;
+justify-content: space-between;
+align-items: center;
+padding: 5 2rem;
+max-width: 1140px;
+margin: 0 auto
+}
+.logo-area {
+width: 180px;
+height: 60px;
+background-image: url("https://dev.blindza.com/static/cv_db/css/alteram/alteram1_1_600x197.png");
+background-size: contain;
+background-repeat: no-repeat;
+background-position: left center;
+margin-left: -250px;
+margin-right: 40px
+}
+nav {
+display: flex;
+align-items: center
+}
+ul.nav {
+width: 100%
+display: flex;
+list-style: none;
+gap: 1rem;
+flex-wrap: nowrap;
+justify-content: center;
+align-items: center;
+padding: 0;
+margin: 0;
+height: 100%
+}
+ul.nav li {
+margin: 0;
+height: 40px;
+display: inline-block;
+align-items: center
+}
+ul.nav li a {
+color: var(--accent-color);
+text-decoration: none;
+font-weight: 600;
+padding: 0.75rem 1.5rem;
+border-radius: 4px;
+transition: all 0.3s ease;
+background-color: transparent;
+border: 2px solid var(--accent-color);
+white-space: nowrap;
+display: flex;
+align-items: center;
+justify-content: center;
+height: 100%;
+font-size: 0.95rem;
+letter-spacing: 0.02em
+}
+ul.nav li a:hover, ul.nav li a[aria-current="true"] {
+background-color: var(--accent-color);
+color: white;
+transform: translatey(-2px);
+box-shadow: 0 4px 12px rgba(250, 122, 30, 0.2)
+}
+main {
+padding-top: 250px;
+min-height: calc(100vh - 100px);
+justify-content: center
+}
+.content-container.content {
+width: auto;
+max-width: 120%;
+height: auto;
+max-height: 180%;
+margin: 2rem auto;
+padding: 0 2rem;
+overflow-x: auto;
+display: block;
+position: relative
+}
+.data-table {
+width: auto;
+min-width: 100%;
+border-collapse: collapse;
+position: relative
+background-color: rgba(255, 255, 255, 0.95);
+box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
+border-radius: 8px;
+border: 1px solid var(--table-border);
+table-layout: auto
+}
+.changed-element::after {
+content: "→";
+position: absolute;
+right: -20px;
+top: 50%;
+transform: translatey(-50%);
+width: 10px;
+height: 10px;
+background-color: #4CAF50;
+border-radius: 50%;
+color: white;
+display: flex;
+align-items: center;
+justify-content: center;
+font-size: 12px;
+padding: 8px
+}
+.data-table td {
+padding: 8px;
+white-space: normal;
+word-wrap: break-word;
+max-width: 300px;
+min-width: 120px
+}
+.data-table td:nth-child(6) {
+min-width: 250px
+}
+.data-table th {
+background-color: var(--table-header-bg);
+color: white;
+padding: 1rem;
+text-align: left;
+font-weight: bold
+}
+.data-table td {
+padding: 1rem;
+border-bottom: 1px solid var(--table-border)
+}
+.data-table tbody tr:hover {
+background-color: var(--table-row-hover)
+}
+#div_alert {
+position: fixed;
+bottom: 20px;
+left: 50%;
+transform: translatex(-50%);
+background-color: var(--accent-color);
+color: white;
+padding: 1rem 2rem;
+border-radius: 4px;
+z-index: 1000;
+display: none;
+max-width: 80%;
+box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1)
+}
+#div_alert.warning {
+background-color: #e53e3e
+}
+@media (max-width: 768px) {
+.header-container {
+flex-direction: column;
+gap: 1.5rem;
+padding: 1rem
+}
+ul.nav li {
+margin: 0.25rem
+}
+ul.nav li a {
+padding: 0.5rem 1rem;
+font-size: 0.9rem
+}
+}
+table.multirow td {
+text-align: left;
+border: 1px solid DimGray
+}
+ul.nav li a:hover {
+background-color: var(--accent-color);
+color: white
+}
+.content {
+flex: 1;
+max-width: 500px;
+margin: 2rem auto;
+padding: 2rem;
+background: rgba(255, 255, 255, 0.95);
+border-radius: 8px;
+box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1)
+}
+.title h2 {
+font-family: CaviarDreams, Arial, sans-serif;
+color: var(--primary-color);
+font-size: 2rem;
+margin-bottom: 2rem;
+text-align: center
+}
+form {
+display: flex;
+flex-direction: column;
+gap: 1.5rem
+}
+label {
+display: block;
+margin-bottom: 0.75rem;
+font-weight: 700;
+font-size: 1.1rem;
+color: var(--primary-color);
+font-family: "CaviarDreams", sans-serif
+}
+.input-actions {
+display: flex;
+gap: 0.5rem;
+align-items: center
+}
+input[type="text"], input[type="password"] {
+width: 100%;
+padding: 0.75rem;
+border: 2px solid rgba(39, 37, 92, 0.2);
+border-radius: 4px;
+font-family: inherit;
+font-size: 1rem;
+transition: border-color 0.3s ease
+}
+input[type="text"]:focus, input[type="password"]:focus {
+outline: none;
+border-color: var(--accent-color)
+}
+input[type="submit"] {
+background-color: var(--accent-color);
+color: white;
+border: none;
+padding: 1rem;
+border-radius: 4px;
+font-family: inherit;
+font-weight: bold;
+font-size: 1rem;
+cursor: pointer;
+transition: all 0.3s ease
+}
+input[type="submit"]:hover {
+transform: translatey(-2px);
+box-shadow: 0 4px 12px rgba(250, 122, 30, 0.2)
+}
+#div_alert {
+position: fixed;
+bottom: 20px;
+left: 50%;
+transform: translatex(-50%);
+background-color: var(--accent-color);
+color: white;
+padding: 1rem 2rem;
+border-radius: 4px;
+text-align: center;
+z-index: 1000;
+display: none;
+max-width: 80%;
+box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1)
+}
+#div_alert.warning {
+background-color: #e53e3e
+}
+@media (max-width: 768px) {
+.content {
+margin: 1rem;
+padding: 1.5rem
+}
+}
+.table-container {
+display: flex;
+justify-content: center;
+/* centers the table */
+padding: 2rem
+}
+/*   .data-table th, */
+.data-table td {
+padding: 1rem;
+border: 1px solid rgba(39, 37, 92, 0.2);
+text-align: left;
+color: var(--primary-color)
+}
+.data-table th label {
+color: white;
+font-weight: bold;
+display: block;
+margin-bottom: 0.5rem
+}
+div.div_data_filtering {
+background: var(--background-color);
+border-radius: 8px;
+padding: 20px;
+margin-bottom: 30px;
+}
+div.div_data_filtering h3 {
+margin-bottom: 20px;
+}
+div.div_filter_row {
+display: flex;
+flex-wrap: wrap;
+gap: 20px;
+}
+button img {
+vertical-align: middle;
+}

+ 9 - 11
flask_app/app/templates/base.html

@@ -3,10 +3,10 @@
 <head>
 <META http-equiv="Content-Type" content="text/html; charset=utf-8">
 <META http-equiv="Content-Style-Type" content="text/css">
-<meta name="viewport" content="width=device-width, initial-scale=0.75">
-<link rel="icon" type="image/x-icon" sizes="32x32" href="{{ url_for("static", filename="cv_db/favicon.ico") }}">
+<meta name="viewport" content="width=device-width, initial-scale=0.8">
+<link rel="icon" type="image/x-icon" sizes="32x32" href="{{ url_for("static", filename=static_prefix+"favicon.ico") }}">
 {% if js %}
-<script type="text/javascript" src="{{ url_for("static", filename="cv_db/js/jquery.js") }}"></script>
+<script type="text/javascript" src="{{ url_for("static", filename=static_prefix+"js/jquery.js") }}"></script>
 <script type="text/javascript">
 var do_alert;
 
@@ -52,9 +52,9 @@ if (String(s_msg).length>0) {
 </script>
 {% endif %}{# end of js check #}
 <title>C.V. Database - {% block title %}{% endblock %}</title>
-<link type="text/css" rel="stylesheet" href="{{ url_for("static", filename="cv_db/css/styles.css") }}" />
-<link type="text/css" rel="stylesheet" href="{{ url_for("static", filename="cv_db/css/alteram/styles_1.css") }}" />
-<link type="text/css" rel="stylesheet" href="{{ url_for("static", filename="cv_db/css/alteram/styles_2.css") }}" />
+<style>
+{% include("combined_styles.css") %}
+</style>
 {% block head_extra %}{% endblock head_extra %}
 </head>
 <body>
@@ -85,12 +85,10 @@ if (String(s_msg).length>0) {
 </div><!-- end of div.header-container -->
 </header>
 
-<main>
-<div class="background-container"></div>
-<div class="content-container content">
+<!-- Wrapper for the entire content to provide spacing from navbar -->
+<div style="padding: 100px 20px 20px 20px; font-family: CaviarDreams, Arial, sans-serif; background: #f0f0f0; min-height: 100vh;">
 <div id="div_alert" style="text-align: center;" aria-live="assertive">&nbsp;</div>
 {% block content %}{% endblock %}
-</div><!-- end of div.content -->
-</main>
+</div><!-- end of wrapper for the entire content -->
 </body>
 </html>

+ 1 - 1
flask_app/app/templates/capture_record.html

@@ -1,7 +1,7 @@
 {% extends base %}
 
 {% block content %}
-{% import "macros/action_icons_static.html" as icons %}
+{% import "macros/action_icons_static.html" as icons with context %}
 <span class="title"><h2>{% block title %}Add/edit record{% endblock %}</h2></span>
 <div class="content-container content">
 {% if record_id>0 %}<div><a href="{{ url_for("main.uploads", i_record=record_id) }}">Record Uploads</a></div>{% endif %}

+ 393 - 0
flask_app/app/templates/combined_styles.css

@@ -0,0 +1,393 @@
+@font-face {
+font-family: CaviarDreams;
+src: local("CaviarDreams"), url("{{ url_for("static", filename=static_prefix+"css/alteram/CaviarDreams.woff") }}") format("woff"), url("{{ url_for("static", filename=static_prefix+"css/alteram/CaviarDreams.ttf") }}") format("truetype");
+font-weight: normal
+}
+@font-face {
+font-family: CaviarDreams;
+src: local("CaviarDreams"), url("{{ url_for("static", filename=static_prefix+"css/alteram/CaviarDreams_Bold.woff") }}") format("woff"), url("{{ url_for("static", filename=static_prefix+"css/alteram/CaviarDreams_Bold.ttf") }}") format("truetype");
+font-weight: bold;
+font-style: normal
+}
+body {
+font-family: CaviarDreams, Arial, sans-serif;
+background-color: var(--background-color);
+color: var(--primary-color);
+position: relative
+min-height: 100vh;
+display: flex;
+flex-direction: column
+}
+h2 {
+font-family: CaviarDreams, Arial, sans-serif;
+font-size: 14pt;
+background-color: white;
+color: rgb(39, 37, 92)
+}
+a {
+color: rgb(250, 122, 30)
+}
+a.visited {
+color: rgb(250, 122, 30)
+}
+#tbl_layout {
+border: 0px solid transparent
+}
+#tbl_layout td {
+text-align: left
+}
+.td_nav {
+width: 20%
+}
+.td_top {
+vertical-align: top
+}
+div {
+line-height: 1.2;
+margin-bottom: 10px
+}
+table.multirow {
+border: 2px solid DimGray
+}
+table.multirow tr {
+vertical-align: top
+}
+table.multirow th {
+text-align: left;
+border: 1px solid DimGray
+}
+table.multirow td {
+text-align: left;
+border: 1px solid DimGray
+}
+:root {
+--primary-color: rgb(39, 37, 92);
+--accent-color: rgb(250, 122, 30);
+--accent-light: rgba(250, 122, 30, 0.8);
+--accent-lighter: rgba(250, 122, 30, 0.1);
+--background-color: white;
+--table-header-bg: rgba(39, 37, 92, 0.9);
+--table-row-hover: rgba(250, 122, 30, 0.05);
+--table-border: rgba(39, 37, 92, 0.2)
+}
+* {
+margin: 0;
+padding: 0;
+box-sizing: border-box
+}
+.background-container {
+position: fixed;
+top: 0;
+left: 0;
+width: 120%;
+height: 100vh;
+background-image: url("{{ url_for("static", filename=static_prefix+"css/alteram/alteram1_1_600x197.png") }}");
+background-repeat: no-repeat;
+background-position: center;
+background-attachment: fixed;
+background-size: cover;
+z-index: -1;
+opacity: 0.15
+}
+header {
+background-color: rgba(255, 255, 255, 0.95);
+padding: 1rem 0;
+box-shadow: 0 2px 10px rgba(0, 0, 0, 0.05);
+position: fixed;
+width: 100%;
+top: 0;
+z-index: 100
+}
+.header-container {
+display: flex;
+justify-content: space-between;
+align-items: center;
+padding: 5 2rem;
+max-width: 1140px;
+margin: 0 auto
+}
+.logo-area {
+width: 180px;
+height: 60px;
+background-image: url(""{{ url_for("static", filename=static_prefix+"css/alteram/alteram1_1_600x197.png") }}");
+background-size: contain;
+background-repeat: no-repeat;
+background-position: left center;
+margin-left: -250px;
+margin-right: 40px
+}
+nav {
+display: flex;
+align-items: center
+}
+ul.nav {
+width: 100%
+display: flex;
+list-style: none;
+gap: 1rem;
+flex-wrap: nowrap;
+justify-content: center;
+align-items: center;
+padding: 0;
+margin: 0;
+height: 100%
+}
+ul.nav li {
+margin: 0;
+height: 40px;
+display: inline-block;
+align-items: center
+}
+ul.nav li a {
+color: var(--accent-color);
+text-decoration: none;
+font-weight: 600;
+padding: 0.75rem 1.5rem;
+border-radius: 4px;
+transition: all 0.3s ease;
+background-color: transparent;
+border: 2px solid var(--accent-color);
+white-space: nowrap;
+display: flex;
+align-items: center;
+justify-content: center;
+height: 100%;
+font-size: 0.95rem;
+letter-spacing: 0.02em
+}
+ul.nav li a:hover, ul.nav li a[aria-current="true"] {
+background-color: var(--accent-color);
+color: white;
+transform: translatey(-2px);
+box-shadow: 0 4px 12px rgba(250, 122, 30, 0.2)
+}
+main {
+padding-top: 250px;
+min-height: calc(100vh - 100px);
+justify-content: center
+}
+.content-container.content {
+width: auto;
+max-width: 120%;
+height: auto;
+max-height: 180%;
+margin: 2rem auto;
+padding: 0 2rem;
+overflow-x: auto;
+display: block;
+position: relative
+}
+.data-table {
+width: auto;
+min-width: 100%;
+border-collapse: collapse;
+position: relative
+background-color: rgba(255, 255, 255, 0.95);
+box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1);
+border-radius: 8px;
+border: 1px solid var(--table-border);
+table-layout: auto
+}
+.changed-element::after {
+content: "→";
+position: absolute;
+right: -20px;
+top: 50%;
+transform: translatey(-50%);
+width: 10px;
+height: 10px;
+background-color: #4CAF50;
+border-radius: 50%;
+color: white;
+display: flex;
+align-items: center;
+justify-content: center;
+font-size: 12px;
+padding: 8px
+}
+.data-table td {
+padding: 8px;
+white-space: normal;
+word-wrap: break-word;
+max-width: 300px;
+min-width: 120px
+}
+.data-table td:nth-child(6) {
+min-width: 250px
+}
+.data-table th {
+background-color: var(--table-header-bg);
+color: white;
+padding: 1rem;
+text-align: left;
+font-weight: bold
+}
+.data-table td {
+padding: 1rem;
+border-bottom: 1px solid var(--table-border)
+}
+.data-table tbody tr:hover {
+background-color: var(--table-row-hover)
+}
+#div_alert {
+position: fixed;
+bottom: 20px;
+left: 50%;
+transform: translatex(-50%);
+background-color: var(--accent-color);
+color: white;
+padding: 1rem 2rem;
+border-radius: 4px;
+z-index: 1000;
+display: none;
+max-width: 80%;
+box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1)
+}
+#div_alert.warning {
+background-color: #e53e3e
+}
+@media (max-width: 768px) {
+.header-container {
+flex-direction: column;
+gap: 1.5rem;
+padding: 1rem
+}
+ul.nav li {
+margin: 0.25rem
+}
+ul.nav li a {
+padding: 0.5rem 1rem;
+font-size: 0.9rem
+}
+}
+table.multirow td {
+text-align: left;
+border: 1px solid DimGray
+}
+ul.nav li a:hover {
+background-color: var(--accent-color);
+color: white
+}
+.content {
+flex: 1;
+max-width: 500px;
+margin: 2rem auto;
+padding: 2rem;
+background: rgba(255, 255, 255, 0.95);
+border-radius: 8px;
+box-shadow: 0 4px 20px rgba(0, 0, 0, 0.1)
+}
+.title h2 {
+font-family: CaviarDreams, Arial, sans-serif;
+color: var(--primary-color);
+font-size: 2rem;
+margin-bottom: 2rem;
+text-align: center
+}
+form {
+display: flex;
+flex-direction: column;
+gap: 1.5rem
+}
+label {
+display: block;
+margin-bottom: 0.75rem;
+font-weight: 700;
+font-size: 1.1rem;
+color: var(--primary-color);
+font-family: "CaviarDreams", sans-serif
+}
+.input-actions {
+display: flex;
+gap: 0.5rem;
+align-items: center
+}
+input[type="text"], input[type="password"] {
+width: 100%;
+padding: 0.75rem;
+border: 2px solid rgba(39, 37, 92, 0.2);
+border-radius: 4px;
+font-family: inherit;
+font-size: 1rem;
+transition: border-color 0.3s ease
+}
+input[type="text"]:focus, input[type="password"]:focus {
+outline: none;
+border-color: var(--accent-color)
+}
+input[type="submit"] {
+background-color: var(--accent-color);
+color: white;
+border: none;
+padding: 1rem;
+border-radius: 4px;
+font-family: inherit;
+font-weight: bold;
+font-size: 1rem;
+cursor: pointer;
+transition: all 0.3s ease
+}
+input[type="submit"]:hover {
+transform: translatey(-2px);
+box-shadow: 0 4px 12px rgba(250, 122, 30, 0.2)
+}
+#div_alert {
+position: fixed;
+bottom: 20px;
+left: 50%;
+transform: translatex(-50%);
+background-color: var(--accent-color);
+color: white;
+padding: 1rem 2rem;
+border-radius: 4px;
+text-align: center;
+z-index: 1000;
+display: none;
+max-width: 80%;
+box-shadow: 0 5px 15px rgba(0, 0, 0, 0.1)
+}
+#div_alert.warning {
+background-color: #e53e3e
+}
+@media (max-width: 768px) {
+.content {
+margin: 1rem;
+padding: 1.5rem
+}
+}
+.table-container {
+display: flex;
+justify-content: center;
+/* centers the table */
+padding: 2rem
+}
+/*   .data-table th, */
+.data-table td {
+padding: 1rem;
+border: 1px solid rgba(39, 37, 92, 0.2);
+text-align: left;
+color: var(--primary-color)
+}
+.data-table th label {
+color: white;
+font-weight: bold;
+display: block;
+margin-bottom: 0.5rem
+}
+div.div_data_filtering {
+background: var(--background-color);
+border-radius: 8px;
+padding: 20px;
+margin-bottom: 30px;
+}
+div.div_data_filtering h3 {
+margin-bottom: 20px;
+}
+div.div_filter_row {
+display: flex;
+flex-wrap: wrap;
+gap: 20px;
+}
+button img {
+vertical-align: middle;
+}

+ 1 - 1
flask_app/app/templates/icons.html

@@ -5,7 +5,7 @@
 <title>collection of icons</title>
 </head>
 <body>
-{% import "macros/action_icons_static.html" as icons %}
+{% import "macros/action_icons_static.html" as icons with context %}
 <div>{{ icons.add_svg(width=16) }}</div>
 <div>{{ icons.add_svg(bl_quotes=False, width=16) }}</div>
 <div>{{ icons.delete_svg(width=16) }}</div>

+ 86 - 56
flask_app/app/templates/index.html

@@ -4,73 +4,103 @@
 .label {
 font-weight: bold;
 }
-# tbl_filters {
-border: 1px solid transparent;
-}
-#tbl_filters tr {
-vertical-align: top;
-}
-#tbl_filters th, #tbl_filters td {
-text-align: left;
-color: dark-blue;
-}
-div.paging {
-color: dark-blue;
-font-size: smaller;
-}
 </style>
 {% endblock %}
 
 {% block content %}
-{% import "macros/action_icons_static.html" as icons %}
+{% import "macros/action_icons_static.html" as icons with context %}
 <span class="title"><h2>{% block title %}Landing page{% endblock %}</h2></span>
 <div class="content-container content">
-<div id="div_filter">
+<div id="div_filter" class="div_data_filtering">
 <h3>Filtering/Searching options</h3>
 <form action="{{ url_for("main.index") }}" method="post" id="frm_filters">
 {{ filter_form.csrf_token }}
 {{ filter_form.hid_page }}
-<div>
-<button type="submit" name="btn_filter" value="Apply Filters">{{ icons.search_svg(s_label="apply filters") }}</button><button type="button" id="btn_clear_filter" name="btn_clear_filter" value="Clear Filters">{{ icons.delete_svg(s_label="remove filters") }}</button><br>
-<span style="font-size: smaller;">{{ filter_form.chk_case_sensitive }}&nbsp;{{ filter_form.chk_case_sensitive.label }}</span>
+<!-- Buttons -->
+<div style="margin-bottom: 15px; display: flex; align-items: center; gap: 10px;">
+<button type="submit" name="btn_filter" value="Apply Filters" style="background-color: rgb(39, 37, 92); color: white; border: none; padding: 8px 12px; border-radius: 4px; cursor: pointer;">
+{{ icons.search_svg(s_label="apply filters") }}
+Search
+</button>
+<button type="button" id="btn_clear_filter" name="btn_clear_filter" value="Clear Filters" style="background-color: rgb(39, 37, 92); color: white; border: none; padding: 8px 12px; border-radius: 4px; cursor: pointer;">
+{{ icons.delete_svg(s_label="remove filters") }}
+Clear
+</button>
+<label for="chk_case_sensitive" style="font-size: 12px; margin-left: 15px;">
+{{ filter_form.chk_case_sensitive }}
+Case-sensitive search
+</label>
 </div>
-<table id="tbl_filters">
-<tr><td>
-<table id="tbl_filter1" class="tbl_filtering">
-<thead>
-<tr>
-<th>Position</th><th>Names</th><th>Surnames</th><th>I.D. or Passport number</th><th>Language</th>
-</tr>
-</thead>
-<tbody>
-<tr>
-<td>{{ filter_form.sel_role_department.label }}&nbsp;{{ filter_form.sel_role_department }}<br>
-{{ filter_form.sel_role.label }}&nbsp;{{ filter_form.sel_role }}</td>
-<td>{{ filter_form.txt_name.label }}&nbsp;{{ filter_form.txt_name }}</td><td>{{ filter_form.txt_surname.label }}&nbsp;{{ filter_form.txt_surname }}</td><td>{{ filter_form.txt_id_number.label }}&nbsp;{{ filter_form.txt_id_number }}</td><td>{{ filter_form.sel_language.label }}&nbsp;{{ filter_form.sel_language }}</td>
-</tr>
-</tbody>
-</table><!-- end of tbl_filter1 -->
-</td></tr>
-<tr><td>
-<table id="tbl_filter2" class="tbl_filtering">
-<thead>
-<tr>
-<th>SAP K-Level</th><th>Qualification/Certification 1</th><th>Qualification/Certification 2</th>
-</tr>
-</thead>
-<tbody>
-<tr>
-<td>{{ filter_form.sel_sap_k_level.label }}&nbsp;{{ filter_form.sel_sap_k_level }}</td><td>
-{{ filter_form.sel_qualification_type_1.label }}&nbsp;{{ filter_form.sel_qualification_type_1 }}<br>
-{{ filter_form.sel_qualification_1.label }}&nbsp;{{ filter_form.sel_qualification_1 }}</td><td>
-{{ filter_form.sel_qualification_type_2.label }}&nbsp;{{ filter_form.sel_qualification_type_2 }}<br>
-{{ filter_form.sel_qualification_2.label }}&nbsp;{{ filter_form.sel_qualification_2 }}</td>
-</tr>
-</tbody>
-</table><!-- end of tbl_filter2 -->
-</td></tr>
-</table><!-- tbl_filters -->
-</div><!-- end of div_filter -->
+<!-- end of div for buttons -->
+
+<!-- div containing filter Rows -->
+<div class="div_filter_row" style="margin-bottom: 20px;">
+
+<!-- Department and Role -->
+<div style="flex: 1 1 200px;">
+{{ filter_form.sel_role_department.label }}
+{{ filter_form.sel_role_department(style="width: 100%; padding: 6px;") }}
+{{ filter_form.sel_role.label(style="margin-top: 10px;") }}
+{{ filter_form.sel_role(style="width: 100%; padding: 6px;") }}
+</div>
+
+<!-- Name -->
+<div style="flex: 1 1 200px;">
+{{ filter_form.txt_name.label }}
+{{ filter_form.txt_name(style="width: 100%; padding: 6px;") }}
+</div>
+
+<!-- Surname -->
+<div style="flex: 1 1 200px;">
+{{ filter_form.txt_surname.label }}
+{{ filter_form.txt_surname(style="width: 100%; padding: 6px;") }}
+</div>
+
+<!-- ID/Passport -->
+<div style="flex: 1 1 200px;">
+{{ filter_form.txt_id_number.label }}
+{{ filter_form.txt_id_number(style="width: 100%; padding: 6px;") }}
+</div>
+
+<!-- Language -->
+<div style="flex: 1 1 200px;">
+{{ filter_form.sel_language.label }}
+{{ filter_form.sel_language(style="width: 100%; padding: 6px;") }}
+</div>
+</div>
+<!-- end of first div.div_filter_row containing filter rows -->
+
+<!-- Second Filter Row -->
+<div class="div_filter_row">
+<!-- SAP K-Level -->
+<div style="flex: 1 1 200px;">
+{{ filter_form.sel_sap_k_level.label }}
+{{ filter_form.sel_sap_k_level(style="width: 100%; padding: 6px;") }}
+</div>
+
+<!-- Qualification Type 1 & Qualification 1 -->
+<div style="flex: 1 1 200px;">
+{{ filter_form.sel_qualification_type_1.label }}
+{{ filter_form.sel_qualification_type_1(style="width: 100%; padding: 6px;") }}
+
+{{ filter_form.sel_qualification_1.label }}
+{{ filter_form.sel_qualification_1(style="width: 100%; padding: 6px;") }}
+</div>
+
+<!-- Qualification Type 2 & Qualification 2 -->
+<div style="flex: 1 1 200px;">
+{{ filter_form.sel_qualification_type_2.label }}
+{{ filter_form.sel_qualification_type_2(style="width: 100%; padding: 6px;") }}
+
+{{ filter_form.sel_qualification_2.label }}
+{{ filter_form.sel_qualification_2(style="width: 100%; padding: 6px;") }}
+</div>
+</div>
+<!-- end of div.div_filter_row containing filter rows -->
+</form>
+</div>
+<!-- end of div.div_data_filtering -->
+
 {% if records %}
 <h3>Records</h3>
 <div class="table-container">

+ 7 - 7
flask_app/app/templates/macros/action_icons_static.html

@@ -1,13 +1,13 @@
-{% macro search_svg(bl_quotes=True, s_label="search", width="16") -%}{% if bl_quotes %}<img src="{{ url_for("static", filename="cv_db/action_icons/search.svg") }}" alt="{{ s_label }}" aria-label="{{ s_label }}" width="{{ width }}">{% else %}<img src='{{ url_for("static", filename="cv_db/action_icons/search.svg") }}' alt='{{ s_label }}' aria-label='{{ s_label }}' width='{{ width }}'>{% endif %}{%- endmacro %}
+{% macro search_svg(bl_quotes=True, s_label="search", width="16") -%}{% if bl_quotes %}<img src="{{ url_for("static", filename=static_prefix+"action_icons/search.svg") }}" alt="{{ s_label }}" aria-label="{{ s_label }}" width="{{ width }}">{% else %}<img src='{{ url_for("static", filename=static_prefix+"action_icons/search.svg") }}' alt='{{ s_label }}' aria-label='{{ s_label }}' width='{{ width }}'>{% endif %}{%- endmacro %}
 
-{% macro edit_svg(bl_quotes=True, s_label="edit", width="16") -%}{% if bl_quotes %}<img src="{{ url_for("static", filename="cv_db/action_icons/edit.svg") }}" alt="{{ s_label }}" aria-label="{{ s_label }}" width="{{ width }}">{% else %}<img src='{{ url_for("static", filename="cv_db/action_icons/edit.svg") }}' alt='{{ s_label }}' aria-label='{{ s_label }}' width='{{ width }}'>{% endif %}{%- endmacro %}
+{% macro edit_svg(bl_quotes=True, s_label="edit", width="16") -%}{% if bl_quotes %}<img src="{{ url_for("static", filename=static_prefix+"action_icons/edit.svg") }}" alt="{{ s_label }}" aria-label="{{ s_label }}" width="{{ width }}">{% else %}<img src='{{ url_for("static", filename=static_prefix+"action_icons/edit.svg") }}' alt='{{ s_label }}' aria-label='{{ s_label }}' width='{{ width }}'>{% endif %}{%- endmacro %}
 
-{% macro view_svg(bl_quotes=True, s_label="view", width="16") -%}{% if bl_quotes %}<img src="{{ url_for("static", filename="cv_db/action_icons/view.svg") }}" alt="{{ s_label }}" aria-label="{{ s_label }}" width="{{ width }}">{% else %}<img src='{{ url_for("static", filename="cv_db/action_icons/view.svg") }}' alt='{{ s_label }}' aria-label='{{ s_label }}' width='{{ width }}'>{% endif %}{%- endmacro %}
+{% macro view_svg(bl_quotes=True, s_label="view", width="16") -%}{% if bl_quotes %}<img src="{{ url_for("static", filename=static_prefix+"action_icons/view.svg") }}" alt="{{ s_label }}" aria-label="{{ s_label }}" width="{{ width }}">{% else %}<img src='{{ url_for("static", filename=static_prefix+"action_icons/view.svg") }}' alt='{{ s_label }}' aria-label='{{ s_label }}' width='{{ width }}'>{% endif %}{%- endmacro %}
 
-{% macro delete_svg(bl_quotes=True, s_label="delete", width="16") -%}{% if bl_quotes %}<img src="{{ url_for("static", filename="cv_db/action_icons/delete.svg") }}" alt="{{ s_label }}" aria-label="{{ s_label }}" width="{{ width }}">{% else %}<img src='{{ url_for("static", filename="cv_db/action_icons/delete.svg") }}' alt='{{ s_label }}' aria-label='{{ s_label }}' width='{{ width }}'>{% endif %}{%- endmacro %}
+{% macro delete_svg(bl_quotes=True, s_label="delete", width="16") -%}{% if bl_quotes %}<img src="{{ url_for("static", filename=static_prefix+"action_icons/delete.svg") }}" alt="{{ s_label }}" aria-label="{{ s_label }}" width="{{ width }}">{% else %}<img src='{{ url_for("static", filename=static_prefix+"action_icons/delete.svg") }}' alt='{{ s_label }}' aria-label='{{ s_label }}' width='{{ width }}'>{% endif %}{%- endmacro %}
 
-{% macro add_svg(bl_quotes=True, s_label="add", width="16") -%}{% if bl_quotes %}<img src="{{ url_for("static", filename="cv_db/action_icons/add.svg") }}" alt="{{ s_label }}" aria-label="{{ s_label }}" width="{{ width }}">{% else %}<img src='{{ url_for("static", filename="cv_db/action_icons/add.svg") }}' alt='{{ s_label }}' aria-label='{{ s_label }}' width='{{ width }}'>{% endif %}{%- endmacro %}
+{% macro add_svg(bl_quotes=True, s_label="add", width="16") -%}{% if bl_quotes %}<img src="{{ url_for("static", filename=static_prefix+"action_icons/add.svg") }}" alt="{{ s_label }}" aria-label="{{ s_label }}" width="{{ width }}">{% else %}<img src='{{ url_for("static", filename=static_prefix+"action_icons/add.svg") }}' alt='{{ s_label }}' aria-label='{{ s_label }}' width='{{ width }}'>{% endif %}{%- endmacro %}
 
-{% macro save_svg(bl_quotes=True, s_label="save", width="16") -%}{% if bl_quotes %}<img src="{{ url_for("static", filename="cv_db/action_icons/save.svg") }}" alt="{{ s_label }}" aria-label="{{ s_label }}" width="{{ width }}">{% else %}<img src='{{ url_for("static", filename="cv_db/action_icons/save.svg") }}' alt='{{ s_label }}' aria-label='{{ s_label }}' width='{{ width }}'>{% endif %}{%- endmacro %}
+{% macro save_svg(bl_quotes=True, s_label="save", width="16") -%}{% if bl_quotes %}<img src="{{ url_for("static", filename=static_prefix+"action_icons/save.svg") }}" alt="{{ s_label }}" aria-label="{{ s_label }}" width="{{ width }}">{% else %}<img src='{{ url_for("static", filename=static_prefix+"action_icons/save.svg") }}' alt='{{ s_label }}' aria-label='{{ s_label }}' width='{{ width }}'>{% endif %}{%- endmacro %}
 
-{% macro settings_svg(bl_quotes=True, s_label="settings", width="16") -%}{% if bl_quotes %}<img src="{{ url_for("static", filename="cv_db/action_icons/settings.svg") }}" alt="{{ s_label }}" aria-label="{{ s_label }}" width="{{ width }}">{% else %}<img src='{{ url_for("static", filename="cv_db/action_icons/settings.svg") }}' alt='{{ s_label }}' aria-label='{{ s_label }}' width='{{ width }}'>{% endif %}{%- endmacro %}
+{% macro settings_svg(bl_quotes=True, s_label="settings", width="16") -%}{% if bl_quotes %}<img src="{{ url_for("static", filename=static_prefix+"action_icons/settings.svg") }}" alt="{{ s_label }}" aria-label="{{ s_label }}" width="{{ width }}">{% else %}<img src='{{ url_for("static", filename=static_prefix+"action_icons/settings.svg") }}' alt='{{ s_label }}' aria-label='{{ s_label }}' width='{{ width }}'>{% endif %}{%- endmacro %}

+ 2 - 2
flask_app/app/templates/macros/dialog.html

@@ -1,6 +1,6 @@
 {% macro dlg_prep(l_ids) -%}
-<script type="text/javascript" src="{{ url_for("static", filename="cv_db/js/jquery-ui.js") }}"></script>
-<link rel="stylesheet" type="text/css" href="{{ url_for("static", filename="cv_db/js/jquery-ui.css") }}" />
+<script type="text/javascript" src="{{ url_for("static", filename=static_prefix+"js/jquery-ui.js") }}"></script>
+<link rel="stylesheet" type="text/css" href="{{ url_for("static", filename=static_prefix+"js/jquery-ui.css") }}" />
 <script type="text/javascript">
 $(document).ready( function() {
 

+ 2 - 2
flask_app/app/templates/macros/tabs_mac.html

@@ -1,6 +1,6 @@
 {% macro tabs_inc() -%}
-<link rel="stylesheet" type="text/css" href="{{ url_for("static", filename="cv_db/js/tabs.css") }}" />
-<script type="text/javascript" src="{{ url_for("static", filename="cv_db/js/tabs-automatic.js") }}"></script>
+<link rel="stylesheet" type="text/css" href="{{ url_for("static", filename=static_prefix+"js/tabs.css") }}" />
+<script type="text/javascript" src="{{ url_for("static", filename=static_prefix+"js/tabs-automatic.js") }}"></script>
 {% endmacro %}
 
 {% macro tabs_start(group_id, group_desc, tabs_id, tabs_list) -%}

+ 2 - 2
flask_app/app/templates/macros/tts.html

@@ -1,5 +1,5 @@
 {%- macro basic_tts() %}
-<script type="text/javascript" src="{{ url_for("static", filename="cv_db/js/articulate.min.js") }}"></script>
+<script type="text/javascript" src="{{ url_for("static", filename=static_prefix+"js/articulate.min.js") }}"></script>
 <script type="text/javascript">
 <!--
 try {
@@ -42,7 +42,7 @@ function stop() {
 
 
 {%- macro full_tts() %}
-<script type="text/javascript" src="{{ url_for("static", filename="cv_db/js/articulate.min.js") }}"></script>
+<script type="text/javascript" src="{{ url_for("static", filename=static_prefix+"js/articulate.min.js") }}"></script>
 <script type="text/javascript">
 <!--
 try {

+ 1 - 1
flask_app/app/templates/qualifications.html

@@ -8,7 +8,7 @@ display: none;
 {% endblock head_extra %}
 
 {% block content %}
-{% import "macros/action_icons_static.html" as icons %}
+{% import "macros/action_icons_static.html" as icons with context %}
 <span class="title" role="main"><h2>{% block title %}Qualifications{% endblock %}</h2></span>
 <div class="content-container content">
 <article>

+ 1 - 1
flask_app/app/templates/roles.html

@@ -8,7 +8,7 @@ display: none;
 {% endblock head_extra %}
 
 {% block content %}
-{% import "macros/action_icons_static.html" as icons %}
+{% import "macros/action_icons_static.html" as icons with context %}
 <span class="title" role="main"><h2>{% block title %}Roles{% endblock %}</h2></span>
 <div class="content-container content">
 <article>

+ 1 - 1
flask_app/app/templates/tenders.html

@@ -12,7 +12,7 @@ font-size: smaller;
 {% endblock %}
 
 {% block content %}
-{% import "macros/action_icons_static.html" as icons %}
+{% import "macros/action_icons_static.html" as icons with context %}
 <span class="title"><h2>{% block title %}Tenders{% endblock %}</h2></span>
 <div class="content-container content">
 <div><a href="#" id="a_add_tender" aria-label="Add tender">{{ icons.add_svg }}</a></div>

+ 1 - 1
flask_app/app/templates/uploads.html

@@ -1,7 +1,7 @@
 {% extends base %}
 
 {% block content %}
-{% import "macros/action_icons_static.html" as icons %}
+{% import "macros/action_icons_static.html" as icons with context %}
 <span class="title"><h2>{% block title %}Capture Record Uploads{% endblock %}</h2></span>
 <div>Manage documents for <span style="font-weight: bold;">{{ names }}</span>.</div>
 <div class="content-container content">

+ 1 - 1
flask_app/app/templates/users.html

@@ -1,7 +1,7 @@
 {% extends base %}
 
 {% block content %}
-{% import "macros/action_icons_static.html" as icons %}
+{% import "macros/action_icons_static.html" as icons with context %}
 <span class="title" role="main"><h2>{% block title %}Access User Profiles{% endblock %}</h2></span>
 <div class="content-container content">
 <article>