Browse Source

start linking gives to projects

pull/27/head
Trent Larson 1 year ago
parent
commit
643f777d10
  1. 12
      src/libs/endorserServer.ts
  2. 120
      src/views/ProjectViewView.vue

12
src/libs/endorserServer.ts

@ -46,6 +46,7 @@ export interface GiveVerifiableCredential {
"@type": string; "@type": string;
agent?: { identifier: string }; agent?: { identifier: string };
description?: string; description?: string;
fulfills?: { "@type": string; identifier: string };
identifier?: string; identifier?: string;
object?: { amountOfThisGood: number; unitCode: string }; object?: { amountOfThisGood: number; unitCode: string };
recipient: { identifier: string }; recipient: { identifier: string };
@ -95,7 +96,7 @@ export function didInfo(did, identifiers, contacts) {
/** /**
* For result, see https://endorser.ch:3000/api-docs/#/claims/post_api_v2_claim * For result, see https://endorser.ch:3000/api-docs/#/claims/post_api_v2_claim
*
* @param identity * @param identity
* @param fromDid may be null * @param fromDid may be null
* @param toDid * @param toDid
@ -109,7 +110,8 @@ export async function createAndSubmitGive(
fromDid: string, fromDid: string,
toDid: string, toDid: string,
description: string, description: string,
hours: number hours: number,
fulfillsProjectHandleId: string
): Promise<AxiosResponse<ClaimResult> | InternalError> { ): Promise<AxiosResponse<ClaimResult> | InternalError> {
// Make a claim // Make a claim
const vcClaim: GiveVerifiableCredential = { const vcClaim: GiveVerifiableCredential = {
@ -126,6 +128,12 @@ export async function createAndSubmitGive(
if (hours) { if (hours) {
vcClaim.object = { amountOfThisGood: hours, unitCode: "HUR" }; vcClaim.object = { amountOfThisGood: hours, unitCode: "HUR" };
} }
if (fulfillsProjectHandleId) {
vcClaim.fulfills = {
"@type": "PlanAction",
identifier: fulfillsProjectHandleId,
};
}
// Make a payload for the claim // Make a payload for the claim
const vcPayload = { const vcPayload = {
vc: { vc: {

120
src/views/ProjectViewView.vue

@ -9,7 +9,7 @@
></router-link> ></router-link>
</li> </li>
<!-- Search --> <!-- Search -->
<li class="basis-1/5 rounded-md bg-slate-400 text-white"> <li class="basis-1/5 rounded-md text-slate-500">
<router-link <router-link
:to="{ name: 'discover' }" :to="{ name: 'discover' }"
class="block text-center py-3 px-1" class="block text-center py-3 px-1"
@ -17,7 +17,7 @@
></router-link> ></router-link>
</li> </li>
<!-- Projects --> <!-- Projects -->
<li class="basis-1/5 rounded-md text-slate-500"> <li class="basis-1/5 rounded-md bg-slate-400 text-white">
<router-link <router-link
:to="{ name: 'projects' }" :to="{ name: 'projects' }"
class="block text-center py-3 px-1" class="block text-center py-3 px-1"
@ -108,14 +108,31 @@
</button> </button>
</div> </div>
<button
@click="openDialog()"
class="block text-center text-lg font-bold uppercase bg-blue-600 text-white px-2 py-3 rounded-md mb-8"
>
Given
</button>
<GiftedDialog
ref="customDialog"
@dialog-result="handleDialogResult"
message="Confirm to publish to the world."
>
</GiftedDialog>
<!-- Commit --> <!-- Commit -->
<!--
<router-link <router-link
:to="{ name: 'new-edit-commitment' }" :to="{ name: 'new-edit-commitment' }"
class="block text-center text-lg font-bold uppercase bg-blue-600 text-white px-2 py-3 rounded-md mb-8" class="block text-center text-lg font-bold uppercase bg-blue-600 text-white px-2 py-3 rounded-md mb-8"
>Make Commitment</router-link >Make Commitment</router-link
> >
-->
<!-- Commitments --> <!-- Commitments -->
<!--
<div class="bg-slate-100 px-4 py-3 rounded-md"> <div class="bg-slate-100 px-4 py-3 rounded-md">
<h3 class="text-sm uppercase font-semibold mb-3">Commitments</h3> <h3 class="text-sm uppercase font-semibold mb-3">Commitments</h3>
@ -142,6 +159,7 @@
</li> </li>
</ul> </ul>
</div> </div>
-->
</section> </section>
</template> </template>
@ -151,15 +169,18 @@ import * as moment from "moment";
import * as R from "ramda"; import * as R from "ramda";
import { Options, Vue } from "vue-class-component"; import { Options, Vue } from "vue-class-component";
import GiftedDialog from "@/components/GiftedDialog.vue";
import { accountsDB, db } from "@/db"; import { accountsDB, db } from "@/db";
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings"; import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
import { createAndSubmitGive } from "@/libs/endorserServer";
import { accessToken } from "@/libs/crypto"; import { accessToken } from "@/libs/crypto";
import { IIdentifier } from "@veramo/core"; import { IIdentifier } from "@veramo/core";
@Options({ @Options({
components: {}, components: { GiftedDialog },
}) })
export default class ProjectViewView extends Vue { export default class ProjectViewView extends Vue {
activeDid = "";
apiServer = ""; apiServer = "";
expanded = false; expanded = false;
name = ""; name = "";
@ -167,7 +188,7 @@ export default class ProjectViewView extends Vue {
truncatedDesc = ""; truncatedDesc = "";
truncateLength = 40; truncateLength = 40;
timeSince = ""; timeSince = "";
projectId = localStorage.getItem("projectId") || ""; projectId = localStorage.getItem("projectId") || ""; // handle ID
errorMessage = ""; errorMessage = "";
onEditClick() { onEditClick() {
@ -230,7 +251,7 @@ export default class ProjectViewView extends Vue {
async created() { async created() {
await db.open(); await db.open();
const settings = await db.settings.get(MASTER_SETTINGS_KEY); const settings = await db.settings.get(MASTER_SETTINGS_KEY);
const activeDid = settings?.activeDid || ""; this.activeDid = settings?.activeDid || "";
this.apiServer = settings?.apiServer || ""; this.apiServer = settings?.apiServer || "";
await accountsDB.open(); await accountsDB.open();
@ -239,7 +260,7 @@ export default class ProjectViewView extends Vue {
console.error("Problem! Should have a profile!"); console.error("Problem! Should have a profile!");
} else { } else {
const accounts = await accountsDB.accounts.toArray(); const accounts = await accountsDB.accounts.toArray();
const account = R.find((acc) => acc.did === activeDid, accounts); const account = R.find((acc) => acc.did === this.activeDid, accounts);
const identity = JSON.parse(account?.identity || "null"); const identity = JSON.parse(account?.identity || "null");
if (!identity) { if (!identity) {
throw new Error("No identity found."); throw new Error("No identity found.");
@ -247,5 +268,92 @@ export default class ProjectViewView extends Vue {
this.LoadProject(identity); this.LoadProject(identity);
} }
} }
openDialog(contact) {
this.$refs.customDialog.open(contact);
}
handleDialogResult(result) {
if (result.action === "confirm") {
return new Promise((resolve) => {
this.recordGive(result.contact, result.description, result.hours);
resolve();
});
} else {
// action was "cancel" so do nothing
}
}
/**
*
* @param contact may be null
* @param description may be an empty string
* @param hours may be 0
*/
async recordGive(contact, description, hours) {
if (this.activeDid == null) {
this.alertTitle = "Error";
this.alertMessage =
"You must select an identity before you can record a give.";
return;
}
const accounts = await accountsDB.accounts.toArray();
const account = R.find((acc) => acc.did === this.activeDid, accounts);
const identity = JSON.parse(account?.identity || "null");
if (!identity) {
throw new Error("No identity found.");
}
createAndSubmitGive(
this.axios,
this.apiServer,
identity,
contact?.did,
this.activeDid,
description,
hours,
this.projectId
)
.then((result) => {
if (result.status != 201 || result.data?.error) {
console.log("Error with give result:", result);
this.alertTitle = "Error";
this.alertMessage =
result.data?.message || "There was an error recording the give.";
} else {
this.alertTitle = "Success";
this.alertMessage = "That gift was recorded.";
//this.updateAllFeed(); // full update is overkill but we should show something
}
})
.catch((e) => {
console.log("Error with give caught:", e);
this.alertTitle = "Error";
this.alertMessage =
e.userMessage || "There was an error recording the give.";
});
}
// This same popup code is in many files.
alertMessage = "";
alertTitle = "";
public onClickClose() {
this.alertTitle = "";
this.alertMessage = "";
}
public computedAlertClassNames() {
return {
hidden: !this.alertMessage,
"dismissable-alert": true,
"bg-slate-100": true,
"p-5": true,
rounded: true,
"drop-shadow-lg": true,
fixed: true,
"top-3": true,
"inset-x-3": true,
"transition-transform": true,
"ease-in": true,
"duration-300": true,
};
}
} }
</script> </script>

Loading…
Cancel
Save