Task #745: allow collapsing sidebar groups even when a child tab is active

- protocol.tsx: `open` for roomsGroup/gifts group now follows only the
  user-controlled state (roomsGroupOpen/giftsGroupOpen) instead of
  `...Open || groupActive`, so the chevron actually collapses the group
  while you're inside one of its tabs (e.g. «الإعدادات»).
- Added a useEffect on `tab` that auto-opens the containing group when
  the active tab becomes one of its children (initial load, deep link,
  or tab switch), so the active item is never hidden unintentionally.
- Group header keeps its text-sky-600 highlight when collapsed with an
  active child (existing styling, unchanged).
- tx-os tsc clean; architect review passed.
This commit is contained in:
Replit Agent
2026-07-09 10:19:31 +00:00
parent f257009130
commit 36a723d47e
+17 -2
View File
@@ -884,6 +884,21 @@ export default function ProtocolPage() {
const [roomsGroupOpen, setRoomsGroupOpen] = useState(false); const [roomsGroupOpen, setRoomsGroupOpen] = useState(false);
const [menuOpen, setMenuOpen] = useState(true); const [menuOpen, setMenuOpen] = useState(true);
// Auto-open the sidebar group containing the active tab (initial load or
// deep link), while still letting the user collapse it manually afterwards.
useEffect(() => {
if (
tab === "roomsDashboard" ||
tab === "rooms" ||
tab === "bookings" ||
tab === "bookingSettings"
) {
setRoomsGroupOpen(true);
} else if (tab === "gifts" || tab === "issues") {
setGiftsGroupOpen(true);
}
}, [tab]);
const bookingAction = useMutation({ const bookingAction = useMutation({
mutationFn: (args: { id: number; action: "approve" | "cancel" }) => mutationFn: (args: { id: number; action: "approve" | "cancel" }) =>
apiJson(`${API}/protocol/bookings/${args.id}/${args.action}`, { apiJson(`${API}/protocol/bookings/${args.id}/${args.action}`, {
@@ -1466,7 +1481,7 @@ export default function ProtocolPage() {
x.key === "bookingSettings", x.key === "bookingSettings",
); );
const groupActive = children.some((x) => x.key === tab); const groupActive = children.some((x) => x.key === tab);
const open = roomsGroupOpen || groupActive; const open = roomsGroupOpen;
return ( return (
<div key="roomsGroup" className="flex md:flex-col gap-1"> <div key="roomsGroup" className="flex md:flex-col gap-1">
<button <button
@@ -1517,7 +1532,7 @@ export default function ProtocolPage() {
(x) => x.key === "gifts" || x.key === "issues", (x) => x.key === "gifts" || x.key === "issues",
); );
const groupActive = children.some((x) => x.key === tab); const groupActive = children.some((x) => x.key === tab);
const open = giftsGroupOpen || groupActive; const open = giftsGroupOpen;
return ( return (
<div key="giftsGroup" className="flex md:flex-col gap-1"> <div key="giftsGroup" className="flex md:flex-col gap-1">
<button <button