v0.12.35 UI fixes

This commit is contained in:
2026-03-28 14:18:20 -04:00
parent 76edd7abd1
commit d07d9e3919
6 changed files with 13 additions and 9 deletions

View File

@@ -1,6 +1,6 @@
{ {
"name": "rosterchirp-backend", "name": "rosterchirp-backend",
"version": "0.12.34", "version": "0.12.35",
"description": "RosterChirp backend server", "description": "RosterChirp backend server",
"main": "src/index.js", "main": "src/index.js",
"scripts": { "scripts": {

View File

@@ -13,7 +13,7 @@
# ───────────────────────────────────────────────────────────── # ─────────────────────────────────────────────────────────────
set -euo pipefail set -euo pipefail
VERSION="${1:-0.12.34}" VERSION="${1:-0.12.35}"
ACTION="${2:-}" ACTION="${2:-}"
REGISTRY="${REGISTRY:-}" REGISTRY="${REGISTRY:-}"
IMAGE_NAME="rosterchirp" IMAGE_NAME="rosterchirp"

View File

@@ -1,6 +1,6 @@
{ {
"name": "rosterchirp-frontend", "name": "rosterchirp-frontend",
"version": "0.12.34", "version": "0.12.35",
"private": true, "private": true,
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",

View File

@@ -475,7 +475,9 @@ export default function MobileEventForm({ event, eventTypes, userGroups, selecte
<button onClick={handle} disabled={saving} style={{ background:'var(--primary)',border:'none',cursor:'pointer',color:'white',borderRadius:20,padding:'8px 20px',fontSize:14,fontWeight:700,opacity:saving?0.6:1 }}>{saving?'…':'Save'}</button> <button onClick={handle} disabled={saving} style={{ background:'var(--primary)',border:'none',cursor:'pointer',color:'white',borderRadius:20,padding:'8px 20px',fontSize:14,fontWeight:700,opacity:saving?0.6:1 }}>{saving?'…':'Save'}</button>
</div> </div>
<div style={{ flex:1,overflowY:'auto' }}> {/* form wrapper suppresses Chrome Android's autofill chip bar; autoComplete="off"
on individual inputs is ignored by Chrome but respected on the form element */}
<form autoComplete="off" onSubmit={e => e.preventDefault()} style={{ flex:1,overflowY:'auto' }}>
{/* Title */} {/* Title */}
<div style={{ padding:'16px 20px',borderBottom:'1px solid var(--border)' }}> <div style={{ padding:'16px 20px',borderBottom:'1px solid var(--border)' }}>
<input value={title} onChange={e => setTitle(e.target.value)} autoComplete="off" placeholder="Add title" autoCorrect="off" autoCapitalize="sentences" spellCheck={false} style={{ width:'100%',border:'none',background:'transparent',fontSize:22,fontWeight:700,color:'var(--text-primary)',outline:'none' }}/> <input value={title} onChange={e => setTitle(e.target.value)} autoComplete="off" placeholder="Add title" autoCorrect="off" autoCapitalize="sentences" spellCheck={false} style={{ width:'100%',border:'none',background:'transparent',fontSize:22,fontWeight:700,color:'var(--text-primary)',outline:'none' }}/>
@@ -581,7 +583,7 @@ export default function MobileEventForm({ event, eventTypes, userGroups, selecte
<button onClick={()=>onDelete(event)} style={{ width:'100%',padding:'14px',border:'1px solid var(--error)',borderRadius:'var(--radius)',background:'transparent',color:'var(--error)',fontSize:15,fontWeight:600,cursor:'pointer' }}>Delete Event</button> <button onClick={()=>onDelete(event)} style={{ width:'100%',padding:'14px',border:'1px solid var(--error)',borderRadius:'var(--radius)',background:'transparent',color:'var(--error)',fontSize:15,fontWeight:600,cursor:'pointer' }}>Delete Event</button>
</div> </div>
)} )}
</div> </form>
{/* Overlays */} {/* Overlays */}
{showStartDate && <CalendarPicker value={sd} onChange={v=>{setSd(v);setShowStartDate(false);}} onClose={()=>setShowStartDate(false)}/>} {showStartDate && <CalendarPicker value={sd} onChange={v=>{setSd(v);setShowStartDate(false);}} onClose={()=>setShowStartDate(false)}/>}

View File

@@ -58,7 +58,7 @@ export default function NavDrawer({ open, onClose, onMessages, onGroupMessages,
{/* Close X */} {/* Close X */}
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 8 }}> <div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', marginBottom: 8 }}>
<div className="nav-drawer-section-label" style={{ margin: 0, padding: 0 }}>User Menu</div> <span style={{ fontWeight: 700, fontSize: 16, color: 'var(--text-primary)' }}>User Menu</span>
<button onClick={onClose} style={{ background: 'none', border: 'none', cursor: 'pointer', color: 'var(--text-secondary)', padding: 4, borderRadius: 6, display: 'flex', alignItems: 'center' }} aria-label="Close menu"> <button onClick={onClose} style={{ background: 'none', border: 'none', cursor: 'pointer', color: 'var(--text-secondary)', padding: 4, borderRadius: 6, display: 'flex', alignItems: 'center' }} aria-label="Close menu">
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg> <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2"><line x1="18" y1="6" x2="6" y2="18"/><line x1="6" y1="6" x2="18" y2="18"/></svg>
</button> </button>

View File

@@ -16,7 +16,9 @@ function useTheme() {
const PUSH_ENABLED_KEY = 'rc_push_enabled'; const PUSH_ENABLED_KEY = 'rc_push_enabled';
function usePushToggle() { function usePushToggle() {
// Push toggle is only relevant when the user has already granted permission // Show the toggle whenever the Notification API is present, not just when
// already granted — so iOS users (where push is still being set up) can still
// reach the toggle and trigger the permission request flow.
const supported = 'serviceWorker' in navigator && typeof Notification !== 'undefined'; const supported = 'serviceWorker' in navigator && typeof Notification !== 'undefined';
const permitted = supported && Notification.permission === 'granted'; const permitted = supported && Notification.permission === 'granted';
const [enabled, setEnabled] = useState(() => localStorage.getItem(PUSH_ENABLED_KEY) !== 'false'); const [enabled, setEnabled] = useState(() => localStorage.getItem(PUSH_ENABLED_KEY) !== 'false');
@@ -40,7 +42,7 @@ function usePushToggle() {
} }
}; };
return { permitted, enabled, toggle }; return { supported, permitted, enabled, toggle };
} }
// ── Debug helpers ───────────────────────────────────────────────────────────── // ── Debug helpers ─────────────────────────────────────────────────────────────
@@ -230,7 +232,7 @@ export default function UserFooter({ onProfile, onHelp, onAbout, mobileCompact=f
const { user, logout } = useAuth(); const { user, logout } = useAuth();
const [showMenu, setShowMenu] = useState(false); const [showMenu, setShowMenu] = useState(false);
const [dark, setDark] = useTheme(); const [dark, setDark] = useTheme();
const { permitted: showPushToggle, enabled: pushEnabled, toggle: togglePush } = usePushToggle(); const { supported: showPushToggle, enabled: pushEnabled, toggle: togglePush } = usePushToggle();
const menuRef = useRef(null); const menuRef = useRef(null);
const btnRef = useRef(null); const btnRef = useRef(null);
const [showConfirm, setShowConfirm] = useState(false); const [showConfirm, setShowConfirm] = useState(false);