From b45a9eccd6eef96f72d4f9128ad07b0a5cdce7fc Mon Sep 17 00:00:00 2001 From: Codex Date: Fri, 10 Jul 2026 12:56:04 -0500 Subject: [PATCH] Phase 1 UI system --- CHANGELOG.md | 3 + docs/DEPLOYMENT.md | 8 +- docs/INSTALL.md | 1 + docs/ROADMAP.md | 4 +- resources/css/app.css | 28 ++ resources/views/auth/login.blade.php | 6 +- resources/views/auth/register.blade.php | 4 +- .../views/components/action-card.blade.php | 12 + resources/views/components/badge.blade.php | 15 + .../views/components/danger-button.blade.php | 2 +- .../views/components/dropdown-link.blade.php | 2 +- resources/views/components/dropdown.blade.php | 4 +- resources/views/components/field.blade.php | 11 +- .../views/components/input-error.blade.php | 2 +- .../views/components/input-label.blade.php | 2 +- resources/views/components/nav-link.blade.php | 4 +- .../views/components/page-header.blade.php | 19 ++ .../views/components/primary-button.blade.php | 2 +- .../components/responsive-nav-link.blade.php | 4 +- .../components/secondary-button.blade.php | 2 +- .../views/components/stat-card.blade.php | 9 + .../views/components/text-input.blade.php | 2 +- .../views/components/theme-toggle.blade.php | 21 ++ resources/views/dashboard.blade.php | 82 ++--- resources/views/layouts/app.blade.php | 15 +- resources/views/layouts/guest.blade.php | 23 +- resources/views/layouts/navigation.blade.php | 25 +- resources/views/welcome.blade.php | 287 +++++------------- routes/web.php | 15 +- tailwind.config.js | 2 + 30 files changed, 324 insertions(+), 292 deletions(-) create mode 100644 resources/views/components/action-card.blade.php create mode 100644 resources/views/components/badge.blade.php create mode 100644 resources/views/components/page-header.blade.php create mode 100644 resources/views/components/stat-card.blade.php create mode 100644 resources/views/components/theme-toggle.blade.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 0a5590c..1603036 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,9 @@ This project uses Git as the primary rollback trail. The `.old` convention is re ### Added +- Added a Phase 1 UI system pass with dark/light theme support, shared page/action/stat components, a product-focused home page, and a more useful dashboard. +- Added roadmap guardrails for open-source-friendly dependencies, public themes, and future license audits. +- Documented `pdo_sqlite` and `sqlite3` as required PHP extensions for SQLite-backed local tests and first-pass deployments. - Created the Laravel Provider Exchange prototype with Breeze authentication, seeded demo users, and role support for admins, providers, buyers, and hybrid accounts. - Added provider and buyer profile management with service areas, profile details, and external profile snapshot records. - Added social posts, buyer job posts, provider quotes, quote revisions, quote decline flow, and buyer quote acceptance. diff --git a/docs/DEPLOYMENT.md b/docs/DEPLOYMENT.md index 5e90f4e..95d75a2 100644 --- a/docs/DEPLOYMENT.md +++ b/docs/DEPLOYMENT.md @@ -17,7 +17,7 @@ This document records the explicit runtime requirements and server changes for P - `mbstring` - `openssl` - `pdo` - - `pdo_sqlite` for the first live test deployment + - `pdo_sqlite` for SQLite test deployments and the default automated test suite - `session` - `tokenizer` - `xml` @@ -28,6 +28,12 @@ This document records the explicit runtime requirements and server changes for P - `bootstrap/cache/` - the SQLite database file for SQLite test deployments. +## Local Test Requirements + +- The default PHPUnit configuration uses an in-memory SQLite database, so whichever PHP runtime executes `php artisan test` must include `pdo_sqlite` and `sqlite3`. +- On Windows, `php -m` should list both `PDO` and `pdo_sqlite`; otherwise the feature tests fail before reaching app code with `could not find driver`. +- WSL Ubuntu is acceptable for local verification when Windows PHP is missing SQLite support, as long as WSL PHP has `pdo_sqlite` and `sqlite3`. + ## Recommended Production Runtime - Nginx. diff --git a/docs/INSTALL.md b/docs/INSTALL.md index 8493d24..5f1944b 100644 --- a/docs/INSTALL.md +++ b/docs/INSTALL.md @@ -31,6 +31,7 @@ APP_DIR=/var/www/technical-services-exchange bash /var/www/technical-services-ex ## Important Notes - The installer is a first-pass Ubuntu/Nginx helper, not a universal hosting panel installer. +- Local and CI test runners need PHP SQLite support: `pdo_sqlite` and `sqlite3`. - Review `.env` before production use. - Configure real mail before inviting users. - Move sessions, cache, and queues to Redis before serious traffic. diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index c84fc30..0a6a91b 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -29,12 +29,13 @@ Provider Exchange is a Laravel application for a provider-centered field-service - Payment remains direct between buyer and provider unless a compliant payment partner is deliberately added later. - Reputation should be mutual, transparent, and appealable through community review. - Dispute voting is a community reputation signal, not legal adjudication. +- Runtime dependencies, UI components, and themes should stay open-source friendly. Avoid proprietary theme kits, unclear asset licenses, or dependencies that would restrict commercial, nonprofit, or community scaling. ## Next Build Phases 1. Profile depth: richer galleries, equipment lists, certifications, insurance fields, service coverage maps, and imported review summaries. 2. Directory quality: saved searches, better filtering, profile badges, availability signals, and stronger buyer/provider discovery pages. -3. Work-order depth: checklist templates, required evidence rules, appointment windows, onsite timestamps, and change-request records. +3. Work-order depth: checklist templates, required evidence rules, appointment windows, onsite timestamps, change-request records, and print/PDF export for work-order packets. 4. Reputation refinement: rating category definitions, anti-abuse controls, edit windows, report flows, and moderation views. 5. Dispute workflow: better evidence timelines, reason-coded votes, quorum/visibility rules, and admin/community moderation tools. 6. Notifications: channel preferences, email templates, and event-specific subscription controls. @@ -42,6 +43,7 @@ Provider Exchange is a Laravel application for a provider-centered field-service 8. Import tooling: guided manual imports for Field Nation, WorkMarket, and similar profile/review history. 9. Admin operations: audit logs, queue health, system status, content moderation, and backup/export workflows. 10. Deployment hardening: production environment docs, queue worker setup, scheduler setup, storage policy, and server provisioning notes. +11. License and runtime audit: generate and review PHP and JavaScript dependency license reports before adding external theme kits, map any risky package to a replacement, and keep required local/runtime extensions such as `pdo_sqlite` documented for testability. ## Scaling Risks To Track diff --git a/resources/css/app.css b/resources/css/app.css index b5c61c9..31a4e14 100644 --- a/resources/css/app.css +++ b/resources/css/app.css @@ -1,3 +1,31 @@ @tailwind base; @tailwind components; @tailwind utilities; + +@layer base { + html { + color-scheme: light; + } + + html.dark { + color-scheme: dark; + } + + body { + @apply bg-slate-100 text-slate-950 antialiased dark:bg-slate-950 dark:text-slate-100; + } + + [x-cloak] { + display: none !important; + } +} + +@layer components { + .tse-panel { + @apply rounded-lg border border-slate-200 bg-white shadow-sm dark:border-slate-800 dark:bg-slate-900; + } + + .tse-muted { + @apply text-slate-600 dark:text-slate-400; + } +} diff --git a/resources/views/auth/login.blade.php b/resources/views/auth/login.blade.php index 78b684f..e959aab 100644 --- a/resources/views/auth/login.blade.php +++ b/resources/views/auth/login.blade.php @@ -27,14 +27,14 @@
@if (Route::has('password.request')) - + {{ __('Forgot your password?') }} @endif diff --git a/resources/views/auth/register.blade.php b/resources/views/auth/register.blade.php index 2c5c560..af5498e 100644 --- a/resources/views/auth/register.blade.php +++ b/resources/views/auth/register.blade.php @@ -18,7 +18,7 @@
- @@ -50,7 +50,7 @@
- + {{ __('Already registered?') }} diff --git a/resources/views/components/action-card.blade.php b/resources/views/components/action-card.blade.php new file mode 100644 index 0000000..02a9bb4 --- /dev/null +++ b/resources/views/components/action-card.blade.php @@ -0,0 +1,12 @@ +@props(['title', 'description', 'href' => null, 'label' => 'Open']) + +
+

{{ $title }}

+

{{ $description }}

+ @if ($href) + + {{ $label }} + + + @endif +
diff --git a/resources/views/components/badge.blade.php b/resources/views/components/badge.blade.php new file mode 100644 index 0000000..059eb53 --- /dev/null +++ b/resources/views/components/badge.blade.php @@ -0,0 +1,15 @@ +@props(['tone' => 'slate']) + +@php +$tones = [ + 'sky' => 'bg-sky-100 text-sky-800 dark:bg-sky-950 dark:text-sky-200', + 'emerald' => 'bg-emerald-100 text-emerald-800 dark:bg-emerald-950 dark:text-emerald-200', + 'amber' => 'bg-amber-100 text-amber-800 dark:bg-amber-950 dark:text-amber-200', + 'rose' => 'bg-rose-100 text-rose-800 dark:bg-rose-950 dark:text-rose-200', + 'slate' => 'bg-slate-100 text-slate-700 dark:bg-slate-800 dark:text-slate-200', +]; +@endphp + +merge(['class' => 'inline-flex items-center rounded-full px-2.5 py-1 text-xs font-semibold '.$tones[$tone]]) }}> + {{ $slot }} + diff --git a/resources/views/components/danger-button.blade.php b/resources/views/components/danger-button.blade.php index d17d288..4862684 100644 --- a/resources/views/components/danger-button.blade.php +++ b/resources/views/components/danger-button.blade.php @@ -1,3 +1,3 @@ - diff --git a/resources/views/components/dropdown-link.blade.php b/resources/views/components/dropdown-link.blade.php index e0f8ce1..0147554 100644 --- a/resources/views/components/dropdown-link.blade.php +++ b/resources/views/components/dropdown-link.blade.php @@ -1 +1 @@ -merge(['class' => 'block w-full px-4 py-2 text-start text-sm leading-5 text-gray-700 hover:bg-gray-100 focus:outline-none focus:bg-gray-100 transition duration-150 ease-in-out']) }}>{{ $slot }} +merge(['class' => 'block w-full px-4 py-2 text-start text-sm leading-5 text-slate-700 transition duration-150 ease-in-out hover:bg-slate-100 focus:bg-slate-100 focus:outline-none dark:text-slate-200 dark:hover:bg-slate-800 dark:focus:bg-slate-800']) }}>{{ $slot }} diff --git a/resources/views/components/dropdown.blade.php b/resources/views/components/dropdown.blade.php index a46f7c8..2fa4e09 100644 --- a/resources/views/components/dropdown.blade.php +++ b/resources/views/components/dropdown.blade.php @@ -1,4 +1,4 @@ -@props(['align' => 'right', 'width' => '48', 'contentClasses' => 'py-1 bg-white']) +@props(['align' => 'right', 'width' => '48', 'contentClasses' => 'py-1 bg-white dark:bg-slate-900']) @php $alignmentClasses = match ($align) { @@ -28,7 +28,7 @@ $width = match ($width) { class="absolute z-50 mt-2 {{ $width }} rounded-md shadow-lg {{ $alignmentClasses }}" style="display: none;" @click="open = false"> -
+
{{ $content }}
diff --git a/resources/views/components/field.blade.php b/resources/views/components/field.blade.php index 7f3d713..8af455d 100644 --- a/resources/views/components/field.blade.php +++ b/resources/views/components/field.blade.php @@ -1,11 +1,14 @@ -@props(['name', 'label', 'value' => '', 'textarea' => false, 'type' => 'text']) +@props(['name', 'label', 'value' => '', 'textarea' => false, 'type' => 'text', 'help' => null])
- + @if ($textarea) - + @else - + + @endif + @if ($help) +

{{ $help }}

@endif @error($name)

{{ $message }}

diff --git a/resources/views/components/input-error.blade.php b/resources/views/components/input-error.blade.php index 9e6da21..adb6563 100644 --- a/resources/views/components/input-error.blade.php +++ b/resources/views/components/input-error.blade.php @@ -1,7 +1,7 @@ @props(['messages']) @if ($messages) -
    merge(['class' => 'text-sm text-red-600 space-y-1']) }}> +
      merge(['class' => 'space-y-1 text-sm text-red-600 dark:text-red-400']) }}> @foreach ((array) $messages as $message)
    • {{ $message }}
    • @endforeach diff --git a/resources/views/components/input-label.blade.php b/resources/views/components/input-label.blade.php index 1cc65e2..f800236 100644 --- a/resources/views/components/input-label.blade.php +++ b/resources/views/components/input-label.blade.php @@ -1,5 +1,5 @@ @props(['value']) -