Data display
Globe Location List code
Copy the implementation or inspect every file that belongs to this component unit.
resources/views/components/ui/globe-location-list.blade.php
@props([
'locations' => [],
])
@php
$locationItems = collect($locations)->values();
$locationVariant = function (array $location): string {
$explicit = strtolower((string) ($location['variant'] ?? ''));
if (in_array($explicit, ['brand', 'red', 'amber', 'green', 'blue', 'gray'], true)) {
return $explicit;
}
return match (strtolower((string) ($location['type'] ?? ''))) {
'hq', 'office', 'region' => 'brand',
'edge', 'cdn', 'datacenter' => 'blue',
'staging', 'beta' => 'amber',
'incident', 'alert' => 'red',
'verified', 'live' => 'green',
default => 'brand',
};
};
$formatCoordinates = function (float $lat, float $lng): string {
return sprintf(
'%.2f°%s · %.2f°%s',
abs($lat),
$lat >= 0 ? 'N' : 'S',
abs($lng),
$lng >= 0 ? 'E' : 'W',
);
};
@endphp
<ul {{ $attributes->merge(['class' => 'harbour-globe-location-list space-y-1']) }}>
@forelse ($locationItems as $index => $location)
@php
$variant = $locationVariant($location);
$label = $location['label'] ?? $location['title'] ?? 'Location';
$type = trim((string) ($location['type'] ?? ''));
$description = $location['description'] ?? null;
$lat = $location['lat'] ?? null;
$lng = $location['lng'] ?? null;
@endphp
<li>
<button
type="button"
data-globe-location-item="{{ $index }}"
aria-current="false"
class="harbour-globe-location-list-item group flex w-full items-start gap-3 rounded-xl px-3 py-2.5 text-left transition hover:bg-gray-50 dark:hover:bg-gray-800/60"
>
{{-- Beacon glyph mirroring the canvas marker: chart ring + LED core. --}}
<span class="harbour-globe-location-beacon relative mt-1 flex h-3.5 w-3.5 shrink-0 items-center justify-center" aria-hidden="true">
<span @class([
'absolute inset-0 rounded-full border',
'border-brand-500/45' => $variant === 'brand',
'border-red-500/45' => $variant === 'red',
'border-amber-500/45' => $variant === 'amber',
'border-green-500/45' => $variant === 'green',
'border-accent-500/45' => $variant === 'blue',
'border-gray-500/45' => $variant === 'gray',
])></span>
<span @class([
'harbour-globe-location-beacon-ping absolute inset-0 rounded-full border opacity-0',
'border-brand-500' => $variant === 'brand',
'border-red-500' => $variant === 'red',
'border-amber-500' => $variant === 'amber',
'border-green-500' => $variant === 'green',
'border-accent-500' => $variant === 'blue',
'border-gray-500' => $variant === 'gray',
])></span>
<span @class([
'h-1.5 w-1.5 rounded-full',
'bg-brand-500' => $variant === 'brand',
'bg-red-500' => $variant === 'red',
'bg-amber-500' => $variant === 'amber',
'bg-green-500' => $variant === 'green',
'bg-accent-500' => $variant === 'blue',
'bg-gray-500' => $variant === 'gray',
])></span>
</span>
<span class="min-w-0 flex-1">
<span class="flex items-baseline gap-2">
<span class="truncate text-sm font-semibold text-gray-900 dark:text-white">{{ $label }}</span>
@if ($type !== '')
<span @class([
'shrink-0 font-mono text-[0.625rem] font-medium uppercase tracking-wider',
'text-brand-600 dark:text-brand-400' => $variant === 'brand',
'text-red-600 dark:text-red-400' => $variant === 'red',
'text-amber-600 dark:text-amber-400' => $variant === 'amber',
'text-green-600 dark:text-green-400' => $variant === 'green',
'text-accent-600 dark:text-accent-400' => $variant === 'blue',
'text-gray-500 dark:text-gray-400' => $variant === 'gray',
])>{{ $type }}</span>
@endif
</span>
@if ($description)
<span class="mt-1 block line-clamp-2 text-xs leading-5 text-gray-500 dark:text-gray-400">{{ $description }}</span>
@endif
@if ($lat !== null && $lng !== null)
<span class="mt-1 block font-mono text-[0.6875rem] uppercase tracking-wide text-gray-400 dark:text-gray-500">
{{ $formatCoordinates((float) $lat, (float) $lng) }}
</span>
@endif
</span>
<span class="mt-0.5 shrink-0 font-mono text-[0.6875rem] tabular-nums text-gray-300 transition group-hover:text-brand-500 dark:text-gray-600 dark:group-hover:text-brand-400" aria-hidden="true">{{ sprintf('%02d', $index + 1) }}</span>
</button>
</li>
@empty
<li class="rounded-xl px-3 py-4 text-sm text-gray-500 dark:text-gray-400">
No locations yet. Pass a `locations` array with `lat`, `lng` and `label` keys.
</li>
@endforelse
</ul>