fix: react-doctor rerender-state-only-in-handlers 37→5 (ref for handler-only state in QRScanModal, HeroSection, MessageLogPanel, FsmaReportModal, SettingsSections, TimeTrackingSettingsClient, OrderEditForm, ProductFormModal, ProductsClient, CampaignComposerPage, MatchingCustomersPanel, SegmentBuilderPanel, MessageCustomersSection, ShippingSettingsForm, StopEditForm, StopTableClient, TimeTrackingFieldClient, WaterFieldClient, UsersPage, LotCreateModal, LotDetailPanel, WholesaleClient, ContactImportForm, AdminOrdersPanel, TuxedoPage)
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
/* eslint-disable react-hooks/set-state-in-effect */
|
||||
|
||||
import { useState, useEffect, useCallback } from "react";
|
||||
import { useState, useEffect, useCallback, useRef } from "react";
|
||||
|
||||
function triggerDownload(url: string) {
|
||||
const a = document.createElement("a");
|
||||
@@ -98,7 +98,7 @@ export default function TimeTrackingSettingsClient({ brandId }: TimeTrackingSett
|
||||
|
||||
const [workers, setWorkers] = useState<TimeWorker[]>([]);
|
||||
const [tasks, setTasks] = useState<TimeTask[]>([]);
|
||||
const [settings, setSettings] = useState<TimeTrackingSettings | null>(null);
|
||||
const settingsRef = useRef<TimeTrackingSettings | null>(null);
|
||||
const [notificationLog, setNotificationLog] = useState<NotificationLogEntry[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
@@ -106,7 +106,7 @@ export default function TimeTrackingSettingsClient({ brandId }: TimeTrackingSett
|
||||
const [payPeriodLength, setPayPeriodLength] = useState(7);
|
||||
const [dailyOvertimeThreshold, setDailyOvertimeThreshold] = useState(12);
|
||||
const [weeklyOvertimeThreshold, setWeeklyOvertimeThreshold] = useState(56);
|
||||
const [overtimeMultiplier, setOvertimeMultiplier] = useState(1.5);
|
||||
const overtimeMultiplierRef = useRef(1.5);
|
||||
const [overtimeNotifications, setOvertimeNotifications] = useState(true);
|
||||
const [settingsSaving, setSettingsSaving] = useState(false);
|
||||
const [settingsSaved, setSettingsSaved] = useState(false);
|
||||
@@ -116,10 +116,10 @@ export default function TimeTrackingSettingsClient({ brandId }: TimeTrackingSett
|
||||
const [notificationSmsNumbers, setNotificationSmsNumbers] = useState<string[]>([]);
|
||||
const [enableDailyAlerts, setEnableDailyAlerts] = useState(true);
|
||||
const [enableWeeklyAlerts, setEnableWeeklyAlerts] = useState(true);
|
||||
const [dailyAlertThreshold, setDailyAlertThreshold] = useState(80);
|
||||
const [weeklyAlertThreshold, setWeeklyAlertThreshold] = useState(80);
|
||||
const [sendEndOfPeriodSummary, setSendEndOfPeriodSummary] = useState(true);
|
||||
const [brandName, setBrandName] = useState("Farm");
|
||||
const dailyAlertThresholdRef = useRef(80);
|
||||
const weeklyAlertThresholdRef = useRef(80);
|
||||
const sendEndOfPeriodSummaryRef = useRef(true);
|
||||
const brandNameRef = useRef("Farm");
|
||||
const [newEmail, setNewEmail] = useState("");
|
||||
const [newSms, setNewSms] = useState("");
|
||||
|
||||
@@ -151,23 +151,24 @@ export default function TimeTrackingSettingsClient({ brandId }: TimeTrackingSett
|
||||
// Track the previous settings object so we can sync form state
|
||||
// inline during render when fresh data arrives from the server
|
||||
// (avoids the stale-frame window a useEffect would introduce).
|
||||
const [prevSettings, setPrevSettings] = useState<TimeTrackingSettings | null>(null);
|
||||
if (settings && settings !== prevSettings) {
|
||||
setPrevSettings(settings);
|
||||
const prevSettingsRef = useRef<TimeTrackingSettings | null>(null);
|
||||
if (settingsRef.current && settingsRef.current !== prevSettingsRef.current) {
|
||||
const settings = settingsRef.current;
|
||||
prevSettingsRef.current = settings;
|
||||
setPayPeriodStartDay(settings.pay_period_start_day);
|
||||
setPayPeriodLength(settings.pay_period_length_days);
|
||||
setDailyOvertimeThreshold(settings.daily_overtime_threshold);
|
||||
setWeeklyOvertimeThreshold(settings.weekly_overtime_threshold);
|
||||
setOvertimeMultiplier(settings.overtime_multiplier);
|
||||
overtimeMultiplierRef.current = settings.overtime_multiplier;
|
||||
setOvertimeNotifications(settings.overtime_notifications);
|
||||
setNotificationEmails(settings.notification_emails ?? []);
|
||||
setNotificationSmsNumbers(settings.notification_sms_numbers ?? []);
|
||||
setEnableDailyAlerts(settings.enable_daily_alerts ?? true);
|
||||
setEnableWeeklyAlerts(settings.enable_weekly_alerts ?? true);
|
||||
setDailyAlertThreshold(Math.round((settings.daily_alert_threshold ?? 0.80) * 100));
|
||||
setWeeklyAlertThreshold(Math.round((settings.weekly_alert_threshold ?? 0.80) * 100));
|
||||
setSendEndOfPeriodSummary(settings.send_end_of_period_summary ?? true);
|
||||
setBrandName(settings.brand_name ?? "Farm");
|
||||
dailyAlertThresholdRef.current = Math.round((settings.daily_alert_threshold ?? 0.80) * 100);
|
||||
weeklyAlertThresholdRef.current = Math.round((settings.weekly_alert_threshold ?? 0.80) * 100);
|
||||
sendEndOfPeriodSummaryRef.current = settings.send_end_of_period_summary ?? true;
|
||||
brandNameRef.current = settings.brand_name ?? "Farm";
|
||||
}
|
||||
|
||||
const load = useCallback(async () => {
|
||||
@@ -179,7 +180,7 @@ export default function TimeTrackingSettingsClient({ brandId }: TimeTrackingSett
|
||||
]);
|
||||
setWorkers(w);
|
||||
setTasks(t);
|
||||
setSettings(s);
|
||||
settingsRef.current = s;
|
||||
const log = await getTimeTrackingNotificationLog(brandId, 50);
|
||||
setNotificationLog(log);
|
||||
setLoading(false);
|
||||
@@ -198,16 +199,16 @@ export default function TimeTrackingSettingsClient({ brandId }: TimeTrackingSett
|
||||
pay_period_length_days: payPeriodLength,
|
||||
daily_overtime_threshold: dailyOvertimeThreshold,
|
||||
weekly_overtime_threshold: weeklyOvertimeThreshold,
|
||||
overtime_multiplier: overtimeMultiplier,
|
||||
overtime_multiplier: overtimeMultiplierRef.current,
|
||||
overtime_notifications: overtimeNotifications,
|
||||
notification_emails: notificationEmails,
|
||||
notification_sms_numbers: notificationSmsNumbers,
|
||||
enable_daily_alerts: enableDailyAlerts,
|
||||
enable_weekly_alerts: enableWeeklyAlerts,
|
||||
daily_alert_threshold: dailyAlertThreshold / 100,
|
||||
weekly_alert_threshold: weeklyAlertThreshold / 100,
|
||||
send_end_of_period_summary: sendEndOfPeriodSummary,
|
||||
brand_name: brandName,
|
||||
daily_alert_threshold: dailyAlertThresholdRef.current / 100,
|
||||
weekly_alert_threshold: weeklyAlertThresholdRef.current / 100,
|
||||
send_end_of_period_summary: sendEndOfPeriodSummaryRef.current,
|
||||
brand_name: brandNameRef.current,
|
||||
});
|
||||
setSettingsSaving(false);
|
||||
if (!result.success) { setSettingsError(result.error ?? "Failed to save"); return; }
|
||||
|
||||
Reference in New Issue
Block a user