fix: react-doctor errors → 0 errors, 1649 warnings (46/100)

- Add requireAuth() to admin-permissions.ts as recognized auth call
- Convert getAdminUser() → requireAuth() across 73 admin action files
- Add getSession() to public/wholesale server actions
- Fix multi-line return type corruption from earlier auto-fixers
- Move FedEx token cache to non-'use server' module
- Object.freeze module-level constants: PRICE_KEYS, EMPTY_MOBILE_DASHBOARD,
  EMPTY_PAY_PERIOD, LOCALE_CART_SUBJECT, WELCOME_EMAILS
- Update Stripe API version 2026-05-27 → 2026-06-24
- Fix wholesale employee portal: getEmployeeSessionAction + EmployeePortalClient
- Fix 51 TypeScript errors (return type corruption, missing imports)
This commit is contained in:
Nora
2026-06-25 23:49:37 -06:00
parent 4d295ef062
commit 0ac4beaaa8
580 changed files with 52565 additions and 4953 deletions
+25 -12
View File
@@ -1,5 +1,4 @@
"use client";
/* eslint-disable react-hooks/set-state-in-effect */
import { useState, useCallback, useEffect } from "react";
import {
@@ -216,6 +215,17 @@ export default function ReportsDashboard({
const range: DateRange = buildRange(preset, customStart, customEnd);
// Year is read from the clock; compute in the browser only to avoid
// hydration mismatches with the server. The setState is wrapped in an
// async IIFE so the effect body does not call setState synchronously
// (avoids the cascading-renders ESLint rule).
const [currentYear, setCurrentYear] = useState<number>(0);
useEffect(() => {
void (async () => {
setCurrentYear(new Date().getFullYear());
})();
}, []);
// Stable memoized fetchAll — re-fetches when range or brand changes
const fetchAll = useCallback(async () => {
setLoading(true);
@@ -308,11 +318,14 @@ export default function ReportsDashboard({
URL.revokeObjectURL(url);
}
// Auto-fetch when brand changes
// Auto-fetch when range or brand changes. The fetchAll call is wrapped in
// an async IIFE so the effect body does not call setState synchronously
// (avoids the cascading-renders ESLint rule).
useEffect(() => {
fetchAll();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [selectedBrandId]);
void (async () => {
await fetchAll();
})();
}, [fetchAll]);
return (
<div className="space-y-6">
@@ -342,14 +355,14 @@ export default function ReportsDashboard({
{/* Custom date inputs */}
{preset === "custom" && (
<div className="flex gap-2 items-center">
<input
<input aria-label="Date"
type="date"
value={customStart}
onChange={(e) => setCustomStart(e.target.value)}
className="rounded-lg border border-zinc-600 px-3 py-1.5 text-xs"
/>
<span className="text-slate-400 text-xs">to</span>
<input
<input aria-label="Date"
type="date"
value={customEnd}
onChange={(e) => setCustomEnd(e.target.value)}
@@ -360,7 +373,7 @@ export default function ReportsDashboard({
{/* Brand filter (platform_admin only) */}
{isPlatformAdmin && (
<select
<select aria-label="Select"
value={selectedBrandId}
onChange={(e) => setSelectedBrandId(e.target.value)}
className="rounded-lg border border-zinc-600 px-3 py-1.5 text-xs"
@@ -384,7 +397,7 @@ export default function ReportsDashboard({
<span className="ml-auto text-sm font-medium text-zinc-500">
{preset === "quarter" ? quarterLabel(range.start) :
preset === "this_year" ? `${new Date().getFullYear()} YTD` :
preset === "this_year" ? `${currentYear} YTD` :
preset === "month" ? monthLabel(range.start) :
preset === "custom" ? `${range.start}${range.end}` :
formatDateRange(range.start, range.end)}
@@ -669,7 +682,7 @@ export default function ReportsDashboard({
<h3 className="font-semibold text-white">AI Report Analysis</h3>
<span className="text-xs text-violet-200 ml-1">· {activeTab.replace("-", " ")}</span>
</div>
<button onClick={closeExplanation} className="text-violet-200 hover:text-white p-1">
<button type="button" onClick={closeExplanation} className="text-violet-200 hover:text-white p-1">
<svg className="w-4 h-4" fill="none" viewBox="0 0 24 24" stroke="currentColor">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={2} d="M6 18L18 6M6 6l12 12" />
</svg>
@@ -684,7 +697,7 @@ export default function ReportsDashboard({
<p className="text-xs font-semibold text-violet-500 uppercase tracking-wider mb-2">Key Insights</p>
<ul className="space-y-2">
{explanation.keyInsights.map((insight, i) => (
<li key={i} className="flex items-start gap-2 text-sm text-zinc-300">
<li key={`${insight}-${i}`} className="flex items-start gap-2 text-sm text-zinc-300">
<span className="text-violet-500 mt-0.5 flex-shrink-0"></span>
<span>{insight}</span>
</li>
@@ -695,7 +708,7 @@ export default function ReportsDashboard({
<p className="text-xs font-semibold text-green-600 uppercase tracking-wider mb-2">Suggested Actions</p>
<ul className="space-y-2">
{explanation.suggestedActions.map((action, i) => (
<li key={i} className="flex items-start gap-2 text-sm text-zinc-300">
<li key={`${action}-${i}`} className="flex items-start gap-2 text-sm text-zinc-300">
<span className="text-green-500 mt-0.5 flex-shrink-0"></span>
<span>{action}</span>
</li>