Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions app/Livewire/Dashboard/DashboardConverter.php
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,25 @@ public function selectTargetFormat(string $targetFormat): void
$this->step = 'settings';
}

public function continueFromSettings(): void
{
if ($this->currentFile === null || $this->selectedTargetFormat === null) {
$this->goToSettingsStep();

return;
}

if (! $this->validateSettings()) {
$this->step = 'settings';

return;
}

// Phase 8 stops at a convert placeholder. CreateConversionJobAction and
// the real conversion flow arrive in Phase 9.
$this->step = 'convert';
}

public function validateSettings(): bool
{
$this->resetErrorBag();
Expand Down
27 changes: 26 additions & 1 deletion resources/views/livewire/dashboard/dashboard-converter.blade.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
<div wire:init="ensureValidStep">
<x-card variant="elevated">
<x-stepper :steps="['File', 'Format', 'Settings', 'Convert']" :active="$step === 'upload' ? 'File' : 'Format'" class="mb-6" />
<x-stepper :steps="['File', 'Format', 'Settings', 'Convert']" :active="match ($step) {
'format' => 'Format',
'settings' => 'Settings',
'convert' => 'Convert',
default => 'File',
}" class="mb-6" />
@if ($step === 'upload' && $this->currentFile)
@php($file = $this->currentFile)
<div class="flex flex-col gap-4">
Expand Down Expand Up @@ -161,6 +166,26 @@ class="flex items-start gap-3 rounded-[var(--ca-radius-md)] border border-[var(-
</div>

@include('livewire.dashboard.dashboard-converter.partials.dynamic-options-form')

<div class="flex justify-end">
<x-button variant="primary" size="sm" wire:click="continueFromSettings">Continue</x-button>
</div>
</div>
@endif

@if ($step === 'convert' && $this->currentFile)
@php($file = $this->currentFile)
<div class="flex flex-col gap-4">
<div>
<x-button variant="ghost" size="sm" wire:click="goToSettingsStep">← Back</x-button>
</div>

<div class="rounded-[var(--ca-radius-md)] border border-dashed border-[var(--ca-border)] bg-[var(--ca-surface-muted)]/40 px-6 py-8 text-center">
<p class="text-base font-semibold text-[var(--ca-text)]">
Ready to convert {{ strtoupper($file->extension) }} to {{ strtoupper($selectedTargetFormat) }}
</p>
<p class="mt-1 text-sm text-[var(--ca-muted)]">Conversion will be available in Phase 9.</p>
</div>
</div>
@endif
</x-card>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,47 @@
->assertHasErrors(['options.bogus']);
});

it('moves to the convert step when settings are valid', function () {
$user = User::factory()->create();
$file = FileRecord::factory()->for($user)->create(['extension' => 'png']);

Livewire::actingAs($user)
->test(DashboardConverter::class)
->set('currentFileId', $file->id)
->call('selectTargetFormat', 'jpg')
->call('continueFromSettings')
->assertSet('step', 'convert')
->assertHasNoErrors();
});

it('stays on the settings step when settings are invalid', function () {
$user = User::factory()->create();
$file = FileRecord::factory()->for($user)->create(['extension' => 'png']);

Livewire::actingAs($user)
->test(DashboardConverter::class)
->set('currentFileId', $file->id)
->call('selectTargetFormat', 'jpg')
->set('options.quality', 'bad')
->call('continueFromSettings')
->assertSet('step', 'settings')
->assertHasErrors(['options.quality']);
});

it('does not create any extra records when continuing to the convert step', function () {
$user = User::factory()->create();
$file = FileRecord::factory()->for($user)->create(['extension' => 'png']);

Livewire::actingAs($user)
->test(DashboardConverter::class)
->set('currentFileId', $file->id)
->call('selectTargetFormat', 'jpg')
->call('continueFromSettings')
->assertSet('step', 'convert');

expect(FileRecord::query()->where('user_id', $user->id)->count())->toBe(1);
});

it('does not create any extra records during settings validation', function () {
$user = User::factory()->create();
$file = FileRecord::factory()->for($user)->create(['extension' => 'png']);
Expand Down