@ -2,19 +2,36 @@
< div v-if ="visible" class="dialog-overlay" >
< div class = "dialog" >
<!-- Step 1 : Giver -- >
< div id = "sectionGiftedGiver" v-show ="currentStep === 1" >
< div v-show ="currentStep === 1" id="sectionGiftedGiver " >
< 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 >
<!-- 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'" >
< template v-if ="showProjects" >
< ul
: 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
v - for = "project in projects.slice(0, 7)"
: key = "project.handleId"
@ click = "selectProject(project)"
class = "cursor-pointer"
@ click = "
stepType === 'recipient'
? selectRecipientProject ( project )
: selectProject ( project )
"
>
< div class = "relative w-fit mx-auto" >
< ProjectIcon
@ -24,86 +41,130 @@
class = "!size-[3rem] mx-auto border border-slate-300 bg-white overflow-hidden rounded-full mb-1"
/ >
< / 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 } }
< / h3 >
< div class = "text-xs text-slate-500 truncate" >
< font -awesome icon = "user" class = "fa-fw text-slate-400" / >
{ { didInfo ( project . issuerDid , activeDid , allMyDids , allContacts ) } }
{ {
didInfo ( project . issuerDid , activeDid , allMyDids , allContacts )
} }
< / div >
< / 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 . )
< / li >
< li v-if ="projects.length > 0" >
< router -link
: to = "{ name: 'discover' }"
class = "cursor-pointer"
>
< 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" >
< router -link : to = "{ name: 'discover' }" class = "cursor-pointer" >
< 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"
>
Show All
< / h3 >
< / r o u t e r - l i n k >
< / li >
< / template >
< template v-else >
<!-- show people ( contacts ) -- >
< li
v - if = "isFromProjectView && activeDid"
@ click = "selectGiver({ did: activeDid, name: 'You' })"
v - if = "
stepType === 'recipient' ||
( stepType === 'giver' && isFromProjectView )
"
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" / >
< 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
< / h3 >
< / li >
< li
@ click = "selectGiver()"
class = "cursor-pointer"
@ click = "
stepType === 'recipient' ? selectRecipient ( ) : selectGiver ( )
"
>
< font -awesome 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" >
< font -awesome
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
< / h3 >
< / 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 . )
< / li >
< li
v - for = "contact in allContacts.slice(0, 10)"
: key = "contact.did"
@ click = "selectGiver(contact)"
class = "cursor-pointer"
@ click = "
stepType === 'recipient'
? selectRecipient ( contact )
: selectGiver ( contact )
"
>
< div class = "relative w-fit mx-auto" >
< EntityIcon
: contact = "contact"
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" >
< font -awesome icon = "clock" class = "block text-white text-xs w-[1em]" / >
< div
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 >
< 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 } }
< / h3 >
< / li >
< li v-if ="allContacts.length > 0" >
< li v-if ="allContacts.length > 0" class="cursor-pointer" >
< router -link
: to = " {
: to = " {
name : 'contact-gift' ,
query : {
recipientProjectId : toProjectId ,
recipientProjectName : giver ? . name ,
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" / >
< h3 class = "text-xs text-slate-500 font-medium italic text-ellipsis whitespace-nowrap overflow-hidden" >
< 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"
>
Show All
< / h3 >
< / r o u t e r - l i n k >
@ -120,71 +181,192 @@
< / div >
<!-- Step 2 : Gift -- >
< div id = "sectionGiftedGift" v-show ="currentStep === 2" >
< button
v - if = "!fromProjectId"
class = "w-full flex items-center gap-2 bg-slate-100 border border-slate-300 rounded-md p-2 mb-4"
@ click = "goBackToStep1"
>
< 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 v-show ="currentStep === 2" id="sectionGiftedGift" >
< div class = "grid grid-cols-2 gap-2 mb-4" >
<!-- Giver Button -- >
< button
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"
@ click = "goBackToStep1('giver')"
>
< 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 >
< div class = "text-start min-w-0" >
< p class = "text-xs text-slate-500 leading-1 -mb-1 uppercase" > { { showProjects ? 'Benefitted from:' : 'Received from:' } } < / p >
< h3 class = "font-semibold truncate" > { { giver ? . 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 ="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 >
< / button >
< div v -else class = "w-full flex items-center gap-2 bg-slate-100 border border-slate-300 rounded-md p-2 mb-4" >
< 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 >
< p class = "ms-auto text-sm text-slate-400 pe-1" >
< font -awesome icon = "lock" title = "Can't be changed" / >
< / p >
< / div >
< div class = "text-start min-w-0" >
< p class = "text-xs text-slate-500 leading-1 -mb-1 uppercase" > { { showProjects ? 'Benefitted from:' : 'Received from:' } } < / p >
< h3 class = "font-semibold truncate" > { { giver ? . name || 'Unnamed' } } < / h3 >
<!-- Recipient Button -- >
< button
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 >
< input
@ -194,33 +376,36 @@
: placeholder = "prompt || 'What was given?'"
/ >
< div class = "flex mb-4" >
< button
< button
class = "rounded-s border border-e-0 border-slate-400 bg-slate-200 px-4 py-2"
@ click = "amountInput === '0' ? null : decrement()"
>
< font -awesome icon = "chevron-left" / >
< / button >
< / button >
< input
id = "inputGivenAmount"
v - model = "amountInput"
type = "number"
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"
@ click = "increment()"
>
< font -awesome icon = "chevron-right" / >
< / button >
< select v-model ="unitCode" class="flex-1 rounded border border-slate-400 ms-2 px-3 py-2" >
< option value = "HUR" > Hours < / option >
< option value = "USD" > US $ < / option >
< option value = "BTC" > BTC < / option >
< option value = "BX" > BX < / option >
< option value = "ETH" > ETH < / option >
< / select >
< / div >
< / button >
< select
v - model = "unitCode"
class = "flex-1 rounded border border-slate-400 ms-2 px-3 py-2"
>
< option value = "HUR" > Hours < / option >
< option value = "USD" > US $ < / option >
< option value = "BTC" > BTC < / option >
< option value = "BX" > BX < / option >
< option value = "ETH" > ETH < / option >
< / select >
< / div >
< router -link
: to = " {
name : 'gifted-details' ,
@ -230,7 +415,10 @@
giverDid : showProjects ? undefined : giver ? . did ,
giverName : giver ? . name ,
offerId ,
fulfillsProjectId : showProjects && isFromProjectView ? giver ? . handleId : toProjectId ,
fulfillsProjectId :
showProjects && isFromProjectView
? giver ? . handleId
: toProjectId ,
providerProjectId : showProjects ? giver ? . handleId : fromProjectId ,
recipientDid : receiver ? . did ,
recipientName : receiver ? . name ,
@ -241,11 +429,11 @@
>
Photo & amp ; more options & hellip ;
< / r o u t e r - l i n k >
< 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
< font -awesome
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()"
/ >
< / p >
@ -269,7 +457,7 @@
< / template >
< 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 {
@ -303,6 +491,21 @@ export default class GiftedDialog extends Vue {
@ Prop ( { default : false } ) showProjects = false ;
@ Prop ( ) isFromProjectView = false ;
@ Watch ( 'showProjects' )
onShowProjectsChange ( ) {
this . updateEntityTypes ( ) ;
}
@ Watch ( 'fromProjectId' )
onFromProjectIdChange ( ) {
this . updateEntityTypes ( ) ;
}
@ Watch ( 'toProjectId' )
onToProjectIdChange ( ) {
this . updateEntityTypes ( ) ;
}
activeDid = "" ;
allContacts : Array < Contact > = [ ] ;
allMyDids : Array < string > = [ ] ;
@ -326,6 +529,42 @@ export default class GiftedDialog extends Vue {
didInfo = didInfo ;
/ / C o m p u t e d p r o p e r t y t o h e l p d e b u g t e m p l a t e l o g i c
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 ( ) {
/ / R e s e t a n d s e t e n t i t y t y p e s b a s e d o n c u r r e n t c o n t e x t
this . giverEntityType = "person" ;
this . recipientEntityType = "person" ;
/ / D e t e r m i n e e n t i t y t y p e s b a s e d o n c u r r e n t c o n t e x t
if ( this . showProjects ) {
/ / H o m e V i e w " P r o j e c t " b u t t o n o r P r o j e c t V i e w V i e w " G i v e n b y T h i s "
this . giverEntityType = "project" ;
this . recipientEntityType = "person" ;
} else if ( this . fromProjectId ) {
/ / P r o j e c t V i e w V i e w " G i v e n b y T h i s " b u t t o n ( p r o j e c t i s g i v e r )
this . giverEntityType = "project" ;
this . recipientEntityType = "person" ;
} else if ( this . toProjectId ) {
/ / P r o j e c t V i e w V i e w " G i v e n t o T h i s " b u t t o n ( p r o j e c t i s r e c i p i e n t )
this . giverEntityType = "person" ;
this . recipientEntityType = "project" ;
} else {
/ / H o m e V i e w " P e r s o n " b u t t o n
this . giverEntityType = "person" ;
this . recipientEntityType = "person" ;
}
}
async open (
giver ? : libsUtil . GiverReceiverInputInfo ,
receiver ? : libsUtil . GiverReceiverInputInfo ,
@ -342,6 +581,10 @@ export default class GiftedDialog extends Vue {
this . callbackOnSuccess = callbackOnSuccess ;
this . offerId = offerId || "" ;
this . currentStep = giver ? 2 : 1 ;
this . stepType = "giver" ;
/ / U p d a t e e n t i t y t y p e s b a s e d o n c u r r e n t p r o p s
this . updateEntityTypes ( ) ;
try {
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 ( ) ;
} else {
/ / C l e a r p r o j e c t s a r r a y w h e n n o t n e e d e d
this . projects = [ ] ;
}
} catch ( err : any ) {
logger . error ( "Error retrieving settings from database:" , err ) ;
@ -510,12 +759,16 @@ export default class GiftedDialog extends Vue {
this . axios ,
this . apiServer ,
this . activeDid ,
this . showProjects ? undefined : giverDid as string ,
this . showProjects && this . isFromProjectView ? this . giver ? . handleId : recipientDid as string ,
this . showProjects ? undefined : ( giverDid as string ) ,
this . showProjects && this . isFromProjectView
? this . giver ? . handleId
: ( recipientDid as string ) ,
description ,
amount ,
unitCode ,
this . showProjects && this . isFromProjectView ? this . giver ? . handleId : this . toProjectId ,
this . showProjects && this . isFromProjectView
? this . giver ? . handleId
: this . toProjectId ,
this . offerId ,
false ,
undefined ,
@ -598,18 +851,19 @@ export default class GiftedDialog extends Vue {
if ( contact ) {
this . giver = {
did : contact . did ,
name : contact . name || contact . did
name : contact . name || contact . did ,
} ;
} else {
this . giver = {
did : '' ,
name : 'Unnamed'
did : "" ,
name : "Unnamed" ,
} ;
}
this . currentStep = 2 ;
}
goBackToStep1 ( ) {
goBackToStep1 ( step : string ) {
this . stepType = step ;
this . currentStep = 1 ;
}
@ -647,11 +901,36 @@ export default class GiftedDialog extends Vue {
did : project . handleId ,
name : project . name ,
image : project . image ,
handleId : project . handleId
handleId : project . handleId ,
} ;
this . receiver = {
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 ;
}