diff --git a/src/views/OnboardMeetingListView.vue b/src/views/OnboardMeetingListView.vue index 33f8a3a7..e1f877f1 100644 --- a/src/views/OnboardMeetingListView.vue +++ b/src/views/OnboardMeetingListView.vue @@ -115,6 +115,9 @@ import { serverMessageForUser, } from "../libs/endorserServer"; import { PlatformServiceMixin } from "@/utils/PlatformServiceMixin"; +import { logger } from "@/utils/logger"; +import { createNotifyHelpers, TIMEOUTS } from "@/utils/notify"; +import { NotificationIface } from "@/constants/app"; interface Meeting { name: string; @@ -129,19 +132,11 @@ interface Meeting { mixins: [PlatformServiceMixin], }) export default class OnboardMeetingListView extends Vue { - $notify!: ( - notification: { - group: string; - type: string; - title: string; - text: string; - onYes?: () => void; - yesText?: string; - }, - timeout?: number, - ) => void; + $notify!: (notification: NotificationIface, timeout?: number) => void; $router!: Router; + notify!: ReturnType; + activeDid = ""; apiServer = ""; attendingMeeting: Meeting | null = null; @@ -153,30 +148,66 @@ export default class OnboardMeetingListView extends Vue { selectedMeeting: Meeting | null = null; showPasswordDialog = false; + /** + * Vue lifecycle hook - component initialization + * + * Initializes the component by loading user settings and fetching available + * onboarding meetings. This method is called when the component is created + * and sets up all necessary data for the meeting list interface. + * + * Workflow: + * 1. Initialize notification system using createNotifyHelpers + * 2. Load user account settings (DID, API server, registration status) + * 3. Fetch available onboarding meetings from the server + * + * Dependencies: + * - PlatformServiceMixin for settings access ($accountSettings) + * - Server API for meeting data (fetchMeetings) + * + * Error Handling: + * - Server errors during meeting fetch are handled in fetchMeetings() + * + * @author Matthew Raymer + */ async created() { + this.notify = createNotifyHelpers(this.$notify); + + // Load user account settings const settings = await this.$accountSettings(); - if (settings?.activeDid) { - try { - // Verify database settings are accessible - await this.$query("SELECT * FROM settings WHERE accountDid = ?", [ - settings.activeDid, - ]); - } catch (error) { - logger.error("Error checking database settings:", error); - } - } - this.activeDid = settings?.activeDid || ""; this.apiServer = settings?.apiServer || ""; this.firstName = settings?.firstName || ""; this.isRegistered = !!settings?.isRegistered; - if (this.isRegistered) { - await this.fetchMeetings(); - } + await this.fetchMeetings(); } + /** + * Fetches available onboarding meetings from the server + * + * This method retrieves the list of onboarding meetings that the user can join. + * It first checks if the user is already attending a meeting, and if so, + * displays that meeting instead of the full list. + * + * Workflow: + * 1. Check if user is already attending a meeting (groupOnboardMember endpoint) + * 2. If attending: Fetch meeting details and display single meeting view + * 3. If not attending: Fetch all available meetings (groupsOnboarding endpoint) + * 4. Handle loading states and error conditions + * + * API Endpoints Used: + * - GET /api/partner/groupOnboardMember - Check current attendance + * - GET /api/partner/groupOnboard/{id} - Get meeting details + * - GET /api/partner/groupsOnboarding - Get all available meetings + * + * State Management: + * - Sets isLoading flag during API calls + * - Updates attendingMeeting or meetings array + * - Handles error states with user notifications + * + * @author Matthew Raymer + */ async fetchMeetings() { this.isLoading = true; try { @@ -226,20 +257,36 @@ export default class OnboardMeetingListView extends Vue { "Error fetching meetings: " + errorStringForLog(error), true, ); - this.$notify( - { - group: "alert", - type: "danger", - title: "Error", - text: serverMessageForUser(error) || "Failed to fetch meetings.", - }, - 5000, + this.notify.error( + serverMessageForUser(error) || "Failed to fetch meetings.", + TIMEOUTS.LONG, ); } finally { this.isLoading = false; } } + /** + * Opens the password dialog for joining a meeting + * + * This method initiates the process of joining an onboarding meeting by + * opening a modal dialog that prompts the user for the meeting password. + * The dialog is focused and ready for input when displayed. + * + * Workflow: + * 1. Clear any previous password input + * 2. Store the selected meeting for later use + * 3. Show the password dialog modal + * 4. Focus the password input field for immediate typing + * + * UI State Changes: + * - Sets showPasswordDialog to true (shows modal) + * - Clears password field for fresh input + * - Stores selectedMeeting for password submission + * + * @param meeting - The meeting object the user wants to join + * @author Matthew Raymer + */ promptPassword(meeting: Meeting) { this.password = ""; this.selectedMeeting = meeting; @@ -252,12 +299,61 @@ export default class OnboardMeetingListView extends Vue { }); } + /** + * Cancels the password dialog and resets state + * + * This method handles the cancellation of the meeting password dialog. + * It cleans up the dialog state and resets all related variables to + * their initial state, ensuring a clean slate for future dialog interactions. + * + * State Cleanup: + * - Clears password input field + * - Removes selected meeting reference + * - Hides password dialog modal + * + * This ensures that if the user reopens the dialog, they start with + * a fresh state without any leftover data from previous attempts. + * + * @author Matthew Raymer + */ cancelPasswordDialog() { this.password = ""; this.selectedMeeting = null; this.showPasswordDialog = false; } + /** + * Submits the password and joins the selected meeting + * + * This method handles the complete workflow of joining an onboarding meeting. + * It encrypts the user's member data with the provided password and sends + * it to the server to register the user as a meeting participant. + * + * Workflow: + * 1. Validate that a meeting is selected (safety check) + * 2. Create member data object with user information + * 3. Encrypt member data using the meeting password + * 4. Send encrypted data to server via groupOnboardMember endpoint + * 5. On success: Navigate to meeting members view with credentials + * 6. On failure: Show error notification to user + * + * Data Encryption: + * - Member data includes: name, DID, registration status + * - Data is encrypted using the meeting password for security + * - Encrypted data is sent to server for verification + * + * Navigation: + * - On successful join: Redirects to onboard-meeting-members view + * - Passes groupId, password, and memberId as route parameters + * - Allows user to see other meeting participants + * + * Error Handling: + * - Invalid passwords result in server rejection + * - Network errors are caught and displayed to user + * - All errors are logged for debugging purposes + * + * @author Matthew Raymer + */ async submitPassword() { if (!this.selectedMeeting) { // this should never happen @@ -316,69 +412,97 @@ export default class OnboardMeetingListView extends Vue { "Error joining meeting: " + errorStringForLog(error), true, ); - this.$notify( - { - group: "alert", - type: "danger", - title: "Error", - text: - serverMessageForUser(error) || "You failed to join the meeting.", - }, - 5000, + this.notify.error( + serverMessageForUser(error) || "You failed to join the meeting.", + TIMEOUTS.LONG, ); } } + /** + * Prompts user to confirm leaving the current meeting + * + * This method initiates the process of leaving an onboarding meeting. + * It shows a confirmation dialog to prevent accidental departures, + * then handles the server-side removal and UI updates. + * + * Workflow: + * 1. Display confirmation dialog asking user to confirm departure + * 2. On confirmation: Send DELETE request to groupOnboardMember endpoint + * 3. On success: Clear attending meeting state and refresh meeting list + * 4. Show success notification to user + * 5. On failure: Show error notification with details + * + * Server Interaction: + * - DELETE /api/partner/groupOnboardMember - Removes user from meeting + * - Requires authentication headers for user verification + * - Server handles the actual removal from meeting database + * + * State Management: + * - Clears attendingMeeting when successfully left + * - Refreshes meetings list to show updated availability + * - Updates UI to show meeting list instead of single meeting + * + * User Experience: + * - Confirmation prevents accidental departures + * - Clear feedback on success/failure + * - Seamless transition back to meeting list + * + * @author Matthew Raymer + */ async leaveMeeting() { - this.$notify( - { - group: "modal", - type: "confirm", - title: "Leave Meeting", - text: "Are you sure you want to leave this meeting?", - onYes: async () => { - try { - const headers = await getHeaders(this.activeDid); - await this.axios.delete( - this.apiServer + "/api/partner/groupOnboardMember", - { headers }, - ); - - this.attendingMeeting = null; - await this.fetchMeetings(); - - this.$notify( - { - group: "alert", - type: "success", - title: "Success", - text: "You left the meeting.", - }, - 5000, - ); - } catch (error) { - this.$logAndConsole( - "Error leaving meeting: " + errorStringForLog(error), - true, - ); - this.$notify( - { - group: "alert", - type: "danger", - title: "Error", - text: - serverMessageForUser(error) || - "You failed to leave the meeting.", - }, - 5000, - ); - } - }, + this.notify.confirm( + "Are you sure you want to leave this meeting?", + async () => { + try { + const headers = await getHeaders(this.activeDid); + await this.axios.delete( + this.apiServer + "/api/partner/groupOnboardMember", + { headers }, + ); + + this.attendingMeeting = null; + await this.fetchMeetings(); + + this.notify.success( + "You left the meeting.", + TIMEOUTS.LONG, + ); + } catch (error) { + this.$logAndConsole( + "Error leaving meeting: " + errorStringForLog(error), + true, + ); + this.notify.error( + serverMessageForUser(error) || + "You failed to leave the meeting.", + TIMEOUTS.LONG, + ); + } }, - -1, ); } + /** + * Navigates to the meeting creation page + * + * This method handles the navigation to the meeting setup page where + * registered users can create new onboarding meetings. It's only + * available to users who are registered in the system. + * + * Navigation: + * - Routes to onboard-meeting-setup view + * - Allows user to configure new meeting settings + * - Only accessible to registered users (controlled by template) + * + * User Flow: + * - User clicks "Create Meeting" button + * - System navigates to setup page + * - User can configure meeting name, password, etc. + * - New meeting becomes available to other users + * + * @author Matthew Raymer + */ createMeeting() { this.$router.push({ name: "onboard-meeting-setup" }); }