forked from jsnbuchanan/crowd-funder-for-time-pwa
add map and location for user profile
This commit is contained in:
@@ -278,12 +278,54 @@
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<textarea
|
<textarea
|
||||||
v-model="userProfile"
|
v-model="userProfileDesc"
|
||||||
class="w-full h-32 p-2 border border-slate-300 rounded-md"
|
class="w-full h-32 p-2 border border-slate-300 rounded-md"
|
||||||
placeholder="Write something about yourself for the public..."
|
placeholder="Write something about yourself for the public..."
|
||||||
:readonly="loadingProfile || savingProfile"
|
:readonly="loadingProfile || savingProfile"
|
||||||
:class="{ 'bg-slate-100': loadingProfile || savingProfile }"
|
:class="{ 'bg-slate-100': loadingProfile || savingProfile }"
|
||||||
></textarea>
|
></textarea>
|
||||||
|
|
||||||
|
<div
|
||||||
|
class="flex items-center mb-4"
|
||||||
|
@click="toggleUserProfileLocation"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
class="mr-2"
|
||||||
|
v-model="includeUserProfileLocation"
|
||||||
|
/>
|
||||||
|
<label for="includeUserProfileLocation">Include Location</label>
|
||||||
|
</div>
|
||||||
|
<div v-if="includeUserProfileLocation" class="mb-4 aspect-video">
|
||||||
|
<p class="text-sm mb-2 text-slate-500">
|
||||||
|
For your security, choose a location nearby but not exactly at your
|
||||||
|
place.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<l-map
|
||||||
|
ref="map"
|
||||||
|
v-model:zoom="zoom"
|
||||||
|
:center="[userProfileLatitude, userProfileLongitude]"
|
||||||
|
class="!z-40 rounded-md"
|
||||||
|
@click="
|
||||||
|
(event: LeafletMouseEvent) => {
|
||||||
|
userProfileLatitude = event.latlng.lat;
|
||||||
|
userProfileLongitude = event.latlng.lng;
|
||||||
|
}
|
||||||
|
"
|
||||||
|
>
|
||||||
|
<l-tile-layer
|
||||||
|
url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png"
|
||||||
|
layer-type="base"
|
||||||
|
name="OpenStreetMap"
|
||||||
|
/>
|
||||||
|
<l-marker
|
||||||
|
v-if="userProfileLatitude && userProfileLongitude"
|
||||||
|
:lat-lng="[userProfileLatitude, userProfileLongitude]"
|
||||||
|
@click="confirmEraseLatLong()"
|
||||||
|
/>
|
||||||
|
</l-map>
|
||||||
|
</div>
|
||||||
<button
|
<button
|
||||||
@click="saveProfile"
|
@click="saveProfile"
|
||||||
class="mt-2 px-4 py-2 bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white rounded-md"
|
class="mt-2 px-4 py-2 bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white rounded-md"
|
||||||
@@ -830,17 +872,21 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import "leaflet/dist/leaflet.css";
|
||||||
|
|
||||||
import { AxiosError } from "axios";
|
import { AxiosError } from "axios";
|
||||||
import { Buffer } from "buffer/";
|
import { Buffer } from "buffer/";
|
||||||
import Dexie from "dexie";
|
import Dexie from "dexie";
|
||||||
import "dexie-export-import";
|
import "dexie-export-import";
|
||||||
import { ImportProgress } from "dexie-export-import/dist/import";
|
import { ImportProgress } from "dexie-export-import/dist/import";
|
||||||
|
import { LeafletMouseEvent } from "leaflet";
|
||||||
import * as R from "ramda";
|
import * as R from "ramda";
|
||||||
import { IIdentifier } from "@veramo/core";
|
import { IIdentifier } from "@veramo/core";
|
||||||
import { ref } from "vue";
|
import { ref } from "vue";
|
||||||
import { Component, Vue } from "vue-facing-decorator";
|
import { Component, Vue } from "vue-facing-decorator";
|
||||||
import { Router } from "vue-router";
|
import { Router } from "vue-router";
|
||||||
import { useClipboard } from "@vueuse/core";
|
import { useClipboard } from "@vueuse/core";
|
||||||
|
import { LMap, LMarker, LTileLayer } from "@vue-leaflet/vue-leaflet";
|
||||||
|
|
||||||
import EntityIcon from "@/components/EntityIcon.vue";
|
import EntityIcon from "@/components/EntityIcon.vue";
|
||||||
import ImageMethodDialog from "@/components/ImageMethodDialog.vue";
|
import ImageMethodDialog from "@/components/ImageMethodDialog.vue";
|
||||||
@@ -891,6 +937,10 @@ const inputImportFileNameRef = ref<Blob>();
|
|||||||
components: {
|
components: {
|
||||||
EntityIcon,
|
EntityIcon,
|
||||||
ImageMethodDialog,
|
ImageMethodDialog,
|
||||||
|
LeafletMouseEvent,
|
||||||
|
LMap,
|
||||||
|
LMarker,
|
||||||
|
LTileLayer,
|
||||||
PushNotificationPermission,
|
PushNotificationPermission,
|
||||||
QuickNav,
|
QuickNav,
|
||||||
TopMessage,
|
TopMessage,
|
||||||
@@ -915,6 +965,7 @@ export default class AccountViewView extends Vue {
|
|||||||
hideRegisterPromptOnNewContact = false;
|
hideRegisterPromptOnNewContact = false;
|
||||||
imageLimits: ImageRateLimits | null = null;
|
imageLimits: ImageRateLimits | null = null;
|
||||||
imageServer = "";
|
imageServer = "";
|
||||||
|
includeUserProfileLocation = false;
|
||||||
isRegistered = false;
|
isRegistered = false;
|
||||||
limitsMessage = "";
|
limitsMessage = "";
|
||||||
loadingLimits = false;
|
loadingLimits = false;
|
||||||
@@ -948,7 +999,10 @@ export default class AccountViewView extends Vue {
|
|||||||
warnIfTestServer = false;
|
warnIfTestServer = false;
|
||||||
webPushServer = "";
|
webPushServer = "";
|
||||||
webPushServerInput = "";
|
webPushServerInput = "";
|
||||||
userProfile = "";
|
userProfileDesc = "";
|
||||||
|
userProfileLatitude = 0;
|
||||||
|
userProfileLongitude = 0;
|
||||||
|
zoom = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Async function executed when the component is mounted.
|
* Async function executed when the component is mounted.
|
||||||
@@ -971,7 +1025,12 @@ export default class AccountViewView extends Vue {
|
|||||||
{ headers },
|
{ headers },
|
||||||
);
|
);
|
||||||
if (response.status === 200) {
|
if (response.status === 200) {
|
||||||
this.userProfile = response.data.description || "";
|
this.userProfileDesc = response.data.description || "";
|
||||||
|
this.userProfileLatitude = response.data.locLat || 0;
|
||||||
|
this.userProfileLongitude = response.data.locLon || 0;
|
||||||
|
if (this.userProfileLatitude && this.userProfileLongitude) {
|
||||||
|
this.includeUserProfileLocation = true;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
// won't get here because axios throws an error instead
|
// won't get here because axios throws an error instead
|
||||||
throw Error("Unable to load profile.");
|
throw Error("Unable to load profile.");
|
||||||
@@ -1734,11 +1793,16 @@ export default class AccountViewView extends Vue {
|
|||||||
this.savingProfile = true;
|
this.savingProfile = true;
|
||||||
try {
|
try {
|
||||||
const headers = await getHeaders(this.activeDid);
|
const headers = await getHeaders(this.activeDid);
|
||||||
|
const payload = {
|
||||||
|
description: this.userProfileDesc,
|
||||||
|
};
|
||||||
|
if (this.userProfileLatitude && this.userProfileLongitude) {
|
||||||
|
payload.locLat = this.userProfileLatitude;
|
||||||
|
payload.locLon = this.userProfileLongitude;
|
||||||
|
}
|
||||||
const response = await this.axios.post(
|
const response = await this.axios.post(
|
||||||
this.apiServer + "/api/partner/user-profile",
|
this.apiServer + "/api/partner/user-profile",
|
||||||
{
|
payload,
|
||||||
description: this.userProfile,
|
|
||||||
},
|
|
||||||
{ headers },
|
{ headers },
|
||||||
);
|
);
|
||||||
if (response.status === 201) {
|
if (response.status === 201) {
|
||||||
@@ -1775,5 +1839,34 @@ export default class AccountViewView extends Vue {
|
|||||||
this.savingProfile = false;
|
this.savingProfile = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
toggleUserProfileLocation() {
|
||||||
|
this.includeUserProfileLocation = !this.includeUserProfileLocation;
|
||||||
|
if (!this.includeUserProfileLocation) {
|
||||||
|
this.userProfileLatitude = 0;
|
||||||
|
this.userProfileLongitude = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
confirmEraseLatLong() {
|
||||||
|
this.$notify(
|
||||||
|
{
|
||||||
|
group: "modal",
|
||||||
|
type: "confirm",
|
||||||
|
title: "Erase Marker",
|
||||||
|
text: "Are you sure you don't want to mark a location? This will erase the current location.",
|
||||||
|
onYes: async () => {
|
||||||
|
this.eraseLatLong();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
-1,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
eraseLatLong() {
|
||||||
|
this.userProfileLatitude = 0;
|
||||||
|
this.userProfileLongitude = 0;
|
||||||
|
this.includeUserProfileLocation = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
Reference in New Issue
Block a user