schedule views update

This commit is contained in:
2026-03-25 09:10:44 -04:00
parent 941d216f38
commit 6af892c9a6

View File

@@ -1203,6 +1203,10 @@ function DayView({ events: rawEvents, selectedDate, onSelect, onSwipe }) {
const events = expandEvents(rawEvents, dayStart, dayEnd);
const hours=Array.from({length:DAY_END - DAY_START},(_,i)=>i+DAY_START);
const day=events.filter(e=>sameDay(new Date(e.start_at),selectedDate));
const allDayEvs=day.filter(e=>e.all_day);
const timedEvs=day.filter(e=>!e.all_day);
const tzOff=-new Date().getTimezoneOffset();
const tzLabel=`GMT${tzOff>=0?'+':'-'}${String(Math.floor(Math.abs(tzOff)/60)).padStart(2,'0')}`;
const scrollRef = useRef(null);
const touchRef = useRef({ x:0, y:0 });
useEffect(()=>{ if(scrollRef.current) scrollRef.current.scrollTop = 7 * HOUR_H; },[selectedDate]);
@@ -1222,6 +1226,16 @@ function DayView({ events: rawEvents, selectedDate, onSelect, onSwipe }) {
<div style={{display:'flex',borderBottom:'1px solid var(--border)',padding:'8px 0 8px 60px',fontSize:13,fontWeight:600,color:'var(--primary)',flexShrink:0}}>
<div style={{textAlign:'center'}}><div>{DAYS[selectedDate.getDay()]}</div><div style={{fontSize:28,fontWeight:700}}>{selectedDate.getDate()}</div></div>
</div>
<div style={{display:'flex',borderBottom:'1px solid var(--border)',flexShrink:0,minHeight:28}}>
<div style={{width:60,flexShrink:0,fontSize:10,color:'var(--text-tertiary)',padding:'4px 8px',textAlign:'right',alignSelf:'center'}}>{tzLabel}</div>
<div style={{flex:1,padding:'2px 4px',display:'flex',flexDirection:'column',gap:2}}>
{allDayEvs.map(e=>(
<div key={e.id} onClick={()=>onSelect(e)} style={{background:e.event_type?.colour||'#6366f1',color:'white',borderRadius:3,padding:'2px 6px',fontSize:12,fontWeight:600,cursor:'pointer',whiteSpace:'nowrap',overflow:'hidden',textOverflow:'ellipsis'}}>
{e.title}
</div>
))}
</div>
</div>
<div ref={scrollRef} style={{flex:1,overflowY:'auto',position:'relative',touchAction:'pan-y'}}>
<div style={{position:'relative',paddingBottom:onSwipe?80:0}}>
{hours.map(h=>(
@@ -1230,7 +1244,7 @@ function DayView({ events: rawEvents, selectedDate, onSelect, onSwipe }) {
<div style={{flex:1}}/>
</div>
))}
{layoutEvents(day).map(({event:e,col,totalCols})=>{
{layoutEvents(timedEvs).map(({event:e,col,totalCols})=>{
const s=new Date(e.start_at), en=new Date(e.end_at);
const top=eventTopOffset(s), height=eventHeightPx(s,en);
return(
@@ -1262,6 +1276,8 @@ function WeekView({ events: rawEvents, selectedDate, onSelect }) {
const events = expandEvents(rawEvents, _ws, _we);
const ws=weekStart(selectedDate), days=Array.from({length:7},(_,i)=>{const d=new Date(ws);d.setDate(d.getDate()+i);return d;});
const hours=Array.from({length:DAY_END - DAY_START},(_,i)=>i+DAY_START), today=new Date();
const tzOff=-new Date().getTimezoneOffset();
const tzLabel=`GMT${tzOff>=0?'+':'-'}${String(Math.floor(Math.abs(tzOff)/60)).padStart(2,'0')}`;
const scrollRef = useRef(null);
const touchRef = useRef({ x:0, y:0 });
useEffect(()=>{ if(scrollRef.current) scrollRef.current.scrollTop = 7 * HOUR_H; },[selectedDate]);
@@ -1283,6 +1299,22 @@ function WeekView({ events: rawEvents, selectedDate, onSelect }) {
<div/>
{days.map((d,i)=><div key={i} style={{textAlign:'center',padding:'6px 4px',fontSize:12,fontWeight:600,color:sameDay(d,today)?'var(--primary)':'var(--text-secondary)'}}>{DAYS[d.getDay()]} {d.getDate()}</div>)}
</div>
{/* All-day row */}
<div style={{display:'grid',gridTemplateColumns:'60px repeat(7,1fr)',borderBottom:'1px solid var(--border)',flexShrink:0,minHeight:28}}>
<div style={{fontSize:10,color:'var(--text-tertiary)',padding:'4px 8px',textAlign:'right',alignSelf:'center'}}>{tzLabel}</div>
{days.map((d,di)=>{
const adEvs=events.filter(e=>e.all_day&&sameDay(new Date(e.start_at),d));
return(
<div key={di} style={{borderLeft:'1px solid var(--border)',padding:'2px 2px',display:'flex',flexDirection:'column',gap:1}}>
{adEvs.map(e=>(
<div key={e.id} onClick={()=>onSelect(e)} style={{background:e.event_type?.colour||'#6366f1',color:'white',borderRadius:3,padding:'2px 4px',fontSize:10,fontWeight:600,cursor:'pointer',whiteSpace:'nowrap',overflow:'hidden',textOverflow:'ellipsis'}}>
{e.title}
</div>
))}
</div>
);
})}
</div>
{/* Scrollable time grid */}
<div ref={scrollRef} style={{flex:1,overflowY:'auto',touchAction:'pan-y'}}>
<div style={{display:'grid',gridTemplateColumns:'60px repeat(7,1fr)',position:'relative'}}>
@@ -1294,7 +1326,7 @@ function WeekView({ events: rawEvents, selectedDate, onSelect }) {
</div>
{/* Day columns */}
{days.map((d,di)=>{
const dayEvs=events.filter(e=>sameDay(new Date(e.start_at),d));
const dayEvs=events.filter(e=>!e.all_day&&sameDay(new Date(e.start_at),d));
return(
<div key={di} style={{position:'relative',borderLeft:'1px solid var(--border)'}}>
{hours.map(h=><div key={h} style={{height:HOUR_H,borderBottom:'1px solid var(--border)'}}/>)}
@@ -1358,7 +1390,7 @@ function MonthView({ events: rawEvents, selectedDate, onSelect, onSelectDay }) {
borderRadius:3,padding:'1px 4px',fontSize:11,marginBottom:1,cursor:'pointer',
whiteSpace:'nowrap',overflow:'hidden',textOverflow:'ellipsis',flexShrink:0,
}}>
{!e.all_day&&<span style={{marginRight:3,opacity:0.85}}>{fmtTime(e.start_at)}</span>}{e.title}
{e.all_day?<span style={{marginRight:3,opacity:0.85}}>All Day:</span>:<span style={{marginRight:3,opacity:0.85}}>{fmtTime(e.start_at)}</span>}{e.title}
</div>
))}
{dayEvs.length>2&&<div style={{fontSize:10,color:'var(--text-tertiary)',flexShrink:0}}>+{dayEvs.length-2} more</div>}