Browse Source

Giver-recipient controls

- Dialog now shows separate cards for giver and recipient
- Ability to change giver and/or recipient
- Project giver/recipient is locked in ProjectView (context reinforcement)
pull/140/head
Jose Olarte III 6 days ago
parent
commit
a7e65b3b49
  1. 519
      src/components/GiftedDialog.vue
  2. 2
      src/libs/fontawesome.ts
  3. 16
      src/views/ContactGiftingView.vue
  4. 34
      src/views/HomeView.vue
  5. 41
      src/views/ProjectViewView.vue

519
src/components/GiftedDialog.vue

@ -2,19 +2,36 @@
<div v-if="visible" class="dialog-overlay"> <div v-if="visible" class="dialog-overlay">
<div class="dialog"> <div class="dialog">
<!-- Step 1: Giver --> <!-- Step 1: Giver -->
<div id="sectionGiftedGiver" v-show="currentStep === 1"> <div v-show="currentStep === 1" id="sectionGiftedGiver">
<label class="block font-bold mb-4"> <label class="block font-bold mb-4">
{{ showProjects ? 'Choose a project to benefit from:' : 'Choose a person to receive from:' }} {{
stepType === "recipient"
? "Choose who received the gift:"
: showProjects
? "Choose a project to benefit from:"
: "Choose a person to receive from:"
}}
</label> </label>
<!-- Unified Quick-pick grid for People and Projects --> <!-- Unified Quick-pick grid for People and Projects -->
<ul :class="showProjects ? 'grid grid-cols-3 md:grid-cols-4 gap-x-2 gap-y-4 text-center mb-4' : 'grid grid-cols-4 sm:grid-cols-5 md:grid-cols-6 gap-x-2 gap-y-4 text-center mb-4'"> <ul
<template v-if="showProjects"> :class="
shouldShowProjects
? 'grid grid-cols-3 md:grid-cols-4 gap-x-2 gap-y-4 text-center mb-4'
: 'grid grid-cols-4 sm:grid-cols-5 md:grid-cols-6 gap-x-2 gap-y-4 text-center mb-4'
"
>
<template v-if="shouldShowProjects">
<!-- show projects -->
<li <li
v-for="project in projects.slice(0, 7)" v-for="project in projects.slice(0, 7)"
:key="project.handleId" :key="project.handleId"
@click="selectProject(project)"
class="cursor-pointer" class="cursor-pointer"
@click="
stepType === 'recipient'
? selectRecipientProject(project)
: selectProject(project)
"
> >
<div class="relative w-fit mx-auto"> <div class="relative w-fit mx-auto">
<ProjectIcon <ProjectIcon
@ -24,86 +41,130 @@
class="!size-[3rem] mx-auto border border-slate-300 bg-white overflow-hidden rounded-full mb-1" class="!size-[3rem] mx-auto border border-slate-300 bg-white overflow-hidden rounded-full mb-1"
/> />
</div> </div>
<h3 class="text-xs font-medium text-ellipsis whitespace-nowrap overflow-hidden"> <h3
class="text-xs font-medium text-ellipsis whitespace-nowrap overflow-hidden"
>
{{ project.name }} {{ project.name }}
</h3> </h3>
<div class="text-xs text-slate-500 truncate"> <div class="text-xs text-slate-500 truncate">
<font-awesome icon="user" class="fa-fw text-slate-400" /> <font-awesome icon="user" class="fa-fw text-slate-400" />
{{ didInfo(project.issuerDid, activeDid, allMyDids, allContacts) }} {{
didInfo(project.issuerDid, activeDid, allMyDids, allContacts)
}}
</div> </div>
</li> </li>
<li v-if="projects.length === 0" class="text-xs text-slate-500 italic col-span-full"> <li
v-if="projects.length === 0"
class="text-xs text-slate-500 italic col-span-full"
>
(No projects found.) (No projects found.)
</li> </li>
<li v-if="projects.length > 0"> <li v-if="projects.length > 0">
<router-link <router-link :to="{ name: 'discover' }" class="cursor-pointer">
:to="{ name: 'discover' }" <font-awesome
class="cursor-pointer" icon="circle-right"
> class="text-blue-500 text-5xl mb-1"
<font-awesome icon="circle-right" class="text-blue-500 text-5xl mb-1" /> />
<h3 class="text-xs text-slate-500 font-medium italic text-ellipsis whitespace-nowrap overflow-hidden"> <h3
class="text-xs text-slate-500 font-medium italic text-ellipsis whitespace-nowrap overflow-hidden"
>
Show All Show All
</h3> </h3>
</router-link> </router-link>
</li> </li>
</template> </template>
<template v-else> <template v-else>
<!-- show people (contacts) -->
<li <li
v-if="isFromProjectView && activeDid" v-if="
@click="selectGiver({ did: activeDid, name: 'You' })" stepType === 'recipient' ||
(stepType === 'giver' && isFromProjectView)
"
class="cursor-pointer" class="cursor-pointer"
@click="
stepType === 'recipient'
? selectRecipient({ did: activeDid, name: 'You' })
: selectGiver({ did: activeDid, name: 'You' })
"
> >
<font-awesome icon="hand" class="text-blue-500 text-5xl mb-1" /> <font-awesome icon="hand" class="text-blue-500 text-5xl mb-1" />
<h3 class="text-xs text-blue-500 font-medium text-ellipsis whitespace-nowrap overflow-hidden"> <h3
class="text-xs text-blue-500 font-medium text-ellipsis whitespace-nowrap overflow-hidden"
>
You You
</h3> </h3>
</li> </li>
<li <li
@click="selectGiver()"
class="cursor-pointer" class="cursor-pointer"
@click="
stepType === 'recipient' ? selectRecipient() : selectGiver()
"
> >
<font-awesome icon="circle-question" class="text-slate-400 text-5xl mb-1" /> <font-awesome
<h3 class="text-xs text-slate-500 font-medium italic text-ellipsis whitespace-nowrap overflow-hidden"> icon="circle-question"
class="text-slate-400 text-5xl mb-1"
/>
<h3
class="text-xs text-slate-500 font-medium italic text-ellipsis whitespace-nowrap overflow-hidden"
>
Unnamed Unnamed
</h3> </h3>
</li> </li>
<li v-if="allContacts.length === 0" class="text-xs text-slate-500 italic col-span-full"> <li
v-if="allContacts.length === 0"
class="text-xs text-slate-500 italic col-span-full"
>
(Add friends to see more people worthy of recognition.) (Add friends to see more people worthy of recognition.)
</li> </li>
<li <li
v-for="contact in allContacts.slice(0, 10)" v-for="contact in allContacts.slice(0, 10)"
:key="contact.did" :key="contact.did"
@click="selectGiver(contact)"
class="cursor-pointer" class="cursor-pointer"
@click="
stepType === 'recipient'
? selectRecipient(contact)
: selectGiver(contact)
"
> >
<div class="relative w-fit mx-auto"> <div class="relative w-fit mx-auto">
<EntityIcon <EntityIcon
:contact="contact" :contact="contact"
class="!size-[3rem] mx-auto border border-slate-300 bg-white overflow-hidden rounded-full mb-1" class="!size-[3rem] mx-auto border border-slate-300 bg-white overflow-hidden rounded-full mb-1"
/> />
<div class="rounded-full bg-slate-400 absolute bottom-0 right-0 p-1 translate-x-1/3"> <div
<font-awesome icon="clock" class="block text-white text-xs w-[1em]" /> class="rounded-full bg-slate-400 absolute bottom-0 right-0 p-1 translate-x-1/3"
>
<font-awesome
icon="clock"
class="block text-white text-xs w-[1em]"
/>
</div> </div>
</div> </div>
<h3 class="text-xs font-medium text-ellipsis whitespace-nowrap overflow-hidden"> <h3
class="text-xs font-medium text-ellipsis whitespace-nowrap overflow-hidden"
>
{{ contact.name || contact.did }} {{ contact.name || contact.did }}
</h3> </h3>
</li> </li>
<li v-if="allContacts.length > 0"> <li v-if="allContacts.length > 0" class="cursor-pointer">
<router-link <router-link
:to="{ :to="{
name: 'contact-gift', name: 'contact-gift',
query: { query: {
recipientProjectId: toProjectId, recipientProjectId: toProjectId,
recipientProjectName: giver?.name, recipientProjectName: giver?.name,
recipientProjectImage: giver?.image, recipientProjectImage: giver?.image,
recipientProjectHandleId: giver?.handleId recipientProjectHandleId: giver?.handleId,
} },
}" }"
class="cursor-pointer"
> >
<font-awesome icon="circle-right" class="text-blue-500 text-5xl mb-1" /> <font-awesome
<h3 class="text-xs text-slate-500 font-medium italic text-ellipsis whitespace-nowrap overflow-hidden"> icon="circle-right"
class="text-blue-500 text-5xl mb-1"
/>
<h3
class="text-xs text-slate-500 font-medium italic text-ellipsis whitespace-nowrap overflow-hidden"
>
Show All Show All
</h3> </h3>
</router-link> </router-link>
@ -120,71 +181,192 @@
</div> </div>
<!-- Step 2: Gift --> <!-- Step 2: Gift -->
<div id="sectionGiftedGift" v-show="currentStep === 2"> <div v-show="currentStep === 2" id="sectionGiftedGift">
<button <div class="grid grid-cols-2 gap-2 mb-4">
v-if="!fromProjectId" <!-- Giver Button -->
class="w-full flex items-center gap-2 bg-slate-100 border border-slate-300 rounded-md p-2 mb-4" <button
@click="goBackToStep1" v-if="(giverEntityType === 'person' || giverEntityType === 'project') && !(isFromProjectView && giverEntityType === 'project')"
> class="flex-1 flex items-center gap-2 bg-slate-100 border border-slate-300 rounded-md p-2"
<div> @click="goBackToStep1('giver')"
<template v-if="showProjects"> >
<ProjectIcon <div>
v-if="giver?.handleId" <template v-if="giverEntityType === 'project'">
:entity-id="giver.handleId" <ProjectIcon
:icon-size="32" v-if="giver?.handleId"
:image-url="giver.image" :entity-id="giver.handleId"
class="rounded-full bg-white overflow-hidden !size-[2rem] object-cover" :icon-size="32"
/> :image-url="giver.image"
</template> class="rounded-full bg-white overflow-hidden !size-[2rem] object-cover"
<template v-else> />
<EntityIcon </template>
v-if="giver?.did" <template v-else>
:contact="giver" <EntityIcon
class="rounded-full bg-white overflow-hidden !size-[2rem] object-cover" v-if="giver?.did"
/> :contact="giver"
<font-awesome class="rounded-full bg-white overflow-hidden !size-[2rem] object-cover"
v-else />
icon="circle-question" <font-awesome
class="text-slate-400 text-3xl" v-else
/> icon="circle-question"
</template> class="text-slate-400 text-3xl"
</div> />
</template>
</div>
<div class="text-start min-w-0">
<p class="text-xs text-slate-500 leading-1 -mb-1 uppercase">
{{
giverEntityType === "project"
? "Benefited from:"
: "Received from:"
}}
</p>
<h3 class="font-semibold truncate">
{{ giver?.name || "Unnamed" }}
</h3>
</div>
<div class="text-start min-w-0"> <p class="ms-auto text-sm text-blue-500 pe-1">
<p class="text-xs text-slate-500 leading-1 -mb-1 uppercase">{{ showProjects ? 'Benefitted from:' : 'Received from:' }}</p> <font-awesome icon="pen" title="Change" />
<h3 class="font-semibold truncate">{{ giver?.name || 'Unnamed' }}</h3> </p>
</div> </button>
<div
v-else
class="flex-1 flex items-center gap-2 bg-slate-100 border border-slate-300 rounded-md p-2"
>
<div>
<template v-if="giverEntityType === 'project'">
<ProjectIcon
v-if="giver?.handleId"
:entity-id="giver.handleId"
:icon-size="32"
:image-url="giver.image"
class="rounded-full bg-white overflow-hidden !size-[2rem] object-cover"
/>
</template>
<template v-else>
<EntityIcon
v-if="giver?.did"
:contact="giver"
class="rounded-full bg-white overflow-hidden !size-[2rem] object-cover"
/>
<font-awesome
v-else
icon="circle-question"
class="text-slate-400 text-3xl"
/>
</template>
</div>
<div class="text-start min-w-0">
<p class="text-xs text-slate-500 leading-1 -mb-1 uppercase">
{{
giverEntityType === "project"
? "Benefited from:"
: "Received from:"
}}
</p>
<h3 class="font-semibold truncate">
{{ giver?.name || "Unnamed" }}
</h3>
</div>
<p class="ms-auto text-sm uppercase font-medium pe-2">Change</p> <p class="ms-auto text-sm text-slate-400 pe-1">
</button> <font-awesome icon="lock" title="Can't be changed" />
<div v-else class="w-full flex items-center gap-2 bg-slate-100 border border-slate-300 rounded-md p-2 mb-4"> </p>
<div>
<template v-if="showProjects">
<ProjectIcon
v-if="giver?.handleId"
:entity-id="giver.handleId"
:icon-size="32"
:image-url="giver.image"
class="rounded-full bg-white overflow-hidden !size-[2rem] object-cover"
/>
</template>
<template v-else>
<EntityIcon
v-if="giver?.did"
:contact="giver"
class="rounded-full bg-white overflow-hidden !size-[2rem] object-cover"
/>
<font-awesome
v-else
icon="circle-question"
class="text-slate-400 text-3xl"
/>
</template>
</div> </div>
<div class="text-start min-w-0"> <!-- Recipient Button -->
<p class="text-xs text-slate-500 leading-1 -mb-1 uppercase">{{ showProjects ? 'Benefitted from:' : 'Received from:' }}</p> <button
<h3 class="font-semibold truncate">{{ giver?.name || 'Unnamed' }}</h3> v-if="recipientEntityType === 'person'"
class="flex-1 flex items-center gap-2 bg-slate-100 border border-slate-300 rounded-md p-2"
@click="goBackToStep1('recipient')"
>
<div>
<template v-if="recipientEntityType === 'project'">
<ProjectIcon
v-if="receiver?.handleId"
:entity-id="receiver.handleId"
:icon-size="32"
:image-url="receiver.image"
class="rounded-full bg-white overflow-hidden !size-[2rem] object-cover"
/>
</template>
<template v-else>
<EntityIcon
v-if="receiver?.did"
:contact="receiver"
class="rounded-full bg-white overflow-hidden !size-[2rem] object-cover"
/>
<font-awesome
v-else
icon="circle-question"
class="text-slate-400 text-3xl"
/>
</template>
</div>
<div class="text-start min-w-0">
<p class="text-xs text-slate-500 leading-1 -mb-1 uppercase">
{{
recipientEntityType === "project"
? "Given to project:"
: "Given to:"
}}
</p>
<h3 class="font-semibold truncate">
{{ receiver?.name || "Unnamed" }}
</h3>
</div>
<p class="ms-auto text-sm text-blue-500 pe-1">
<font-awesome icon="pen" title="Change" />
</p>
</button>
<div
v-else
class="flex-1 flex items-center gap-2 bg-slate-100 border border-slate-300 rounded-md p-2"
>
<div>
<template v-if="recipientEntityType === 'project'">
<ProjectIcon
v-if="receiver?.handleId"
:entity-id="receiver.handleId"
:icon-size="32"
:image-url="receiver.image"
class="rounded-full bg-white overflow-hidden !size-[2rem] object-cover"
/>
</template>
<template v-else>
<EntityIcon
v-if="receiver?.did"
:contact="receiver"
class="rounded-full bg-white overflow-hidden !size-[2rem] object-cover"
/>
<font-awesome
v-else
icon="circle-question"
class="text-slate-400 text-3xl"
/>
</template>
</div>
<div class="text-start min-w-0">
<p class="text-xs text-slate-500 leading-1 -mb-1 uppercase">
{{
recipientEntityType === "project"
? "Given to project:"
: "Given to:"
}}
</p>
<h3 class="font-semibold truncate">
{{ receiver?.name || "Unnamed" }}
</h3>
</div>
<p class="ms-auto text-sm text-slate-400 pe-1">
<font-awesome icon="lock" title="Can't be changed" />
</p>
</div> </div>
</div> </div>
<input <input
@ -194,33 +376,36 @@
:placeholder="prompt || 'What was given?'" :placeholder="prompt || 'What was given?'"
/> />
<div class="flex mb-4"> <div class="flex mb-4">
<button <button
class="rounded-s border border-e-0 border-slate-400 bg-slate-200 px-4 py-2" class="rounded-s border border-e-0 border-slate-400 bg-slate-200 px-4 py-2"
@click="amountInput === '0' ? null : decrement()" @click="amountInput === '0' ? null : decrement()"
> >
<font-awesome icon="chevron-left" /> <font-awesome icon="chevron-left" />
</button> </button>
<input <input
id="inputGivenAmount" id="inputGivenAmount"
v-model="amountInput" v-model="amountInput"
type="number" type="number"
class="flex-1 border border-e-0 border-slate-400 px-2 py-2 text-center w-[1px]" class="flex-1 border border-e-0 border-slate-400 px-2 py-2 text-center w-[1px]"
/> />
<button <button
class="rounded-e border border-slate-400 bg-slate-200 px-4 py-2" class="rounded-e border border-slate-400 bg-slate-200 px-4 py-2"
@click="increment()" @click="increment()"
> >
<font-awesome icon="chevron-right" /> <font-awesome icon="chevron-right" />
</button> </button>
<select v-model="unitCode" class="flex-1 rounded border border-slate-400 ms-2 px-3 py-2"> <select
<option value="HUR">Hours</option> v-model="unitCode"
<option value="USD">US $</option> class="flex-1 rounded border border-slate-400 ms-2 px-3 py-2"
<option value="BTC">BTC</option> >
<option value="BX">BX</option> <option value="HUR">Hours</option>
<option value="ETH">ETH</option> <option value="USD">US $</option>
</select> <option value="BTC">BTC</option>
</div> <option value="BX">BX</option>
<option value="ETH">ETH</option>
</select>
</div>
<router-link <router-link
:to="{ :to="{
name: 'gifted-details', name: 'gifted-details',
@ -230,7 +415,10 @@
giverDid: showProjects ? undefined : giver?.did, giverDid: showProjects ? undefined : giver?.did,
giverName: giver?.name, giverName: giver?.name,
offerId, offerId,
fulfillsProjectId: showProjects && isFromProjectView ? giver?.handleId : toProjectId, fulfillsProjectId:
showProjects && isFromProjectView
? giver?.handleId
: toProjectId,
providerProjectId: showProjects ? giver?.handleId : fromProjectId, providerProjectId: showProjects ? giver?.handleId : fromProjectId,
recipientDid: receiver?.did, recipientDid: receiver?.did,
recipientName: receiver?.name, recipientName: receiver?.name,
@ -241,11 +429,11 @@
> >
Photo &amp; more options&hellip; Photo &amp; more options&hellip;
</router-link> </router-link>
<p class="text-center mb-4"> <p class="text-center text-sm mb-4">
<b class="font-medium">Sign &amp; Send</b> to publish to the world <b class="font-medium">Sign &amp; Send</b> to publish to the world
<font-awesome <font-awesome
icon="circle-info" icon="circle-info"
class="fa-fw text-blue-500 text-lg cursor-pointer" class="fa-fw text-blue-500 text-base cursor-pointer"
@click="explainData()" @click="explainData()"
/> />
</p> </p>
@ -269,7 +457,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { Vue, Component, Prop } from "vue-facing-decorator"; import { Vue, Component, Prop, Watch } from "vue-facing-decorator";
import { NotificationIface, USE_DEXIE_DB } from "../constants/app"; import { NotificationIface, USE_DEXIE_DB } from "../constants/app";
import { import {
@ -303,6 +491,21 @@ export default class GiftedDialog extends Vue {
@Prop({ default: false }) showProjects = false; @Prop({ default: false }) showProjects = false;
@Prop() isFromProjectView = false; @Prop() isFromProjectView = false;
@Watch('showProjects')
onShowProjectsChange() {
this.updateEntityTypes();
}
@Watch('fromProjectId')
onFromProjectIdChange() {
this.updateEntityTypes();
}
@Watch('toProjectId')
onToProjectIdChange() {
this.updateEntityTypes();
}
activeDid = ""; activeDid = "";
allContacts: Array<Contact> = []; allContacts: Array<Contact> = [];
allMyDids: Array<string> = []; allMyDids: Array<string> = [];
@ -326,6 +529,42 @@ export default class GiftedDialog extends Vue {
didInfo = didInfo; didInfo = didInfo;
// Computed property to help debug template logic
get shouldShowProjects() {
const result = (this.stepType === 'giver' && this.giverEntityType === 'project') ||
(this.stepType === 'recipient' && this.recipientEntityType === 'project');
return result;
}
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( async open(
giver?: libsUtil.GiverReceiverInputInfo, giver?: libsUtil.GiverReceiverInputInfo,
receiver?: libsUtil.GiverReceiverInputInfo, receiver?: libsUtil.GiverReceiverInputInfo,
@ -342,6 +581,10 @@ export default class GiftedDialog extends Vue {
this.callbackOnSuccess = callbackOnSuccess; this.callbackOnSuccess = callbackOnSuccess;
this.offerId = offerId || ""; this.offerId = offerId || "";
this.currentStep = giver ? 2 : 1; this.currentStep = giver ? 2 : 1;
this.stepType = "giver";
// Update entity types based on current props
this.updateEntityTypes();
try { try {
let settings = await databaseUtil.retrieveSettingsForActiveAccount(); let settings = await databaseUtil.retrieveSettingsForActiveAccount();
@ -373,8 +616,14 @@ export default class GiftedDialog extends Vue {
); );
} }
if (this.showProjects) { if (
this.giverEntityType === "project" ||
this.recipientEntityType === "project"
) {
await this.loadProjects(); await this.loadProjects();
} else {
// Clear projects array when not needed
this.projects = [];
} }
} catch (err: any) { } catch (err: any) {
logger.error("Error retrieving settings from database:", err); logger.error("Error retrieving settings from database:", err);
@ -510,12 +759,16 @@ export default class GiftedDialog extends Vue {
this.axios, this.axios,
this.apiServer, this.apiServer,
this.activeDid, this.activeDid,
this.showProjects ? undefined : giverDid as string, this.showProjects ? undefined : (giverDid as string),
this.showProjects && this.isFromProjectView ? this.giver?.handleId : recipientDid as string, this.showProjects && this.isFromProjectView
? this.giver?.handleId
: (recipientDid as string),
description, description,
amount, amount,
unitCode, unitCode,
this.showProjects && this.isFromProjectView ? this.giver?.handleId : this.toProjectId, this.showProjects && this.isFromProjectView
? this.giver?.handleId
: this.toProjectId,
this.offerId, this.offerId,
false, false,
undefined, undefined,
@ -598,18 +851,19 @@ export default class GiftedDialog extends Vue {
if (contact) { if (contact) {
this.giver = { this.giver = {
did: contact.did, did: contact.did,
name: contact.name || contact.did name: contact.name || contact.did,
}; };
} else { } else {
this.giver = { this.giver = {
did: '', did: "",
name: 'Unnamed' name: "Unnamed",
}; };
} }
this.currentStep = 2; this.currentStep = 2;
} }
goBackToStep1() { goBackToStep1(step: string) {
this.stepType = step;
this.currentStep = 1; this.currentStep = 1;
} }
@ -647,11 +901,36 @@ export default class GiftedDialog extends Vue {
did: project.handleId, did: project.handleId,
name: project.name, name: project.name,
image: project.image, image: project.image,
handleId: project.handleId handleId: project.handleId,
}; };
this.receiver = { this.receiver = {
did: this.activeDid, did: this.activeDid,
name: "You" name: "You",
};
this.currentStep = 2;
}
selectRecipient(contact?: Contact) {
if (contact) {
this.receiver = {
did: contact.did,
name: contact.name || contact.did,
};
} else {
this.receiver = {
did: "",
name: "Unnamed",
};
}
this.currentStep = 2;
}
selectRecipientProject(project: PlanData) {
this.receiver = {
did: project.handleId,
name: project.name,
image: project.image,
handleId: project.handleId,
}; };
this.currentStep = 2; this.currentStep = 2;
} }

2
src/libs/fontawesome.ts

@ -61,6 +61,7 @@ import {
faLightbulb, faLightbulb,
faLink, faLink,
faLocationDot, faLocationDot,
faLock,
faLongArrowAltLeft, faLongArrowAltLeft,
faLongArrowAltRight, faLongArrowAltRight,
faMagnifyingGlass, faMagnifyingGlass,
@ -145,6 +146,7 @@ library.add(
faLightbulb, faLightbulb,
faLink, faLink,
faLocationDot, faLocationDot,
faLock,
faLongArrowAltLeft, faLongArrowAltLeft,
faLongArrowAltRight, faLongArrowAltRight,
faMagnifyingGlass, faMagnifyingGlass,

16
src/views/ContactGiftingView.vue

@ -127,10 +127,14 @@ export default class ContactGiftingView extends Vue {
); );
} }
this.projectId = (this.$route.query["recipientProjectId"] as string) || ""; this.projectId =
this.recipientProjectName = (this.$route.query["recipientProjectName"] as string) || ""; (this.$route.query["recipientProjectId"] as string) || "";
this.recipientProjectImage = (this.$route.query["recipientProjectImage"] as string) || ""; this.recipientProjectName =
this.recipientProjectHandleId = (this.$route.query["recipientProjectHandleId"] as string) || ""; (this.$route.query["recipientProjectName"] as string) || "";
this.recipientProjectImage =
(this.$route.query["recipientProjectImage"] as string) || "";
this.recipientProjectHandleId =
(this.$route.query["recipientProjectHandleId"] as string) || "";
this.prompt = (this.$route.query["prompt"] as string) ?? this.prompt; this.prompt = (this.$route.query["prompt"] as string) ?? this.prompt;
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
@ -156,10 +160,10 @@ export default class ContactGiftingView extends Vue {
did: this.recipientProjectHandleId, did: this.recipientProjectHandleId,
name: this.recipientProjectName, name: this.recipientProjectName,
image: this.recipientProjectImage, image: this.recipientProjectImage,
handleId: this.recipientProjectHandleId handleId: this.recipientProjectHandleId,
} }
: { did: this.activeDid, name: "you" }; : { did: this.activeDid, name: "you" };
if (giver === "Unnamed") { if (giver === "Unnamed") {
// Special case: Pass undefined to trigger Step 1, but with "Unnamed" pre-selected // Special case: Pass undefined to trigger Step 1, but with "Unnamed" pre-selected
(this.$refs.customDialog as GiftedDialog).open( (this.$refs.customDialog as GiftedDialog).open(

34
src/views/HomeView.vue

@ -122,26 +122,29 @@ Raymer * @version 1.0.0 */
<div class="flex gap-2 items-center mb-2"> <div class="flex gap-2 items-center mb-2">
<h2 class="text-xl font-bold">Record something given by:</h2> <h2 class="text-xl font-bold">Record something given by:</h2>
<button <button
@click="openGiftedPrompts()"
class="block ms-auto text-center text-white bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] p-2 rounded-full" class="block ms-auto text-center text-white bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] p-2 rounded-full"
@click="openGiftedPrompts()"
> >
<font-awesome icon="lightbulb" class="block text-center w-[1em]" /> <font-awesome
icon="lightbulb"
class="block text-center w-[1em]"
/>
</button> </button>
</div> </div>
<div class="grid grid-cols-2 gap-2"> <div class="grid grid-cols-2 gap-2">
<button <button
type="button" type="button"
@click="openDialogPerson()"
class="text-center text-base uppercase bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-3 py-2 rounded-lg" class="text-center text-base uppercase bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-3 py-2 rounded-lg"
@click="openDialogPerson()"
> >
<font-awesome icon="user" /> <font-awesome icon="user" />
Person Person
</button> </button>
<button <button
type="button" type="button"
@click="openProjectDialog()"
class="text-center text-base uppercase bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-3 py-2 rounded-lg" class="text-center text-base uppercase bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-3 py-2 rounded-lg"
@click="openProjectDialog()"
> >
<font-awesome icon="folder-open" /> <font-awesome icon="folder-open" />
Project Project
@ -160,22 +163,26 @@ Raymer * @version 1.0.0 */
<!-- Results List --> <!-- Results List -->
<div class="mt-4 mb-4"> <div class="mt-4 mb-4">
<div class="flex gap-2 items-center mb-3"> <div class="flex gap-2 items-center mb-3">
<h2 class="text-xl font-bold"> <h2 class="text-xl font-bold">Latest Activity</h2>
Latest Activity
</h2>
<button <button
v-if="resultsAreFiltered()" v-if="resultsAreFiltered()"
class="block ms-auto text-center text-white bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] p-2 rounded-full" class="block ms-auto text-center text-white bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] p-2 rounded-full"
@click="openFeedFilters()" @click="openFeedFilters()"
> >
<font-awesome icon="filter" class="block text-center w-[1em] translate-y-[0.05em]" /> <font-awesome
icon="filter"
class="block text-center w-[1em] translate-y-[0.05em]"
/>
</button> </button>
<button <button
v-else v-else
class="block ms-auto text-center text-white bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] p-2 rounded-full" class="block ms-auto text-center text-white bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] p-2 rounded-full"
@click="openFeedFilters()" @click="openFeedFilters()"
> >
<font-awesome icon="filter" class="block text-center w-[1em] translate-y-[0.05em]" /> <font-awesome
icon="filter"
class="block text-center w-[1em] translate-y-[0.05em]"
/>
</button> </button>
</div> </div>
@ -1610,7 +1617,7 @@ export default class HomeView extends Vue {
undefined, undefined,
{ {
did: this.activeDid, did: this.activeDid,
name: "you", name: "You",
} as GiverReceiverInputInfo, } as GiverReceiverInputInfo,
undefined, undefined,
"Given by Unnamed", "Given by Unnamed",
@ -1623,7 +1630,7 @@ export default class HomeView extends Vue {
giver, giver,
{ {
did: this.activeDid, did: this.activeDid,
name: "you", name: "You",
} as GiverReceiverInputInfo, } as GiverReceiverInputInfo,
undefined, undefined,
"Given by " + (giver?.name || "someone not named"), "Given by " + (giver?.name || "someone not named"),
@ -1864,7 +1871,10 @@ export default class HomeView extends Vue {
} }
} }
openDialogPerson(giver?: GiverReceiverInputInfo | "Unnamed", description?: string) { openDialogPerson(
giver?: GiverReceiverInputInfo | "Unnamed",
description?: string,
) {
this.showProjectsDialog = false; this.showProjectsDialog = false;
this.openDialog(giver, description); this.openDialog(giver, description);
} }

41
src/views/ProjectViewView.vue

@ -196,7 +196,11 @@
</div> </div>
</div> </div>
<GiftedDialog ref="giveDialogToThis" :to-project-id="projectId" :is-from-project-view="true" /> <GiftedDialog
ref="giveDialogToThis"
:to-project-id="projectId"
:is-from-project-view="true"
/>
<!-- Offers & Gifts to & from this --> <!-- Offers & Gifts to & from this -->
<div class="grid items-start grid-cols-1 sm:grid-cols-3 gap-4 mt-4"> <div class="grid items-start grid-cols-1 sm:grid-cols-3 gap-4 mt-4">
@ -462,7 +466,12 @@
</button> </button>
</div> </div>
</div> </div>
<GiftedDialog ref="giveDialogFromThis" :from-project-id="projectId" :show-projects="true" /> <GiftedDialog
ref="giveDialogFromThis"
:from-project-id="projectId"
:show-projects="true"
:is-from-project-view="true"
/>
<h3 class="text-lg font-bold mb-3 mt-4"> <h3 class="text-lg font-bold mb-3 mt-4">
Benefitted From This Project Benefitted From This Project
@ -1173,7 +1182,9 @@ export default class ProjectViewView extends Vue {
); );
} }
openGiftDialogToProject(contact?: libsUtil.GiverReceiverInputInfo | "Unnamed") { openGiftDialogToProject(
contact?: libsUtil.GiverReceiverInputInfo | "Unnamed",
) {
if (contact === "Unnamed") { if (contact === "Unnamed") {
// Special case: Pass undefined to trigger Step 1, but with "Unnamed" pre-selected // Special case: Pass undefined to trigger Step 1, but with "Unnamed" pre-selected
(this.$refs.giveDialogToThis as GiftedDialog).open( (this.$refs.giveDialogToThis as GiftedDialog).open(
@ -1185,10 +1196,18 @@ export default class ProjectViewView extends Vue {
// Immediately select "Unnamed" and move to Step 2 // Immediately select "Unnamed" and move to Step 2
(this.$refs.giveDialogToThis as GiftedDialog).selectGiver(); (this.$refs.giveDialogToThis as GiftedDialog).selectGiver();
} else { } else {
// Set only the project as recipient, allowing user to select giver in Step 1 // Open straight to Step 2 with current user as giver and current project as recipient
(this.$refs.giveDialogToThis as GiftedDialog).open( (this.$refs.giveDialogToThis as GiftedDialog).open(
undefined, {
{ did: this.issuer, name: this.name, handleId: this.projectId, image: this.imageUrl }, did: this.activeDid,
name: "You",
},
{
did: this.issuer,
name: this.name,
handleId: this.projectId,
image: this.imageUrl,
},
undefined, undefined,
`Given to ${this.name}`, `Given to ${this.name}`,
); );
@ -1198,13 +1217,18 @@ export default class ProjectViewView extends Vue {
openGiftDialogFromProject() { openGiftDialogFromProject() {
// Set the project as giver and the current user as recipient // Set the project as giver and the current user as recipient
(this.$refs.giveDialogFromThis as GiftedDialog).open( (this.$refs.giveDialogFromThis as GiftedDialog).open(
{ did: undefined, name: this.name, handleId: this.projectId, image: this.imageUrl }, {
did: undefined,
name: this.name,
handleId: this.projectId,
image: this.imageUrl,
},
{ did: this.activeDid, name: "You" }, { did: this.activeDid, name: "You" },
undefined, undefined,
`${this.name} gave to you`, `${this.name} gave to you`,
undefined, undefined,
undefined, undefined,
true true,
); );
} }
@ -1479,4 +1503,3 @@ export default class ProjectViewView extends Vue {
} }
} }
</script> </script>

Loading…
Cancel
Save