136 lines
4.9 KiB
TypeScript
136 lines
4.9 KiB
TypeScript
'use client';
|
|
|
|
import { useState } from 'react';
|
|
import type { SceneTheme } from '@/entities/scene';
|
|
import type { TimerPreset } from '@/entities/session';
|
|
import { DEFAULT_PRESET_OPTIONS } from '@/shared/config/settingsOptions';
|
|
import { cn } from '@/shared/lib/cn';
|
|
|
|
interface SettingsToolPanelProps {
|
|
scenes: SceneTheme[];
|
|
selectedSceneId: string;
|
|
selectedTimerLabel: string;
|
|
timerPresets: TimerPreset[];
|
|
onSelectScene: (sceneId: string) => void;
|
|
onSelectTimer: (timerLabel: string) => void;
|
|
}
|
|
|
|
export const SettingsToolPanel = ({
|
|
scenes,
|
|
selectedSceneId,
|
|
selectedTimerLabel,
|
|
timerPresets,
|
|
onSelectScene,
|
|
onSelectTimer,
|
|
}: SettingsToolPanelProps) => {
|
|
const [reduceMotion, setReduceMotion] = useState(false);
|
|
const [defaultPresetId, setDefaultPresetId] = useState<
|
|
(typeof DEFAULT_PRESET_OPTIONS)[number]['id']
|
|
>(DEFAULT_PRESET_OPTIONS[0].id);
|
|
|
|
return (
|
|
<div className="space-y-4">
|
|
<section className="rounded-2xl border border-white/14 bg-white/7 px-3.5 py-3">
|
|
<div className="flex items-center justify-between gap-3">
|
|
<div>
|
|
<p className="text-sm font-medium text-white">Reduce Motion</p>
|
|
<p className="mt-1 text-xs text-white/58">화면 전환을 조금 더 차분하게 표시합니다.</p>
|
|
</div>
|
|
<button
|
|
type="button"
|
|
role="switch"
|
|
aria-checked={reduceMotion}
|
|
onClick={() => setReduceMotion((current) => !current)}
|
|
className={cn(
|
|
'inline-flex w-14 items-center rounded-full border px-1 py-1 transition-colors',
|
|
reduceMotion
|
|
? 'border-sky-200/44 bg-sky-200/24'
|
|
: 'border-white/24 bg-white/9',
|
|
)}
|
|
>
|
|
<span
|
|
className={cn(
|
|
'h-4.5 w-4.5 rounded-full bg-white transition-transform duration-200 motion-reduce:transition-none',
|
|
reduceMotion ? 'translate-x-7' : 'translate-x-0',
|
|
)}
|
|
/>
|
|
</button>
|
|
</div>
|
|
</section>
|
|
|
|
<section className="rounded-2xl border border-white/14 bg-white/7 px-3.5 py-3">
|
|
<p className="text-sm font-medium text-white">배경</p>
|
|
<p className="mt-1 text-xs text-white/58">몰입 중에도 배경 scene을 바꿀 수 있어요.</p>
|
|
<div className="mt-2 flex flex-wrap gap-2">
|
|
{scenes.slice(0, 4).map((scene) => {
|
|
const selected = scene.id === selectedSceneId;
|
|
|
|
return (
|
|
<button
|
|
key={scene.id}
|
|
type="button"
|
|
onClick={() => onSelectScene(scene.id)}
|
|
className={cn(
|
|
'rounded-full border px-3 py-1.5 text-xs transition-colors',
|
|
selected
|
|
? 'border-sky-200/44 bg-sky-200/20 text-sky-100'
|
|
: 'border-white/18 bg-white/8 text-white/80 hover:bg-white/14',
|
|
)}
|
|
>
|
|
{scene.name}
|
|
</button>
|
|
);
|
|
})}
|
|
</div>
|
|
</section>
|
|
|
|
<section className="rounded-2xl border border-white/14 bg-white/7 px-3.5 py-3">
|
|
<p className="text-sm font-medium text-white">타이머 프리셋</p>
|
|
<p className="mt-1 text-xs text-white/58">기본 프리셋만 빠르게 고를 수 있어요.</p>
|
|
<div className="mt-2 flex flex-wrap gap-2">
|
|
{timerPresets.slice(0, 3).map((preset) => {
|
|
const selected = preset.label === selectedTimerLabel;
|
|
|
|
return (
|
|
<button
|
|
key={preset.id}
|
|
type="button"
|
|
onClick={() => onSelectTimer(preset.label)}
|
|
className={cn(
|
|
'rounded-full border px-3 py-1.5 text-xs transition-colors',
|
|
selected
|
|
? 'border-sky-200/44 bg-sky-200/20 text-sky-100'
|
|
: 'border-white/18 bg-white/8 text-white/80 hover:bg-white/14',
|
|
)}
|
|
>
|
|
{preset.label}
|
|
</button>
|
|
);
|
|
})}
|
|
</div>
|
|
</section>
|
|
|
|
<section className="rounded-2xl border border-white/14 bg-white/7 px-3.5 py-3">
|
|
<p className="text-sm font-medium text-white">기본 프리셋</p>
|
|
<div className="mt-2 flex flex-wrap gap-2">
|
|
{DEFAULT_PRESET_OPTIONS.map((preset) => (
|
|
<button
|
|
key={preset.id}
|
|
type="button"
|
|
onClick={() => setDefaultPresetId(preset.id)}
|
|
className={cn(
|
|
'rounded-full border px-3 py-1.5 text-xs transition-colors',
|
|
defaultPresetId === preset.id
|
|
? 'border-sky-200/44 bg-sky-200/20 text-sky-100'
|
|
: 'border-white/18 bg-white/8 text-white/80 hover:bg-white/14',
|
|
)}
|
|
>
|
|
{preset.label}
|
|
</button>
|
|
))}
|
|
</div>
|
|
</section>
|
|
</div>
|
|
);
|
|
};
|