v0.12.35 UI fixes
This commit is contained in:
@@ -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": {
|
||||||
|
|||||||
2
build.sh
2
build.sh
@@ -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"
|
||||||
|
|||||||
@@ -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",
|
||||||
|
|||||||
@@ -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)}/>}
|
||||||
|
|||||||
@@ -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>
|
||||||
|
|||||||
@@ -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);
|
||||||
|
|||||||
Reference in New Issue
Block a user