From d22ef70f7437209ea1165dd6bcfccbff5d71a9cd Mon Sep 17 00:00:00 2001 From: "PC-20260115JRSN\\Administrator" Date: Sun, 4 Oct 2026 14:34:13 +0800 Subject: [PATCH] =?UTF-8?q?=E7=99=BC=E8=B2=A8=E8=88=87=E9=85=8D=E9=80=81>?= =?UTF-8?q?=E5=93=A1=E5=B7=A5=E7=99=BC=E8=B2=A8=E7=B8=BE=E6=95=88=20added?= =?UTF-8?q?=20a=20new=20access=20right=20=E7=B8=BE=E6=95=88?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/app/(main)/chart/delivery/page.tsx | 19 +++++++++++++++++-- src/authorities.ts | 2 ++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/src/app/(main)/chart/delivery/page.tsx b/src/app/(main)/chart/delivery/page.tsx index bbbf3bb8..4cc04524 100644 --- a/src/app/(main)/chart/delivery/page.tsx +++ b/src/app/(main)/chart/delivery/page.tsx @@ -1,6 +1,8 @@ "use client"; import React, { useCallback, useMemo, useState } from "react"; +import { useSession } from "next-auth/react"; +import { AUTH, hasAbility } from "@/authorities"; import { Box, Typography, @@ -68,6 +70,9 @@ const defaultCriteria: Criteria = { /** FP-MTMS Version Checklist | Functions Ref. No. 61 | v1.0.0 | 2026-08-10 */ export default function DeliveryChartPage() { + const { data: session } = useSession(); + const abilities = session?.abilities ?? session?.user?.abilities ?? []; + const canSeeStaffPerformance = hasAbility(abilities, AUTH.PERFORMANCE); const [criteria, setCriteria] = useState(defaultCriteria); const [topItemsSelected, setTopItemsSelected] = useState([]); const [topItemOptions, setTopItemOptions] = useState([]); @@ -132,6 +137,10 @@ export default function DeliveryChartPage() { }, [criteria.topItems, topItemsSelected, setChartLoading]); React.useEffect(() => { + if (!canSeeStaffPerformance) { + setChartData((prev) => ({ ...prev, staffPerf: [] })); + return; + } const s = criteria.staffPerf.startDate; const e = criteria.staffPerf.endDate; if (!s || !e) { @@ -161,13 +170,17 @@ export default function DeliveryChartPage() { ) .catch((err) => setError(err instanceof Error ? err.message : "Request failed")) .finally(() => setChartLoading("staffPerf", false)); - }, [criteria.staffPerf, staffSelected, setChartLoading]); + }, [canSeeStaffPerformance, criteria.staffPerf, staffSelected, setChartLoading]); React.useEffect(() => { + if (!canSeeStaffPerformance) { + setStaffOptions([]); + return; + } fetchStaffDeliveryPerformanceHandlers() .then(setStaffOptions) .catch(() => setStaffOptions([])); - }, []); + }, [canSeeStaffPerformance]); React.useEffect(() => { const { startDate: s, endDate: e } = toDateRange(criteria.topItems.rangeDays); fetchTopDeliveryItemsItemOptions(s, e).then(setTopItemOptions).catch(() => setTopItemOptions([])); @@ -317,6 +330,7 @@ export default function DeliveryChartPage() { )} + {canSeeStaffPerformance && ( )} + )} ); } diff --git a/src/authorities.ts b/src/authorities.ts index 12747b66..b601e86f 100644 --- a/src/authorities.ts +++ b/src/authorities.ts @@ -29,6 +29,8 @@ export const AUTH = { M18_SYNC: "M18_SYNC", /** Route board (/settings/shop/board): ADMIN or this ability (DB name: 車線) */ TRUCK_LANE: "TRUCK_LANE", + /** 員工發貨績效 on /chart/delivery (DB name: 績效) */ + PERFORMANCE: "PERFORMANCE", } as const; /**