feat: migrate QuickActionBvcBeginView to Enhanced Triple Migration Pattern
- Database: Replace databaseUtil with PlatformServiceMixin - Notifications: Add BVC constants and helper system - Template: Extract computed properties and goBack method - Enhanced logging and comprehensive documentation - All BVC meeting functionality preserved
This commit is contained in:
@@ -8,7 +8,7 @@
|
||||
<div class="text-lg text-center font-light relative px-7">
|
||||
<h1
|
||||
class="text-lg text-center px-2 py-1 absolute -left-2 -top-1"
|
||||
@click="$router.back()"
|
||||
@click="goBack()"
|
||||
>
|
||||
<font-awesome icon="chevron-left" class="fa-fw"></font-awesome>
|
||||
</h1>
|
||||
@@ -44,11 +44,11 @@
|
||||
</div>
|
||||
|
||||
<div
|
||||
v-if="attended || (gaveTime && hoursStr && hoursStr != '0')"
|
||||
v-if="canSubmit"
|
||||
class="flex justify-center mt-4"
|
||||
>
|
||||
<button
|
||||
class="block text-center text-md font-bold bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2 py-3 rounded-md w-56"
|
||||
:class="activeButtonClass"
|
||||
@click="record()"
|
||||
>
|
||||
Sign & Send
|
||||
@@ -56,7 +56,7 @@
|
||||
</div>
|
||||
<div v-else class="flex justify-center mt-4">
|
||||
<button
|
||||
class="block text-center text-md font-bold bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2 py-3 rounded-md w-56"
|
||||
:class="disabledButtonClass"
|
||||
>
|
||||
Select Your Actions
|
||||
</button>
|
||||
@@ -73,7 +73,14 @@ import { Component, Vue } from "vue-facing-decorator";
|
||||
import QuickNav from "../components/QuickNav.vue";
|
||||
import TopMessage from "../components/TopMessage.vue";
|
||||
import { NotificationIface } from "../constants/app";
|
||||
import * as databaseUtil from "../db/databaseUtil";
|
||||
import {
|
||||
NOTIFY_BVC_PROCESSING,
|
||||
NOTIFY_BVC_TIME_ERROR,
|
||||
NOTIFY_BVC_ATTENDANCE_ERROR,
|
||||
NOTIFY_BVC_SUBMISSION_ERROR,
|
||||
createBvcSuccessMessage,
|
||||
} from "../constants/notifications";
|
||||
import { createNotifyHelpers, TIMEOUTS } from "../utils/notify";
|
||||
import {
|
||||
BVC_MEETUPS_PROJECT_CLAIM_ID,
|
||||
bvcMeetingJoinClaim,
|
||||
@@ -82,21 +89,42 @@ import {
|
||||
} from "../libs/endorserServer";
|
||||
import * as libsUtil from "../libs/util";
|
||||
import { logger } from "../utils/logger";
|
||||
import { PlatformServiceMixin } from "../utils/PlatformServiceMixin";
|
||||
|
||||
/**
|
||||
* @file QuickActionBvcBeginView.vue
|
||||
* @description BVC (Bountiful Volunteerism Community) meeting attendance tracker
|
||||
* for Saturday meetings. Allows users to record attendance and time contributions
|
||||
* for weekly BVC meetings in Bountiful, using America/Denver timezone.
|
||||
* @author Matthew Raymer
|
||||
*/
|
||||
|
||||
@Component({
|
||||
components: {
|
||||
QuickNav,
|
||||
TopMessage,
|
||||
},
|
||||
mixins: [PlatformServiceMixin],
|
||||
})
|
||||
export default class QuickActionBvcBeginView extends Vue {
|
||||
$notify!: (notification: NotificationIface, timeout?: number) => void;
|
||||
$router!: Router;
|
||||
|
||||
// Notification helper system
|
||||
private notify = createNotifyHelpers(this.$notify);
|
||||
|
||||
attended = true;
|
||||
gaveTime = true;
|
||||
hoursStr = "1";
|
||||
todayOrPreviousStartDate = "";
|
||||
|
||||
/**
|
||||
* Lifecycle hook to calculate the current or previous Saturday meeting date
|
||||
* Uses America/Denver timezone for Bountiful location
|
||||
*/
|
||||
async mounted() {
|
||||
logger.debug("[QuickActionBvcBeginView] Mounted - calculating meeting date");
|
||||
|
||||
// use the time zone for Bountiful
|
||||
let currentOrPreviousSat = DateTime.now().setZone("America/Denver");
|
||||
if (currentOrPreviousSat.weekday < 6) {
|
||||
@@ -114,21 +142,52 @@ export default class QuickActionBvcBeginView extends Vue {
|
||||
eventStartDateObj.toISO({
|
||||
suppressMilliseconds: true,
|
||||
}) || "";
|
||||
|
||||
logger.debug(
|
||||
"[QuickActionBvcBeginView] Meeting date calculated:",
|
||||
this.todayOrPreviousStartDate
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Records attendance and/or time contribution to BVC meeting
|
||||
* Creates claims for both attendance and time if applicable
|
||||
*/
|
||||
async record() {
|
||||
const settings = await databaseUtil.retrieveSettingsForActiveAccount();
|
||||
logger.debug("[QuickActionBvcBeginView] Recording BVC meeting participation");
|
||||
|
||||
// Get account settings using PlatformServiceMixin
|
||||
const settings = await this.$accountSettings();
|
||||
const activeDid = settings.activeDid || "";
|
||||
const apiServer = settings.apiServer || "";
|
||||
|
||||
if (!activeDid || !apiServer) {
|
||||
logger.error(
|
||||
"[QuickActionBvcBeginView] Missing required settings:",
|
||||
{ activeDid: !!activeDid, apiServer: !!apiServer }
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
const hoursNum = libsUtil.numberOrZero(this.hoursStr);
|
||||
|
||||
logger.debug(
|
||||
"[QuickActionBvcBeginView] Processing submission:",
|
||||
{ attended: this.attended, gaveTime: this.gaveTime, hours: hoursNum }
|
||||
);
|
||||
|
||||
this.$notify({ group: "alert", type: "toast", title: "Sent..." }, 1000);
|
||||
// Use notification helper with proper timeout
|
||||
this.notify.toast(NOTIFY_BVC_PROCESSING.title, NOTIFY_BVC_PROCESSING.message, TIMEOUTS.BRIEF);
|
||||
|
||||
// first send the claim for time given
|
||||
let timeSuccess = false;
|
||||
if (this.gaveTime && hoursNum > 0) {
|
||||
logger.debug(
|
||||
"[QuickActionBvcBeginView] Submitting time gift:",
|
||||
{ hours: hoursNum }
|
||||
);
|
||||
|
||||
const timeResult = await createAndSubmitGive(
|
||||
axios,
|
||||
apiServer,
|
||||
@@ -140,18 +199,15 @@ export default class QuickActionBvcBeginView extends Vue {
|
||||
"HUR",
|
||||
BVC_MEETUPS_PROJECT_CLAIM_ID,
|
||||
);
|
||||
|
||||
if (timeResult.success) {
|
||||
timeSuccess = true;
|
||||
logger.debug("[QuickActionBvcBeginView] Time gift submission successful");
|
||||
} else {
|
||||
logger.error("Error sending time:", timeResult);
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error",
|
||||
text: timeResult?.error || "There was an error sending the time.",
|
||||
},
|
||||
5000,
|
||||
logger.error("[QuickActionBvcBeginView] Error sending time:", timeResult);
|
||||
this.notify.error(
|
||||
timeResult?.error || NOTIFY_BVC_TIME_ERROR.message,
|
||||
TIMEOUTS.LONG
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -159,62 +215,76 @@ export default class QuickActionBvcBeginView extends Vue {
|
||||
// now send the claim for attendance
|
||||
let attendedSuccess = false;
|
||||
if (this.attended) {
|
||||
logger.debug("[QuickActionBvcBeginView] Submitting attendance claim");
|
||||
|
||||
const attendResult = await createAndSubmitClaim(
|
||||
bvcMeetingJoinClaim(activeDid, this.todayOrPreviousStartDate),
|
||||
activeDid,
|
||||
apiServer,
|
||||
axios,
|
||||
);
|
||||
|
||||
if (attendResult.success) {
|
||||
attendedSuccess = true;
|
||||
logger.debug("[QuickActionBvcBeginView] Attendance claim submission successful");
|
||||
} else {
|
||||
logger.error("Error sending attendance:", attendResult);
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error",
|
||||
text:
|
||||
attendResult?.error ||
|
||||
"There was an error sending the attendance.",
|
||||
},
|
||||
5000,
|
||||
logger.error("[QuickActionBvcBeginView] Error sending attendance:", attendResult);
|
||||
this.notify.error(
|
||||
attendResult?.error || NOTIFY_BVC_ATTENDANCE_ERROR.message,
|
||||
TIMEOUTS.LONG
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (timeSuccess || attendedSuccess) {
|
||||
const actions =
|
||||
timeSuccess && attendedSuccess
|
||||
? "Your attendance and time have been recorded."
|
||||
: timeSuccess
|
||||
? "Your time has been recorded."
|
||||
: "Your attendance has been recorded.";
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "success",
|
||||
title: "Success",
|
||||
text: actions,
|
||||
},
|
||||
3000,
|
||||
const successMessage = createBvcSuccessMessage(timeSuccess, attendedSuccess);
|
||||
|
||||
logger.debug(
|
||||
"[QuickActionBvcBeginView] Submission completed successfully:",
|
||||
{ timeSuccess, attendedSuccess }
|
||||
);
|
||||
|
||||
this.notify.success(successMessage, TIMEOUTS.STANDARD);
|
||||
this.$router.push({ path: "/quick-action-bvc" });
|
||||
}
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
} catch (error: any) {
|
||||
logger.error("Error sending claims.", error);
|
||||
this.$notify(
|
||||
{
|
||||
group: "alert",
|
||||
type: "danger",
|
||||
title: "Error",
|
||||
text: error.userMessage || "There was an error sending the claims.",
|
||||
},
|
||||
5000,
|
||||
logger.error("[QuickActionBvcBeginView] Error sending claims:", error);
|
||||
this.notify.error(
|
||||
error.userMessage || NOTIFY_BVC_SUBMISSION_ERROR.message,
|
||||
TIMEOUTS.LONG
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Navigates back to the previous page
|
||||
*/
|
||||
goBack() {
|
||||
this.$router.back();
|
||||
}
|
||||
|
||||
/**
|
||||
* Computed property for active button styling
|
||||
*/
|
||||
get activeButtonClass() {
|
||||
return "block text-center text-md font-bold bg-gradient-to-b from-blue-400 to-blue-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2 py-3 rounded-md w-56";
|
||||
}
|
||||
|
||||
/**
|
||||
* Computed property for disabled button styling
|
||||
*/
|
||||
get disabledButtonClass() {
|
||||
return "block text-center text-md font-bold bg-gradient-to-b from-slate-400 to-slate-700 shadow-[inset_0_-1px_0_0_rgba(0,0,0,0.5)] text-white px-2 py-3 rounded-md w-56";
|
||||
}
|
||||
|
||||
/**
|
||||
* Computed property to determine if the submit button should be enabled
|
||||
* Returns true if user has attended or provided valid time contribution
|
||||
*/
|
||||
get canSubmit() {
|
||||
return this.attended || (this.gaveTime && this.hoursStr && this.hoursStr !== '0');
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
Reference in New Issue
Block a user