@if(session('admin_status'))
✓ {{ __('ui.admin_saved') }}
@endif
@if(session('admin_status_message'))
{{ session('admin_status_message') }}
@endif
@if(session('admin_error_message'))
{{ session('admin_error_message') }}
@endif
@if(session('catalog_sync_status'))
@php $syncStatus=session('catalog_sync_status'); @endphp
{{ $syncStatus['message'] }}
@endif
@if($errors->any())
{{ __('ui.admin_validation_error') }}
@endif
@php
$rcdbMatch=$park->rcdbMatch;
$analysisRun=$park->latestCoasterAnalysis;
$sourceKeys=$externalReferences->pluck('source_key')->all();
$rcdbLinked=in_array('rcdb',$sourceKeys,true) || ($rcdbMatch && in_array($rcdbMatch->status,['confirmed','manual'],true));
$coasterpediaLinked=in_array('coasterpedia',$sourceKeys,true);
$themeParksLinked=(bool)$themeParksExternalId;
$hasLocation=$parkLatitude !== null && $parkLongitude !== null;
$autoFillReport=session('park_auto_fill_report');
@endphp
{{ __('ui.admin_status') }}{{ $park->is_published ? __('ui.admin_published') : __('ui.admin_park_draft') }}{{ __('ui.admin_park_type_'.$park->park_type) }}
{{ __('ui.admin_park_location_title') }}{{ $hasLocation ? __('ui.admin_park_location_present') : __('ui.admin_park_location_missing') }}{{ $hasLocation ? number_format($parkLatitude,5,'.','').', '.number_format($parkLongitude,5,'.','') : __('ui.admin_park_location_missing_help') }}
{{ __('ui.admin_park_external_sources') }}{{ $externalReferences->count() }}{{ $externalReferences->pluck('source_key')->take(4)->join(' · ') ?: __('ui.admin_park_no_external_source') }}
{{ __('ui.admin_park_catalog_content') }}{{ $catalogOverview['attractions'] }}{{ $catalogOverview['coasters'] }} {{ __('ui.admin_analysis_coasters_short') }} · {{ $catalogOverview['pois'] }} POI
@if(session('poi_sync_report'))
@php $poiReport=session('poi_sync_report'); $tpReport=$poiReport['themeparks'] ?? []; $osmReport=$poiReport['osm'] ?? []; @endphp
ThemeParks.wiki{{ __('ui.admin_poi_sync_source_themeparks') }}
{{ __('ui.admin_poi_sync_status_'.($tpReport['status'] ?? 'partial')) }}
{{ __('ui.admin_poi_sync_report_themeparks', ['created'=>(int)($tpReport['pois_created'] ?? 0),'updated'=>(int)($tpReport['pois_updated'] ?? 0),'unchanged'=>(int)($tpReport['pois_unchanged'] ?? 0),'errors'=>count($tpReport['errors'] ?? [])]) }}
OpenStreetMap{{ __('ui.admin_poi_sync_source_osm') }}
{{ __('ui.admin_poi_sync_status_'.($osmReport['status'] ?? 'partial')) }}
{{ __('ui.admin_poi_sync_report_osm', ['received'=>(int)($osmReport['received'] ?? 0),'imported'=>(int)($osmReport['imported'] ?? 0),'created'=>(int)($osmReport['created'] ?? 0),'updated'=>(int)($osmReport['updated'] ?? 0),'merged'=>(int)($osmReport['merged'] ?? 0),'ignored'=>(int)($osmReport['ignored'] ?? 0)]) }}
@if(!empty($osmReport['warnings']))
{{ trans_choice('ui.admin_poi_sync_warnings_count', count($osmReport['warnings']), ['count'=>count($osmReport['warnings'])]) }}
@foreach(array_slice($osmReport['warnings'],0,8) as $warning)- {{ $warning }}
@endforeach
@endif
@endif
@if($autoFillReport)
@php $created=$autoFillReport['created'] ?? ['attractions'=>0,'coasters'=>0,'pois'=>0]; @endphp
{{ __('ui.admin_park_auto_fill_report_kicker') }}
{{ __('ui.admin_park_auto_fill_report_title') }}
{{ __('ui.admin_park_auto_fill_result', ['attractions'=>(int)($created['attractions'] ?? 0),'coasters'=>(int)($created['coasters'] ?? 0),'pois'=>(int)($created['pois'] ?? 0),'errors'=>count($autoFillReport['errors'] ?? [])]) }}
@if(!empty($autoFillReport['linked_sources']))
{{ __('ui.admin_park_auto_fill_linked_sources', ['sources'=>implode(' · ', $autoFillReport['linked_sources'])]) }}@endif
@endif
{{ __('ui.admin_park_auto_fill_kicker') }}
{{ __('ui.admin_park_auto_fill_title') }}
{{ __('ui.admin_park_auto_fill_help') }}
{{ __('ui.admin_park_auto_fill_recommended') }}
{{ __('ui.admin_attractions') }}{{ $catalogOverview['attractions'] }}
{{ __('ui.admin_coasters') }}{{ $catalogOverview['coasters'] }}
POI{{ $catalogOverview['pois'] }}
ThemeParks.wiki{{ $themeParksLinked ? __('ui.admin_catalog_sync_linked') : __('ui.admin_park_auto_source_searchable') }}
RCDB{{ $rcdbLinked ? __('ui.admin_rcdb_linked') : __('ui.admin_park_auto_source_searchable') }}
Coasterpedia{{ $coasterpediaLinked ? __('ui.admin_catalog_sync_linked') : __('ui.admin_park_auto_source_searchable') }}
OpenStreetMap{{ $hasLocation ? __('ui.admin_park_source_ready') : __('ui.admin_park_source_needs_location') }}
@if(is_array($lastAutoFill) && !empty($lastAutoFill['at']))
{{ __('ui.admin_park_auto_fill_last_run', ['date'=>\Illuminate\Support\Carbon::parse($lastAutoFill['at'])->format('d/m/Y H:i')]) }}
@endif
{{ __('ui.admin_park_manual_tools_kicker') }}
{{ __('ui.admin_park_manual_tools_title') }}
{{ __('ui.admin_park_manual_tools_help') }}
{{ __('ui.admin_park_manual_tools_preserve_help') }}
{{ __('ui.admin_park_hours_kicker') }}
{{ __('ui.admin_park_hours_title') }}
{{ __('ui.admin_park_hours_help') }}
@if(session('park_hours_sync_report'))
@php $hoursSync=session('park_hours_sync_report'); @endphp
@endif
{{ __('ui.admin_park_hours_next_45') }}{{ $openingHoursOverview['scheduled_days'] }}{{ __('ui.admin_park_hours_days_known') }}
{{ __('ui.admin_park_hours_missing') }}{{ $openingHoursOverview['missing_days'] }}{{ __('ui.admin_park_hours_days_unknown') }}
{{ __('ui.admin_park_hours_manual') }}{{ $openingHoursOverview['manual_days'] }}{{ __('ui.admin_park_hours_manual_priority') }}
{{ __('ui.admin_park_hours_auto_kicker') }}
{{ __('ui.admin_park_hours_auto_title') }}
{{ __('ui.admin_park_hours_auto_help') }}
ThemeParks.wiki{{ $openingHoursOverview['themeparks_linked'] ? __('ui.admin_catalog_sync_linked') : __('ui.admin_park_hours_source_unlinked') }}
DATAtourisme{{ !$openingHoursOverview['datatourisme_configured'] ? __('ui.admin_park_hours_source_not_configured') : ($openingHoursOverview['datatourisme_linked'] ? __('ui.admin_catalog_sync_linked') : __('ui.admin_park_hours_source_unlinked')) }}
{{ __('ui.admin_park_hours_auto_priority') }}
{{ __('ui.admin_park_hours_manual_kicker') }}
{{ __('ui.admin_park_hours_manual_title') }}
{{ __('ui.admin_park_hours_manual_help') }}
| {{ __('ui.admin_park_hours_date') }} | {{ __('ui.admin_park_hours_status') }} | {{ __('ui.admin_park_hours_hours') }} | {{ __('ui.admin_park_hours_source') }} | {{ __('ui.admin_park_hours_actions') }} |
@foreach($openingHoursCalendar as $day)
| {{ $day['date']->translatedFormat('D d/m') }} |
@if(!$day['has_schedule']){{ __('ui.admin_park_hours_unknown') }}
@elseif($day['closed']){{ __('ui.admin_park_hours_closed') }}
@else{{ __('ui.admin_park_hours_open') }}@endif
|
{{ $day['opens_at'] && $day['closes_at'] ? $day['opens_at']->format('H:i').' – '.$day['closes_at']->format('H:i') : '—' }} |
{{ $day['source'] === 'manual' ? __('ui.admin_park_hours_source_manual') : ($day['source'] ?: '—') }} |
@if($day['manual'])
@endif
|
@endforeach
{{ __('ui.admin_park_catalog_manager_kicker') }}
{{ __('ui.admin_park_catalog_manager_title') }}
{{ __('ui.admin_park_catalog_manager_help') }}
{{ __('ui.admin_attractions') }}{{ $catalogOverview['attractions'] }}{{ $catalogOverview['published_attractions'] }} {{ __('ui.admin_park_catalog_visible') }} · {{ $catalogOverview['attractions_without_location'] }} {{ __('ui.admin_park_catalog_to_position') }}
{{ __('ui.admin_coasters') }}{{ $catalogOverview['coasters'] }}{{ $catalogOverview['published_coasters'] }} {{ __('ui.admin_park_catalog_visible') }} · {{ $catalogOverview['coasters_without_location'] }} {{ __('ui.admin_park_catalog_to_position') }}
POI{{ $catalogOverview['pois'] }}{{ $catalogOverview['published_pois'] }} {{ __('ui.admin_park_catalog_visible') }} · {{ $catalogOverview['pois_without_location'] }} {{ __('ui.admin_park_catalog_without_gps') }}
@forelse($parkAttractions as $attraction)
@php
$refs=$catalogExternalReferences->get('attraction:'.$attraction->id, collect());
$attractionLocation=$attractionLocations->get($attraction->id);
$attractionHasGps=$attractionLocation && $attractionLocation->latitude !== null && $attractionLocation->longitude !== null;
$attractionManualLocked=isset($manualLocationLocks[(int)$attraction->id]);
$attractionLocationSource=$attractionManualLocked
? 'manual_location'
: ($refs->pluck('source_key')->first(fn($source)=>str_starts_with((string)$source,'location_')) ?: '');
@endphp
{{ $attraction->official_name }}
{{ $attraction->attraction_type ?: __('ui.admin_park_catalog_unknown_type') }}
{{ $attraction->status }}
{{ $attraction->media_links_count }} {{ __('ui.admin_park_catalog_media') }}
{{ $attractionHasGps ? __('ui.admin_park_catalog_gps_ok') : __('ui.admin_park_catalog_position_missing') }}
@if($attractionManualLocked){{ __('ui.admin_park_catalog_position_manual') }}@endif
@foreach($refs->pluck('source_key')->reject(fn($source)=>$source==='manual_location')->unique()->take(3) as $source){{ $source }}@endforeach
{{ $attraction->is_published ? __('ui.admin_park_catalog_published') : __('ui.admin_park_catalog_hidden') }}
{{ __('ui.admin_edit') }}
@empty
{{ __('ui.admin_park_catalog_no_attractions') }}
@endforelse
@forelse($parkCoasters as $coaster)
@php
$coasterRefs=$catalogExternalReferences->get('coaster:'.$coaster->id, collect());
$coasterAttraction=$coaster->attraction;
$coasterLocation=$coasterAttraction ? $attractionLocations->get($coasterAttraction->id) : null;
$coasterHasGps=$coasterLocation && $coasterLocation->latitude !== null && $coasterLocation->longitude !== null;
$coasterManualLocked=$coasterAttraction ? isset($manualLocationLocks[(int)$coasterAttraction->id]) : false;
$coasterAttractionRefs=$coasterAttraction ? $catalogExternalReferences->get('attraction:'.$coasterAttraction->id, collect()) : collect();
$coasterLocationSource=$coasterManualLocked
? 'manual_location'
: ($coasterAttractionRefs->pluck('source_key')->first(fn($source)=>str_starts_with((string)$source,'location_')) ?: '');
@endphp
{{ $coasterAttraction?->official_name ?: '—' }}
{{ $coaster->manufacturer?->name ?: __('ui.admin_park_catalog_manufacturer_unknown') }}
@if($coaster->coaster_type){{ $coaster->coaster_type }}@endif
@if($coaster->speed_kmh){{ rtrim(rtrim(number_format((float)$coaster->speed_kmh,1,'.',''),'0'),'.') }} km/h@endif
{{ (int)$coaster->media_links_count + ($coasterAttraction?->mediaLinks?->count() ?? 0) }} {{ __('ui.admin_park_catalog_media') }}
{{ $coasterHasGps ? __('ui.admin_park_catalog_gps_ok') : __('ui.admin_park_catalog_position_missing') }}
@if($coasterManualLocked){{ __('ui.admin_park_catalog_position_manual') }}@endif
@foreach($coasterRefs->pluck('source_key')->unique()->take(3) as $source){{ $source }}@endforeach
{{ $coasterAttraction?->is_published ? __('ui.admin_park_catalog_published') : __('ui.admin_park_catalog_hidden') }}
@if($coasterAttraction)
@endif
{{ __('ui.admin_edit') }}
@empty
{{ __('ui.admin_park_catalog_no_coasters') }}
@endforelse
@forelse($parkPois as $poi)
@php $poiRefs=$catalogExternalReferences->get('park_poi:'.$poi->id, collect()); $poiHasGps=$poi->latitude !== null && $poi->longitude !== null; @endphp
{{ $poi->official_name }}
{{ $poi->poi_type }}
{{ $poi->status }}
{{ $poiHasGps ? __('ui.admin_park_catalog_gps_ok') : __('ui.admin_park_catalog_gps_missing') }}
@foreach($poiRefs->pluck('source_key')->unique()->take(3) as $source){{ $source }}@endforeach
{{ $poi->is_published ? __('ui.admin_park_catalog_published') : __('ui.admin_park_catalog_hidden') }}
@empty
{{ __('ui.admin_park_catalog_no_pois') }}
@endforelse
{{ __('ui.admin_park_catalog_no_results') }}
@php $entity=$park; $mediaType='park'; $mediaRoles=["logo", "hero", "gallery"]; @endphp
@include('admin._media_manager', ['entity' => $entity, 'mediaType' => $mediaType, 'mediaRoles' => $mediaRoles])
@include('admin._external_references')
@include('admin._enrichment', ['entity' => $entity, 'mediaType' => $mediaType])
@if(in_array($park->source_type, ['manual', 'curated'], true))
{{ __('ui.admin_danger_zone') }}{{ __('ui.admin_delete_park_v107') }}
{{ __('ui.admin_delete_park_help_v107') }}
@endif
@if(app()->environment('local'))
{{ __('ui.admin_dev_force_delete_kicker') }}
{{ __('ui.admin_dev_force_delete_title') }}
{{ __('ui.admin_dev_force_delete_help') }}
@endif