add details on contact-specific page

This commit is contained in:
2023-03-25 19:03:25 -06:00
parent 9317b59231
commit f281e41181
6 changed files with 348 additions and 126 deletions

View File

@@ -122,10 +122,10 @@
@click="setVisibility(contact, false)"
>
<fa icon="eye" class="text-slate-900 fa-fw ml-1" />
<span class="tooltiptext">Can see you</span>
<span class="tooltiptext">They can see you</span>
</button>
<button v-else class="tooltip" @click="setVisibility(contact, true)">
<span class="tooltiptext">Cannot see you</span>
<span class="tooltiptext">They cannot see you</span>
<fa icon="eye-slash" class="text-slate-900 fa-fw ml-1" />
</button>
@@ -135,11 +135,11 @@
</button>
<button v-if="contact.registered" class="tooltip">
<span class="tooltiptext">Registered</span>
<span class="tooltiptext">They are registered</span>
<fa icon="person-circle-check" class="text-slate-900 fa-fw ml-1" />
</button>
<button v-else @click="register(contact)" class="tooltip">
<span class="tooltiptext">Maybe not registered</span>
<span class="tooltiptext">They may not be registered</span>
<fa
icon="person-circle-question"
class="text-slate-900 fa-fw ml-1"
@@ -165,9 +165,9 @@
: (givenByMeUnconfirmed[contact.did] || 0)
/* eslint-enable prettier/prettier */
}}
<span class="tooltiptext-left">{{
givenByMeDescriptions[contact.did]
}}</span>
<span class="tooltiptext-left">
{{ givenByMeDescriptions[contact.did] || "Nothing" }}
</span>
<button
class="text-md uppercase bg-slate-500 text-white px-1.5 py-2 rounded-md mb-6"
@click="onClickAddGive(identity.did, contact.did)"
@@ -188,7 +188,7 @@
/* eslint-enable prettier/prettier */
}}
<span class="tooltiptext-left">
{{ givenToMeDescriptions[contact.did] }}
{{ givenToMeDescriptions[contact.did] || "Nothing" }}
</span>
<button
class="text-md uppercase bg-slate-500 text-white px-1.5 py-2 rounded-md mb-6"
@@ -197,6 +197,16 @@
+
</button>
</div>
<router-link
:to="{
name: 'contact-amounts',
query: { contactDid: contact.did },
}"
class="tooltip"
>
<fa icon="file-lines" class="text-slate-600 fa-fw ml-1" />
<span class="tooltiptext-left">See All Given Activity</span>
</router-link>
</div>
</div>
</div>
@@ -223,44 +233,20 @@ import { IIdentifier } from "@veramo/core";
import { Options, Vue } from "vue-class-component";
import { AppString } from "@/constants/app";
import { accessToken, SimpleSigner } from "@/libs/crypto";
import { accountsDB, db } from "@/db";
import { Contact } from "@/db/tables/contacts";
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
import { accessToken, SimpleSigner } from "@/libs/crypto";
import {
GiveServerRecord,
GiveVerifiableCredential,
RegisterVerifiableCredential,
SERVICE_ID,
} from "@/libs/endorserServer";
// eslint-disable-next-line @typescript-eslint/no-var-requires
const Buffer = require("buffer/").Buffer;
const SERVICE_ID = "endorser.ch";
export interface GiveServerRecord {
agentDid: string;
amount: number;
confirmed: number;
description: string;
fullClaim: GiveVerifiableCredential;
handleId: string;
recipientDid: string;
unit: string;
}
export interface GiveVerifiableCredential {
"@context": string;
"@type": string;
agent: { identifier: string };
description?: string;
object: { amountOfThisGood: number; unitCode: string };
recipient: { identifier: string };
}
export interface RegisterVerifiableCredential {
"@context": string;
"@type": string;
agent: { identifier: string };
object: string;
recipient: { identifier: string };
}
@Options({
components: {},
})
@@ -305,33 +291,6 @@ export default class ContactsView extends Vue {
);
}
async onClickNewContact(): Promise<void> {
let did = this.contactInput;
let name, publicKeyBase64;
const commaPos1 = this.contactInput.indexOf(",");
if (commaPos1 > -1) {
did = this.contactInput.substring(0, commaPos1).trim();
name = this.contactInput.substring(commaPos1 + 1).trim();
const commaPos2 = this.contactInput.indexOf(",", commaPos1 + 1);
if (commaPos2 > -1) {
name = this.contactInput.substring(commaPos1 + 1, commaPos2).trim();
publicKeyBase64 = this.contactInput.substring(commaPos2 + 1).trim();
}
}
// help with potential mistakes while this sharing requires copy-and-paste
if (publicKeyBase64 && /^[0-9A-Fa-f]{66}$/i.test(publicKeyBase64)) {
// it must be all hex (compressed public key), so convert
publicKeyBase64 = Buffer.from(publicKeyBase64, "hex").toString("base64");
}
const newContact = { did, name, publicKeyBase64 };
await db.contacts.add(newContact);
const allContacts = this.contacts.concat([newContact]);
this.contacts = R.sort(
(a: Contact, b) => (a.name || "").localeCompare(b.name || ""),
allContacts
);
}
async loadGives() {
if (!this.identity) {
console.error(
@@ -346,7 +305,7 @@ export default class ContactsView extends Vue {
try {
const url =
endorserApiServer +
"/api/v2/report/gives?agentId=" +
"/api/v2/report/gives?agentDid=" +
encodeURIComponent(this.identity?.did);
const token = await accessToken(this.identity);
const headers = {
@@ -400,7 +359,7 @@ export default class ContactsView extends Vue {
try {
const url =
endorserApiServer +
"/api/v2/report/gives?recipientId=" +
"/api/v2/report/gives?recipientDid=" +
encodeURIComponent(this.identity.did);
const token = await accessToken(this.identity);
const headers = {
@@ -450,6 +409,33 @@ export default class ContactsView extends Vue {
}
}
async onClickNewContact(): Promise<void> {
let did = this.contactInput;
let name, publicKeyBase64;
const commaPos1 = this.contactInput.indexOf(",");
if (commaPos1 > -1) {
did = this.contactInput.substring(0, commaPos1).trim();
name = this.contactInput.substring(commaPos1 + 1).trim();
const commaPos2 = this.contactInput.indexOf(",", commaPos1 + 1);
if (commaPos2 > -1) {
name = this.contactInput.substring(commaPos1 + 1, commaPos2).trim();
publicKeyBase64 = this.contactInput.substring(commaPos2 + 1).trim();
}
}
// help with potential mistakes while this sharing requires copy-and-paste
if (publicKeyBase64 && /^[0-9A-Fa-f]{66}$/i.test(publicKeyBase64)) {
// it must be all hex (compressed public key), so convert
publicKeyBase64 = Buffer.from(publicKeyBase64, "hex").toString("base64");
}
const newContact = { did, name, publicKeyBase64 };
await db.contacts.add(newContact);
const allContacts = this.contacts.concat([newContact]);
this.contacts = R.sort(
(a: Contact, b) => (a.name || "").localeCompare(b.name || ""),
allContacts
);
}
async deleteContact(contact: Contact) {
if (
confirm(
@@ -647,6 +633,22 @@ export default class ContactsView extends Vue {
}
async onClickAddGive(fromDid: string, toDid: string): Promise<void> {
// if they have unconfirmed amounts, ask to confirm those first
if (toDid == this.identity?.did && this.givenToMeUnconfirmed[fromDid] > 0) {
if (
confirm(
"There are " +
this.givenToMeUnconfirmed[fromDid] +
" unconfirmed hours from them." +
" Would you like to confirm some of those hours?"
)
) {
this.$router.push({
name: "contact-amounts",
query: { contactDid: fromDid },
});
}
}
if (!this.isNumeric(this.hourInput)) {
this.alertTitle = "Input Error";
this.alertMessage =
@@ -661,61 +663,36 @@ export default class ContactsView extends Vue {
this.alertMessage = "No identity is available.";
this.isAlertVisible = true;
} else {
// if they have unconfirmed amounts, ask to confirm those first
let wantsToConfirm = false;
if (
toDid == this.identity?.did &&
this.givenToMeUnconfirmed[fromDid] > 0
) {
if (
confirm(
"There are " +
this.givenToMeUnconfirmed[fromDid] +
" unconfirmed hours from them." +
" Would you like to confirm some of those hours?"
)
) {
wantsToConfirm = true;
}
}
if (wantsToConfirm) {
this.$router.push({
name: "contact-amounts",
query: { contactDid: fromDid },
});
// ask to confirm amount
let toFrom;
if (fromDid == this.identity?.did) {
toFrom = "from you to " + this.nameForDid(this.contacts, toDid);
} else {
// ask to confirm amount
let toFrom;
if (fromDid == this.identity?.did) {
toFrom = "from you to " + this.nameForDid(this.contacts, toDid);
} else {
toFrom =
"from " + this.nameForDid(this.contacts, fromDid) + " to you";
}
let description;
if (this.hourDescriptionInput) {
description = " with description '" + this.hourDescriptionInput + "'";
} else {
description = " with no description";
}
if (
confirm(
"Are you sure you want to record " +
this.hourInput +
" hours " +
toFrom +
description +
"?"
)
) {
this.createAndSubmitGive(
this.identity,
fromDid,
toDid,
parseFloat(this.hourInput),
this.hourDescriptionInput
);
}
toFrom = "from " + this.nameForDid(this.contacts, fromDid) + " to you";
}
let description;
if (this.hourDescriptionInput) {
description = " with description '" + this.hourDescriptionInput + "'";
} else {
description = " with no description";
}
if (
confirm(
"Are you sure you want to record " +
this.hourInput +
" hours " +
toFrom +
description +
"?"
)
) {
this.createAndSubmitGive(
this.identity,
fromDid,
toDid,
parseFloat(this.hourInput),
this.hourDescriptionInput
);
}
}
}