Compare commits
No commits in common. "9b48ba73e2e1c0a141d2e102915e0a1c3e8492b5" and "d9de0fdd73a560d960a572c66b37cb780519ad96" have entirely different histories.
9b48ba73e2
...
d9de0fdd73
1 changed files with 153 additions and 221 deletions
|
|
@ -428,34 +428,13 @@ watch(
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const { resetForm } = form;
|
const { resetForm, meta } = form;
|
||||||
|
const isFormValid = computed(
|
||||||
/** Field name -> what the organiser calls it, for the invalid-submit toast. */
|
() =>
|
||||||
const FIELD_LABELS: Record<string, string> = {
|
meta.value.valid &&
|
||||||
name: "Title",
|
!hasPromoErrors(promoErrors.value) &&
|
||||||
info: "Description",
|
!hasWaveErrors.value,
|
||||||
event_start_date: "Start date",
|
);
|
||||||
event_start_time: "Start time",
|
|
||||||
event_end_date: "End date",
|
|
||||||
event_end_time: "End time",
|
|
||||||
location: "Location",
|
|
||||||
currency: "Price currency",
|
|
||||||
payment_methods: "Payment methods",
|
|
||||||
fiat_currency: "Fiat currency",
|
|
||||||
amount_tickets: "Tickets",
|
|
||||||
price_per_ticket: "Price",
|
|
||||||
notification_subject: "Subject",
|
|
||||||
notification_body: "Body",
|
|
||||||
};
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Open whichever collapsible section holds a problem, so the reason is on
|
|
||||||
* screen rather than hidden behind a closed panel.
|
|
||||||
*/
|
|
||||||
function revealSectionFor(field: string) {
|
|
||||||
if (field === "promo_codes") promoOpen.value = true;
|
|
||||||
if (field === "ticket_waves") wavesOpen.value = true;
|
|
||||||
}
|
|
||||||
const isLoading = ref(false);
|
const isLoading = ref(false);
|
||||||
|
|
||||||
const today = computed(() => format(new Date(), "yyyy-MM-dd"));
|
const today = computed(() => format(new Date(), "yyyy-MM-dd"));
|
||||||
|
|
@ -469,22 +448,8 @@ function toggleCategory(cat: string) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const onSubmit = form.handleSubmit(
|
const onSubmit = form.handleSubmit(async (formValues) => {
|
||||||
async (formValues) => {
|
if (!isFormValid.value) return;
|
||||||
// Promo codes and ticket waves are not part of the Zod schema, so
|
|
||||||
// vee-validate cannot block on them. Check here and OPEN the section
|
|
||||||
// that holds the problem — both editors live inside collapsibles, and
|
|
||||||
// an error rendered inside a closed one is invisible.
|
|
||||||
if (hasWaveErrors.value) {
|
|
||||||
revealSectionFor("ticket_waves");
|
|
||||||
toastService.error("Check the ticket waves below");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (hasPromoErrors(promoErrors.value)) {
|
|
||||||
revealSectionFor("promo_codes");
|
|
||||||
toastService.error("Check the promo codes below");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!paymentService) {
|
if (!paymentService) {
|
||||||
toastService.error("Payment service not available");
|
toastService.error("Payment service not available");
|
||||||
|
|
@ -503,10 +468,7 @@ const onSubmit = form.handleSubmit(
|
||||||
const eventData: CreateEventRequest = {
|
const eventData: CreateEventRequest = {
|
||||||
name: formValues.name,
|
name: formValues.name,
|
||||||
event_start_date: withLocalTzOffset(
|
event_start_date: withLocalTzOffset(
|
||||||
foldDateTime(
|
foldDateTime(formValues.event_start_date, formValues.event_start_time),
|
||||||
formValues.event_start_date,
|
|
||||||
formValues.event_start_time,
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
if (!isEditMode.value) {
|
if (!isEditMode.value) {
|
||||||
|
|
@ -524,9 +486,7 @@ const onSubmit = form.handleSubmit(
|
||||||
}
|
}
|
||||||
if (formValues.location) eventData.location = formValues.location;
|
if (formValues.location) eventData.location = formValues.location;
|
||||||
if (bannerImages.value.length > 0) {
|
if (bannerImages.value.length > 0) {
|
||||||
eventData.banner = imageService.getImageUrl(
|
eventData.banner = imageService.getImageUrl(bannerImages.value[0].alias);
|
||||||
bannerImages.value[0].alias,
|
|
||||||
);
|
|
||||||
} else if (isEditMode.value) {
|
} else if (isEditMode.value) {
|
||||||
// User cleared the banner during edit — propagate the null so the
|
// User cleared the banner during edit — propagate the null so the
|
||||||
// backend wipes the field instead of keeping the old image.
|
// backend wipes the field instead of keeping the old image.
|
||||||
|
|
@ -641,28 +601,7 @@ const onSubmit = form.handleSubmit(
|
||||||
} finally {
|
} finally {
|
||||||
isLoading.value = false;
|
isLoading.value = false;
|
||||||
}
|
}
|
||||||
},
|
});
|
||||||
// vee-validate blocks the submit when the schema fails. Say WHY: a field
|
|
||||||
// whose FormMessage sits inside a closed section — or is not rendered at
|
|
||||||
// all — otherwise leaves a dead button and no explanation, which is the
|
|
||||||
// dead end disabling the button used to create.
|
|
||||||
({ errors }) => {
|
|
||||||
const fields = Object.keys(errors);
|
|
||||||
fields.forEach(revealSectionFor);
|
|
||||||
const named = fields.map((f) => FIELD_LABELS[f] ?? f);
|
|
||||||
toastService.error(
|
|
||||||
named.length
|
|
||||||
? `Check ${named.join(", ")}`
|
|
||||||
: "Some details still need attention",
|
|
||||||
);
|
|
||||||
const first = fields[0];
|
|
||||||
if (first) {
|
|
||||||
document
|
|
||||||
.querySelector(`[name="${first}"], #${CSS.escape(first)}`)
|
|
||||||
?.scrollIntoView({ behavior: "smooth", block: "center" });
|
|
||||||
}
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
const handleOpenChange = (open: boolean) => {
|
const handleOpenChange = (open: boolean) => {
|
||||||
if (!open && !isLoading.value) {
|
if (!open && !isLoading.value) {
|
||||||
|
|
@ -1237,17 +1176,10 @@ const handleOpenChange = (open: boolean) => {
|
||||||
>
|
>
|
||||||
Cancel
|
Cancel
|
||||||
</Button>
|
</Button>
|
||||||
<!-- Disabled only while a submit is genuinely in flight, NOT on
|
|
||||||
validity. vee-validate's `meta.valid` is false before the form
|
|
||||||
has ever validated, counts disabled and conditionally rendered
|
|
||||||
fields against you, and is documented to go stale
|
|
||||||
(logaretm/vee-validate#4630). Gating on it produced a dead
|
|
||||||
button with no visible reason; let the click through and the
|
|
||||||
invalid handler says what is wrong. -->
|
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
class="w-full sm:w-auto"
|
class="w-full sm:w-auto"
|
||||||
:disabled="isLoading"
|
:disabled="isLoading || !isFormValid"
|
||||||
>
|
>
|
||||||
<Loader2 v-if="isLoading" class="w-4 h-4 mr-2 animate-spin" />
|
<Loader2 v-if="isLoading" class="w-4 h-4 mr-2 animate-spin" />
|
||||||
{{
|
{{
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue