Fix create listing publish flow

This commit is contained in:
fatihalp 2026-03-08 16:45:42 +03:00
parent 6fde32cc8b
commit 46b70a91f7
2 changed files with 91 additions and 6 deletions

View File

@ -29,6 +29,7 @@ class PanelQuickListingForm extends Component
private const TOTAL_STEPS = 5;
private const DRAFT_SESSION_KEY = 'panel_quick_listing_draft';
private const OTHER_CITY_ID = -1;
public array $photos = [];
public array $videos = [];
@ -57,6 +58,7 @@ class PanelQuickListingForm extends Component
public ?int $selectedCityId = null;
public bool $isPublishing = false;
public bool $shouldPersistDraft = true;
public ?string $publishError = null;
public function mount(): void
{
@ -117,11 +119,13 @@ class PanelQuickListingForm extends Component
public function goToStep(int $step): void
{
$this->publishError = null;
$this->currentStep = max(1, min(self::TOTAL_STEPS, $step));
}
public function goToCategoryStep(): void
{
$this->publishError = null;
$this->validatePhotos();
$this->validateVideos();
$this->currentStep = 2;
@ -133,12 +137,14 @@ class PanelQuickListingForm extends Component
public function goToDetailsStep(): void
{
$this->publishError = null;
$this->validateCategoryStep();
$this->currentStep = 3;
}
public function goToFeaturesStep(): void
{
$this->publishError = null;
$this->validateCategoryStep();
$this->validateDetailsStep();
$this->currentStep = 4;
@ -146,6 +152,7 @@ class PanelQuickListingForm extends Component
public function goToPreviewStep(): void
{
$this->publishError = null;
$this->validateCategoryStep();
$this->validateDetailsStep();
$this->validateCustomFieldsStep();
@ -199,6 +206,7 @@ class PanelQuickListingForm extends Component
return;
}
$this->publishError = null;
$this->selectedCategoryId = $categoryId;
$this->loadListingCustomFields();
}
@ -210,6 +218,8 @@ class PanelQuickListingForm extends Component
}
$this->isPublishing = true;
$this->publishError = null;
$this->resetErrorBag();
try {
$this->validatePhotos();
@ -221,11 +231,13 @@ class PanelQuickListingForm extends Component
$listing = $this->createListing();
} catch (ValidationException $exception) {
$this->isPublishing = false;
$this->handlePublishValidationFailure($exception);
throw $exception;
return;
} catch (Throwable $exception) {
report($exception);
$this->isPublishing = false;
$this->publishError = 'The listing could not be created. Please try again.';
session()->flash('error', 'The listing could not be created. Please try again.');
return;
@ -361,10 +373,20 @@ class PanelQuickListingForm extends Component
return [];
}
return collect($this->cities)
$cities = collect($this->cities)
->where('country_id', $this->selectedCountryId)
->values()
->all();
if ($cities !== []) {
return $cities;
}
return [[
'id' => self::OTHER_CITY_ID,
'name' => 'Other',
'country_id' => $this->selectedCountryId,
]];
}
public function getSelectedCountryNameProperty(): ?string
@ -384,6 +406,10 @@ class PanelQuickListingForm extends Component
return null;
}
if ((int) $this->selectedCityId === self::OTHER_CITY_ID) {
return 'Other';
}
$city = collect($this->cities)->firstWhere('id', $this->selectedCityId);
return $city['name'] ?? null;
@ -772,6 +798,49 @@ class PanelQuickListingForm extends Component
return (string) config('media_storage.local_disk', MediaStorage::diskFromDriver(MediaStorage::DRIVER_LOCAL));
}
private function handlePublishValidationFailure(ValidationException $exception): void
{
$errors = $exception->errors();
foreach ($errors as $key => $messages) {
foreach ($messages as $message) {
$this->addError($key, $message);
}
}
$this->currentStep = $this->stepForValidationErrors(array_keys($errors));
$this->publishError = collect($errors)->flatten()->filter()->first() ?: 'Please fix the highlighted fields before publishing.';
}
private function stepForValidationErrors(array $keys): int
{
$normalizedKeys = collect($keys)->map(fn ($key) => (string) $key)->values();
if ($normalizedKeys->contains(fn ($key) => str_starts_with($key, 'photos') || str_starts_with($key, 'videos'))) {
return 1;
}
if ($normalizedKeys->contains('selectedCategoryId')) {
return 2;
}
if ($normalizedKeys->contains(fn ($key) => in_array($key, [
'listingTitle',
'price',
'description',
'selectedCountryId',
'selectedCityId',
], true))) {
return 3;
}
if ($normalizedKeys->contains(fn ($key) => str_starts_with($key, 'customFieldValues.'))) {
return 4;
}
return 5;
}
private function restoreDraft(): void
{
$draft = session()->get($this->draftSessionKey(), []);

View File

@ -1,5 +1,6 @@
@php
$maxPhotoCount = (int) config('quick-listing.max_photo_count', 20);
$visiblePhotoSlotCount = min($maxPhotoCount, 8);
$maxVideoCount = (int) config('video.max_listing_videos', 5);
$currency = \Modules\Listing\Support\ListingPanelHelper::defaultCurrency();
$displayPrice = is_numeric($price) ? number_format((float) $price, 0, ',', '.') : $price;
@ -737,6 +738,8 @@
.qc-publish-stack {
display: grid;
gap: 0.7rem;
position: relative;
z-index: 2;
}
.qc-button,
@ -841,6 +844,14 @@
</div>
<div class="qc-card">
@if ($publishError)
<div class="px-4 pt-4">
<div class="rounded-[18px] border border-rose-200 bg-rose-50 px-4 py-3 text-sm font-semibold text-rose-700">
{{ $publishError }}
</div>
</div>
@endif
@if ($currentStep === 1)
<div class="qc-body">
<div class="qc-stack">
@ -880,7 +891,7 @@
</div>
<div class="qc-photo-grid">
@for ($index = 0; $index < $maxPhotoCount; $index++)
@for ($index = 0; $index < $visiblePhotoSlotCount; $index++)
<div class="qc-photo-slot">
@if (isset($photos[$index]))
<img src="{{ $photos[$index]->temporaryUrl() }}" alt="Uploaded photo {{ $index + 1 }}">
@ -894,6 +905,10 @@
</div>
@endfor
</div>
@if (count($photos) > $visiblePhotoSlotCount)
<p class="qc-meta-copy mt-3">{{ count($photos) - $visiblePhotoSlotCount }} more photos added.</p>
@endif
</div>
@else
<div class="qc-empty">Add one cover photo to continue.</div>
@ -1322,10 +1337,11 @@
</div>
<div class="qc-panel">
<form class="qc-publish-stack" wire:submit.prevent="publishListing">
<div class="qc-publish-stack">
<button
type="submit"
type="button"
class="qc-button"
wire:click.prevent="publishListing"
wire:loading.attr="disabled"
wire:target="publishListing"
>
@ -1333,7 +1349,7 @@
<span wire:loading wire:target="publishListing">Publishing...</span>
</button>
<button type="button" class="qc-button-secondary" wire:click="goToStep(4)" wire:loading.attr="disabled" wire:target="publishListing">Back</button>
</form>
</div>
</div>
</div>
</div>