diff --git a/src/components/EntitySelectionStep.vue b/src/components/EntitySelectionStep.vue
index c0c8bf92..185fb929 100644
--- a/src/components/EntitySelectionStep.vue
+++ b/src/components/EntitySelectionStep.vue
@@ -146,6 +146,10 @@ export default class EntitySelectionStep extends Vue {
@Prop({ default: "HUR" })
unitCode!: string;
+ /** Offer ID for context when fulfilling an offer */
+ @Prop({ default: "" })
+ offerId!: string;
+
/** Notification function from parent component */
@Prop()
notify?: (notification: NotificationIface, timeout?: number) => void;
@@ -242,6 +246,7 @@ export default class EntitySelectionStep extends Vue {
description: this.description,
amountInput: this.amountInput,
unitCode: this.unitCode,
+ offerId: this.offerId,
...(this.stepType === "giver"
? {
recipientProjectId: this.toProjectId || "",
diff --git a/src/components/GiftedDialog.vue b/src/components/GiftedDialog.vue
index 96538346..d44f0d73 100644
--- a/src/components/GiftedDialog.vue
+++ b/src/components/GiftedDialog.vue
@@ -21,6 +21,7 @@
:description="description"
:amount-input="amountInput"
:unit-code="unitCode"
+ :offer-id="offerId"
:notify="$notify"
@entity-selected="handleEntitySelected"
@cancel="cancel"
@@ -233,6 +234,7 @@ export default class GiftedDialog extends Vue {
this.giver = giver;
this.receiver = receiver;
this.offerId = offerId || "";
+ console.log("offerId", this.offerId);
this.prompt = prompt || "";
this.description = description || "";
this.amountInput = amountInput || "0";
diff --git a/src/views/ClaimView.vue b/src/views/ClaimView.vue
index be588b2c..4b7c3879 100644
--- a/src/views/ClaimView.vue
+++ b/src/views/ClaimView.vue
@@ -199,7 +199,14 @@
/>
-
+
@@ -549,6 +556,12 @@ export default class ClaimView extends Vue {
fulfillsHandleId?: string;
} | null = null;
detailsForOffer: { fulfillsPlanHandleId?: string } | null = null;
+ // Project information for fulfillsPlanHandleId
+ projectInfo: {
+ name: string;
+ imageUrl?: string;
+ issuer: string;
+ } | null = null;
fullClaim = null;
fullClaimDump = "";
fullClaimMessage = "";
@@ -674,6 +687,7 @@ export default class ClaimView extends Vue {
this.confsVisibleToIdList = [];
this.detailsForGive = null;
this.detailsForOffer = null;
+ this.projectInfo = null;
this.fullClaim = null;
this.fullClaimDump = "";
this.fullClaimMessage = "";
@@ -851,6 +865,14 @@ export default class ClaimView extends Vue {
}
}
+ // Load project information if there's a fulfillsPlanHandleId
+ const planHandleId =
+ this.detailsForGive?.fulfillsPlanHandleId ||
+ this.detailsForOffer?.fulfillsPlanHandleId;
+ if (planHandleId) {
+ await this.loadProjectInfo(planHandleId, userDid);
+ }
+
// retrieve the list of confirmers
const confirmerInfo = await libsUtil.retrieveConfirmerIdList(
this.apiServer,
@@ -878,6 +900,33 @@ export default class ClaimView extends Vue {
}
}
+ async loadProjectInfo(planHandleId: string, userDid: string) {
+ const url =
+ this.apiServer +
+ "/api/claim/byHandle/" +
+ encodeURIComponent(planHandleId);
+ const headers = await serverUtil.getHeaders(userDid);
+
+ try {
+ const resp = await this.axios.get(url, { headers });
+ if (resp.status === 200) {
+ this.projectInfo = {
+ name: resp.data.claim?.name || "(no name)",
+ imageUrl: resp.data.claim?.image,
+ issuer: resp.data.issuer,
+ };
+ } else {
+ await this.$logError(
+ "Error getting project info: " + JSON.stringify(resp),
+ );
+ }
+ } catch (error: unknown) {
+ await this.$logError(
+ "Error retrieving project info: " + JSON.stringify(error),
+ );
+ }
+ }
+
async showFullClaim(claimId: string) {
const url =
this.apiServer + "/api/claim/full/" + encodeURIComponent(claimId);
@@ -997,10 +1046,37 @@ export default class ClaimView extends Vue {
this.veriClaim as GenericCredWrapper,
),
};
+
+ // Use project info as recipient if available, otherwise use undefined
+ const recipient = this.projectInfo
+ ? {
+ did:
+ this.detailsForGive?.fulfillsPlanHandleId ||
+ this.detailsForOffer?.fulfillsPlanHandleId,
+ name: this.projectInfo.name,
+ handleId:
+ this.detailsForGive?.fulfillsPlanHandleId ||
+ this.detailsForOffer?.fulfillsPlanHandleId,
+ image: this.projectInfo.imageUrl,
+ }
+ : undefined;
+
+ // Extract offer information from the claim
+ const offerClaim = this.veriClaim.claim as OfferClaim;
+ const description =
+ offerClaim.itemOffered?.description || offerClaim.description;
+ const amount =
+ offerClaim.includesObject?.amountOfThisGood?.toString() || "0";
+ const unitCode = offerClaim.includesObject?.unitCode || "HUR";
+
(this.$refs.customGiveDialog as GiftedDialog).open(
giver,
- undefined,
+ recipient,
this.veriClaim.handleId,
+ undefined, // prompt
+ description,
+ amount,
+ unitCode,
);
}
diff --git a/src/views/ContactGiftingView.vue b/src/views/ContactGiftingView.vue
index 13654e43..23bf8fdf 100644
--- a/src/views/ContactGiftingView.vue
+++ b/src/views/ContactGiftingView.vue
@@ -125,6 +125,7 @@ export default class ContactGiftingView extends Vue {
toProjectId = "";
showProjects = false;
isFromProjectView = false;
+ offerId = "";
async created() {
this.notify = createNotifyHelpers(this.$notify);
@@ -173,6 +174,7 @@ export default class ContactGiftingView extends Vue {
(this.$route.query["showProjects"] as string) === "true";
this.isFromProjectView =
(this.$route.query["isFromProjectView"] as string) === "true";
+ this.offerId = (this.$route.query["offerId"] as string) || "";
// eslint-disable-next-line @typescript-eslint/no-explicit-any
} catch (err: any) {
@@ -229,13 +231,13 @@ export default class ContactGiftingView extends Vue {
(this.$refs.giftedDialog as GiftedDialog).open(
giver,
recipient,
- undefined,
+ this.offerId,
this.prompt,
this.description,
this.amountInput,
this.unitCode,
);
-
+
// Immediately select "Unnamed" and move to Step 2 based on stepType
if (this.stepType === "giver") {
(this.$refs.giftedDialog as GiftedDialog).selectGiver();
@@ -287,7 +289,7 @@ export default class ContactGiftingView extends Vue {
(this.$refs.giftedDialog as GiftedDialog).open(
giver,
recipient,
- undefined,
+ this.offerId,
this.prompt,
this.description,
this.amountInput,