for BVC shortcut: send attend & give actions, and list actions to confirm
This commit is contained in:
@@ -582,7 +582,7 @@ export default class App extends Vue {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.log("Push provider server communication failed:", error);
|
console.error("Push provider server communication failed:", error);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -597,7 +597,7 @@ export default class App extends Vue {
|
|||||||
return response.ok;
|
return response.ok;
|
||||||
})
|
})
|
||||||
.catch((error) => {
|
.catch((error) => {
|
||||||
console.log("Push server communication failed:", error);
|
console.error("Push server communication failed:", error);
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -77,7 +77,6 @@ import {
|
|||||||
import * as libsUtil from "@/libs/util";
|
import * as libsUtil from "@/libs/util";
|
||||||
import { accountsDB, db } from "@/db/index";
|
import { accountsDB, db } from "@/db/index";
|
||||||
import { MASTER_SETTINGS_KEY, Settings } from "@/db/tables/settings";
|
import { MASTER_SETTINGS_KEY, Settings } from "@/db/tables/settings";
|
||||||
import { Account } from "@/db/tables/accounts";
|
|
||||||
import { Contact } from "@/db/tables/contacts";
|
import { Contact } from "@/db/tables/contacts";
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@@ -206,22 +205,6 @@ export default class GiftedDialog extends Vue {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getIdentity(activeDid: string) {
|
|
||||||
await accountsDB.open();
|
|
||||||
const account = (await accountsDB.accounts
|
|
||||||
.where("did")
|
|
||||||
.equals(activeDid)
|
|
||||||
.first()) as Account;
|
|
||||||
const identity = JSON.parse(account?.identity || "null");
|
|
||||||
|
|
||||||
if (!identity) {
|
|
||||||
throw new Error(
|
|
||||||
"Attempted to load Give records for DID ${activeDid} but no identifier was found",
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return identity;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param giverDid may be null
|
* @param giverDid may be null
|
||||||
@@ -262,7 +245,7 @@ export default class GiftedDialog extends Vue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const identity = await this.getIdentity(this.activeDid);
|
const identity = await libsUtil.getIdentity(this.activeDid);
|
||||||
const result = await createAndSubmitGive(
|
const result = await createAndSubmitGive(
|
||||||
this.axios,
|
this.axios,
|
||||||
this.apiServer,
|
this.apiServer,
|
||||||
|
|||||||
@@ -72,9 +72,8 @@ import { Vue, Component, Prop } from "vue-facing-decorator";
|
|||||||
import { NotificationIface } from "@/constants/app";
|
import { NotificationIface } from "@/constants/app";
|
||||||
import { createAndSubmitOffer } from "@/libs/endorserServer";
|
import { createAndSubmitOffer } from "@/libs/endorserServer";
|
||||||
import * as libsUtil from "@/libs/util";
|
import * as libsUtil from "@/libs/util";
|
||||||
import { accountsDB, db } from "@/db/index";
|
import { db } from "@/db/index";
|
||||||
import { MASTER_SETTINGS_KEY, Settings } from "@/db/tables/settings";
|
import { MASTER_SETTINGS_KEY, Settings } from "@/db/tables/settings";
|
||||||
import { Account } from "@/db/tables/accounts";
|
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
export default class OfferDialog extends Vue {
|
export default class OfferDialog extends Vue {
|
||||||
@@ -102,7 +101,7 @@ export default class OfferDialog extends Vue {
|
|||||||
this.activeDid = settings?.activeDid || "";
|
this.activeDid = settings?.activeDid || "";
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
console.log("Error retrieving settings from database:", err);
|
console.error("Error retrieving settings from database:", err);
|
||||||
this.$notify(
|
this.$notify(
|
||||||
{
|
{
|
||||||
group: "alert",
|
group: "alert",
|
||||||
@@ -173,22 +172,6 @@ export default class OfferDialog extends Vue {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public async getIdentity(activeDid: string) {
|
|
||||||
await accountsDB.open();
|
|
||||||
const account = (await accountsDB.accounts
|
|
||||||
.where("did")
|
|
||||||
.equals(activeDid)
|
|
||||||
.first()) as Account;
|
|
||||||
const identity = JSON.parse(account?.identity || "null");
|
|
||||||
|
|
||||||
if (!identity) {
|
|
||||||
throw new Error(
|
|
||||||
`Attempted to load Offer records for DID ${activeDid} but no identifier was found`,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
return identity;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
* @param description may be an empty string
|
* @param description may be an empty string
|
||||||
@@ -228,7 +211,7 @@ export default class OfferDialog extends Vue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const identity = await this.getIdentity(this.activeDid);
|
const identity = await libsUtil.getIdentity(this.activeDid);
|
||||||
const result = await createAndSubmitOffer(
|
const result = await createAndSubmitOffer(
|
||||||
this.axios,
|
this.axios,
|
||||||
this.apiServer,
|
this.apiServer,
|
||||||
@@ -245,7 +228,7 @@ export default class OfferDialog extends Vue {
|
|||||||
this.isOfferCreationError(result.response)
|
this.isOfferCreationError(result.response)
|
||||||
) {
|
) {
|
||||||
const errorMessage = this.getOfferCreationErrorMessage(result);
|
const errorMessage = this.getOfferCreationErrorMessage(result);
|
||||||
console.log("Error with offer creation result:", result);
|
console.error("Error with offer creation result:", result);
|
||||||
this.$notify(
|
this.$notify(
|
||||||
{
|
{
|
||||||
group: "alert",
|
group: "alert",
|
||||||
@@ -268,7 +251,7 @@ export default class OfferDialog extends Vue {
|
|||||||
}
|
}
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
console.log("Error with offer recordation caught:", error);
|
console.error("Error with offer recordation caught:", error);
|
||||||
const message =
|
const message =
|
||||||
error.userMessage ||
|
error.userMessage ||
|
||||||
error.response?.data?.error?.message ||
|
error.response?.data?.error?.message ||
|
||||||
|
|||||||
@@ -229,16 +229,16 @@ export interface ErrorResponse {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ErrorResult {
|
|
||||||
type: "error";
|
|
||||||
error: InternalError;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface InternalError {
|
export interface InternalError {
|
||||||
error: string; // for system logging
|
error: string; // for system logging
|
||||||
userMessage?: string; // for user display
|
userMessage?: string; // for user display
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ErrorResult extends ResultWithType {
|
||||||
|
type: "error";
|
||||||
|
error: InternalError;
|
||||||
|
}
|
||||||
|
|
||||||
export type CreateAndSubmitClaimResult = SuccessResult | ErrorResult;
|
export type CreateAndSubmitClaimResult = SuccessResult | ErrorResult;
|
||||||
|
|
||||||
// This is used to check for hidden info.
|
// This is used to check for hidden info.
|
||||||
@@ -758,12 +758,23 @@ export const claimSpecialDescription = (
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// from https://stackoverflow.com/a/175787/845494
|
export const BVC_MEETUPS_PROJECT_CLAIM_ID =
|
||||||
//
|
//"https://endorser.ch/entity/01GXYPFF7FA03NXKPYY142PY4H";
|
||||||
export function isNumeric(str: string): boolean {
|
"https://endorser.ch/entity/01HNTZYJJXTGT0EZS3VEJGX7AK";
|
||||||
return !isNaN(+str);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function numberOrZero(str: string): number {
|
export const bvcMeetingJoinClaim = (did: string, startTime: string) => {
|
||||||
return isNumeric(str) ? +str : 0;
|
return {
|
||||||
}
|
"@context": SCHEMA_ORG_CONTEXT,
|
||||||
|
"@type": "JoinAction",
|
||||||
|
agent: {
|
||||||
|
identifier: did,
|
||||||
|
},
|
||||||
|
event: {
|
||||||
|
organizer: {
|
||||||
|
name: "Bountiful Voluntaryist Community",
|
||||||
|
},
|
||||||
|
name: "Saturday Morning Meeting",
|
||||||
|
startTime: startTime,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|||||||
@@ -1,14 +1,16 @@
|
|||||||
// many of these are also found in endorser-mobile utility.ts
|
// many of these are also found in endorser-mobile utility.ts
|
||||||
|
|
||||||
import axios, { AxiosResponse } from "axios";
|
import axios, { AxiosResponse } from "axios";
|
||||||
|
import { IIdentifier } from "@veramo/core";
|
||||||
|
import { useClipboard } from "@vueuse/core";
|
||||||
|
|
||||||
import { DEFAULT_PUSH_SERVER } from "@/constants/app";
|
import { DEFAULT_PUSH_SERVER } from "@/constants/app";
|
||||||
import { accountsDB, db } from "@/db/index";
|
import { accountsDB, db } from "@/db/index";
|
||||||
|
import { Account } from "@/db/tables/accounts";
|
||||||
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
|
import { MASTER_SETTINGS_KEY } from "@/db/tables/settings";
|
||||||
import { deriveAddress, generateSeed, newIdentifier } from "@/libs/crypto";
|
import { deriveAddress, generateSeed, newIdentifier } from "@/libs/crypto";
|
||||||
import { GenericServerRecord, containsHiddenDid } from "@/libs/endorserServer";
|
import { GenericServerRecord, containsHiddenDid } from "@/libs/endorserServer";
|
||||||
import * as serverUtil from "@/libs/endorserServer";
|
import * as serverUtil from "@/libs/endorserServer";
|
||||||
import { useClipboard } from "@vueuse/core";
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
const Buffer = require("buffer/").Buffer;
|
const Buffer = require("buffer/").Buffer;
|
||||||
@@ -55,6 +57,16 @@ export function iconForUnitCode(unitCode: string) {
|
|||||||
return UNIT_CODES[unitCode]?.faIcon || "question";
|
return UNIT_CODES[unitCode]?.faIcon || "question";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// from https://stackoverflow.com/a/175787/845494
|
||||||
|
//
|
||||||
|
export function isNumeric(str: string): boolean {
|
||||||
|
return !isNaN(+str);
|
||||||
|
}
|
||||||
|
|
||||||
|
export function numberOrZero(str: string): number {
|
||||||
|
return isNumeric(str) ? +str : 0;
|
||||||
|
}
|
||||||
|
|
||||||
export const isGlobalUri = (uri: string) => {
|
export const isGlobalUri = (uri: string) => {
|
||||||
return uri && uri.match(new RegExp(/^[A-Za-z][A-Za-z0-9+.-]+:/));
|
return uri && uri.match(new RegExp(/^[A-Za-z][A-Za-z0-9+.-]+:/));
|
||||||
};
|
};
|
||||||
@@ -180,6 +192,22 @@ export function findAllVisibleToDids(
|
|||||||
*
|
*
|
||||||
**/
|
**/
|
||||||
|
|
||||||
|
export const getIdentity = async (activeDid: string): Promise<IIdentifier> => {
|
||||||
|
await accountsDB.open();
|
||||||
|
const account = (await accountsDB.accounts
|
||||||
|
.where("did")
|
||||||
|
.equals(activeDid)
|
||||||
|
.first()) as Account;
|
||||||
|
const identity = JSON.parse(account?.identity || "null");
|
||||||
|
|
||||||
|
if (!identity) {
|
||||||
|
throw new Error(
|
||||||
|
`Attempted to load Offer records for DID ${activeDid} but no identifier was found`,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return identity;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a new identity, saves it to the database, and sets it as the active identity.
|
* Generates a new identity, saves it to the database, and sets it as the active identity.
|
||||||
* @return {Promise<string>} with the DID of the new identity
|
* @return {Promise<string>} with the DID of the new identity
|
||||||
|
|||||||
@@ -446,7 +446,7 @@
|
|||||||
>
|
>
|
||||||
<!-- label -->
|
<!-- label -->
|
||||||
<span class="text-slate-500 text-sm font-bold"
|
<span class="text-slate-500 text-sm font-bold"
|
||||||
>Show Shortcut on Home Page</span
|
>Show BVC Shortcut on Home Page</span
|
||||||
>
|
>
|
||||||
<!-- toggle -->
|
<!-- toggle -->
|
||||||
<div class="relative ml-2">
|
<div class="relative ml-2">
|
||||||
|
|||||||
@@ -179,7 +179,7 @@ export default class ContactAmountssView extends Vue {
|
|||||||
}
|
}
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
console.log("Error retrieving settings or gives.", err);
|
console.error("Error retrieving settings or gives.", err);
|
||||||
this.$notify(
|
this.$notify(
|
||||||
{
|
{
|
||||||
group: "alert",
|
group: "alert",
|
||||||
|
|||||||
@@ -119,7 +119,7 @@ export default class ContactGiftingView extends Vue {
|
|||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
console.log("Error retrieving settings & contacts:", err);
|
console.error("Error retrieving settings & contacts:", err);
|
||||||
this.$notify(
|
this.$notify(
|
||||||
{
|
{
|
||||||
group: "alert",
|
group: "alert",
|
||||||
|
|||||||
@@ -180,7 +180,6 @@ export default class ContactQRScanShow extends Vue {
|
|||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
onScanDetect(content: any) {
|
onScanDetect(content: any) {
|
||||||
if (content[0]?.rawValue) {
|
if (content[0]?.rawValue) {
|
||||||
//console.log("onDetect", content[0].rawValue);
|
|
||||||
localStorage.setItem("contactEndorserUrl", content[0].rawValue);
|
localStorage.setItem("contactEndorserUrl", content[0].rawValue);
|
||||||
this.$router.push({ name: "contacts" });
|
this.$router.push({ name: "contacts" });
|
||||||
} else {
|
} else {
|
||||||
@@ -198,7 +197,7 @@ export default class ContactQRScanShow extends Vue {
|
|||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
onScanError(error: any) {
|
onScanError(error: any) {
|
||||||
console.log("Scan was invalid:", error);
|
console.error("Scan was invalid:", error);
|
||||||
this.$notify(
|
this.$notify(
|
||||||
{
|
{
|
||||||
group: "alert",
|
group: "alert",
|
||||||
|
|||||||
@@ -284,6 +284,7 @@
|
|||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { AxiosError } from "axios";
|
import { AxiosError } from "axios";
|
||||||
|
import { IndexableType } from "dexie";
|
||||||
import * as didJwt from "did-jwt";
|
import * as didJwt from "did-jwt";
|
||||||
import * as R from "ramda";
|
import * as R from "ramda";
|
||||||
import { IIdentifier } from "@veramo/core";
|
import { IIdentifier } from "@veramo/core";
|
||||||
@@ -311,7 +312,6 @@ import * as libsUtil from "@/libs/util";
|
|||||||
import QuickNav from "@/components/QuickNav.vue";
|
import QuickNav from "@/components/QuickNav.vue";
|
||||||
import EntityIcon from "@/components/EntityIcon.vue";
|
import EntityIcon from "@/components/EntityIcon.vue";
|
||||||
import { Account } from "@/db/tables/accounts";
|
import { Account } from "@/db/tables/accounts";
|
||||||
import { IndexableType } from "dexie";
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||||
const Buffer = require("buffer/").Buffer;
|
const Buffer = require("buffer/").Buffer;
|
||||||
@@ -497,7 +497,7 @@ export default class ContactsView extends Vue {
|
|||||||
this.givenToMeConfirmed = givenToMeConfirmed;
|
this.givenToMeConfirmed = givenToMeConfirmed;
|
||||||
this.givenToMeUnconfirmed = givenToMeUnconfirmed;
|
this.givenToMeUnconfirmed = givenToMeUnconfirmed;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("Error loading gives", error);
|
console.error("Error loading gives", error);
|
||||||
this.$notify(
|
this.$notify(
|
||||||
{
|
{
|
||||||
group: "alert",
|
group: "alert",
|
||||||
@@ -1000,7 +1000,7 @@ export default class ContactsView extends Vue {
|
|||||||
-1,
|
-1,
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
console.log("Got bad server response when checking visibility: ", resp);
|
console.error("Got bad server response checking visibility:", resp);
|
||||||
const message = resp.data.error?.message || "Got bad server response.";
|
const message = resp.data.error?.message || "Got bad server response.";
|
||||||
this.$notify(
|
this.$notify(
|
||||||
{
|
{
|
||||||
@@ -1013,7 +1013,7 @@ export default class ContactsView extends Vue {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.log("Caught error from request to check visibility:", err);
|
console.error("Caught error from request to check visibility:", err);
|
||||||
this.$notify(
|
this.$notify(
|
||||||
{
|
{
|
||||||
group: "alert",
|
group: "alert",
|
||||||
@@ -1026,12 +1026,6 @@ export default class ContactsView extends Vue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// from https://stackoverflow.com/a/175787/845494
|
|
||||||
//
|
|
||||||
private isNumeric(str: string): boolean {
|
|
||||||
return !isNaN(+str);
|
|
||||||
}
|
|
||||||
|
|
||||||
private nameForDid(contacts: Array<Contact>, did: string): string {
|
private nameForDid(contacts: Array<Contact>, did: string): string {
|
||||||
const contact = R.find((con) => con.did == did, contacts);
|
const contact = R.find((con) => con.did == did, contacts);
|
||||||
return this.nameForContact(contact);
|
return this.nameForContact(contact);
|
||||||
@@ -1067,7 +1061,7 @@ export default class ContactsView extends Vue {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!this.isNumeric(this.hourInput)) {
|
if (!libsUtil.isNumeric(this.hourInput)) {
|
||||||
this.$notify(
|
this.$notify(
|
||||||
{
|
{
|
||||||
group: "alert",
|
group: "alert",
|
||||||
@@ -1204,7 +1198,7 @@ export default class ContactsView extends Vue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log("Error in createAndSubmitContactGive: ", error);
|
console.error("Error in createAndSubmitContactGive: ", error);
|
||||||
let userMessage = "There was an error. See logs for more info.";
|
let userMessage = "There was an error. See logs for more info.";
|
||||||
const serverError = error as AxiosError;
|
const serverError = error as AxiosError;
|
||||||
if (serverError) {
|
if (serverError) {
|
||||||
|
|||||||
@@ -254,7 +254,7 @@ export default class DiscoverView extends Vue {
|
|||||||
|
|
||||||
if (response.status !== 200) {
|
if (response.status !== 200) {
|
||||||
const details = await response.text();
|
const details = await response.text();
|
||||||
console.log("Problem with full search:", details);
|
console.error("Problem with full search:", details);
|
||||||
this.$notify(
|
this.$notify(
|
||||||
{
|
{
|
||||||
group: "alert",
|
group: "alert",
|
||||||
@@ -282,7 +282,7 @@ export default class DiscoverView extends Vue {
|
|||||||
}
|
}
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
console.log("Error with feed load:", e);
|
console.error("Error with feed load:", e);
|
||||||
this.$notify(
|
this.$notify(
|
||||||
{
|
{
|
||||||
group: "alert",
|
group: "alert",
|
||||||
@@ -337,7 +337,7 @@ export default class DiscoverView extends Vue {
|
|||||||
|
|
||||||
if (response.status !== 200) {
|
if (response.status !== 200) {
|
||||||
const details = await response.text();
|
const details = await response.text();
|
||||||
console.log("Problem with nearby search:", details);
|
console.error("Problem with nearby search:", details);
|
||||||
this.$notify(
|
this.$notify(
|
||||||
{
|
{
|
||||||
group: "alert",
|
group: "alert",
|
||||||
@@ -374,7 +374,7 @@ export default class DiscoverView extends Vue {
|
|||||||
}
|
}
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
console.log("Error with feed load:", e);
|
console.error("Error with feed load:", e);
|
||||||
this.$notify(
|
this.$notify(
|
||||||
{
|
{
|
||||||
group: "alert",
|
group: "alert",
|
||||||
|
|||||||
@@ -3,8 +3,8 @@
|
|||||||
<TopMessage />
|
<TopMessage />
|
||||||
|
|
||||||
<!-- CONTENT -->
|
<!-- CONTENT -->
|
||||||
<section id="Content" class="p-6 pb-24 max-w-3xl mx-auto">
|
<section id="Content" class="p-2 pb-24 max-w-3xl mx-auto">
|
||||||
<h1 id="ViewHeading" class="text-4xl text-center font-light pt-4 mb-8">
|
<h1 id="ViewHeading" class="text-4xl text-center font-light px-4 mb-8">
|
||||||
Time Safari
|
Time Safari
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
@@ -346,7 +346,7 @@ export default class HomeView extends Vue {
|
|||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
} catch (err: any) {
|
} catch (err: any) {
|
||||||
console.log("Error retrieving settings or feed.", err);
|
console.error("Error retrieving settings or feed.", err);
|
||||||
this.$notify(
|
this.$notify(
|
||||||
{
|
{
|
||||||
group: "alert",
|
group: "alert",
|
||||||
@@ -452,7 +452,7 @@ export default class HomeView extends Vue {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((e) => {
|
.catch((e) => {
|
||||||
console.log("Error with feed load:", e);
|
console.error("Error with feed load:", e);
|
||||||
this.$notify(
|
this.$notify(
|
||||||
{
|
{
|
||||||
group: "alert",
|
group: "alert",
|
||||||
|
|||||||
@@ -15,20 +15,24 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Heading -->
|
<!-- Heading -->
|
||||||
<h1 id="ViewHeading" class="text-4xl text-center font-light pt-4 mb-4">
|
<h1 id="ViewHeading" class="text-4xl text-center font-light px-4 mb-4">
|
||||||
Beginning of BVC Saturday Meeting
|
Beginning of BVC Saturday Meeting
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<h2 class="text-2xl m-4">You're Here</h2>
|
<h2 class="text-2xl m-2">You're Here</h2>
|
||||||
<div class="m-4 flex">
|
<div class="m-2 flex">
|
||||||
<input type="checkbox" v-model="gaveTime" class="h-6 w-6" />
|
<input type="checkbox" v-model="attended" class="h-6 w-6" />
|
||||||
<span class="pb-2 pl-2 pr-2">Attended</span>
|
<span class="pb-2 pl-2 pr-2">Attended</span>
|
||||||
|
</div>
|
||||||
|
<div class="m-2 flex">
|
||||||
|
<input type="checkbox" v-model="gaveTime" class="h-6 w-6" />
|
||||||
|
<span class="pb-2 pl-2 pr-2">Spent Time</span>
|
||||||
<span v-if="gaveTime">
|
<span v-if="gaveTime">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
placeholder="How much time"
|
placeholder="How much time"
|
||||||
v-model="hours"
|
v-model="hoursStr"
|
||||||
size="1"
|
size="1"
|
||||||
class="border border-slate-400 h-6 px-2"
|
class="border border-slate-400 h-6 px-2"
|
||||||
/>
|
/>
|
||||||
@@ -39,25 +43,44 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="m-4" v-if="gaveTime && hours && hours != '0'">
|
<div
|
||||||
|
v-if="attended || (gaveTime && hoursStr && hoursStr != '0')"
|
||||||
|
class="flex justify-center mt-4"
|
||||||
|
>
|
||||||
<button
|
<button
|
||||||
@click="record()"
|
@click="record()"
|
||||||
class="block text-center text-md font-bold bg-blue-500 text-white px-2 py-3 rounded-md"
|
class="block text-center text-md font-bold bg-blue-500 text-white px-2 py-3 rounded-md w-56"
|
||||||
>
|
>
|
||||||
Sign & Send
|
Sign & Send
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-else class="flex justify-center mt-4">
|
||||||
|
<button
|
||||||
|
class="block text-center text-md font-bold bg-slate-500 text-white px-2 py-3 rounded-md w-56"
|
||||||
|
>
|
||||||
|
Select Your Actions
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
import axios from "axios";
|
||||||
import { DateTime } from "luxon";
|
import { DateTime } from "luxon";
|
||||||
import { Component, Vue } from "vue-facing-decorator";
|
import { Component, Vue } from "vue-facing-decorator";
|
||||||
|
|
||||||
import QuickNav from "@/components/QuickNav.vue";
|
import QuickNav from "@/components/QuickNav.vue";
|
||||||
import TopMessage from "@/components/TopMessage.vue";
|
import TopMessage from "@/components/TopMessage.vue";
|
||||||
import { NotificationIface } from "@/constants/app";
|
import { NotificationIface } from "@/constants/app";
|
||||||
import { numberOrZero } from "@/libs/endorserServer";
|
import { db } from "@/db/index";
|
||||||
|
import {
|
||||||
|
BVC_MEETUPS_PROJECT_CLAIM_ID,
|
||||||
|
bvcMeetingJoinClaim,
|
||||||
|
createAndSubmitClaim,
|
||||||
|
createAndSubmitGive,
|
||||||
|
} from "@/libs/endorserServer";
|
||||||
|
import * as libsUtil from "@/libs/util";
|
||||||
|
import { MASTER_SETTINGS_KEY, Settings } from "@/db/tables/settings";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
components: {
|
components: {
|
||||||
@@ -68,8 +91,11 @@ import { numberOrZero } from "@/libs/endorserServer";
|
|||||||
export default class QuickActionBvcBeginView extends Vue {
|
export default class QuickActionBvcBeginView extends Vue {
|
||||||
$notify!: (notification: NotificationIface, timeout?: number) => void;
|
$notify!: (notification: NotificationIface, timeout?: number) => void;
|
||||||
|
|
||||||
gaveTime = false;
|
activeDid = "";
|
||||||
hours = "1";
|
apiServer = "";
|
||||||
|
attended = true;
|
||||||
|
gaveTime = true;
|
||||||
|
hoursStr = "1";
|
||||||
todayOrPreviousStartDate = "";
|
todayOrPreviousStartDate = "";
|
||||||
|
|
||||||
async mounted() {
|
async mounted() {
|
||||||
@@ -91,9 +117,88 @@ export default class QuickActionBvcBeginView extends Vue {
|
|||||||
}) || "";
|
}) || "";
|
||||||
}
|
}
|
||||||
|
|
||||||
record() {
|
async record() {
|
||||||
const hoursNum = numberOrZero(this.hours);
|
await db.open();
|
||||||
alert("Nope" + hoursNum);
|
const settings = (await db.settings.get(MASTER_SETTINGS_KEY)) as Settings;
|
||||||
|
const activeDid = settings?.activeDid || "";
|
||||||
|
const apiServer = settings?.apiServer || "";
|
||||||
|
|
||||||
|
try {
|
||||||
|
const hoursNum = libsUtil.numberOrZero(this.hoursStr);
|
||||||
|
const identity = await libsUtil.getIdentity(activeDid);
|
||||||
|
|
||||||
|
const result = await createAndSubmitGive(
|
||||||
|
axios,
|
||||||
|
apiServer,
|
||||||
|
identity,
|
||||||
|
activeDid,
|
||||||
|
undefined,
|
||||||
|
undefined,
|
||||||
|
hoursNum,
|
||||||
|
"HUR",
|
||||||
|
BVC_MEETUPS_PROJECT_CLAIM_ID,
|
||||||
|
);
|
||||||
|
if (result.type === "error") {
|
||||||
|
console.error("Error sending give:", result);
|
||||||
|
this.$notify(
|
||||||
|
{
|
||||||
|
group: "alert",
|
||||||
|
type: "danger",
|
||||||
|
title: "Error",
|
||||||
|
text:
|
||||||
|
result?.error?.userMessage ||
|
||||||
|
"There was an error sending the give.",
|
||||||
|
},
|
||||||
|
-1,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const result2 = await createAndSubmitClaim(
|
||||||
|
bvcMeetingJoinClaim(this.activeDid, this.todayOrPreviousStartDate),
|
||||||
|
identity,
|
||||||
|
apiServer,
|
||||||
|
axios,
|
||||||
|
);
|
||||||
|
if (result2.type === "error") {
|
||||||
|
console.error("Error sending give:", result2);
|
||||||
|
this.$notify(
|
||||||
|
{
|
||||||
|
group: "alert",
|
||||||
|
type: "danger",
|
||||||
|
title: "Error",
|
||||||
|
text:
|
||||||
|
result2?.error?.userMessage ||
|
||||||
|
"There was an error sending the attendance.",
|
||||||
|
},
|
||||||
|
-1,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.type === "success" || result2.type === "success") {
|
||||||
|
this.$notify(
|
||||||
|
{
|
||||||
|
group: "alert",
|
||||||
|
type: "success",
|
||||||
|
title: "Success",
|
||||||
|
text: "Your actions have been recorded.",
|
||||||
|
},
|
||||||
|
-1,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
} catch (error: any) {
|
||||||
|
console.error("Error sending claims.", error);
|
||||||
|
this.$notify(
|
||||||
|
{
|
||||||
|
group: "alert",
|
||||||
|
type: "danger",
|
||||||
|
title: "Error",
|
||||||
|
text: error.userMessage || "There was an error sending those claims.",
|
||||||
|
},
|
||||||
|
-1,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -15,19 +15,26 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Heading -->
|
<!-- Heading -->
|
||||||
<h1 id="ViewHeading" class="text-4xl text-center font-light pt-4 mb-4">
|
<h1 id="ViewHeading" class="text-4xl text-center font-light px-4 mb-4">
|
||||||
End of BVC Saturday Meeting
|
End of BVC Saturday Meeting
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<h2 class="text-2xl m-4">Confirm</h2>
|
<h2 class="text-2xl m-2">Confirm</h2>
|
||||||
<div v-if="claimsToConfirm.length === 0">
|
<div v-if="loadingConfirms" class="flex justify-center">
|
||||||
There are no claims today yet for you to confirm.
|
<fa icon="spinner" class="animate-spin" />
|
||||||
<span v-if="claimCountWithHidden">
|
</div>
|
||||||
(There are {{ claimCountWithHidden }} hidden claims.)
|
<div v-else-if="claimsToConfirm.length === 0">
|
||||||
|
There are no claims yet today for you to confirm.
|
||||||
|
<span v-if="claimCountWithHidden > 0">
|
||||||
|
{{
|
||||||
|
claimCountWithHidden === 1
|
||||||
|
? "(There is 1 claim with hidden details.)"
|
||||||
|
: `(There are ${claimCountWithHidden} claims with hidden details.)`
|
||||||
|
}}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<ul class="border-t border-slate-300">
|
<ul class="border-t border-slate-300 m-2">
|
||||||
<li
|
<li
|
||||||
class="border-b border-slate-300 py-2"
|
class="border-b border-slate-300 py-2"
|
||||||
v-for="record in claimsToConfirm"
|
v-for="record in claimsToConfirm"
|
||||||
@@ -36,7 +43,19 @@
|
|||||||
<div class="grid grid-cols-12">
|
<div class="grid grid-cols-12">
|
||||||
<span class="col-span-11 justify-self-start">
|
<span class="col-span-11 justify-self-start">
|
||||||
<span>
|
<span>
|
||||||
<input type="checkbox" class="mr-2 h-6 w-6" />
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
:checked="claimsToConfirmSelected.includes(record.id)"
|
||||||
|
@click="
|
||||||
|
claimsToConfirmSelected.includes(record.id)
|
||||||
|
? claimsToConfirmSelected.splice(
|
||||||
|
claimsToConfirmSelected.indexOf(record.id),
|
||||||
|
1,
|
||||||
|
)
|
||||||
|
: claimsToConfirmSelected.push(record.id)
|
||||||
|
"
|
||||||
|
class="mr-2 h-6 w-6"
|
||||||
|
/>
|
||||||
</span>
|
</span>
|
||||||
{{
|
{{
|
||||||
claimSpecialDescription(
|
claimSpecialDescription(
|
||||||
@@ -59,10 +78,10 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<h2 class="text-2xl m-4">Anything else?</h2>
|
<h2 class="text-2xl m-2">Anything else?</h2>
|
||||||
<div class="m-4 flex">
|
<div class="m-2 flex">
|
||||||
<input type="checkbox" v-model="someoneGave" class="h-6 w-6" />
|
<input type="checkbox" v-model="someoneGave" class="h-6 w-6" />
|
||||||
<span class="pb-2 pl-2 pr-2">Someone gave</span>
|
<span class="pb-2 pl-2 pr-2">Someone else gave</span>
|
||||||
<span v-if="someoneGave">
|
<span v-if="someoneGave">
|
||||||
<input
|
<input
|
||||||
type="text"
|
type="text"
|
||||||
@@ -76,14 +95,24 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="m-4" v-if="someoneGave && description">
|
<div
|
||||||
|
v-if="claimsToConfirmSelected.length || (someoneGave && description)"
|
||||||
|
class="flex justify-center mt-4"
|
||||||
|
>
|
||||||
<button
|
<button
|
||||||
@click="record()"
|
@click="record()"
|
||||||
class="block text-center text-md font-bold bg-blue-500 text-white px-2 py-3 rounded-md"
|
class="block text-center text-md font-bold bg-blue-500 text-white px-2 py-3 rounded-md w-56"
|
||||||
>
|
>
|
||||||
Sign & Send
|
Sign & Send
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
<div v-else class="flex justify-center mt-4">
|
||||||
|
<button
|
||||||
|
class="block text-center text-md font-bold bg-slate-500 text-white px-2 py-3 rounded-md w-56"
|
||||||
|
>
|
||||||
|
Choose What To Confirm
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -123,7 +152,9 @@ export default class QuickActionBvcBeginView extends Vue {
|
|||||||
apiServer = "";
|
apiServer = "";
|
||||||
claimCountWithHidden = 0;
|
claimCountWithHidden = 0;
|
||||||
claimsToConfirm: GenericServerRecord[] = [];
|
claimsToConfirm: GenericServerRecord[] = [];
|
||||||
description = "";
|
claimsToConfirmSelected: string[] = [];
|
||||||
|
description = "breakfast";
|
||||||
|
loadingConfirms = true;
|
||||||
someoneGave = false;
|
someoneGave = false;
|
||||||
|
|
||||||
async created() {
|
async created() {
|
||||||
@@ -135,6 +166,7 @@ export default class QuickActionBvcBeginView extends Vue {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async mounted() {
|
async mounted() {
|
||||||
|
this.loadingConfirms = true;
|
||||||
let currentOrPreviousSat = DateTime.now().setZone("America/Denver");
|
let currentOrPreviousSat = DateTime.now().setZone("America/Denver");
|
||||||
if (currentOrPreviousSat.weekday < 6) {
|
if (currentOrPreviousSat.weekday < 6) {
|
||||||
// it's not Saturday or Sunday,
|
// it's not Saturday or Sunday,
|
||||||
@@ -165,15 +197,7 @@ export default class QuickActionBvcBeginView extends Vue {
|
|||||||
const headers = {
|
const headers = {
|
||||||
Authorization: "Bearer " + (await accessToken(identity)),
|
Authorization: "Bearer " + (await accessToken(identity)),
|
||||||
};
|
};
|
||||||
console.log("todayOrPreviousStartDate", todayOrPreviousStartDate);
|
|
||||||
try {
|
try {
|
||||||
console.log(
|
|
||||||
this.apiServer +
|
|
||||||
"/api/claim/?" +
|
|
||||||
"issuedAt_greaterThanOrEqualTo=" +
|
|
||||||
encodeURIComponent(todayOrPreviousStartDate) +
|
|
||||||
"&excludeConfirmations=true",
|
|
||||||
);
|
|
||||||
const response = await fetch(
|
const response = await fetch(
|
||||||
this.apiServer +
|
this.apiServer +
|
||||||
"/api/claim/?" +
|
"/api/claim/?" +
|
||||||
@@ -187,7 +211,7 @@ export default class QuickActionBvcBeginView extends Vue {
|
|||||||
console.log("Bad response", response);
|
console.log("Bad response", response);
|
||||||
throw new Error("Bad response when retrieving claims.");
|
throw new Error("Bad response when retrieving claims.");
|
||||||
}
|
}
|
||||||
response.json().then((data) => {
|
await response.json().then((data) => {
|
||||||
const dataByOthers = R.reject(
|
const dataByOthers = R.reject(
|
||||||
(claim: GenericServerRecord) => claim.issuer === this.activeDid,
|
(claim: GenericServerRecord) => claim.issuer === this.activeDid,
|
||||||
data,
|
data,
|
||||||
@@ -212,6 +236,7 @@ export default class QuickActionBvcBeginView extends Vue {
|
|||||||
-1,
|
-1,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
this.loadingConfirms = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
onClickLoadClaim(jwtId: string) {
|
onClickLoadClaim(jwtId: string) {
|
||||||
|
|||||||
@@ -15,7 +15,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Heading -->
|
<!-- Heading -->
|
||||||
<h1 id="ViewHeading" class="text-4xl text-center font-light pt-4 mb-4">
|
<h1 id="ViewHeading" class="text-4xl text-center font-light px-4 mb-4">
|
||||||
Bountiful Voluntaryist Community Actions
|
Bountiful Voluntaryist Community Actions
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user