73 lines
5.2 KiB
PHP
73 lines
5.2 KiB
PHP
<div>
|
|
<x-topbar :title="__('nav.addons')" :subtitle="__('addons.subtitle')" />
|
|
|
|
<div class="px-5 lg:px-[26px] py-6 flex flex-col gap-5 max-w-[1560px] mx-auto w-full">
|
|
<div class="grid grid-cols-1 lg:grid-cols-2 gap-4">
|
|
@foreach ($addons as $addon)
|
|
@php
|
|
$statusState = match ($addon['status']) {
|
|
'connected' => 'online',
|
|
'connecting' => 'warning',
|
|
'error' => 'offline',
|
|
default => 'neutral',
|
|
};
|
|
@endphp
|
|
<x-panel>
|
|
<div class="flex flex-col gap-4">
|
|
<div class="flex items-start gap-3.5">
|
|
<span class="grid place-items-center w-11 h-11 rounded-xl bg-accent/10 text-accent shrink-0"><x-icon :name="$addon['icon']" :size="22" /></span>
|
|
<div class="min-w-0 flex-1">
|
|
<div class="flex items-center gap-2 flex-wrap">
|
|
<h3 class="text-[15px] font-bold text-ink">{{ $addon['name'] }}</h3>
|
|
@if ($addon['cloud'])
|
|
<span title="{{ __('addons.cloud_hint') }}" class="inline-flex items-center gap-1 rounded-full bg-inset px-2 py-[2px] text-[10px] font-bold text-ink-2">
|
|
<x-icon name="cloud" :size="12" /> {{ __('addons.cloud') }}
|
|
</span>
|
|
@endif
|
|
</div>
|
|
<p class="text-[12.5px] text-ink-2 mt-0.5">{{ __($addon['summary_key']) }}</p>
|
|
</div>
|
|
@if ($addon['installed'])
|
|
<x-status-pill :state="$statusState" class="shrink-0">{{ __('addons.status_'.$addon['status']) }}</x-status-pill>
|
|
@endif
|
|
</div>
|
|
|
|
<p class="text-[12.5px] text-ink-3 leading-relaxed">{{ __($addon['body_key']) }}</p>
|
|
|
|
@if ($addon['installed'] && $addon['status_detail'])
|
|
<p class="text-[11.5px] text-offline font-mono">{{ $addon['status_detail'] }}</p>
|
|
@endif
|
|
|
|
<div class="flex items-center gap-2 pt-0.5">
|
|
@if (! $addon['installed'])
|
|
<button type="button" wire:click="install('{{ $addon['key'] }}')"
|
|
class="inline-flex items-center gap-1.5 rounded-lg bg-accent px-3.5 py-2 text-[13px] font-bold text-base hover:brightness-110 transition-[filter]">
|
|
<x-icon name="plus" :size="15" /> {{ __('addons.install') }}
|
|
</button>
|
|
@else
|
|
<button type="button" wire:click="$dispatch('openModal', { component: 'modals.ring-connect' })"
|
|
class="inline-flex items-center gap-1.5 rounded-lg bg-accent px-3.5 py-2 text-[13px] font-bold text-base hover:brightness-110 transition-[filter]">
|
|
<x-icon name="user" :size="15" /> {{ $addon['status'] === 'connected' ? __('addons.reconnect') : __('addons.connect') }}
|
|
</button>
|
|
<a href="{{ $addon['docs'] }}" target="_blank" rel="noopener noreferrer"
|
|
class="inline-flex items-center gap-1.5 rounded-lg border border-line px-3 py-2 text-[12.5px] font-semibold text-ink-2 hover:text-ink hover:bg-raised transition-colors">
|
|
{{ __('common.docs') }}
|
|
</a>
|
|
{{-- to: 'addons' — Livewire names App\Livewire\Addons\Index as "addons" (the Index
|
|
suffix is dropped for index components), NOT "addons.index". Verified against the
|
|
rendered wire:snapshot; "addons.index" silently drops the event. Use $wire.$dispatch
|
|
(Livewire), not Alpine's $dispatch, so wire-elements' modal listener receives it. --}}
|
|
<button type="button"
|
|
x-on:click="$wire.set('pendingUninstall', @js($addon['key'])); $wire.$dispatch('openModal', { component: 'modals.confirm', arguments: { title: @js(__('addons.uninstall_title', ['name' => $addon['name']])), body: @js(__('addons.uninstall_body')), confirmLabel: @js(__('addons.uninstall')), event: 'addon-uninstall', to: 'addons', danger: true } })"
|
|
class="ml-auto inline-flex items-center gap-1.5 rounded-lg border border-line px-3 py-2 text-[12.5px] font-semibold text-ink-3 hover:text-offline hover:border-offline/40 transition-colors">
|
|
{{ __('addons.uninstall') }}
|
|
</button>
|
|
@endif
|
|
</div>
|
|
</div>
|
|
</x-panel>
|
|
@endforeach
|
|
</div>
|
|
</div>
|
|
</div>
|