From 9f7d656d5ee59dff8a9252945ef69352aa519bb2 Mon Sep 17 00:00:00 2001 From: NguyenND Date: Thu, 7 May 2026 11:09:06 -0400 Subject: [PATCH] 05/06 Phase 2: fixed issues --- app/admin/__init__.py | 2 +- app/models/platform.py | 2 +- app/templates/admin/analytics/index.html | 84 ++++++++ app/templates/admin/audit_log/index.html | 88 ++++++++ app/templates/admin/auth/login.html | 60 ++++-- .../admin/auth/password_reset_confirm.html | 34 ++++ .../admin/auth/password_reset_request.html | 28 +++ app/templates/admin/billing/form.html | 37 ++++ app/templates/admin/billing/index.html | 32 +++ app/templates/admin/billing/tenant.html | 35 ++++ app/templates/admin/layouts/base.html | 96 +++++++++ app/templates/admin/plans/form.html | 65 ++++++ app/templates/admin/plans/index.html | 48 +++++ .../admin/settings_override/form.html | 37 ++++ .../admin/settings_override/list.html | 66 ++++++ app/templates/admin/system_users/form.html | 57 ++++++ app/templates/admin/system_users/index.html | 61 ++++++ app/templates/admin/tenants/detail.html | 128 ++++++++++++ app/templates/admin/tenants/form.html | 77 +++++++ app/templates/admin/tenants/index.html | 58 ++++++ app/templates/tenant/auth/account_locked.html | 17 ++ app/templates/tenant/auth/login.html | 72 ++++--- .../tenant/auth/password_reset_confirm.html | 51 ++--- .../tenant/auth/password_reset_request.html | 40 ++-- app/templates/tenant/feature_unavailable.html | 18 ++ app/templates/tenant/layouts/base.html | 189 ++++++++++++++++++ .../tenant/staff_auth/staff_login.html | 51 +++++ app/tenant/__init__.py | 2 +- templates/admin/auth/login.html | 1 - 29 files changed, 1442 insertions(+), 94 deletions(-) create mode 100644 app/templates/admin/analytics/index.html create mode 100644 app/templates/admin/audit_log/index.html create mode 100644 app/templates/admin/auth/password_reset_confirm.html create mode 100644 app/templates/admin/auth/password_reset_request.html create mode 100644 app/templates/admin/billing/form.html create mode 100644 app/templates/admin/billing/index.html create mode 100644 app/templates/admin/billing/tenant.html create mode 100644 app/templates/admin/layouts/base.html create mode 100644 app/templates/admin/plans/form.html create mode 100644 app/templates/admin/plans/index.html create mode 100644 app/templates/admin/settings_override/form.html create mode 100644 app/templates/admin/settings_override/list.html create mode 100644 app/templates/admin/system_users/form.html create mode 100644 app/templates/admin/system_users/index.html create mode 100644 app/templates/admin/tenants/detail.html create mode 100644 app/templates/admin/tenants/form.html create mode 100644 app/templates/admin/tenants/index.html create mode 100644 app/templates/tenant/auth/account_locked.html create mode 100644 app/templates/tenant/feature_unavailable.html create mode 100644 app/templates/tenant/layouts/base.html create mode 100644 app/templates/tenant/staff_auth/staff_login.html diff --git a/app/admin/__init__.py b/app/admin/__init__.py index a2bf660..470ecd2 100644 --- a/app/admin/__init__.py +++ b/app/admin/__init__.py @@ -92,4 +92,4 @@ def create_admin_app(config_override=None): import app.models # noqa: F401 logger.info("Admin app created (env=%s)", flask_app.config.get("FLASK_ENV")) - return flask_app \ No newline at end of file + return flask_app diff --git a/app/models/platform.py b/app/models/platform.py index 0da90c4..79cafa8 100644 --- a/app/models/platform.py +++ b/app/models/platform.py @@ -275,4 +275,4 @@ class JWTBlocklist(db.Model): default=lambda: datetime.now(timezone.utc)) def __repr__(self): - return f"" \ No newline at end of file + return f"" diff --git a/app/templates/admin/analytics/index.html b/app/templates/admin/analytics/index.html new file mode 100644 index 0000000..e8697db --- /dev/null +++ b/app/templates/admin/analytics/index.html @@ -0,0 +1,84 @@ +{% extends "admin/layouts/base.html" %} +{% block title %}Platform Analytics{% endblock %} +{% block content %} +

Platform Analytics

+ +
+ {% set kpis = [ + ('Total Tenants', stats.total_tenants, 'building', 'primary'), + ('Active', stats.active_count, 'check-circle', 'success'), + ('Trial', stats.trial_count, 'hourglass-split', 'info'), + ('Suspended/Cancelled', stats.suspended_count + stats.cancelled_count, 'x-circle', 'danger'), + ('MRR', '$' ~ "%.2f"|format(stats.mrr), 'currency-dollar', 'success'), + ('Revenue (30d)', '$' ~ "%.2f"|format(stats.revenue_30d), 'graph-up', 'primary'), + ('New Tenants (30d)', stats.new_tenants_30d, 'person-plus', 'secondary'), + ('Conversions (30d)', stats.converted_30d, 'arrow-up-circle', 'success'), + ('Churn (30d)', stats.churned_30d, 'arrow-down-circle', 'danger'), + ] %} + {% for label, value, icon, color in kpis %} +
+
+
+
+ +
+
+
{{ value }}
+
{{ label }}
+
+
+
+
+ {% endfor %} +
+ +
+ +
+
+
Active Tenants by Plan
+
+ {% for plan_name, count in stats.plan_counts %} +
+ {{ plan_name }} + {{ count }} +
+ {% else %} +

No data yet.

+ {% endfor %} +
+
+
+ + +
+
+
+ Trials Expiring in 3 Days +
+ {% if expiring_soon %} +
+ + + + {% for t in expiring_soon %} + + + + + + + {% endfor %} + +
TenantPlanTrial Ends
{{ t.name }}{{ t.plan.name if t.plan else '—' }}{{ t.trial_ends_at.strftime('%Y-%m-%d %H:%M') }} + Convert +
+
+ {% else %} +
No trials expiring in the next 3 days.
+ {% endif %} +
+
+
+{% endblock %} \ No newline at end of file diff --git a/app/templates/admin/audit_log/index.html b/app/templates/admin/audit_log/index.html new file mode 100644 index 0000000..f1fddeb --- /dev/null +++ b/app/templates/admin/audit_log/index.html @@ -0,0 +1,88 @@ +{% extends "admin/layouts/base.html" %} +{% block title %}Audit Log{% endblock %} +{% block content %} +
+

Audit Log

+ + Export CSV + +
+ +
+
+
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+
+
+
+ +
+
+ + + + + + {% for e in entries %} + + + + + + + + {% else %} + + {% endfor %} + +
TimeActorActionTargetIP
{{ e.created_at.strftime('%Y-%m-%d %H:%M:%S') }}{{ e.actor_type }}:{{ e.actor_id }}{{ e.action }}{{ (e.target_type ~ ':' ~ e.target_id) if e.target_type else '—' }}{{ e.ip_address or '—' }}
No entries match your filter.
+
+
+ +{% if pagination.pages > 1 %} + +{% endif %} +{% endblock %} \ No newline at end of file diff --git a/app/templates/admin/auth/login.html b/app/templates/admin/auth/login.html index 45c4c25..43d52ae 100644 --- a/app/templates/admin/auth/login.html +++ b/app/templates/admin/auth/login.html @@ -1,26 +1,44 @@ -{% extends "admin/base.html" %} +{% extends "admin/layouts/base.html" %} {% block title %}Admin Login{% endblock %} + {% block content %} -
-
-
-
-

Admin Portal

- {% if error %} -
{{ error }}
- {% endif %} -
- -
- - -
-
- - -
- -
+
+
+
+
+ +

Admin Portal

+

Restricted access

+
+ + {% if error %} +
{{ error }}
+ {% endif %} + +
+ + +
+ + +
+ +
+ + +
+ +
+ +
+
+ +
diff --git a/app/templates/admin/auth/password_reset_confirm.html b/app/templates/admin/auth/password_reset_confirm.html new file mode 100644 index 0000000..27a24c6 --- /dev/null +++ b/app/templates/admin/auth/password_reset_confirm.html @@ -0,0 +1,34 @@ +{% extends "admin/layouts/base.html" %} +{% block title %}Set New Password{% endblock %} + +{% block content %} +
+
+
+
Set New Password
+ + {% if error %} +
{{ error }}
+ {% endif %} + +
+ +
+ + +
Min 10 characters. Must include uppercase, lowercase, and a digit.
+
+
+ + +
+
+ +
+
+
+
+
+{% endblock %} diff --git a/app/templates/admin/auth/password_reset_request.html b/app/templates/admin/auth/password_reset_request.html new file mode 100644 index 0000000..9faed0d --- /dev/null +++ b/app/templates/admin/auth/password_reset_request.html @@ -0,0 +1,28 @@ +{% extends "admin/layouts/base.html" %} +{% block title %}Reset Password{% endblock %} + +{% block content %} +
+
+
+
Reset Admin Password
+

Enter your registered email address and we'll send a reset link.

+ +
+ +
+ + +
+
+ +
+
+ + +
+
+
+{% endblock %} diff --git a/app/templates/admin/billing/form.html b/app/templates/admin/billing/form.html new file mode 100644 index 0000000..9ac8568 --- /dev/null +++ b/app/templates/admin/billing/form.html @@ -0,0 +1,37 @@ +{% extends "admin/layouts/base.html" %} +{% block title %}Add Billing Entry{% endblock %} +{% block content %} +
+
+
+
Add Billing Entry — {{ tenant.name }}
+
+ {% if error %}
{{ error }}
{% endif %} +
+ +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + Cancel +
+
+
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/app/templates/admin/billing/index.html b/app/templates/admin/billing/index.html new file mode 100644 index 0000000..50537eb --- /dev/null +++ b/app/templates/admin/billing/index.html @@ -0,0 +1,32 @@ +{% extends "admin/layouts/base.html" %} +{% block title %}Billing History{% endblock %} +{% block content %} +

Billing History

+
+
+ + + + + + {% for b in entries %} + + + + + + + + + {% else %} + + {% endfor %} + +
DateTenantAmountDescriptionInvoice RefPaid
{{ b.created_at.strftime('%Y-%m-%d') }} + + {{ b.tenant.name if b.tenant else b.tenant_id }} + + ${{ "%.2f"|format(b.amount) }}{{ b.description }}{{ b.invoice_ref or '—' }}{{ b.paid_at.strftime('%Y-%m-%d') if b.paid_at else '—' }}
No billing entries yet.
+
+
+{% endblock %} \ No newline at end of file diff --git a/app/templates/admin/billing/tenant.html b/app/templates/admin/billing/tenant.html new file mode 100644 index 0000000..c7607a9 --- /dev/null +++ b/app/templates/admin/billing/tenant.html @@ -0,0 +1,35 @@ +{% extends "admin/layouts/base.html" %} +{% block title %}Billing — {{ tenant.name }}{% endblock %} +{% block content %} +
+

Billing — {{ tenant.name }}

+ + Add Entry + +
+
+
+ + + + + + {% for b in entries %} + + + + + + + + {% else %} + + {% endfor %} + +
DateAmountDescriptionInvoice RefPaid
{{ b.created_at.strftime('%Y-%m-%d') }}${{ "%.2f"|format(b.amount) }}{{ b.description }}{{ b.invoice_ref or '—' }}{{ b.paid_at.strftime('%Y-%m-%d') if b.paid_at else '—' }}
No entries yet.
+
+
+ + Back to Tenant + +{% endblock %} \ No newline at end of file diff --git a/app/templates/admin/layouts/base.html b/app/templates/admin/layouts/base.html new file mode 100644 index 0000000..5f6bb32 --- /dev/null +++ b/app/templates/admin/layouts/base.html @@ -0,0 +1,96 @@ + + + + + + {% block title %}Admin Portal{% endblock %} — Salon POS + + + + + + +{% if current_user.is_authenticated %} + + +
+
+ + + + +
+{% endif %} + + {% with messages = get_flashed_messages(with_categories=true) %} + {% for category, message in messages %} + + {% endfor %} + {% endwith %} + + {% block content %}{% endblock %} + +{% if current_user.is_authenticated %} +
+
+
+{% endif %} + + +{% block scripts %}{% endblock %} + + diff --git a/app/templates/admin/plans/form.html b/app/templates/admin/plans/form.html new file mode 100644 index 0000000..d6e432a --- /dev/null +++ b/app/templates/admin/plans/form.html @@ -0,0 +1,65 @@ +{% extends "admin/layouts/base.html" %} +{% block title %}{{ 'Edit' if mode == 'edit' else 'New' }} Plan{% endblock %} +{% block content %} +
+
+
+
{{ 'Edit' if mode == 'edit' else 'New' }} Plan
+
+ {% if error %}
{{ error }}
{% endif %} +
+ +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ +
+ {% for flag in all_features %} +
+
+ + +
+
+ {% endfor %} +
+
+
+
+ + +
+
+
+
+ + Cancel +
+
+
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/app/templates/admin/plans/index.html b/app/templates/admin/plans/index.html new file mode 100644 index 0000000..b0d4e6d --- /dev/null +++ b/app/templates/admin/plans/index.html @@ -0,0 +1,48 @@ +{% extends "admin/layouts/base.html" %} +{% block title %}Plans{% endblock %} +{% block content %} +
+

Subscription Plans

+ + New Plan + +
+
+ {% for plan in plans %} +
+
+
+ {{ plan.name }} + + {{ 'Active' if plan.is_active else 'Inactive' }} + +
+
+

${{ "%.2f"|format(plan.price_monthly) }}/mo

+

+ Staff: {{ plan.max_staff or 'Unlimited' }} • + Locations: {{ plan.max_locations or 'Unlimited' }} +

+
+ {% for flag, enabled in (plan.features_json or {}).items() %} + + {{ flag }} + + {% endfor %} +
+
+ +
+
+ {% endfor %} +
+{% endblock %} \ No newline at end of file diff --git a/app/templates/admin/settings_override/form.html b/app/templates/admin/settings_override/form.html new file mode 100644 index 0000000..ab0f819 --- /dev/null +++ b/app/templates/admin/settings_override/form.html @@ -0,0 +1,37 @@ +{% extends "admin/layouts/base.html" %} +{% block title %}Set Override — {{ tenant.name }}{% endblock %} +{% block content %} +
+
+
+
Set Setting Override — {{ tenant.name }}
+
+ {% if error %}
{{ error }}
{% endif %} +
+ +
+ + +
Alphanumeric, underscores, dots. Use feature_FLAG to force-enable/disable a plan feature.
+
+
+ + +
For feature flags: true or false
+
+
+ + +
+
+ + Cancel +
+
+
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/app/templates/admin/settings_override/list.html b/app/templates/admin/settings_override/list.html new file mode 100644 index 0000000..952c834 --- /dev/null +++ b/app/templates/admin/settings_override/list.html @@ -0,0 +1,66 @@ +{% extends "admin/layouts/base.html" %} +{% block title %}Settings Overrides — {{ tenant.name }}{% endblock %} +{% block content %} +
+

Overrides — {{ tenant.name }}

+ + Set Override + +
+ +{% if active %} +
+
Active Overrides
+
+ + + + {% for ov in active %} + + + + + + + + + {% endfor %} + +
KeyValueSet bySet atNote
{{ ov.setting_key }}{{ ov.setting_value }}{{ ov.admin.name if ov.admin else ov.overridden_by }}{{ ov.overridden_at.strftime('%Y-%m-%d %H:%M') }}{{ ov.note or '—' }} +
+ + +
+
+
+
+{% else %} +
No active overrides for this tenant.
+{% endif %} + +{% if history %} +
+
Override History
+
+ + + + {% for ov in history %} + + + + + + + {% endfor %} + +
KeyValueSet atLifted at
{{ ov.setting_key }}{{ ov.setting_value }}{{ ov.overridden_at.strftime('%Y-%m-%d %H:%M') }}{{ ov.lifted_at.strftime('%Y-%m-%d %H:%M') if ov.lifted_at else '—' }}
+
+
+{% endif %} + + + Back to Tenant + +{% endblock %} \ No newline at end of file diff --git a/app/templates/admin/system_users/form.html b/app/templates/admin/system_users/form.html new file mode 100644 index 0000000..004e37c --- /dev/null +++ b/app/templates/admin/system_users/form.html @@ -0,0 +1,57 @@ +{% extends "admin/layouts/base.html" %} +{% block title %}{{ 'Edit' if mode == 'edit' else 'New' }} System User{% endblock %} +{% block content %} +
+
+
+
{{ 'Edit' if mode == 'edit' else 'New' }} System User
+
+ {% if error %}
{{ error }}
{% endif %} +
+ +
+ + +
+
+ + +
+
+ + +
+ {% if mode == 'create' %} +
+ + +
Min 10 chars, uppercase, lowercase, digit.
+
+
+ + +
+ {% else %} +
+
+ + +
+
+ {% endif %} +
+ + Cancel +
+
+
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/app/templates/admin/system_users/index.html b/app/templates/admin/system_users/index.html new file mode 100644 index 0000000..3297a8a --- /dev/null +++ b/app/templates/admin/system_users/index.html @@ -0,0 +1,61 @@ +{% extends "admin/layouts/base.html" %} +{% block title %}System Users{% endblock %} +{% block content %} +
+

System Users

+ + New User + +
+
+
+ + + + + + + + + {% for u in users %} + + + + + + + + + {% else %} + + {% endfor %} + +
EmailNameRoleStatusLast LoginActions
{{ u.email }}{{ u.name }}{{ u.role }} + {% if u.is_active %} + Active + {% else %} + Inactive + {% endif %} + {% if u.is_locked() %} + Locked + {% endif %} + + {{ u.last_login_at.strftime('%Y-%m-%d %H:%M') if u.last_login_at else 'Never' }} + + Edit +
+ + +
+
+ + +
+
No system users found.
+
+
+{% endblock %} \ No newline at end of file diff --git a/app/templates/admin/tenants/detail.html b/app/templates/admin/tenants/detail.html new file mode 100644 index 0000000..f05140d --- /dev/null +++ b/app/templates/admin/tenants/detail.html @@ -0,0 +1,128 @@ +{% extends "admin/layouts/base.html" %} +{% block title %}{{ tenant.name }}{% endblock %} +{% block content %} +
+
+

{{ tenant.name }} + {{ tenant.slug }} + {% if tenant.is_demo %}Demo{% endif %} +

+ + {{ tenant.status }} + +
+ +
+ +
+
+
+
{{ tenant.plan.name if tenant.plan else '—' }}
+
Plan
+
+
+
+
+
{{ locations|length }}
+
Locations
+
+
+
+
+
{{ users|length }}
+
Portal Users
+
+
+
+
+
{{ overrides|length }}
+
Active Overrides
+
+
+
+ + +
+
Change Status
+
+
+ + + +
+
+
+ + +{% if overrides %} +
+
+ Active Setting Overrides +
+
+ + + + {% for ov in overrides %} + + + + + + + + {% endfor %} + +
KeyValueSet byNote
{{ ov.setting_key }}{{ ov.setting_value }}{{ ov.admin.name if ov.admin else ov.overridden_by }}{{ ov.note or '—' }} +
+ + +
+
+
+
+{% endif %} + + +{% if billing %} +
+
Recent Billing
+
+ + + + {% for b in billing %} + + + + + + + + {% endfor %} + +
DateAmountDescriptionInvoice RefPaid
{{ b.created_at.strftime('%Y-%m-%d') }}${{ "%.2f"|format(b.amount) }}{{ b.description }}{{ b.invoice_ref or '—' }}{{ b.paid_at.strftime('%Y-%m-%d') if b.paid_at else '—' }}
+
+
+{% endif %} + + + Back to Tenants + +{% endblock %} \ No newline at end of file diff --git a/app/templates/admin/tenants/form.html b/app/templates/admin/tenants/form.html new file mode 100644 index 0000000..89439a5 --- /dev/null +++ b/app/templates/admin/tenants/form.html @@ -0,0 +1,77 @@ +{% extends "admin/layouts/base.html" %} +{% block title %}{{ 'Edit' if mode == 'edit' else 'New Tenant' }}{% endblock %} +{% block content %} +
+
+
+
{{ 'Edit Tenant' if mode == 'edit' else 'New Tenant' }}
+
+ {% if error %}
{{ error }}
{% endif %} +
+ +
+ + +
+ {% if mode == 'create' %} +
+ + +
+ {% endif %} +
+ + +
+
+ + +
+ {% if mode == 'create' %} +
+ + +
+
+
Owner Account Password
+
+ + +
Min 10 chars, uppercase, lowercase, digit.
+
+
+ + +
+ {% else %} +
+ + +
+
+ + +
+ {% endif %} +
+ + Cancel +
+
+
+
+
+
+{% endblock %} \ No newline at end of file diff --git a/app/templates/admin/tenants/index.html b/app/templates/admin/tenants/index.html new file mode 100644 index 0000000..e29301c --- /dev/null +++ b/app/templates/admin/tenants/index.html @@ -0,0 +1,58 @@ +{% extends "admin/layouts/base.html" %} +{% block title %}Tenants{% endblock %} +{% block content %} +
+

Tenants

+ + New Tenant + +
+ +
+
+
+ + {% for s in ['', 'active', 'trial', 'suspended', 'cancelled'] %} + + {{ s.capitalize() if s else 'All' }} + + {% endfor %} +
+
+
+ +
+
+ + + + + + + + + {% for t in tenants %} + + + + + + + + + + {% else %} + + {% endfor %} + +
SlugNamePlanStatusOwnerCreatedActions
{{ t.slug }}{% if t.is_demo %}Demo{% endif %}{{ t.name }}{{ t.plan.name if t.plan else '—' }} + + {{ t.status }} + + {{ t.owner_email }}{{ t.created_at.strftime('%Y-%m-%d') }} + View +
No tenants found.
+
+
+{% endblock %} \ No newline at end of file diff --git a/app/templates/tenant/auth/account_locked.html b/app/templates/tenant/auth/account_locked.html new file mode 100644 index 0000000..3250c4c --- /dev/null +++ b/app/templates/tenant/auth/account_locked.html @@ -0,0 +1,17 @@ +{% extends "layouts/base.html" %} +{% block title %}Account Suspended{% endblock %} + +{% block content %} +
+
+ +

Account Suspended

+

+ Your account has been suspended. Please contact support to resolve any outstanding issues. +

+ + Sign Out + +
+
+{% endblock %} diff --git a/app/templates/tenant/auth/login.html b/app/templates/tenant/auth/login.html index bb3bc2e..260a9e5 100644 --- a/app/templates/tenant/auth/login.html +++ b/app/templates/tenant/auth/login.html @@ -1,32 +1,52 @@ -{% extends "tenant/base.html" %} +{% extends "layouts/base.html" %} {% block title %}Sign In{% endblock %} + {% block content %} -
-
-
-
-

Salon Login

- {% if error %} -
{{ error }}
- {% endif %} -
- -
- - -
-
- - -
- -
-
-
- Forgot password? -  |  - Staff login +
+
+
+
+ +

Salon POS

+

Sign in to your account

+
+ + {% if error %} +
{{ error }}
+ {% endif %} + +
+ + +
+ +
+ +
+ + +
+ +
+ +
+
+ +
+ +
diff --git a/app/templates/tenant/auth/password_reset_confirm.html b/app/templates/tenant/auth/password_reset_confirm.html index 915c896..4c938c6 100644 --- a/app/templates/tenant/auth/password_reset_confirm.html +++ b/app/templates/tenant/auth/password_reset_confirm.html @@ -1,28 +1,33 @@ -{% extends "tenant/base.html" %} +{% extends "layouts/base.html" %} {% block title %}Set New Password{% endblock %} + {% block content %} -
-
-
-
-
Set New Password
- {% if error %} -
{{ error }}
- {% endif %} -
- -
- - -
Min 10 chars, must include uppercase, lowercase, and a digit.
-
-
- - -
- -
-
+
+
+
+
Set New Password
+ + {% if error %} +
{{ error }}
+ {% endif %} + +
+ +
+ + +
Min 10 characters. Uppercase, lowercase, and a digit required.
+
+
+ + +
+
+ +
+
diff --git a/app/templates/tenant/auth/password_reset_request.html b/app/templates/tenant/auth/password_reset_request.html index 4449540..96dd2fd 100644 --- a/app/templates/tenant/auth/password_reset_request.html +++ b/app/templates/tenant/auth/password_reset_request.html @@ -1,26 +1,26 @@ -{% extends "tenant/base.html" %} +{% extends "layouts/base.html" %} {% block title %}Reset Password{% endblock %} + {% block content %} -
-
-
-
-
Reset Password
- {% if message %} -
{{ message }}
- {% else %} -
- -
- - -
- -
- {% endif %} -
- Back to login +
+
+
+
Reset Password
+

Enter your email address and we'll send a reset link.

+ +
+ +
+ +
+
+ +
+
+ +
diff --git a/app/templates/tenant/feature_unavailable.html b/app/templates/tenant/feature_unavailable.html new file mode 100644 index 0000000..e2caebf --- /dev/null +++ b/app/templates/tenant/feature_unavailable.html @@ -0,0 +1,18 @@ +{% extends "layouts/base.html" %} +{% block title %}Feature Unavailable{% endblock %} + +{% block content %} +
+
+ +

Feature Not Available on Your Plan

+

+ The {{ feature }} feature is not included in your current subscription plan. + Please contact your account administrator to upgrade. +

+ + Back to Dashboard + +
+
+{% endblock %} diff --git a/app/templates/tenant/layouts/base.html b/app/templates/tenant/layouts/base.html new file mode 100644 index 0000000..34564f3 --- /dev/null +++ b/app/templates/tenant/layouts/base.html @@ -0,0 +1,189 @@ + + + + + + {% block title %}Salon POS{% endblock %} + + + + + + +{% if current_user.is_authenticated %} + + + +
+
+ + {% if current_user.role != 'tenant_staff' %} + + {% endif %} + + +
+{% endif %} + + {% with messages = get_flashed_messages(with_categories=true) %} + {% for category, message in messages %} + + {% endfor %} + {% endwith %} + + {% block content %}{% endblock %} + +{% if current_user.is_authenticated %} +
+
+
+{% endif %} + + +{% block scripts %}{% endblock %} + + diff --git a/app/templates/tenant/staff_auth/staff_login.html b/app/templates/tenant/staff_auth/staff_login.html new file mode 100644 index 0000000..a3fca4f --- /dev/null +++ b/app/templates/tenant/staff_auth/staff_login.html @@ -0,0 +1,51 @@ +{% extends "layouts/base.html" %} +{% block title %}Staff Login{% endblock %} + +{% block content %} +
+
+
+
+ +

Staff Login

+

Enter your phone number and PIN

+
+ + {% if error %} +
{{ error }}
+ {% endif %} + +
+ + +
+ + +
+ +
+ + +
4–6 digit PIN
+
+ +
+ +
+
+ + +
+
+
+{% endblock %} diff --git a/app/tenant/__init__.py b/app/tenant/__init__.py index fc2351f..0b384e1 100644 --- a/app/tenant/__init__.py +++ b/app/tenant/__init__.py @@ -107,4 +107,4 @@ def create_tenant_app(config_override=None): import app.models # noqa: F401 logger.info("Tenant app created (env=%s)", flask_app.config.get("FLASK_ENV")) - return flask_app \ No newline at end of file + return flask_app diff --git a/templates/admin/auth/login.html b/templates/admin/auth/login.html index ebe7c58..43d52ae 100644 --- a/templates/admin/auth/login.html +++ b/templates/admin/auth/login.html @@ -16,7 +16,6 @@ {% endif %}
- {{ csrf_token() if csrf_token is defined }}