Phase 8 and 9 marketplace matching
This commit is contained in:
@@ -6,6 +6,41 @@
|
||||
<section class="grid gap-4 md:grid-cols-2">
|
||||
<x-field name="title" label="Title" />
|
||||
<x-field name="service_category" label="Service category" />
|
||||
<div>
|
||||
<label for="work_category_id" class="block text-sm font-medium text-slate-800 dark:text-slate-200">Work category</label>
|
||||
<select id="work_category_id" name="work_category_id" 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="">Choose category</option>
|
||||
@foreach ($categories as $category)
|
||||
<option value="{{ $category->id }}">{{ $category->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="work_specialty_id" class="block text-sm font-medium text-slate-800 dark:text-slate-200">Specialty</label>
|
||||
<select id="work_specialty_id" name="work_specialty_id" 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="">Choose specialty</option>
|
||||
@foreach ($specialties as $specialty)
|
||||
<option value="{{ $specialty->id }}">{{ $specialty->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="required_technician_level" class="block text-sm font-medium text-slate-800 dark:text-slate-200">Technician level requested</label>
|
||||
<select id="required_technician_level" name="required_technician_level" 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">
|
||||
@foreach ($technicianLevels as $level => $definition)
|
||||
<option value="{{ $level }}">{{ $definition['name'] }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<p class="mt-1 text-sm text-slate-500 dark:text-slate-400">The posted scope should match this level. Smart-hands work needs clear instructions and active support.</p>
|
||||
</div>
|
||||
<div>
|
||||
<label for="work_mode" class="block text-sm font-medium text-slate-800 dark:text-slate-200">Work mode</label>
|
||||
<select id="work_mode" name="work_mode" 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="onsite">Onsite</option>
|
||||
<option value="remote">Remote</option>
|
||||
<option value="hybrid">Hybrid</option>
|
||||
</select>
|
||||
</div>
|
||||
<x-field name="location" label="Location" />
|
||||
<x-field name="starts_at" label="Start date/time" type="datetime-local" />
|
||||
<x-field name="time_window" label="Time window" />
|
||||
@@ -21,6 +56,16 @@
|
||||
<input type="checkbox" name="remote_eligible" value="1" class="rounded border-slate-300 text-sky-600 shadow-sm focus:ring-sky-500 dark:border-slate-700 dark:bg-slate-950">
|
||||
Remote eligible
|
||||
</label>
|
||||
<div>
|
||||
<label for="pay_type" class="block text-sm font-medium text-slate-800 dark:text-slate-200">Pay type</label>
|
||||
<select id="pay_type" name="pay_type" 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="not_listed">Not listed</option>
|
||||
<option value="fixed">Fixed</option>
|
||||
<option value="hourly">Hourly</option>
|
||||
<option value="blended">Blended</option>
|
||||
</select>
|
||||
</div>
|
||||
<x-field name="posted_terms_summary" label="Posted terms summary" />
|
||||
</section>
|
||||
|
||||
<section class="space-y-4">
|
||||
|
||||
@@ -1,40 +1,104 @@
|
||||
<x-app-layout>
|
||||
<x-slot name="header"><h2 class="text-xl font-semibold">Jobs</h2></x-slot>
|
||||
<div class="mx-auto max-w-7xl space-y-4 p-6">
|
||||
<form method="GET" action="{{ route('jobs.index') }}" class="grid gap-3 rounded border bg-white p-4 md:grid-cols-3">
|
||||
<input name="q" value="{{ request('q') }}" placeholder="Search jobs..." class="rounded-md border-gray-300">
|
||||
<select name="status" class="rounded-md border-gray-300">
|
||||
<option value="">Any status</option>
|
||||
@foreach (['open', 'assigned', 'closed', 'cancelled'] as $status)
|
||||
<option value="{{ $status }}" @selected(request('status') === $status)>{{ $status }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<x-primary-button>Search</x-primary-button>
|
||||
<form method="GET" action="{{ route('jobs.index') }}" class="rounded border bg-white p-4 dark:border-slate-800 dark:bg-slate-900">
|
||||
<div class="grid gap-3 lg:grid-cols-6">
|
||||
<input name="q" value="{{ request('q') }}" placeholder="Search jobs..." class="rounded-md border-gray-300 lg:col-span-2">
|
||||
<select name="work_category_id" class="rounded-md border-gray-300">
|
||||
<option value="">Any category</option>
|
||||
@foreach ($categories as $category)
|
||||
<option value="{{ $category->id }}" @selected((int) request('work_category_id') === $category->id)>{{ $category->name }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<select name="technician_level" class="rounded-md border-gray-300">
|
||||
<option value="">Any tech level</option>
|
||||
@foreach ($technicianLevels as $level => $definition)
|
||||
<option value="{{ $level }}" @selected((int) request('technician_level') === $level)>Up to {{ $definition['short_name'] }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<select name="scope_clarity" class="rounded-md border-gray-300">
|
||||
<option value="">Any clarity</option>
|
||||
@foreach (\App\Models\JobPost::SCOPE_CLARITY_STATUSES as $value => $label)
|
||||
<option value="{{ $value }}" @selected(request('scope_clarity') === $value)>{{ $label }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<select name="status" class="rounded-md border-gray-300">
|
||||
<option value="">Any status</option>
|
||||
@foreach (['open', 'assigned', 'closed', 'cancelled'] as $status)
|
||||
<option value="{{ $status }}" @selected(request('status') === $status)>{{ $status }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div class="mt-3 flex flex-wrap items-center gap-3">
|
||||
<label class="inline-flex items-center gap-2 text-sm text-slate-700 dark:text-slate-300">
|
||||
<input type="checkbox" name="support_certified" value="1" @checked(request()->boolean('support_certified')) class="rounded border-slate-300 text-sky-600">
|
||||
Support certified
|
||||
</label>
|
||||
<label class="inline-flex items-center gap-2 text-sm text-slate-700 dark:text-slate-300">
|
||||
<input type="checkbox" name="remote_only" value="1" @checked(request()->boolean('remote_only')) class="rounded border-slate-300 text-sky-600">
|
||||
Remote eligible
|
||||
</label>
|
||||
<label class="inline-flex items-center gap-2 text-sm text-slate-700 dark:text-slate-300">
|
||||
<input type="checkbox" name="hide_risky" value="1" @checked(request()->boolean('hide_risky')) class="rounded border-slate-300 text-sky-600">
|
||||
Hide risky jobs
|
||||
</label>
|
||||
<x-primary-button>Filter</x-primary-button>
|
||||
<a href="{{ route('jobs.index') }}" class="rounded-md border border-slate-300 bg-white px-4 py-2 text-sm font-semibold text-slate-700 shadow-sm hover:bg-slate-50">Reset</a>
|
||||
</div>
|
||||
</form>
|
||||
@auth @role('buyer')<a class="rounded bg-indigo-600 px-4 py-2 text-white" href="{{ route('jobs.create') }}">Post job</a>@endrole @endauth
|
||||
@foreach ($jobs as $job)
|
||||
<a href="{{ route('jobs.show', $job) }}" class="block rounded border bg-white p-4 shadow-sm">
|
||||
<div class="flex flex-col gap-2 sm:flex-row sm:items-start sm:justify-between">
|
||||
<div>
|
||||
<h3 class="font-semibold">{{ $job->title }}</h3>
|
||||
<p class="text-sm text-gray-600">{{ $job->location }} | {{ $job->service_category }} | {{ $job->status }}</p>
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<x-badge tone="{{ $job->scope_clarity_status === 'clear' ? 'emerald' : 'amber' }}">Scope {{ str_replace('_', ' ', $job->scope_clarity_status) }}</x-badge>
|
||||
<x-badge tone="{{ $job->contact_certified ? 'emerald' : 'rose' }}">{{ $job->contact_certified ? 'Support certified' : 'Support not certified' }}</x-badge>
|
||||
</div>
|
||||
</div>
|
||||
@if (is_array($job->risk_flags) && $job->risk_flags)
|
||||
<div class="mt-2 flex flex-wrap gap-2">
|
||||
@foreach ($job->risk_flags as $flag)
|
||||
<x-badge tone="amber">{{ str_replace('_', ' ', $flag) }}</x-badge>
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
<p class="mt-2 line-clamp-2 text-sm">{{ $job->scope }}</p>
|
||||
<x-rating-summary :ratings="$job->ratings" />
|
||||
</a>
|
||||
@endforeach
|
||||
<div class="overflow-hidden rounded border bg-white shadow-sm dark:border-slate-800 dark:bg-slate-900">
|
||||
<table class="min-w-full divide-y divide-slate-200 text-sm dark:divide-slate-800">
|
||||
<thead class="bg-slate-50 text-left text-xs uppercase tracking-wide text-slate-500 dark:bg-slate-950 dark:text-slate-400">
|
||||
<tr>
|
||||
<th class="px-4 py-3">Job</th>
|
||||
<th class="px-4 py-3">Category</th>
|
||||
<th class="px-4 py-3">Level</th>
|
||||
<th class="px-4 py-3">Schedule</th>
|
||||
<th class="px-4 py-3">Terms</th>
|
||||
<th class="px-4 py-3">Signals</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody class="divide-y divide-slate-100 dark:divide-slate-800">
|
||||
@forelse ($jobs as $job)
|
||||
<tr class="align-top">
|
||||
<td class="px-4 py-4">
|
||||
<a href="{{ route('jobs.show', $job) }}" class="font-semibold text-slate-950 hover:text-sky-700 dark:text-white">{{ $job->title }}</a>
|
||||
<p class="mt-1 text-xs text-slate-500">{{ $job->buyer->buyerProfile?->company_name ?? $job->buyer->name }} | {{ $job->location }}</p>
|
||||
<p class="mt-2 line-clamp-2 text-slate-600 dark:text-slate-400">{{ $job->primary_objective ?: $job->scope }}</p>
|
||||
</td>
|
||||
<td class="px-4 py-4">
|
||||
<p>{{ $job->workCategory?->name ?? $job->service_category ?? 'Uncategorized' }}</p>
|
||||
<p class="text-xs text-slate-500">{{ $job->workSpecialty?->name }}</p>
|
||||
</td>
|
||||
<td class="px-4 py-4">
|
||||
<x-badge tone="sky">{{ $job->technicianLevel()['short_name'] }}</x-badge>
|
||||
</td>
|
||||
<td class="px-4 py-4">
|
||||
<p>{{ $job->starts_at?->format('M j g:i A') ?? 'No start' }}</p>
|
||||
<p class="text-xs text-slate-500">{{ $job->time_window ?: 'No window' }} | {{ str_replace('_', ' ', $job->work_mode ?: 'onsite') }}</p>
|
||||
</td>
|
||||
<td class="px-4 py-4">
|
||||
<p>{{ str_replace('_', ' ', $job->pay_type ?: 'not listed') }}</p>
|
||||
<p class="text-xs text-slate-500">{{ $job->posted_terms_summary ?: $job->payment_terms }}</p>
|
||||
<p class="text-xs text-slate-500">{{ $job->quotes_count }} quote{{ $job->quotes_count === 1 ? '' : 's' }}</p>
|
||||
</td>
|
||||
<td class="px-4 py-4">
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<x-badge tone="{{ $job->scope_clarity_status === 'clear' ? 'emerald' : 'amber' }}">{{ str_replace('_', ' ', $job->scope_clarity_status) }}</x-badge>
|
||||
<x-badge tone="{{ $job->contact_certified ? 'emerald' : 'rose' }}">{{ $job->contact_certified ? 'Support certified' : 'No support cert' }}</x-badge>
|
||||
@foreach (array_slice(is_array($job->risk_flags) ? $job->risk_flags : [], 0, 3) as $flag)
|
||||
<x-badge tone="amber">{{ str_replace('_', ' ', $flag) }}</x-badge>
|
||||
@endforeach
|
||||
</div>
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr><td colspan="6" class="px-4 py-8 text-center text-slate-500">No jobs matched these filters.</td></tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
{{ $jobs->links() }}
|
||||
</div>
|
||||
</x-app-layout>
|
||||
|
||||
@@ -7,6 +7,10 @@
|
||||
<p class="text-sm text-gray-500">{{ $job->location }} | {{ $job->service_category }} | {{ $job->status }}</p>
|
||||
<div class="mt-3 flex flex-wrap gap-2">
|
||||
<x-badge tone="{{ $job->scope_clarity_status === 'clear' ? 'emerald' : 'amber' }}">Scope {{ str_replace('_', ' ', $job->scope_clarity_status) }}</x-badge>
|
||||
<x-badge tone="sky">{{ $job->technicianLevel()['name'] }}</x-badge>
|
||||
@if ($job->workCategory)
|
||||
<x-badge tone="slate">{{ $job->workCategory->name }}</x-badge>
|
||||
@endif
|
||||
@if ($job->contact_certified)
|
||||
<x-badge tone="emerald">Support certified</x-badge>
|
||||
@else
|
||||
@@ -20,6 +24,7 @@
|
||||
<div class="text-sm text-slate-600 dark:text-slate-400 sm:text-right">
|
||||
<p>{{ $job->starts_at?->format('M j, Y g:i A') ?? 'No start set' }}</p>
|
||||
<p>{{ $job->time_window ?: 'No window set' }} | {{ str_replace('_', ' ', $job->schedule_type ?: 'schedule not set') }}</p>
|
||||
<p>{{ str_replace('_', ' ', $job->work_mode ?: 'onsite') }} | {{ str_replace('_', ' ', $job->pay_type ?: 'pay not listed') }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -41,6 +46,8 @@
|
||||
|
||||
<dl class="mt-6 grid gap-4 md:grid-cols-2">
|
||||
<div><dt class="text-sm text-gray-500">Primary objective</dt><dd class="whitespace-pre-line">{{ $job->primary_objective ?: $job->scope }}</dd></div>
|
||||
<div><dt class="text-sm text-gray-500">Technician level</dt><dd class="whitespace-pre-line">{{ $job->technicianLevel()['description'] }}</dd></div>
|
||||
<div><dt class="text-sm text-gray-500">Level scope rule</dt><dd class="whitespace-pre-line">{{ $job->technicianLevel()['scope_rule'] }}</dd></div>
|
||||
<div><dt class="text-sm text-gray-500">Expected duration</dt><dd class="whitespace-pre-line">{{ $job->expected_duration ?: 'Not specified' }}</dd></div>
|
||||
<div><dt class="text-sm text-gray-500">Included work</dt><dd class="whitespace-pre-line">{{ $job->included_work ?: 'Not specified' }}</dd></div>
|
||||
<div><dt class="text-sm text-gray-500">Excluded work</dt><dd class="whitespace-pre-line">{{ $job->excluded_work ?: 'Not specified' }}</dd></div>
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
$certsText = collect($profile?->certification_records ?? [])->map(fn ($row) => trim(($row['name'] ?? '').' | '.($row['issuer'] ?? ''), ' |'))->implode("\n");
|
||||
$visibility = $profile?->profile_visibility ?? [];
|
||||
$visible = fn (string $field): bool => (bool) ($visibility[$field] ?? true);
|
||||
$selectedTaxonomy = $profile?->taxonomyTerms?->pluck('id')->all() ?? [];
|
||||
@endphp
|
||||
|
||||
<x-app-layout>
|
||||
@@ -22,7 +23,28 @@
|
||||
<x-field name="headline" label="Headline" :value="$profile?->headline" />
|
||||
<x-field name="bio" label="Bio" :value="$profile?->bio" textarea />
|
||||
<x-field name="service_area" label="Service area" :value="$profile?->service_area" />
|
||||
<div>
|
||||
<label for="max_technician_level" class="block text-sm font-medium text-slate-800 dark:text-slate-200">Maximum technician level</label>
|
||||
<select id="max_technician_level" name="max_technician_level" 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">
|
||||
@foreach ($technicianLevels as $level => $definition)
|
||||
<option value="{{ $level }}" @selected((int) ($profile?->max_technician_level ?? 1) === $level)>{{ $definition['name'] }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
<p class="mt-1 text-sm text-slate-500 dark:text-slate-400">This is self-declared until native work history, buyer endorsements, certifications, or admin verification support it.</p>
|
||||
</div>
|
||||
<x-field name="skills" label="Skills summary" :value="$profile?->skills" textarea />
|
||||
<div class="rounded-md border border-slate-200 p-4 dark:border-slate-800">
|
||||
<h3 class="font-semibold text-slate-950 dark:text-white">Self-declared tags and evidence</h3>
|
||||
<p class="mt-1 text-sm text-slate-600 dark:text-slate-400">Choose categories, specialties, skills, tools, and certifications that describe your work. Later passes can let buyers endorse or challenge these after completed work orders.</p>
|
||||
<div class="mt-3 grid gap-2 md:grid-cols-2">
|
||||
@foreach ($taxonomyTerms as $term)
|
||||
<label class="inline-flex items-center gap-2 rounded-md border border-slate-200 px-3 py-2 text-sm text-slate-700 dark:border-slate-800 dark:text-slate-300">
|
||||
<input type="checkbox" name="taxonomy_terms[]" value="{{ $term->id }}" @checked(in_array($term->id, $selectedTaxonomy, true)) class="rounded border-slate-300 text-sky-600 shadow-sm focus:ring-sky-500 dark:border-slate-700 dark:bg-slate-950">
|
||||
<span>{{ $term->name }} <span class="text-xs text-slate-500">({{ str_replace('_', ' ', $term->type) }})</span></span>
|
||||
</label>
|
||||
@endforeach
|
||||
</div>
|
||||
</div>
|
||||
<x-field name="services_text" label="Structured services" :value="$servicesText" textarea help="One per line. Use: service name | level, for example POS install | experienced." />
|
||||
<x-field name="tools" label="Tools and equipment summary" :value="$profile?->tools" textarea />
|
||||
<x-field name="tool_inventory_text" label="Tool inventory" :value="$toolsText" textarea help="One per line. Use: tool name | category, for example Cable tester | network." />
|
||||
|
||||
@@ -27,6 +27,24 @@
|
||||
<label for="skill" class="block text-sm font-medium text-slate-800 dark:text-slate-200">Skill</label>
|
||||
<input id="skill" name="skill" value="{{ $filters['skill'] ?? '' }}" placeholder="POS, network, cabling" 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">
|
||||
</div>
|
||||
<div>
|
||||
<label for="technician_level" class="block text-sm font-medium text-slate-800 dark:text-slate-200">Technician level</label>
|
||||
<select id="technician_level" name="technician_level" 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="">Any level</option>
|
||||
@foreach ($technicianLevels as $level => $definition)
|
||||
<option value="{{ $level }}" @selected((int) ($filters['technician_level'] ?? 0) === $level)>{{ $definition['name'] }}</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="taxonomy_term_id" class="block text-sm font-medium text-slate-800 dark:text-slate-200">Tag</label>
|
||||
<select id="taxonomy_term_id" name="taxonomy_term_id" 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="">Any tag</option>
|
||||
@foreach ($taxonomyTerms as $term)
|
||||
<option value="{{ $term->id }}" @selected((int) ($filters['taxonomy_term_id'] ?? 0) === $term->id)>{{ $term->name }} ({{ str_replace('_', ' ', $term->type) }})</option>
|
||||
@endforeach
|
||||
</select>
|
||||
</div>
|
||||
<div>
|
||||
<label for="insurance" class="block text-sm font-medium text-slate-800 dark:text-slate-200">Insurance</label>
|
||||
<input id="insurance" name="insurance" value="{{ $filters['insurance'] ?? '' }}" placeholder="Insured, COI available" 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">
|
||||
@@ -65,6 +83,9 @@
|
||||
@if (request()->boolean('public_contact'))
|
||||
<x-badge tone="emerald">Public contact</x-badge>
|
||||
@endif
|
||||
@if (! empty($filters['technician_level']))
|
||||
<x-badge tone="sky">Level: {{ $technicianLevels[(int) $filters['technician_level']]['short_name'] ?? $filters['technician_level'] }}</x-badge>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -90,6 +111,7 @@
|
||||
@if ($profile->service_area)
|
||||
<x-badge tone="slate">{{ $profile->service_area }}</x-badge>
|
||||
@endif
|
||||
<x-badge tone="sky">{{ $profile->technicianLevel()['short_name'] }}</x-badge>
|
||||
@if ($profile->public_contact)
|
||||
<x-badge tone="emerald">Public contact</x-badge>
|
||||
@endif
|
||||
@@ -107,6 +129,13 @@
|
||||
@if ($profile->skills)
|
||||
<p class="mt-4 text-sm leading-6 text-slate-600 dark:text-slate-400">{{ \Illuminate\Support\Str::limit($profile->skills, 220) }}</p>
|
||||
@endif
|
||||
@if ($profile->taxonomyTerms->isNotEmpty())
|
||||
<div class="mt-3 flex flex-wrap gap-2">
|
||||
@foreach ($profile->taxonomyTerms->take(8) as $term)
|
||||
<x-badge tone="slate">{{ $term->name }}</x-badge>
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
</a>
|
||||
@empty
|
||||
<div class="tse-panel p-8 text-center lg:col-span-2">
|
||||
|
||||
@@ -18,6 +18,12 @@
|
||||
@if ($profile->insurance_status)
|
||||
<x-badge tone="sky">{{ $profile->insurance_status }}</x-badge>
|
||||
@endif
|
||||
<x-badge tone="sky">{{ $profile->technicianLevel()['name'] }}</x-badge>
|
||||
</div>
|
||||
<div class="mt-4 rounded-md border border-sky-200 bg-sky-50 p-4 text-sm text-sky-950 dark:border-sky-900 dark:bg-sky-950/40 dark:text-sky-100">
|
||||
<p class="font-semibold">{{ $profile->technicianLevel()['short_name'] }}</p>
|
||||
<p class="mt-1">{{ $profile->technicianLevel()['description'] }}</p>
|
||||
<p class="mt-2 text-xs">Level and tags are self-declared unless supported by buyer endorsements, completed TSE work, certification proof, or admin verification.</p>
|
||||
</div>
|
||||
|
||||
@if ($profile->visible('bio'))
|
||||
@@ -25,6 +31,16 @@
|
||||
@endif
|
||||
|
||||
<dl class="mt-6 grid gap-4 md:grid-cols-2">
|
||||
<div>
|
||||
<dt class="text-sm text-slate-500 dark:text-slate-400">Tags and evidence</dt>
|
||||
<dd class="mt-2 flex flex-wrap gap-2">
|
||||
@forelse ($profile->taxonomyTerms as $term)
|
||||
<x-badge tone="slate">{{ $term->name }}{{ $term->pivot?->evidence_source ? ' | '.str_replace('_', ' ', $term->pivot->evidence_source) : '' }}</x-badge>
|
||||
@empty
|
||||
<span class="text-sm text-slate-600 dark:text-slate-400">No taxonomy tags yet.</span>
|
||||
@endforelse
|
||||
</dd>
|
||||
</div>
|
||||
@if ($profile->visible('services'))
|
||||
<div>
|
||||
<dt class="text-sm text-slate-500 dark:text-slate-400">Services</dt>
|
||||
|
||||
@@ -42,6 +42,7 @@
|
||||
<section>
|
||||
<h2>Scope Safeguards</h2>
|
||||
<p class="muted">Scope clarity: {{ str_replace('_', ' ', $workOrder->scope_clarity_status) }}</p>
|
||||
<p class="muted">Technician level: {{ $workOrder->technicianLevel()['name'] }}</p>
|
||||
@if (is_array($workOrder->risk_flags) && $workOrder->risk_flags)
|
||||
<p class="muted">Risk flags: {{ collect($workOrder->risk_flags)->map(fn ($flag) => str_replace('_', ' ', $flag))->implode(', ') }}</p>
|
||||
@endif
|
||||
|
||||
@@ -68,6 +68,7 @@
|
||||
</div>
|
||||
<div class="flex flex-wrap gap-2">
|
||||
<x-badge tone="{{ $workOrder->scope_clarity_status === 'clear' ? 'emerald' : 'amber' }}">Scope {{ str_replace('_', ' ', $workOrder->scope_clarity_status) }}</x-badge>
|
||||
<x-badge tone="sky">{{ $workOrder->technicianLevel()['name'] }}</x-badge>
|
||||
@if ($workOrder->contactSnapshotValue('contact_certified'))
|
||||
<x-badge tone="emerald">Support certified</x-badge>
|
||||
@else
|
||||
|
||||
Reference in New Issue
Block a user