From 0277b05fefc81ce9a00e6867c355318f11845874 Mon Sep 17 00:00:00 2001 From: Jose Olarte III Date: Fri, 8 Aug 2025 18:21:00 +0800 Subject: [PATCH] Fix: offer validation prematurely closes dialog - Transferred form validation error handling to an earlier step - Added validation for negative input (similar to gifting forms) - Switched amount input to component version for consistency --- src/components/OfferDialog.vue | 141 +++++++++++++-------------------- 1 file changed, 53 insertions(+), 88 deletions(-) diff --git a/src/components/OfferDialog.vue b/src/components/OfferDialog.vue index d29972a4..b8b8093f 100644 --- a/src/components/OfferDialog.vue +++ b/src/components/OfferDialog.vue @@ -15,26 +15,25 @@ Raymer */ class="block w-full rounded border border-slate-400 mb-2 px-3 py-2" placeholder="Description of what is offered" /> -
- - {{ libsUtil.UNIT_SHORT[amountUnitCode] }} - -
- -
- + -
- -
+ +
@@ -73,10 +72,15 @@ import { NOTIFY_OFFER_CREATION_ERROR, NOTIFY_OFFER_SUCCESS, NOTIFY_OFFER_SUBMISSION_ERROR, + NOTIFY_OFFER_ERROR_NEGATIVE_AMOUNT, } from "@/constants/notifications"; +import AmountInput from "./AmountInput.vue"; @Component({ mixins: [PlatformServiceMixin], + components: { + AmountInput, + }, }) export default class OfferDialog extends Vue { @Prop projectId?: string; @@ -122,35 +126,10 @@ export default class OfferDialog extends Vue { } /** - * CSS classes for unit code selector and increment/decrement buttons - * Reduces template complexity for repeated border and styling patterns - */ - get controlButtonClasses(): string { - return "border border-r-0 border-slate-400 bg-slate-200 px-4 py-2"; - } - - /** - * CSS classes for unit code display span - * Reduces template complexity for unit code button styling + * Computed property to get unit options for the select dropdown */ - get unitCodeDisplayClasses(): string { - return "rounded-l border border-r-0 border-slate-400 bg-slate-200 w-1/3 text-center text-blue-500 px-2 py-2"; - } - - /** - * CSS classes for amount input field - * Reduces template complexity for input styling - */ - get amountInputClasses(): string { - return "w-full border border-r-0 border-slate-400 px-2 py-2 text-center"; - } - - /** - * CSS classes for the right-most increment button - * Reduces template complexity for border styling - */ - get incrementButtonClasses(): string { - return "rounded-r border border-slate-400 bg-slate-200 px-4 py-2"; + get unitOptions() { + return this.libsUtil.UNIT_SHORT; } /** @@ -173,13 +152,7 @@ export default class OfferDialog extends Vue { }; } - /** - * Whether the decrement button should be visible - * Encapsulates conditional logic from template - */ - get showDecrementButton(): boolean { - return this.amountInput !== "0"; - } + // ================================================= // COMPONENT METHODS @@ -226,30 +199,14 @@ export default class OfferDialog extends Vue { this.visible = false; } - /** - * Cycle through available unit codes - */ - changeUnitCode() { - const units = Object.keys(this.libsUtil.UNIT_SHORT); - const index = units.indexOf(this.amountUnitCode); - this.amountUnitCode = units[(index + 1) % units.length]; - } - /** - * Increment the amount input - */ - increment() { - this.amountInput = `${(parseFloat(this.amountInput) || 0) + 1}`; - } /** - * Decrement the amount input + * Handle amount updates from AmountInput component + * @param value - New amount value */ - decrement() { - this.amountInput = `${Math.max( - 0, - (parseFloat(this.amountInput) || 1) - 1, - )}`; + handleAmountUpdate(value: number) { + this.amountInput = value.toString(); } /** @@ -273,6 +230,28 @@ export default class OfferDialog extends Vue { * Confirm and submit the offer */ async confirm() { + if (!this.activeDid) { + this.notify.error(NOTIFY_OFFER_IDENTITY_REQUIRED.message, TIMEOUTS.LONG); + return; + } + + if (parseFloat(this.amountInput) < 0) { + this.notify.error( + NOTIFY_OFFER_ERROR_NEGATIVE_AMOUNT.message, + TIMEOUTS.SHORT, + ); + return; + } + + if (!this.description && !parseFloat(this.amountInput)) { + const message = NOTIFY_OFFER_DESCRIPTION_REQUIRED.message.replace( + "{unit}", + this.libsUtil.UNIT_LONG[this.amountUnitCode], + ); + this.notify.error(message, TIMEOUTS.SHORT); + return; + } + this.close(); this.notify.toast(NOTIFY_OFFER_RECORDING.text, undefined, TIMEOUTS.BRIEF); @@ -301,20 +280,6 @@ export default class OfferDialog extends Vue { unitCode: string = "HUR", expirationDateInput?: string, ) { - if (!this.activeDid) { - this.notify.error(NOTIFY_OFFER_IDENTITY_REQUIRED.message, TIMEOUTS.LONG); - return; - } - - if (!description && !amount) { - const message = NOTIFY_OFFER_DESCRIPTION_REQUIRED.message.replace( - "{unit}", - this.libsUtil.UNIT_LONG[unitCode], - ); - this.notify.error(message, TIMEOUTS.MODAL); - return; - } - try { const result = await createAndSubmitOffer( this.axios, @@ -363,7 +328,7 @@ export default class OfferDialog extends Vue { display: flex; justify-content: center; align-items: center; - z-index: 1000; + z-index: 50; } .dialog {