more toast fixes
This commit is contained in:
parent
ef3e8f38d6
commit
5a453db3a4
10 changed files with 102 additions and 167 deletions
|
@ -2,9 +2,6 @@
|
||||||
import FilePreview from "./universal/FilePreview";
|
import FilePreview from "./universal/FilePreview";
|
||||||
import EventCheckIn from "./EventsSection/EventCheckIn";
|
import EventCheckIn from "./EventsSection/EventCheckIn";
|
||||||
import EventLoad from "./EventsSection/EventLoad";
|
import EventLoad from "./EventsSection/EventLoad";
|
||||||
import { Icon } from "astro-icon/components";
|
|
||||||
import { Get } from "../../scripts/pocketbase/Get";
|
|
||||||
import { toast } from "react-hot-toast";
|
|
||||||
---
|
---
|
||||||
|
|
||||||
<div id="" class="">
|
<div id="" class="">
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
import { useEffect, useState } from "react";
|
import { useState } from "react";
|
||||||
import { Get } from "../../../scripts/pocketbase/Get";
|
import { Get } from "../../../scripts/pocketbase/Get";
|
||||||
import { Authentication } from "../../../scripts/pocketbase/Authentication";
|
import { Authentication } from "../../../scripts/pocketbase/Authentication";
|
||||||
import { Update } from "../../../scripts/pocketbase/Update";
|
import { Update } from "../../../scripts/pocketbase/Update";
|
||||||
|
|
|
@ -4,10 +4,6 @@ import { Get } from "../../scripts/pocketbase/Get";
|
||||||
import EventRequestForm from "./Officer_EventRequestForm/EventRequestForm";
|
import EventRequestForm from "./Officer_EventRequestForm/EventRequestForm";
|
||||||
import UserEventRequests from "./Officer_EventRequestForm/UserEventRequests";
|
import UserEventRequests from "./Officer_EventRequestForm/UserEventRequests";
|
||||||
import { Collections } from "../../schemas/pocketbase/schema";
|
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 the EventRequest type from UserEventRequests to ensure consistency
|
||||||
import type { EventRequest as UserEventRequest } from "./Officer_EventRequestForm/UserEventRequests";
|
import type { EventRequest as UserEventRequest } from "./Officer_EventRequestForm/UserEventRequests";
|
||||||
|
|
|
@ -4,7 +4,6 @@ import toast from 'react-hot-toast';
|
||||||
import type { EventRequestFormData } from './EventRequestForm';
|
import type { EventRequestFormData } from './EventRequestForm';
|
||||||
import InvoiceBuilder from './InvoiceBuilder';
|
import InvoiceBuilder from './InvoiceBuilder';
|
||||||
import type { InvoiceData } from './InvoiceBuilder';
|
import type { InvoiceData } from './InvoiceBuilder';
|
||||||
import type { EventRequest } from '../../../schemas/pocketbase';
|
|
||||||
|
|
||||||
// Animation variants
|
// Animation variants
|
||||||
const itemVariants = {
|
const itemVariants = {
|
||||||
|
|
|
@ -4,10 +4,8 @@ import toast from 'react-hot-toast';
|
||||||
import { Authentication } from '../../../scripts/pocketbase/Authentication';
|
import { Authentication } from '../../../scripts/pocketbase/Authentication';
|
||||||
import { Update } from '../../../scripts/pocketbase/Update';
|
import { Update } from '../../../scripts/pocketbase/Update';
|
||||||
import { FileManager } from '../../../scripts/pocketbase/FileManager';
|
import { FileManager } from '../../../scripts/pocketbase/FileManager';
|
||||||
import { Get } from '../../../scripts/pocketbase/Get';
|
|
||||||
import { DataSyncService } from '../../../scripts/database/DataSyncService';
|
import { DataSyncService } from '../../../scripts/database/DataSyncService';
|
||||||
import { Collections } from '../../../schemas/pocketbase/schema';
|
import { Collections } from '../../../schemas/pocketbase/schema';
|
||||||
import type { EventRequest } from '../../../schemas/pocketbase';
|
|
||||||
import { EventRequestStatus } from '../../../schemas/pocketbase';
|
import { EventRequestStatus } from '../../../schemas/pocketbase';
|
||||||
|
|
||||||
// Form sections
|
// Form sections
|
||||||
|
@ -16,7 +14,6 @@ import EventDetailsSection from './EventDetailsSection';
|
||||||
import TAPFormSection from './TAPFormSection';
|
import TAPFormSection from './TAPFormSection';
|
||||||
import ASFundingSection from './ASFundingSection';
|
import ASFundingSection from './ASFundingSection';
|
||||||
import EventRequestFormPreview from './EventRequestFormPreview';
|
import EventRequestFormPreview from './EventRequestFormPreview';
|
||||||
import InvoiceBuilder from './InvoiceBuilder';
|
|
||||||
import type { InvoiceData, InvoiceItem } from './InvoiceBuilder';
|
import type { InvoiceData, InvoiceItem } from './InvoiceBuilder';
|
||||||
|
|
||||||
// Animation variants
|
// 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
|
// Handle form submission
|
||||||
const handleSubmit = async (e: React.FormEvent) => {
|
const handleSubmit = async (e: React.FormEvent) => {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
@ -186,9 +227,6 @@ const EventRequestForm: React.FC = () => {
|
||||||
setIsSubmitting(true);
|
setIsSubmitting(true);
|
||||||
setError(null);
|
setError(null);
|
||||||
|
|
||||||
// Show initial submitting toast
|
|
||||||
const submittingToast = toast.loading('Preparing to submit your event request...');
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const auth = Authentication.getInstance();
|
const auth = Authentication.getInstance();
|
||||||
const update = Update.getInstance();
|
const update = Update.getInstance();
|
||||||
|
@ -196,14 +234,14 @@ const EventRequestForm: React.FC = () => {
|
||||||
const dataSync = DataSyncService.getInstance();
|
const dataSync = DataSyncService.getInstance();
|
||||||
|
|
||||||
if (!auth.isAuthenticated()) {
|
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');
|
throw new Error('You must be logged in to submit an event request');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create the event request record
|
// Create the event request record
|
||||||
const userId = auth.getUserId();
|
const userId = auth.getUserId();
|
||||||
if (!userId) {
|
if (!userId) {
|
||||||
toast.error('User ID not found', { id: submittingToast });
|
toast.error('User ID not found');
|
||||||
throw new Error('User ID not found');
|
throw new Error('User ID not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -245,102 +283,53 @@ const EventRequestForm: React.FC = () => {
|
||||||
status: EventRequestStatus.SUBMITTED,
|
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 {
|
// Force sync the event requests collection to update IndexedDB
|
||||||
// Create the record using the Update service
|
await dataSync.syncCollection(Collections.EVENT_REQUESTS);
|
||||||
// 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
|
// Upload files if they exist
|
||||||
await dataSync.syncCollection(Collections.EVENT_REQUESTS);
|
if (formData.other_logos.length > 0) {
|
||||||
|
await fileManager.uploadFiles('event_request', record.id, 'other_logos', formData.other_logos);
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} catch (err: any) {
|
if (formData.room_booking) {
|
||||||
console.error('Error submitting event request:', err);
|
await fileManager.uploadFile('event_request', record.id, 'room_booking', formData.room_booking);
|
||||||
setError(err.message || 'An error occurred while submitting your request');
|
}
|
||||||
toast.error(err.message || 'An error occurred while submitting your request', { id: submittingToast });
|
|
||||||
|
// 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 {
|
} finally {
|
||||||
setIsSubmitting(false);
|
setIsSubmitting(false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
import React, { useState, useEffect } from 'react';
|
import React, { useState, useEffect } from 'react';
|
||||||
import { motion, AnimatePresence } from 'framer-motion';
|
import { motion, AnimatePresence } from 'framer-motion';
|
||||||
import { Get } from '../../../scripts/pocketbase/Get';
|
|
||||||
import { Authentication } from '../../../scripts/pocketbase/Authentication';
|
import { Authentication } from '../../../scripts/pocketbase/Authentication';
|
||||||
import { DataSyncService } from '../../../scripts/database/DataSyncService';
|
import { DataSyncService } from '../../../scripts/database/DataSyncService';
|
||||||
import { Collections } from '../../../schemas/pocketbase/schema';
|
import { Collections } from '../../../schemas/pocketbase/schema';
|
||||||
import toast from 'react-hot-toast';
|
|
||||||
import type { EventRequest as SchemaEventRequest } from '../../../schemas/pocketbase';
|
import type { EventRequest as SchemaEventRequest } from '../../../schemas/pocketbase';
|
||||||
|
|
||||||
// Extended EventRequest interface with additional properties needed for this component
|
// Extended EventRequest interface with additional properties needed for this component
|
||||||
|
@ -27,19 +25,16 @@ const UserEventRequests: React.FC<UserEventRequestsProps> = ({ eventRequests: in
|
||||||
// Refresh event requests
|
// Refresh event requests
|
||||||
const refreshEventRequests = async () => {
|
const refreshEventRequests = async () => {
|
||||||
setIsRefreshing(true);
|
setIsRefreshing(true);
|
||||||
const refreshToast = toast.loading('Refreshing submissions...');
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const auth = Authentication.getInstance();
|
const auth = Authentication.getInstance();
|
||||||
|
|
||||||
if (!auth.isAuthenticated()) {
|
if (!auth.isAuthenticated()) {
|
||||||
toast.error('You must be logged in to refresh submissions', { id: refreshToast });
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const userId = auth.getUserId();
|
const userId = auth.getUserId();
|
||||||
if (!userId) {
|
if (!userId) {
|
||||||
toast.error('User ID not found', { id: refreshToast });
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,10 +47,8 @@ const UserEventRequests: React.FC<UserEventRequestsProps> = ({ eventRequests: in
|
||||||
);
|
);
|
||||||
|
|
||||||
setEventRequests(updatedRequests);
|
setEventRequests(updatedRequests);
|
||||||
toast.success('Submissions refreshed successfully', { id: refreshToast });
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Failed to refresh event requests:', err);
|
console.error('Failed to refresh event requests:', err);
|
||||||
toast.error('Failed to refresh submissions. Please try again.', { id: refreshToast });
|
|
||||||
} finally {
|
} finally {
|
||||||
setIsRefreshing(false);
|
setIsRefreshing(false);
|
||||||
}
|
}
|
||||||
|
|
|
@ -48,8 +48,6 @@ const EventRequestManagementTable = ({ eventRequests: initialEventRequests }: Ev
|
||||||
// Refresh event requests
|
// Refresh event requests
|
||||||
const refreshEventRequests = async () => {
|
const refreshEventRequests = async () => {
|
||||||
setIsRefreshing(true);
|
setIsRefreshing(true);
|
||||||
const refreshToast = toast.loading('Refreshing event requests...');
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const auth = Authentication.getInstance();
|
const auth = Authentication.getInstance();
|
||||||
|
|
||||||
|
@ -71,22 +69,9 @@ const EventRequestManagementTable = ({ eventRequests: initialEventRequests }: Ev
|
||||||
|
|
||||||
setEventRequests(updatedRequests);
|
setEventRequests(updatedRequests);
|
||||||
applyFilters(updatedRequests);
|
applyFilters(updatedRequests);
|
||||||
toast.success('Event requests refreshed successfully', { id: refreshToast });
|
} catch (error) {
|
||||||
} catch (err) {
|
console.error('Error refreshing event requests:', error);
|
||||||
console.error('Failed to refresh event requests:', err);
|
toast.error('Failed to refresh event requests');
|
||||||
|
|
||||||
// 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 });
|
|
||||||
}
|
|
||||||
} finally {
|
} finally {
|
||||||
setIsRefreshing(false);
|
setIsRefreshing(false);
|
||||||
}
|
}
|
||||||
|
@ -146,8 +131,6 @@ const EventRequestManagementTable = ({ eventRequests: initialEventRequests }: Ev
|
||||||
|
|
||||||
// Update event request status
|
// Update event request status
|
||||||
const updateEventRequestStatus = async (id: string, status: "submitted" | "pending" | "completed" | "declined") => {
|
const updateEventRequestStatus = async (id: string, status: "submitted" | "pending" | "completed" | "declined") => {
|
||||||
const updateToast = toast.loading(`Updating status to ${status}...`);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const update = Update.getInstance();
|
const update = Update.getInstance();
|
||||||
const result = await update.updateField('event_request', id, 'status', status);
|
const result = await update.updateField('event_request', id, 'status', status);
|
||||||
|
@ -173,17 +156,15 @@ const EventRequestManagementTable = ({ eventRequests: initialEventRequests }: Ev
|
||||||
// Force sync to update IndexedDB
|
// Force sync to update IndexedDB
|
||||||
await dataSync.syncCollection<ExtendedEventRequest>(Collections.EVENT_REQUESTS);
|
await dataSync.syncCollection<ExtendedEventRequest>(Collections.EVENT_REQUESTS);
|
||||||
|
|
||||||
toast.success(`Status updated to ${status}`, { id: updateToast });
|
// Remove success toast for updating status
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
console.error('Failed to update event request status:', err);
|
console.error('Error updating status:', error);
|
||||||
toast.error('Failed to update status. Please try again.', { id: updateToast });
|
toast.error('Failed to update status');
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Add feedback to event request
|
// Add feedback to event request
|
||||||
const addFeedback = async (id: string, feedback: string) => {
|
const addFeedback = async (id: string, feedback: string) => {
|
||||||
const feedbackToast = toast.loading('Saving feedback...');
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const update = Update.getInstance();
|
const update = Update.getInstance();
|
||||||
const result = await update.updateField('event_request', id, 'feedback', feedback);
|
const result = await update.updateField('event_request', id, 'feedback', feedback);
|
||||||
|
@ -204,11 +185,11 @@ const EventRequestManagementTable = ({ eventRequests: initialEventRequests }: Ev
|
||||||
// Force sync to update IndexedDB
|
// Force sync to update IndexedDB
|
||||||
await dataSync.syncCollection<ExtendedEventRequest>(Collections.EVENT_REQUESTS);
|
await dataSync.syncCollection<ExtendedEventRequest>(Collections.EVENT_REQUESTS);
|
||||||
|
|
||||||
toast.success('Feedback saved successfully', { id: feedbackToast });
|
// Remove success toast for saving feedback
|
||||||
return true;
|
return true;
|
||||||
} catch (err) {
|
} catch (error) {
|
||||||
console.error('Failed to save feedback:', err);
|
console.error('Error saving feedback:', error);
|
||||||
toast.error('Failed to save feedback. Please try again.', { id: feedbackToast });
|
toast.error('Failed to save feedback');
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
|
@ -180,8 +180,6 @@ export default function ReimbursementForm() {
|
||||||
throw new Error('User not authenticated');
|
throw new Error('User not authenticated');
|
||||||
}
|
}
|
||||||
|
|
||||||
toast.loading('Adding receipt...');
|
|
||||||
|
|
||||||
// Create receipt record
|
// Create receipt record
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('field', receiptData.field);
|
formData.append('field', receiptData.field);
|
||||||
|
@ -211,11 +209,9 @@ export default function ReimbursementForm() {
|
||||||
}));
|
}));
|
||||||
|
|
||||||
setShowReceiptForm(false);
|
setShowReceiptForm(false);
|
||||||
toast.dismiss();
|
|
||||||
toast.success('Receipt added successfully');
|
toast.success('Receipt added successfully');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error creating receipt:', error);
|
console.error('Error creating receipt:', error);
|
||||||
toast.dismiss();
|
|
||||||
toast.error('Failed to add receipt');
|
toast.error('Failed to add receipt');
|
||||||
setError('Failed to add receipt. Please try again.');
|
setError('Failed to add receipt. Please try again.');
|
||||||
}
|
}
|
||||||
|
@ -252,8 +248,6 @@ export default function ReimbursementForm() {
|
||||||
throw new Error('User not authenticated');
|
throw new Error('User not authenticated');
|
||||||
}
|
}
|
||||||
|
|
||||||
const loadingToast = toast.loading('Submitting reimbursement request...');
|
|
||||||
|
|
||||||
// Create reimbursement record
|
// Create reimbursement record
|
||||||
const formData = new FormData();
|
const formData = new FormData();
|
||||||
formData.append('title', request.title);
|
formData.append('title', request.title);
|
||||||
|
@ -286,8 +280,6 @@ export default function ReimbursementForm() {
|
||||||
setReceipts([]);
|
setReceipts([]);
|
||||||
setError('');
|
setError('');
|
||||||
|
|
||||||
// Dismiss loading toast and show success
|
|
||||||
toast.dismiss(loadingToast);
|
|
||||||
toast.success('🎉 Reimbursement request submitted successfully! Check "My Requests" to view it.', {
|
toast.success('🎉 Reimbursement request submitted successfully! Check "My Requests" to view it.', {
|
||||||
duration: 5000,
|
duration: 5000,
|
||||||
position: 'top-center',
|
position: 'top-center',
|
||||||
|
|
|
@ -4,7 +4,6 @@ import { Get } from '../../../scripts/pocketbase/Get';
|
||||||
import { Authentication } from '../../../scripts/pocketbase/Authentication';
|
import { Authentication } from '../../../scripts/pocketbase/Authentication';
|
||||||
import { FileManager } from '../../../scripts/pocketbase/FileManager';
|
import { FileManager } from '../../../scripts/pocketbase/FileManager';
|
||||||
import FilePreview from '../universal/FilePreview';
|
import FilePreview from '../universal/FilePreview';
|
||||||
import { toast } from 'react-hot-toast';
|
|
||||||
import { motion, AnimatePresence } from 'framer-motion';
|
import { motion, AnimatePresence } from 'framer-motion';
|
||||||
import type { ItemizedExpense, Reimbursement, Receipt } from '../../../schemas/pocketbase';
|
import type { ItemizedExpense, Reimbursement, Receipt } from '../../../schemas/pocketbase';
|
||||||
import { DataSyncService } from '../../../scripts/database/DataSyncService';
|
import { DataSyncService } from '../../../scripts/database/DataSyncService';
|
||||||
|
@ -133,8 +132,6 @@ export default function ReimbursementList() {
|
||||||
throw new Error('User not authenticated');
|
throw new Error('User not authenticated');
|
||||||
}
|
}
|
||||||
|
|
||||||
const loadingToast = toast.loading('Loading reimbursements...');
|
|
||||||
|
|
||||||
// Use DataSyncService to get data from IndexedDB with forced sync
|
// Use DataSyncService to get data from IndexedDB with forced sync
|
||||||
const dataSync = DataSyncService.getInstance();
|
const dataSync = DataSyncService.getInstance();
|
||||||
|
|
||||||
|
@ -181,7 +178,6 @@ export default function ReimbursementList() {
|
||||||
});
|
});
|
||||||
|
|
||||||
setRequests(processedRecords);
|
setRequests(processedRecords);
|
||||||
toast.success('Reimbursements loaded successfully', { id: loadingToast });
|
|
||||||
|
|
||||||
// Fetch receipt details for each reimbursement
|
// Fetch receipt details for each reimbursement
|
||||||
for (const record of processedRecords) {
|
for (const record of processedRecords) {
|
||||||
|
@ -237,7 +233,6 @@ export default function ReimbursementList() {
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error fetching reimbursements:', err);
|
console.error('Error fetching reimbursements:', err);
|
||||||
setError('Failed to load reimbursements. Please try again.');
|
setError('Failed to load reimbursements. Please try again.');
|
||||||
toast.error('Failed to load reimbursements');
|
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
|
@ -245,7 +240,6 @@ export default function ReimbursementList() {
|
||||||
|
|
||||||
const handlePreviewFile = async (request: ReimbursementRequest, receiptId: string) => {
|
const handlePreviewFile = async (request: ReimbursementRequest, receiptId: string) => {
|
||||||
try {
|
try {
|
||||||
const loadingToast = toast.loading('Loading receipt...');
|
|
||||||
const pb = auth.getPocketBase();
|
const pb = auth.getPocketBase();
|
||||||
|
|
||||||
// Check if we already have the receipt details in our map
|
// Check if we already have the receipt details in our map
|
||||||
|
@ -258,8 +252,6 @@ export default function ReimbursementList() {
|
||||||
setPreviewUrl(url);
|
setPreviewUrl(url);
|
||||||
setPreviewFilename(receiptDetailsMap[receiptId].field);
|
setPreviewFilename(receiptDetailsMap[receiptId].field);
|
||||||
setShowPreview(true);
|
setShowPreview(true);
|
||||||
toast.dismiss(loadingToast);
|
|
||||||
toast.success('Receipt loaded successfully');
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -302,14 +294,11 @@ export default function ReimbursementList() {
|
||||||
setPreviewUrl(url);
|
setPreviewUrl(url);
|
||||||
setPreviewFilename(receiptRecord.field);
|
setPreviewFilename(receiptRecord.field);
|
||||||
setShowPreview(true);
|
setShowPreview(true);
|
||||||
toast.dismiss(loadingToast);
|
|
||||||
toast.success('Receipt loaded successfully');
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error('Receipt not found');
|
throw new Error('Receipt not found');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error loading receipt:', error);
|
console.error('Error loading receipt:', error);
|
||||||
toast.error('Failed to load receipt');
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,10 @@
|
||||||
import React from 'react';
|
|
||||||
import { Toaster } from 'react-hot-toast';
|
import { Toaster } from 'react-hot-toast';
|
||||||
|
|
||||||
// Centralized toast provider to ensure consistent rendering
|
// Centralized toast provider to ensure consistent rendering
|
||||||
export default function ToastProvider() {
|
export default function ToastProvider() {
|
||||||
return (
|
return (
|
||||||
<Toaster
|
<Toaster
|
||||||
position="bottom-right"
|
position="top-center"
|
||||||
toastOptions={{
|
toastOptions={{
|
||||||
duration: 4000,
|
duration: 4000,
|
||||||
style: {
|
style: {
|
||||||
|
|
Loading…
Reference in a new issue