feat: Implement unified Vue SPA with granular service control
Consolidate Reports and Data Entry apps into a single Vue.js SPA with: Architecture: - Module-based structure with lazy-loaded routes (@reports, @data-entry) - Error boundaries per module to prevent cascade failures - Dual API proxy in Vite for microservices (reports:8001, data-entry:8003) - Pinia store factories for shared auth, company, and period stores - Vite path aliases for clear module boundaries (@shared, @reports, @data-entry) Service Management: - Granular service control scripts (backend-reports.sh, backend-data-entry.sh, bot.sh, frontend.sh) - 87% faster frontend restart: 7s vs 53s full restart - 38% faster full startup: 33s vs 53s via parallel backend initialization - Enhanced start-dev.sh with proper service timeouts (OCR: 30s, Vite: 15s, Bot: 10s) - status.sh for comprehensive health checks Features: - Auto-select first company on login with period auto-load - Hamburger menu with feature toggle support - JWT token auto-injection via axios interceptors - Unified header with company/period selectors - IIS web.config for production deployment with multi-API routing UX Improvements: - Vue watchers for reactive company/period loading - Lazy store initialization with graceful error handling - Period persistence per user+company in localStorage - Feature flags for optional modules Deployment: - Single IIS site serves unified frontend with API proxy rules - Maintains separate backend processes for microservices - Windows line ending fixes (.env CRLF → LF conversion) Stats: 112 files changed, 38,342 insertions(+), 2,342 deletions(-) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
This commit is contained in:
138
src/assets/css/vendor/primevue-overrides.css
vendored
Normal file
138
src/assets/css/vendor/primevue-overrides.css
vendored
Normal file
@@ -0,0 +1,138 @@
|
||||
/* PrimeVue Component Overrides - ROA2WEB */
|
||||
/* Global customization of PrimeVue saga-blue theme */
|
||||
|
||||
/* ===== Input Components ===== */
|
||||
.p-inputtext,
|
||||
.p-password input,
|
||||
.p-dropdown,
|
||||
.p-calendar input,
|
||||
.p-autocomplete input {
|
||||
border: 2px solid var(--color-border) !important;
|
||||
border-radius: var(--radius-md) !important;
|
||||
padding: var(--space-sm) var(--space-md) !important;
|
||||
font-size: var(--text-base) !important;
|
||||
font-family: inherit !important;
|
||||
color: var(--color-text) !important;
|
||||
background: var(--color-bg) !important;
|
||||
transition: all var(--transition-fast) !important;
|
||||
min-height: 44px !important;
|
||||
}
|
||||
|
||||
/* ===== Focus States ===== */
|
||||
.p-inputtext:focus,
|
||||
.p-password input:focus,
|
||||
.p-dropdown:focus,
|
||||
.p-calendar input:focus,
|
||||
.p-autocomplete input:focus {
|
||||
outline: none !important;
|
||||
border-color: var(--color-primary) !important;
|
||||
box-shadow: var(--focus-ring) !important;
|
||||
}
|
||||
|
||||
/* ===== Hover States ===== */
|
||||
.p-inputtext:hover:not(:disabled),
|
||||
.p-password input:hover:not(:disabled),
|
||||
.p-dropdown:hover:not(:disabled) {
|
||||
border-color: var(--color-border-dark, #d1d5db) !important;
|
||||
}
|
||||
|
||||
/* ===== Disabled States ===== */
|
||||
.p-inputtext:disabled,
|
||||
.p-password input:disabled,
|
||||
.p-dropdown:disabled {
|
||||
background: var(--color-bg-muted, #f3f4f6) !important;
|
||||
color: var(--color-text-muted, #9ca3af) !important;
|
||||
opacity: 0.6 !important;
|
||||
cursor: not-allowed !important;
|
||||
}
|
||||
|
||||
/* ===== Validation States ===== */
|
||||
.p-invalid.p-component,
|
||||
.p-inputtext.p-invalid,
|
||||
.p-password.p-invalid input {
|
||||
border-color: var(--color-error, #ef4444) !important;
|
||||
}
|
||||
|
||||
/* ===== Button Overrides ===== */
|
||||
.p-button {
|
||||
padding: var(--space-sm) var(--space-md) !important;
|
||||
font-size: var(--text-sm) !important;
|
||||
font-weight: var(--font-medium) !important;
|
||||
border-radius: var(--radius-md) !important;
|
||||
transition: all var(--transition-fast) !important;
|
||||
}
|
||||
|
||||
.p-button:hover {
|
||||
transform: translateY(-1px) !important;
|
||||
box-shadow: var(--shadow-md) !important;
|
||||
}
|
||||
|
||||
/* ===== DataTable ===== */
|
||||
.p-datatable .p-datatable-thead > tr > th {
|
||||
background: var(--color-bg-muted, #f9fafb) !important;
|
||||
color: var(--color-text) !important;
|
||||
font-weight: var(--font-semibold) !important;
|
||||
border-bottom: 2px solid var(--color-border) !important;
|
||||
padding: var(--space-md) var(--space-lg) !important;
|
||||
}
|
||||
|
||||
.p-datatable .p-datatable-tbody > tr {
|
||||
transition: background-color var(--transition-fast) !important;
|
||||
}
|
||||
|
||||
/* DataTable Striped Rows - Global Pattern */
|
||||
.p-datatable .p-datatable-tbody > tr:nth-child(odd) {
|
||||
background-color: #ffffff !important;
|
||||
}
|
||||
|
||||
.p-datatable .p-datatable-tbody > tr:nth-child(even) {
|
||||
background-color: #f8f9fa !important;
|
||||
}
|
||||
|
||||
.p-datatable .p-datatable-tbody > tr:hover {
|
||||
background-color: #e3f2fd !important;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
/* Compact DataTable variant (p-datatable-sm) */
|
||||
.p-datatable-sm .p-datatable-thead > tr > th {
|
||||
padding: 0.5rem 0.75rem !important;
|
||||
font-weight: 600 !important;
|
||||
white-space: nowrap !important;
|
||||
}
|
||||
|
||||
.p-datatable-sm .p-datatable-tbody > tr > td {
|
||||
padding: 0.4rem 0.75rem !important;
|
||||
}
|
||||
|
||||
/* DataTable font size for compact tables */
|
||||
.p-datatable-sm {
|
||||
font-size: 0.875rem !important;
|
||||
}
|
||||
|
||||
/* ===== Card ===== */
|
||||
.p-card {
|
||||
box-shadow: var(--shadow-sm) !important;
|
||||
border: 1px solid var(--color-border) !important;
|
||||
border-radius: var(--card-radius, 8px) !important;
|
||||
}
|
||||
|
||||
.p-card .p-card-header {
|
||||
background: var(--color-bg-secondary) !important;
|
||||
border-bottom: 1px solid var(--color-border) !important;
|
||||
padding: var(--space-lg) !important;
|
||||
}
|
||||
|
||||
.p-card .p-card-body {
|
||||
padding: var(--space-lg) !important;
|
||||
}
|
||||
|
||||
/* ===== Mobile Optimizations ===== */
|
||||
@media (max-width: 768px) {
|
||||
.p-inputtext,
|
||||
.p-password input,
|
||||
.p-dropdown,
|
||||
.p-calendar input {
|
||||
font-size: 16px !important; /* Prevent iOS zoom */
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user