Files
sapiens-web3/frontend-issues.md
kimjaehyeon0101 e4a776f67e Fix critical issues to ensure platform stability and user functionality
Addresses critical issues including SSR crashes due to improper localStorage/document access and a broken betting feature in Article.tsx.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: aabe2db1-f078-4501-aab5-be145ebc6b9a
Replit-Commit-Checkpoint-Type: intermediate_checkpoint
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/3df548ff-50ae-432f-9be4-25d34eccc983/aabe2db1-f078-4501-aab5-be145ebc6b9a/TqVS1Ec
2025-10-12 08:24:44 +00:00

8.9 KiB

Frontend Issues - Code Review Report

🔴 Critical Issues (Immediate Fix Required)

1. localStorage Access Without Browser Check - SSR Crash Risk

Severity: CRITICAL
Files Affected:

  • client/src/pages/Home.tsx
  • client/src/pages/Landing.tsx
  • client/src/pages/Auctions.tsx
  • client/src/pages/MediaOutlet.tsx

Problem: Multiple pages initialize React state directly from localStorage without checking if window is defined:

const [theme, setTheme] = useState(() => localStorage.getItem('theme') || 'light');

Impact:

  • ReferenceError in SSR/non-browser environments (tests, server-side rendering)
  • Application crashes immediately on page load
  • Breaks testing infrastructure
  • Prevents server-side rendering if needed in future

Reproduction:

  1. Run unit tests that mount these components
  2. Try server-side rendering
  3. Access localStorage before window is available

Fix Solution:

// ❌ Current (BROKEN)
const [theme, setTheme] = useState(() => localStorage.getItem('theme') || 'light');

// ✅ Fixed
const [theme, setTheme] = useState(() => {
  if (typeof window !== 'undefined') {
    return localStorage.getItem('theme') || 'light';
  }
  return 'light';
});

// Alternative: Move to useEffect
const [theme, setTheme] = useState('light');

useEffect(() => {
  if (typeof window !== 'undefined') {
    const savedTheme = localStorage.getItem('theme');
    if (savedTheme) setTheme(savedTheme);
  }
}, []);

Priority: P0 - Fix immediately


2. Betting Feature Completely Broken - Ignores User Input

Severity: CRITICAL
File: client/src/pages/Article.tsx

Problem: The handlePlaceBet function ignores user input and always submits hardcoded value:

const handlePlaceBet = (marketId: string, option: "yes" | "no") => {
  // User input stored in betAmounts[marketId] is IGNORED
  const amount = 10000; // ❌ HARDCODED!
  
  placeBetMutation.mutate({ marketId, option, amount });
};

Impact:

  • Users cannot place custom bets
  • All bets are forced to 10,000 regardless of input
  • Primary feature of the page is non-functional
  • Poor user experience

Reproduction:

  1. Navigate to an article with prediction market
  2. Enter any bet amount (e.g., 500)
  3. Click place bet
  4. Backend receives 10,000 instead of 500

Fix Solution:

// ❌ Current (BROKEN)
const handlePlaceBet = (marketId: string, option: "yes" | "no") => {
  const amount = 10000; // Hardcoded!
  placeBetMutation.mutate({ marketId, option, amount });
};

// ✅ Fixed
const handlePlaceBet = (marketId: string, option: "yes" | "no") => {
  const inputAmount = betAmounts[marketId];
  
  // Validate input
  if (!inputAmount || parseFloat(inputAmount) <= 0) {
    toast({
      title: "Invalid Amount",
      description: "Please enter a valid bet amount greater than 0",
      variant: "destructive"
    });
    return;
  }
  
  const amount = parseFloat(inputAmount);
  placeBetMutation.mutate({ marketId, option, amount });
};

Priority: P0 - Fix immediately


🟠 High Priority Issues

3. document.documentElement Access Without Browser Check

Severity: HIGH
Files Affected:

  • client/src/pages/Home.tsx
  • client/src/pages/Landing.tsx
  • client/src/pages/Auctions.tsx
  • client/src/pages/MediaOutlet.tsx

Problem: Direct access to document.documentElement in useEffect without browser check:

useEffect(() => {
  if (theme === 'dark') {
    document.documentElement.classList.add('dark'); // No browser check!
  }
}, [theme]);

Impact:

  • Crashes in SSR environments
  • Breaks in test environments without DOM
  • Prevents future SSR implementation

Fix Solution:

useEffect(() => {
  if (typeof window === 'undefined') return;
  
  if (theme === 'dark') {
    document.documentElement.classList.add('dark');
  } else {
    document.documentElement.classList.remove('dark');
  }
  localStorage.setItem('theme', theme);
}, [theme]);

Priority: P1 - Fix soon


4. Missing Error State Rendering

Severity: HIGH
Files Affected:

  • client/src/pages/Auctions.tsx
  • client/src/pages/MediaOutlet.tsx
  • client/src/pages/Article.tsx
  • client/src/pages/AdminDashboard.tsx

Problem: Queries fetch data but don't handle error states:

const { data: auctions = [], isLoading } = useQuery<Auction[]>({
  queryKey: ["/api/auctions"],
});
// No error handling! 😱

Impact:

  • Users see blank screen on API failures
  • No feedback when network is down
  • Poor user experience
  • Difficult debugging

Fix Solution:

const { data: auctions = [], isLoading, error, isError } = useQuery<Auction[]>({
  queryKey: ["/api/auctions"],
});

// Add error rendering
if (isError) {
  return (
    <div className="flex flex-col items-center justify-center min-h-[400px] p-8">
      <AlertCircle className="h-12 w-12 text-destructive mb-4" />
      <h3 className="text-xl font-semibold mb-2">Failed to Load Auctions</h3>
      <p className="text-muted-foreground mb-4">
        {error?.message || "An error occurred while fetching data"}
      </p>
      <Button onClick={() => queryClient.invalidateQueries({ queryKey: ["/api/auctions"] })}>
        Try Again
      </Button>
    </div>
  );
}

Priority: P1 - Add error boundaries


🟡 Medium Priority Issues

5. Potential Memory Leak - Missing Cleanup in Mutations

Severity: MEDIUM
Files Affected: Multiple pages with mutations

Problem: Mutations don't cancel on component unmount:

const placeBetMutation = useMutation({
  mutationFn: async (data) => { /* ... */ },
  onSuccess: () => { /* ... */ }
});
// No cleanup when component unmounts!

Impact:

  • State updates after unmount warnings
  • Memory leaks in SPA navigation
  • React warnings in console

Fix Solution:

// Use React Query's built-in cleanup or add manual abort
const placeBetMutation = useMutation({
  mutationFn: async (data, { signal }) => {
    return await apiRequest("POST", `/api/endpoint`, data, { signal });
  },
  // React Query handles cleanup automatically
});

Priority: P2 - Improve stability


6. Form Validation Missing on Frontend

Severity: MEDIUM
Files Affected:

  • client/src/pages/Auctions.tsx (bid form)
  • client/src/pages/Article.tsx (bet form)
  • client/src/components/LoginModal.tsx

Problem: Forms rely only on backend validation:

<Input
  type="number"
  value={bidForm.amount}
  onChange={(e) => setBidForm(prev => ({ ...prev, amount: e.target.value }))}
  required
/>

Impact:

  • Poor UX - errors shown only after submission
  • Unnecessary API calls with invalid data
  • Backend load from validation

Fix Solution:

// Add react-hook-form with zod validation
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import { z } from "zod";

const bidSchema = z.object({
  amount: z.number()
    .min(0.01, "Amount must be greater than 0")
    .max(1000000, "Amount too large"),
  qualityScore: z.number()
    .int("Must be a whole number")
    .min(1, "Score must be at least 1")
    .max(100, "Score cannot exceed 100")
});

const form = useForm({
  resolver: zodResolver(bidSchema),
  defaultValues: { amount: "", qualityScore: "" }
});

Priority: P2 - Enhance UX


🟢 Low Priority Issues

7. Inconsistent Loading States

Severity: LOW
Files Affected: Multiple pages

Problem: Some pages show skeleton loaders, others show nothing:

{isLoading ? (
  <div>Loading...</div> // Inconsistent!
) : (
  <Content />
)}

Impact:

  • Inconsistent user experience
  • Some pages feel slower than others

Fix Solution: Create reusable skeleton components and use consistently.

Priority: P3 - Polish


8. Accessibility Issues

Severity: LOW
Files Affected: Multiple components

Issues Found:

  • Missing ARIA labels on icon buttons
  • Color contrast issues in dark mode
  • Keyboard navigation not fully tested
  • Focus management in modals could be improved

Fix Solution:

  • Add aria-label to icon-only buttons
  • Test with screen readers
  • Implement focus traps in modals
  • Add skip navigation links

Priority: P3 - Accessibility enhancement


Summary

Severity Count Must Fix Before Production
🔴 Critical 2 Yes
🟠 High 2 Yes
🟡 Medium 2 ⚠️ Recommended
🟢 Low 2 Nice to have

Total Issues: 8

Estimated Fix Time:

  • Critical issues: 2-4 hours
  • High priority: 4-6 hours
  • Medium priority: 4-8 hours
  • Low priority: 8-12 hours

Recommended Fix Order:

  1. Fix localStorage/document browser checks (affects all environments)
  2. Fix betting input bug (core functionality)
  3. Add error state rendering (user experience)
  4. Add form validation (UX improvement)
  5. Address memory leaks (stability)
  6. Polish loading states and accessibility (enhancement)