Improve live recordings UI, upload flow, and default Flux theme.
Refresh list status over Reverb with polling fallback, clarify queued vs processing, streamline upload empty states, and seed an admin login.
This commit is contained in:
@@ -1,25 +1,8 @@
|
||||
<div
|
||||
x-data="recordingsIndex(@js([
|
||||
'recordings' => $recordings->map(fn ($recording) => [
|
||||
'id' => $recording->id,
|
||||
'status' => $recording->transcription_status,
|
||||
'status_label' => $recording->transcriptionStatusLabel(),
|
||||
'progress' => $recording->transcription_progress,
|
||||
'percent' => $recording->transcription_percent,
|
||||
'is_active' => $recording->isTranscribing(),
|
||||
'word_count' => $recording->word_count,
|
||||
'word_count_display' => $recording->word_count > 0
|
||||
? number_format($recording->word_count)
|
||||
: '—',
|
||||
'badge_color' => match ($recording->transcription_status) {
|
||||
'done' => 'teal',
|
||||
'processing', 'pending' => 'amber',
|
||||
'failed' => 'red',
|
||||
default => 'zinc',
|
||||
},
|
||||
])->values(),
|
||||
'pendingCount' => $pendingCount,
|
||||
]))"
|
||||
@if ($hasActiveTranscriptions)
|
||||
wire:poll.2s.visible
|
||||
@endif
|
||||
x-data="recordingsIndex()"
|
||||
x-init="
|
||||
start();
|
||||
return () => destroy();
|
||||
@@ -39,34 +22,64 @@
|
||||
class="min-w-[16rem]"
|
||||
/>
|
||||
</div>
|
||||
<div x-show="pendingCount > 0" x-cloak>
|
||||
<flux:button
|
||||
type="button"
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
wire:click="queuePending"
|
||||
>
|
||||
Queue <span x-text="pendingCount"></span> pending
|
||||
<span x-text="pendingCount === 1 ? 'transcription' : 'transcriptions'"></span>
|
||||
</flux:button>
|
||||
<div class="flex flex-wrap items-center justify-end gap-2">
|
||||
@if ($pendingCount > 0)
|
||||
<flux:button
|
||||
type="button"
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
wire:click="queuePending"
|
||||
>
|
||||
Queue {{ $pendingCount }} pending
|
||||
{{ $pendingCount === 1 ? 'transcription' : 'transcriptions' }}
|
||||
</flux:button>
|
||||
@endif
|
||||
|
||||
@if ($totalCount > 0)
|
||||
<flux:modal.trigger name="delete-all-recordings">
|
||||
<flux:button type="button" variant="danger" size="sm">
|
||||
Delete all
|
||||
</flux:button>
|
||||
</flux:modal.trigger>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if ($totalCount > 0)
|
||||
<flux:modal name="delete-all-recordings" class="max-w-md">
|
||||
<div class="space-y-6">
|
||||
<div>
|
||||
<flux:heading size="lg">Delete all recordings?</flux:heading>
|
||||
<flux:text class="mt-2">
|
||||
This permanently removes
|
||||
{{ $totalCount === 1 ? 'your 1 recording' : "all {$totalCount} recordings" }}
|
||||
and their audio files. This cannot be undone.
|
||||
</flux:text>
|
||||
</div>
|
||||
<div class="flex justify-end gap-2">
|
||||
<flux:modal.close>
|
||||
<flux:button variant="ghost">Cancel</flux:button>
|
||||
</flux:modal.close>
|
||||
<flux:button type="button" variant="danger" wire:click="deleteAll">
|
||||
Delete all
|
||||
</flux:button>
|
||||
</div>
|
||||
</div>
|
||||
</flux:modal>
|
||||
@endif
|
||||
|
||||
@if ($recordings->isEmpty())
|
||||
<flux:card class="border-dashed py-16 text-center">
|
||||
@if (filled($search))
|
||||
@if (filled($search))
|
||||
<flux:card class="border-dashed py-16 text-center">
|
||||
<flux:text>No recordings match “{{ $search }}”.</flux:text>
|
||||
<div class="mt-4">
|
||||
<flux:button variant="ghost" wire:click="$set('search', '')">Clear search</flux:button>
|
||||
</div>
|
||||
@else
|
||||
<flux:text>No recordings yet.</flux:text>
|
||||
<div class="mt-4">
|
||||
<flux:link href="{{ route('recordings.create') }}" wire:navigate>Upload your first MP3</flux:link>
|
||||
</div>
|
||||
@endif
|
||||
</flux:card>
|
||||
</flux:card>
|
||||
@else
|
||||
<livewire:upload-recordings :show-cancel="false" />
|
||||
@endif
|
||||
@else
|
||||
<audio
|
||||
x-ref="player"
|
||||
@@ -90,7 +103,7 @@
|
||||
|
||||
<flux:table.rows>
|
||||
@foreach ($recordings as $recording)
|
||||
<flux:table.row wire:key="recording-{{ $recording->id }}">
|
||||
<flux:table.row wire:key="recording-{{ $recording->id }}-{{ $recording->transcription_status }}-{{ $recording->transcription_percent }}">
|
||||
<flux:table.cell>
|
||||
<flux:button
|
||||
type="button"
|
||||
@@ -127,10 +140,7 @@
|
||||
</flux:table.cell>
|
||||
<flux:table.cell>{{ $recording->duration_formatted }}</flux:table.cell>
|
||||
<flux:table.cell>
|
||||
<span
|
||||
class="tabular-nums"
|
||||
x-text="row({{ $recording->id }}).word_count_display"
|
||||
>
|
||||
<span class="tabular-nums">
|
||||
{{ $recording->word_count > 0 ? number_format($recording->word_count) : '—' }}
|
||||
</span>
|
||||
</flux:table.cell>
|
||||
@@ -138,17 +148,25 @@
|
||||
<x-transcription-status-badge
|
||||
:status="$recording->transcription_status"
|
||||
:label="$recording->transcriptionStatusLabel()"
|
||||
:alpine-row="'row('.$recording->id.')'"
|
||||
/>
|
||||
<div
|
||||
class="mt-1 max-w-[14rem] truncate text-xs text-amber-700 dark:text-amber-300"
|
||||
x-show="row({{ $recording->id }}).is_active && row({{ $recording->id }}).progress"
|
||||
x-cloak
|
||||
:title="row({{ $recording->id }}).progress"
|
||||
>
|
||||
<span x-text="row({{ $recording->id }}).percent ? (row({{ $recording->id }}).percent + '% · ') : ''"></span>
|
||||
<span x-text="row({{ $recording->id }}).progress"></span>
|
||||
</div>
|
||||
@if ($recording->transcription_status === 'pending' && filled($recording->transcription_progress))
|
||||
<div
|
||||
class="mt-1 max-w-[14rem] truncate text-xs text-zinc-500 dark:text-zinc-400"
|
||||
title="{{ $recording->transcription_progress }}"
|
||||
>
|
||||
{{ $recording->transcription_progress }}
|
||||
</div>
|
||||
@elseif ($recording->transcription_status === 'processing' && filled($recording->transcription_progress))
|
||||
<div
|
||||
class="mt-1 max-w-[14rem] truncate text-xs text-amber-700 dark:text-amber-300"
|
||||
title="{{ $recording->transcription_progress }}"
|
||||
>
|
||||
@if ($recording->transcription_percent)
|
||||
{{ $recording->transcription_percent }}% ·
|
||||
@endif
|
||||
{{ $recording->transcription_progress }}
|
||||
</div>
|
||||
@endif
|
||||
</flux:table.cell>
|
||||
<flux:table.cell>
|
||||
{{ $recording->created_at?->format('Y-m-d H:i') }}
|
||||
|
||||
Reference in New Issue
Block a user