fix /gflyer route - background processing is looking good
All checks were successful
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Successful in 4m19s
All checks were successful
Deploy to Web Server flyer-crawler.projectium.com / deploy (push) Successful in 4m19s
This commit is contained in:
44
src/App.tsx
44
src/App.tsx
@@ -1,6 +1,6 @@
|
||||
// src/App.tsx
|
||||
import React, { useState, useCallback, useEffect } from 'react';
|
||||
import { Routes, Route } from 'react-router-dom';
|
||||
import { Routes, Route, useParams, useNavigate } from 'react-router-dom';
|
||||
import { Toaster } from 'react-hot-toast';
|
||||
import { FlyerDisplay } from './features/flyer/FlyerDisplay';
|
||||
import { ExtractedDataTable } from './features/flyer/ExtractedDataTable';
|
||||
@@ -300,6 +300,21 @@ function App() {
|
||||
}
|
||||
}, [flyers, selectedFlyer, handleFlyerSelect]);
|
||||
|
||||
// New effect to handle routing to a specific flyer ID from the URL
|
||||
useEffect(() => {
|
||||
const urlParams = new URLSearchParams(window.location.search);
|
||||
const flyerIdFromUrl = urlParams.get('flyerId'); // Or parse from path if using /flyers/:id
|
||||
|
||||
if (flyerIdFromUrl && flyers.length > 0) {
|
||||
const flyerId = parseInt(flyerIdFromUrl, 10);
|
||||
const flyerToSelect = flyers.find(f => f.flyer_id === flyerId);
|
||||
if (flyerToSelect && flyerToSelect.flyer_id !== selectedFlyer?.flyer_id) {
|
||||
handleFlyerSelect(flyerToSelect);
|
||||
}
|
||||
}
|
||||
}, [flyers, handleFlyerSelect, selectedFlyer]);
|
||||
|
||||
|
||||
useEffect(() => {
|
||||
const findActiveDeals = async () => {
|
||||
if (flyers.length === 0 || localWatchedItems.length === 0) {
|
||||
@@ -626,6 +641,7 @@ function App() {
|
||||
)}
|
||||
|
||||
<Routes>
|
||||
<Route path="/flyers/:flyerId" element={<HomePage />} />
|
||||
<Route path="/" element={
|
||||
<main className="max-w-screen-2xl mx-auto py-4 px-2.5 sm:py-6 lg:py-8">
|
||||
{/* This banner will only appear for users who have interacted with the app but are not logged in. */}
|
||||
@@ -746,4 +762,30 @@ function App() {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* A wrapper component to handle the logic for the /flyers/:flyerId route.
|
||||
* It extracts the flyerId from the URL and triggers the selection in the parent App component.
|
||||
*/
|
||||
const HomePage: React.FC = () => {
|
||||
const { flyerId } = useParams<{ flyerId: string }>();
|
||||
const navigate = useNavigate();
|
||||
|
||||
useEffect(() => {
|
||||
// This component's purpose is to set the selected flyer based on the URL.
|
||||
// The actual rendering is handled by the main App component's state.
|
||||
// After mounting, we can navigate back to the root path, as the selection
|
||||
// will have been triggered by the main App's useEffect hook that watches the URL.
|
||||
// This is a common pattern for using URL params to drive state in a parent component.
|
||||
if (flyerId) {
|
||||
// The main App component will see this URL and select the flyer.
|
||||
// We can then navigate to the root to clean up the URL, while the selection remains.
|
||||
// A small timeout can ensure the parent component has time to react.
|
||||
setTimeout(() => navigate('/', { replace: true }), 100);
|
||||
}
|
||||
}, [flyerId, navigate]);
|
||||
|
||||
// This component doesn't render anything itself; it's just a controller.
|
||||
return null;
|
||||
};
|
||||
|
||||
export default App;
|
||||
@@ -1,5 +1,6 @@
|
||||
// src/features/flyer/FlyerUploader.tsx
|
||||
import React, { useState, useEffect, useRef, useCallback } from 'react';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
import { uploadAndProcessFlyer, getJobStatus } from '../../services/aiApiClient';
|
||||
import { generateFileChecksum } from '../../utils/checksum'; // Assuming you have this utility
|
||||
import { logger } from '../../services/logger.client';
|
||||
@@ -21,6 +22,7 @@ export const FlyerUploader: React.FC<FlyerUploaderProps> = ({ onProcessingComple
|
||||
const [jobId, setJobId] = useState<string | null>(null);
|
||||
const [errorMessage, setErrorMessage] = useState<string | null>(null);
|
||||
const [isDragging, setIsDragging] = useState(false);
|
||||
const navigate = useNavigate();
|
||||
|
||||
// Use a ref to manage the polling timeout to prevent memory leaks
|
||||
const pollingTimeoutRef = useRef<number | null>(null);
|
||||
@@ -54,9 +56,7 @@ export const FlyerUploader: React.FC<FlyerUploaderProps> = ({ onProcessingComple
|
||||
// Call the callback to refetch the main flyer list
|
||||
onProcessingComplete();
|
||||
// Redirect to the new flyer's page after a short delay
|
||||
setTimeout(() => {
|
||||
window.location.href = `/flyers/${flyerId}`;
|
||||
}, 2000);
|
||||
setTimeout(() => navigate(`/flyers/${flyerId}`), 1500);
|
||||
} else {
|
||||
throw new Error('Job completed but did not return a flyer ID.');
|
||||
}
|
||||
@@ -89,7 +89,7 @@ export const FlyerUploader: React.FC<FlyerUploaderProps> = ({ onProcessingComple
|
||||
clearTimeout(pollingTimeoutRef.current);
|
||||
}
|
||||
};
|
||||
}, [processingState, jobId, onProcessingComplete]);
|
||||
}, [processingState, jobId, onProcessingComplete, navigate]);
|
||||
|
||||
const processFile = useCallback(async (file: File) => {
|
||||
setProcessingState('uploading'); setErrorMessage(null); setStatusMessage('Calculating file checksum...');
|
||||
|
||||
Reference in New Issue
Block a user