mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-20 10:31:13 -05:00
Refactor: Implement logging phases
This commit is contained in:
@@ -26,7 +26,7 @@ export default tseslint.config(
|
|||||||
...reactHooks.configs.recommended.rules,
|
...reactHooks.configs.recommended.rules,
|
||||||
"react-refresh/only-export-components": ["warn", { allowConstantExport: true }],
|
"react-refresh/only-export-components": ["warn", { allowConstantExport: true }],
|
||||||
// Console statement prevention (P0 #2 - Security Critical)
|
// Console statement prevention (P0 #2 - Security Critical)
|
||||||
"no-console": ["error", { allow: ["warn", "error"] }],
|
"no-console": "error", // Block ALL console statements
|
||||||
"@typescript-eslint/no-unused-vars": "warn",
|
"@typescript-eslint/no-unused-vars": "warn",
|
||||||
"@typescript-eslint/no-explicit-any": "warn",
|
"@typescript-eslint/no-explicit-any": "warn",
|
||||||
"@typescript-eslint/no-unsafe-assignment": "warn",
|
"@typescript-eslint/no-unsafe-assignment": "warn",
|
||||||
@@ -52,7 +52,7 @@ export default tseslint.config(
|
|||||||
},
|
},
|
||||||
rules: {
|
rules: {
|
||||||
// Console statement prevention (P0 #2 - Security Critical)
|
// Console statement prevention (P0 #2 - Security Critical)
|
||||||
"no-console": ["error", { allow: ["warn", "error"] }],
|
"no-console": "error", // Block ALL console statements
|
||||||
"@typescript-eslint/no-unused-vars": "error",
|
"@typescript-eslint/no-unused-vars": "error",
|
||||||
"@typescript-eslint/no-explicit-any": "error",
|
"@typescript-eslint/no-explicit-any": "error",
|
||||||
"@typescript-eslint/explicit-function-return-type": ["error", {
|
"@typescript-eslint/explicit-function-return-type": ["error", {
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ import { useAuth } from '@/hooks/useAuth';
|
|||||||
import { MFAChallenge } from '@/components/auth/MFAChallenge';
|
import { MFAChallenge } from '@/components/auth/MFAChallenge';
|
||||||
import { toast } from '@/hooks/use-toast';
|
import { toast } from '@/hooks/use-toast';
|
||||||
import type { UserRole } from '@/hooks/useUserRole';
|
import type { UserRole } from '@/hooks/useUserRole';
|
||||||
|
import { handleError } from '@/lib/errorHandler';
|
||||||
|
|
||||||
interface AdminUserDeletionDialogProps {
|
interface AdminUserDeletionDialogProps {
|
||||||
open: boolean;
|
open: boolean;
|
||||||
@@ -131,7 +132,10 @@ export function AdminUserDeletionDialog({
|
|||||||
}, 2000);
|
}, 2000);
|
||||||
|
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.error('Error deleting user:', err);
|
handleError(err, {
|
||||||
|
action: 'Delete User',
|
||||||
|
metadata: { targetUserId: targetUser.userId }
|
||||||
|
});
|
||||||
setError(err instanceof Error ? err.message : 'Failed to delete user');
|
setError(err instanceof Error ? err.message : 'Failed to delete user');
|
||||||
setStep('final_confirm');
|
setStep('final_confirm');
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs';
|
|||||||
import { Search, Edit, MapPin, Loader2, X } from 'lucide-react';
|
import { Search, Edit, MapPin, Loader2, X } from 'lucide-react';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { cn } from '@/lib/utils';
|
import { cn } from '@/lib/utils';
|
||||||
|
import { logger } from '@/lib/logger';
|
||||||
|
|
||||||
interface LocationResult {
|
interface LocationResult {
|
||||||
place_id: number;
|
place_id: number;
|
||||||
@@ -64,7 +65,7 @@ export function HeadquartersLocationInput({
|
|||||||
setShowResults(true);
|
setShowResults(true);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error searching locations:', error);
|
logger.error('Error searching locations', { error });
|
||||||
} finally {
|
} finally {
|
||||||
setIsSearching(false);
|
setIsSearching(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import { useSuperuserGuard } from '@/hooks/useSuperuserGuard';
|
|||||||
import { IntegrationTestRunner as TestRunner, allTestSuites, type TestResult } from '@/lib/integrationTests';
|
import { IntegrationTestRunner as TestRunner, allTestSuites, type TestResult } from '@/lib/integrationTests';
|
||||||
import { Play, Square, Download, ChevronDown, CheckCircle2, XCircle, Clock, SkipForward } from 'lucide-react';
|
import { Play, Square, Download, ChevronDown, CheckCircle2, XCircle, Clock, SkipForward } from 'lucide-react';
|
||||||
import { toast } from 'sonner';
|
import { toast } from 'sonner';
|
||||||
|
import { logger } from '@/lib/logger';
|
||||||
|
|
||||||
export function IntegrationTestRunner() {
|
export function IntegrationTestRunner() {
|
||||||
const superuserGuard = useSuperuserGuard();
|
const superuserGuard = useSuperuserGuard();
|
||||||
@@ -67,7 +68,7 @@ export function IntegrationTestRunner() {
|
|||||||
toast.success(`All ${summary.passed} tests passed!`);
|
toast.success(`All ${summary.passed} tests passed!`);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Test run error:', error);
|
logger.error('Test run error', { error });
|
||||||
toast.error('Test run failed');
|
toast.error('Test run failed');
|
||||||
} finally {
|
} finally {
|
||||||
setIsRunning(false);
|
setIsRunning(false);
|
||||||
|
|||||||
@@ -102,7 +102,7 @@ export function LocationSearch({ onLocationSelect, initialLocationId, className
|
|||||||
// Check if response is OK and content-type is JSON
|
// Check if response is OK and content-type is JSON
|
||||||
if (!response.ok) {
|
if (!response.ok) {
|
||||||
const errorMsg = `Location search failed (${response.status}). Please try again.`;
|
const errorMsg = `Location search failed (${response.status}). Please try again.`;
|
||||||
console.error('OpenStreetMap API error:', response.status);
|
logger.error('OpenStreetMap API error', { status: response.status });
|
||||||
setSearchError(errorMsg);
|
setSearchError(errorMsg);
|
||||||
setResults([]);
|
setResults([]);
|
||||||
setShowResults(false);
|
setShowResults(false);
|
||||||
@@ -112,7 +112,7 @@ export function LocationSearch({ onLocationSelect, initialLocationId, className
|
|||||||
const contentType = response.headers.get('content-type');
|
const contentType = response.headers.get('content-type');
|
||||||
if (!contentType || !contentType.includes('application/json')) {
|
if (!contentType || !contentType.includes('application/json')) {
|
||||||
const errorMsg = 'Invalid response from location service. Please try again.';
|
const errorMsg = 'Invalid response from location service. Please try again.';
|
||||||
console.error('Invalid response format from OpenStreetMap');
|
logger.error('Invalid response format from OpenStreetMap', { contentType });
|
||||||
setSearchError(errorMsg);
|
setSearchError(errorMsg);
|
||||||
setResults([]);
|
setResults([]);
|
||||||
setShowResults(false);
|
setShowResults(false);
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@
|
|||||||
import { AlertTriangle, CheckCircle, RefreshCw, Loader2 } from 'lucide-react';
|
import { AlertTriangle, CheckCircle, RefreshCw, Loader2 } from 'lucide-react';
|
||||||
import { supabase } from '@/integrations/supabase/client';
|
import { supabase } from '@/integrations/supabase/client';
|
||||||
import { format } from 'date-fns';
|
import { format } from 'date-fns';
|
||||||
|
import { logger } from '@/lib/logger';
|
||||||
|
|
||||||
interface DuplicateStats {
|
interface DuplicateStats {
|
||||||
date: string | null;
|
date: string | null;
|
||||||
@@ -86,7 +87,7 @@ export function NotificationDebugPanel() {
|
|||||||
})));
|
})));
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to load notification debug data:', error);
|
logger.error('Failed to load notification debug data', { error });
|
||||||
} finally {
|
} finally {
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ import { Loader2, Trash2, CheckCircle, AlertCircle } from 'lucide-react';
|
|||||||
import { useToast } from '@/hooks/use-toast';
|
import { useToast } from '@/hooks/use-toast';
|
||||||
import { supabase } from '@/integrations/supabase/client';
|
import { supabase } from '@/integrations/supabase/client';
|
||||||
import { format } from 'date-fns';
|
import { format } from 'date-fns';
|
||||||
|
import { logger } from '@/lib/logger';
|
||||||
|
|
||||||
export function VersionCleanupSettings() {
|
export function VersionCleanupSettings() {
|
||||||
const [retentionDays, setRetentionDays] = useState(90);
|
const [retentionDays, setRetentionDays] = useState(90);
|
||||||
@@ -52,7 +53,7 @@ export function VersionCleanupSettings() {
|
|||||||
setLastCleanup(cleanupValue);
|
setLastCleanup(cleanupValue);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to load settings:', error);
|
logger.error('Failed to load settings', { error });
|
||||||
toast({
|
toast({
|
||||||
title: 'Error',
|
title: 'Error',
|
||||||
description: 'Failed to load cleanup settings',
|
description: 'Failed to load cleanup settings',
|
||||||
|
|||||||
@@ -383,7 +383,7 @@ export const ReportsQueue = forwardRef<ReportsQueueRef>((props, ref) => {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (auditError) {
|
} catch (auditError) {
|
||||||
console.error('Failed to log report action audit:', auditError);
|
logger.error('Failed to log report action audit', { error: auditError });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import { Component, ReactNode } from 'react';
|
import { Component, ReactNode } from 'react';
|
||||||
import { useAdminGuard } from '@/hooks/useAdminGuard';
|
import { useAdminGuard } from '@/hooks/useAdminGuard';
|
||||||
import { AdminLayout } from '@/components/layout/AdminLayout';
|
import { AdminLayout } from '@/components/layout/AdminLayout';
|
||||||
|
import { logger } from '@/lib/logger';
|
||||||
import { SystemActivityLog } from '@/components/admin/SystemActivityLog';
|
import { SystemActivityLog } from '@/components/admin/SystemActivityLog';
|
||||||
import { Skeleton } from '@/components/ui/skeleton';
|
import { Skeleton } from '@/components/ui/skeleton';
|
||||||
import { Card, CardContent } from '@/components/ui/card';
|
import { Card, CardContent } from '@/components/ui/card';
|
||||||
@@ -28,7 +29,7 @@ class ErrorBoundary extends Component<ErrorBoundaryProps, ErrorBoundaryState> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
componentDidCatch(error: Error, errorInfo: any) {
|
componentDidCatch(error: Error, errorInfo: any) {
|
||||||
console.error('System Activity Log Error:', error, errorInfo);
|
logger.error('System Activity Log Error', { error, errorInfo });
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import { Zap, Mail, Lock, User, AlertCircle, Eye, EyeOff } from 'lucide-react';
|
|||||||
import { supabase } from '@/integrations/supabase/client';
|
import { supabase } from '@/integrations/supabase/client';
|
||||||
import { useToast } from '@/hooks/use-toast';
|
import { useToast } from '@/hooks/use-toast';
|
||||||
import { getErrorMessage } from '@/lib/errorHandler';
|
import { getErrorMessage } from '@/lib/errorHandler';
|
||||||
|
import { logger } from '@/lib/logger';
|
||||||
import { TurnstileCaptcha } from '@/components/auth/TurnstileCaptcha';
|
import { TurnstileCaptcha } from '@/components/auth/TurnstileCaptcha';
|
||||||
import { notificationService } from '@/lib/notificationService';
|
import { notificationService } from '@/lib/notificationService';
|
||||||
import { StorageWarning } from '@/components/auth/StorageWarning';
|
import { StorageWarning } from '@/components/auth/StorageWarning';
|
||||||
@@ -180,7 +181,7 @@ export default function Auth() {
|
|||||||
// Reset CAPTCHA widget to force fresh token generation
|
// Reset CAPTCHA widget to force fresh token generation
|
||||||
setSignInCaptchaKey(prev => prev + 1);
|
setSignInCaptchaKey(prev => prev + 1);
|
||||||
|
|
||||||
console.error('[Auth] Sign in error:', error);
|
logger.error('[Auth] Sign in error', { error });
|
||||||
|
|
||||||
// Enhanced error messages
|
// Enhanced error messages
|
||||||
const errorMsg = getErrorMessage(error);
|
const errorMsg = getErrorMessage(error);
|
||||||
@@ -301,7 +302,7 @@ export default function Auth() {
|
|||||||
username: formData.username,
|
username: formData.username,
|
||||||
}
|
}
|
||||||
}).catch(err => {
|
}).catch(err => {
|
||||||
console.error('Failed to register Novu subscriber:', err);
|
logger.error('Failed to register Novu subscriber', { error: err });
|
||||||
// Don't block signup if Novu registration fails
|
// Don't block signup if Novu registration fails
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import { ArrowLeft, MapPin, Star, Globe, Calendar, Edit, Ruler } from 'lucide-re
|
|||||||
import { Company } from '@/types/database';
|
import { Company } from '@/types/database';
|
||||||
import { supabase } from '@/integrations/supabase/client';
|
import { supabase } from '@/integrations/supabase/client';
|
||||||
import { DesignerPhotoGallery } from '@/components/companies/DesignerPhotoGallery';
|
import { DesignerPhotoGallery } from '@/components/companies/DesignerPhotoGallery';
|
||||||
|
import { logger } from '@/lib/logger';
|
||||||
|
|
||||||
// Lazy load admin form
|
// Lazy load admin form
|
||||||
const DesignerForm = lazy(() => import('@/components/admin/DesignerForm').then(m => ({ default: m.DesignerForm })));
|
const DesignerForm = lazy(() => import('@/components/admin/DesignerForm').then(m => ({ default: m.DesignerForm })));
|
||||||
@@ -81,7 +82,7 @@ export default function DesignerDetail() {
|
|||||||
fetchStatistics(data.id);
|
fetchStatistics(data.id);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching designer:', error);
|
logger.error('Error fetching designer', { error });
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
@@ -108,7 +109,7 @@ export default function DesignerDetail() {
|
|||||||
if (photosError) throw photosError;
|
if (photosError) throw photosError;
|
||||||
setTotalPhotos(photosCount || 0);
|
setTotalPhotos(photosCount || 0);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching statistics:', error);
|
logger.error('Error fetching statistics', { error });
|
||||||
} finally {
|
} finally {
|
||||||
setStatsLoading(false);
|
setStatsLoading(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import { toast } from '@/hooks/use-toast';
|
|||||||
import { useAuthModal } from '@/hooks/useAuthModal';
|
import { useAuthModal } from '@/hooks/useAuthModal';
|
||||||
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
||||||
import { useOpenGraph } from '@/hooks/useOpenGraph';
|
import { useOpenGraph } from '@/hooks/useOpenGraph';
|
||||||
|
import { logger } from '@/lib/logger';
|
||||||
|
|
||||||
export default function DesignerRides() {
|
export default function DesignerRides() {
|
||||||
const { designerSlug } = useParams<{ designerSlug: string }>();
|
const { designerSlug } = useParams<{ designerSlug: string }>();
|
||||||
@@ -90,7 +91,7 @@ export default function DesignerRides() {
|
|||||||
setRides((ridesData || []) as any);
|
setRides((ridesData || []) as any);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching data:', error);
|
logger.error('Error fetching data', { error });
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import { DesignerCard } from '@/components/designers/DesignerCard';
|
|||||||
import { DesignerListView } from '@/components/designers/DesignerListView';
|
import { DesignerListView } from '@/components/designers/DesignerListView';
|
||||||
import { DesignerForm } from '@/components/admin/DesignerForm';
|
import { DesignerForm } from '@/components/admin/DesignerForm';
|
||||||
import { useAuth } from '@/hooks/useAuth';
|
import { useAuth } from '@/hooks/useAuth';
|
||||||
|
import { logger } from '@/lib/logger';
|
||||||
import { useUserRole } from '@/hooks/useUserRole';
|
import { useUserRole } from '@/hooks/useUserRole';
|
||||||
import { toast } from '@/hooks/use-toast';
|
import { toast } from '@/hooks/use-toast';
|
||||||
import { submitCompanyCreation } from '@/lib/companyHelpers';
|
import { submitCompanyCreation } from '@/lib/companyHelpers';
|
||||||
@@ -88,7 +89,7 @@ export default function Designers() {
|
|||||||
const { data } = await query;
|
const { data } = await query;
|
||||||
setCompanies(data || []);
|
setCompanies(data || []);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching companies:', error);
|
logger.error('Error fetching companies', { error });
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import { useNavigate } from "react-router-dom";
|
|||||||
import { supabase } from "@/integrations/supabase/client";
|
import { supabase } from "@/integrations/supabase/client";
|
||||||
import { authStorage } from "@/lib/authStorage";
|
import { authStorage } from "@/lib/authStorage";
|
||||||
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
||||||
|
import { logger } from '@/lib/logger';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* ForceLogout - Hidden endpoint for completely clearing auth session
|
* ForceLogout - Hidden endpoint for completely clearing auth session
|
||||||
@@ -15,26 +16,26 @@ const ForceLogout = () => {
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const performFullLogout = async () => {
|
const performFullLogout = async () => {
|
||||||
console.log('[ForceLogout] Starting complete auth cleanup...');
|
logger.info('[ForceLogout] Starting complete auth cleanup');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// 1. Sign out from Supabase
|
// 1. Sign out from Supabase
|
||||||
console.log('[ForceLogout] Signing out from Supabase...');
|
logger.info('[ForceLogout] Signing out from Supabase');
|
||||||
await supabase.auth.signOut();
|
await supabase.auth.signOut();
|
||||||
|
|
||||||
// 2. Clear all auth-related storage
|
// 2. Clear all auth-related storage
|
||||||
console.log('[ForceLogout] Clearing all auth storage...');
|
logger.info('[ForceLogout] Clearing all auth storage');
|
||||||
authStorage.clearAll();
|
authStorage.clearAll();
|
||||||
|
|
||||||
// 3. Brief delay to ensure cleanup completes
|
// 3. Brief delay to ensure cleanup completes
|
||||||
await new Promise(resolve => setTimeout(resolve, 500));
|
await new Promise(resolve => setTimeout(resolve, 500));
|
||||||
|
|
||||||
console.log('[ForceLogout] ✓ Auth cleanup complete, redirecting to home...');
|
logger.info('[ForceLogout] Auth cleanup complete, redirecting to home');
|
||||||
|
|
||||||
// 4. Redirect to home page
|
// 4. Redirect to home page
|
||||||
navigate('/', { replace: true });
|
navigate('/', { replace: true });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('[ForceLogout] Error during logout:', error);
|
logger.error('[ForceLogout] Error during logout', { error });
|
||||||
// Still redirect even if there's an error
|
// Still redirect even if there's an error
|
||||||
navigate('/', { replace: true });
|
navigate('/', { replace: true });
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ import { ArrowLeft, MapPin, Star, Globe, Calendar, Edit, Factory, FerrisWheel }
|
|||||||
import { Company } from '@/types/database';
|
import { Company } from '@/types/database';
|
||||||
import { supabase } from '@/integrations/supabase/client';
|
import { supabase } from '@/integrations/supabase/client';
|
||||||
import { ManufacturerPhotoGallery } from '@/components/companies/ManufacturerPhotoGallery';
|
import { ManufacturerPhotoGallery } from '@/components/companies/ManufacturerPhotoGallery';
|
||||||
|
import { logger } from '@/lib/logger';
|
||||||
|
|
||||||
// Lazy load admin form
|
// Lazy load admin form
|
||||||
const ManufacturerForm = lazy(() => import('@/components/admin/ManufacturerForm').then(m => ({ default: m.ManufacturerForm })));
|
const ManufacturerForm = lazy(() => import('@/components/admin/ManufacturerForm').then(m => ({ default: m.ManufacturerForm })));
|
||||||
@@ -82,7 +83,7 @@ export default function ManufacturerDetail() {
|
|||||||
fetchStatistics(data.id);
|
fetchStatistics(data.id);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching manufacturer:', error);
|
logger.error('Error fetching manufacturer', { error });
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
@@ -118,7 +119,7 @@ export default function ManufacturerDetail() {
|
|||||||
if (photosError) throw photosError;
|
if (photosError) throw photosError;
|
||||||
setTotalPhotos(photosCount || 0);
|
setTotalPhotos(photosCount || 0);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching statistics:', error);
|
logger.error('Error fetching statistics', { error });
|
||||||
} finally {
|
} finally {
|
||||||
setStatsLoading(false);
|
setStatsLoading(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import { toast } from '@/hooks/use-toast';
|
|||||||
import { useAuthModal } from '@/hooks/useAuthModal';
|
import { useAuthModal } from '@/hooks/useAuthModal';
|
||||||
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
||||||
import { useOpenGraph } from '@/hooks/useOpenGraph';
|
import { useOpenGraph } from '@/hooks/useOpenGraph';
|
||||||
|
import { logger } from '@/lib/logger';
|
||||||
|
|
||||||
interface RideModelWithCount extends RideModel {
|
interface RideModelWithCount extends RideModel {
|
||||||
ride_count: number;
|
ride_count: number;
|
||||||
@@ -85,7 +86,7 @@ export default function ManufacturerModels() {
|
|||||||
setModels(modelsWithCounts);
|
setModels(modelsWithCounts);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching data:', error);
|
logger.error('Error fetching data', { error });
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import { toast } from '@/hooks/use-toast';
|
|||||||
import { useAuthModal } from '@/hooks/useAuthModal';
|
import { useAuthModal } from '@/hooks/useAuthModal';
|
||||||
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
||||||
import { useOpenGraph } from '@/hooks/useOpenGraph';
|
import { useOpenGraph } from '@/hooks/useOpenGraph';
|
||||||
|
import { logger } from '@/lib/logger';
|
||||||
|
|
||||||
export default function ManufacturerRides() {
|
export default function ManufacturerRides() {
|
||||||
const { manufacturerSlug } = useParams<{ manufacturerSlug: string }>();
|
const { manufacturerSlug } = useParams<{ manufacturerSlug: string }>();
|
||||||
@@ -90,7 +91,7 @@ export default function ManufacturerRides() {
|
|||||||
setRides((ridesData || []) as any);
|
setRides((ridesData || []) as any);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching data:', error);
|
logger.error('Error fetching data', { error });
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,7 @@ import { ManufacturerCard } from '@/components/manufacturers/ManufacturerCard';
|
|||||||
import { ManufacturerListView } from '@/components/manufacturers/ManufacturerListView';
|
import { ManufacturerListView } from '@/components/manufacturers/ManufacturerListView';
|
||||||
import { ManufacturerForm } from '@/components/admin/ManufacturerForm';
|
import { ManufacturerForm } from '@/components/admin/ManufacturerForm';
|
||||||
import { useAuth } from '@/hooks/useAuth';
|
import { useAuth } from '@/hooks/useAuth';
|
||||||
|
import { logger } from '@/lib/logger';
|
||||||
import { useUserRole } from '@/hooks/useUserRole';
|
import { useUserRole } from '@/hooks/useUserRole';
|
||||||
import { toast } from '@/hooks/use-toast';
|
import { toast } from '@/hooks/use-toast';
|
||||||
import { submitCompanyCreation } from '@/lib/companyHelpers';
|
import { submitCompanyCreation } from '@/lib/companyHelpers';
|
||||||
@@ -75,7 +76,7 @@ export default function Manufacturers() {
|
|||||||
const { data } = await query;
|
const { data } = await query;
|
||||||
setCompanies(data || []);
|
setCompanies(data || []);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching companies:', error);
|
logger.error('Error fetching companies', { error });
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
import { useLocation } from "react-router-dom";
|
import { useLocation } from "react-router-dom";
|
||||||
import { useEffect } from "react";
|
import { useEffect } from "react";
|
||||||
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
||||||
|
import { logger } from '@/lib/logger';
|
||||||
|
|
||||||
const NotFound = () => {
|
const NotFound = () => {
|
||||||
useDocumentTitle('404 - Page Not Found');
|
useDocumentTitle('404 - Page Not Found');
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
console.error("404 Error: User attempted to access non-existent route:", location.pathname);
|
logger.error("404 Error: User attempted to access non-existent route", { pathname: location.pathname });
|
||||||
}, [location.pathname]);
|
}, [location.pathname]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { Company, Park } from '@/types/database';
|
|||||||
import { supabase } from '@/integrations/supabase/client';
|
import { supabase } from '@/integrations/supabase/client';
|
||||||
import { OperatorPhotoGallery } from '@/components/companies/OperatorPhotoGallery';
|
import { OperatorPhotoGallery } from '@/components/companies/OperatorPhotoGallery';
|
||||||
import { ParkCard } from '@/components/parks/ParkCard';
|
import { ParkCard } from '@/components/parks/ParkCard';
|
||||||
|
import { logger } from '@/lib/logger';
|
||||||
|
|
||||||
// Lazy load admin form
|
// Lazy load admin form
|
||||||
const OperatorForm = lazy(() => import('@/components/admin/OperatorForm').then(m => ({ default: m.OperatorForm })));
|
const OperatorForm = lazy(() => import('@/components/admin/OperatorForm').then(m => ({ default: m.OperatorForm })));
|
||||||
@@ -89,7 +90,7 @@ export default function OperatorDetail() {
|
|||||||
fetchPhotoCount(data.id);
|
fetchPhotoCount(data.id);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching operator:', error);
|
logger.error('Error fetching operator', { error });
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
@@ -110,7 +111,7 @@ export default function OperatorDetail() {
|
|||||||
if (error) throw error;
|
if (error) throw error;
|
||||||
setParks(data || []);
|
setParks(data || []);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching parks:', error);
|
logger.error('Error fetching parks', { error });
|
||||||
} finally {
|
} finally {
|
||||||
setParksLoading(false);
|
setParksLoading(false);
|
||||||
}
|
}
|
||||||
@@ -137,7 +138,7 @@ export default function OperatorDetail() {
|
|||||||
if (ridesError) throw ridesError;
|
if (ridesError) throw ridesError;
|
||||||
setOperatingRides(ridesData?.length || 0);
|
setOperatingRides(ridesData?.length || 0);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching statistics:', error);
|
logger.error('Error fetching statistics', { error });
|
||||||
} finally {
|
} finally {
|
||||||
setStatsLoading(false);
|
setStatsLoading(false);
|
||||||
}
|
}
|
||||||
@@ -154,7 +155,7 @@ export default function OperatorDetail() {
|
|||||||
if (error) throw error;
|
if (error) throw error;
|
||||||
setTotalPhotos(count || 0);
|
setTotalPhotos(count || 0);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching photo count:', error);
|
logger.error('Error fetching photo count', { error });
|
||||||
setTotalPhotos(0);
|
setTotalPhotos(0);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import { Grid3X3, List } from 'lucide-react';
|
|||||||
import { FilterState, SortState } from './Parks';
|
import { FilterState, SortState } from './Parks';
|
||||||
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
||||||
import { useOpenGraph } from '@/hooks/useOpenGraph';
|
import { useOpenGraph } from '@/hooks/useOpenGraph';
|
||||||
|
import { logger } from '@/lib/logger';
|
||||||
|
|
||||||
const initialFilters: FilterState = {
|
const initialFilters: FilterState = {
|
||||||
search: '',
|
search: '',
|
||||||
@@ -86,7 +87,7 @@ export default function OperatorParks() {
|
|||||||
setParks(parksData || []);
|
setParks(parksData || []);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching data:', error);
|
logger.error('Error fetching data', { error });
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,6 +17,7 @@ import { Grid3X3, List } from 'lucide-react';
|
|||||||
import { FilterState, SortState } from './Parks';
|
import { FilterState, SortState } from './Parks';
|
||||||
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
||||||
import { useOpenGraph } from '@/hooks/useOpenGraph';
|
import { useOpenGraph } from '@/hooks/useOpenGraph';
|
||||||
|
import { logger } from '@/lib/logger';
|
||||||
|
|
||||||
const initialFilters: FilterState = {
|
const initialFilters: FilterState = {
|
||||||
search: '',
|
search: '',
|
||||||
@@ -86,7 +87,7 @@ export default function OwnerParks() {
|
|||||||
setParks(parksData || []);
|
setParks(parksData || []);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching data:', error);
|
logger.error('Error fetching data', { error });
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import { supabase } from '@/integrations/supabase/client';
|
|||||||
import { useAuth } from '@/hooks/useAuth';
|
import { useAuth } from '@/hooks/useAuth';
|
||||||
import { toast } from '@/hooks/use-toast';
|
import { toast } from '@/hooks/use-toast';
|
||||||
import { getErrorMessage } from '@/lib/errorHandler';
|
import { getErrorMessage } from '@/lib/errorHandler';
|
||||||
|
import { logger } from '@/lib/logger';
|
||||||
import { useAuthModal } from '@/hooks/useAuthModal';
|
import { useAuthModal } from '@/hooks/useAuthModal';
|
||||||
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
||||||
import { useOpenGraph } from '@/hooks/useOpenGraph';
|
import { useOpenGraph } from '@/hooks/useOpenGraph';
|
||||||
@@ -110,7 +111,7 @@ export default function ParkRides() {
|
|||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
setRides((ridesData || []) as any);
|
setRides((ridesData || []) as any);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching park and rides:', error);
|
logger.error('Error fetching park and rides', { error });
|
||||||
toast({
|
toast({
|
||||||
title: "Error",
|
title: "Error",
|
||||||
description: "Failed to load park rides.",
|
description: "Failed to load park rides.",
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import { User, MapPin, Calendar, Star, Trophy, Settings, Camera, Edit3, Save, X,
|
|||||||
import { Profile as ProfileType } from '@/types/database';
|
import { Profile as ProfileType } from '@/types/database';
|
||||||
import { supabase } from '@/integrations/supabase/client';
|
import { supabase } from '@/integrations/supabase/client';
|
||||||
import { useToast } from '@/hooks/use-toast';
|
import { useToast } from '@/hooks/use-toast';
|
||||||
|
import { logger } from '@/lib/logger';
|
||||||
import { getErrorMessage } from '@/lib/errorHandler';
|
import { getErrorMessage } from '@/lib/errorHandler';
|
||||||
import { PhotoUpload } from '@/components/upload/PhotoUpload';
|
import { PhotoUpload } from '@/components/upload/PhotoUpload';
|
||||||
import { profileEditSchema } from '@/lib/validation';
|
import { profileEditSchema } from '@/lib/validation';
|
||||||
@@ -215,7 +216,7 @@ export default function Profile() {
|
|||||||
parkCount: parkCount
|
parkCount: parkCount
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching calculated stats:', error);
|
logger.error('Error fetching calculated stats', { error });
|
||||||
toast({
|
toast({
|
||||||
variant: 'destructive',
|
variant: 'destructive',
|
||||||
description: getErrorMessage(error),
|
description: getErrorMessage(error),
|
||||||
@@ -379,7 +380,7 @@ export default function Profile() {
|
|||||||
|
|
||||||
setRecentActivity(combined);
|
setRecentActivity(combined);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching recent activity:', error);
|
logger.error('Error fetching recent activity', { error });
|
||||||
toast({
|
toast({
|
||||||
variant: 'destructive',
|
variant: 'destructive',
|
||||||
description: getErrorMessage(error),
|
description: getErrorMessage(error),
|
||||||
@@ -440,7 +441,7 @@ export default function Profile() {
|
|||||||
await fetchRecentActivity(data.user_id || '');
|
await fetchRecentActivity(data.user_id || '');
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching profile:', error);
|
logger.error('Error fetching profile', { error });
|
||||||
toast({
|
toast({
|
||||||
variant: "destructive",
|
variant: "destructive",
|
||||||
title: "Error loading profile",
|
title: "Error loading profile",
|
||||||
@@ -481,7 +482,7 @@ export default function Profile() {
|
|||||||
await fetchRecentActivity(user.id);
|
await fetchRecentActivity(user.id);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching profile:', error);
|
logger.error('Error fetching profile', { error });
|
||||||
toast({
|
toast({
|
||||||
variant: "destructive",
|
variant: "destructive",
|
||||||
title: "Error loading profile",
|
title: "Error loading profile",
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ import { Company, Park } from '@/types/database';
|
|||||||
import { supabase } from '@/integrations/supabase/client';
|
import { supabase } from '@/integrations/supabase/client';
|
||||||
import { PropertyOwnerPhotoGallery } from '@/components/companies/PropertyOwnerPhotoGallery';
|
import { PropertyOwnerPhotoGallery } from '@/components/companies/PropertyOwnerPhotoGallery';
|
||||||
import { ParkCard } from '@/components/parks/ParkCard';
|
import { ParkCard } from '@/components/parks/ParkCard';
|
||||||
|
import { logger } from '@/lib/logger';
|
||||||
|
|
||||||
// Lazy load admin form
|
// Lazy load admin form
|
||||||
const PropertyOwnerForm = lazy(() => import('@/components/admin/PropertyOwnerForm').then(m => ({ default: m.PropertyOwnerForm })));
|
const PropertyOwnerForm = lazy(() => import('@/components/admin/PropertyOwnerForm').then(m => ({ default: m.PropertyOwnerForm })));
|
||||||
@@ -89,7 +90,7 @@ export default function PropertyOwnerDetail() {
|
|||||||
fetchPhotoCount(data.id);
|
fetchPhotoCount(data.id);
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching property owner:', error);
|
logger.error('Error fetching property owner', { error });
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
@@ -110,7 +111,7 @@ export default function PropertyOwnerDetail() {
|
|||||||
if (error) throw error;
|
if (error) throw error;
|
||||||
setParks(data || []);
|
setParks(data || []);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching parks:', error);
|
logger.error('Error fetching parks', { error });
|
||||||
} finally {
|
} finally {
|
||||||
setParksLoading(false);
|
setParksLoading(false);
|
||||||
}
|
}
|
||||||
@@ -137,7 +138,7 @@ export default function PropertyOwnerDetail() {
|
|||||||
if (ridesError) throw ridesError;
|
if (ridesError) throw ridesError;
|
||||||
setOperatingRides(ridesData?.length || 0);
|
setOperatingRides(ridesData?.length || 0);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching statistics:', error);
|
logger.error('Error fetching statistics', { error });
|
||||||
} finally {
|
} finally {
|
||||||
setStatsLoading(false);
|
setStatsLoading(false);
|
||||||
}
|
}
|
||||||
@@ -154,7 +155,7 @@ export default function PropertyOwnerDetail() {
|
|||||||
if (error) throw error;
|
if (error) throw error;
|
||||||
setTotalPhotos(count || 0);
|
setTotalPhotos(count || 0);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching photo count:', error);
|
logger.error('Error fetching photo count', { error });
|
||||||
setTotalPhotos(0);
|
setTotalPhotos(0);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -16,6 +16,7 @@ import { useAuthModal } from '@/hooks/useAuthModal';
|
|||||||
import { useAuth } from '@/hooks/useAuth';
|
import { useAuth } from '@/hooks/useAuth';
|
||||||
import { toast } from '@/hooks/use-toast';
|
import { toast } from '@/hooks/use-toast';
|
||||||
import { getErrorMessage } from '@/lib/errorHandler';
|
import { getErrorMessage } from '@/lib/errorHandler';
|
||||||
|
import { logger } from '@/lib/logger';
|
||||||
import { ManufacturerPhotoGallery } from '@/components/companies/ManufacturerPhotoGallery';
|
import { ManufacturerPhotoGallery } from '@/components/companies/ManufacturerPhotoGallery';
|
||||||
|
|
||||||
// Lazy load admin form
|
// Lazy load admin form
|
||||||
@@ -108,7 +109,7 @@ export default function RideModelDetail() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Error fetching data:', error);
|
logger.error('Error fetching data', { error });
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ import { useAuth } from '@/hooks/useAuth';
|
|||||||
import { useAuthModal } from '@/hooks/useAuthModal';
|
import { useAuthModal } from '@/hooks/useAuthModal';
|
||||||
import { toast } from '@/hooks/use-toast';
|
import { toast } from '@/hooks/use-toast';
|
||||||
import { getErrorMessage } from '@/lib/errorHandler';
|
import { getErrorMessage } from '@/lib/errorHandler';
|
||||||
|
import { logger } from '@/lib/logger';
|
||||||
import type { Ride, Company, RideModel } from "@/types/database";
|
import type { Ride, Company, RideModel } from "@/types/database";
|
||||||
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
import { useDocumentTitle } from '@/hooks/useDocumentTitle';
|
||||||
|
|
||||||
@@ -110,7 +111,7 @@ export default function RideModelRides() {
|
|||||||
setModel(modelData as RideModel);
|
setModel(modelData as RideModel);
|
||||||
setRides(ridesData as Ride[] || []);
|
setRides(ridesData as Ride[] || []);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error("Error fetching data:", error);
|
logger.error("Error fetching data", { error });
|
||||||
} finally {
|
} finally {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user