You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
165 lines
4.7 KiB
165 lines
4.7 KiB
<template>
|
|
<!-- CONTENT -->
|
|
<section id="Content" class="p-6 pb-24">
|
|
<!-- Breadcrumb -->
|
|
<div id="ViewBreadcrumb" class="mb-8">
|
|
<h1 class="text-lg text-center font-light relative px-7">
|
|
<!-- Cancel -->
|
|
<router-link
|
|
:to="{ name: 'project' }"
|
|
class="text-lg text-center px-2 py-1 absolute -left-2 -top-1"
|
|
><fa icon="chevron-left" class="fa-fw"></fa
|
|
></router-link>
|
|
[New/Edit] Project
|
|
</h1>
|
|
</div>
|
|
|
|
<!-- Project Details -->
|
|
<!-- Image - (see design model) Empty -->
|
|
|
|
<!-- Image - Populated -->
|
|
<div class="relative mb-4 rounded-md overflow-hidden">
|
|
<div class="absolute top-3 right-3 flex gap-2">
|
|
<button
|
|
class="text-md font-bold uppercase bg-blue-600 text-white px-3 py-2 rounded"
|
|
>
|
|
<fa icon="pen" class="fa-fw"></fa>
|
|
</button>
|
|
<button
|
|
class="text-md font-bold uppercase bg-red-600 text-white px-3 py-2 rounded"
|
|
>
|
|
<fa icon="trash-can" class="fa-fw"></fa>
|
|
</button>
|
|
</div>
|
|
<img src="https://picsum.photos/800/400" class="w-full" />
|
|
</div>
|
|
|
|
<input
|
|
type="text"
|
|
placeholder="Project Name"
|
|
class="block w-full rounded border border-slate-400 mb-4 px-3 py-2"
|
|
v-model="projectName"
|
|
/>
|
|
|
|
<textarea
|
|
placeholder="Description"
|
|
class="block w-full rounded border border-slate-400 mb-4 px-3 py-2"
|
|
rows="5"
|
|
v-model="description"
|
|
></textarea>
|
|
<div class="text-xs text-slate-500 italic -mt-3 mb-4">
|
|
88/500 max. characters
|
|
</div>
|
|
|
|
<div class="mt-8">
|
|
<button
|
|
class="block w-full text-center text-lg font-bold uppercase bg-blue-600 text-white px-2 py-3 rounded-md mb-2"
|
|
@click="onSaveProjectClick()"
|
|
>
|
|
Save Project
|
|
</button>
|
|
<button
|
|
type="button"
|
|
class="block w-full text-center text-md uppercase bg-slate-500 text-white px-1.5 py-2 rounded-md"
|
|
@click="onCancelClick()"
|
|
>
|
|
Cancel
|
|
</button>
|
|
</div>
|
|
</section>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import { Options, Vue } from "vue-class-component";
|
|
import { AppString } from "@/constants/app";
|
|
import { db } from "../db";
|
|
import { accessToken, SimpleSigner } from "@/libs/crypto";
|
|
import * as didJwt from "did-jwt";
|
|
import { IIdentifier } from "@veramo/core";
|
|
import { useAppStore } from "@/store/app";
|
|
|
|
@Options({
|
|
components: {},
|
|
})
|
|
export default class NewEditProjectView extends Vue {
|
|
projectName = "";
|
|
description = "";
|
|
|
|
private async SaveProject(identity: IIdentifier) {
|
|
const address = identity.did;
|
|
// Make a claim
|
|
const vcClaim = {
|
|
"@context": "https://schema.org",
|
|
"@type": "PlanAction",
|
|
identifier: address,
|
|
name: this.projectName,
|
|
description: this.description,
|
|
};
|
|
// Make a payload for the claim
|
|
const vcPayload = {
|
|
sub: "PlanAction",
|
|
vc: {
|
|
"@context": ["https://www.w3.org/2018/credentials/v1"],
|
|
type: ["VerifiableCredential"],
|
|
credentialSubject: vcClaim,
|
|
},
|
|
};
|
|
// create a signature using private key of identity
|
|
if (
|
|
identity.keys[0].privateKeyHex !== "undefined" &&
|
|
identity.keys[0].privateKeyHex !== null
|
|
) {
|
|
// eslint-disable-next-line
|
|
const privateKeyHex: string = identity.keys[0].privateKeyHex!;
|
|
const signer = await SimpleSigner(privateKeyHex);
|
|
const alg = undefined;
|
|
// create a JWT for the request
|
|
const vcJwt: string = await didJwt.createJWT(vcPayload, {
|
|
alg: alg,
|
|
issuer: identity.did,
|
|
signer: signer,
|
|
});
|
|
|
|
// Make the xhr request payload
|
|
|
|
const payload = JSON.stringify({ jwtEncoded: vcJwt });
|
|
const endorserApiServer = AppString.DEFAULT_ENDORSER_API_SERVER;
|
|
const url = endorserApiServer + "/api/claim";
|
|
const token = await accessToken(identity);
|
|
const headers = {
|
|
"Content-Type": "application/json",
|
|
Authorization: "Bearer " + token,
|
|
};
|
|
|
|
try {
|
|
const resp = await this.axios.post(url, payload, { headers });
|
|
console.log(resp.status, resp.data);
|
|
useAppStore().setProjectId(resp.data);
|
|
const route = {
|
|
name: "project",
|
|
};
|
|
console.log(route);
|
|
this.$router.push(route);
|
|
} catch (error) {
|
|
console.log(error);
|
|
}
|
|
}
|
|
}
|
|
|
|
public async onSaveProjectClick() {
|
|
await db.open();
|
|
const num_accounts = await db.accounts.count();
|
|
if (num_accounts === 0) {
|
|
console.log("Problem! Should have a profile!");
|
|
} else {
|
|
const accounts = await db.accounts.toArray();
|
|
const identity = JSON.parse(accounts[0].identity);
|
|
this.SaveProject(identity);
|
|
}
|
|
}
|
|
|
|
public onCancelClick() {
|
|
this.$router.back();
|
|
}
|
|
}
|
|
</script>
|
|
|