forked from jsnbuchanan/crowd-funder-for-time-pwa
fix: update import paths from alias to relative - Replace @ alias imports with relative paths in HiddenDidDialog and UserProfileView - Maintain consistent import style across components - Improve build compatibility across different environments This change helps ensure consistent module resolution across different build targets including Capacitor and Electron builds.
188 lines
5.4 KiB
Vue
188 lines
5.4 KiB
Vue
<template>
|
|
<QuickNav selected="Discover" />
|
|
<TopMessage />
|
|
|
|
<!-- CONTENT -->
|
|
<section id="Content" class="p-6 pb-24 max-w-3xl mx-auto">
|
|
<!-- Breadcrumb -->
|
|
<div id="ViewBreadcrumb" class="mb-8">
|
|
<h1 id="ViewHeading" class="text-lg text-center font-light relative px-7">
|
|
<!-- Back -->
|
|
<button
|
|
@click="$router.go(-1)"
|
|
class="text-lg text-center px-2 py-1 absolute -left-2 -top-1"
|
|
>
|
|
<fa icon="chevron-left" class="fa-fw"></fa>
|
|
</button>
|
|
Individual Profile
|
|
</h1>
|
|
</div>
|
|
|
|
<!-- Loading Animation -->
|
|
<div
|
|
class="fixed left-6 mt-16 text-center text-4xl leading-none bg-slate-400 text-white w-14 py-2.5 rounded-full"
|
|
v-if="isLoading"
|
|
>
|
|
<fa icon="spinner" class="fa-spin-pulse"></fa>
|
|
</div>
|
|
|
|
<div v-else-if="profile">
|
|
<!-- Profile Info -->
|
|
<div class="mt-8">
|
|
<div class="text-sm">
|
|
<fa icon="user" class="fa-fw text-slate-400"></fa>
|
|
{{ didInfo(profile.issuerDid, activeDid, allMyDids, allContacts) }}
|
|
</div>
|
|
<p v-if="profile.description" class="mt-4 text-slate-600">
|
|
{{ profile.description }}
|
|
</p>
|
|
</div>
|
|
|
|
<!-- Map for first coordinates -->
|
|
<div v-if="profile?.locLat && profile?.locLon" class="mt-4">
|
|
<h2 class="text-lg font-semibold">Location</h2>
|
|
<div class="h-96 mt-2 w-full">
|
|
<l-map
|
|
ref="profileMap"
|
|
:center="[profile.locLat, profile.locLon]"
|
|
:zoom="12"
|
|
>
|
|
<l-tile-layer
|
|
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
|
layer-type="base"
|
|
name="OpenStreetMap"
|
|
/>
|
|
<l-marker :lat-lng="[profile.locLat, profile.locLon]">
|
|
<l-popup>{{
|
|
didInfo(profile.issuerDid, activeDid, allMyDids, allContacts)
|
|
}}</l-popup>
|
|
</l-marker>
|
|
</l-map>
|
|
</div>
|
|
</div>
|
|
|
|
<!-- Map for second coordinates -->
|
|
<div v-if="profile?.locLat2 && profile?.locLon2" class="mt-4">
|
|
<h2 class="text-lg font-semibold">Second Location</h2>
|
|
<div class="h-96 mt-2 w-full">
|
|
<l-map
|
|
ref="profileMap"
|
|
:center="[profile.locLat2, profile.locLon2]"
|
|
:zoom="12"
|
|
>
|
|
<l-tile-layer
|
|
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
|
layer-type="base"
|
|
name="OpenStreetMap"
|
|
/>
|
|
<l-marker :lat-lng="[profile.locLat2, profile.locLon2]">
|
|
<l-popup>{{
|
|
didInfo(profile.issuerDid, activeDid, allMyDids, allContacts)
|
|
}}</l-popup>
|
|
</l-marker>
|
|
</l-map>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div v-else class="text-center mt-8">
|
|
<p class="text-lg text-slate-500">Profile not found.</p>
|
|
</div>
|
|
</section>
|
|
</template>
|
|
|
|
<script lang="ts">
|
|
import "leaflet/dist/leaflet.css";
|
|
import { Component, Vue } from "vue-facing-decorator";
|
|
import { LMap, LTileLayer, LMarker, LPopup } from "@vue-leaflet/vue-leaflet";
|
|
import { Router, RouteLocationNormalizedLoaded } from "vue-router";
|
|
|
|
import QuickNav from "../components/QuickNav.vue";
|
|
import TopMessage from "../components/TopMessage.vue";
|
|
import {
|
|
DEFAULT_PARTNER_API_SERVER,
|
|
NotificationIface,
|
|
} from "../constants/app";
|
|
import { db } from "../db/index";
|
|
import { Contact } from "../db/tables/contacts";
|
|
import { didInfo, getHeaders } from "../libs/endorserServer";
|
|
import { UserProfile } from "../libs/partnerServer";
|
|
import { retrieveAccountDids } from "../libs/util";
|
|
|
|
@Component({
|
|
components: {
|
|
LMap,
|
|
LMarker,
|
|
LPopup,
|
|
LTileLayer,
|
|
QuickNav,
|
|
TopMessage,
|
|
},
|
|
})
|
|
export default class UserProfileView extends Vue {
|
|
$notify!: (notification: NotificationIface, timeout?: number) => void;
|
|
$router!: Router;
|
|
$route!: RouteLocationNormalizedLoaded;
|
|
|
|
activeDid = "";
|
|
allContacts: Array<Contact> = [];
|
|
allMyDids: Array<string> = [];
|
|
isLoading = true;
|
|
partnerApiServer = DEFAULT_PARTNER_API_SERVER;
|
|
profile: UserProfile | null = null;
|
|
|
|
// make this function available to the Vue template
|
|
didInfo = didInfo;
|
|
|
|
async mounted() {
|
|
const settings = await db.settings.toArray();
|
|
this.activeDid = settings[0]?.activeDid || "";
|
|
this.partnerApiServer =
|
|
settings[0]?.partnerApiServer || this.partnerApiServer;
|
|
|
|
this.allContacts = await db.contacts.toArray();
|
|
this.allMyDids = await retrieveAccountDids();
|
|
|
|
await this.loadProfile();
|
|
}
|
|
|
|
async loadProfile() {
|
|
const profileId: string = this.$route.params.id as string;
|
|
if (!profileId) {
|
|
this.isLoading = false;
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const response = await fetch(
|
|
`${this.partnerApiServer}/api/partner/userProfile/${encodeURIComponent(profileId)}`,
|
|
{
|
|
method: "GET",
|
|
headers: await getHeaders(this.activeDid),
|
|
},
|
|
);
|
|
|
|
if (response.status === 200) {
|
|
const result = await response.json();
|
|
this.profile = result.data;
|
|
} else {
|
|
throw new Error("Failed to load profile");
|
|
}
|
|
} catch (error) {
|
|
console.error("Error loading profile:", error);
|
|
this.$notify(
|
|
{
|
|
group: "alert",
|
|
type: "danger",
|
|
title: "Error",
|
|
text: "There was a problem loading the profile.",
|
|
},
|
|
5000,
|
|
);
|
|
} finally {
|
|
this.isLoading = false;
|
|
}
|
|
}
|
|
}
|
|
</script>
|