diff --git a/.env.example b/.env.example
index bfc6d3c..175dc68 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.80
+JAMA_VERSION=0.9.81
# App port — the host port Docker maps to the container
PORT=3000
diff --git a/backend/package.json b/backend/package.json
index 672e439..c379b3e 100644
--- a/backend/package.json
+++ b/backend/package.json
@@ -1,6 +1,6 @@
{
"name": "jama-backend",
- "version": "0.9.80",
+ "version": "0.9.81",
"description": "TeamChat backend server",
"main": "src/index.js",
"scripts": {
diff --git a/build.sh b/build.sh
index c41386c..81a224e 100644
--- a/build.sh
+++ b/build.sh
@@ -13,7 +13,7 @@
# ─────────────────────────────────────────────────────────────
set -euo pipefail
-VERSION="${1:-0.9.80}"
+VERSION="${1:-0.9.81}"
ACTION="${2:-}"
REGISTRY="${REGISTRY:-}"
IMAGE_NAME="jama"
diff --git a/frontend/package.json b/frontend/package.json
index 85be1a0..d45ae84 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -1,6 +1,6 @@
{
"name": "jama-frontend",
- "version": "0.9.80",
+ "version": "0.9.81",
"private": true,
"scripts": {
"dev": "vite",
diff --git a/frontend/src/components/MobileEventForm.jsx b/frontend/src/components/MobileEventForm.jsx
index f37a771..c888892 100644
--- a/frontend/src/components/MobileEventForm.jsx
+++ b/frontend/src/components/MobileEventForm.jsx
@@ -277,7 +277,7 @@ export default function MobileEventForm({ event, eventTypes, userGroups, selecte
{/* Title */}
- setTitle(e.target.value)} placeholder="Add title" style={{ width:'100%',border:'none',background:'transparent',fontSize:22,fontWeight:700,color:'var(--text-primary)',outline:'none' }}/>
+ setTitle(e.target.value)} placeholder="Add title" autoComplete="off" autoCorrect="off" autoCapitalize="sentences" spellCheck={false} style={{ width:'100%',border:'none',background:'transparent',fontSize:22,fontWeight:700,color:'var(--text-primary)',outline:'none' }}/>
{/* Event Type */}
@@ -359,12 +359,12 @@ export default function MobileEventForm({ event, eventTypes, userGroups, selecte
{/* Location */}
}>
- setLocation(e.target.value)} placeholder="Add location" style={{ width:'100%',border:'none',background:'transparent',fontSize:15,color:'var(--text-primary)',outline:'none' }}/>
+ setLocation(e.target.value)} placeholder="Add location" autoComplete="off" autoCorrect="off" autoCapitalize="off" spellCheck={false} style={{ width:'100%',border:'none',background:'transparent',fontSize:15,color:'var(--text-primary)',outline:'none' }}/>
{/* Description */}
} border={false}>
-
{/* Delete */}
@@ -394,7 +394,7 @@ export default function MobileEventForm({ event, eventTypes, userGroups, selecte
value={newTypeName}
onChange={e=>setNewTypeName(e.target.value)}
onKeyDown={e=>e.key==='Enter'&&createEventType()}
- placeholder="Type name…"
+ placeholder="Type name…" autoComplete="off" autoCorrect="off" autoCapitalize="words" spellCheck={false}
style={{ width:'100%',padding:'12px 14px',border:'1px solid var(--border)',borderRadius:'var(--radius)',fontSize:16,marginBottom:12,boxSizing:'border-box',background:'var(--background)',color:'var(--text-primary)' }}
/>
diff --git a/frontend/src/components/SchedulePage.jsx b/frontend/src/components/SchedulePage.jsx
index 395eedb..2896a30 100644
--- a/frontend/src/components/SchedulePage.jsx
+++ b/frontend/src/components/SchedulePage.jsx
@@ -159,6 +159,7 @@ function MobileScheduleFilter({ selected, onMonthChange, view, eventTypes, filte
value={filterKeyword}
onChange={e=>onFilterKeyword(e.target.value)}
placeholder="Search events…"
+ autoComplete="off" autoCorrect="off" autoCapitalize="off" spellCheck={false}
style={{width:'100%',padding:'7px 8px 7px 28px',border:'1px solid var(--border)',borderRadius:'var(--radius)',background:'var(--background)',color:'var(--text-primary)',fontSize:13,boxSizing:'border-box'}}
/>
@@ -806,17 +807,18 @@ function DayView({ events, selectedDate, onSelect, onSwipe }) {
const handleTouchEnd = e => {
const dx = e.changedTouches[0].clientX - touchRef.current.x;
const dy = Math.abs(e.changedTouches[0].clientY - touchRef.current.y);
- // Require horizontal swipe > 60px, not too vertical, and not from left edge (< 30px = back gesture)
- if(Math.abs(dx) > 60 && dy < 80 && touchRef.current.x > 30) {
+ // Only trigger horizontal swipe if clearly horizontal (dx > dy) and > 60px
+ // and not from left edge (< 30px = OS back gesture)
+ if(Math.abs(dx) > 60 && Math.abs(dx) > dy * 1.5 && touchRef.current.x > 30) {
onSwipe?.(dx < 0 ? 1 : -1); // left = next day, right = prev day
}
};
return(
-
+
{DAYS[selectedDate.getDay()]}
{selectedDate.getDate()}
-
+
{hours.map(h=>(
@@ -861,20 +863,21 @@ function WeekView({ events, selectedDate, onSelect }) {
const handleTouchEnd = e => {
const dx = e.changedTouches[0].clientX - touchRef.current.x;
const dy = Math.abs(e.changedTouches[0].clientY - touchRef.current.y);
- // Require horizontal swipe > 60px, not too vertical, and not from left edge (< 30px = back gesture)
- if(Math.abs(dx) > 60 && dy < 80 && touchRef.current.x > 30) {
+ // Only trigger horizontal swipe if clearly horizontal (dx > dy) and > 60px
+ // and not from left edge (< 30px = OS back gesture)
+ if(Math.abs(dx) > 60 && Math.abs(dx) > dy * 1.5 && touchRef.current.x > 30) {
onSwipe?.(dx < 0 ? 1 : -1); // left = next day, right = prev day
}
};
return(
-
+
{/* Day headers */}
{days.map((d,i)=>
{DAYS[d.getDay()]} {d.getDate()}
)}
{/* Scrollable time grid */}
-
+
{/* Time labels column */}
@@ -1049,8 +1052,8 @@ export default function SchedulePage({ isToolManager, isMobile, onProfile, onHel
{createOpen && (
- {[['Event', ()=>{setPanel('eventForm');setEditingEvent(null);setCreateOpen(false);}],
- ['Event Type', ()=>{setPanel('eventTypes');setCreateOpen(false);}],
+ {[['Event', ()=>{setPanel('eventForm');setEditingEvent(null);setCreateOpen(false);setFilterKeyword('');setFilterTypeId('');}],
+ ['Event Type', ()=>{setPanel('eventTypes');setCreateOpen(false);setFilterKeyword('');setFilterTypeId('');}],
['Bulk Event Import', ()=>{setPanel('bulkImport');setCreateOpen(false);}]
].map(([label,action])=>(
setFilterKeyword(e.target.value)}
+ autoComplete="off" autoCorrect="off" autoCapitalize="off" spellCheck={false}
style={{ marginBottom:8, fontSize:13 }}
/>
{
const labels = { schedule:'Schedule', day:'Day', week:'Week', month:'Month' };
return (
- {setView(v);setPanel('calendar');}} style={{ padding:'4px 10px', borderRadius:5, border:'none', cursor:'pointer', fontSize:12, fontWeight:600, background:view===v?'var(--surface)':'transparent', color:view===v?'var(--text-primary)':'var(--text-tertiary)', boxShadow:view===v?'0 1px 3px rgba(0,0,0,0.1)':'none', transition:'all 0.15s', whiteSpace:'nowrap' }}>
+ {setView(v);setPanel('calendar');setSelDate(new Date());setFilterKeyword('');setFilterTypeId('');}} style={{ padding:'4px 10px', borderRadius:5, border:'none', cursor:'pointer', fontSize:12, fontWeight:600, background:view===v?'var(--surface)':'transparent', color:view===v?'var(--text-primary)':'var(--text-tertiary)', boxShadow:view===v?'0 1px 3px rgba(0,0,0,0.1)':'none', transition:'all 0.15s', whiteSpace:'nowrap' }}>
{labels[v]}
);
@@ -1165,7 +1169,7 @@ export default function SchedulePage({ isToolManager, isMobile, onProfile, onHel
{editingEvent?'Edit Event':'New Event'}
{setPanel('calendar');setEditingEvent(null);}} onDelete={handleDelete}/>
+ onSave={handleSaved} onCancel={()=>{setPanel('calendar');setEditingEvent(null);setFilterKeyword('');setFilterTypeId('');}} onDelete={handleDelete}/>
)}
@@ -1212,7 +1216,7 @@ export default function SchedulePage({ isToolManager, isMobile, onProfile, onHel
selectedDate={selDate}
isToolManager={isToolManager}
onSave={handleSaved}
- onCancel={()=>{setPanel('calendar');setEditingEvent(null);}}
+ onCancel={()=>{setPanel('calendar');setEditingEvent(null);setFilterKeyword('');setFilterTypeId('');}}
onDelete={handleDelete}
/>
@@ -1228,8 +1232,8 @@ export default function SchedulePage({ isToolManager, isMobile, onProfile, onHel
{createOpen && (
- {[['Event', ()=>{setPanel('eventForm');setEditingEvent(null);setCreateOpen(false);}],
- ['Event Type', ()=>{setPanel('eventTypes');setCreateOpen(false);}],
+ {[['Event', ()=>{setPanel('eventForm');setEditingEvent(null);setCreateOpen(false);setFilterKeyword('');setFilterTypeId('');}],
+ ['Event Type', ()=>{setPanel('eventTypes');setCreateOpen(false);setFilterKeyword('');setFilterTypeId('');}],
].map(([label,action])=>(
e.currentTarget.style.background='var(--background)'} onMouseLeave={e=>e.currentTarget.style.background=''}>{label}