forked from trent_larson/crowd-funder-for-time-pwa
Merge branch 'offer-validation-logic' into build-improvement
This commit is contained in:
@@ -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"
|
||||
/>
|
||||
<div class="flex flex-row mt-2">
|
||||
<span :class="unitCodeDisplayClasses" @click="changeUnitCode()">
|
||||
{{ libsUtil.UNIT_SHORT[amountUnitCode] }}
|
||||
</span>
|
||||
<div
|
||||
v-if="showDecrementButton"
|
||||
:class="controlButtonClasses"
|
||||
@click="decrement()"
|
||||
>
|
||||
<font-awesome icon="chevron-left" />
|
||||
</div>
|
||||
<input
|
||||
v-model="amountInput"
|
||||
<div class="flex mb-4">
|
||||
<AmountInput
|
||||
:value="parseFloat(amountInput) || 0"
|
||||
:onUpdateValue="handleAmountUpdate"
|
||||
data-testId="inputOfferAmount"
|
||||
type="number"
|
||||
:class="amountInputClasses"
|
||||
/>
|
||||
<div :class="incrementButtonClasses" @click="increment()">
|
||||
<font-awesome icon="chevron-right" />
|
||||
</div>
|
||||
|
||||
<select
|
||||
v-model="amountUnitCode"
|
||||
class="flex-1 rounded border border-slate-400 ms-2 px-3 py-2"
|
||||
>
|
||||
<option
|
||||
v-for="(displayName, code) in unitOptions"
|
||||
:key="code"
|
||||
:value="code"
|
||||
>
|
||||
{{ displayName }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="mt-4 flex justify-center">
|
||||
<span>
|
||||
@@ -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
|
||||
* Computed property to get unit options for the select dropdown
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
* Handle amount updates from AmountInput component
|
||||
* @param value - New amount value
|
||||
*/
|
||||
increment() {
|
||||
this.amountInput = `${(parseFloat(this.amountInput) || 0) + 1}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Decrement the amount input
|
||||
*/
|
||||
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 {
|
||||
|
||||
Reference in New Issue
Block a user