update sync data from site dashboard and testing closing cycles

This commit is contained in:
Alberto-Audrix committed 2026-09-15 16:52:41 +07:00
1 parent 36639d8c38
commit f49e72592c
42 files changed
+1966 -688

No files matched your search

+37 -2
View File
@@ -1,6 +1,7 @@
import React, { useEffect, useMemo, useRef, useState } from 'react';
import { useAuth } from '../context/AuthContext.tsx';
import { useFarm } from '../context/FarmContext.tsx';
import { api, errorMessage } from '../services/apiClient.ts';
import type { UserStatus } from '../types/api.ts';
import { formatDateId, resolveCycleStatus } from '../utils/format.ts';
@@ -22,6 +23,10 @@ type HeaderProps = {
onToggleTimeline: () => void;
};
function canMirrorSync(status?: UserStatus | string | null): boolean {
return status === 'gm' || status === 'gm_admin';
}
const Header: React.FC<HeaderProps> = ({
onToggleSidebar,
isTimelineVisible,
@@ -38,12 +43,15 @@ const Header: React.FC<HeaderProps> = ({
setSelectedSiteId,
setSelectedKandangId,
setSelectedCycleId,
reload: reloadFarm,
} = useFarm();
const [open, setOpen] = useState(false);
const [gmFilter, setGmFilter] = useState<'all' | number>('all');
const [syncing, setSyncing] = useState(false);
const dropdownRef = useRef<HTMLDivElement>(null);
const isBuh = user?.status === 'buh' || user?.status === 'bu_admin';
const showSync = canMirrorSync(user?.status);
const gmOptions = useMemo(() => {
const byId = new Map<number, string>();
@@ -81,6 +89,19 @@ const Header: React.FC<HeaderProps> = ({
return () => document.removeEventListener('mousedown', onClick);
}, []);
const handleMirrorSync = async () => {
setSyncing(true);
try {
await api.activeSites.syncAll();
await reloadFarm();
} catch (err) {
// Keep sync failures visible in the browser console; UI stays quiet.
console.error(errorMessage(err));
} finally {
setSyncing(false);
}
};
if (!user) return null;
return (
@@ -164,7 +185,21 @@ const Header: React.FC<HeaderProps> = ({
</select>
</div>
</div>
<div className="flex items-center ml-auto">
<div className="flex items-center ml-auto gap-2">
{showSync && (
<button
type="button"
onClick={() => void handleMirrorSync()}
disabled={syncing}
title="Sinkronkan data dari site dashboard"
className="inline-flex items-center gap-2 px-3 py-1.5 rounded-lg bg-red-600 text-white text-sm font-semibold hover:bg-red-700 disabled:opacity-60"
>
<i
className={`fa-solid ${syncing ? 'fa-spinner fa-spin' : 'fa-arrows-rotate'}`}
/>
<span className="hidden sm:inline">{syncing ? 'Sync...' : 'Sync'}</span>
</button>
)}
<button
onClick={onToggleTimeline}
title="Toggle Linimasa"
@@ -175,7 +210,7 @@ const Header: React.FC<HeaderProps> = ({
/>
</button>
<div className="relative ml-4" ref={dropdownRef}>
<div className="relative ml-2" ref={dropdownRef}>
<button
onClick={() => setOpen(!open)}
className="flex items-center space-x-2 focus:outline-none"