5minbetter's picture
Deploy to Hugging Face
cc7330c
'use client';
/**
* @license
* SPDX-License-Identifier: Apache-2.0
*/
import { useState, useEffect } from 'react';
import { SearchParams } from '../../types/diagnosis';
import { motion } from 'framer-motion';
import { SearchSelect, SearchRadioGroup, SearchInput } from './SearchComponents';
import { diagnosisService } from '../../services/diagnosisService';
export function SearchView({
params,
setParams,
onNext,
onReset
}: {
params: SearchParams;
setParams: (p: SearchParams) => void;
onNext: () => void;
onReset?: () => void;
}) {
const [options, setOptions] = useState<{
jobs: string[];
bms: string[];
sales: string[];
emps: string[];
userBases: string[];
}>({
jobs: [],
bms: [],
sales: [],
emps: [],
userBases: ['지급총액', '고정급']
});
useEffect(() => {
async function fetchOpts() {
try {
const data = await diagnosisService.getOptions({
job: params.job,
bm: params.bm,
sales: params.sales
});
setOptions(prev => ({
jobs: data.job_options?.length ? data.job_options : prev.jobs,
bms: data.bm_options?.length ? data.bm_options : prev.bms,
sales: data.sales_options?.length ? data.sales_options : prev.sales,
emps: data.emp_options?.length ? data.emp_options : prev.emps,
userBases: ['지급총액', '고정급'],
}));
let newParams = { ...params };
let modified = false;
if (data.job_options?.length && newParams.job && !data.job_options.includes(newParams.job)) {
newParams.job = '';
modified = true;
}
if (data.bm_options?.length && !data.bm_options.includes(newParams.bm)) {
newParams.bm = data.bm_options[0];
modified = true;
}
if (data.sales_options?.length && !data.sales_options.includes(newParams.sales)) {
newParams.sales = data.sales_options[0];
modified = true;
}
if (data.emp_options?.length && !data.emp_options.includes(newParams.emp)) {
newParams.emp = data.emp_options[0];
modified = true;
}
if (modified && newParams.job) {
setParams(newParams);
}
} catch (e) {
console.error("Failed to load dynamic options", e);
}
}
fetchOpts();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [params.job, params.bm, params.sales, setParams]);
return (
<div className="w-screen sm:w-auto relative left-1/2 right-1/2 -ml-[50vw] -mr-[50vw] sm:static sm:left-auto sm:right-auto sm:mx-auto sm:my-0 sm:max-w-3xl py-6 sm:py-12 px-0 sm:px-6">
<motion.div initial={{ opacity: 0, y: 20 }} animate={{ opacity: 1, y: 0 }} className="space-y-10">
<div className="text-center space-y-4">
<h2 className="text-3xl font-bold text-slate-900 tracking-tight">상세 분석 조건 설정</h2>
<p className="text-slate-500 font-medium">정확한 시장 임금 비교를 위해 현재 상태를 입력해주세요.</p>
</div>
<div className="bg-white p-4 sm:p-8 md:p-12 border border-slate-100 rounded-[2rem] sm:rounded-[2.5rem] shadow-2xl shadow-slate-100 space-y-7 sm:space-y-10">
<SearchRadioGroup
label="직무 선택"
name="job"
value={params.job}
options={options.jobs}
onChange={val => setParams({
...params,
job: val,
bm: '',
sales: '',
emp: ''
})}
/>
<div className="space-y-10">
{/* 1row : 비즈니스 모델 */}
<SearchSelect
label="비즈니스 모델"
value={params.bm}
options={options.bms}
onChange={val => setParams({ ...params, bm: val })}
/>
{/* 2row : 매출규모 + 직원규모 */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-8">
<SearchSelect
label="매출 규모"
value={params.sales}
options={options.sales}
onChange={val => setParams({ ...params, sales: val })}
/>
<SearchSelect
label="직원 규모"
value={params.emp}
options={options.emps}
onChange={val => setParams({ ...params, emp: val })}
/>
</div>
{/* 3row : 보상단위 + 보상액 */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-8 items-end">
<SearchSelect
label="보상 단위"
value={params.userBase}
options={options.userBases}
onChange={val => setParams({ ...params, userBase: val })}
/>
<SearchInput
label="현재 보상액 (세전)"
value={params.userValue}
unit="만원"
onChange={val => setParams({ ...params, userValue: val })}
/>
</div>
</div>
<div className="grid grid-cols-1 md:grid-cols-4 gap-3 sm:gap-4 mt-8">
<button
onClick={() => {
if (onReset) onReset();
setOptions(prev => ({
...prev,
bms: [],
sales: [],
emps: [],
}));
}}
className="md:col-span-1 h-14 text-base bg-white text-slate-400 border border-slate-100 rounded-[1.5rem] font-bold hover:bg-slate-50 hover:text-slate-600 transition-all active:scale-[0.98]"
>
초기화
</button>
<button
onClick={onNext}
disabled={!params.job}
className={`md:col-span-3 h-14 text-base rounded-[1.5rem] font-bold shadow-2xl transition-all active:scale-[0.98] ${!params.job
? 'bg-slate-200 text-slate-400 cursor-not-allowed'
: 'bg-slate-900 text-white shadow-slate-200 hover:bg-cyan-600 hover:shadow-cyan-200'
}`}
>
진단 시작하기
</button>
</div>
</div>
</motion.div>
</div>
);
}