From a6d8767c283c4f3e0d3293a278d659da5f04c2ac Mon Sep 17 00:00:00 2001 From: Javier Date: Fri, 30 Jan 2026 10:30:17 -0600 Subject: [PATCH] Refactor Admin Dashboard and organize Counts module --- app.py | 18 +-- .../__pycache__/counting.cpython-313.pyc | Bin 25255 -> 27381 bytes blueprints/counting.py | 50 +++++++- templates/admin_dashboard.html | 115 ++---------------- templates/cons_sheets/admin_processes.html | 22 ++-- .../DELETE_count_session.html} | 0 templates/counts/admin_dashboard.html | 102 ++++++++++++++++ templates/{ => counts}/count_location.html | 0 templates/{ => counts}/my_counts.html | 0 templates/{ => counts}/staff_dashboard.html | 0 10 files changed, 172 insertions(+), 135 deletions(-) rename templates/{count_session.html => counts/DELETE_count_session.html} (100%) create mode 100644 templates/counts/admin_dashboard.html rename templates/{ => counts}/count_location.html (100%) rename templates/{ => counts}/my_counts.html (100%) rename templates/{ => counts}/staff_dashboard.html (100%) diff --git a/app.py b/app.py index 47edfc3..a324ce3 100644 --- a/app.py +++ b/app.py @@ -38,7 +38,7 @@ app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(hours=1) # 1. Define the version -APP_VERSION = '0.13.0' +APP_VERSION = '0.13.2' # 2. Inject it into all templates automatically @app.context_processor @@ -164,22 +164,6 @@ def admin_dashboard(): -@app.route('/staff-mode') -@login_required -def staff_mode(): - """Allow admin/owner to switch to staff view for scanning""" - # Show staff dashboard view regardless of role - active_sessions = query_db(''' - SELECT session_id, session_name, session_type, created_timestamp - FROM CountSessions - WHERE status = 'active' - ORDER BY created_timestamp DESC - ''') - - return render_template('staff_dashboard.html', sessions=active_sessions, is_admin_mode=True) - - - # ==================== PWA SUPPORT ROUTES ==================== @app.route('/manifest.json') diff --git a/blueprints/__pycache__/counting.cpython-313.pyc b/blueprints/__pycache__/counting.cpython-313.pyc index a3a9aaf4529a99d37997048a3ac3847605bc2600..e8d6273ee55ead760d5efa2645030f3287b09ce9 100644 GIT binary patch delta 3873 zcmeHKeQaDu5r2E%KHvEq*N&ZY56}R1PrvN|s-DeX$^A{@WOiuIFwie>*A;=bl zsS3%>CdhVsh2-fVQYAY_0uF=hHL>53PDeqKeMq{jhD^Y;qnuN{CeYu&j+wS^@k;fm z&p8{tLXTm-_@x`CD#KgY@v29*Zz`Av-OUe>+$1%41-iK)zeQXl-}nIehS?@xvv$wq zH*Ixy#4@>bR_&1EsYE)K_kn+GfM)o+?ILWywfz~%^f-h-76oC_3T*z9%#x+YWYD58 zY0tBT$+7|^SqtGPd|QM`9$}OSy9#opZ`h2RUbIQ}f@R6kw@(n#!nn|u7n4D6(o@ip z$_lpAWUPD*-&x{Mt}9BHPgF{-UUQ4!b1yUw;J(GUtj3R8@>C>4Xw*7Y#j{Nh%^$j^`2-n7S=4r)L#?n{nbfhQf=k_JVB$UlVlvjQX60;76?coR ziFEWB&CF5=PwPXht`RBO<(p>piaBv?6vDz|z#2Qe z4h$L!v9W_2$J$j`7&aPB#K9Z%tT?{UD(pNQ0yBBX!FpS(9LqvRTK!^cAvvw=YE$hZ zNIlrdSa>iL7N7W3$_Thn$~Mut#^r)HiAE_&HjsyLd@XI%*>QL zH)2NUR*>`Ad8BA7>U34sICwbB)X)5m9&0CXd)bU*wrtn6y({I?vPIJV;+Q05xCCuN zosctZ?FK^9E;%brHe*72({+v5{J@r%w7*q-;bJR|dekRxYY;e;Fbda5|ZM7Z*^1Sv|?HyBF5J=q)twoh*72U~wl}}; z(dP9vgUGEzkP)U44zT&=7HbU1Rqb2NI| z`@U`$G5GW|2=~_=Jq)~s%T9K5XEXcL6K9FS4h7HFqk9W339Ehe9phxs|Ha57~`U6n7r_n)^sq?$I3a$s8kH_>1(q^M0;`izi_`m9yy%+9o`H~4_jUq;^d4vT7UUttS^;xv^ktgD( zAo^0tnD!INNy5Q zb_^N@rjd2ZTipa(oO})XLc`SOpjcm>`fWMS)bnV-&yq(Ps(8^&;dloCRv~-kNKbR| z$Qca_yPA5RqMs()czsh1V7BM!<`LVvDEPsc8%W zj~c}@K(UZ1mI>btMPo+Ksz-|7_Kr^&|Df!l?*Na$pDMGtqyDF=1e5zZsahdb=l8CX w=D!lpzf4<5hTJv_rb>jCTNWJOI!H>Ay{lvsm#iU?lH}%F78q;4Jo*pvUzh*V7XSbN delta 2158 zcmah~du&r>6z_NYSlg|ocJD_YW0S4v7%;Z60U{ewV01$$B$LgRyWYD}TyMvBTVNxK zFG6^TBS(xR1_FbCkHqLTK5#@4^j`#GFgG#rFaHq}4Pqie<2kpZ;}6vP$FJx8o$s9U zo!%s?(^{goBTEL?2PGQg;odf+WT;Rz`;2>+U zw=wcDncxarXuod>_t+w<;RP+i;=;n*igkPDf)4>oz)to6va;D{&TSoG=oYlV?-EfMW+&j2g&qvEbRp3W+n zq>^Y(Dw4b#hP@lDAyhPIpLsokjcoWl?P|%FjQO<5vIDHxof?lBPHOYEOllO*3Blru z-o_>}osXc>@j?7}B@((LZ_k^NZ-?_0@3FA9xpL5K3!{L~gHLKiTLY1e;P=gEel6mY z@jUp@KhA2QDbUZ_U|%3)dyH&4;iEu<^$8>;?Z?0!p|t}^yf5EHWQG;))r*zh>_ zk;cN)qw?E=ZcXn}WUgC9DV0>;In&1J<#MzPTuxluLV z4vWGyu5OCakAN+#f)~BTkP4TTc9OJ$U<<(jK{vb^uD1>%c}}|&Uc%Ty?a!ur_HrZT zwJ6q|qv=dc$)<*7j?s(S6Ku7XX>Vm-8cp4)#zjS$DGOX!GK?klb!=jO;2oD1Y@;K# z6FiHc3J5dp;|fXB2w{9Ae2lmqFx+{g$|$>6k!4B6c~C}@JZ0RQ_rUt4Wy^Mxnp4k72Dn_uCKqR0d>uz~>Ql)ngqe5X&((EHJ z@=if-_bS^f#2_1#L$1ape2(ZU!^k8e_7Hs64T(iUX09xJ*Gt;Ds&yHUBl# z@cWk5dJ*S*W}?Z96Q~5n*ky^@Ns<2ddAyIN+h>DmHwK)ncs9+KP%Zj!vSG(yDcl;U zgP`3Cp27JrR$zglXQuZ~qJ{2|@%74F#L+%NXTOFJ^6+w^X>N5-Jj*$DD8EYhDbfuP zOpyUg>drAP@0^+86e)ngFW;IVoN6(XR&5KhaV)86K^5IH?SPA`Mgcyk&a z<072mQI!a~eR(P^Wk=-|{3~R!DJFFZ9NyN{;5G@ao6LKSc_%w>FyHrV&Tm2~ V>t(miCc#7C|J8!L=1AUR{{U(h2>k#6 diff --git a/blueprints/counting.py b/blueprints/counting.py index 0c258b5..4a5ee4a 100644 --- a/blueprints/counting.py +++ b/blueprints/counting.py @@ -10,6 +10,50 @@ def get_active_session(session_id): return None return sess + + +@counting_bp.route('/counts/admin') +@login_required +def admin_dashboard(): + """Admin dashboard for Counts module""" + # Security check: Ensure user is admin/owner + if session.get('role') not in ['owner', 'admin']: + flash('Access denied. Admin role required.', 'danger') + return redirect(url_for('counting.index')) + + show_archived = request.args.get('show_archived', '0') == '1' + + # This SQL was moved from app.py + if show_archived: + sessions_list = query_db(''' + SELECT s.*, u.full_name as created_by_name, + COUNT(DISTINCT lc.location_count_id) as total_locations, + SUM(CASE WHEN lc.status = 'completed' THEN 1 ELSE 0 END) as completed_locations, + SUM(CASE WHEN lc.status = 'in_progress' THEN 1 ELSE 0 END) as in_progress_locations + FROM CountSessions s + LEFT JOIN Users u ON s.created_by = u.user_id + LEFT JOIN LocationCounts lc ON s.session_id = lc.session_id + WHERE s.status IN ('active', 'archived') + GROUP BY s.session_id + ORDER BY s.status ASC, s.created_timestamp DESC + ''') + else: + sessions_list = query_db(''' + SELECT s.*, u.full_name as created_by_name, + COUNT(DISTINCT lc.location_count_id) as total_locations, + SUM(CASE WHEN lc.status = 'completed' THEN 1 ELSE 0 END) as completed_locations, + SUM(CASE WHEN lc.status = 'in_progress' THEN 1 ELSE 0 END) as in_progress_locations + FROM CountSessions s + LEFT JOIN Users u ON s.created_by = u.user_id + LEFT JOIN LocationCounts lc ON s.session_id = lc.session_id + WHERE s.status = 'active' + GROUP BY s.session_id + ORDER BY s.created_timestamp DESC + ''') + + return render_template('counts/admin_dashboard.html', sessions=sessions_list, show_archived=show_archived) + + @counting_bp.route('/counts') @login_required def index(): @@ -33,7 +77,7 @@ def index(): ORDER BY created_timestamp DESC ''') - return render_template('staff_dashboard.html', sessions=active_sessions) + return render_template('counts/staff_dashboard.html', sessions=active_sessions) @counting_bp.route('/count/') @@ -91,7 +135,7 @@ def my_counts(session_id): ORDER BY lc.end_timestamp DESC ''', [session_id, session['user_id']]) - return render_template('my_counts.html', + return render_template('counts/my_counts.html', count_session=sess, active_bins=active_bins, completed_bins=completed_bins) @@ -219,7 +263,7 @@ def count_location(session_id, location_count_id): ORDER BY lot_number ''', [session_id, location['location_name'], location_count_id]) - return render_template('count_location.html', + return render_template('counts/count_location.html', session_id=session_id, location=location, scans=scans, diff --git a/templates/admin_dashboard.html b/templates/admin_dashboard.html index 1ed1226..c03c978 100644 --- a/templates/admin_dashboard.html +++ b/templates/admin_dashboard.html @@ -4,121 +4,28 @@ {% block content %}
- -
- - Back to Home - - - -
- - - -
-
-

Admin Dashboard

- + - - - - - {% if sessions %} -
- {% for session in sessions %} -
-
-

- {{ session.session_name }} - {% if session.status == 'archived' %}ARCHIVED{% endif %} -

- - {{ 'Full Physical' if session.session_type == 'full_physical' else 'Cycle Count' }} - -
- -
-
-
{{ session.total_locations or 0 }}
-
Total Locations
-
-
-
{{ session.completed_locations or 0 }}
-
Completed
-
-
-
{{ session.in_progress_locations or 0 }}
-
In Progress
-
-
- -
-
- Created: - {{ session.created_timestamp[:16] }} -
-
- By: - {{ session.created_by_name }} -
-
- - -
- {% endfor %} -
- {% else %} -
-
📋
-

No Active Sessions

-

Create a new count session to get started

- - Create First Session - -
- {% endif %}
{% endblock %} \ No newline at end of file diff --git a/templates/cons_sheets/admin_processes.html b/templates/cons_sheets/admin_processes.html index f0f66de..a776ef4 100644 --- a/templates/cons_sheets/admin_processes.html +++ b/templates/cons_sheets/admin_processes.html @@ -4,18 +4,18 @@ {% block content %}
- - - -
-
-

Consumption Sheets

-

Manage process types and templates

+
+
+ + Back to Admin + + +
+

Consumption Sheets

+

Manage process types and templates

+
+ + New Process diff --git a/templates/count_session.html b/templates/counts/DELETE_count_session.html similarity index 100% rename from templates/count_session.html rename to templates/counts/DELETE_count_session.html diff --git a/templates/counts/admin_dashboard.html b/templates/counts/admin_dashboard.html new file mode 100644 index 0000000..4fa1d21 --- /dev/null +++ b/templates/counts/admin_dashboard.html @@ -0,0 +1,102 @@ +{% extends "base.html" %} + +{% block title %}Inventory Counts - ScanLook{% endblock %} + +{% block content %} +
+
+
+ + Back to Admin + +
+

Inventory Counts

+

Manage cycle counts and physical inventory

+
+
+
+ + + + New Session + +
+
+ + {% if sessions %} +
+ {% for session in sessions %} +
+
+

+ {{ session.session_name }} + {% if session.status == 'archived' %}ARCHIVED{% endif %} +

+ + {{ 'Full Physical' if session.session_type == 'full_physical' else 'Cycle Count' }} + +
+ +
+
+
{{ session.total_locations or 0 }}
+
Total Locations
+
+
+
{{ session.completed_locations or 0 }}
+
Completed
+
+
+
{{ session.in_progress_locations or 0 }}
+
In Progress
+
+
+ +
+
+ Created: + {{ session.created_timestamp[:16] }} +
+
+ By: + {{ session.created_by_name }} +
+
+ + +
+ {% endfor %} +
+ {% else %} +
+
📋
+

No Active Sessions

+

Create a new count session to get started

+
+ {% endif %} +
+ + + + +{% endblock %} \ No newline at end of file diff --git a/templates/count_location.html b/templates/counts/count_location.html similarity index 100% rename from templates/count_location.html rename to templates/counts/count_location.html diff --git a/templates/my_counts.html b/templates/counts/my_counts.html similarity index 100% rename from templates/my_counts.html rename to templates/counts/my_counts.html diff --git a/templates/staff_dashboard.html b/templates/counts/staff_dashboard.html similarity index 100% rename from templates/staff_dashboard.html rename to templates/counts/staff_dashboard.html