Skip to content

Consolidation

This page tracks concrete issues where the codebase uses duplicate implementations, bypasses the shared component library, or uses hardcoded values instead of design tokens. Each item includes the recommended fix.


Priority 1 — Duplicate Components

1. ShaderGradientBackground

Status: Duplicated across apps

FileApp
apps/landing/src/app/components/shader-gradient-background.tsxLanding
apps/admin/src/app/components/ShaderGradientBackground.tsxAdmin

Both files contain identical implementations: a ShaderErrorBoundary class component wrapping ShaderGradientCanvas with the same parameters and CSS fallback.

Fix: Move to packages/shared/components/shader-gradient-background.tsx and import from @prosper/shared in both apps.


Priority 2 — Shared Components Not Used

2. ApplicationForm uses raw HTML elements

File: apps/landing/src/app/components/ApplicationForm.tsx

This 700+ line form uses raw HTML elements with inline Tailwind classes throughout:

Raw ElementShared Replacement
<input>Input
<select>Select + SelectTrigger + SelectContent + SelectItem
<textarea>Textarea
<label>Label
<input type="radio">RadioGroup + RadioGroupItem
<button>Button

Impact: Inconsistent focus rings, missing error styling patterns, visual discrepancies between the application form and the contact form (which correctly uses shared components).

Fix: Replace all raw elements with their shared counterparts. The ContactPage (contact-page.tsx) serves as a reference for the correct import pattern.

3. CandidateInfoPage minimal shared UI usage

File: apps/admin/src/app/components/CandidateInfoPage.tsx

Uses mostly raw HTML + Tailwind for layout. Local helper components FilePill and SectionHeading are defined inline.

Fix:

  • Use Card for the main content area
  • Use Badge for status indicators (work auth, sponsorship, etc.)
  • Use Separator between sections
  • Extract FilePill and SectionHeading if reused elsewhere, or at minimum adopt shared styling patterns

4. ProsperChatPanel fully custom UI

File: apps/admin/src/app/components/ProsperChatPanel.tsx

A 700+ line component with entirely custom button, input, and card styling.

Fix: Adopt Button, Input, Card, and ScrollArea from shared where applicable, particularly for the input bar and action buttons.


Priority 3 — Token / Style Issues

5. SearchInput debug logging

File: packages/shared/components/ui/search-input.tsx

Contains #region agent log blocks with fetch() calls to 127.0.0.1:7242 in useEffect, onFocus, and onChange handlers. This is leftover debug instrumentation.

Fix: Remove all code between // #region agent log and // #endregion comments.

6. OpportunityCard hardcoded shadows

File: apps/landing/src/app/components/job-card.tsx

Uses inline shadow-[...] with raw CSS var references instead of the shadow-card token:

shadow-[0px_0px_0px_1px_var(--color-gray-200),0px_1px_3px_0px_rgba(0,0,0,0.1),0px_1px_2px_-1px_rgba(0,0,0,0.1)]

Fix: Use the shared Card component, or at minimum apply the shadow-card token which provides the same visual effect.

7. LoadingSpinner / ErrorState hardcoded colors

File: packages/shared/components/ui/loading-spinner.tsx

Uses border-gray-300, border-t-gray-900, text-gray-600, text-red-600, text-gray-700, and bg-gray-900 instead of semantic tokens.

Fix: Replace with border-muted, border-foreground, text-muted-foreground, text-destructive, text-foreground, and bg-foreground respectively. Also use shared Button in ErrorState instead of a raw <button>.

8. FilterDropdown custom implementation

File: apps/landing/src/app/components/filter-dropdown.tsx

A fully custom dropdown with manual click-outside handling, no keyboard navigation, and no ARIA attributes.

Fix: Rebuild using Popover + a simple list (or Command for search support). This would gain:

  • Keyboard navigation (arrow keys, Escape, Enter)
  • Proper ARIA roles and focus management
  • Consistent animation and styling
  • Reduced code (~100 lines vs ~50)

Summary

#IssueSeverityEffort
1ShaderGradientBackground duplicateHighLow — move file, update imports
2ApplicationForm raw HTMLHighMedium — replace ~20 elements
3CandidateInfoPage minimal shared UIMediumLow — swap containers and labels
4ProsperChatPanel custom UILowMedium — incremental adoption
5SearchInput debug loggingHighTrivial — delete code
6OpportunityCard hardcoded shadowsLowLow — swap to Card or token
7LoadingSpinner hardcoded colorsMediumLow — swap class names
8FilterDropdown accessibilityMediumMedium — rebuild with Popover