Phase 1 UI system
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,14 +27,14 @@
|
||||
<!-- Remember Me -->
|
||||
<div class="block mt-4">
|
||||
<label for="remember_me" class="inline-flex items-center">
|
||||
<input id="remember_me" type="checkbox" class="rounded border-gray-300 text-indigo-600 shadow-sm focus:ring-indigo-500" name="remember">
|
||||
<span class="ms-2 text-sm text-gray-600">{{ __('Remember me') }}</span>
|
||||
<input id="remember_me" type="checkbox" class="rounded border-slate-300 text-sky-600 shadow-sm focus:ring-sky-500 dark:border-slate-700 dark:bg-slate-950" name="remember">
|
||||
<span class="ms-2 text-sm text-slate-600 dark:text-slate-400">{{ __('Remember me') }}</span>
|
||||
</label>
|
||||
</div>
|
||||
|
||||
<div class="flex items-center justify-end mt-4">
|
||||
@if (Route::has('password.request'))
|
||||
<a class="underline text-sm text-gray-600 hover:text-gray-900 rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" href="{{ route('password.request') }}">
|
||||
<a class="rounded-md text-sm text-slate-600 underline hover:text-slate-950 focus:outline-none focus:ring-2 focus:ring-sky-500 focus:ring-offset-2 dark:text-slate-400 dark:hover:text-white dark:focus:ring-offset-slate-900" href="{{ route('password.request') }}">
|
||||
{{ __('Forgot your password?') }}
|
||||
</a>
|
||||
@endif
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
|
||||
<div class="mt-4">
|
||||
<x-input-label for="account_type" :value="__('Account type')" />
|
||||
<select id="account_type" name="account_type" required class="block mt-1 w-full border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 rounded-md shadow-sm">
|
||||
<select id="account_type" name="account_type" required class="mt-1 block w-full rounded-md border-slate-300 bg-white text-slate-950 shadow-sm focus:border-sky-500 focus:ring-sky-500 dark:border-slate-700 dark:bg-slate-950 dark:text-slate-100">
|
||||
<option value="provider" @selected(old('account_type') === 'provider')>Provider</option>
|
||||
<option value="buyer" @selected(old('account_type') === 'buyer')>Buyer</option>
|
||||
<option value="both" @selected(old('account_type') === 'both')>Provider and buyer</option>
|
||||
@@ -50,7 +50,7 @@
|
||||
</div>
|
||||
|
||||
<div class="flex items-center justify-end mt-4">
|
||||
<a class="underline text-sm text-gray-600 hover:text-gray-900 rounded-md focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" href="{{ route('login') }}">
|
||||
<a class="rounded-md text-sm text-slate-600 underline hover:text-slate-950 focus:outline-none focus:ring-2 focus:ring-sky-500 focus:ring-offset-2 dark:text-slate-400 dark:hover:text-white dark:focus:ring-offset-slate-900" href="{{ route('login') }}">
|
||||
{{ __('Already registered?') }}
|
||||
</a>
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
@props(['title', 'description', 'href' => null, 'label' => 'Open'])
|
||||
|
||||
<div class="tse-panel flex h-full flex-col p-5">
|
||||
<h3 class="text-base font-semibold text-slate-950 dark:text-white">{{ $title }}</h3>
|
||||
<p class="mt-2 flex-1 text-sm leading-6 text-slate-600 dark:text-slate-400">{{ $description }}</p>
|
||||
@if ($href)
|
||||
<a href="{{ $href }}" class="mt-4 inline-flex items-center text-sm font-semibold text-sky-700 hover:text-sky-900 dark:text-sky-300 dark:hover:text-sky-200">
|
||||
{{ $label }}
|
||||
<span aria-hidden="true" class="ms-1">-></span>
|
||||
</a>
|
||||
@endif
|
||||
</div>
|
||||
@@ -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
|
||||
|
||||
<span {{ $attributes->merge(['class' => 'inline-flex items-center rounded-full px-2.5 py-1 text-xs font-semibold '.$tones[$tone]]) }}>
|
||||
{{ $slot }}
|
||||
</span>
|
||||
@@ -1,3 +1,3 @@
|
||||
<button {{ $attributes->merge(['type' => 'submit', 'class' => 'inline-flex items-center px-4 py-2 bg-red-600 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-red-500 active:bg-red-700 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 transition ease-in-out duration-150']) }}>
|
||||
<button {{ $attributes->merge(['type' => 'submit', 'class' => 'inline-flex items-center rounded-md border border-transparent bg-red-600 px-4 py-2 text-xs font-semibold uppercase tracking-widest text-white transition duration-150 ease-in-out hover:bg-red-500 focus:outline-none focus:ring-2 focus:ring-red-500 focus:ring-offset-2 active:bg-red-700 dark:focus:ring-offset-slate-900']) }}>
|
||||
{{ $slot }}
|
||||
</button>
|
||||
|
||||
@@ -1 +1 @@
|
||||
<a {{ $attributes->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 }}</a>
|
||||
<a {{ $attributes->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 }}</a>
|
||||
|
||||
@@ -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">
|
||||
<div class="rounded-md ring-1 ring-black ring-opacity-5 {{ $contentClasses }}">
|
||||
<div class="rounded-md ring-1 ring-black ring-opacity-5 dark:ring-white/10 {{ $contentClasses }}">
|
||||
{{ $content }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,11 +1,14 @@
|
||||
@props(['name', 'label', 'value' => '', 'textarea' => false, 'type' => 'text'])
|
||||
@props(['name', 'label', 'value' => '', 'textarea' => false, 'type' => 'text', 'help' => null])
|
||||
|
||||
<div>
|
||||
<label for="{{ $name }}" class="block text-sm font-medium text-gray-700">{{ $label }}</label>
|
||||
<label for="{{ $name }}" class="block text-sm font-medium text-slate-800 dark:text-slate-200">{{ $label }}</label>
|
||||
@if ($textarea)
|
||||
<textarea id="{{ $name }}" name="{{ $name }}" rows="4" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500">{{ old($name, $value) }}</textarea>
|
||||
<textarea id="{{ $name }}" name="{{ $name }}" rows="4" class="mt-1 block w-full rounded-md border-slate-300 bg-white text-slate-950 shadow-sm focus:border-sky-500 focus:ring-sky-500 dark:border-slate-700 dark:bg-slate-950 dark:text-slate-100">{{ old($name, $value) }}</textarea>
|
||||
@else
|
||||
<input id="{{ $name }}" type="{{ $type }}" name="{{ $name }}" value="{{ old($name, $value) }}" class="mt-1 block w-full rounded-md border-gray-300 shadow-sm focus:border-indigo-500 focus:ring-indigo-500">
|
||||
<input id="{{ $name }}" type="{{ $type }}" name="{{ $name }}" value="{{ old($name, $value) }}" class="mt-1 block w-full rounded-md border-slate-300 bg-white text-slate-950 shadow-sm focus:border-sky-500 focus:ring-sky-500 dark:border-slate-700 dark:bg-slate-950 dark:text-slate-100">
|
||||
@endif
|
||||
@if ($help)
|
||||
<p class="mt-1 text-sm text-slate-500 dark:text-slate-400">{{ $help }}</p>
|
||||
@endif
|
||||
@error($name)
|
||||
<p class="mt-1 text-sm text-red-600">{{ $message }}</p>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
@props(['messages'])
|
||||
|
||||
@if ($messages)
|
||||
<ul {{ $attributes->merge(['class' => 'text-sm text-red-600 space-y-1']) }}>
|
||||
<ul {{ $attributes->merge(['class' => 'space-y-1 text-sm text-red-600 dark:text-red-400']) }}>
|
||||
@foreach ((array) $messages as $message)
|
||||
<li>{{ $message }}</li>
|
||||
@endforeach
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
@props(['value'])
|
||||
|
||||
<label {{ $attributes->merge(['class' => 'block font-medium text-sm text-gray-700']) }}>
|
||||
<label {{ $attributes->merge(['class' => 'block text-sm font-medium text-slate-800 dark:text-slate-200']) }}>
|
||||
{{ $value ?? $slot }}
|
||||
</label>
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
@php
|
||||
$classes = ($active ?? false)
|
||||
? 'inline-flex items-center px-1 pt-1 border-b-2 border-indigo-400 text-sm font-medium leading-5 text-gray-900 focus:outline-none focus:border-indigo-700 transition duration-150 ease-in-out'
|
||||
: 'inline-flex items-center px-1 pt-1 border-b-2 border-transparent text-sm font-medium leading-5 text-gray-500 hover:text-gray-700 hover:border-gray-300 focus:outline-none focus:text-gray-700 focus:border-gray-300 transition duration-150 ease-in-out';
|
||||
? 'inline-flex items-center px-1 pt-1 border-b-2 border-sky-500 text-sm font-medium leading-5 text-slate-950 focus:outline-none focus:border-sky-700 transition duration-150 ease-in-out dark:text-white'
|
||||
: 'inline-flex items-center px-1 pt-1 border-b-2 border-transparent text-sm font-medium leading-5 text-slate-500 hover:text-slate-800 hover:border-slate-300 focus:outline-none focus:text-slate-800 focus:border-slate-300 transition duration-150 ease-in-out dark:text-slate-400 dark:hover:text-slate-100 dark:hover:border-slate-600 dark:focus:text-slate-100 dark:focus:border-slate-600';
|
||||
@endphp
|
||||
|
||||
<a {{ $attributes->merge(['class' => $classes]) }}>
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
@props(['eyebrow' => null, 'title', 'description' => null])
|
||||
|
||||
<div class="flex flex-col gap-2 sm:flex-row sm:items-end sm:justify-between">
|
||||
<div>
|
||||
@if ($eyebrow)
|
||||
<p class="text-sm font-semibold uppercase tracking-wide text-sky-700 dark:text-sky-300">{{ $eyebrow }}</p>
|
||||
@endif
|
||||
<h1 class="text-2xl font-semibold tracking-tight text-slate-950 dark:text-white">{{ $title }}</h1>
|
||||
@if ($description)
|
||||
<p class="mt-2 max-w-3xl text-sm leading-6 text-slate-600 dark:text-slate-400">{{ $description }}</p>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@if (trim($slot) !== '')
|
||||
<div class="flex flex-wrap items-center gap-2">
|
||||
{{ $slot }}
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
@@ -1,3 +1,3 @@
|
||||
<button {{ $attributes->merge(['type' => 'submit', 'class' => 'inline-flex items-center px-4 py-2 bg-gray-800 border border-transparent rounded-md font-semibold text-xs text-white uppercase tracking-widest hover:bg-gray-700 focus:bg-gray-700 active:bg-gray-900 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 transition ease-in-out duration-150']) }}>
|
||||
<button {{ $attributes->merge(['type' => 'submit', 'class' => 'inline-flex items-center rounded-md border border-transparent bg-sky-600 px-4 py-2 text-xs font-semibold uppercase tracking-widest text-white transition duration-150 ease-in-out hover:bg-sky-700 focus:bg-sky-700 focus:outline-none focus:ring-2 focus:ring-sky-500 focus:ring-offset-2 active:bg-sky-800 dark:focus:ring-offset-slate-900']) }}>
|
||||
{{ $slot }}
|
||||
</button>
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
|
||||
@php
|
||||
$classes = ($active ?? false)
|
||||
? 'block w-full ps-3 pe-4 py-2 border-l-4 border-indigo-400 text-start text-base font-medium text-indigo-700 bg-indigo-50 focus:outline-none focus:text-indigo-800 focus:bg-indigo-100 focus:border-indigo-700 transition duration-150 ease-in-out'
|
||||
: 'block w-full ps-3 pe-4 py-2 border-l-4 border-transparent text-start text-base font-medium text-gray-600 hover:text-gray-800 hover:bg-gray-50 hover:border-gray-300 focus:outline-none focus:text-gray-800 focus:bg-gray-50 focus:border-gray-300 transition duration-150 ease-in-out';
|
||||
? 'block w-full ps-3 pe-4 py-2 border-l-4 border-sky-500 text-start text-base font-medium text-sky-800 bg-sky-50 focus:outline-none focus:text-sky-900 focus:bg-sky-100 focus:border-sky-700 transition duration-150 ease-in-out dark:bg-sky-950/40 dark:text-sky-200'
|
||||
: 'block w-full ps-3 pe-4 py-2 border-l-4 border-transparent text-start text-base font-medium text-slate-600 hover:text-slate-900 hover:bg-slate-50 hover:border-slate-300 focus:outline-none focus:text-slate-900 focus:bg-slate-50 focus:border-slate-300 transition duration-150 ease-in-out dark:text-slate-300 dark:hover:text-white dark:hover:bg-slate-800 dark:hover:border-slate-600 dark:focus:text-white dark:focus:bg-slate-800 dark:focus:border-slate-600';
|
||||
@endphp
|
||||
|
||||
<a {{ $attributes->merge(['class' => $classes]) }}>
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
<button {{ $attributes->merge(['type' => 'button', 'class' => 'inline-flex items-center px-4 py-2 bg-white border border-gray-300 rounded-md font-semibold text-xs text-gray-700 uppercase tracking-widest shadow-sm hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 disabled:opacity-25 transition ease-in-out duration-150']) }}>
|
||||
<button {{ $attributes->merge(['type' => 'button', 'class' => 'inline-flex items-center rounded-md border border-slate-300 bg-white px-4 py-2 text-xs font-semibold uppercase tracking-widest text-slate-700 shadow-sm transition duration-150 ease-in-out hover:bg-slate-50 focus:outline-none focus:ring-2 focus:ring-sky-500 focus:ring-offset-2 disabled:opacity-25 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-200 dark:hover:bg-slate-800 dark:focus:ring-offset-slate-900']) }}>
|
||||
{{ $slot }}
|
||||
</button>
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
@props(['label', 'value', 'description' => null])
|
||||
|
||||
<div class="tse-panel p-5">
|
||||
<p class="text-sm font-medium text-slate-500 dark:text-slate-400">{{ $label }}</p>
|
||||
<p class="mt-2 text-3xl font-semibold tracking-tight text-slate-950 dark:text-white">{{ $value }}</p>
|
||||
@if ($description)
|
||||
<p class="mt-2 text-sm text-slate-600 dark:text-slate-400">{{ $description }}</p>
|
||||
@endif
|
||||
</div>
|
||||
@@ -1,3 +1,3 @@
|
||||
@props(['disabled' => false])
|
||||
|
||||
<input @disabled($disabled) {{ $attributes->merge(['class' => 'border-gray-300 focus:border-indigo-500 focus:ring-indigo-500 rounded-md shadow-sm']) }}>
|
||||
<input @disabled($disabled) {{ $attributes->merge(['class' => 'rounded-md border-slate-300 bg-white text-slate-950 shadow-sm focus:border-sky-500 focus:ring-sky-500 dark:border-slate-700 dark:bg-slate-950 dark:text-slate-100']) }}>
|
||||
|
||||
@@ -0,0 +1,21 @@
|
||||
<button
|
||||
type="button"
|
||||
x-data="{
|
||||
dark: document.documentElement.classList.contains('dark'),
|
||||
toggle() {
|
||||
this.dark = ! this.dark;
|
||||
document.documentElement.classList.toggle('dark', this.dark);
|
||||
localStorage.setItem('tse-theme', this.dark ? 'dark' : 'light');
|
||||
}
|
||||
}"
|
||||
x-on:click="toggle()"
|
||||
class="inline-flex h-9 w-9 items-center justify-center rounded-md border border-slate-200 bg-white text-slate-600 shadow-sm transition hover:border-slate-300 hover:text-slate-950 focus:outline-none focus:ring-2 focus:ring-sky-500 focus:ring-offset-2 dark:border-slate-700 dark:bg-slate-900 dark:text-slate-300 dark:hover:border-slate-600 dark:hover:text-white dark:focus:ring-offset-slate-900"
|
||||
aria-label="Toggle color theme"
|
||||
>
|
||||
<svg x-show="!dark" class="h-4 w-4" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||
<path d="M10 2a1 1 0 0 1 1 1v1a1 1 0 1 1-2 0V3a1 1 0 0 1 1-1Zm0 12a4 4 0 1 0 0-8 4 4 0 0 0 0 8Zm7-5a1 1 0 1 1 0 2h-1a1 1 0 1 1 0-2h1ZM5 10a1 1 0 0 1-1 1H3a1 1 0 1 1 0-2h1a1 1 0 0 1 1 1Zm10.657-5.657a1 1 0 0 1 0 1.414l-.707.707a1 1 0 1 1-1.414-1.414l.707-.707a1 1 0 0 1 1.414 0ZM6.464 13.536a1 1 0 0 1 0 1.414l-.707.707a1 1 0 0 1-1.414-1.414l.707-.707a1 1 0 0 1 1.414 0Zm9.193 2.121a1 1 0 0 1-1.414 0l-.707-.707a1 1 0 0 1 1.414-1.414l.707.707a1 1 0 0 1 0 1.414ZM6.464 6.464A1 1 0 0 1 5.05 6.464l-.707-.707a1 1 0 0 1 1.414-1.414l.707.707a1 1 0 0 1 0 1.414ZM10 15a1 1 0 0 1 1 1v1a1 1 0 1 1-2 0v-1a1 1 0 0 1 1-1Z"/>
|
||||
</svg>
|
||||
<svg x-show="dark" x-cloak class="h-4 w-4" viewBox="0 0 20 20" fill="currentColor" aria-hidden="true">
|
||||
<path fill-rule="evenodd" d="M7.455 2.004a.75.75 0 0 1 .79.927 7.5 7.5 0 0 0 8.824 8.824.75.75 0 0 1 .927.79A8.5 8.5 0 1 1 7.455 2.004Z" clip-rule="evenodd"/>
|
||||
</svg>
|
||||
</button>
|
||||
@@ -1,52 +1,60 @@
|
||||
<x-app-layout>
|
||||
<x-slot name="header">
|
||||
<h2 class="font-semibold text-xl text-gray-800 leading-tight">
|
||||
{{ __('Dashboard') }}
|
||||
</h2>
|
||||
<x-page-header
|
||||
title="Dashboard"
|
||||
description="A quick operating view for profiles, jobs, work orders, and reputation activity."
|
||||
>
|
||||
<a href="{{ route('jobs.create') }}" class="rounded-md bg-sky-600 px-4 py-2 text-sm font-semibold text-white shadow-sm hover:bg-sky-700">Post job</a>
|
||||
</x-page-header>
|
||||
</x-slot>
|
||||
|
||||
<div class="py-12">
|
||||
<div class="max-w-7xl mx-auto sm:px-6 lg:px-8">
|
||||
<div class="bg-white overflow-hidden shadow-sm sm:rounded-lg">
|
||||
<div class="p-6 text-gray-900 space-y-4">
|
||||
<div>
|
||||
<p class="text-sm text-gray-500">Signed in as</p>
|
||||
<p class="font-semibold">{{ auth()->user()->name }}</p>
|
||||
<div class="py-8">
|
||||
<div class="mx-auto max-w-7xl space-y-6 px-4 sm:px-6 lg:px-8">
|
||||
<section class="grid gap-4 sm:grid-cols-2 lg:grid-cols-5">
|
||||
<x-stat-card label="Providers" :value="$counts['providers']" description="Service profiles" />
|
||||
<x-stat-card label="Buyers" :value="$counts['buyers']" description="Company profiles" />
|
||||
<x-stat-card label="Jobs" :value="$counts['jobs']" description="Open and historical posts" />
|
||||
<x-stat-card label="Work orders" :value="$counts['workOrders']" description="Accepted quote records" />
|
||||
<x-stat-card label="Disputes" :value="$counts['disputes']" description="Peer review cases" />
|
||||
</section>
|
||||
|
||||
<section class="grid gap-4 lg:grid-cols-[.8fr_1.2fr]">
|
||||
<div class="tse-panel p-5">
|
||||
<h2 class="text-base font-semibold text-slate-950 dark:text-white">Signed in</h2>
|
||||
<div class="mt-4">
|
||||
<p class="text-sm text-slate-500 dark:text-slate-400">Account</p>
|
||||
<p class="font-semibold text-slate-950 dark:text-white">{{ auth()->user()->name }}</p>
|
||||
<p class="text-sm text-slate-600 dark:text-slate-400">{{ auth()->user()->email }}</p>
|
||||
</div>
|
||||
|
||||
<div>
|
||||
<p class="text-sm text-gray-500">Roles</p>
|
||||
<div class="mt-5">
|
||||
<p class="text-sm text-slate-500 dark:text-slate-400">Roles</p>
|
||||
<div class="mt-2 flex flex-wrap gap-2">
|
||||
@foreach (auth()->user()->roles->pluck('name') as $role)
|
||||
<span class="rounded bg-gray-100 px-3 py-1 text-sm">{{ $role }}</span>
|
||||
<x-badge tone="slate">{{ $role }}</x-badge>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid gap-4 md:grid-cols-3">
|
||||
@role('provider')
|
||||
<div class="rounded border border-gray-200 p-4">
|
||||
<h3 class="font-semibold">Provider workspace</h3>
|
||||
<p class="mt-2 text-sm text-gray-600">Profile, service areas, rate cards, and work requests will land here.</p>
|
||||
</div>
|
||||
@endrole
|
||||
|
||||
@role('buyer')
|
||||
<div class="rounded border border-gray-200 p-4">
|
||||
<h3 class="font-semibold">Buyer workspace</h3>
|
||||
<p class="mt-2 text-sm text-gray-600">Company profile, job posts, quotes, and assignments will land here.</p>
|
||||
</div>
|
||||
@endrole
|
||||
|
||||
@role('admin')
|
||||
<div class="rounded border border-gray-200 p-4">
|
||||
<h3 class="font-semibold">Admin workspace</h3>
|
||||
<p class="mt-2 text-sm text-gray-600">Moderation, role review, and platform controls will land here.</p>
|
||||
</div>
|
||||
@endrole
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="grid gap-4 md:grid-cols-3">
|
||||
@role('provider')
|
||||
<x-action-card title="Provider workspace" description="Update services, coverage, equipment, rate cards, and imported profile history." :href="route('providers.edit')" label="Edit profile" />
|
||||
@endrole
|
||||
|
||||
@role('buyer')
|
||||
<x-action-card title="Buyer workspace" description="Maintain company details, create jobs, review quotes, and manage accepted work." :href="route('buyers.edit')" label="Edit profile" />
|
||||
@endrole
|
||||
|
||||
@role('admin')
|
||||
<x-action-card title="Admin workspace" description="Review users, moderation surfaces, ratings, disputes, and platform operating signals." :href="route('admin.index')" label="Open admin" />
|
||||
@endrole
|
||||
|
||||
<x-action-card title="Notifications" description="Review unread platform events for quotes, work orders, reviews, disputes, and profile activity." :href="route('notifications.index')" label="Open inbox" />
|
||||
<x-action-card title="Directory" description="Search providers and buyers without enforcing platform-set rates or preferred pricing." :href="route('providers.index')" label="Browse" />
|
||||
<x-action-card title="Jobs" description="Review posted opportunities, quote history, and accepted work-order paths." :href="route('jobs.index')" label="View jobs" />
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
</div>
|
||||
</x-app-layout>
|
||||
|
||||
@@ -12,15 +12,24 @@
|
||||
<link href="https://fonts.bunny.net/css?family=figtree:400,500,600&display=swap" rel="stylesheet" />
|
||||
|
||||
<!-- Scripts -->
|
||||
<script>
|
||||
(function () {
|
||||
const stored = localStorage.getItem('tse-theme');
|
||||
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
if (stored === 'dark' || (!stored && prefersDark)) {
|
||||
document.documentElement.classList.add('dark');
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
||||
</head>
|
||||
<body class="font-sans antialiased">
|
||||
<div class="min-h-screen bg-gray-100">
|
||||
<body class="font-sans">
|
||||
<div class="min-h-screen bg-slate-100 dark:bg-slate-950">
|
||||
@include('layouts.navigation')
|
||||
|
||||
<!-- Page Heading -->
|
||||
@isset($header)
|
||||
<header class="bg-white shadow">
|
||||
<header class="border-b border-slate-200 bg-white/90 shadow-sm dark:border-slate-800 dark:bg-slate-900/90">
|
||||
<div class="max-w-7xl mx-auto py-6 px-4 sm:px-6 lg:px-8">
|
||||
{{ $header }}
|
||||
</div>
|
||||
|
||||
@@ -12,17 +12,28 @@
|
||||
<link href="https://fonts.bunny.net/css?family=figtree:400,500,600&display=swap" rel="stylesheet" />
|
||||
|
||||
<!-- Scripts -->
|
||||
<script>
|
||||
(function () {
|
||||
const stored = localStorage.getItem('tse-theme');
|
||||
const prefersDark = window.matchMedia('(prefers-color-scheme: dark)').matches;
|
||||
if (stored === 'dark' || (!stored && prefersDark)) {
|
||||
document.documentElement.classList.add('dark');
|
||||
}
|
||||
})();
|
||||
</script>
|
||||
@vite(['resources/css/app.css', 'resources/js/app.js'])
|
||||
</head>
|
||||
<body class="font-sans text-gray-900 antialiased">
|
||||
<div class="min-h-screen flex flex-col sm:justify-center items-center pt-6 sm:pt-0 bg-gray-100">
|
||||
<div>
|
||||
<a href="/">
|
||||
<x-application-logo class="w-20 h-20 fill-current text-gray-500" />
|
||||
<body class="font-sans">
|
||||
<div class="min-h-screen flex flex-col sm:justify-center items-center px-4 pt-6 sm:pt-0 bg-slate-100 dark:bg-slate-950">
|
||||
<div class="flex items-center gap-3">
|
||||
<a href="{{ url('/') }}" class="flex items-center gap-3 text-slate-950 dark:text-white">
|
||||
<x-application-logo class="h-10 w-10 fill-current text-sky-600 dark:text-sky-400" />
|
||||
<span class="text-lg font-semibold">Provider Exchange</span>
|
||||
</a>
|
||||
<x-theme-toggle />
|
||||
</div>
|
||||
|
||||
<div class="w-full sm:max-w-md mt-6 px-6 py-4 bg-white shadow-md overflow-hidden sm:rounded-lg">
|
||||
<div class="w-full sm:max-w-md mt-6 overflow-hidden rounded-lg border border-slate-200 bg-white px-6 py-5 shadow-sm dark:border-slate-800 dark:bg-slate-900">
|
||||
{{ $slot }}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,12 +1,13 @@
|
||||
<nav x-data="{ open: false }" class="bg-white border-b border-gray-100">
|
||||
<nav x-data="{ open: false }" class="border-b border-slate-200 bg-white/95 dark:border-slate-800 dark:bg-slate-900/95">
|
||||
<!-- Primary Navigation Menu -->
|
||||
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
|
||||
<div class="flex justify-between h-16">
|
||||
<div class="flex">
|
||||
<!-- Logo -->
|
||||
<div class="shrink-0 flex items-center">
|
||||
<a href="{{ route('dashboard') }}">
|
||||
<x-application-logo class="block h-9 w-auto fill-current text-gray-800" />
|
||||
<a href="{{ route('dashboard') }}" class="flex items-center gap-2 text-slate-950 dark:text-white">
|
||||
<x-application-logo class="block h-9 w-auto fill-current text-sky-600 dark:text-sky-400" />
|
||||
<span class="hidden text-sm font-semibold tracking-wide md:inline">Provider Exchange</span>
|
||||
</a>
|
||||
</div>
|
||||
|
||||
@@ -47,11 +48,12 @@
|
||||
</div>
|
||||
|
||||
<!-- Settings Dropdown -->
|
||||
<div class="hidden sm:flex sm:items-center sm:ms-6">
|
||||
<div class="hidden sm:flex sm:items-center sm:ms-6 sm:gap-3">
|
||||
<x-theme-toggle />
|
||||
@auth
|
||||
<x-dropdown align="right" width="48">
|
||||
<x-slot name="trigger">
|
||||
<button class="inline-flex items-center px-3 py-2 border border-transparent text-sm leading-4 font-medium rounded-md text-gray-500 bg-white hover:text-gray-700 focus:outline-none transition ease-in-out duration-150">
|
||||
<button class="inline-flex items-center rounded-md border border-transparent bg-white px-3 py-2 text-sm font-medium leading-4 text-slate-600 transition duration-150 ease-in-out hover:text-slate-900 focus:outline-none dark:bg-slate-900 dark:text-slate-300 dark:hover:text-white">
|
||||
<div>{{ Auth::user()->name }}</div>
|
||||
|
||||
<div class="ms-1">
|
||||
@@ -91,15 +93,16 @@
|
||||
</x-dropdown>
|
||||
@else
|
||||
<div class="flex gap-4 text-sm">
|
||||
<a href="{{ route('login') }}" class="text-gray-600 hover:text-gray-900">Log in</a>
|
||||
<a href="{{ route('register') }}" class="text-gray-600 hover:text-gray-900">Register</a>
|
||||
<a href="{{ route('login') }}" class="text-slate-600 hover:text-slate-950 dark:text-slate-300 dark:hover:text-white">Log in</a>
|
||||
<a href="{{ route('register') }}" class="text-slate-600 hover:text-slate-950 dark:text-slate-300 dark:hover:text-white">Register</a>
|
||||
</div>
|
||||
@endauth
|
||||
</div>
|
||||
|
||||
<!-- Hamburger -->
|
||||
<div class="-me-2 flex items-center sm:hidden">
|
||||
<button @click="open = ! open" class="inline-flex items-center justify-center p-2 rounded-md text-gray-400 hover:text-gray-500 hover:bg-gray-100 focus:outline-none focus:bg-gray-100 focus:text-gray-500 transition duration-150 ease-in-out">
|
||||
<x-theme-toggle />
|
||||
<button @click="open = ! open" class="ms-2 inline-flex items-center justify-center rounded-md p-2 text-slate-500 transition duration-150 ease-in-out hover:bg-slate-100 hover:text-slate-700 focus:bg-slate-100 focus:text-slate-700 focus:outline-none dark:text-slate-300 dark:hover:bg-slate-800 dark:hover:text-white dark:focus:bg-slate-800 dark:focus:text-white">
|
||||
<svg class="h-6 w-6" stroke="currentColor" fill="none" viewBox="0 0 24 24">
|
||||
<path :class="{'hidden': open, 'inline-flex': ! open }" class="inline-flex" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M4 6h16M4 12h16M4 18h16" />
|
||||
<path :class="{'hidden': ! open, 'inline-flex': open }" class="hidden" stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M6 18L18 6M6 6l12 12" />
|
||||
@@ -145,11 +148,11 @@
|
||||
</div>
|
||||
|
||||
<!-- Responsive Settings Options -->
|
||||
<div class="pt-4 pb-1 border-t border-gray-200">
|
||||
<div class="pt-4 pb-1 border-t border-slate-200 dark:border-slate-800">
|
||||
@auth
|
||||
<div class="px-4">
|
||||
<div class="font-medium text-base text-gray-800">{{ Auth::user()->name }}</div>
|
||||
<div class="font-medium text-sm text-gray-500">{{ Auth::user()->email }}</div>
|
||||
<div class="font-medium text-base text-slate-900 dark:text-white">{{ Auth::user()->name }}</div>
|
||||
<div class="font-medium text-sm text-slate-500 dark:text-slate-400">{{ Auth::user()->email }}</div>
|
||||
</div>
|
||||
@endauth
|
||||
|
||||
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user