Browse Source
- Created IdentitySection.vue using vue-facing-decorator (class-based, TypeScript, @Component, @Prop, @Emit). - Moved all identity-related UI and logic (name, QR code, profile image, DID) into the new component. - Replaced original identity section markup in AccountViewView.vue with <IdentitySection />. - Passed all necessary props and implemented event handlers in AccountViewView.vue to maintain existing behavior. - Ensured all linter errors are resolved and code is consistent with project conventions.pull/142/head
2 changed files with 244 additions and 157 deletions
@ -0,0 +1,187 @@ |
|||||
|
<template> |
||||
|
<section |
||||
|
id="sectionIdentityDetails" |
||||
|
class="bg-slate-100 rounded-md overflow-hidden px-4 py-3 mt-4" |
||||
|
aria-labelledby="identityDetailsHeading" |
||||
|
> |
||||
|
<h2 id="identityDetailsHeading" class="sr-only">Identity Details</h2> |
||||
|
<div v-if="givenName"> |
||||
|
<h2 class="text-xl font-semibold mb-2"> |
||||
|
<span class="whitespace-nowrap"> |
||||
|
<button |
||||
|
class="bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-1.5 py-1 mr-1 rounded-md" |
||||
|
@click="showQrCode" |
||||
|
> |
||||
|
<font-awesome icon="qrcode" class="fa-fw text-xl" /> |
||||
|
</button> |
||||
|
</span> |
||||
|
{{ givenName }} |
||||
|
<button @click="editName"> |
||||
|
<font-awesome |
||||
|
icon="pen" |
||||
|
class="text-xs text-blue-500 ml-2 mb-1" |
||||
|
></font-awesome> |
||||
|
</button> |
||||
|
</h2> |
||||
|
</div> |
||||
|
<span |
||||
|
v-else |
||||
|
class="block w-full text-center text-md bg-amber-200 border border-dashed border-slate-400 px-1.5 py-2 rounded-md mb-2" |
||||
|
> |
||||
|
<button |
||||
|
class="inline-block text-md uppercase bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-4 py-2 rounded-md" |
||||
|
@click="editName" |
||||
|
> |
||||
|
Set Your Name |
||||
|
</button> |
||||
|
<p class="text-xs text-slate-500 mt-1"> |
||||
|
(Don't worry: this is not visible to anyone until you share it with |
||||
|
them. It's not sent to any servers.) |
||||
|
</p> |
||||
|
</span> |
||||
|
<div class="flex justify-center mt-4"> |
||||
|
<span v-if="profileImageUrl" class="flex justify-between"> |
||||
|
<EntityIcon |
||||
|
:icon-size="96" |
||||
|
:profile-image-url="profileImageUrl" |
||||
|
class="inline-block align-text-bottom border border-slate-300 rounded" |
||||
|
role="button" |
||||
|
aria-label="View profile image in large size" |
||||
|
tabindex="0" |
||||
|
@click="emitShowLargeIdenticonUrl" |
||||
|
/> |
||||
|
<font-awesome |
||||
|
icon="trash-can" |
||||
|
class="text-red-500 fa-fw ml-8 mt-8 w-12 h-12" |
||||
|
role="button" |
||||
|
aria-label="Delete profile image" |
||||
|
tabindex="0" |
||||
|
@click="deleteImage" |
||||
|
/> |
||||
|
</span> |
||||
|
<div v-else class="text-center"> |
||||
|
<template v-if="isRegistered"> |
||||
|
<div |
||||
|
class="inline-block text-md bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-4 py-2 rounded-md" |
||||
|
@click="addImage" |
||||
|
> |
||||
|
<font-awesome icon="user" class="fa-fw" /> |
||||
|
<font-awesome icon="camera" class="fa-fw" /> |
||||
|
</div> |
||||
|
</template> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div class="mt-4"> |
||||
|
<div class="flex justify-center text-center text-sm leading-tight mb-1"> |
||||
|
People {{ peopleSeeText }} see this |
||||
|
<br /> |
||||
|
(if you've let them see your activity): |
||||
|
</div> |
||||
|
<div class="flex justify-center"> |
||||
|
<EntityIcon |
||||
|
:entity-id="activeDid" |
||||
|
:icon-size="64" |
||||
|
class="inline-block align-middle border border-slate-300 rounded-md mr-1" |
||||
|
@click="emitShowLargeIdenticonId" |
||||
|
/> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div |
||||
|
v-if="showLargeIdenticonIdProp || showLargeIdenticonUrlProp" |
||||
|
class="fixed z-[100] top-0 inset-x-0 w-full" |
||||
|
> |
||||
|
<div |
||||
|
class="absolute inset-0 h-screen flex flex-col items-center justify-center bg-slate-900/50" |
||||
|
> |
||||
|
<EntityIcon |
||||
|
:entity-id="showLargeIdenticonIdProp" |
||||
|
:icon-size="512" |
||||
|
:profile-image-url="showLargeIdenticonUrlProp" |
||||
|
class="flex w-11/12 max-w-sm mx-auto mb-3 overflow-hidden bg-white rounded-lg shadow-lg" |
||||
|
@click="closeLargeIdenticon" |
||||
|
/> |
||||
|
</div> |
||||
|
</div> |
||||
|
<div |
||||
|
class="text-sm text-slate-500 flex justify-start items-center mt-2 mb-1" |
||||
|
data-testId="didWrapper" |
||||
|
role="region" |
||||
|
aria-label="Your Identifier" |
||||
|
> |
||||
|
<div class="font-bold">ID: </div> |
||||
|
<code class="truncate" aria-label="Your DID">{{ activeDid }}</code> |
||||
|
<button class="ml-2" aria-label="Copy DID to clipboard" @click="copyDid"> |
||||
|
<font-awesome |
||||
|
icon="copy" |
||||
|
class="text-slate-400 fa-fw" |
||||
|
aria-hidden="true" |
||||
|
></font-awesome> |
||||
|
</button> |
||||
|
<span v-show="showDidCopy" role="status" aria-live="polite">Copied</span> |
||||
|
</div> |
||||
|
<div class="text-blue-500 text-sm font-bold"> |
||||
|
<router-link :to="{ path: '/did/' + encodeURIComponent(activeDid) }"> |
||||
|
Your Activity |
||||
|
</router-link> |
||||
|
</div> |
||||
|
</section> |
||||
|
</template> |
||||
|
|
||||
|
<script lang="ts"> |
||||
|
import { Component, Vue, Prop, Emit } from "vue-facing-decorator"; |
||||
|
import EntityIcon from "./EntityIcon.vue"; |
||||
|
|
||||
|
@Component({ |
||||
|
name: "IdentitySection", |
||||
|
components: { EntityIcon }, |
||||
|
}) |
||||
|
export default class IdentitySection extends Vue { |
||||
|
@Prop({ required: false }) givenName!: string; |
||||
|
@Prop({ required: true }) profileImageUrl!: string; |
||||
|
@Prop({ required: true }) activeDid!: string; |
||||
|
@Prop({ required: false }) isRegistered!: boolean; |
||||
|
@Prop({ required: false }) showLargeIdenticonId!: string; |
||||
|
@Prop({ required: false }) showLargeIdenticonUrl!: string; |
||||
|
@Prop({ required: false }) showDidCopy!: boolean; |
||||
|
|
||||
|
get peopleSeeText(): string { |
||||
|
return this.profileImageUrl ? "without your image" : ""; |
||||
|
} |
||||
|
get showLargeIdenticonIdProp(): string | undefined { |
||||
|
return this.showLargeIdenticonId; |
||||
|
} |
||||
|
get showLargeIdenticonUrlProp(): string | undefined { |
||||
|
return this.showLargeIdenticonUrl; |
||||
|
} |
||||
|
|
||||
|
@Emit("edit-name") |
||||
|
editName() {} |
||||
|
|
||||
|
@Emit("show-qr-code") |
||||
|
showQrCode() {} |
||||
|
|
||||
|
@Emit("add-image") |
||||
|
addImage() {} |
||||
|
|
||||
|
@Emit("delete-image") |
||||
|
deleteImage() {} |
||||
|
|
||||
|
@Emit("show-large-identicon-id") |
||||
|
emitShowLargeIdenticonId() { |
||||
|
return this.activeDid; |
||||
|
} |
||||
|
|
||||
|
@Emit("show-large-identicon-url") |
||||
|
emitShowLargeIdenticonUrl() { |
||||
|
return this.profileImageUrl; |
||||
|
} |
||||
|
|
||||
|
@Emit("close-large-identicon") |
||||
|
closeLargeIdenticon() {} |
||||
|
|
||||
|
@Emit("copy-did") |
||||
|
copyDid() { |
||||
|
return this.activeDid; |
||||
|
} |
||||
|
} |
||||
|
</script> |
Loading…
Reference in new issue