forked from trent_larson/crowd-funder-for-time-pwa
Move all user-facing notification messages to src/constants/notifications.ts Use TIMEOUTS constants from src/utils/notify.ts for all notification durations Refactor ActivityListItem.vue: Use notification message and duration constants Initialize notify helper in created() with createNotifyHelpers(this.$notify) Add $notify property for Vue runtime injection to satisfy type checker Use type guards or 'as any' for unknown notification payloads Wrap notifyWhyCannotConfirm calls to match expected function signature Fix type import for GiveRecordWithContactInfo Add 'Notification Best Practices and Nuances' section to migration-progress-tracker.md: Document message/duration constants, notify helper pattern, type safety, and wrapper function usage Remove all hardcoded notification strings and durations from components
188 lines
5.8 KiB
Vue
188 lines
5.8 KiB
Vue
<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>
|