Files
thrillwiki_laravel/resources/views/components/universal-listing-card.blade.php
pacnpal 97a7682eb7 Add Livewire components for parks, rides, and manufacturers
- Implemented ParksLocationSearch component with loading state and refresh functionality.
- Created ParksMapView component with similar structure and functionality.
- Added RegionalParksListing component for displaying regional parks.
- Developed RidesListingUniversal component for universal listing integration.
- Established ManufacturersListing view with navigation and Livewire integration.
- Added feature tests for various Livewire components including OperatorHierarchyView, OperatorParksListing, OperatorPortfolioCard, OperatorsListing, OperatorsRoleFilter, ParksListing, ParksLocationSearch, ParksMapView, and RegionalParksListing to ensure proper rendering and adherence to patterns.
2025-06-23 21:31:05 -04:00

204 lines
11 KiB
PHP

@props([
'item' => null,
'config' => [],
'badges' => [],
'colorScheme' => ['primary' => 'blue', 'secondary' => 'green', 'accent' => 'purple'],
'layout' => 'grid'
])
@php
$cardConfig = collect($config);
$badgeConfig = collect($badges);
@endphp
@if($layout === 'grid')
{{-- Grid Layout Card --}}
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-md p-6 border border-gray-200 dark:border-gray-700 hover:shadow-lg transition-shadow">
{{-- Header --}}
<div class="flex items-start justify-between mb-4">
<div class="flex-1">
<h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100">
{{ data_get($item, $cardConfig->get('title', 'name')) }}
</h3>
@if($cardConfig->has('subtitle') && data_get($item, $cardConfig->get('subtitle')))
<p class="text-sm text-gray-600 dark:text-gray-400">
{{ data_get($item, $cardConfig->get('subtitle')) }}
</p>
@endif
</div>
@if($cardConfig->has('score') && data_get($item, $cardConfig->get('score')))
<div class="text-right">
<div class="text-lg font-bold text-{{ $colorScheme['primary'] }}-600 dark:text-{{ $colorScheme['primary'] }}-400">
{{ data_get($item, $cardConfig->get('score')) }}
</div>
<div class="text-xs text-gray-500">{{ $cardConfig->get('scoreLabel', 'Score') }}</div>
</div>
@endif
</div>
{{-- Badges --}}
@if($badgeConfig->has('fields'))
<div class="flex flex-wrap gap-2 mb-4">
@foreach($badgeConfig->get('fields', []) as $badgeField)
@if(data_get($item, $badgeField['field']))
<span class="px-3 py-1 text-sm bg-{{ $badgeField['color'] ?? $colorScheme['primary'] }}-100 dark:bg-{{ $badgeField['color'] ?? $colorScheme['primary'] }}-900 text-{{ $badgeField['color'] ?? $colorScheme['primary'] }}-800 dark:text-{{ $badgeField['color'] ?? $colorScheme['primary'] }}-200 rounded-full">
{{ $badgeField['prefix'] ?? '' }}{{ data_get($item, $badgeField['field']) }}{{ $badgeField['suffix'] ?? '' }}
</span>
@endif
@endforeach
</div>
@endif
{{-- Metrics --}}
@if($cardConfig->has('metrics'))
<div class="grid grid-cols-2 gap-4 text-sm">
@foreach(array_slice($cardConfig->get('metrics', []), 0, 4) as $metric)
@if(data_get($item, $metric['field']))
<div>
<div class="font-semibold text-gray-900 dark:text-gray-100">
{{ isset($metric['format']) ? sprintf($metric['format'], data_get($item, $metric['field'])) : data_get($item, $metric['field']) }}
</div>
<div class="text-gray-600 dark:text-gray-400">{{ $metric['label'] }}</div>
</div>
@endif
@endforeach
</div>
@endif
</div>
@elseif($layout === 'list')
{{-- List Layout Card --}}
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-md p-6 border border-gray-200 dark:border-gray-700 hover:shadow-lg transition-shadow">
<div class="flex items-start justify-between">
<div class="flex-1">
<div class="flex items-start justify-between mb-3">
<div class="flex-1">
<h3 class="text-xl font-semibold text-gray-900 dark:text-gray-100">
{{ data_get($item, $cardConfig->get('title', 'name')) }}
</h3>
@if($cardConfig->has('description') && data_get($item, $cardConfig->get('description')))
<p class="text-gray-600 dark:text-gray-400 mt-1">
{{ Str::limit(data_get($item, $cardConfig->get('description')), 150) }}
</p>
@endif
</div>
@if($cardConfig->has('score') && data_get($item, $cardConfig->get('score')))
<div class="text-right ml-6">
<div class="text-2xl font-bold text-{{ $colorScheme['primary'] }}-600 dark:text-{{ $colorScheme['primary'] }}-400">
{{ data_get($item, $cardConfig->get('score')) }}
</div>
<div class="text-sm text-gray-500">{{ $cardConfig->get('scoreLabel', 'Score') }}</div>
</div>
@endif
</div>
{{-- Badges --}}
@if($badgeConfig->has('fields'))
<div class="flex flex-wrap gap-2 mb-4">
@foreach($badgeConfig->get('fields', []) as $badgeField)
@if(data_get($item, $badgeField['field']))
<span class="px-3 py-1 text-sm bg-{{ $badgeField['color'] ?? $colorScheme['primary'] }}-100 dark:bg-{{ $badgeField['color'] ?? $colorScheme['primary'] }}-900 text-{{ $badgeField['color'] ?? $colorScheme['primary'] }}-800 dark:text-{{ $badgeField['color'] ?? $colorScheme['primary'] }}-200 rounded-full">
{{ $badgeField['prefix'] ?? '' }}{{ data_get($item, $badgeField['field']) }}{{ $badgeField['suffix'] ?? '' }}
</span>
@endif
@endforeach
</div>
@endif
{{-- Metrics --}}
@if($cardConfig->has('metrics'))
<div class="grid grid-cols-4 gap-6 text-sm">
@foreach($cardConfig->get('metrics', []) as $metric)
@if(data_get($item, $metric['field']))
<div>
<div class="text-lg font-semibold text-gray-900 dark:text-gray-100">
{{ isset($metric['format']) ? sprintf($metric['format'], data_get($item, $metric['field'])) : data_get($item, $metric['field']) }}
</div>
<div class="text-gray-600 dark:text-gray-400">{{ $metric['label'] }}</div>
</div>
@endif
@endforeach
</div>
@endif
</div>
</div>
</div>
@elseif($layout === 'portfolio')
{{-- Portfolio Layout Card --}}
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-md p-8 border border-gray-200 dark:border-gray-700 hover:shadow-lg transition-shadow">
<div class="flex items-start justify-between mb-6">
<div class="flex-1">
<h3 class="text-2xl font-semibold text-gray-900 dark:text-gray-100 mb-3">
{{ data_get($item, $cardConfig->get('title', 'name')) }}
</h3>
@if($cardConfig->has('description') && data_get($item, $cardConfig->get('description')))
<p class="text-gray-600 dark:text-gray-400 mb-4 text-lg">
{{ data_get($item, $cardConfig->get('description')) }}
</p>
@endif
{{-- Enhanced Badges for Portfolio --}}
@if($badgeConfig->has('fields'))
<div class="flex flex-wrap gap-3">
@foreach($badgeConfig->get('fields', []) as $badgeField)
@if(data_get($item, $badgeField['field']))
<span class="px-4 py-2 text-sm bg-{{ $badgeField['color'] ?? $colorScheme['primary'] }}-100 dark:bg-{{ $badgeField['color'] ?? $colorScheme['primary'] }}-900 text-{{ $badgeField['color'] ?? $colorScheme['primary'] }}-800 dark:text-{{ $badgeField['color'] ?? $colorScheme['primary'] }}-200 rounded-full font-medium">
{{ $badgeField['prefix'] ?? '' }}{{ data_get($item, $badgeField['field']) }}{{ $badgeField['suffix'] ?? '' }}
</span>
@endif
@endforeach
</div>
@endif
</div>
@if($cardConfig->has('score') && data_get($item, $cardConfig->get('score')))
<div class="text-right ml-8">
<div class="text-3xl font-bold text-{{ $colorScheme['primary'] }}-600 dark:text-{{ $colorScheme['primary'] }}-400">
{{ data_get($item, $cardConfig->get('score')) }}
</div>
<div class="text-sm text-gray-500">{{ $cardConfig->get('scoreLabel', 'Score') }}</div>
</div>
@endif
</div>
{{-- Enhanced Metrics Grid for Portfolio --}}
@if($cardConfig->has('metrics'))
<div class="grid grid-cols-4 gap-8 text-sm border-t border-gray-200 dark:border-gray-700 pt-6">
@foreach($cardConfig->get('metrics', []) as $metric)
@if(data_get($item, $metric['field']))
<div class="text-center">
<div class="text-2xl font-bold text-gray-900 dark:text-gray-100">
{{ isset($metric['format']) ? sprintf($metric['format'], data_get($item, $metric['field'])) : data_get($item, $metric['field']) }}
</div>
<div class="text-gray-600 dark:text-gray-400 mt-1">{{ $metric['label'] }}</div>
</div>
@endif
@endforeach
</div>
@endif
</div>
@else
{{-- Default/Compact Layout --}}
<div class="bg-white dark:bg-gray-800 rounded-lg shadow-md p-4 border border-gray-200 dark:border-gray-700 hover:shadow-lg transition-shadow">
<div class="flex items-center justify-between">
<div class="flex-1">
<h3 class="text-lg font-semibold text-gray-900 dark:text-gray-100">
{{ data_get($item, $cardConfig->get('title', 'name')) }}
</h3>
@if($cardConfig->has('subtitle') && data_get($item, $cardConfig->get('subtitle')))
<p class="text-sm text-gray-600 dark:text-gray-400">
{{ data_get($item, $cardConfig->get('subtitle')) }}
</p>
@endif
</div>
@if($cardConfig->has('score') && data_get($item, $cardConfig->get('score')))
<div class="text-right">
<div class="text-lg font-bold text-{{ $colorScheme['primary'] }}-600 dark:text-{{ $colorScheme['primary'] }}-400">
{{ data_get($item, $cardConfig->get('score')) }}
</div>
</div>
@endif
</div>
</div>
@endif