From 5a453db3a4fd120c1acc845d1027395492b57e5c Mon Sep 17 00:00:00 2001 From: chark1es Date: Sat, 1 Mar 2025 04:56:51 -0800 Subject: [PATCH] more toast fixes --- src/components/dashboard/EventsSection.astro | 3 - .../dashboard/EventsSection/EventCheckIn.tsx | 2 +- .../dashboard/Officer_EventRequestForm.astro | 4 - .../ASFundingSection.tsx | 1 - .../EventRequestForm.tsx | 189 +++++++++--------- .../UserEventRequests.tsx | 7 - .../EventRequestManagementTable.tsx | 41 +--- .../reimbursement/ReimbursementForm.tsx | 8 - .../reimbursement/ReimbursementList.tsx | 11 - .../dashboard/universal/ToastProvider.tsx | 3 +- 10 files changed, 102 insertions(+), 167 deletions(-) diff --git a/src/components/dashboard/EventsSection.astro b/src/components/dashboard/EventsSection.astro index 41dd3d7..83e8610 100644 --- a/src/components/dashboard/EventsSection.astro +++ b/src/components/dashboard/EventsSection.astro @@ -2,9 +2,6 @@ import FilePreview from "./universal/FilePreview"; import EventCheckIn from "./EventsSection/EventCheckIn"; import EventLoad from "./EventsSection/EventLoad"; -import { Icon } from "astro-icon/components"; -import { Get } from "../../scripts/pocketbase/Get"; -import { toast } from "react-hot-toast"; ---
diff --git a/src/components/dashboard/EventsSection/EventCheckIn.tsx b/src/components/dashboard/EventsSection/EventCheckIn.tsx index a3518a0..c6f64d7 100644 --- a/src/components/dashboard/EventsSection/EventCheckIn.tsx +++ b/src/components/dashboard/EventsSection/EventCheckIn.tsx @@ -1,4 +1,4 @@ -import { useEffect, useState } from "react"; +import { useState } from "react"; import { Get } from "../../../scripts/pocketbase/Get"; import { Authentication } from "../../../scripts/pocketbase/Authentication"; import { Update } from "../../../scripts/pocketbase/Update"; diff --git a/src/components/dashboard/Officer_EventRequestForm.astro b/src/components/dashboard/Officer_EventRequestForm.astro index a532ac6..f5a115b 100644 --- a/src/components/dashboard/Officer_EventRequestForm.astro +++ b/src/components/dashboard/Officer_EventRequestForm.astro @@ -4,10 +4,6 @@ import { Get } from "../../scripts/pocketbase/Get"; import EventRequestForm from "./Officer_EventRequestForm/EventRequestForm"; import UserEventRequests from "./Officer_EventRequestForm/UserEventRequests"; import { Collections } from "../../schemas/pocketbase/schema"; -import { Icon } from "astro-icon/components"; -import { Create } from "../../scripts/pocketbase/Create"; -import { Update } from "../../scripts/pocketbase/Update"; -import { toast } from "react-hot-toast"; // Import the EventRequest type from UserEventRequests to ensure consistency import type { EventRequest as UserEventRequest } from "./Officer_EventRequestForm/UserEventRequests"; diff --git a/src/components/dashboard/Officer_EventRequestForm/ASFundingSection.tsx b/src/components/dashboard/Officer_EventRequestForm/ASFundingSection.tsx index 9d20e69..bb063de 100644 --- a/src/components/dashboard/Officer_EventRequestForm/ASFundingSection.tsx +++ b/src/components/dashboard/Officer_EventRequestForm/ASFundingSection.tsx @@ -4,7 +4,6 @@ import toast from 'react-hot-toast'; import type { EventRequestFormData } from './EventRequestForm'; import InvoiceBuilder from './InvoiceBuilder'; import type { InvoiceData } from './InvoiceBuilder'; -import type { EventRequest } from '../../../schemas/pocketbase'; // Animation variants const itemVariants = { diff --git a/src/components/dashboard/Officer_EventRequestForm/EventRequestForm.tsx b/src/components/dashboard/Officer_EventRequestForm/EventRequestForm.tsx index 42e0659..a1cece1 100644 --- a/src/components/dashboard/Officer_EventRequestForm/EventRequestForm.tsx +++ b/src/components/dashboard/Officer_EventRequestForm/EventRequestForm.tsx @@ -4,10 +4,8 @@ import toast from 'react-hot-toast'; import { Authentication } from '../../../scripts/pocketbase/Authentication'; import { Update } from '../../../scripts/pocketbase/Update'; import { FileManager } from '../../../scripts/pocketbase/FileManager'; -import { Get } from '../../../scripts/pocketbase/Get'; import { DataSyncService } from '../../../scripts/database/DataSyncService'; import { Collections } from '../../../schemas/pocketbase/schema'; -import type { EventRequest } from '../../../schemas/pocketbase'; import { EventRequestStatus } from '../../../schemas/pocketbase'; // Form sections @@ -16,7 +14,6 @@ import EventDetailsSection from './EventDetailsSection'; import TAPFormSection from './TAPFormSection'; import ASFundingSection from './ASFundingSection'; import EventRequestFormPreview from './EventRequestFormPreview'; -import InvoiceBuilder from './InvoiceBuilder'; import type { InvoiceData, InvoiceItem } from './InvoiceBuilder'; // Animation variants @@ -173,6 +170,50 @@ const EventRequestForm: React.FC = () => { })); }; + // Add this function before the handleSubmit function + const resetForm = () => { + setFormData({ + name: '', + location: '', + start_date_time: '', + end_date_time: '', + event_description: '', + flyers_needed: false, + flyer_type: [], + other_flyer_type: '', + flyer_advertising_start_date: '', + flyer_additional_requests: '', + photography_needed: false, + required_logos: [], + other_logos: [], + advertising_format: '', + will_or_have_room_booking: false, + expected_attendance: 0, + room_booking: null, + as_funding_required: false, + food_drinks_being_served: false, + itemized_invoice: '', + invoice: null, + invoice_files: [], // Reset multiple invoice files + needs_graphics: null, + needs_as_funding: false, + invoiceData: { + items: [], + subtotal: 0, + taxRate: 7.75, // Default tax rate for San Diego + taxAmount: 0, + tipPercentage: 15, // Default tip percentage + tipAmount: 0, + total: 0, + vendor: '' + }, + formReviewed: false // Reset review status + }); + + // Reset to first step + setCurrentStep(1); + }; + // Handle form submission const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); @@ -186,9 +227,6 @@ const EventRequestForm: React.FC = () => { setIsSubmitting(true); setError(null); - // Show initial submitting toast - const submittingToast = toast.loading('Preparing to submit your event request...'); - try { const auth = Authentication.getInstance(); const update = Update.getInstance(); @@ -196,14 +234,14 @@ const EventRequestForm: React.FC = () => { const dataSync = DataSyncService.getInstance(); if (!auth.isAuthenticated()) { - toast.error('You must be logged in to submit an event request', { id: submittingToast }); + toast.error('You must be logged in to submit an event request'); throw new Error('You must be logged in to submit an event request'); } // Create the event request record const userId = auth.getUserId(); if (!userId) { - toast.error('User ID not found', { id: submittingToast }); + toast.error('User ID not found'); throw new Error('User ID not found'); } @@ -245,102 +283,53 @@ const EventRequestForm: React.FC = () => { status: EventRequestStatus.SUBMITTED, }; - toast.loading('Creating event request record...', { id: submittingToast }); + // Create the record using the Update service + // This will send the data to the server + const record = await update.create('event_request', submissionData); - try { - // Create the record using the Update service - // This will send the data to the server - const record = await update.create('event_request', submissionData); + // Force sync the event requests collection to update IndexedDB + await dataSync.syncCollection(Collections.EVENT_REQUESTS); - // Force sync the event requests collection to update IndexedDB - await dataSync.syncCollection(Collections.EVENT_REQUESTS); - - // Upload files if they exist - if (formData.other_logos.length > 0) { - toast.loading('Uploading logo files...', { id: submittingToast }); - await fileManager.uploadFiles('event_request', record.id, 'other_logos', formData.other_logos); - } - - if (formData.room_booking) { - toast.loading('Uploading room booking confirmation...', { id: submittingToast }); - await fileManager.uploadFile('event_request', record.id, 'room_booking', formData.room_booking); - } - - // Upload multiple invoice files - if (formData.invoice_files && formData.invoice_files.length > 0) { - toast.loading('Uploading invoice files...', { id: submittingToast }); - - // Use appendFiles instead of uploadFiles to ensure we're adding files, not replacing them - await fileManager.appendFiles('event_request', record.id, 'invoice_files', formData.invoice_files); - - // For backward compatibility, also upload the first file as the main invoice - if (formData.invoice || formData.invoice_files[0]) { - const mainInvoice = formData.invoice || formData.invoice_files[0]; - await fileManager.uploadFile('event_request', record.id, 'invoice', mainInvoice); - } - } else if (formData.invoice) { - // If there are no invoice_files but there is a main invoice, upload it - toast.loading('Uploading invoice file...', { id: submittingToast }); - await fileManager.uploadFile('event_request', record.id, 'invoice', formData.invoice); - } - - // Clear form data from localStorage - localStorage.removeItem('eventRequestFormData'); - - // Show success message - toast.success('Event request submitted successfully!', { id: submittingToast }); - - // Reset form - setFormData({ - name: '', - location: '', - start_date_time: '', - end_date_time: '', - event_description: '', - flyers_needed: false, - flyer_type: [], - other_flyer_type: '', - flyer_advertising_start_date: '', - flyer_additional_requests: '', - photography_needed: false, - required_logos: [], - other_logos: [], - advertising_format: '', - will_or_have_room_booking: false, - expected_attendance: 0, - room_booking: null, - as_funding_required: false, - food_drinks_being_served: false, - itemized_invoice: '', - invoice: null, - invoice_files: [], // Reset multiple invoice files - needs_graphics: null, - needs_as_funding: false, - invoiceData: { - items: [], - subtotal: 0, - taxRate: 7.75, // Default tax rate for San Diego - taxAmount: 0, - tipPercentage: 15, // Default tip percentage - tipAmount: 0, - total: 0, - vendor: '' - }, - formReviewed: false // Reset review status - }); - - // Reset to first step - setCurrentStep(1); - } catch (uploadErr: any) { - console.error('Error during file upload:', uploadErr); - toast.error(`Error during file upload: ${uploadErr.message || 'Unknown error'}`, { id: submittingToast }); - throw uploadErr; + // Upload files if they exist + if (formData.other_logos.length > 0) { + await fileManager.uploadFiles('event_request', record.id, 'other_logos', formData.other_logos); } - } catch (err: any) { - console.error('Error submitting event request:', err); - setError(err.message || 'An error occurred while submitting your request'); - toast.error(err.message || 'An error occurred while submitting your request', { id: submittingToast }); + if (formData.room_booking) { + await fileManager.uploadFile('event_request', record.id, 'room_booking', formData.room_booking); + } + + // Upload multiple invoice files + if (formData.invoice_files && formData.invoice_files.length > 0) { + await fileManager.appendFiles('event_request', record.id, 'invoice_files', formData.invoice_files); + + // For backward compatibility, also upload the first file as the main invoice + if (formData.invoice || formData.invoice_files[0]) { + const mainInvoice = formData.invoice || formData.invoice_files[0]; + await fileManager.uploadFile('event_request', record.id, 'invoice', mainInvoice); + } + } else if (formData.invoice) { + await fileManager.uploadFile('event_request', record.id, 'invoice', formData.invoice); + } + + // Clear form data from localStorage + localStorage.removeItem('eventRequestFormData'); + + // Keep success toast for form submission since it's a user action + toast.success('Event request submitted successfully!'); + + // Reset form + resetForm(); + + // Switch to the submissions tab + const submissionsTab = document.getElementById('submissions-tab'); + if (submissionsTab) { + submissionsTab.click(); + } + } catch (error) { + console.error('Error submitting event request:', error); + toast.error('Failed to submit event request. Please try again.'); + setError('Failed to submit event request. Please try again.'); } finally { setIsSubmitting(false); } diff --git a/src/components/dashboard/Officer_EventRequestForm/UserEventRequests.tsx b/src/components/dashboard/Officer_EventRequestForm/UserEventRequests.tsx index 4469543..fb7d4bf 100644 --- a/src/components/dashboard/Officer_EventRequestForm/UserEventRequests.tsx +++ b/src/components/dashboard/Officer_EventRequestForm/UserEventRequests.tsx @@ -1,10 +1,8 @@ import React, { useState, useEffect } from 'react'; import { motion, AnimatePresence } from 'framer-motion'; -import { Get } from '../../../scripts/pocketbase/Get'; import { Authentication } from '../../../scripts/pocketbase/Authentication'; import { DataSyncService } from '../../../scripts/database/DataSyncService'; import { Collections } from '../../../schemas/pocketbase/schema'; -import toast from 'react-hot-toast'; import type { EventRequest as SchemaEventRequest } from '../../../schemas/pocketbase'; // Extended EventRequest interface with additional properties needed for this component @@ -27,19 +25,16 @@ const UserEventRequests: React.FC = ({ eventRequests: in // Refresh event requests const refreshEventRequests = async () => { setIsRefreshing(true); - const refreshToast = toast.loading('Refreshing submissions...'); try { const auth = Authentication.getInstance(); if (!auth.isAuthenticated()) { - toast.error('You must be logged in to refresh submissions', { id: refreshToast }); return; } const userId = auth.getUserId(); if (!userId) { - toast.error('User ID not found', { id: refreshToast }); return; } @@ -52,10 +47,8 @@ const UserEventRequests: React.FC = ({ eventRequests: in ); setEventRequests(updatedRequests); - toast.success('Submissions refreshed successfully', { id: refreshToast }); } catch (err) { console.error('Failed to refresh event requests:', err); - toast.error('Failed to refresh submissions. Please try again.', { id: refreshToast }); } finally { setIsRefreshing(false); } diff --git a/src/components/dashboard/Officer_EventRequestManagement/EventRequestManagementTable.tsx b/src/components/dashboard/Officer_EventRequestManagement/EventRequestManagementTable.tsx index 82e1b0b..889f6ae 100644 --- a/src/components/dashboard/Officer_EventRequestManagement/EventRequestManagementTable.tsx +++ b/src/components/dashboard/Officer_EventRequestManagement/EventRequestManagementTable.tsx @@ -48,8 +48,6 @@ const EventRequestManagementTable = ({ eventRequests: initialEventRequests }: Ev // Refresh event requests const refreshEventRequests = async () => { setIsRefreshing(true); - const refreshToast = toast.loading('Refreshing event requests...'); - try { const auth = Authentication.getInstance(); @@ -71,22 +69,9 @@ const EventRequestManagementTable = ({ eventRequests: initialEventRequests }: Ev setEventRequests(updatedRequests); applyFilters(updatedRequests); - toast.success('Event requests refreshed successfully', { id: refreshToast }); - } catch (err) { - console.error('Failed to refresh event requests:', err); - - // Check if it's an authentication error - if (err instanceof Error && - (err.message.includes('authentication') || - err.message.includes('auth') || - err.message.includes('logged in'))) { - toast.error('Authentication error. Please log in again.', { id: refreshToast }); - setTimeout(() => { - window.location.href = "/login"; - }, 2000); - } else { - toast.error('Failed to refresh event requests. Please try again.', { id: refreshToast }); - } + } catch (error) { + console.error('Error refreshing event requests:', error); + toast.error('Failed to refresh event requests'); } finally { setIsRefreshing(false); } @@ -146,8 +131,6 @@ const EventRequestManagementTable = ({ eventRequests: initialEventRequests }: Ev // Update event request status const updateEventRequestStatus = async (id: string, status: "submitted" | "pending" | "completed" | "declined") => { - const updateToast = toast.loading(`Updating status to ${status}...`); - try { const update = Update.getInstance(); const result = await update.updateField('event_request', id, 'status', status); @@ -173,17 +156,15 @@ const EventRequestManagementTable = ({ eventRequests: initialEventRequests }: Ev // Force sync to update IndexedDB await dataSync.syncCollection(Collections.EVENT_REQUESTS); - toast.success(`Status updated to ${status}`, { id: updateToast }); - } catch (err) { - console.error('Failed to update event request status:', err); - toast.error('Failed to update status. Please try again.', { id: updateToast }); + // Remove success toast for updating status + } catch (error) { + console.error('Error updating status:', error); + toast.error('Failed to update status'); } }; // Add feedback to event request const addFeedback = async (id: string, feedback: string) => { - const feedbackToast = toast.loading('Saving feedback...'); - try { const update = Update.getInstance(); const result = await update.updateField('event_request', id, 'feedback', feedback); @@ -204,11 +185,11 @@ const EventRequestManagementTable = ({ eventRequests: initialEventRequests }: Ev // Force sync to update IndexedDB await dataSync.syncCollection(Collections.EVENT_REQUESTS); - toast.success('Feedback saved successfully', { id: feedbackToast }); + // Remove success toast for saving feedback return true; - } catch (err) { - console.error('Failed to save feedback:', err); - toast.error('Failed to save feedback. Please try again.', { id: feedbackToast }); + } catch (error) { + console.error('Error saving feedback:', error); + toast.error('Failed to save feedback'); return false; } }; diff --git a/src/components/dashboard/reimbursement/ReimbursementForm.tsx b/src/components/dashboard/reimbursement/ReimbursementForm.tsx index 7966949..dbb9710 100644 --- a/src/components/dashboard/reimbursement/ReimbursementForm.tsx +++ b/src/components/dashboard/reimbursement/ReimbursementForm.tsx @@ -180,8 +180,6 @@ export default function ReimbursementForm() { throw new Error('User not authenticated'); } - toast.loading('Adding receipt...'); - // Create receipt record const formData = new FormData(); formData.append('field', receiptData.field); @@ -211,11 +209,9 @@ export default function ReimbursementForm() { })); setShowReceiptForm(false); - toast.dismiss(); toast.success('Receipt added successfully'); } catch (error) { console.error('Error creating receipt:', error); - toast.dismiss(); toast.error('Failed to add receipt'); setError('Failed to add receipt. Please try again.'); } @@ -252,8 +248,6 @@ export default function ReimbursementForm() { throw new Error('User not authenticated'); } - const loadingToast = toast.loading('Submitting reimbursement request...'); - // Create reimbursement record const formData = new FormData(); formData.append('title', request.title); @@ -286,8 +280,6 @@ export default function ReimbursementForm() { setReceipts([]); setError(''); - // Dismiss loading toast and show success - toast.dismiss(loadingToast); toast.success('🎉 Reimbursement request submitted successfully! Check "My Requests" to view it.', { duration: 5000, position: 'top-center', diff --git a/src/components/dashboard/reimbursement/ReimbursementList.tsx b/src/components/dashboard/reimbursement/ReimbursementList.tsx index 542dcde..a844122 100644 --- a/src/components/dashboard/reimbursement/ReimbursementList.tsx +++ b/src/components/dashboard/reimbursement/ReimbursementList.tsx @@ -4,7 +4,6 @@ import { Get } from '../../../scripts/pocketbase/Get'; import { Authentication } from '../../../scripts/pocketbase/Authentication'; import { FileManager } from '../../../scripts/pocketbase/FileManager'; import FilePreview from '../universal/FilePreview'; -import { toast } from 'react-hot-toast'; import { motion, AnimatePresence } from 'framer-motion'; import type { ItemizedExpense, Reimbursement, Receipt } from '../../../schemas/pocketbase'; import { DataSyncService } from '../../../scripts/database/DataSyncService'; @@ -133,8 +132,6 @@ export default function ReimbursementList() { throw new Error('User not authenticated'); } - const loadingToast = toast.loading('Loading reimbursements...'); - // Use DataSyncService to get data from IndexedDB with forced sync const dataSync = DataSyncService.getInstance(); @@ -181,7 +178,6 @@ export default function ReimbursementList() { }); setRequests(processedRecords); - toast.success('Reimbursements loaded successfully', { id: loadingToast }); // Fetch receipt details for each reimbursement for (const record of processedRecords) { @@ -237,7 +233,6 @@ export default function ReimbursementList() { } catch (err) { console.error('Error fetching reimbursements:', err); setError('Failed to load reimbursements. Please try again.'); - toast.error('Failed to load reimbursements'); } finally { setLoading(false); } @@ -245,7 +240,6 @@ export default function ReimbursementList() { const handlePreviewFile = async (request: ReimbursementRequest, receiptId: string) => { try { - const loadingToast = toast.loading('Loading receipt...'); const pb = auth.getPocketBase(); // Check if we already have the receipt details in our map @@ -258,8 +252,6 @@ export default function ReimbursementList() { setPreviewUrl(url); setPreviewFilename(receiptDetailsMap[receiptId].field); setShowPreview(true); - toast.dismiss(loadingToast); - toast.success('Receipt loaded successfully'); return; } @@ -302,14 +294,11 @@ export default function ReimbursementList() { setPreviewUrl(url); setPreviewFilename(receiptRecord.field); setShowPreview(true); - toast.dismiss(loadingToast); - toast.success('Receipt loaded successfully'); } else { throw new Error('Receipt not found'); } } catch (error) { console.error('Error loading receipt:', error); - toast.error('Failed to load receipt'); } }; diff --git a/src/components/dashboard/universal/ToastProvider.tsx b/src/components/dashboard/universal/ToastProvider.tsx index 98251ea..d53b441 100644 --- a/src/components/dashboard/universal/ToastProvider.tsx +++ b/src/components/dashboard/universal/ToastProvider.tsx @@ -1,11 +1,10 @@ -import React from 'react'; import { Toaster } from 'react-hot-toast'; // Centralized toast provider to ensure consistent rendering export default function ToastProvider() { return (