style: make CalendarEventModal more compact for mobile

Reduce padding, gaps, font sizes, and combine Status/Visibility into
a single row for better usability on smaller screens.

v1.36.1
This commit is contained in:
mARTin 2026-03-16 17:04:25 +01:00
parent b9c05571be
commit d991e7a65b
2 changed files with 220 additions and 232 deletions

View File

@ -1,6 +1,6 @@
{
"name": "my-weekly-todo-list",
"version": "1.36.0",
"version": "1.36.1",
"description": "A web-based weekly task management application that organizes to-dos and calendar events in a single, intuitive weekly view",
"main": "index.js",
"scripts": {

View File

@ -87,7 +87,6 @@ export default function CalendarEventModal({
);
const [newAttachmentUrl, setNewAttachmentUrl] = useState('');
const [showMoreOptions, setShowMoreOptions] = useState(
// Auto-expand if event has these fields set
!!(event?.attendees?.length || event?.attachments?.length || (event?.busyStatus && event.busyStatus !== 'busy') || (event?.visibility && event.visibility !== 'default'))
);
@ -143,7 +142,7 @@ export default function CalendarEventModal({
case 'google': return <FontAwesomeIcon icon={faGoogle} style={{ opacity: 0.8 }} />;
case 'apple': return <FontAwesomeIcon icon={faApple} style={{ opacity: 0.8 }} />;
case 'outlook': return <FontAwesomeIcon icon={faMicrosoft} style={{ opacity: 0.8 }} />;
case 'synology': return <FontAwesomeIcon icon={faServer} style={{ opacity: 0.8, fontSize: '0.8rem' }} />;
case 'synology': return <FontAwesomeIcon icon={faServer} style={{ opacity: 0.8, fontSize: '0.75rem' }} />;
default: return null;
}
};
@ -165,7 +164,6 @@ export default function CalendarEventModal({
setIsSaving(true);
setError('');
try {
// Filter out "none" reminders
const activeReminders = reminders.filter(r => r.minutes >= 0);
await onSave({
@ -255,7 +253,6 @@ export default function CalendarEventModal({
const updateReminder = (index: number, minutes: number) => {
if (minutes === -1) {
// Remove this reminder
setReminders(reminders.filter((_, i) => i !== index));
return;
}
@ -270,30 +267,32 @@ export default function CalendarEventModal({
const rowStyle: React.CSSProperties = {
display: 'flex', alignItems: 'center', justifyContent: 'space-between',
padding: '0 10px', minHeight: '32px',
};
const labelStyle: React.CSSProperties = {
fontSize: '0.9rem', color: 'var(--weekly-text-light)', fontWeight: 500,
fontSize: '0.82rem', color: 'var(--weekly-text-light)', fontWeight: 500,
};
const selectStyle: React.CSSProperties = {
background: 'transparent', border: 'none', textAlign: 'right' as const,
fontSize: '0.9rem', cursor: 'pointer', outline: 'none', color: 'var(--weekly-text)',
fontSize: '0.82rem', cursor: 'pointer', outline: 'none', color: 'var(--weekly-text)',
};
return (
<div className="weekly-modal-overlay" onClick={onClose}>
<div className="weekly-modal-content" onClick={e => e.stopPropagation()} style={{
maxWidth: '450px',
padding: '20px',
borderRadius: '12px',
maxWidth: '400px',
width: 'calc(100vw - 16px)',
padding: '12px',
borderRadius: '10px',
boxShadow: '0 10px 25px rgba(0,0,0,0.15)',
border: '1px solid var(--weekly-border)',
maxHeight: '90vh',
maxHeight: '85vh',
overflowY: 'auto',
}}>
{error && <div style={{ color: '#ef4444', marginBottom: '1rem', fontSize: '0.85rem', textAlign: 'center' }}>{error}</div>}
{error && <div style={{ color: '#ef4444', marginBottom: '6px', fontSize: '0.8rem', textAlign: 'center' }}>{error}</div>}
<div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>
{/* Title Input */}
<div style={{ display: 'flex', flexDirection: 'column', gap: '4px' }}>
{/* Title */}
<input
type="text"
value={title}
@ -301,87 +300,74 @@ export default function CalendarEventModal({
placeholder="New Event"
autoFocus
style={{
width: '100%',
padding: '12px 16px',
fontSize: '1.25rem',
fontWeight: 600,
border: 'none',
borderBottom: '1px solid var(--weekly-border)',
borderRadius: '0',
background: 'transparent',
outline: 'none',
marginBottom: '4px'
width: '100%', padding: '6px 10px', fontSize: '1.05rem', fontWeight: 600,
border: 'none', borderBottom: '1px solid var(--weekly-border)',
borderRadius: '0', background: 'transparent', outline: 'none',
}}
/>
{/* Location Input */}
{/* Location */}
<input
type="text"
value={location}
onChange={e => setLocation(e.target.value)}
placeholder="Location or Video Call"
style={{
width: '100%',
padding: '8px 16px',
border: 'none',
width: '100%', padding: '5px 10px', border: 'none',
borderBottom: '1px solid var(--weekly-border)',
borderRadius: '0',
background: 'transparent',
outline: 'none',
fontSize: '0.95rem'
borderRadius: '0', background: 'transparent', outline: 'none', fontSize: '0.82rem',
}}
/>
{/* Calendar row */}
<div style={{ ...rowStyle, padding: '4px 16px', position: 'relative' }}>
<div style={{ ...rowStyle, position: 'relative' }}>
<span style={labelStyle}>Calendar</span>
<div ref={calendarSelectorRef} style={{ position: 'relative', flex: 1, display: 'flex', justifyContent: 'flex-end' }}>
<button
type="button"
onClick={() => !event && setIsCalendarSelectorOpen(!isCalendarSelectorOpen)}
disabled={!!event}
style={{
display: 'flex', alignItems: 'center', gap: '8px',
display: 'flex', alignItems: 'center', gap: '6px',
background: 'transparent', border: 'none', fontWeight: 500,
cursor: event ? 'default' : 'pointer', outline: 'none',
color: 'var(--weekly-text)', fontSize: '0.95rem',
padding: '4px 0', maxWidth: '200px', justifyContent: 'flex-end'
color: 'var(--weekly-text)', fontSize: '0.82rem',
padding: '2px 0', maxWidth: '180px', justifyContent: 'flex-end'
}}
>
<span style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
{selectedCal?.summary || selectedCal?.title || 'Select Calendar'}
</span>
<div style={{
width: '12px', height: '12px', borderRadius: '50%',
width: '10px', height: '10px', borderRadius: '50%', flexShrink: 0,
backgroundColor: selectedCal?.backgroundColor || selectedCal?.color || '#3b82f6'
}} />
{!event && (isCalendarSelectorOpen ? <ChevronUp size={14} /> : <ChevronDown size={14} />)}
{!event && (isCalendarSelectorOpen ? <ChevronUp size={12} /> : <ChevronDown size={12} />)}
</button>
{isCalendarSelectorOpen && (
<div style={{
position: 'absolute', top: '100%', right: 0, zIndex: 100,
minWidth: '220px', backgroundColor: 'var(--weekly-bg-popover, #ffffff)',
borderRadius: '10px', boxShadow: '0 4px 15px rgba(0,0,0,0.1)',
border: '1px solid var(--weekly-border)', marginTop: '5px',
padding: '6px', maxHeight: '250px', overflowY: 'auto'
minWidth: '200px', backgroundColor: 'var(--weekly-bg-popover, #ffffff)',
borderRadius: '8px', boxShadow: '0 4px 15px rgba(0,0,0,0.1)',
border: '1px solid var(--weekly-border)', marginTop: '2px',
padding: '4px', maxHeight: '200px', overflowY: 'auto'
}}>
{availableCalendars.map((cal: any) => (
<div
key={cal.id}
onClick={() => { setCalendarId(cal.id); setIsCalendarSelectorOpen(false); }}
style={{
display: 'flex', alignItems: 'center', gap: '10px',
padding: '8px 12px', borderRadius: '6px', cursor: 'pointer',
fontSize: '0.9rem', color: 'var(--weekly-text)',
display: 'flex', alignItems: 'center', gap: '8px',
padding: '6px 10px', borderRadius: '5px', cursor: 'pointer',
fontSize: '0.82rem', color: 'var(--weekly-text)',
backgroundColor: calendarId === cal.id ? 'var(--weekly-selection, rgba(59, 130, 246, 0.1))' : 'transparent',
transition: 'background 0.2s', textAlign: 'left'
}}
onMouseEnter={(e) => e.currentTarget.style.backgroundColor = 'var(--weekly-hover, rgba(0,0,0,0.05))'}
onMouseLeave={(e) => e.currentTarget.style.backgroundColor = calendarId === cal.id ? 'var(--weekly-selection, rgba(59, 130, 246, 0.1))' : 'transparent'}
>
<div style={{ width: '10px', height: '10px', borderRadius: '50%', backgroundColor: cal.backgroundColor || cal.color || '#3b82f6', flexShrink: 0 }} />
<div style={{ width: '8px', height: '8px', borderRadius: '50%', backgroundColor: cal.backgroundColor || cal.color || '#3b82f6', flexShrink: 0 }} />
<span style={{ flex: 1, overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
{cal.summary || cal.title}
</span>
@ -395,99 +381,101 @@ export default function CalendarEventModal({
</div>
</div>
{/* All Day row */}
<div style={{ ...rowStyle, padding: '4px 16px' }}>
{/* All Day */}
<div style={rowStyle}>
<span style={labelStyle}>All Day</span>
<input
type="checkbox"
checked={allDay}
onChange={e => setAllDay(e.target.checked)}
style={{ width: '18px', height: '18px', cursor: 'pointer' }}
style={{ width: '16px', height: '16px', cursor: 'pointer' }}
/>
</div>
{/* Date/Time rows */}
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px', padding: '0 16px' }}>
<div style={rowStyle}>
{/* Start / End on same row when not all-day */}
<div style={{ display: 'flex', flexDirection: 'column', gap: '2px', padding: '0 10px' }}>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', minHeight: '30px' }}>
<span style={labelStyle}>Starts</span>
<input
type={allDay ? "date" : "datetime-local"}
value={allDay ? startDate.toISOString().split('T')[0] : toLocalISOString(startDate)}
onChange={e => handleStartDateChange(e.target.value)}
style={{
padding: '4px 8px', border: 'none', borderRadius: '6px',
padding: '2px 6px', border: 'none', borderRadius: '4px',
background: 'var(--weekly-bg-secondary, #f3f4f6)',
fontSize: '0.9rem', textAlign: 'center'
fontSize: '0.8rem', textAlign: 'center',
}}
/>
</div>
<div style={rowStyle}>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', minHeight: '30px' }}>
<span style={labelStyle}>Ends</span>
<input
type={allDay ? "date" : "datetime-local"}
value={allDay ? endDate.toISOString().split('T')[0] : toLocalISOString(endDate)}
onChange={e => setEndDate(new Date(e.target.value))}
style={{
padding: '4px 8px', border: 'none', borderRadius: '6px',
padding: '2px 6px', border: 'none', borderRadius: '4px',
background: 'var(--weekly-bg-secondary, #f3f4f6)',
fontSize: '0.9rem', textAlign: 'center'
fontSize: '0.8rem', textAlign: 'center',
}}
/>
</div>
</div>
{/* Meta Fields Group */}
<div style={{ padding: '8px 16px', display: 'flex', flexDirection: 'column', gap: '12px', marginTop: '4px' }}>
{/* Recurrence */}
<div style={rowStyle}>
<span style={labelStyle}>Repeat</span>
<select value={recurrence} onChange={e => setRecurrence(e.target.value)} style={selectStyle}>
<option value="none">Never</option>
<option value="daily">Every Day</option>
<option value="weekly">Every Week</option>
<option value="monthly">Every Month</option>
<option value="yearly">Every Year</option>
</select>
</div>
{/* Divider */}
<div style={{ borderTop: '1px solid var(--weekly-border)', margin: '2px 10px' }} />
{/* Reminders */}
<div>
<div style={{ ...rowStyle, marginBottom: reminders.length > 0 ? '6px' : 0 }}>
<span style={{ ...labelStyle, display: 'flex', alignItems: 'center', gap: '6px' }}>
<Bell size={14} /> Alert
</span>
{reminders.length === 0 && (
<button onClick={addReminder} style={{ ...selectStyle, color: '#3b82f6', cursor: 'pointer', background: 'none', border: 'none' }}>
Add
</button>
)}
</div>
{reminders.map((reminder, idx) => (
<div key={idx} style={{ display: 'flex', alignItems: 'center', justifyContent: 'flex-end', gap: '8px', marginBottom: '4px' }}>
<select
value={reminder.minutes}
onChange={e => updateReminder(idx, parseInt(e.target.value))}
style={selectStyle}
>
{REMINDER_OPTIONS.map(opt => (
<option key={opt.value} value={opt.value}>{opt.label}</option>
))}
</select>
<button onClick={() => setReminders(reminders.filter((_, i) => i !== idx))}
style={{ background: 'none', border: 'none', cursor: 'pointer', padding: '2px', color: 'var(--weekly-text-light)' }}>
<X size={14} />
</button>
</div>
))}
{reminders.length > 0 && reminders.length < 2 && (
<button onClick={addReminder} style={{ fontSize: '0.85rem', color: '#3b82f6', background: 'none', border: 'none', cursor: 'pointer', padding: '2px 0' }}>
+ Add another alert
{/* Repeat */}
<div style={rowStyle}>
<span style={labelStyle}>Repeat</span>
<select value={recurrence} onChange={e => setRecurrence(e.target.value)} style={selectStyle}>
<option value="none">Never</option>
<option value="daily">Every Day</option>
<option value="weekly">Every Week</option>
<option value="monthly">Every Month</option>
<option value="yearly">Every Year</option>
</select>
</div>
{/* Alert */}
<div style={{ padding: '0 10px' }}>
<div style={{ display: 'flex', alignItems: 'center', justifyContent: 'space-between', minHeight: '32px' }}>
<span style={{ ...labelStyle, display: 'flex', alignItems: 'center', gap: '4px' }}>
<Bell size={12} /> Alert
</span>
{reminders.length === 0 && (
<button onClick={addReminder} style={{ ...selectStyle, color: '#3b82f6', cursor: 'pointer', background: 'none', border: 'none' }}>
Add
</button>
)}
</div>
{reminders.map((reminder, idx) => (
<div key={idx} style={{ display: 'flex', alignItems: 'center', justifyContent: 'flex-end', gap: '4px', marginBottom: '2px' }}>
<select
value={reminder.minutes}
onChange={e => updateReminder(idx, parseInt(e.target.value))}
style={selectStyle}
>
{REMINDER_OPTIONS.map(opt => (
<option key={opt.value} value={opt.value}>{opt.label}</option>
))}
</select>
<button onClick={() => setReminders(reminders.filter((_, i) => i !== idx))}
style={{ background: 'none', border: 'none', cursor: 'pointer', padding: '1px', color: 'var(--weekly-text-light)' }}>
<X size={12} />
</button>
</div>
))}
{reminders.length > 0 && reminders.length < 2 && (
<button onClick={addReminder} style={{ fontSize: '0.78rem', color: '#3b82f6', background: 'none', border: 'none', cursor: 'pointer', padding: '1px 0' }}>
+ Add another alert
</button>
)}
</div>
{/* Busy Status */}
<div style={rowStyle}>
{/* Status & Visibility side by side */}
<div style={{ display: 'flex', gap: '8px', padding: '0 10px' }}>
<div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'space-between', minHeight: '32px' }}>
<span style={labelStyle}>Status</span>
<select value={busyStatus} onChange={e => setBusyStatus(e.target.value)} style={selectStyle}>
{BUSY_STATUS_OPTIONS.map(opt => (
@ -495,9 +483,8 @@ export default function CalendarEventModal({
))}
</select>
</div>
{/* Visibility */}
<div style={rowStyle}>
<div style={{ width: '1px', background: 'var(--weekly-border)', margin: '4px 0' }} />
<div style={{ flex: 1, display: 'flex', alignItems: 'center', justifyContent: 'space-between', minHeight: '32px' }}>
<span style={labelStyle}>Visibility</span>
<select value={visibility} onChange={e => setVisibility(e.target.value)} style={selectStyle}>
{VISIBILITY_OPTIONS.map(opt => (
@ -505,159 +492,160 @@ export default function CalendarEventModal({
))}
</select>
</div>
</div>
{/* URL (Conditional) */}
{supportsURL && (
<input
type="url"
value={url}
onChange={e => setUrl(e.target.value)}
placeholder="URL"
style={{
width: '100%', padding: '6px 0', border: 'none',
borderBottom: '1px solid var(--weekly-border)',
background: 'transparent', fontSize: '0.9rem', outline: 'none'
}}
/>
)}
{/* Expandable section: Attendees & Attachments */}
<button
onClick={() => setShowMoreOptions(!showMoreOptions)}
{/* URL (Conditional) */}
{supportsURL && (
<input
type="url"
value={url}
onChange={e => setUrl(e.target.value)}
placeholder="URL"
style={{
display: 'flex', alignItems: 'center', gap: '6px',
background: 'none', border: 'none', cursor: 'pointer',
color: '#3b82f6', fontSize: '0.9rem', padding: '4px 0',
width: '100%', padding: '4px 10px', border: 'none',
borderBottom: '1px solid var(--weekly-border)',
background: 'transparent', fontSize: '0.82rem', outline: 'none'
}}
>
{showMoreOptions ? <ChevronUp size={14} /> : <ChevronDown size={14} />}
Invitees & Attachments
</button>
/>
)}
{showMoreOptions && (
<div style={{ display: 'flex', flexDirection: 'column', gap: '12px' }}>
{/* Attendees */}
{/* Expandable: Invitees & Attachments */}
<button
onClick={() => setShowMoreOptions(!showMoreOptions)}
style={{
display: 'flex', alignItems: 'center', gap: '4px',
background: 'none', border: 'none', cursor: 'pointer',
color: '#3b82f6', fontSize: '0.8rem', padding: '2px 10px',
}}
>
{showMoreOptions ? <ChevronUp size={12} /> : <ChevronDown size={12} />}
Invitees & Attachments
</button>
{showMoreOptions && (
<div style={{ display: 'flex', flexDirection: 'column', gap: '8px', padding: '0 10px' }}>
{/* Attendees */}
<div>
<span style={{ ...labelStyle, display: 'flex', alignItems: 'center', gap: '4px', marginBottom: '4px' }}>
<Users size={12} /> Invitees
</span>
{attendees.map((att, idx) => (
<div key={idx} style={{
display: 'flex', alignItems: 'center', justifyContent: 'space-between',
padding: '3px 6px', marginBottom: '2px',
background: 'var(--weekly-bg-secondary, #f3f4f6)', borderRadius: '4px',
fontSize: '0.78rem',
}}>
<span style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
{att.displayName ? `${att.displayName} (${att.email})` : att.email}
</span>
<button onClick={() => removeAttendee(att.email)}
style={{ background: 'none', border: 'none', cursor: 'pointer', padding: '1px', color: 'var(--weekly-text-light)', flexShrink: 0 }}>
<X size={12} />
</button>
</div>
))}
<div style={{ display: 'flex', gap: '4px' }}>
<input
type="email"
value={newAttendeeEmail}
onChange={e => setNewAttendeeEmail(e.target.value)}
placeholder="Add email address"
onKeyDown={e => e.key === 'Enter' && addAttendee()}
style={{
flex: 1, padding: '4px 6px', border: 'none',
borderBottom: '1px solid var(--weekly-border)',
background: 'transparent', fontSize: '0.78rem', outline: 'none',
}}
/>
<button onClick={addAttendee} style={{
background: 'none', border: 'none', cursor: 'pointer',
color: '#3b82f6', padding: '2px',
}}>
<Plus size={14} />
</button>
</div>
</div>
{/* Attachments (Apple/Synology only) */}
{supportsAttachments && (
<div>
<span style={{ ...labelStyle, display: 'flex', alignItems: 'center', gap: '6px', marginBottom: '6px' }}>
<Users size={14} /> Invitees
<span style={{ ...labelStyle, display: 'flex', alignItems: 'center', gap: '4px', marginBottom: '4px' }}>
<Paperclip size={12} /> Attachments
</span>
{attendees.map((att, idx) => (
{attachments.map((att, idx) => (
<div key={idx} style={{
display: 'flex', alignItems: 'center', justifyContent: 'space-between',
padding: '4px 8px', marginBottom: '4px',
background: 'var(--weekly-bg-secondary, #f3f4f6)', borderRadius: '6px',
fontSize: '0.85rem',
padding: '3px 6px', marginBottom: '2px',
background: 'var(--weekly-bg-secondary, #f3f4f6)', borderRadius: '4px',
fontSize: '0.78rem',
}}>
<span style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
{att.displayName ? `${att.displayName} (${att.email})` : att.email}
{att.title || att.url}
</span>
<button onClick={() => removeAttendee(att.email)}
style={{ background: 'none', border: 'none', cursor: 'pointer', padding: '2px', color: 'var(--weekly-text-light)', flexShrink: 0 }}>
<X size={14} />
<button onClick={() => removeAttachment(att.url)}
style={{ background: 'none', border: 'none', cursor: 'pointer', padding: '1px', color: 'var(--weekly-text-light)', flexShrink: 0 }}>
<X size={12} />
</button>
</div>
))}
<div style={{ display: 'flex', gap: '6px' }}>
<div style={{ display: 'flex', gap: '4px' }}>
<input
type="email"
value={newAttendeeEmail}
onChange={e => setNewAttendeeEmail(e.target.value)}
placeholder="Add email address"
onKeyDown={e => e.key === 'Enter' && addAttendee()}
type="url"
value={newAttachmentUrl}
onChange={e => setNewAttachmentUrl(e.target.value)}
placeholder="Add attachment URL"
onKeyDown={e => e.key === 'Enter' && addAttachment()}
style={{
flex: 1, padding: '6px 8px', border: 'none',
flex: 1, padding: '4px 6px', border: 'none',
borderBottom: '1px solid var(--weekly-border)',
background: 'transparent', fontSize: '0.85rem', outline: 'none',
background: 'transparent', fontSize: '0.78rem', outline: 'none',
}}
/>
<button onClick={addAttendee} style={{
<button onClick={addAttachment} style={{
background: 'none', border: 'none', cursor: 'pointer',
color: '#3b82f6', padding: '4px',
color: '#3b82f6', padding: '2px',
}}>
<Plus size={16} />
<Plus size={14} />
</button>
</div>
</div>
{/* Attachments (URL-based, Apple/Synology only) */}
{supportsAttachments && (
<div>
<span style={{ ...labelStyle, display: 'flex', alignItems: 'center', gap: '6px', marginBottom: '6px' }}>
<Paperclip size={14} /> Attachments
</span>
{attachments.map((att, idx) => (
<div key={idx} style={{
display: 'flex', alignItems: 'center', justifyContent: 'space-between',
padding: '4px 8px', marginBottom: '4px',
background: 'var(--weekly-bg-secondary, #f3f4f6)', borderRadius: '6px',
fontSize: '0.85rem',
}}>
<span style={{ overflow: 'hidden', textOverflow: 'ellipsis', whiteSpace: 'nowrap' }}>
{att.title || att.url}
</span>
<button onClick={() => removeAttachment(att.url)}
style={{ background: 'none', border: 'none', cursor: 'pointer', padding: '2px', color: 'var(--weekly-text-light)', flexShrink: 0 }}>
<X size={14} />
</button>
</div>
))}
<div style={{ display: 'flex', gap: '6px' }}>
<input
type="url"
value={newAttachmentUrl}
onChange={e => setNewAttachmentUrl(e.target.value)}
placeholder="Add attachment URL"
onKeyDown={e => e.key === 'Enter' && addAttachment()}
style={{
flex: 1, padding: '6px 8px', border: 'none',
borderBottom: '1px solid var(--weekly-border)',
background: 'transparent', fontSize: '0.85rem', outline: 'none',
}}
/>
<button onClick={addAttachment} style={{
background: 'none', border: 'none', cursor: 'pointer',
color: '#3b82f6', padding: '4px',
}}>
<Plus size={16} />
</button>
</div>
</div>
)}
</div>
)}
{/* Notes */}
<div style={{ marginTop: '4px' }}>
<Suspense fallback={
<textarea
value={description}
onChange={e => setDescription(e.target.value)}
placeholder="Notes"
rows={3}
style={{ width: '100%', padding: '8px 0', border: 'none', borderBottom: '1px solid var(--weekly-border)', background: 'transparent', resize: 'none', fontSize: '0.9rem', outline: 'none' }}
/>
}>
<RichTextEditor
value={description}
onChange={setDescription}
placeholder="Notes"
minHeight="80px"
/>
</Suspense>
)}
</div>
)}
{/* Notes */}
<div style={{ padding: '0 10px' }}>
<Suspense fallback={
<textarea
value={description}
onChange={e => setDescription(e.target.value)}
placeholder="Notes"
rows={2}
style={{ width: '100%', padding: '4px 0', border: 'none', borderBottom: '1px solid var(--weekly-border)', background: 'transparent', resize: 'none', fontSize: '0.82rem', outline: 'none' }}
/>
}>
<RichTextEditor
value={description}
onChange={setDescription}
placeholder="Notes"
minHeight="60px"
/>
</Suspense>
</div>
</div>
<div className="weekly-modal-actions" style={{ marginTop: '20px', display: 'flex', justifyContent: 'space-between', borderTop: '1px solid var(--weekly-border)', paddingTop: '15px' }}>
<div style={{ display: 'flex', gap: '12px', alignItems: 'center' }}>
{/* Actions */}
<div style={{ marginTop: '10px', display: 'flex', justifyContent: 'space-between', alignItems: 'center', borderTop: '1px solid var(--weekly-border)', paddingTop: '10px' }}>
<div style={{ display: 'flex', gap: '8px', alignItems: 'center' }}>
{event && onDelete && (
<button
onClick={handleDelete}
disabled={isSaving || isDeleting}
style={{
padding: '8px 12px', background: 'none', color: '#ef4444',
border: 'none', borderRadius: '6px', fontSize: '0.9rem',
fontWeight: 500, cursor: 'pointer', transition: 'all 0.2s',
padding: '6px 10px', background: 'none', color: '#ef4444',
border: 'none', borderRadius: '6px', fontSize: '0.82rem',
fontWeight: 500, cursor: 'pointer',
opacity: isSaving || isDeleting ? 0.5 : 1
}}
>
@ -665,15 +653,15 @@ export default function CalendarEventModal({
</button>
)}
{!event && (
<button className="weekly-btn-ghost" onClick={onClose} style={{ padding: '8px 12px', fontSize: '0.9rem', color: 'var(--weekly-text-light)', border: 'none', background: 'none', cursor: 'pointer' }}>
<button onClick={onClose} style={{ padding: '6px 10px', fontSize: '0.82rem', color: 'var(--weekly-text-light)', border: 'none', background: 'none', cursor: 'pointer' }}>
Cancel
</button>
)}
</div>
<div style={{ display: 'flex', gap: '8px' }}>
<div style={{ display: 'flex', gap: '6px' }}>
{event && (
<button className="weekly-btn-ghost" onClick={onClose} style={{ padding: '8px 12px', fontSize: '0.9rem', color: 'var(--weekly-text-light)', border: 'none', background: 'none', cursor: 'pointer' }}>
<button onClick={onClose} style={{ padding: '6px 10px', fontSize: '0.82rem', color: 'var(--weekly-text-light)', border: 'none', background: 'none', cursor: 'pointer' }}>
Cancel
</button>
)}
@ -682,7 +670,7 @@ export default function CalendarEventModal({
onClick={handleSubmit}
disabled={isSaving || isDeleting}
style={{
padding: '8px 20px', borderRadius: '8px', fontSize: '0.95rem',
padding: '6px 16px', borderRadius: '6px', fontSize: '0.85rem',
fontWeight: 600, backgroundColor: '#3b82f6', color: 'white',
border: 'none', cursor: 'pointer',
opacity: isSaving || isDeleting ? 0.7 : 1