TQPro Admin Interface (tqweb-adm) -- UX Improvement Recommendations¶
Update (2026-04-02, TQ-103): The design system has been created and a design reconciliation has been applied across all admin modules. The root cause identified below (absence of a shared design system) is now addressed by:
doc/design-system/tq-tokens.css— Unified design tokensdoc/design-system/tq-components.md— Canonical component librarydoc/design-system/tq-templates.md— Page template skeletonsdoc/design-system/DECISIONS.md— 42 design decisions applied across 65 filesCross-cutting CSS inconsistencies (breadcrumbs, cards, KPI cards, filter bars, empty states, button colors, table classes) have been resolved. Individual module bugs listed below may still require attention on a per-module basis.
Executive Summary¶
A comprehensive UX audit was conducted across all 9 modules of the tqweb-adm admin interface, comparing documented requirements against actual code implementation. The audit catalogued 137 issues across 9 modules (30 critical, 42 high, 30 medium, 35 low) and identified 10 cross-cutting bug patterns affecting 3+ modules each.
Module readiness ranges from 40% (Dashboard) to 80% (Offer Management). The root cause of most cross-cutting issues is the absence of a shared component library and design system.
Module Readiness Summary¶
| Module | Readiness | Key Blockers |
|---|---|---|
| Offer Management | 80% | Modal-closes-before-validation bug; cascade delete inconsistency |
| Outbound Groups | 75% | Missing quote generation; activity pricing incomplete; mixed currency bug |
| Hotel Management | 70% | Date cap blocks 2026+ use; async bug; no validation |
| Cruise Management | 60% | Exchange rate broken; status values limited; data corruption in bulk ops |
| Visa Management | 55% | Invoice/delivery workflows missing; supplier dropdown empty; backend stubs |
| Trip Maker | 45% | ~50% of documented use cases non-functional; fake auto-save; no PDF output |
| Dashboard & Navigation | 40% | All KPIs hardcoded; multiple dead links; broken login flow |
| Inbound Groups | (not fully assessed) | Report incomplete |
| Marketing Planning | (not fully assessed) | Report incomplete |
Issue Distribution by Severity¶
| Module | Critical | High | Medium | Low | Total |
|---|---|---|---|---|---|
| Dashboard & Navigation | 6 | 8 | 4 | 5 | 23 |
| Hotel Management | 2 | 5 | 1 | 0 | 8 |
| Cruise Management | 4 | 4 | 2 | 0 | 10 |
| Outbound Groups | 4 | 7 | 11 | 10 | 32 |
| Trip Maker | 7 | 8 | 0 | 11 | 26 |
| Visa Management | 5 | 5 | 5 | 5 | 20 |
| Offer Management | 2 | 5 | 7 | 4 | 18 |
| TOTALS | 30 | 42 | 30 | 35 | 137 |
1. Cross-Module Navigation and Information Architecture¶
1.1 Sidebar and Header Navigation Are Misaligned¶
The application has two primary navigation mechanisms -- a global header (header_bootstrap.html) and a dashboard sidebar (index.html). These present different feature sets with no clear rationale for the differences.
| Feature | In Header | In Sidebar | Status |
|---|---|---|---|
| Groups (Inbound) | Yes | Yes | Working |
| Outbound Groups | Yes | No | Working but hidden from sidebar users |
| Flights | No | Yes | Working but hidden from header users |
| Hotels | Yes | Yes | Working |
| Visas | Yes | Yes | Working |
| Trip Maker | Yes | Yes | Working |
| Cruises | Yes (dead #) |
Yes (dead #) |
Both broken |
| Offers/Current Offers | Yes (broken -- current-offers.html does not exist) |
Yes (dead #) |
Both non-functional |
| Activities | Yes (dead #) |
Yes (dead #) |
Both broken |
| Calendar | No | Yes (dead #) |
Broken |
| Settings | No | Yes (dead #) |
Broken |
| Offer Manager | No | Yes | Working but different name from "Offers" |
| Marketing Planning | No | No | Page exists (mktplan.html) but unreachable |
Impact: Users discover features inconsistently depending on whether they use the header or sidebar. Marketing Planning is entirely orphaned with no navigation path. Outbound Groups -- a module with 11 dedicated pages -- has no sidebar entry at all.
1.2 Dead Links¶
Across the header and sidebar, there are at least 7 dead links (href="#") that produce no response when clicked. There is no visual distinction between functional and non-functional links. Affected items: Cruises (header + sidebar), Tours & Activities (header + sidebar), Offers (sidebar), Calendar (sidebar), Settings (sidebar), plus current-offers.html (header -- file does not exist).
1.3 No Unified Cross-Module Search¶
There is no global search capability. Each module implements its own search independently (dashboard has none, Visa has inline search, Groups has filter panels, TripMaker has debounced text search).
1.4 Flight Search Page Breaks Navigation¶
The flight search page (flights.html) is a third-party React widget that does not include the shared header template. When a user navigates to the flight search, they lose all global navigation and must use the browser back button to return.
1.5 No Breadcrumb System¶
Outbound Groups is the only module that implements breadcrumbs (inconsistently). No other module provides any breadcrumb trail. Deep pages like the Cruise cabin assignment (3 dialogs deep) or Hotel calendar editing have no orientation indicators.
1.6 Flat Top-Level Navigation¶
The header navigation has 10+ items at the same level with no grouping. This exceeds the recommended maximum of 7 items. Logical groupings exist but are not applied: - Group Tourism: Inbound Groups, Outbound Groups - Products: Hotels, Flights, Cruises, Activities - Tools: Trip Maker, Offer Manager, Marketing Planning - Administration: Settings, Dashboard
1.7 Module Naming Inconsistency¶
| Concept | Header Name | Sidebar Name | Page Title |
|---|---|---|---|
| Marketing pages | "Offers" | "Offer Manager" | "Trip Offer Management" |
| Outbound groups | "Outbound" | (absent) | "Outbound Groups" |
| Activities in Outbound | "Activities" | -- | "Activities & Tours" |
1.8 Dashboard Provides No Operational Value¶
All KPI cards (Groups, Visas, Itineraries) are hardcoded to zero with no API calls. KPI cards are non-clickable. Hotels, Flights, Cruises, and Offers have no dashboard presence.
2. Screen Usability and Visual Consistency¶
2.1 Required Field Indicators -- Absent Everywhere¶
No module consistently marks required fields. The only asterisk in the entire application appears on groupDestination in Outbound Groups. Users discover required fields only when save fails.
2.2 Form Validation -- Four Incompatible Strategies¶
| Strategy | Where Used | Limitations |
|---|---|---|
| Manual JS check before API call | Outbound Groups, Offer Management | Only checks subset of fields |
pageutil.js validators |
Hotel Management, older forms | Uses Foundation-era is-invalid-input class -- no Bootstrap CSS match |
HTML5 required attribute |
Sporadic | Never triggered (forms use button clicks, not <form> submission) |
| No validation at all | Visa wizard, Trip Maker creation | Zero field validation before API call |
Key finding: The pageutil.js validation class is-invalid-input is a Foundation CSS class with no corresponding Bootstrap 5 styles. Validation errors set aria-invalid but produce no visual feedback. Bootstrap's own classes (is-invalid, was-validated, invalid-feedback) are never used anywhere.
2.3 Error Feedback -- Five Different Mechanisms¶
| Mechanism | Modules Using It |
|---|---|
$.notify() toasts |
Hotel, Cruise, Offer Mgmt |
alert() browser dialogs |
Login page, error handlers |
showMessageSection() banners |
pageutil.js (underused) |
showMediumDialog() modals |
pageutil.js |
| Console logging only | Various error handlers |
Critical gap: No module implements inline field-level errors (red borders + error text below the field). The standard Bootstrap pattern (is-invalid class + .invalid-feedback div) is never used.
2.4 CSS Framework Fragmentation¶
| Framework | Pages |
|---|---|
| Bootstrap 5 | Most admin pages |
| PicoCSS v2 | Login page |
| React + custom CSS + Material Icons | Flight search |
| Foundation-era CSS remnants | Hotel management validation |
2.5 CSS Variable Duplication¶
Design tokens (:root variables) are duplicated identically in three places:
1. index.html -- inline <style> block
2. visamgmt.html -- inline <style> block
3. css/tqadmin.css -- external stylesheet
2.6 Button Styling -- Four Different Approaches¶
| Approach | Where |
|---|---|
Standard Bootstrap btn btn-primary |
Groups, Outbound Groups, Visa |
Custom perun-button |
Hotel Management, older pages |
tqadmin scoped buttons |
Offer Management, Cruise |
| Inline-styled buttons | Offer Management |
Hotel Management has no visual distinction between creative and destructive action buttons.
2.7 Status Badge Inconsistency¶
Status terminology and badge colors differ across every module. Visa Management uses identical colors for Cancelled and Rejected. Cruise Management uses rgba(255,255,255,0.2) for status badges -- poor contrast.
2.8 Aggressive Global CSS Rule¶
The global rule p { margin-bottom: 0; text-align: center; } in tqapp.css forces ALL paragraphs to center-align with no bottom margin -- causing widespread layout anomalies.
3. Interaction Patterns¶
3.1 Modal-Closes-Before-Validation Bug (Critical)¶
In Offer Management, save buttons have data-bs-dismiss="modal" as an HTML attribute, causing Bootstrap to close the modal the instant the button is clicked -- before the JavaScript validation handler runs. If validation fails, the modal is gone and form data is lost. Affected locations: offerman.html lines 223, 262, 367, 486, 591, 634.
3.2 No Unsaved Changes Warning (Affects All Modules)¶
No module implements beforeunload event handling or dirty-state tracking. Users who navigate away from partially completed forms lose all entered data without warning. The Trip Maker module has a fake auto-save that shows "Saving..." text but makes no API call -- actively deceptive.
3.3 Delete Confirmations -- Inconsistent¶
| Pattern | Where Used |
|---|---|
Native confirm() dialog |
Outbound Groups, Offer Management |
| No confirmation at all | Visa Management quick-status change |
No module uses a styled Bootstrap confirmation modal for delete operations.
3.4 Loading States -- Absent or Inconsistent¶
| Module | Loading Indicator |
|---|---|
| Cruise Management | None |
| Offer Management | None |
| Visa Management | None on initial load |
| Trip Maker | None on create button |
| Hotel Management | Not documented |
The shared showWaitDialog() utility exists in pageutil.js but most modules do not call it.
3.5 Pagination -- Non-Functional¶
| Module | Status |
|---|---|
| Offer Management | Functional (only module) |
| Trip Maker | Pagination HTML exists, JS never renders it |
| Visa Management | Pagination buttons exist, no click handlers |
| Outbound Groups list | No pagination -- all items at once |
3.6 Search and Filtering -- Wildly Inconsistent¶
Trip Maker is particularly problematic: three filter controls on the same bar each have different trigger behaviors (auto on type, auto on blur, manual button click).
4. Within-Module Workflow Issues¶
4.1 No Workflow Step Indicators¶
| Module | Expected Workflow | Guidance Provided |
|---|---|---|
| Outbound Groups | 8-step process | 8 equal buttons with no ordering, completion, or dependency hints |
| Visa Management | 5-step wizard | Stepper exists but step 4 (Invoice) is entirely missing; stepper is non-clickable |
| Trip Maker | Multi-step project creation | Overview has checkmarks but no step sequencing; many steps non-functional |
| Cruise Management | Company > Ship > Cruise > Cabins > Pricing | Tree implies order but no completeness indicators |
| Hotel Management | Hotel > Calendar > Rates > Supplements > Promotions | Promotions tab is non-functional mockup |
4.2 Implicit Dependencies Without Guards¶
- Outbound Groups Rooming -- requires Passengers and Accommodation; silently shows empty state
- Outbound Groups Invoicing -- requires Passengers and Pricing; minimal empty state
- Cruise Cabin Assignment -- requires ship and cabin types; no validation
- Hotel Calendar -- "Add New Hotel" requires selecting a hotel first; buried workflow
4.3 Dual-Interface Editing (Visa Management)¶
Two completely different editing interfaces for the same data: a 5-step wizard for new applications and a 3-tab modal for existing applications. Fields organized differently, nationality handling differs, document management uses different mechanics.
4.4 Hub-and-Spoke Navigation (Outbound Groups)¶
No inter-page navigation between sub-pages. To go from Passengers to Accommodation: navigate back to Summary, then click Accommodation. For sequential workflows, this doubles the navigation steps.
5. Feature Gap Analysis¶
Tier 1: Core Workflow Blockers¶
| Gap | Module | Impact |
|---|---|---|
| Invoice & Payment step missing | Visa Management | Cannot complete visa workflow end-to-end |
| PDF quotation inaccessible | Trip Maker | No button to trigger generatePDF(); agents cannot produce client-facing output |
| Activity scheduling non-functional | Trip Maker | Missing Date/Time fields; calendar is a stub |
| Fake auto-save | Trip Maker | Users believe data is saved when it is not |
| Exchange rate hardcoded to 1.0 | Cruise Management | Multi-currency pricing broken |
| Bulk cabin maxPax data loss | Cruise Management | Only first cabin's value sent during bulk assignment |
| Year cap max="2025" on calendar | Hotel Management | Module non-functional for 2026+ dates |
| Supplier dropdown empty | Visa Management | Cannot submit to suppliers |
| Project status transitions missing | Trip Maker | Cannot execute project lifecycle |
| Quote generation missing | Outbound Groups | Cannot produce quotes despite workflow expecting them |
Tier 2: Significant Functional Gaps¶
| Gap | Module |
|---|---|
| Visa delivery management | Visa Management |
| Visa supplier cost/price tracking | Visa Management |
| No activity edit/remove | Trip Maker |
| Activities missing price fields | Outbound Groups |
| Mixed currency summing without conversion | Outbound Groups |
| Drag-and-drop non-functional | Trip Maker |
showOverridePriceModal() undefined |
Trip Maker |
updateComponentMargin parameter swap |
Trip Maker |
| Async/await misuse in saveQuickRates | Hotel Management |
| Cruise status values limited | Cruise Management |
| Promotions tab is mockup | Hotel Management |
Tier 3: Missing Enhancements¶
| Gap | Module |
|---|---|
| No trip deletion/cloning | Outbound Groups |
| No calendar view | Outbound Groups |
| No print function | Outbound Groups |
| No inter-page navigation | Outbound Groups |
| No project delete | Trip Maker |
| No document preview/download | Visa Management |
| No keyboard shortcuts | Trip Maker |
| No keyboard navigation in tree | Cruise Management |
6. Cross-Module Bug Patterns¶
These 10 patterns recur across 3+ modules, indicating systemic issues:
| # | Pattern | Affected Modules | Severity |
|---|---|---|---|
| 1 | No client-side form validation | Hotel, Cruise, Visa, Outbound, Offer, TripMaker | HIGH |
| 2 | No loading indicators / spinners | Cruise, Visa, Offer, Dashboard, TripMaker, Outbound | HIGH |
| 3 | No unsaved changes warning | Hotel, Cruise, Outbound, TripMaker, Offer | HIGH |
| 4 | Native confirm() / alert() / prompt() |
Outbound, Offer, TripMaker, Visa, Dashboard | MEDIUM |
| 5 | Non-functional pagination | Visa, TripMaker, Dashboard | HIGH |
| 6 | Dead / broken navigation links | Dashboard & Nav, Flight Search | CRITICAL |
| 7 | Hardcoded values (dates, rates, currency, KPIs) | Hotel, Cruise, Offer, Dashboard | CRITICAL |
| 8 | Backend API stubs returning null | Visa, TripMaker, Cruise | CRITICAL |
| 9 | Inconsistent delete confirmation / no undo | Outbound, Offer, Visa, Cruise | MEDIUM |
| 10 | Stale / incorrect documentation | Hotel, Offer, TripMaker, Visa | MEDIUM |
7. Quick Wins (~4 Hours Total)¶
Issues fixable in under 2 hours each, with high visibility improvement:
| # | Fix | Module | Est. | Impact |
|---|---|---|---|---|
| 1 | Change max="2025" to max="2030" on hotel date inputs |
Hotel | 5 min | Unblocks entire module |
| 2 | Remove data-bs-dismiss="modal" from 6 save buttons in offerman.html |
Offer | 10 min | Stops form data loss |
| 3 | Fix forEach -> for...of in saveQuickRates for async/await |
Hotel | 15 min | Prevents silent save failures |
| 4 | Add "Generate PDF" button to Trip Maker workspace HTML | TripMaker | 15 min | Unlocks quotation workflow |
| 5 | Fix updateComponentMargin parameter order |
TripMaker | 5 min | Fixes data corruption |
| 6 | Remove fake auto-save indicator (or add real API call) | TripMaker | 15 min | Eliminates deceptive UX |
| 7 | Fix onclick="toggleLoader" -> onclick="toggleLoader()" |
Dashboard | 5 min | Fixes login spinner |
| 8 | Fix current-offers.html link -> offerman.html |
Dashboard | 5 min | Removes dead nav link |
| 9 | Fix Cruise bulk cabin assignment to send per-cabin maxPax | Cruise | 30 min | Prevents data corruption |
| 10 | Add required field asterisks to all mandatory form fields | ALL | 1 hour | Improves form clarity |
| 11 | Differentiate Cancelled/Rejected badge colors in Visa | Visa | 10 min | Removes visual ambiguity |
| 12 | Replace window.prompt() with Bootstrap modal in Trip Maker |
TripMaker | 30 min | Eliminates jarring native dialog |
| 13 | Fix login.html path in header |
Dashboard | 5 min | Fixes broken login link |
| 14 | Remove developer placeholder text | TripMaker | 5 min | Removes developer text from UI |
| 15 | Add min-chars hint to partner lookup fields | Outbound | 10 min | Removes hidden interaction requirement |
Total: ~4 hours | Fixes 6 critical bugs, 5 high-priority issues, 4 polish items
8. Top 20 Prioritized Recommendations¶
| Rank | Recommendation | Effort | Impact |
|---|---|---|---|
| 1 | Fix hardcoded date cap (max="2025") in Hotel Management | S | CRITICAL |
| 2 | Implement global form validation framework | M | HIGH |
| 3 | Fix updateComponentMargin parameter swap and showOverridePriceModal |
S | CRITICAL |
| 4 | Replace fake auto-save with real persistence (or remove indicator) | S | CRITICAL |
| 5 | Add loading indicators to all API operations | M | HIGH |
| 6 | Fix Cruise bulk cabin maxPax data loss | S | CRITICAL |
| 7 | Fix exchange rate hardcoding in Cruise Management | M | CRITICAL |
| 8 | Fix all broken navigation links | S | HIGH |
| 9 | Remove data-bs-dismiss="modal" from Offer Management save buttons |
S | CRITICAL |
| 10 | Implement dashboard KPI data from live APIs | M | HIGH |
| 11 | Add unsaved changes detection | M | HIGH |
| 12 | Fix Hotel Management async/await in saveQuickRates | S | CRITICAL |
| 13 | Add Generate PDF button to Trip Maker workspace | S | HIGH |
| 14 | Populate Visa Management supplier dropdown | S | HIGH |
| 15 | Add activity Date and Time Period fields to Trip Maker | M | HIGH |
| 16 | Standardize notification system across all modules | M | MEDIUM |
| 17 | Add Hotel Management form validation | M | HIGH |
| 18 | Implement Outbound Groups inter-page navigation | S | MEDIUM |
| 19 | Fix login page technical issues (PicoCSS, XHR, credentials) | M | HIGH |
| 20 | Implement functional pagination | M | MEDIUM |
9. Strategic Improvements¶
9.1 Shared Component Library (tqpro-components.js)¶
Effort: 2-3 weeks | Impact: Eliminates inconsistency across all 9 modules
Provides: standard form validation, loading state management, notification system, confirmation dialog, unsaved changes detection, pagination component. Resolves patterns 1-5 from Section 6 in a single coordinated effort.
9.2 Navigation Architecture Overhaul¶
Effort: 1 week | Impact: Resolves all navigation-related issues
Unify sidebar and header, implement dropdown grouping, remove/mark dead links, add global search, ensure flight search is wrapped in standard layout.
9.3 Trip Maker Feature Completion¶
Effort: 3-4 weeks | Impact: Makes module production-ready (currently ~45%)
Priority: Activity scheduling > Edit/remove > PDF generation > Real auto-save > Status transitions > Pagination.
9.4 Visa Management Module Completion¶
Effort: 3-4 weeks | Impact: Completes workflow from application to delivery
Priority: Supplier dropdown > Invoice step > Backend APIs > Delivery management > File upload > Document preview.
9.5 Cruise Management Pricing Infrastructure¶
Effort: 1-2 weeks | Impact: Makes multi-currency pricing functional
Replace hardcoded exchange rate, implement proper status lifecycle, fix bulk cabin handling.
9.6 Dashboard as Operational Command Center¶
Effort: 1-2 weeks | Impact: Transforms landing page from mockup to operational tool
Live KPI data, clickable drill-down cards, Quick Actions bar, Recent Items section.
10. Design System Gaps (Root Cause Analysis)¶
The root cause of most cross-cutting issues is the absence of a shared design system:
- No shared component library for forms, tables, cards, modals, or notifications
- No standardized form validation approach
- No consistent status badge palette
- No consistent button hierarchy
- CSS design tokens duplicated rather than centralized
- Mixed CSS frameworks (Bootstrap 5, PicoCSS, React SSR, Foundation artifacts)
- Multiple competing utility libraries with overlapping functionality
| Component | Variants in Use |
|---|---|
| CSS Framework | Bootstrap 5, PicoCSS (login), Foundation remnants, React CSS-in-JS (flights) |
| Button Styles | btn btn-primary, perun-button, tqadmin-scoped, inline-styled |
| Notification System | alert(), $.notify(), showMessageSection(), showMediumDialog(), console logging |
| Dialog Pattern | Inline modals, dynamically loaded modals, window.prompt() |
| Loading Indicators | showWaitDialog(), Bootstrap spinners, PicoCSS spinner, none |
| jQuery CDN | cdn.jsdelivr.net/npm/jquery, code.jquery.com |
| CSS Variables | Defined in index.html, visamgmt.html, and tqadmin.css (3 copies) |
The single most impactful investment would be creating a shared tqpro-components.js module providing unified form validation, notifications, loading states, modal lifecycle, and status badges. This, combined with consolidating CSS tokens into tqadmin.css and removing legacy framework artifacts, would address roughly 80% of the cross-cutting usability issues.
Report generated: 2026-02-17 Methodology: Per-module analysis (9 agents) comparing documented requirements against code implementation, followed by 3-agent review board synthesis (User Flow, Usability, Prioritization) Total issues catalogued: 137 across 9 modules