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.
280 lines
8.4 KiB
280 lines
8.4 KiB
<template>
|
|
<!-- QUICK NAV -->
|
|
<nav id="QuickNav" class="fixed bottom-0 left-0 right-0 bg-slate-200">
|
|
<ul class="flex text-2xl p-2 gap-2">
|
|
<!-- Home Feed -->
|
|
<li class="basis-1/5 rounded-md text-slate-500">
|
|
<router-link :to="{ name: 'home' }" class="block text-center py-3 px-1">
|
|
<fa icon="house-chimney" class="fa-fw"></fa>
|
|
</router-link>
|
|
</li>
|
|
<!-- Search -->
|
|
<li class="basis-1/5 rounded-md text-slate-500">
|
|
<router-link
|
|
:to="{ name: 'discover' }"
|
|
class="block text-center py-3 px-1"
|
|
>
|
|
<fa icon="magnifying-glass" class="fa-fw"></fa>
|
|
</router-link>
|
|
</li>
|
|
<!-- Projects -->
|
|
<li class="basis-1/5 rounded-md text-slate-500">
|
|
<router-link
|
|
:to="{ name: 'projects' }"
|
|
class="block text-center py-3 px-1"
|
|
>
|
|
<fa icon="folder-open" class="fa-fw"></fa>
|
|
</router-link>
|
|
</li>
|
|
<!-- Commitments -->
|
|
<li class="basis-1/5 rounded-md text-slate-500">
|
|
<router-link
|
|
:to="{ name: 'commitments' }"
|
|
class="block text-center py-3 px-1"
|
|
>
|
|
<fa icon="hand" class="fa-fw"></fa>
|
|
</router-link>
|
|
</li>
|
|
<!-- Profile -->
|
|
<li class="basis-1/5 rounded-md bg-slate-400 text-white">
|
|
<router-link
|
|
:to="{ name: 'account' }"
|
|
class="block text-center py-3 px-1"
|
|
>
|
|
<fa icon="circle-user" class="fa-fw"></fa>
|
|
</router-link>
|
|
</li>
|
|
</ul>
|
|
</nav>
|
|
|
|
<!-- CONTENT -->
|
|
<section id="Content" class="p-6 pb-24">
|
|
<!-- Heading -->
|
|
<h1 id="ViewHeading" class="text-4xl text-center font-light pt-4 mb-8">
|
|
Your Identity
|
|
</h1>
|
|
|
|
<!-- Friend referral requirement notice -->
|
|
<div
|
|
class="bg-amber-200 text-amber-900 border-amber-500 border-dashed border text-center rounded-md overflow-hidden px-4 py-3 mb-4"
|
|
>
|
|
<p class="mb-4">
|
|
<b>Important:</b> before you can create a new project or commit time to
|
|
one, you need a friend to register you.
|
|
</p>
|
|
<button
|
|
id="btnShowQR"
|
|
class="inline-block text-md uppercase bg-amber-600 text-white px-4 py-2 rounded-md"
|
|
>
|
|
Share Your ID
|
|
</button>
|
|
</div>
|
|
|
|
<!-- Identity Details -->
|
|
<div class="bg-slate-100 rounded-md overflow-hidden px-4 py-3 mb-4">
|
|
<h2 class="text-xl font-semibold mb-2">{{ firstName }} {{ lastName }}</h2>
|
|
|
|
<div class="text-slate-500 text-sm font-bold">ID</div>
|
|
<div
|
|
class="text-sm text-slate-500 flex justify-between items-center mb-1"
|
|
>
|
|
<span
|
|
><code>{{ address }}</code>
|
|
<button @click="copy(address)">
|
|
<fa icon="copy" class="text-slate-400 fa-fw ml-1"></fa>
|
|
</button>
|
|
</span>
|
|
<span>
|
|
<button
|
|
class="text-xs uppercase bg-slate-500 text-white px-1.5 py-1 rounded-md"
|
|
>
|
|
<fa icon="share-nodes" class="fa-fw"></fa>
|
|
</button>
|
|
<button
|
|
class="text-xs uppercase bg-slate-500 text-white px-1.5 py-1 rounded-md ml-1"
|
|
>
|
|
<fa icon="qrcode" class="fa-fw"></fa>
|
|
</button>
|
|
</span>
|
|
</div>
|
|
|
|
<div class="text-slate-500 text-sm font-bold">Public Key</div>
|
|
<div class="text-sm text-slate-500 mb-1">
|
|
<span
|
|
><code>{{ publicHex }}</code>
|
|
<button @click="copy(publicHex)">
|
|
<fa icon="copy" class="text-slate-400 fa-fw ml-1"></fa>
|
|
</button>
|
|
</span>
|
|
</div>
|
|
|
|
<div class="text-slate-500 text-sm font-bold">Derivation Path</div>
|
|
<div class="text-sm text-slate-500 mb-1">
|
|
<span
|
|
><code>{{ derivationPath }}</code>
|
|
<button @click="copy(derivationPath)">
|
|
<fa icon="copy" class="text-slate-400 fa-fw ml-1"></fa>
|
|
</button>
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
<router-link
|
|
:to="{ name: 'new-edit-account' }"
|
|
class="block text-center text-lg font-bold uppercase bg-blue-600 text-white px-2 py-3 rounded-md mb-8"
|
|
>Edit Identity</router-link
|
|
>
|
|
|
|
<h3 class="text-sm uppercase font-semibold mb-3">Contact Actions</h3>
|
|
|
|
<a
|
|
href="contact-scan.html"
|
|
class="block w-full text-center text-md uppercase bg-slate-500 text-white px-1.5 py-2 rounded-md mb-6"
|
|
>Scan New Contact</a
|
|
>
|
|
|
|
<h3 class="text-sm uppercase font-semibold mb-3">Identity Actions</h3>
|
|
|
|
<a
|
|
href=""
|
|
class="block w-full text-center text-md uppercase bg-slate-500 text-white px-1.5 py-2 rounded-md mb-2"
|
|
>Backup Seed</a
|
|
>
|
|
<a
|
|
href=""
|
|
class="block w-full text-center text-md uppercase bg-slate-500 text-white px-1.5 py-2 rounded-md mb-6"
|
|
>Backup Other Data</a
|
|
>
|
|
|
|
<!-- QR code popup -->
|
|
<dialog id="dlgQR" class="backdrop:bg-black/75 rounded-md">
|
|
<form method="dialog">
|
|
<div class="text-slate-500 text-center">
|
|
<b>ID:</b> <code>did:peer:kl45kj41lk451kl3</code>
|
|
</div>
|
|
<img src="img/sample-qr-code.png" class="w-full mb-3" />
|
|
|
|
<button
|
|
value="cancel"
|
|
class="block w-full text-center text-md uppercase bg-slate-500 text-white px-1.5 py-2 rounded-md mb-2"
|
|
>
|
|
Copy to Clipboard
|
|
</button>
|
|
<button
|
|
value="cancel"
|
|
class="block w-full text-center text-md uppercase bg-slate-500 text-white px-1.5 py-2 rounded-md"
|
|
>
|
|
Close
|
|
</button>
|
|
</form>
|
|
</dialog>
|
|
|
|
<div v-bind:class="computedAlertClassNames()">
|
|
<button
|
|
class="close-button bg-slate-200 w-8 leading-loose rounded-full absolute top-2 right-2"
|
|
@click="onClickClose()"
|
|
>
|
|
<fa icon="xmark"></fa>
|
|
</button>
|
|
<h4 class="font-bold pr-5">{{ alertTitle }}</h4>
|
|
<p>{{ alertMessage }}</p>
|
|
</div>
|
|
</section>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import { Options, Vue } from "vue-class-component";
|
|
import { useClipboard } from "@vueuse/core";
|
|
import { deriveAddress, generateSeed, newIdentifier } from "../libs/crypto";
|
|
import { db } from "../db";
|
|
//import { testServerRegisterUser } from "../test";
|
|
|
|
@Options({
|
|
components: {},
|
|
})
|
|
export default class AccountViewView extends Vue {
|
|
firstName =
|
|
localStorage.getItem("firstName") === null
|
|
? "--"
|
|
: localStorage.getItem("firstName");
|
|
lastName =
|
|
localStorage.getItem("lastName") === null
|
|
? "--"
|
|
: localStorage.getItem("lastName");
|
|
mnemonic = "";
|
|
address = "";
|
|
privateHex = "";
|
|
publicHex = "";
|
|
derivationPath = "";
|
|
copy = useClipboard().copy;
|
|
|
|
// This registers current user in vue plugin with: $vm.ctx.testRegisterUser()
|
|
//testRegisterUser = testServerRegisterUser;
|
|
|
|
// 'created' hook runs when the Vue instance is first created
|
|
async created() {
|
|
await db.open();
|
|
const num_accounts = await db.accounts.count();
|
|
if (num_accounts === 0) {
|
|
try {
|
|
this.mnemonic = generateSeed();
|
|
[this.address, this.privateHex, this.publicHex, this.derivationPath] =
|
|
deriveAddress(this.mnemonic);
|
|
|
|
const newId = newIdentifier(
|
|
this.address,
|
|
this.publicHex,
|
|
this.privateHex,
|
|
this.derivationPath
|
|
);
|
|
await db.accounts.add({
|
|
dateCreated: new Date(),
|
|
derivationPath: this.derivationPath,
|
|
identity: JSON.stringify(newId),
|
|
mnemonic: this.mnemonic,
|
|
publicKeyHex: newId.keys[0].publicKeyHex,
|
|
});
|
|
} catch (err) {
|
|
this.alertMessage =
|
|
"Clear your cache and start over. Root Cause: " + err;
|
|
this.alertTitle = "Error Creating Account";
|
|
this.isAlertVisible = true;
|
|
console.log(err);
|
|
}
|
|
}
|
|
|
|
const accounts = await db.accounts.toArray();
|
|
const identity = JSON.parse(accounts[0].identity);
|
|
this.address = identity.did;
|
|
this.publicHex = identity.keys[0].publicKeyHex;
|
|
this.derivationPath = identity.keys[0].meta.derivationPath;
|
|
}
|
|
|
|
alertMessage = "";
|
|
alertTitle = "";
|
|
isAlertVisible = false;
|
|
|
|
public onClickClose() {
|
|
this.isAlertVisible = false;
|
|
this.alertTitle = "";
|
|
this.alertMessage = "";
|
|
}
|
|
|
|
public computedAlertClassNames() {
|
|
return {
|
|
hidden: !this.isAlertVisible,
|
|
"dismissable-alert": true,
|
|
"bg-slate-100": true,
|
|
"p-5": true,
|
|
rounded: true,
|
|
"drop-shadow-lg": true,
|
|
absolute: true,
|
|
"top-3": true,
|
|
"inset-x-3": true,
|
|
"transition-transform": true,
|
|
"ease-in": true,
|
|
"duration-300": true,
|
|
};
|
|
}
|
|
}
|
|
</script>
|
|
|