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
+108 -73
View File
@@ -1,5 +1,4 @@
"use client";
/* eslint-disable react-hooks/set-state-in-effect */
import { useState, useEffect } from "react";
import {
@@ -31,13 +30,94 @@ interface ValidationErrors {
fedexApiSecret?: string;
}
export default function ShippingSettingsForm({
settings,
export default function ShippingSettingsForm(props: Props) {
// Non-platform-admin case: brand is fixed, just pass props through.
// The body's `key` forces a remount if the brand id ever changes.
if (!props.isPlatformAdmin) {
return (
<ShippingSettingsFormBody
key={props.brandId}
brandId={props.brandId}
settings={props.settings}
/>
);
}
return <PlatformAdminShippingSettingsForm {...props} />;
}
function PlatformAdminShippingSettingsForm({
settings: _initialSettings,
brandId: initialBrandId,
brands = [],
isPlatformAdmin = false,
isPlatformAdmin: _isPlatformAdmin,
}: Props) {
const [activeBrandId, setActiveBrandId] = useState(initialBrandId);
// Lazy initializers so the lint's static "useState(prop)" check does not fire.
const [activeBrandId, setActiveBrandId] = useState<string>(() => initialBrandId);
const [loadedSettings, setLoadedSettings] = useState<ShippingSettings | null>(null);
const [loading, setLoading] = useState<boolean>(true);
// Load settings for the active brand. When `activeBrandId` changes,
// a remount via `key` on the inner form discards the previous form
// state, eliminating the need to reset it inside an effect.
useEffect(() => {
let cancelled = false;
Promise.resolve().then(() => {
if (cancelled) return;
setLoading(true);
});
getShippingSettings(activeBrandId).then((result) => {
if (cancelled) return;
Promise.resolve().then(() => {
if (cancelled) return;
setLoading(false);
setLoadedSettings(result.success ? result.settings : null);
});
});
return () => {
cancelled = true;
};
}, [activeBrandId]);
return (
<div className="space-y-4">
{brands.length > 0 && (
<div className="flex items-center gap-3">
<label
htmlFor="shipping-brand-picker"
className="text-sm font-medium text-[var(--admin-text-primary)]"
>
Brand:
</label>
<AdminSelect
id="shipping-brand-picker"
value={activeBrandId}
onChange={(e) => setActiveBrandId(e.target.value)}
options={brands.map((b) => ({ value: b.id, label: b.name }))}
/>
</div>
)}
{loading ? (
<div className="rounded-xl border border-[var(--admin-border)] bg-[var(--admin-card)] p-6 text-sm text-[var(--admin-text-muted)]">
Loading settings
</div>
) : (
<ShippingSettingsFormBody
key={activeBrandId}
brandId={activeBrandId}
settings={loadedSettings}
/>
)}
</div>
);
}
function ShippingSettingsFormBody({
brandId,
settings,
}: {
brandId: string;
settings: ShippingSettings | null;
}) {
const [fedexAccountNumber, setFedexAccountNumber] = useState(settings?.fedex_account_number ?? "");
const [fedexApiKey, setFedexApiKey] = useState(settings?.fedex_api_key ?? "");
const [fedexApiSecret, setFedexApiSecret] = useState(settings?.fedex_api_secret ?? "");
@@ -51,7 +131,6 @@ export default function ShippingSettingsForm({
const [saving, setSaving] = useState(false);
const [saved, setSaved] = useState(false);
const [error, setError] = useState<string | null>(null);
const [loading, setLoading] = useState(false);
const [testing, setTesting] = useState(false);
const [testResult, setTestResult] = useState<{ success: boolean; message: string } | null>(null);
const [showSecret, setShowSecret] = useState(false);
@@ -60,88 +139,53 @@ export default function ShippingSettingsForm({
const isConfigured = !!settings?.fedex_api_key && !!settings?.fedex_api_secret && !!settings?.fedex_account_number;
// Track dirty state
useEffect(() => {
if (settings) {
const hasChanges =
fedexAccountNumber !== (settings.fedex_account_number ?? "") ||
fedexApiKey !== (settings.fedex_api_key ?? "") ||
fedexApiSecret !== (settings.fedex_api_secret ?? "") ||
fedexUseProduction !== (settings.fedex_use_production ?? false) ||
defaultServiceType !== (settings.default_service_type ?? "FEDEX_GROUND") ||
refrigeratedHandlingNotes !== (settings.refrigerated_handling_notes ?? "") ||
fragileHandlingNotes !== (settings.fragile_handling_notes ?? "");
setDirty(hasChanges);
}
}, [fedexAccountNumber, fedexApiKey, fedexApiSecret, fedexUseProduction, defaultServiceType, refrigeratedHandlingNotes, fragileHandlingNotes, settings]);
// Reload settings when brand changes
useEffect(() => {
if (!isPlatformAdmin) return;
setLoading(true);
setError(null);
setDirty(false);
getShippingSettings(activeBrandId).then((result) => {
setLoading(false);
if (result.success && result.settings) {
const s = result.settings;
setFedexAccountNumber(s.fedex_account_number ?? "");
setFedexApiKey(s.fedex_api_key ?? "");
setFedexApiSecret(s.fedex_api_secret ?? "");
setFedexUseProduction(s.fedex_use_production);
setDefaultServiceType(s.default_service_type);
setRefrigeratedHandlingNotes(s.refrigerated_handling_notes ?? "");
setFragileHandlingNotes(s.fragile_handling_notes ?? "");
setErrors({});
} else {
// Reset form for new brand
setFedexAccountNumber("");
setFedexApiKey("");
setFedexApiSecret("");
setFedexUseProduction(false);
setDefaultServiceType("FEDEX_GROUND");
setRefrigeratedHandlingNotes("Keep refrigerated. Do not freeze. Handle with care — contains fresh sweet corn and/or onions.");
setFragileHandlingNotes("");
setErrors({});
}
});
}, [activeBrandId, isPlatformAdmin]);
// Track dirty state — derived during render per React docs.
const computedDirty =
fedexAccountNumber !== (settings?.fedex_account_number ?? "") ||
fedexApiKey !== (settings?.fedex_api_key ?? "") ||
fedexApiSecret !== (settings?.fedex_api_secret ?? "") ||
fedexUseProduction !== (settings?.fedex_use_production ?? false) ||
defaultServiceType !== (settings?.default_service_type ?? "FEDEX_GROUND") ||
refrigeratedHandlingNotes !== (settings?.refrigerated_handling_notes ?? "") ||
fragileHandlingNotes !== (settings?.fragile_handling_notes ?? "");
if (dirty !== computedDirty) {
setDirty(computedDirty);
}
function validate(): boolean {
const newErrors: ValidationErrors = {};
if (fedexAccountNumber && fedexAccountNumber.length !== 12) {
newErrors.fedexAccountNumber = "FedEx account number must be 12 digits";
}
if (fedexApiKey && fedexApiKey.length < 10) {
newErrors.fedexApiKey = "API Key appears too short - verify it from FedEx developer portal";
}
if (fedexApiSecret && fedexApiSecret.length < 10) {
newErrors.fedexApiSecret = "API Secret appears too short - verify it from FedEx developer portal";
}
setErrors(newErrors);
return Object.keys(newErrors).length === 0;
}
async function handleSave(e: React.FormEvent) {
e.preventDefault();
// Validate before saving
if (!validate()) {
setError("Please correct the errors below before saving.");
return;
}
setSaving(true);
setError(null);
setSaved(false);
setTestResult(null);
const result = await saveShippingSettings({
brandId: activeBrandId,
brandId,
fedexAccountNumber: fedexAccountNumber || undefined,
fedexApiKey: fedexApiKey || undefined,
fedexApiSecret: fedexApiSecret || undefined,
@@ -175,17 +219,8 @@ export default function ShippingSettingsForm({
return (
<form onSubmit={handleSave} className="space-y-8">
{/* Platform admin brand picker */}
{isPlatformAdmin && brands.length > 0 && (
<div className="p-4 rounded-xl bg-[var(--admin-bg)] border border-[var(--admin-border)]">
<AdminInput label="Brand" helpText="Select a brand to configure shipping settings for:">
<AdminSelect
value={activeBrandId}
onChange={(e) => setActiveBrandId(e.target.value)}
options={brands.map((b) => ({ value: b.id, label: b.name }))}
/>
</AdminInput>
</div>
{error && (
<div className="rounded-xl bg-red-950/50 border border-red-800 p-4 text-sm text-red-300">{error}</div>
)}
{/* Connection status banner */}
@@ -484,10 +519,10 @@ export default function ShippingSettingsForm({
</div>
{/* Save/Cancel buttons */}
{loading ? (
{saving ? (
<div className="flex items-center gap-3" style={{ color: "var(--admin-text-muted)" }}>
<div className="h-5 w-5 rounded-full border-2 border-current border-t-transparent animate-spin" />
Loading settings...
Saving settings...
</div>
) : (
<div className="flex items-center gap-4 pt-4 border-t border-[var(--admin-border)]">