From 3d3e8068db6d27847564774fc700a14ca26cc681 Mon Sep 17 00:00:00 2001 From: Ricky Stretch Date: Wed, 18 Mar 2026 10:14:05 -0400 Subject: [PATCH] v0.9.66 minor bug fixes --- .env.example | 2 +- backend/package.json | 2 +- build.sh | 2 +- frontend/package.json | 2 +- frontend/src/components/SchedulePage.jsx | 29 ++++++++++++++++++++---- frontend/src/components/UserFooter.jsx | 22 +++++++++++++++++- 6 files changed, 49 insertions(+), 10 deletions(-) diff --git a/.env.example b/.env.example index 82902b4..9767565 100644 --- a/.env.example +++ b/.env.example @@ -10,7 +10,7 @@ PROJECT_NAME=jama # Image version to run (set by build.sh, or use 'latest') -JAMA_VERSION=0.9.66 +JAMA_VERSION=0.9.67 # App port — the host port Docker maps to the container PORT=3000 diff --git a/backend/package.json b/backend/package.json index c07ec8d..e12722d 100644 --- a/backend/package.json +++ b/backend/package.json @@ -1,6 +1,6 @@ { "name": "jama-backend", - "version": "0.9.66", + "version": "0.9.67", "description": "TeamChat backend server", "main": "src/index.js", "scripts": { diff --git a/build.sh b/build.sh index 5fedb73..b752455 100644 --- a/build.sh +++ b/build.sh @@ -13,7 +13,7 @@ # ───────────────────────────────────────────────────────────── set -euo pipefail -VERSION="${1:-0.9.66}" +VERSION="${1:-0.9.67}" ACTION="${2:-}" REGISTRY="${REGISTRY:-}" IMAGE_NAME="jama" diff --git a/frontend/package.json b/frontend/package.json index 28c13b3..889e525 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -1,6 +1,6 @@ { "name": "jama-frontend", - "version": "0.9.66", + "version": "0.9.67", "private": true, "scripts": { "dev": "vite", diff --git a/frontend/src/components/SchedulePage.jsx b/frontend/src/components/SchedulePage.jsx index db6313c..3a0c0c0 100644 --- a/frontend/src/components/SchedulePage.jsx +++ b/frontend/src/components/SchedulePage.jsx @@ -610,7 +610,7 @@ function BulkImportPanel({ onImported, onCancel }) { } // ── Calendar Views ──────────────────────────────────────────────────────────── -function ScheduleView({ events, selectedDate, onSelect, filterKeyword='', filterTypeId='' }) { +function ScheduleView({ events, selectedDate, onSelect, filterKeyword='', filterTypeId='', isMobile=false }) { const y=selectedDate.getFullYear(), m=selectedDate.getMonth(); const monthStart=new Date(y,m,1), monthEnd=new Date(y,m+1,0,23,59,59); const kw=filterKeyword.toLowerCase().trim(); @@ -624,7 +624,15 @@ function ScheduleView({ events, selectedDate, onSelect, filterKeyword='', filter return true; }); if(!filtered.length) return
{kw||filterTypeId?'No events match your filters':'No events in'} {!kw&&!filterTypeId&&`${MONTHS[m]} ${y}`}
; - return <>{filtered.map(e=>{const s=new Date(e.start_at);const col=e.event_type?.colour||'#9ca3af';return(
onSelect(e)} style={{display:'flex',alignItems:'center',gap:10,padding:'12px 14px',borderBottom:'1px solid var(--border)',cursor:'pointer'}} onMouseEnter={el=>el.currentTarget.style.background='var(--background)'} onMouseLeave={el=>el.currentTarget.style.background=''}>
{s.getDate()}
{SHORT_MONTHS[s.getMonth()]}, {DAYS[s.getDay()]}
{e.all_day?All day:{fmtTime(e.start_at)} –
{fmtTime(e.end_at)}
}
{e.event_type?.name&&{e.event_type.name}:}{e.title}{!!e.track_availability&&( + return <>{filtered.map(e=>{const s=new Date(e.start_at);const col=e.event_type?.colour||'#9ca3af'; + // Desktop: original pre-v0.9.64 sizes. Mobile: compact sizes from v0.9.64 + const rowPad=isMobile?'12px 14px':'14px 20px'; + const rowGap=isMobile?10:20; + const datW=isMobile?36:44; const datFs=isMobile?20:22; const datSFs=isMobile?10:11; + const timeW=isMobile?62:100; const timeGap=isMobile?5:8; const timeFs=isMobile?11:13; + const dotSz=isMobile?8:10; + const typeFs=isMobile?10:11; const titleGap=isMobile?6:8; + return(
onSelect(e)} style={{display:'flex',alignItems:'center',gap:rowGap,padding:rowPad,borderBottom:'1px solid var(--border)',cursor:'pointer'}} onMouseEnter={el=>el.currentTarget.style.background='var(--background)'} onMouseLeave={el=>el.currentTarget.style.background=''}>
{s.getDate()}
{SHORT_MONTHS[s.getMonth()]}, {DAYS[s.getDay()]}
{e.all_day?All day:{fmtTime(e.start_at)} –
{fmtTime(e.end_at)}
}
{e.event_type?.name&&{e.event_type.name}:}{e.title}{!!e.track_availability&&( e.my_response ? RESP_ICON[e.my_response](RESP_COLOR[e.my_response]) : BELL_ICON )}
{e.location&&
{e.location}
}
);})}; } @@ -885,7 +893,14 @@ export default function SchedulePage({ isToolManager, isMobile, onProfile, onHel const handleSaved = () => { load(); setPanel('calendar'); setEditingEvent(null); }; const handleDelete = async e => { if (!confirm(`Delete "${e.title}"?`)) return; - try { await api.deleteEvent(e.id); toast('Deleted','success'); load(); setDetailEvent(null); } catch(err) { toast(err.message,'error'); } + try { + await api.deleteEvent(e.id); + toast('Deleted','success'); + setPanel('calendar'); + setEditingEvent(null); + setDetailEvent(null); + load(); // reload list so deleted event disappears immediately + } catch(err) { toast(err.message,'error'); } }; if (loading) return
Loading schedule…
; @@ -969,7 +984,11 @@ export default function SchedulePage({ isToolManager, isMobile, onProfile, onHel
{/* Mobile title + create */} {isMobile && ( - Team Schedule + <> + Team Schedule + {/* User footer trigger on mobile — compact avatar button */} + + )} {!isMobile && ( @@ -1004,7 +1023,7 @@ export default function SchedulePage({ isToolManager, isMobile, onProfile, onHel {/* Calendar or panel content */}
- {panel === 'calendar' && view === 'schedule' && } + {panel === 'calendar' && view === 'schedule' && } {panel === 'calendar' && view === 'day' && } {panel === 'calendar' && view === 'week' && } {panel === 'calendar' && view === 'month' && {setSelDate(d);setView('schedule');}}/>} diff --git a/frontend/src/components/UserFooter.jsx b/frontend/src/components/UserFooter.jsx index be917dd..f620fb4 100644 --- a/frontend/src/components/UserFooter.jsx +++ b/frontend/src/components/UserFooter.jsx @@ -11,7 +11,7 @@ function useTheme() { return [dark, setDark]; } -export default function UserFooter({ onProfile, onHelp, onAbout }) { +export default function UserFooter({ onProfile, onHelp, onAbout, mobileCompact=false }) { const { user, logout } = useAuth(); const [showMenu, setShowMenu] = useState(false); const [dark, setDark] = useTheme(); @@ -32,6 +32,26 @@ export default function UserFooter({ onProfile, onHelp, onAbout }) { const handleLogout = async () => { await logout(); }; + if (mobileCompact) return ( +
+ + {showMenu && ( +
+
{user?.display_name||user?.name}
+ {[['Profile',()=>{setShowMenu(false);onProfile?.();}],['Help',()=>{setShowMenu(false);onHelp?.();}],['About',()=>{setShowMenu(false);onAbout?.();}]].map(([label,action])=>( + + ))} +
+ +
+
+ )} +
+ ); + return (