clusev/resources/views/livewire/files/index.blade.php

131 lines
6.6 KiB
PHP

@php
$dirs = collect($entries)->where('type', 'dir')->count();
$files = collect($entries)->where('type', 'file')->count();
// Human-readable byte sizes for the mock listing (real values come from SFTP later).
$fmtSize = function (?int $bytes): string {
if ($bytes === null) {
return '—';
}
$units = ['B', 'KB', 'MB', 'GB', 'TB'];
$i = 0;
$val = (float) $bytes;
while ($val >= 1024 && $i < count($units) - 1) {
$val /= 1024;
$i++;
}
return ($i === 0 ? (int) $val : number_format($val, 1)).' '.$units[$i];
};
@endphp
<div class="space-y-4">
{{-- Header --}}
<div class="flex flex-wrap items-end justify-between gap-3">
<div>
<p class="font-mono text-[11px] uppercase tracking-[0.2em] text-accent-text">Dateien</p>
<h2 class="mt-0.5 font-display text-xl font-semibold text-ink sm:text-2xl">Dateien</h2>
</div>
<x-status-pill status="online">SFTP verbunden</x-status-pill>
</div>
{{-- Breadcrumb / path --}}
<x-panel :padded="false">
<div class="flex flex-wrap items-center gap-x-1 gap-y-1.5 px-4 py-3 sm:px-5">
<x-icon name="folder" class="mr-1 h-4 w-4 shrink-0 text-ink-3" />
@foreach ($this->crumbs as $crumb)
@if (! $loop->first)
<span class="font-mono text-xs text-ink-4">/</span>
@endif
{{-- Segments are plain mono spans for now; wire to wire:click="cd(...)" with the SFTP layer. --}}
<span @class([
'font-mono text-xs',
'text-ink-3' => $loop->last,
'text-accent-text hover:text-accent' => ! $loop->last,
])>{{ $crumb['label'] }}</span>
@endforeach
</div>
</x-panel>
{{-- Listing --}}
<x-panel :title="$path" :subtitle="$dirs . ' Ordner · ' . $files . ' Dateien'" :padded="false">
<x-slot:actions>
<button type="button" class="inline-flex min-h-11 items-center gap-1.5 rounded-md border border-accent/25 bg-accent/10 px-3 py-1.5 text-xs text-accent-text hover:bg-accent/15">
<x-icon name="plus" class="h-3.5 w-3.5" /> Hochladen
</button>
</x-slot:actions>
{{-- Column header (desktop only) --}}
<div class="hidden border-b border-line px-4 py-2 sm:px-5 lg:grid lg:grid-cols-[minmax(0,1fr)_8rem_6rem_11rem_auto] lg:items-center lg:gap-4">
<span class="font-mono text-[10px] uppercase tracking-wider text-ink-4">Name</span>
<span class="font-mono text-[10px] uppercase tracking-wider text-ink-4">Rechte</span>
<span class="text-right font-mono text-[10px] uppercase tracking-wider text-ink-4">Größe</span>
<span class="font-mono text-[10px] uppercase tracking-wider text-ink-4">Geändert</span>
<span class="sr-only">Aktionen</span>
</div>
<div class="divide-y divide-line">
@foreach ($entries as $e)
@php $isDir = $e['type'] === 'dir'; @endphp
<div class="group grid grid-cols-1 gap-x-4 gap-y-2 px-4 py-3 transition-colors hover:bg-raised sm:px-5 lg:grid-cols-[minmax(0,1fr)_8rem_6rem_11rem_auto] lg:items-center">
{{-- Name + icon (directories look clickable) --}}
<div class="flex min-w-0 items-center gap-3">
<span @class([
'grid h-8 w-8 shrink-0 place-items-center rounded-sm',
'bg-accent/10 text-accent-text' => $isDir,
'bg-raised text-ink-3' => ! $isDir,
])>
<x-icon :name="$isDir ? 'folder' : 'audit'" class="h-4 w-4" />
</span>
@if ($isDir)
{{-- Plain element for now; wire to wire:click="cd(...)" with the SFTP layer. --}}
<button type="button" class="min-w-0 flex-1 text-left">
<span class="truncate font-mono text-sm text-ink group-hover:text-accent-text">{{ $e['name'] }}/</span>
</button>
@else
<p class="min-w-0 flex-1 truncate font-mono text-sm text-ink-2">{{ $e['name'] }}</p>
@endif
</div>
{{-- Permissions (hidden on mobile; shown inline below name on tablet+) --}}
<p class="hidden font-mono text-xs text-ink-3 lg:block">{{ $e['perms'] }}</p>
{{-- Size (hidden on mobile) --}}
<p class="hidden font-mono text-xs text-ink-3 sm:block lg:text-right">{{ $fmtSize($e['size']) }}</p>
{{-- Modified --}}
<p class="hidden font-mono text-xs text-ink-3 sm:block">{{ $e['modified'] }}</p>
{{-- Compact meta line for mobile (perms · size · modified) --}}
<p class="flex flex-wrap items-center gap-x-2 font-mono text-[11px] text-ink-4 sm:hidden">
<span>{{ $e['perms'] }}</span>
<span>·</span>
<span>{{ $fmtSize($e['size']) }}</span>
<span>·</span>
<span>{{ $e['modified'] }}</span>
</p>
{{-- Row actions --}}
<div class="flex shrink-0 items-center gap-1 lg:justify-end">
@unless ($isDir)
{{-- R5: wire to wire-elements/modal --}}
<button type="button" class="inline-flex min-h-11 items-center rounded-sm px-2.5 py-1 font-mono text-[11px] text-ink-2 hover:bg-line hover:text-ink">
Download
</button>
@endunless
{{-- R5: wire to wire-elements/modal --}}
<button type="button" class="inline-flex min-h-11 items-center rounded-sm px-2.5 py-1 font-mono text-[11px] text-ink-2 hover:bg-line hover:text-ink">
Bearbeiten
</button>
{{-- R5: destructive wire-elements/modal confirm + audit --}}
<button type="button" wire:click="confirmDelete('{{ $e['name'] }}')" class="inline-flex min-h-11 items-center rounded-sm px-2.5 py-1 font-mono text-[11px] text-offline hover:bg-offline/10">
Löschen
</button>
</div>
</div>
@endforeach
</div>
</x-panel>
</div>