Skip to main content

Infrastructure

Forge Provider Picker code

Copy the implementation or inspect every file that belongs to this component unit.

resources/views/components/ui/forge-provider-picker.blade.php

@props([
    'providers' => [],
    'name' => 'provider',
    'selected' => null,
])

@php
    /*
    | Radio-card picker for Forge-style server providers. Each provider accepts:
    | value, label, description, icon, connected, badge, meta, disabled.
    |
    | Usage:
    |   <x-ui.forge-provider-picker selected="laravel-vps" :providers="$providers" />
    */
    $providers = collect($providers)->map(function (array $provider, int $index): array {
        $value = (string) ($provider['value'] ?? $provider['label'] ?? "provider-{$index}");

        return [
            'value' => $value,
            'label' => $provider['label'] ?? $value,
            'description' => $provider['description'] ?? null,
            'icon' => $provider['icon'] ?? 'cloud',
            'connected' => (bool) ($provider['connected'] ?? false),
            'badge' => $provider['badge'] ?? null,
            'meta' => $provider['meta'] ?? null,
            'disabled' => (bool) ($provider['disabled'] ?? false),
        ];
    })->values();
@endphp

<fieldset {{ $attributes->merge(['class' => 'min-w-0']) }}>
    <legend class="sr-only">Server provider</legend>

    <div class="grid min-w-0 gap-3 sm:grid-cols-2 xl:grid-cols-3">
        @foreach ($providers as $provider)
            @php
                $isSelected = (string) $selected === (string) $provider['value'];
                $inputId = $name.'-'.substr(md5((string) $provider['value']), 0, 8);
            @endphp

            <label
                for="{{ $inputId }}"
                @class([
                    'group relative flex min-w-0 cursor-pointer flex-col gap-3 rounded-xl border bg-white p-4 transition dark:bg-gray-900',
                    'border-gray-200 hover:border-gray-300 dark:border-gray-800 dark:hover:border-gray-700 has-[:checked]:border-brand-500 has-[:checked]:ring-2 has-[:checked]:ring-brand-500/20 dark:has-[:checked]:border-brand-400' => ! $provider['disabled'],
                    'cursor-not-allowed opacity-60' => $provider['disabled'],
                ])
            >
                <input
                    id="{{ $inputId }}"
                    type="radio"
                    name="{{ $name }}"
                    value="{{ $provider['value'] }}"
                    class="sr-only"
                    @checked($isSelected)
                    @disabled($provider['disabled'])
                >

                <span class="flex min-w-0 flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
                    <span class="flex min-w-0 items-center gap-3">
                        <span class="flex h-10 w-10 shrink-0 items-center justify-center rounded-lg bg-gray-100 text-gray-600 dark:bg-gray-800 dark:text-gray-300">
                            <x-ui.icon :name="$provider['icon']" weight="duotone" size="lg" />
                        </span>
                        <span class="min-w-0">
                            <span class="block truncate text-sm font-semibold text-gray-900 dark:text-white">{{ $provider['label'] }}</span>
                            @if ($provider['meta'])
                                <span class="mt-0.5 block truncate text-xs text-gray-500 dark:text-gray-400">{{ $provider['meta'] }}</span>
                            @endif
                        </span>
                    </span>

                    @if ($provider['badge'])
                        <x-ui.badge variant="outline" size="sm" class="w-fit sm:shrink-0">{{ $provider['badge'] }}</x-ui.badge>
                    @elseif ($provider['connected'])
                        <x-ui.badge variant="green" size="sm" dot class="w-fit sm:shrink-0">Connected</x-ui.badge>
                    @else
                        <x-ui.badge variant="gray" size="sm" class="w-fit sm:shrink-0">Setup</x-ui.badge>
                    @endif
                </span>

                @if ($provider['description'])
                    <span class="block text-sm leading-5 text-gray-600 dark:text-gray-400">{{ $provider['description'] }}</span>
                @endif
            </label>
        @endforeach
    </div>
</fieldset>