From 65e7cc4007d23bd3ba756197e8da21cf370aed57 Mon Sep 17 00:00:00 2001 From: Ricky Stretch Date: Tue, 24 Mar 2026 13:08:30 -0400 Subject: [PATCH] v0.12.21 adjusted mobile group manager ui --- backend/package.json | 2 +- build.sh | 2 +- frontend/package.json | 2 +- frontend/src/pages/GroupManagerPage.jsx | 245 +++++++++++++++++------- 4 files changed, 183 insertions(+), 68 deletions(-) diff --git a/backend/package.json b/backend/package.json index 8c9f05f..ca1c9a7 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,6 +1,6 @@ { "name": "rosterchirp-backend", - "version": "0.12.20", + "version": "0.12.21", "description": "RosterChirp backend server", "main": "src/index.js", "scripts": { diff --git a/build.sh b/build.sh index 8526633..94d4611 100644 --- a/build.sh +++ b/build.sh @@ -13,7 +13,7 @@ # ───────────────────────────────────────────────────────────── set -euo pipefail -VERSION="${1:-0.12.20}" +VERSION="${1:-0.12.21}" ACTION="${2:-}" REGISTRY="${REGISTRY:-}" IMAGE_NAME="rosterchirp" diff --git a/frontend/package.json b/frontend/package.json index cad5604..01c41c0 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "rosterchirp-frontend", - "version": "0.12.20", + "version": "0.12.21", "private": true, "scripts": { "dev": "vite", diff --git a/frontend/src/pages/GroupManagerPage.jsx b/frontend/src/pages/GroupManagerPage.jsx index 20c1eb8..b3ee0bd 100644 --- a/frontend/src/pages/GroupManagerPage.jsx +++ b/frontend/src/pages/GroupManagerPage.jsx @@ -72,6 +72,7 @@ function AllGroupsTab({ allUsers, onRefresh, isMobile = false, onIF, onIB }) { const [saving, setSaving] = useState(false); const [deleting, setDeleting] = useState(false); const [showDelete, setShowDelete] = useState(false); + const [accordionOpen, setAccordionOpen] = useState(false); const load = useCallback(() => api.getUserGroups().then(({ groups }) => setGroups([...(groups||[])].sort((a, b) => a.name.localeCompare(b.name)))).catch(() => {}), []); @@ -79,6 +80,7 @@ function AllGroupsTab({ allUsers, onRefresh, isMobile = false, onIF, onIB }) { const selectGroup = async (g) => { setShowDelete(false); + setAccordionOpen(false); const { members: mems } = await api.getUserGroup(g.id); const ids = new Set(mems.map(m => m.id)); setSelected(g); setEditName(g.name); setMembers(ids); setSavedMembers(ids); @@ -141,24 +143,58 @@ function AllGroupsTab({ allUsers, onRefresh, isMobile = false, onIF, onIB }) { return (
- {/* Sidebar list */} -
-
User Groups
- - {groups.map(g => ( - + {groups.map(g => ( + + ))} + {groups.length===0 &&
No groups yet
} +
+ )} + + {/* Mobile accordion */} + {isMobile && ( +
+ + - ))} - {groups.length===0 &&
No groups yet
} -
+ {accordionOpen && ( +
+ {groups.map(g => ( + + ))} + {groups.length===0 &&
No groups yet
} +
+ )} +
+ )} {/* Form */}
@@ -238,6 +274,7 @@ function DirectMessagesTab({ allUserGroups, onRefresh, refreshKey, isMobile = fa const [saving, setSaving] = useState(false); const [deleting, setDeleting] = useState(false); const [showDelete, setShowDelete] = useState(false); + const [accordionOpen, setAccordionOpen] = useState(false); const load = useCallback(() => api.getMultiGroupDms().then(({ dms }) => setDms([...(dms||[])].sort((a, b) => a.name.localeCompare(b.name)))).catch(() => {}), []); @@ -245,7 +282,7 @@ function DirectMessagesTab({ allUserGroups, onRefresh, refreshKey, isMobile = fa const clearSelection = () => { setSelected(null); setDmName(''); setGroupIds(new Set()); setSavedGroupIds(new Set()); setShowDelete(false); }; const selectDm = (dm) => { - setShowDelete(false); setSelected(dm); setDmName(dm.name); + setShowDelete(false); setAccordionOpen(false); setSelected(dm); setDmName(dm.name); const ids = new Set(dm.memberGroupIds||[]); setGroupIds(ids); setSavedGroupIds(ids); }; @@ -282,23 +319,59 @@ function DirectMessagesTab({ allUserGroups, onRefresh, refreshKey, isMobile = fa return (
-
-
Multi-Group DMs
- - {dms.map(dm => ( - + {dms.map(dm => ( + + ))} + {dms.length===0 &&
No multi-group DMs yet
} +
+ )} + + {/* Mobile accordion */} + {isMobile && ( +
+ + - ))} - {dms.length===0 &&
No multi-group DMs yet
} -
+ {accordionOpen && ( +
+ {dms.map(dm => ( + + ))} + {dms.length===0 &&
No multi-group DMs yet
} +
+ )} +
+ )} +
@@ -345,6 +418,7 @@ function U2URestrictionsTab({ allUserGroups, isMobile = false, onIF, onIB }) { const [loading, setLoading] = useState(false); const [saving, setSaving] = useState(false); const [search, setSearch] = useState(''); + const [accordionOpen, setAccordionOpen] = useState(true); // Map of groupId → number of restrictions (for showing dots in sidebar) const [restrictionCounts, setRestrictionCounts] = useState({}); @@ -376,6 +450,7 @@ function U2URestrictionsTab({ allUserGroups, isMobile = false, onIF, onIB }) { const selectGroup = (g) => { setSelectedGroup(g); setSearch(''); + setAccordionOpen(false); loadRestrictions(g); }; @@ -413,40 +488,80 @@ function U2URestrictionsTab({ allUserGroups, isMobile = false, onIF, onIB }) { ? otherGroups.filter(g => g.name.toLowerCase().includes(search.toLowerCase())) : otherGroups; + const u2uGroupButton = (g) => { + const hasRestrictions = g.id === selectedGroup?.id ? blockedIds.size > 0 : (restrictionCounts[g.id] || 0) > 0; + return ( + + ); + }; + return (
- {/* Group selector sidebar */} -
-
- Select Group + + {/* Group selector — desktop sidebar */} + {!isMobile && ( +
+
+ Select Group +
+ {allUserGroups.map(g => u2uGroupButton(g))} + {allUserGroups.length === 0 && ( +
No user groups yet
+ )}
- {allUserGroups.map(g => { - const hasRestrictions = g.id === selectedGroup?.id ? blockedIds.size > 0 : (restrictionCounts[g.id] || 0) > 0; - return ( - - ); - })} - {allUserGroups.length === 0 && ( -
No user groups yet
- )} -
+ )} + + {/* Mobile accordion — expanded by default, collapses on selection */} + {isMobile && ( +
+ + {accordionOpen && ( +
+ {allUserGroups.map(g => { + const hasRestrictions = g.id === selectedGroup?.id ? blockedIds.size > 0 : (restrictionCounts[g.id] || 0) > 0; + return ( + + ); + })} + {allUserGroups.length === 0 &&
No user groups yet
} +
+ )} +
+ )} {/* Restriction editor */}