forked from trent_larson/crowd-funder-for-time-pwa
Compare commits
14 Commits
cleanup-an
...
notiwind-a
| Author | SHA1 | Date | |
|---|---|---|---|
| d2e2fc707e | |||
|
|
f55e50067f | ||
| 179a5cd9f8 | |||
|
|
eff67c2a4a | ||
|
|
db22d559b7 | ||
|
|
c4443f2ed1 | ||
|
|
05a7758c65 | ||
| d0ec7930e1 | |||
| 3e2cd1291c | |||
| 8d42fe905d | |||
| a7e98c8f1a | |||
| f07c804b24 | |||
|
|
7c77578f79 | ||
|
|
5134e2f562 |
17
package-lock.json
generated
17
package-lock.json
generated
@@ -38,6 +38,7 @@
|
||||
"luxon": "^3.3.0",
|
||||
"merkletreejs": "^0.3.10",
|
||||
"moment": "^2.29.4",
|
||||
"notiwind": "^2.0.2",
|
||||
"papaparse": "^5.4.1",
|
||||
"pina": "^0.20.2204228",
|
||||
"pinia-plugin-persistedstate": "^3.1.0",
|
||||
@@ -20928,6 +20929,11 @@
|
||||
"node": ">= 8"
|
||||
}
|
||||
},
|
||||
"node_modules/mitt": {
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/mitt/-/mitt-3.0.1.tgz",
|
||||
"integrity": "sha512-vKivATfr97l2/QBCYAkXYDbrIWPM2IIKEl7YPhjCvKlG3kE2gm+uBo6nEXK3M5/Ffh/FLpKExzOQ3JJoJGFKBw=="
|
||||
},
|
||||
"node_modules/mkdirp": {
|
||||
"version": "0.5.6",
|
||||
"resolved": "https://registry.npmmirror.com/mkdirp/-/mkdirp-0.5.6.tgz",
|
||||
@@ -21275,6 +21281,17 @@
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/notiwind": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/notiwind/-/notiwind-2.0.2.tgz",
|
||||
"integrity": "sha512-wMCf+07E093d0Q78C5UHroT9GQHm4mIGerhg7dGLJ0GN6zONqKj8nTR3clkq/Y44On9k28/0DtDNwOX7FT5p/A==",
|
||||
"dependencies": {
|
||||
"mitt": "^3.0.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"vue": "^3.3.4"
|
||||
}
|
||||
},
|
||||
"node_modules/npm-package-arg": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/npm-package-arg/-/npm-package-arg-7.0.0.tgz",
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
"luxon": "^3.3.0",
|
||||
"merkletreejs": "^0.3.10",
|
||||
"moment": "^2.29.4",
|
||||
"notiwind": "^2.0.2",
|
||||
"papaparse": "^5.4.1",
|
||||
"pina": "^0.20.2204228",
|
||||
"pinia-plugin-persistedstate": "^3.1.0",
|
||||
|
||||
@@ -1,32 +1,36 @@
|
||||
|
||||
tasks:
|
||||
- 40 notifications :
|
||||
- push, where we trigger a ServiceWorker(?) in the app to reach out and check for new data assignee:matthew
|
||||
|
||||
- 01 add a location for a project via map pin
|
||||
- 04 search by a bounding box for local projects (see API by clicking on "Nearby")
|
||||
- 01 Replace Gifted/Give in ContactsView with GiftedDialog assignee:matthew
|
||||
- 02 Fix images on projectview - allow choice of image from a pallete of images or a url image (discovery page display also)
|
||||
- SEE: https://github.com/dmester/jdenticon assignee:jose
|
||||
- 01 Replace Gifted/Give in ContactsView with GiftedDialog assignee:jose
|
||||
- 02 Fix images on projectview - allow choice of image from a pallete of images or a url image.
|
||||
|
||||
- 08 Scan QR code to import into contacts assignee:matthew
|
||||
- SEE: https://github.com/gruhn/vue-qrcode-reader
|
||||
- 08 Scan QR code to import into contacts.
|
||||
|
||||
- Show pop-up or some message confirming that settings & contacts download has been initiated/finished assignee:matthew
|
||||
- 40 notifications :
|
||||
- push, where we trigger a ServiceWorker(?) in the app to reach out and check for new data
|
||||
|
||||
- Ensure each action sent to the server has a confirmation - eg registration (ie a toast something that dismisses after 5-10s)
|
||||
- SEE: https://github.com/emmanuelsw/notiwind assignee:jose
|
||||
- refactor UI :
|
||||
- .5 Alerts show at the top and can be missed if you've scrolled down on the page, eg. account data download
|
||||
- .2 Make alerts at the top more visible (because they're currently a similar color and sometimes aren't seen)
|
||||
|
||||
- Show pop-up or some message confirming that settings & contacts download has been initiated/finished
|
||||
|
||||
- Ensure each action sent to the server has a confirmation - eg registration
|
||||
|
||||
- Home Feed & Quick Give screen :
|
||||
- 01 save the feed-viewed status in settings storage ("afterQuery")
|
||||
- 01 quick action - send action, maybe choose via canvas tool
|
||||
- SEE: https://github.com/konvajs/vue-konva
|
||||
- 01 quick action - send action, maybe choose via canvas tool https://github.com/konvajs/vue-konva
|
||||
|
||||
- 24 Move to Vite assignee:matthew
|
||||
- 24 Move to Vite
|
||||
|
||||
- .5 add project ID to the URL, to make a project publicly-accessible
|
||||
- .5 remove edit from project page for projects owned by others
|
||||
- .5 fix where user 0 sees no txns from user 1 on contacts page but sees them on list page
|
||||
- .2 there are three dots at the top of ProjectViewView that refreshes the page but doesn't do anything else
|
||||
- 01 fix images on project page, on discovery page
|
||||
- .2 on ProjectViewView, show different messages for "to" and "from" sections if none exist
|
||||
- .2 fix static icon to the right on project page (Matthew - I've made "Rotary" into issuer?) assignee:jose
|
||||
- .2 fix static icon to the right on project page (Matthew - I've made "Rotary" into issuer?)
|
||||
- .2 fix rate limit verbiage (with the new one-per-day allowance) assignee:trent
|
||||
|
||||
- Discuss whether the remaining tasks are worthwhile before MVP release.
|
||||
|
||||
127
src/App.vue
127
src/App.vue
@@ -1,5 +1,132 @@
|
||||
<template>
|
||||
<router-view />
|
||||
|
||||
<NotificationGroup group="alert">
|
||||
<div
|
||||
class="fixed top-4 right-4 w-full max-w-sm flex flex-col items-start justify-end"
|
||||
>
|
||||
<Notification
|
||||
v-slot="{ notifications, close }"
|
||||
enter="transform ease-out duration-300 transition"
|
||||
enter-from="translate-y-2 opacity-0 sm:translate-y-0 sm:translate-x-4"
|
||||
enter-to="translate-y-0 opacity-100 sm:translate-x-0"
|
||||
leave="transition ease-in duration-500"
|
||||
leave-from="opacity-100"
|
||||
leave-to="opacity-0"
|
||||
move="transition duration-500"
|
||||
move-delay="delay-300"
|
||||
>
|
||||
<div
|
||||
v-for="notification in notifications"
|
||||
:key="notification.id"
|
||||
class="w-full"
|
||||
role="alert"
|
||||
>
|
||||
<div
|
||||
v-if="notification.type === 'toast'"
|
||||
class="w-full max-w-sm mx-auto mb-3 overflow-hidden bg-slate-900/90 text-white rounded-lg shadow-md"
|
||||
>
|
||||
<div class="w-full px-4 py-3">
|
||||
<span class="font-semibold">{{ notification.title }}</span>
|
||||
<p class="text-sm">{{ notification.text }}</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="notification.type === 'info'"
|
||||
class="flex w-full max-w-sm mx-auto mb-3 overflow-hidden bg-slate-100 rounded-lg shadow-md"
|
||||
>
|
||||
<div
|
||||
class="flex items-center justify-center w-12 bg-slate-600 text-slate-100"
|
||||
>
|
||||
<fa icon="circle-info" class="fa-fw fa-xl"></fa>
|
||||
</div>
|
||||
|
||||
<div class="relative w-full pl-4 pr-8 py-2 text-slate-900">
|
||||
<span class="font-semibold">{{ notification.title }}</span>
|
||||
<p class="text-sm">{{ notification.text }}</p>
|
||||
|
||||
<button
|
||||
@click="close(notification.id)"
|
||||
class="absolute top-2 right-2 px-0.5 py-0 rounded-full bg-slate-200 text-slate-600"
|
||||
>
|
||||
<fa icon="xmark" class="fa-fw"></fa>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="notification.type === 'success'"
|
||||
class="flex w-full max-w-sm mx-auto mb-3 overflow-hidden bg-emerald-100 rounded-lg shadow-md"
|
||||
>
|
||||
<div
|
||||
class="flex items-center justify-center w-12 bg-emerald-600 text-emerald-100"
|
||||
>
|
||||
<fa icon="circle-info" class="fa-fw fa-xl"></fa>
|
||||
</div>
|
||||
|
||||
<div class="relative w-full pl-4 pr-8 py-2 text-emerald-900">
|
||||
<span class="font-semibold">{{ notification.title }}</span>
|
||||
<p class="text-sm">{{ notification.text }}</p>
|
||||
|
||||
<button
|
||||
@click="close(notification.id)"
|
||||
class="absolute top-2 right-2 px-0.5 py-0 rounded-full bg-emerald-200 text-emerald-600"
|
||||
>
|
||||
<fa icon="xmark" class="fa-fw"></fa>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="notification.type === 'warning'"
|
||||
class="flex w-full max-w-sm mx-auto mb-3 overflow-hidden bg-amber-100 rounded-lg shadow-md"
|
||||
>
|
||||
<div
|
||||
class="flex items-center justify-center w-12 bg-amber-600 text-amber-100"
|
||||
>
|
||||
<fa icon="triangle-exclamation" class="fa-fw fa-xl"></fa>
|
||||
</div>
|
||||
|
||||
<div class="relative w-full pl-4 pr-8 py-2 text-amber-900">
|
||||
<span class="font-semibold">{{ notification.title }}</span>
|
||||
<p class="text-sm">{{ notification.text }}</p>
|
||||
|
||||
<button
|
||||
@click="close(notification.id)"
|
||||
class="absolute top-2 right-2 px-0.5 py-0 rounded-full bg-amber-200 text-amber-600"
|
||||
>
|
||||
<fa icon="xmark" class="fa-fw"></fa>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="notification.type === 'danger'"
|
||||
class="flex w-full max-w-sm mx-auto mb-3 overflow-hidden bg-rose-100 rounded-lg shadow-md"
|
||||
>
|
||||
<div
|
||||
class="flex items-center justify-center w-12 bg-rose-600 text-rose-100"
|
||||
>
|
||||
<fa icon="triangle-exclamation" class="fa-fw fa-xl"></fa>
|
||||
</div>
|
||||
|
||||
<div class="relative w-full pl-4 pr-8 py-2 text-rose-900">
|
||||
<span class="font-semibold">{{ notification.title }}</span>
|
||||
<p class="text-sm">{{ notification.text }}</p>
|
||||
|
||||
<button
|
||||
@click="close(notification.id)"
|
||||
class="absolute top-2 right-2 px-0.5 py-0 rounded-full bg-rose-200 text-rose-600"
|
||||
>
|
||||
<fa icon="xmark" class="fa-fw"></fa>
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Notification>
|
||||
</div>
|
||||
</NotificationGroup>
|
||||
</template>
|
||||
|
||||
<style></style>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
<div v-if="visible" class="dialog-overlay">
|
||||
<div class="dialog">
|
||||
<h1 class="text-xl font-bold text-center mb-4">
|
||||
{{ message }} {{ giver?.did || "somebody not specified" }}
|
||||
{{ message }} {{ giver?.name || "somebody not specified" }}
|
||||
</h1>
|
||||
<input
|
||||
type="text"
|
||||
|
||||
@@ -5,6 +5,7 @@ import "./registerServiceWorker";
|
||||
import router from "./router";
|
||||
import axios from "axios";
|
||||
import VueAxios from "vue-axios";
|
||||
import Notifications from "notiwind";
|
||||
|
||||
import "./assets/styles/tailwind.css";
|
||||
|
||||
@@ -16,6 +17,7 @@ import {
|
||||
faChevronRight,
|
||||
faCircle,
|
||||
faCircleCheck,
|
||||
faCircleInfo,
|
||||
faCircleQuestion,
|
||||
faCircleUser,
|
||||
faClock,
|
||||
@@ -45,6 +47,7 @@ import {
|
||||
faSquareCaretDown,
|
||||
faSquareCaretUp,
|
||||
faTrashCan,
|
||||
faTriangleExclamation,
|
||||
faUser,
|
||||
faUsers,
|
||||
faXmark,
|
||||
@@ -57,6 +60,7 @@ library.add(
|
||||
faChevronRight,
|
||||
faCircle,
|
||||
faCircleCheck,
|
||||
faCircleInfo,
|
||||
faCircleQuestion,
|
||||
faCircleUser,
|
||||
faClock,
|
||||
@@ -86,6 +90,7 @@ library.add(
|
||||
faSquareCaretDown,
|
||||
faSquareCaretUp,
|
||||
faTrashCan,
|
||||
faTriangleExclamation,
|
||||
faUser,
|
||||
faUsers,
|
||||
faXmark,
|
||||
@@ -98,4 +103,5 @@ createApp(App)
|
||||
.use(createPinia())
|
||||
.use(VueAxios, axios)
|
||||
.use(router)
|
||||
.use(Notifications)
|
||||
.mount("#app");
|
||||
|
||||
@@ -182,4 +182,14 @@ const router = createRouter({
|
||||
routes,
|
||||
});
|
||||
|
||||
const errorHandler = (error, to, from) => {
|
||||
// Handle the error here
|
||||
console.error(error, to, from);
|
||||
console.log("XXXXX");
|
||||
|
||||
// You can also perform additional actions, such as displaying an error message or redirecting the user to a specific page
|
||||
};
|
||||
|
||||
router.onError(errorHandler); // Assign the error handler to the router instance
|
||||
|
||||
export default router;
|
||||
|
||||
@@ -400,13 +400,19 @@ export default class AccountViewView extends Vue {
|
||||
this.limitsMessage = "No identity.";
|
||||
this.loadingLimits = false;
|
||||
} else {
|
||||
this.alertMessage =
|
||||
"Clear your cache and start over (after data backup).";
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error Creating Account",
|
||||
text: "Clear your cache and start over (after data backup).",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
console.error(
|
||||
"Telling user to clear cache at page create because:",
|
||||
err,
|
||||
);
|
||||
this.alertTitle = "Error Creating Account";
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -418,13 +424,19 @@ export default class AccountViewView extends Vue {
|
||||
showContactGivesInline: this.showContactGives,
|
||||
});
|
||||
} catch (err) {
|
||||
this.alertMessage =
|
||||
"Clear your cache and start over (after data backup).";
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error Updating Contact Setting",
|
||||
text: "Clear your cache and start over (after data backup).",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
console.error(
|
||||
"Telling user to clear cache after contact setting update because:",
|
||||
err,
|
||||
);
|
||||
this.alertTitle = "Error Updating Contact Setting";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -440,11 +452,25 @@ export default class AccountViewView extends Vue {
|
||||
|
||||
URL.revokeObjectURL(url);
|
||||
|
||||
this.alertTitle = "Download Started";
|
||||
this.alertMessage = "See your downloads directory for the backup.";
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "toast",
|
||||
title: "Download Started",
|
||||
text: "See your downloads directory for the backup.",
|
||||
},
|
||||
5000,
|
||||
);
|
||||
} catch (error) {
|
||||
this.alertTitle = "Export Error";
|
||||
this.alertMessage = "See console logs for more info.";
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Export Error",
|
||||
text: "See console logs for more info.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
console.error("Export Error:", error);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,6 @@
|
||||
<template>
|
||||
<QuickNav selected="Contacts"></QuickNav>
|
||||
<section id="Content" class="p-6 pb-24">
|
||||
<!-- Breadcrumb -->
|
||||
<div id="ViewBreadcrumb" class="mb-8">
|
||||
<h1 class="text-lg text-center font-light relative px-7">
|
||||
<!-- Back -->
|
||||
<router-link
|
||||
:to="{ name: 'contacts' }"
|
||||
class="text-lg text-center px-2 py-1 absolute -left-2 -top-1"
|
||||
><fa icon="chevron-left" class="fa-fw"></fa
|
||||
></router-link>
|
||||
</h1>
|
||||
</div>
|
||||
|
||||
<h1 id="ViewHeading" class="text-4xl text-center font-light pt-4 mb-8">
|
||||
Given with {{ contact?.name }}
|
||||
</h1>
|
||||
@@ -158,10 +146,17 @@ export default class ContactsView extends Vue {
|
||||
this.loadGives(this.activeDid, this.contact);
|
||||
}
|
||||
} catch (err) {
|
||||
this.alertTitle = "Error";
|
||||
this.alertMessage =
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error",
|
||||
text:
|
||||
err.userMessage ||
|
||||
"There was an error retrieving the latest sweet, sweet action.";
|
||||
"There was an error retrieving the latest sweet, sweet action.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -185,9 +180,15 @@ export default class ContactsView extends Vue {
|
||||
resp.status,
|
||||
resp.data,
|
||||
);
|
||||
this.alertTitle = "Error With Server";
|
||||
this.alertMessage =
|
||||
"Got an error retrieving your given time from the server.";
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error With Server",
|
||||
text: "Got an error retrieving your given time from the server.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
}
|
||||
|
||||
const url2 =
|
||||
@@ -206,9 +207,15 @@ export default class ContactsView extends Vue {
|
||||
resp2.status,
|
||||
resp2.data,
|
||||
);
|
||||
this.alertTitle = "Error With Server";
|
||||
this.alertMessage =
|
||||
"Got an error retrieving your given time from the server.";
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error With Server",
|
||||
text: "Got an error retrieving your given time from the server.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
}
|
||||
|
||||
const sortedResult: Array<GiveServerRecord> = R.sort(
|
||||
@@ -218,8 +225,15 @@ export default class ContactsView extends Vue {
|
||||
);
|
||||
this.giveRecords = sortedResult;
|
||||
} catch (error) {
|
||||
this.alertTitle = "Error With Server";
|
||||
this.alertMessage = error as string;
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error With Server",
|
||||
text: error as string,
|
||||
},
|
||||
-1,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -288,15 +302,29 @@ export default class ContactsView extends Vue {
|
||||
userMessage = error as string;
|
||||
}
|
||||
// Now set that error for the user to see.
|
||||
this.alertTitle = "Error With Server";
|
||||
this.alertMessage = userMessage;
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error With Server",
|
||||
text: userMessage,
|
||||
},
|
||||
-1,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cannotConfirmMessage() {
|
||||
this.alertTitle = "Not Allowed";
|
||||
this.alertMessage = "Only the recipient can confirm final receipt.";
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Not Allowed",
|
||||
text: "Only the recipient can confirm final receipt.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -145,10 +145,17 @@ export default class HomeView extends Vue {
|
||||
this.feedLastViewedId = settings?.lastViewedClaimId;
|
||||
this.updateAllFeed();
|
||||
} catch (err) {
|
||||
this.alertTitle = "Error";
|
||||
this.alertMessage =
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error",
|
||||
text:
|
||||
err.userMessage ||
|
||||
"There was an error retrieving the latest sweet, sweet action.";
|
||||
"There was an error retrieving the latest sweet, sweet action.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -197,17 +204,27 @@ export default class HomeView extends Vue {
|
||||
*/
|
||||
public async recordGive(giverDid, description, hours) {
|
||||
if (!this.activeDid) {
|
||||
this.setAlert(
|
||||
"Error",
|
||||
"You must select an identity before you can record a give.",
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error",
|
||||
text: "You must select an identity before you can record a give.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!description && !hours) {
|
||||
this.setAlert(
|
||||
"Error",
|
||||
"You must enter a description or some number of hours.",
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error",
|
||||
text: "You must enter a description or some number of hours.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -227,18 +244,38 @@ export default class HomeView extends Vue {
|
||||
if (isGiveCreationError(result)) {
|
||||
const errorMessage = getGiveCreationErrorMessage(result);
|
||||
console.log("Error with give result:", result);
|
||||
this.setAlert(
|
||||
"Error",
|
||||
errorMessage || "There was an error recording the give.",
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error",
|
||||
text: errorMessage || "There was an error recording the give.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
} else {
|
||||
this.setAlert("Success", "That gift was recorded.");
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "success",
|
||||
title: "Success",
|
||||
text: "That gift was recorded.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("Error with give caught:", error);
|
||||
this.setAlert(
|
||||
"Error",
|
||||
getGiveErrorMessage(error) || "There was an error recording the give.",
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error",
|
||||
text:
|
||||
getGiveErrorMessage(error) ||
|
||||
"There was an error recording the give.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,7 +85,15 @@ export default class ContactQRScanShow extends Vue {
|
||||
const accounts = await accountsDB.accounts.toArray();
|
||||
const account = R.find((acc) => acc.did === this.activeDid, accounts);
|
||||
if (!account) {
|
||||
this.alertMessage = "You have no identity yet.";
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "warning",
|
||||
title: "",
|
||||
text: "You have no identity yet.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
} else {
|
||||
const identity = await this.getIdentity(this.activeDid);
|
||||
const publicKeyHex = identity.keys[0].publicKeyHex;
|
||||
|
||||
@@ -70,9 +70,9 @@
|
||||
</div>
|
||||
|
||||
<!-- Results List -->
|
||||
<ul v-if="contacts.length > 0">
|
||||
<ul v-if="contacts.length > 0" class="border-t border-slate-300">
|
||||
<li
|
||||
class="border-b border-slate-300"
|
||||
class="border-b border-slate-300 py-4"
|
||||
v-for="contact in contacts"
|
||||
:key="contact.did"
|
||||
>
|
||||
@@ -85,45 +85,63 @@
|
||||
Public Key (base 64): {{ contact.publicKeyBase64 }}
|
||||
</div>
|
||||
|
||||
<div id="ContactActions" class="flex gap-1.5 mt-2">
|
||||
<button
|
||||
v-if="contact.seesMe"
|
||||
class="tooltip"
|
||||
class="text-sm uppercase bg-slate-500 text-white px-2 py-1.5 rounded-md"
|
||||
@click="setVisibility(contact, false)"
|
||||
title="They can see you"
|
||||
>
|
||||
<fa icon="eye" class="text-slate-900 fa-fw ml-1" />
|
||||
<span class="tooltiptext">They can see you</span>
|
||||
<fa icon="eye" class="fa-fw" />
|
||||
</button>
|
||||
<button v-else class="tooltip" @click="setVisibility(contact, true)">
|
||||
<span class="tooltiptext">They cannot see you</span>
|
||||
<fa icon="eye-slash" class="text-slate-900 fa-fw ml-1" />
|
||||
<button
|
||||
v-else
|
||||
class="text-sm uppercase bg-slate-500 text-white px-2 py-1.5 rounded-md"
|
||||
@click="setVisibility(contact, true)"
|
||||
title="They cannot see you"
|
||||
>
|
||||
<fa icon="eye-slash" class="fa-fw" />
|
||||
</button>
|
||||
|
||||
<button class="tooltip" @click="checkVisibility(contact)">
|
||||
<span class="tooltiptext">Check Visibility</span>
|
||||
<fa icon="rotate" class="text-slate-900 fa-fw ml-1" />
|
||||
<button
|
||||
class="text-sm uppercase bg-slate-500 text-white px-2 py-1.5 rounded-md"
|
||||
@click="checkVisibility(contact)"
|
||||
title="Check Visibility"
|
||||
>
|
||||
<fa icon="rotate" class="fa-fw" />
|
||||
</button>
|
||||
|
||||
<button v-if="contact.registered" class="tooltip">
|
||||
<span class="tooltiptext">Registered</span>
|
||||
<fa icon="person-circle-check" class="text-slate-900 fa-fw ml-1" />
|
||||
<button
|
||||
v-if="contact.registered"
|
||||
class="text-sm uppercase bg-slate-500 text-white px-2 py-1.5 rounded-md"
|
||||
title="Registered"
|
||||
>
|
||||
<fa icon="person-circle-check" class="fa-fw" />
|
||||
</button>
|
||||
<button v-else @click="register(contact)" class="tooltip">
|
||||
<span class="tooltiptext">Registration Unknown</span>
|
||||
<fa
|
||||
icon="person-circle-question"
|
||||
class="text-slate-900 fa-fw ml-1"
|
||||
/>
|
||||
<button
|
||||
v-else
|
||||
@click="register(contact)"
|
||||
class="text-sm uppercase bg-slate-500 text-white px-2 py-1.5 rounded-md"
|
||||
title="Registration unknown"
|
||||
>
|
||||
<fa icon="person-circle-question" class="fa-fw" />
|
||||
</button>
|
||||
|
||||
<button @click="deleteContact(contact)" class="px-9 tooltip">
|
||||
<span class="tooltiptext">Delete!</span>
|
||||
<fa icon="trash-can" class="text-red-600 fa-fw ml-1" />
|
||||
<button
|
||||
@click="deleteContact(contact)"
|
||||
class="text-sm uppercase bg-red-600 text-white px-2 py-1.5 rounded-md"
|
||||
title="Delete"
|
||||
>
|
||||
<fa icon="trash-can" class="fa-fw" />
|
||||
</button>
|
||||
|
||||
<div v-if="showGiveNumbers" class="float-right">
|
||||
<div class="float-right">
|
||||
<div class="tooltip">
|
||||
to:
|
||||
<div v-if="!showGiveNumbers" class="ml-auto flex gap-1.5">
|
||||
<button
|
||||
class="text-sm uppercase bg-blue-600 text-white px-2 py-1.5 rounded-md"
|
||||
@click="onClickAddGive(activeDid, contact.did)"
|
||||
title="givenByMeDescriptions[contact.did]"
|
||||
>
|
||||
To:
|
||||
{{
|
||||
/* eslint-disable prettier/prettier */
|
||||
this.showGiveTotals
|
||||
@@ -134,15 +152,15 @@
|
||||
: (givenByMeUnconfirmed[contact.did] || 0)
|
||||
/* eslint-enable prettier/prettier */
|
||||
}}
|
||||
<span
|
||||
v-if="givenByMeDescriptions[contact.did]"
|
||||
class="tooltiptext-left"
|
||||
<fa icon="plus" class="fa-fw" />
|
||||
</button>
|
||||
|
||||
<button
|
||||
class="text-sm uppercase bg-blue-600 text-white px-2 py-1.5 rounded-md"
|
||||
@click="onClickAddGive(contact.did, activeDid)"
|
||||
title="givenToMeDescriptions[contact.did]"
|
||||
>
|
||||
{{ givenByMeDescriptions[contact.did] }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="tooltip px-2">
|
||||
from:
|
||||
From:
|
||||
{{
|
||||
/* eslint-disable prettier/prettier */
|
||||
this.showGiveTotals
|
||||
@@ -153,25 +171,18 @@
|
||||
: (givenToMeUnconfirmed[contact.did] || 0)
|
||||
/* eslint-enable prettier/prettier */
|
||||
}}
|
||||
<span
|
||||
v-if="givenToMeDescriptions[contact.did]"
|
||||
class="tooltiptext-left"
|
||||
>
|
||||
{{ givenToMeDescriptions[contact.did] }}
|
||||
</span>
|
||||
</div>
|
||||
<fa icon="plus" class="fa-fw" />
|
||||
</button>
|
||||
|
||||
<router-link
|
||||
:to="{
|
||||
name: 'contact-amounts',
|
||||
query: { contactDid: contact.did },
|
||||
}"
|
||||
class="tooltip"
|
||||
class="text-sm uppercase bg-slate-500 text-white px-2 py-1.5 rounded-md"
|
||||
title="See all given activity"
|
||||
>
|
||||
<button>
|
||||
<fa icon="gift" class="pt-1 pr-2 text-slate-500" />Give
|
||||
</button>
|
||||
<fa icon="file-lines" class="text-slate-600 fa-fw ml-1" />
|
||||
<span class="tooltiptext-left">See All Given Activity</span>
|
||||
<fa icon="file-lines" class="fa-fw" />
|
||||
</router-link>
|
||||
</div>
|
||||
</div>
|
||||
@@ -203,13 +214,12 @@ import {
|
||||
import { Component, Vue } from "vue-facing-decorator";
|
||||
import AlertMessage from "@/components/AlertMessage";
|
||||
import QuickNav from "@/components/QuickNav";
|
||||
import GiftedDialog from "@/components/GiftedDialog.vue";
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const Buffer = require("buffer/").Buffer;
|
||||
|
||||
@Component({
|
||||
components: { AlertMessage, QuickNav, GiftedDialog },
|
||||
components: { AlertMessage, QuickNav },
|
||||
})
|
||||
export default class ContactsView extends Vue {
|
||||
activeDid = "";
|
||||
@@ -307,12 +317,19 @@ export default class ContactsView extends Vue {
|
||||
resp.status,
|
||||
resp.data,
|
||||
);
|
||||
this.alertTitle = "Error With Server";
|
||||
this.alertMessage =
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error With Server",
|
||||
text:
|
||||
"Got an error retrieving your " +
|
||||
resp.config.url.includes("recipientDid")
|
||||
? "received"
|
||||
: "given" + " time from the server.";
|
||||
: "given" + " time from the server.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -360,8 +377,15 @@ export default class ContactsView extends Vue {
|
||||
this.givenToMeConfirmed = givenToMeConfirmed;
|
||||
this.givenToMeUnconfirmed = givenToMeUnconfirmed;
|
||||
} catch (error) {
|
||||
this.alertTitle = "Error With Server";
|
||||
this.alertMessage = error as string;
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error With Server",
|
||||
text: error as string,
|
||||
},
|
||||
-1,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -454,18 +478,32 @@ export default class ContactsView extends Vue {
|
||||
try {
|
||||
const resp = await this.axios.post(url, payload, { headers });
|
||||
if (resp.data?.success?.embeddedRecordError) {
|
||||
this.alertTitle = "Registration Still Unknown";
|
||||
let message = "There was some problem with the registration.";
|
||||
if (typeof resp.data.success.embeddedRecordError == "string") {
|
||||
message += " " + resp.data.success.embeddedRecordError;
|
||||
}
|
||||
this.alertMessage = message;
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Registration Still Unknown",
|
||||
text: message,
|
||||
},
|
||||
-1,
|
||||
);
|
||||
} else if (resp.data?.success?.handleId) {
|
||||
contact.registered = true;
|
||||
db.contacts.update(contact.did, { registered: true });
|
||||
|
||||
this.alertTitle = "Registration Success";
|
||||
this.alertMessage = contact.name + " has been registered.";
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "info",
|
||||
title: "Registration Success",
|
||||
text: contact.name + " has been registered.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
let userMessage = "There was an error. See logs for more info.";
|
||||
@@ -480,8 +518,15 @@ export default class ContactsView extends Vue {
|
||||
userMessage = error as string;
|
||||
}
|
||||
// Now set that error for the user to see.
|
||||
this.alertTitle = "Error With Server";
|
||||
this.alertMessage = userMessage;
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error With Server",
|
||||
text: userMessage,
|
||||
},
|
||||
-1,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -502,17 +547,39 @@ export default class ContactsView extends Vue {
|
||||
contact.seesMe = visibility;
|
||||
db.contacts.update(contact.did, { seesMe: visibility });
|
||||
} else {
|
||||
this.alertTitle = "Error With Server";
|
||||
console.error("Bad response setting visibility: ", resp.data);
|
||||
if (resp.data.error?.message) {
|
||||
this.alertMessage = resp.data.error?.message;
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error With Server",
|
||||
text: resp.data.error?.message,
|
||||
},
|
||||
-1,
|
||||
);
|
||||
} else {
|
||||
this.alertMessage = "Bad server response of " + resp.status;
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error With Server",
|
||||
text: "Bad server response of " + resp.status,
|
||||
},
|
||||
-1,
|
||||
);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
this.alertTitle = "Error With Server";
|
||||
this.alertMessage = err as string;
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error With Server",
|
||||
text: err as string,
|
||||
},
|
||||
-1,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -529,23 +596,52 @@ export default class ContactsView extends Vue {
|
||||
contact.seesMe = visibility;
|
||||
db.contacts.update(contact.did, { seesMe: visibility });
|
||||
|
||||
this.alertTitle = "Refreshed";
|
||||
this.alertMessage =
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "toast",
|
||||
title: "Refreshed",
|
||||
text:
|
||||
this.nameForContact(contact, true) +
|
||||
" can " +
|
||||
(visibility ? "" : "not ") +
|
||||
"see your activity.";
|
||||
"see your activity.",
|
||||
},
|
||||
5000,
|
||||
);
|
||||
} else {
|
||||
this.alertTitle = "Error With Server";
|
||||
if (resp.data.error?.message) {
|
||||
this.alertMessage = resp.data.error?.message;
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error With Server",
|
||||
text: resp.data.error?.message,
|
||||
},
|
||||
-1,
|
||||
);
|
||||
} else {
|
||||
this.alertMessage = "Bad server response of " + resp.status;
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error With Server",
|
||||
text: "Bad server response of " + resp.status,
|
||||
},
|
||||
-1,
|
||||
);
|
||||
}
|
||||
}
|
||||
} catch (err) {
|
||||
this.alertTitle = "Error With Server";
|
||||
this.alertMessage = err as string;
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error With Server",
|
||||
text: err as string,
|
||||
},
|
||||
-1,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -584,15 +680,35 @@ export default class ContactsView extends Vue {
|
||||
}
|
||||
}
|
||||
if (!this.isNumeric(this.hourInput)) {
|
||||
this.alertTitle = "Input Error";
|
||||
this.alertMessage =
|
||||
"This is not a valid number of hours: " + this.hourInput;
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Input Error",
|
||||
text: "This is not a valid number of hours: " + this.hourInput,
|
||||
},
|
||||
-1,
|
||||
);
|
||||
} else if (!parseFloat(this.hourInput)) {
|
||||
this.alertTitle = "Input Error";
|
||||
this.alertMessage = "Giving 0 hours does nothing.";
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Input Error",
|
||||
text: "Giving 0 hours does nothing.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
} else if (!identity) {
|
||||
this.alertTitle = "Status Error";
|
||||
this.alertMessage = "No identity is available.";
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Status Error",
|
||||
text: "No identity is available.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
} else {
|
||||
// ask to confirm amount
|
||||
let toFrom;
|
||||
@@ -676,8 +792,15 @@ export default class ContactsView extends Vue {
|
||||
try {
|
||||
const resp = await this.axios.post(url, payload, { headers });
|
||||
if (resp.data?.success?.handleId) {
|
||||
this.alertTitle = "Done";
|
||||
this.alertMessage = "Successfully logged time to the server.";
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "success",
|
||||
title: "Done",
|
||||
text: "Successfully logged time to the server.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
|
||||
if (fromDid === identity.did) {
|
||||
const newList = R.clone(this.givenByMeUnconfirmed);
|
||||
@@ -702,8 +825,15 @@ export default class ContactsView extends Vue {
|
||||
userMessage = error as string;
|
||||
}
|
||||
// Now set that error for the user to see.
|
||||
this.alertTitle = "Error With Server";
|
||||
this.alertMessage = userMessage;
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error With Server",
|
||||
text: userMessage,
|
||||
},
|
||||
-1,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,6 +186,16 @@ export default class DiscoverView extends Vue {
|
||||
|
||||
if (response.status !== 200) {
|
||||
const details = await response.text();
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error",
|
||||
text: `There was a problem accessing the server. Please try again later. (${details})`,
|
||||
},
|
||||
-1,
|
||||
);
|
||||
|
||||
throw details;
|
||||
}
|
||||
|
||||
@@ -204,9 +214,15 @@ export default class DiscoverView extends Vue {
|
||||
}
|
||||
} catch (e) {
|
||||
console.log("Error with feed load:", e);
|
||||
this.alertMessage =
|
||||
e.userMessage || "There was an error retrieving projects.";
|
||||
this.alertTitle = "Error";
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error",
|
||||
text: e.userMessage || "There was a problem retrieving projects.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
} finally {
|
||||
this.isLoading = false;
|
||||
}
|
||||
@@ -240,6 +256,16 @@ export default class DiscoverView extends Vue {
|
||||
);
|
||||
|
||||
if (response.status !== 200) {
|
||||
const details = await response.text();
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error",
|
||||
text: `There was a problem accessing the server. Please try again later. (${details})`,
|
||||
},
|
||||
-1,
|
||||
);
|
||||
throw await response.text();
|
||||
}
|
||||
|
||||
@@ -263,9 +289,15 @@ export default class DiscoverView extends Vue {
|
||||
}
|
||||
} catch (e) {
|
||||
console.log("Error with feed load:", e);
|
||||
this.alertMessage =
|
||||
e.userMessage || "There was an error retrieving projects.";
|
||||
this.alertTitle = "Error";
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error",
|
||||
text: e.userMessage || "There was a problem retrieving projects.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
} finally {
|
||||
this.isLoading = false;
|
||||
}
|
||||
|
||||
@@ -6,6 +6,94 @@
|
||||
Time Safari
|
||||
</h1>
|
||||
|
||||
<div class="mb-8">
|
||||
<h2 class="text-xl font-bold mb-4">Notiwind Alert Test Suite</h2>
|
||||
|
||||
<button
|
||||
@click="
|
||||
this.$notify(
|
||||
{
|
||||
group: 'alert',
|
||||
type: 'toast',
|
||||
text: 'I\'m a toast. Don\'t mind me.',
|
||||
},
|
||||
5000,
|
||||
)
|
||||
"
|
||||
class="font-bold uppercase bg-slate-400 text-white px-3 py-2 rounded-md mr-2"
|
||||
>
|
||||
Toast (self-dismiss)
|
||||
</button>
|
||||
|
||||
<button
|
||||
@click="
|
||||
this.$notify(
|
||||
{
|
||||
group: 'alert',
|
||||
type: 'info',
|
||||
title: 'Information Alert',
|
||||
text: 'Just wanted you to know.',
|
||||
},
|
||||
-1,
|
||||
)
|
||||
"
|
||||
class="font-bold uppercase bg-slate-600 text-white px-3 py-2 rounded-md mr-2"
|
||||
>
|
||||
Info
|
||||
</button>
|
||||
|
||||
<button
|
||||
@click="
|
||||
this.$notify(
|
||||
{
|
||||
group: 'alert',
|
||||
type: 'success',
|
||||
title: 'Success Alert',
|
||||
text: 'Congratulations!',
|
||||
},
|
||||
-1,
|
||||
)
|
||||
"
|
||||
class="font-bold uppercase bg-emerald-600 text-white px-3 py-2 rounded-md mr-2"
|
||||
>
|
||||
Success
|
||||
</button>
|
||||
|
||||
<button
|
||||
@click="
|
||||
this.$notify(
|
||||
{
|
||||
group: 'alert',
|
||||
type: 'warning',
|
||||
title: 'Warning Alert',
|
||||
text: 'You might wanna look at this.',
|
||||
},
|
||||
-1,
|
||||
)
|
||||
"
|
||||
class="font-bold uppercase bg-amber-600 text-white px-3 py-2 rounded-md mr-2"
|
||||
>
|
||||
Warning
|
||||
</button>
|
||||
|
||||
<button
|
||||
@click="
|
||||
this.$notify(
|
||||
{
|
||||
group: 'alert',
|
||||
type: 'danger',
|
||||
title: 'Danger Alert',
|
||||
text: 'Something terrible has happened!',
|
||||
},
|
||||
-1,
|
||||
)
|
||||
"
|
||||
class="font-bold uppercase bg-rose-600 text-white px-3 py-2 rounded-md mr-2"
|
||||
>
|
||||
Danger
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<div class="mb-8">
|
||||
<h2 class="text-xl font-bold">Quick Action</h2>
|
||||
<p class="mb-4">Show appreciation to a contact:</p>
|
||||
@@ -22,7 +110,7 @@
|
||||
<h3
|
||||
class="text-xs font-medium text-ellipsis whitespace-nowrap overflow-hidden"
|
||||
>
|
||||
{{ contact.name || contact.did }}
|
||||
{{ contact.name || "(no name)" }}
|
||||
</h3>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -39,7 +127,6 @@
|
||||
<!-- If there are no contacts, show this instead: -->
|
||||
<div
|
||||
class="rounded border border-dashed border-slate-300 bg-slate-100 px-4 py-3 text-center italic text-slate-500"
|
||||
v-if="allContacts.length === 0"
|
||||
>
|
||||
(No contacts to show.)
|
||||
</div>
|
||||
@@ -158,10 +245,17 @@ export default class HomeView extends Vue {
|
||||
this.feedLastViewedId = settings?.lastViewedClaimId;
|
||||
this.updateAllFeed();
|
||||
} catch (err) {
|
||||
this.alertTitle = "Error";
|
||||
this.alertMessage =
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error",
|
||||
text:
|
||||
err.userMessage ||
|
||||
"There was an error retrieving the latest sweet, sweet action.";
|
||||
"There was an error retrieving the latest sweet, sweet action.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -210,9 +304,15 @@ export default class HomeView extends Vue {
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log("Error with feed load:", e);
|
||||
this.alertMessage =
|
||||
e.userMessage || "There was an error retrieving feed data.";
|
||||
this.alertTitle = "Error";
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Export Error",
|
||||
text: e.userMessage || "There was an error retrieving feed data.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
});
|
||||
|
||||
this.isHiddenSpinner = true;
|
||||
@@ -287,7 +387,7 @@ export default class HomeView extends Vue {
|
||||
handleDialogResult(result) {
|
||||
if (result.action === "confirm") {
|
||||
return new Promise((resolve) => {
|
||||
this.recordGive(result.giver?.did, result.description, result.hours);
|
||||
this.recordGive(result.contact?.did, result.description, result.hours);
|
||||
resolve();
|
||||
});
|
||||
} else {
|
||||
@@ -303,17 +403,27 @@ export default class HomeView extends Vue {
|
||||
*/
|
||||
public async recordGive(giverDid, description, hours) {
|
||||
if (!this.activeDid) {
|
||||
this.setAlert(
|
||||
"Error",
|
||||
"You must select an identity before you can record a give.",
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error",
|
||||
text: "You must select an identity before you can record a give.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!description && !hours) {
|
||||
this.setAlert(
|
||||
"Error",
|
||||
"You must enter a description or some number of hours.",
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error",
|
||||
text: "You must enter a description or some number of hours.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
return;
|
||||
}
|
||||
@@ -333,19 +443,38 @@ export default class HomeView extends Vue {
|
||||
if (this.isGiveCreationError(result)) {
|
||||
const errorMessage = this.getGiveCreationErrorMessage(result);
|
||||
console.log("Error with give result:", result);
|
||||
this.setAlert(
|
||||
"Error",
|
||||
errorMessage || "There was an error recording the give.",
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error",
|
||||
text: errorMessage || "There was an error recording the give.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
} else {
|
||||
this.setAlert("Success", "That gift was recorded.");
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "success",
|
||||
title: "Success",
|
||||
text: "That gift was recorded.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log("Error with give caught:", error);
|
||||
this.setAlert(
|
||||
"Error",
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error",
|
||||
text:
|
||||
this.getGiveErrorMessage(error) ||
|
||||
"There was an error recording the give.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -133,13 +133,19 @@ export default class IdentitySwitcherView extends Vue {
|
||||
this.limitsMessage = "No identity.";
|
||||
this.loadingLimits = false;
|
||||
} else {
|
||||
this.alertMessage =
|
||||
"Clear your cache and start over (after data backup).";
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error Creating Account",
|
||||
text: "Clear your cache and start over (after data backup).",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
console.error(
|
||||
"Telling user to clear cache at page create because:",
|
||||
err,
|
||||
);
|
||||
this.alertTitle = "Error Creating Account";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,20 +245,41 @@ export default class NewEditProjectView extends Vue {
|
||||
if (serverError) {
|
||||
if (Object.prototype.hasOwnProperty.call(serverError, "message")) {
|
||||
console.log(serverError);
|
||||
this.alertTitle = "User Message";
|
||||
userMessage = serverError.response.data.error.message; // This is info for the user.
|
||||
this.alertMessage = userMessage;
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "User Message",
|
||||
text: userMessage,
|
||||
},
|
||||
-1,
|
||||
);
|
||||
} else {
|
||||
this.alertTitle = "Server Message";
|
||||
this.alertMessage = JSON.stringify(serverError.toJSON());
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Server Message",
|
||||
text: JSON.stringify(serverError.toJSON()),
|
||||
},
|
||||
-1,
|
||||
);
|
||||
}
|
||||
} else {
|
||||
console.error(
|
||||
"Here's the full error trying to save the claim:",
|
||||
error,
|
||||
);
|
||||
this.alertTitle = "Claim Error";
|
||||
this.alertMessage = error as string;
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Claim Error",
|
||||
text: error as string,
|
||||
},
|
||||
-1,
|
||||
);
|
||||
}
|
||||
// Now set that error for the user to see.
|
||||
this.errorMessage = userMessage;
|
||||
|
||||
@@ -12,6 +12,13 @@
|
||||
>
|
||||
<fa icon="chevron-left" class="fa-fw"></fa>
|
||||
</button>
|
||||
<!-- Context Menu -->
|
||||
<a
|
||||
href=""
|
||||
class="text-lg text-center px-2 py-1 absolute -right-2 -top-1"
|
||||
><fa icon="ellipsis-vertical" class="fa-fw"></fa
|
||||
></a>
|
||||
|
||||
View Plan
|
||||
</h1>
|
||||
</div>
|
||||
@@ -49,7 +56,6 @@
|
||||
</div>
|
||||
</div>
|
||||
<button
|
||||
v-if="issuer == activeDid"
|
||||
type="button"
|
||||
class="block w-full text-center text-md uppercase bg-slate-500 text-white px-1.5 py-2 rounded-md"
|
||||
@click="onEditClick()"
|
||||
@@ -279,16 +285,38 @@ export default class ProjectViewView extends Vue {
|
||||
this.truncatedDesc = this.description.slice(0, this.truncateLength);
|
||||
} else if (resp.status === 404) {
|
||||
// actually, axios throws an error so we never get here
|
||||
this.alertMessage = "That project does not exist.";
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error",
|
||||
text: "That project does not exist.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
}
|
||||
} catch (error: unknown) {
|
||||
const serverError = error as AxiosError;
|
||||
if (serverError.response?.status === 404) {
|
||||
this.alertMessage = "That project does not exist.";
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error",
|
||||
text: "That project does not exist.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
} else {
|
||||
this.alertMessage =
|
||||
"Something went wrong retrieving that project." +
|
||||
" See logs for more info.";
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error",
|
||||
text: "Something went wrong retrieving that project. See logs for more info.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
console.error("Error retrieving project:", serverError.message);
|
||||
}
|
||||
}
|
||||
@@ -302,12 +330,27 @@ export default class ProjectViewView extends Vue {
|
||||
if (resp.status === 200 && resp.data.data) {
|
||||
this.givesToThis = resp.data.data;
|
||||
} else {
|
||||
this.alertMessage = "Failed to retrieve gives to this project.";
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error",
|
||||
text: "Failed to retrieve gives to this project.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
}
|
||||
} catch (error: unknown) {
|
||||
const serverError = error as AxiosError;
|
||||
this.alertMessage =
|
||||
"Something went wrong retrieving gives to this project.";
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error",
|
||||
text: "Something went wrong retrieving gives to this project.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
console.error(
|
||||
"Error retrieving gives to this project:",
|
||||
serverError.message,
|
||||
@@ -323,11 +366,27 @@ export default class ProjectViewView extends Vue {
|
||||
if (resp.status === 200 && resp.data.data) {
|
||||
this.givesByThis = resp.data.data;
|
||||
} else {
|
||||
this.alertMessage = "Failed to retrieve gives by this project.";
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error",
|
||||
text: "Failed to retrieve gives by this project.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
}
|
||||
} catch (error: unknown) {
|
||||
const serverError = error as AxiosError;
|
||||
this.alertMessage = "Something went wrong retrieving gives by project.";
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error",
|
||||
text: "Something went wrong retrieving gives by project.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
console.error(
|
||||
"Error retrieving gives by this project:",
|
||||
serverError.message,
|
||||
@@ -358,16 +417,28 @@ export default class ProjectViewView extends Vue {
|
||||
*/
|
||||
async recordGive(giverDid, description, hours) {
|
||||
if (!this.activeDid) {
|
||||
this.alertTitle = "Error";
|
||||
this.alertMessage =
|
||||
"You must select an identity before you can record a give.";
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error",
|
||||
text: "You must select an identity before you can record a give.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!description && !hours) {
|
||||
this.alertTitle = "Error";
|
||||
this.alertMessage =
|
||||
"You must enter a description or some number of hours.";
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error",
|
||||
text: "You must enter a description or some number of hours.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -386,21 +457,42 @@ export default class ProjectViewView extends Vue {
|
||||
|
||||
if (result.status !== 201 || result.data?.error) {
|
||||
console.log("Error with give result:", result);
|
||||
this.alertTitle = "Error";
|
||||
this.alertMessage =
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error",
|
||||
text:
|
||||
result.data?.error?.message ||
|
||||
"There was an error recording the give.";
|
||||
"There was an error recording the give.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
} else {
|
||||
this.alertTitle = "Success";
|
||||
this.alertMessage = "That gift was recorded.";
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "success",
|
||||
title: "Success",
|
||||
text: "That gift was recorded.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
}
|
||||
} catch (e) {
|
||||
console.log("Error with give caught:", e);
|
||||
this.alertTitle = "Error";
|
||||
this.alertMessage =
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error",
|
||||
text:
|
||||
e.userMessage ||
|
||||
e.response?.data?.error?.message ||
|
||||
"There was an error recording the give.";
|
||||
"There was an error recording the give.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
|
||||
<!-- Quick Search -->
|
||||
|
||||
<div id="QuickSearch" class="mb-4 flex">
|
||||
<input
|
||||
type="text"
|
||||
placeholder="Search…"
|
||||
@@ -18,6 +19,7 @@
|
||||
>
|
||||
<fa icon="magnifying-glass" class="fa-fw"></fa>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- New Project -->
|
||||
<button
|
||||
@@ -37,7 +39,7 @@
|
||||
|
||||
<!-- Results List -->
|
||||
<InfiniteScroll @reached-bottom="loadMoreData">
|
||||
<ul>
|
||||
<ul class="border-t border-slate-300">
|
||||
<li
|
||||
class="border-b border-slate-300"
|
||||
v-for="project in projects"
|
||||
@@ -124,8 +126,15 @@ export default class ProjectsView extends Vue {
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Got error loading projects:", error.message);
|
||||
this.alertTitle = "Error";
|
||||
this.alertMessage = "Got an error loading projects:" + error.message;
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error",
|
||||
text: "Got an error loading projects: " + error.message,
|
||||
},
|
||||
-1,
|
||||
);
|
||||
} finally {
|
||||
this.isLoading = false;
|
||||
}
|
||||
@@ -194,8 +203,15 @@ export default class ProjectsView extends Vue {
|
||||
|
||||
if (this.numAccounts === 0) {
|
||||
console.error("No accounts found.");
|
||||
this.alertTitle = "Error";
|
||||
this.alertMessage = "You need an identity to load your projects.";
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error",
|
||||
text: "You need an identity to load your projects.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
} else {
|
||||
const identity = await this.getIdentity(activeDid);
|
||||
this.current = identity;
|
||||
@@ -203,8 +219,15 @@ export default class ProjectsView extends Vue {
|
||||
}
|
||||
} catch (err) {
|
||||
console.log("Error initializing:", err);
|
||||
this.alertTitle = "Error";
|
||||
this.alertMessage = "Something went wrong loading your projects.";
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error",
|
||||
text: "Something went wrong loading your projects.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -72,8 +72,15 @@ export default class SeedBackupView extends Vue {
|
||||
this.activeAccount = R.find((acc) => acc.did === activeDid, accounts);
|
||||
} catch (err) {
|
||||
console.error("Got an error loading an identity:", err);
|
||||
this.alertTitle = "Error Loading Account";
|
||||
this.alertMessage = "Got an error loading your seed data.";
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error Loading Account",
|
||||
text: "Got an error loading your seed data.",
|
||||
},
|
||||
-1,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -62,8 +62,15 @@ export default class StatisticsView extends Vue {
|
||||
this.world = newWorld;
|
||||
} catch (err) {
|
||||
console.log(err);
|
||||
this.alertTitle = "Mounting error";
|
||||
this.alertMessage = err.message;
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Mounting Error",
|
||||
text: err.message,
|
||||
},
|
||||
-1,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user