forked from trent_larson/crowd-funder-for-time-pwa
add contact-methods to a contact
This commit is contained in:
@@ -332,7 +332,7 @@ export default class App extends Vue {
|
|||||||
truncateLongWords(sentence: string) {
|
truncateLongWords(sentence: string) {
|
||||||
return sentence
|
return sentence
|
||||||
.split(" ")
|
.split(" ")
|
||||||
.map(word => (word.length > 30 ? word.slice(0, 30) + "..." : word))
|
.map((word) => (word.length > 30 ? word.slice(0, 30) + "..." : word))
|
||||||
.join(" ");
|
.join(" ");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,12 @@
|
|||||||
|
export interface ContactMethod {
|
||||||
|
label: string;
|
||||||
|
type: string; // eg. "EMAIL", "SMS", "WHATSAPP"
|
||||||
|
value: string;
|
||||||
|
}
|
||||||
|
|
||||||
export interface Contact {
|
export interface Contact {
|
||||||
did: string;
|
did: string;
|
||||||
|
contactMethods?: Array<ContactMethod>;
|
||||||
name?: string;
|
name?: string;
|
||||||
nextPubKeyHashB64?: string; // base64-encoded SHA256 hash of next public key
|
nextPubKeyHashB64?: string; // base64-encoded SHA256 hash of next public key
|
||||||
notes?: string;
|
notes?: string;
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import {
|
|||||||
faBurst,
|
faBurst,
|
||||||
faCalendar,
|
faCalendar,
|
||||||
faCamera,
|
faCamera,
|
||||||
|
faCaretDown,
|
||||||
faCheck,
|
faCheck,
|
||||||
faChevronDown,
|
faChevronDown,
|
||||||
faChevronLeft,
|
faChevronLeft,
|
||||||
@@ -98,6 +99,7 @@ library.add(
|
|||||||
faBurst,
|
faBurst,
|
||||||
faCalendar,
|
faCalendar,
|
||||||
faCamera,
|
faCamera,
|
||||||
|
faCaretDown,
|
||||||
faCheck,
|
faCheck,
|
||||||
faChevronDown,
|
faChevronDown,
|
||||||
faChevronLeft,
|
faChevronLeft,
|
||||||
|
|||||||
@@ -346,12 +346,12 @@
|
|||||||
|
|
||||||
<!-- Note that a similar section is found in ConfirmGiftView.vue -->
|
<!-- Note that a similar section is found in ConfirmGiftView.vue -->
|
||||||
<h2
|
<h2
|
||||||
class="font-bold uppercase text-xl text-blue-500 mt-8 cursor-pointer"
|
class="font-bold uppercase text-xl text-blue-500 mt-8 cursor-pointer"
|
||||||
@click="showVeriClaimDump = !showVeriClaimDump"
|
@click="showVeriClaimDump = !showVeriClaimDump"
|
||||||
>
|
>
|
||||||
Details
|
Details
|
||||||
<fa v-if="showVeriClaimDump" icon="chevron-up" />
|
<fa v-if="showVeriClaimDump" icon="chevron-up" />
|
||||||
<fa v-else icon="chevron-right" />
|
<fa v-else icon="chevron-right" />
|
||||||
</h2>
|
</h2>
|
||||||
<div v-if="showVeriClaimDump">
|
<div v-if="showVeriClaimDump">
|
||||||
<div
|
<div
|
||||||
|
|||||||
@@ -44,8 +44,77 @@
|
|||||||
></textarea>
|
></textarea>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<!-- Contact Methods -->
|
||||||
|
<div class="mt-4">
|
||||||
|
<h2 class="text-lg font-medium text-gray-700">Contact Methods</h2>
|
||||||
|
<div
|
||||||
|
v-for="(method, index) in contactMethods"
|
||||||
|
:key="index"
|
||||||
|
class="flex mt-2"
|
||||||
|
>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
v-model="method.label"
|
||||||
|
class="block w-1/4 border border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500"
|
||||||
|
placeholder="Label"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
v-model="method.type"
|
||||||
|
class="block ml-2 w-1/4 border border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500"
|
||||||
|
placeholder="Type"
|
||||||
|
/>
|
||||||
|
<div class="relative">
|
||||||
|
<button
|
||||||
|
@click="toggleDropdown(index)"
|
||||||
|
class="px-2 py-1 bg-gray-200 rounded-md"
|
||||||
|
>
|
||||||
|
<fa icon="caret-down" class="fa-fw" />
|
||||||
|
</button>
|
||||||
|
<div
|
||||||
|
v-if="dropdownIndex === index"
|
||||||
|
class="absolute bg-white border border-gray-300 rounded-md mt-1"
|
||||||
|
>
|
||||||
|
<div
|
||||||
|
@click="setMethodType(index, 'CELL')"
|
||||||
|
class="px-4 py-2 hover:bg-gray-100 cursor-pointer"
|
||||||
|
>
|
||||||
|
CELL
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
@click="setMethodType(index, 'EMAIL')"
|
||||||
|
class="px-4 py-2 hover:bg-gray-100 cursor-pointer"
|
||||||
|
>
|
||||||
|
EMAIL
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
@click="setMethodType(index, 'WHATSAPP')"
|
||||||
|
class="px-4 py-2 hover:bg-gray-100 cursor-pointer"
|
||||||
|
>
|
||||||
|
WHATSAPP
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
v-model="method.value"
|
||||||
|
class="block ml-2 w-1/2 border border-gray-300 rounded-md shadow-sm focus:ring-indigo-500 focus:border-indigo-500"
|
||||||
|
placeholder="Number, email, etc."
|
||||||
|
/>
|
||||||
|
<button @click="removeContactMethod(index)" class="ml-2 text-red-500">
|
||||||
|
<fa icon="trash-can" class="fa-fw" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<button @click="addContactMethod" class="mt-2">
|
||||||
|
<fa
|
||||||
|
icon="plus"
|
||||||
|
class="fa-fw px-2 py-2.5 bg-green-500 text-green-100 rounded-full"
|
||||||
|
/>
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
<!-- Save Button -->
|
<!-- Save Button -->
|
||||||
<div class="mt-4 flex justify-between">
|
<div class="mt-8 flex justify-between">
|
||||||
<button
|
<button
|
||||||
class="px-4 py-2 bg-blue-500 text-white rounded-md"
|
class="px-4 py-2 bg-blue-500 text-white rounded-md"
|
||||||
@click="saveEdit"
|
@click="saveEdit"
|
||||||
@@ -63,6 +132,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import * as R from "ramda";
|
||||||
import { Component, Vue } from "vue-facing-decorator";
|
import { Component, Vue } from "vue-facing-decorator";
|
||||||
import { RouteLocation, Router } from "vue-router";
|
import { RouteLocation, Router } from "vue-router";
|
||||||
|
|
||||||
@@ -70,7 +140,7 @@ import QuickNav from "@/components/QuickNav.vue";
|
|||||||
import TopMessage from "@/components/TopMessage.vue";
|
import TopMessage from "@/components/TopMessage.vue";
|
||||||
import { AppString, NotificationIface } from "@/constants/app";
|
import { AppString, NotificationIface } from "@/constants/app";
|
||||||
import { db } from "@/db/index";
|
import { db } from "@/db/index";
|
||||||
import { Contact } from "@/db/tables/contacts";
|
import { Contact, ContactMethod } from "@/db/tables/contacts";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
components: {
|
components: {
|
||||||
@@ -88,6 +158,8 @@ export default class ContactEditView extends Vue {
|
|||||||
};
|
};
|
||||||
contactName = "";
|
contactName = "";
|
||||||
contactNotes = "";
|
contactNotes = "";
|
||||||
|
contactMethods: Array<ContactMethod> = [];
|
||||||
|
dropdownIndex: number | null = null;
|
||||||
|
|
||||||
AppString = AppString;
|
AppString = AppString;
|
||||||
|
|
||||||
@@ -98,6 +170,7 @@ export default class ContactEditView extends Vue {
|
|||||||
this.contact = contact;
|
this.contact = contact;
|
||||||
this.contactName = contact.name || "";
|
this.contactName = contact.name || "";
|
||||||
this.contactNotes = contact.notes || "";
|
this.contactNotes = contact.notes || "";
|
||||||
|
this.contactMethods = contact.contactMethods || [];
|
||||||
} else {
|
} else {
|
||||||
this.$notify({
|
this.$notify({
|
||||||
group: "alert",
|
group: "alert",
|
||||||
@@ -110,16 +183,52 @@ export default class ContactEditView extends Vue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
addContactMethod() {
|
||||||
|
this.contactMethods.push({ label: "", type: "", value: "" });
|
||||||
|
}
|
||||||
|
|
||||||
|
removeContactMethod(index: number) {
|
||||||
|
this.contactMethods.splice(index, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleDropdown(index: number) {
|
||||||
|
this.dropdownIndex = this.dropdownIndex === index ? null : index;
|
||||||
|
}
|
||||||
|
|
||||||
|
setMethodType(index: number, type: string) {
|
||||||
|
this.contactMethods[index].type = type;
|
||||||
|
this.dropdownIndex = null;
|
||||||
|
}
|
||||||
|
|
||||||
async saveEdit() {
|
async saveEdit() {
|
||||||
|
// without this conversion, "Failed to execute 'put' on 'IDBObjectStore': [object Array] could not be cloned."
|
||||||
|
const contactMethodsObj = JSON.parse(JSON.stringify(this.contactMethods));
|
||||||
|
const contactMethods = contactMethodsObj.map((method: ContactMethod) =>
|
||||||
|
R.set(R.lensProp("type"), method.type.toUpperCase(), method),
|
||||||
|
);
|
||||||
|
if (!R.equals(contactMethodsObj, contactMethods)) {
|
||||||
|
this.contactMethods = contactMethods;
|
||||||
|
this.$notify(
|
||||||
|
{
|
||||||
|
group: "alert",
|
||||||
|
type: "warning",
|
||||||
|
title: "Contact Methods Updated",
|
||||||
|
text: "Note that some methods have been updated, such as uppercasing 'email' to 'EMAIL'. Save again if the changes are acceptable.",
|
||||||
|
},
|
||||||
|
15000,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
await db.contacts.update(this.contact.did, {
|
await db.contacts.update(this.contact.did, {
|
||||||
name: this.contactName,
|
name: this.contactName,
|
||||||
notes: this.contactNotes,
|
notes: this.contactNotes,
|
||||||
|
contactMethods: contactMethods,
|
||||||
});
|
});
|
||||||
this.$notify({
|
this.$notify({
|
||||||
group: "alert",
|
group: "alert",
|
||||||
type: "success",
|
type: "success",
|
||||||
title: "Notes Saved",
|
title: "Notes Saved",
|
||||||
text: "The contact notes have been updated successfully.",
|
text: "The contact info has been updated successfully.",
|
||||||
});
|
});
|
||||||
(this.$router as Router).push({
|
(this.$router as Router).push({
|
||||||
path: "/did/" + encodeURIComponent(this.contact.did),
|
path: "/did/" + encodeURIComponent(this.contact.did),
|
||||||
|
|||||||
@@ -174,7 +174,9 @@
|
|||||||
data-testId="contactCheckOne"
|
data-testId="contactCheckOne"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<h2 class="text-base font-semibold ml-2 w-1/3 truncate flex-shrink-0">
|
<h2
|
||||||
|
class="text-base font-semibold ml-2 w-1/3 truncate flex-shrink-0"
|
||||||
|
>
|
||||||
{{ contactNameNonBreakingSpace(contact.name) }}
|
{{ contactNameNonBreakingSpace(contact.name) }}
|
||||||
</h2>
|
</h2>
|
||||||
|
|
||||||
@@ -191,8 +193,7 @@
|
|||||||
|
|
||||||
<span class="ml-4 text-sm overflow-hidden">{{
|
<span class="ml-4 text-sm overflow-hidden">{{
|
||||||
shortDid(contact.did)
|
shortDid(contact.did)
|
||||||
}}</span
|
}}</span>
|
||||||
>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-4 text-sm">
|
<div class="ml-4 text-sm">
|
||||||
{{ contact.notes }}
|
{{ contact.notes }}
|
||||||
|
|||||||
Reference in New Issue
Block a user