Browse Source

Feature: giver-recipient validation

- Ensures person-to-person gifting won't allow the same entity as giver and recipient
- Disable user item selection if it would create conflict
- Error messaging fallback
pull/140/head
Jose Olarte III 5 days ago
parent
commit
d3b80fbe47
  1. 100
      src/components/GiftedDialog.vue

100
src/components/GiftedDialog.vue

@ -80,16 +80,29 @@
stepType === 'recipient' || stepType === 'recipient' ||
(stepType === 'giver' && isFromProjectView) (stepType === 'giver' && isFromProjectView)
" "
class="cursor-pointer" :class="{
'cursor-pointer': !wouldCreateConflict(activeDid),
'cursor-not-allowed opacity-50': wouldCreateConflict(activeDid)
}"
@click=" @click="
stepType === 'recipient' !wouldCreateConflict(activeDid) &&
(stepType === 'recipient'
? selectRecipient({ did: activeDid, name: 'You' }) ? selectRecipient({ did: activeDid, name: 'You' })
: selectGiver({ did: activeDid, name: 'You' }) : selectGiver({ did: activeDid, name: 'You' }))
" "
> >
<font-awesome icon="hand" class="text-blue-500 text-5xl mb-1" /> <font-awesome
:class="{
'text-blue-500 text-5xl mb-1': !wouldCreateConflict(activeDid),
'text-slate-400 text-5xl mb-1': wouldCreateConflict(activeDid)
}"
icon="hand"
/>
<h3 <h3
class="text-xs text-blue-500 font-medium text-ellipsis whitespace-nowrap overflow-hidden" :class="{
'text-xs text-blue-500 font-medium text-ellipsis whitespace-nowrap overflow-hidden': !wouldCreateConflict(activeDid),
'text-xs text-slate-400 font-medium text-ellipsis whitespace-nowrap overflow-hidden': wouldCreateConflict(activeDid)
}"
> >
You You
</h3> </h3>
@ -119,11 +132,15 @@
<li <li
v-for="contact in allContacts.slice(0, 10)" v-for="contact in allContacts.slice(0, 10)"
:key="contact.did" :key="contact.did"
class="cursor-pointer" :class="{
'cursor-pointer': !wouldCreateConflict(contact.did),
'cursor-not-allowed opacity-50': wouldCreateConflict(contact.did)
}"
@click=" @click="
stepType === 'recipient' !wouldCreateConflict(contact.did) &&
(stepType === 'recipient'
? selectRecipient(contact) ? selectRecipient(contact)
: selectGiver(contact) : selectGiver(contact))
" "
> >
<div class="relative w-fit mx-auto"> <div class="relative w-fit mx-auto">
@ -141,7 +158,10 @@
</div> </div>
</div> </div>
<h3 <h3
class="text-xs font-medium text-ellipsis whitespace-nowrap overflow-hidden" :class="{
'text-xs font-medium text-ellipsis whitespace-nowrap overflow-hidden': !wouldCreateConflict(contact.did),
'text-xs font-medium text-ellipsis whitespace-nowrap overflow-hidden text-slate-400': wouldCreateConflict(contact.did)
}"
> >
{{ contact.name || contact.did }} {{ contact.name || contact.did }}
</h3> </h3>
@ -425,9 +445,22 @@
@click="explainData()" @click="explainData()"
/> />
</p> </p>
<!-- Conflict warning -->
<div v-if="hasPersonConflict" class="mb-4 p-3 bg-red-50 border border-red-200 rounded-md">
<p class="text-red-700 text-sm text-center">
<font-awesome icon="exclamation-triangle" class="fa-fw mr-1" />
Cannot record: Same person selected as both giver and recipient
</p>
</div>
<div class="grid grid-cols-1 sm:grid-cols-2 gap-2"> <div class="grid grid-cols-1 sm:grid-cols-2 gap-2">
<button <button
class="block w-full text-center text-md uppercase font-bold 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-1.5 py-2 rounded-lg" :disabled="hasPersonConflict"
:class="{
'block w-full text-center text-md uppercase font-bold 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-1.5 py-2 rounded-lg': !hasPersonConflict,
'block w-full text-center text-md uppercase font-bold bg-gradient-to-b from-slate-300 to-slate-500 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-slate-400 px-1.5 py-2 rounded-lg cursor-not-allowed': hasPersonConflict
}"
@click="confirm" @click="confirm"
> >
Sign &amp; Send Sign &amp; Send
@ -525,6 +558,39 @@ export default class GiftedDialog extends Vue {
return result; return result;
} }
// Computed property to check if current selection would create a conflict
get hasPersonConflict() {
// Only check for conflicts when both entities are persons
if (this.giverEntityType !== "person" || this.recipientEntityType !== "person") {
return false;
}
// Check if giver and recipient are the same person
if (this.giver?.did && this.receiver?.did && this.giver.did === this.receiver.did) {
return true;
}
return false;
}
// Computed property to check if a contact would create a conflict when selected
wouldCreateConflict(contactDid: string) {
// Only check for conflicts when both entities are persons
if (this.giverEntityType !== "person" || this.recipientEntityType !== "person") {
return false;
}
if (this.stepType === "giver") {
// If selecting as giver, check if it conflicts with current recipient
return this.receiver?.did === contactDid;
} else if (this.stepType === "recipient") {
// If selecting as recipient, check if it conflicts with current giver
return this.giver?.did === contactDid;
}
return false;
}
stepType = "giver"; stepType = "giver";
giverEntityType = "person" as "person" | "project"; giverEntityType = "person" as "person" | "project";
recipientEntityType = "person" as "person" | "project"; recipientEntityType = "person" as "person" | "project";
@ -705,6 +771,20 @@ export default class GiftedDialog extends Vue {
); );
return; return;
} }
// Check for person conflict
if (this.hasPersonConflict) {
this.$notify(
{
group: "alert",
type: "danger",
title: "Error",
text: "You cannot select the same person as both giver and recipient.",
},
3000,
);
return;
}
this.close(); this.close();
this.$notify( this.$notify(

Loading…
Cancel
Save