summaryrefslogtreecommitdiff
path: root/src/components/SettingsPanel.tsx
diff options
context:
space:
mode:
Diffstat (limited to 'src/components/SettingsPanel.tsx')
-rw-r--r--src/components/SettingsPanel.tsx38
1 files changed, 28 insertions, 10 deletions
diff --git a/src/components/SettingsPanel.tsx b/src/components/SettingsPanel.tsx
index 0d3cbf9..71bc7b8 100644
--- a/src/components/SettingsPanel.tsx
+++ b/src/components/SettingsPanel.tsx
@@ -1,6 +1,8 @@
import { useState, useEffect } from 'react';
import { useSettingsStore, Settings } from '../store/settingsStore';
+const clampValue = (value: number, min: number, max: number) => Math.min(max, Math.max(min, value));
+
interface SettingsPanelProps {
open: boolean;
onClose: () => void;
@@ -22,21 +24,31 @@ export function SettingsPanel({ open, onClose }: SettingsPanelProps) {
useEffect(() => {
if (settings) {
- setWorkMins(Math.round(settings.work_duration_secs / 60));
- setShortBreakMins(Math.round(settings.short_break_secs / 60));
- setLongBreakMins(Math.round(settings.long_break_secs / 60));
- setSessionsBeforeLong(settings.sessions_before_long_break);
+ setWorkMins(clampValue(Math.round(settings.work_duration_secs / 60), 1, 120));
+ setShortBreakMins(clampValue(Math.round(settings.short_break_secs / 60), 1, 60));
+ setLongBreakMins(clampValue(Math.round(settings.long_break_secs / 60), 1, 60));
+ setSessionsBeforeLong(clampValue(settings.sessions_before_long_break, 1, 10));
}
}, [settings]);
if (!open) return null;
const handleSave = async () => {
+ const nextWorkMins = clampValue(workMins, 1, 120);
+ const nextShortBreakMins = clampValue(shortBreakMins, 1, 60);
+ const nextLongBreakMins = clampValue(longBreakMins, 1, 60);
+ const nextSessionsBeforeLong = clampValue(sessionsBeforeLong, 1, 10);
+
+ setWorkMins(nextWorkMins);
+ setShortBreakMins(nextShortBreakMins);
+ setLongBreakMins(nextLongBreakMins);
+ setSessionsBeforeLong(nextSessionsBeforeLong);
+
const s: Settings = {
- work_duration_secs: workMins * 60,
- short_break_secs: shortBreakMins * 60,
- long_break_secs: longBreakMins * 60,
- sessions_before_long_break: sessionsBeforeLong,
+ work_duration_secs: nextWorkMins * 60,
+ short_break_secs: nextShortBreakMins * 60,
+ long_break_secs: nextLongBreakMins * 60,
+ sessions_before_long_break: nextSessionsBeforeLong,
};
await updateSettings(s);
onClose();
@@ -64,7 +76,9 @@ export function SettingsPanel({ open, onClose }: SettingsPanelProps) {
borderRadius: 'var(--r-3)',
boxShadow: 'var(--shadow-3)',
padding: '32px',
- width: '360px',
+ width: 'min(360px, calc(100vw - 32px))',
+ maxHeight: 'calc(100vh - 32px)',
+ overflowY: 'auto',
display: 'flex',
flexDirection: 'column',
gap: '24px',
@@ -109,6 +123,10 @@ export function SettingsPanel({ open, onClose }: SettingsPanelProps) {
/>
</div>
+ <span style={{ fontFamily: 'var(--font-sans)', fontSize: '12px', color: 'var(--fg-4)', lineHeight: 1.4 }}>
+ Values are clamped to sensible minimums before saving.
+ </span>
+
<div style={{ display: 'flex', gap: '8px', justifyContent: 'flex-end' }}>
<button
onClick={onClose}
@@ -203,7 +221,7 @@ function NumberField({ label, unit, value, min, max, onChange }: NumberFieldProp
min={min}
max={max}
value={value}
- onChange={(e) => onChange(Math.min(max, Math.max(min, parseInt(e.target.value) || min)))}
+ onChange={(e) => onChange(clampValue(parseInt(e.target.value, 10) || min, min, max))}
style={{
fontFamily: 'var(--font-mono)',
fontSize: '14px',