forked from jsnbuchanan/crowd-funder-for-time-pwa
Merge branch 'master' into contact-gifting-current-user
This commit is contained in:
@@ -1,13 +1,19 @@
|
||||
<template>
|
||||
<div v-if="visible" class="dialog-overlay">
|
||||
<div class="dialog">
|
||||
<div
|
||||
class="dialog"
|
||||
data-testid="gifted-dialog"
|
||||
:data-recipient-entity-type="recipientEntityType"
|
||||
>
|
||||
<!-- Step 1: Entity Selection -->
|
||||
<EntitySelectionStep
|
||||
v-show="firstStep"
|
||||
:step-type="stepType"
|
||||
:giver-entity-type="giverEntityType"
|
||||
:recipient-entity-type="recipientEntityType"
|
||||
:show-projects="showProjects"
|
||||
:show-projects="
|
||||
giverEntityType === 'project' || recipientEntityType === 'project'
|
||||
"
|
||||
:is-from-project-view="isFromProjectView"
|
||||
:projects="projects"
|
||||
:all-contacts="allContacts"
|
||||
@@ -18,6 +24,10 @@
|
||||
:to-project-id="toProjectId"
|
||||
:giver="giver"
|
||||
:receiver="receiver"
|
||||
:description="description"
|
||||
:amount-input="amountInput"
|
||||
:unit-code="unitCode"
|
||||
:offer-id="offerId"
|
||||
:notify="$notify"
|
||||
:hide-show-all="hideShowAll"
|
||||
@entity-selected="handleEntitySelected"
|
||||
@@ -53,7 +63,7 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { Vue, Component, Prop, Watch } from "vue-facing-decorator";
|
||||
import { Vue, Component, Prop } from "vue-facing-decorator";
|
||||
|
||||
import {
|
||||
createAndSubmitGive,
|
||||
@@ -72,6 +82,12 @@ import GiftDetailsStep from "../components/GiftDetailsStep.vue";
|
||||
import { PlanData } from "../interfaces/records";
|
||||
import { PlatformServiceMixin } from "@/utils/PlatformServiceMixin";
|
||||
import { createNotifyHelpers, TIMEOUTS } from "@/utils/notify";
|
||||
import {
|
||||
NOTIFY_GIFT_ERROR_NEGATIVE_AMOUNT,
|
||||
NOTIFY_GIFT_ERROR_NO_DESCRIPTION,
|
||||
NOTIFY_GIFTED_DETAILS_NO_IDENTIFIER,
|
||||
NOTIFY_GIFTED_DETAILS_RECORDING_GIVE,
|
||||
} from "@/constants/notifications";
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
@@ -98,24 +114,13 @@ export default class GiftedDialog extends Vue {
|
||||
|
||||
@Prop() fromProjectId = "";
|
||||
@Prop() toProjectId = "";
|
||||
@Prop({ default: false }) showProjects = false;
|
||||
@Prop() isFromProjectView = false;
|
||||
@Prop({ default: false }) hideShowAll = false;
|
||||
|
||||
@Watch("showProjects")
|
||||
onShowProjectsChange() {
|
||||
this.updateEntityTypes();
|
||||
}
|
||||
|
||||
@Watch("fromProjectId")
|
||||
onFromProjectIdChange() {
|
||||
this.updateEntityTypes();
|
||||
}
|
||||
|
||||
@Watch("toProjectId")
|
||||
onToProjectIdChange() {
|
||||
this.updateEntityTypes();
|
||||
}
|
||||
@Prop({ default: "person" }) giverEntityType = "person" as
|
||||
| "person"
|
||||
| "project";
|
||||
@Prop({ default: "person" }) recipientEntityType = "person" as
|
||||
| "person"
|
||||
| "project";
|
||||
|
||||
activeDid = "";
|
||||
allContacts: Array<Contact> = [];
|
||||
@@ -124,20 +129,19 @@ export default class GiftedDialog extends Vue {
|
||||
|
||||
amountInput = "0";
|
||||
callbackOnSuccess?: (amount: number) => void = () => {};
|
||||
customTitle?: string;
|
||||
description = "";
|
||||
firstStep = true; // true = Step 1 (giver/recipient selection), false = Step 2 (amount/description)
|
||||
giver?: libsUtil.GiverReceiverInputInfo; // undefined means no identified giver agent
|
||||
offerId = "";
|
||||
projects: PlanData[] = [];
|
||||
prompt = "";
|
||||
receiver?: libsUtil.GiverReceiverInputInfo;
|
||||
stepType = "giver";
|
||||
unitCode = "HUR";
|
||||
visible = false;
|
||||
|
||||
libsUtil = libsUtil;
|
||||
|
||||
projects: PlanData[] = [];
|
||||
|
||||
didInfo = didInfo;
|
||||
|
||||
// Computed property to help debug template logic
|
||||
@@ -191,56 +195,27 @@ export default class GiftedDialog extends Vue {
|
||||
return false;
|
||||
}
|
||||
|
||||
stepType = "giver";
|
||||
giverEntityType = "person" as "person" | "project";
|
||||
recipientEntityType = "person" as "person" | "project";
|
||||
|
||||
updateEntityTypes() {
|
||||
// Reset and set entity types based on current context
|
||||
this.giverEntityType = "person";
|
||||
this.recipientEntityType = "person";
|
||||
|
||||
// Determine entity types based on current context
|
||||
if (this.showProjects) {
|
||||
// HomeView "Project" button or ProjectViewView "Given by This"
|
||||
this.giverEntityType = "project";
|
||||
this.recipientEntityType = "person";
|
||||
} else if (this.fromProjectId) {
|
||||
// ProjectViewView "Given by This" button (project is giver)
|
||||
this.giverEntityType = "project";
|
||||
this.recipientEntityType = "person";
|
||||
} else if (this.toProjectId) {
|
||||
// ProjectViewView "Given to This" button (project is recipient)
|
||||
this.giverEntityType = "person";
|
||||
this.recipientEntityType = "project";
|
||||
} else {
|
||||
// HomeView "Person" button
|
||||
this.giverEntityType = "person";
|
||||
this.recipientEntityType = "person";
|
||||
}
|
||||
}
|
||||
|
||||
async open(
|
||||
giver?: libsUtil.GiverReceiverInputInfo,
|
||||
receiver?: libsUtil.GiverReceiverInputInfo,
|
||||
offerId?: string,
|
||||
customTitle?: string,
|
||||
prompt?: string,
|
||||
description?: string,
|
||||
amountInput?: string,
|
||||
unitCode?: string,
|
||||
callbackOnSuccess: (amount: number) => void = () => {},
|
||||
) {
|
||||
this.customTitle = customTitle;
|
||||
this.giver = giver;
|
||||
this.prompt = prompt || "";
|
||||
this.receiver = receiver;
|
||||
this.amountInput = "0";
|
||||
this.callbackOnSuccess = callbackOnSuccess;
|
||||
this.offerId = offerId || "";
|
||||
this.prompt = prompt || "";
|
||||
this.description = description || "";
|
||||
this.amountInput = amountInput || "0";
|
||||
this.unitCode = unitCode || "HUR";
|
||||
this.callbackOnSuccess = callbackOnSuccess;
|
||||
this.firstStep = !giver;
|
||||
this.stepType = "giver";
|
||||
|
||||
// Update entity types based on current props
|
||||
this.updateEntityTypes();
|
||||
|
||||
try {
|
||||
const settings = await this.$settings();
|
||||
this.apiServer = settings.apiServer || "";
|
||||
@@ -320,23 +295,24 @@ export default class GiftedDialog extends Vue {
|
||||
async confirm() {
|
||||
if (!this.activeDid) {
|
||||
this.safeNotify.error(
|
||||
"You must select an identifier before you can record a give.",
|
||||
TIMEOUTS.STANDARD,
|
||||
NOTIFY_GIFTED_DETAILS_NO_IDENTIFIER.message,
|
||||
TIMEOUTS.SHORT,
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (parseFloat(this.amountInput) < 0) {
|
||||
this.safeNotify.error(
|
||||
"You may not send a negative number.",
|
||||
NOTIFY_GIFT_ERROR_NEGATIVE_AMOUNT.message,
|
||||
TIMEOUTS.SHORT,
|
||||
);
|
||||
return;
|
||||
}
|
||||
if (!this.description && !parseFloat(this.amountInput)) {
|
||||
this.safeNotify.error(
|
||||
`You must enter a description or some number of ${
|
||||
this.libsUtil.UNIT_LONG[this.unitCode]
|
||||
}.`,
|
||||
NOTIFY_GIFT_ERROR_NO_DESCRIPTION.message.replace(
|
||||
"{unit}",
|
||||
this.libsUtil.UNIT_SHORT[this.unitCode] || this.unitCode,
|
||||
),
|
||||
TIMEOUTS.SHORT,
|
||||
);
|
||||
return;
|
||||
@@ -352,7 +328,11 @@ export default class GiftedDialog extends Vue {
|
||||
}
|
||||
|
||||
this.close();
|
||||
this.safeNotify.toast("Recording the give...", undefined, TIMEOUTS.BRIEF);
|
||||
this.safeNotify.toast(
|
||||
NOTIFY_GIFTED_DETAILS_RECORDING_GIVE.message,
|
||||
undefined,
|
||||
TIMEOUTS.BRIEF,
|
||||
);
|
||||
// this is asynchronous, but we don't need to wait for it to complete
|
||||
await this.recordGive(
|
||||
(this.giver?.did as string) || null,
|
||||
@@ -479,10 +459,13 @@ export default class GiftedDialog extends Vue {
|
||||
name: contact.name || contact.did,
|
||||
};
|
||||
} else {
|
||||
this.giver = {
|
||||
did: "",
|
||||
name: "Unnamed",
|
||||
};
|
||||
// Only set to "Unnamed" if no giver is currently set
|
||||
if (!this.giver || !this.giver.did) {
|
||||
this.giver = {
|
||||
did: "",
|
||||
name: "Unnamed",
|
||||
};
|
||||
}
|
||||
}
|
||||
this.firstStep = false;
|
||||
}
|
||||
@@ -492,6 +475,10 @@ export default class GiftedDialog extends Vue {
|
||||
this.firstStep = true;
|
||||
}
|
||||
|
||||
moveToStep2() {
|
||||
this.firstStep = false;
|
||||
}
|
||||
|
||||
async loadProjects() {
|
||||
try {
|
||||
const response = await fetch(this.apiServer + "/api/v2/report/plans", {
|
||||
@@ -534,10 +521,13 @@ export default class GiftedDialog extends Vue {
|
||||
name: contact.name || contact.did,
|
||||
};
|
||||
} else {
|
||||
this.receiver = {
|
||||
did: "",
|
||||
name: "Unnamed",
|
||||
};
|
||||
// Only set to "Unnamed" if no receiver is currently set
|
||||
if (!this.receiver || !this.receiver.did) {
|
||||
this.receiver = {
|
||||
did: "",
|
||||
name: "Unnamed",
|
||||
};
|
||||
}
|
||||
}
|
||||
this.firstStep = false;
|
||||
}
|
||||
@@ -561,16 +551,13 @@ export default class GiftedDialog extends Vue {
|
||||
giverName: this.giver?.name,
|
||||
offerId: this.offerId,
|
||||
fulfillsProjectId:
|
||||
this.giverEntityType === "person" &&
|
||||
this.recipientEntityType === "project"
|
||||
? this.toProjectId
|
||||
: undefined,
|
||||
this.recipientEntityType === "project" ? this.toProjectId : undefined,
|
||||
providerProjectId:
|
||||
this.giverEntityType === "project" &&
|
||||
this.recipientEntityType === "person"
|
||||
this.giverEntityType === "project"
|
||||
? this.giver?.handleId
|
||||
: this.fromProjectId,
|
||||
recipientDid: this.receiver?.did,
|
||||
recipientDid:
|
||||
this.recipientEntityType === "person" ? this.receiver?.did : undefined,
|
||||
recipientName: this.receiver?.name,
|
||||
unitCode: this.unitCode,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user