diff --git a/src/component/ai_explore/DistanceSlider.tsx b/src/component/ai_explore/DistanceSlider.tsx new file mode 100644 index 0000000..b996a96 --- /dev/null +++ b/src/component/ai_explore/DistanceSlider.tsx @@ -0,0 +1,67 @@ +import { useMemo } from 'react'; +import { cn } from '@/utils/cn'; + +type Props = { + min?: number; + max?: number; + step?: number; + value: number | null; + onChange: (v: number) => void; + className?: string; +}; + +export default function DistanceSlider({ + min = 1, + max = 50, + step = 1, + value, + onChange, + className, +}: Props) { + const safeValue = value ?? min; + const percent = useMemo( + () => Math.round(((safeValue - min) / (max - min)) * 100), + [safeValue, min, max], + ); + return ( +
+
+ 거리(km) + + {value === null ? `N km` : `${safeValue}km`} + +
+
+ {min} + {max} +
+
+
+
+ {/*노브*/} +
+
+ +
+
+ + onChange(Number(e.target.value))} + aria-label="거리 (km)" + className="absolute inset-0 w-full cursor-pointer opacity-0" + /> +
+
+ ); +} diff --git a/src/pages/ai/MainAI.tsx b/src/pages/ai/MainAI.tsx index 747e54e..80612cf 100644 --- a/src/pages/ai/MainAI.tsx +++ b/src/pages/ai/MainAI.tsx @@ -2,22 +2,28 @@ import { useMemo, useState } from 'react'; import { useNavigate } from 'react-router-dom'; import { LabeledInput, Button, Header, Sidebar } from '@/component'; import { useAIExploreStore } from '@/stores/useAIExploreStore'; +import DistanceSlider from '@/component/ai_explore/DistanceSlider'; export default function AiExplorePage() { const navigate = useNavigate(); const address = useAIExploreStore((s) => s.address); const theme = useAIExploreStore((s) => s.theme); + const distanceKm = useAIExploreStore((s) => s.distanceKm); const setAddress = useAIExploreStore((s) => s.setAddress); + const setDistanceKm = useAIExploreStore((s) => s.setDistanceKm); - const isReady = useMemo(() => !!address && !!theme?.subs.length, [address, theme]); + const isReady = useMemo( + () => !!address && !!theme?.subs.length && distanceKm !== null, + [address, theme, distanceKm], + ); const fillSampleAddress = () => { setAddress('경기도 성남시 수정구 성남대로 1342 이렇게 길어지면'); // UI 확인용입니당... 추후 API 연결 }; - const goThemeSelect = () => navigate('/explore/theme'); // ← 쿼리/state 없이 이동 + const goThemeSelect = () => navigate('/explore/theme'); - const startSearch = () => navigate('/explore/result'); // ← 결과 페이지에서 AI 호출 + const startSearch = () => navigate('/explore/result'); const [isSidebarOpen, setIsSidebarOpen] = useState(false); @@ -56,6 +62,8 @@ export default function AiExplorePage() { onClick={goThemeSelect} /> + +
diff --git a/src/stores/useAIExploreStore.ts b/src/stores/useAIExploreStore.ts index 59aa470..c7b1cae 100644 --- a/src/stores/useAIExploreStore.ts +++ b/src/stores/useAIExploreStore.ts @@ -5,15 +5,19 @@ export type ThemeGroup = { main: string; subs: string[] }; type ExploreState = { address: string; theme: ThemeGroup | null; + distanceKm: number | null; setAddress: (v: string) => void; setTheme: (v: ThemeGroup | null) => void; + setDistanceKm: (v: number | null) => void; reset: () => void; }; export const useAIExploreStore = create((set) => ({ address: '', theme: null, + distanceKm: null, setAddress: (v) => set({ address: v }), setTheme: (v) => set({ theme: v }), - reset: () => set({ address: '', theme: null }), + setDistanceKm: (v) => set({ distanceKm: v }), + reset: () => set({ address: '', theme: null, distanceKm: null }), }));