import React, { useState, useEffect, useRef } from "react"; const formatWon = (n) => { if (Math.abs(n) >= 100000000) return `${(n / 100000000).toFixed(1)}억`; if (Math.abs(n) >= 10000) return `${Math.round(n / 10000).toLocaleString()}만원`; return `${Math.round(n).toLocaleString()}원`; }; const formatWonFull = (n) => `${Math.round(n).toLocaleString()}원`; function AnimatedNumber({ value, duration = 1000 }) { const [display, setDisplay] = useState(0); const start = useRef(0); const startTime = useRef(null); const raf = useRef(null); useEffect(() => { start.current = display; startTime.current = null; const animate = (ts) => { if (!startTime.current) startTime.current = ts; const progress = Math.min((ts - startTime.current) / duration, 1); const ease = 1 - Math.pow(1 - progress, 4); setDisplay(Math.round(start.current + (value - start.current) * ease)); if (progress < 1) raf.current = requestAnimationFrame(animate); }; raf.current = requestAnimationFrame(animate); return () => cancelAnimationFrame(raf.current); }, [value]); return {display.toLocaleString()}; } const steps = [ { id: 1, label: "현재 직장", icon: "🏢" }, { id: 2, label: "이직 제안", icon: "🚀" }, { id: 3, label: "결과 분석", icon: "📊" }, ]; const InputField = ({ label, value, onChange, unit = "만원", hint }) => (
onChange(Number(e.target.value))} style={{ flex: 1, background: "transparent", border: "none", outline: "none", color: "#f0f4ff", fontSize: 22, fontFamily: "monospace", fontWeight: 600, padding: "14px 16px", width: "100%" }} /> {unit}
{hint &&

{hint}

}
); export default function App() { const [step, setStep] = useState(1); const [showResult, setShowResult] = useState(false); const [current, setCurrent] = useState({ salary: 4500, commute: 45, welfare: 30, tenure: 3 }); const [offer, setOffer] = useState({ salary: 5500, commute: 30, welfare: 20 }); const hourlyWage = (current.salary * 10000) / (12 * 20 * 8); const commuteDiffMinutes = (current.commute - offer.commute) * 2 * 250; const commuteValueYear = (commuteDiffMinutes / 60) * hourlyWage; const salaryDiff = (offer.salary - current.salary) * 10000; const welfareDiff = (offer.welfare - current.welfare) * 10000 * 12; const severanceLoss = (current.salary * 10000) / 12 * current.tenure; const totalBenefitYear = salaryDiff + welfareDiff + commuteValueYear - severanceLoss; const totalBenefitMonth = totalBenefitYear / 12; const isGood = totalBenefitYear > 0; const factors = [ { label: "연봉 차이", value: salaryDiff }, { label: "복지 차이", value: welfareDiff }, { label: "통근 시간 절감 가치", value: commuteValueYear }, { label: "퇴직금 손실", value: -severanceLoss }, ]; const barMax = Math.max(...factors.map(f => Math.abs(f.value))); return (

이직, 진짜 이득일까?

연봉만 보면 안 됩니다. 통근·복지·퇴직금까지 실질 손익 계산

{steps.map((s, i) => (
step > s.id && setStep(s.id)} style={{ display: "flex", alignItems: "center", gap: 8, padding: "8px 16px", background: step === s.id ? "rgba(0,212,170,0.15)" : "rgba(255,255,255,0.03)", border: `1px solid ${step === s.id ? "rgba(0,212,170,0.5)" : "rgba(255,255,255,0.06)"}`, borderRadius: 999, cursor: step > s.id ? "pointer" : "default" }}> {step > s.id ? "✓" : s.icon} {s.label}
{i < steps.length - 1 &&
}
))}
{step === 1 && (

🏢 현재 직장 정보

setCurrent(p => ({ ...p, salary: v }))} hint="세전 기준" /> setCurrent(p => ({ ...p, commute: v }))} unit="분" /> setCurrent(p => ({ ...p, welfare: v }))} hint="식대·교통비 등 합산" /> setCurrent(p => ({ ...p, tenure: v }))} unit="년" hint="퇴직금 계산에 사용" />
)} {step === 2 && (

🚀 이직 제안 정보

setOffer(p => ({ ...p, salary: v }))} /> setOffer(p => ({ ...p, commute: v }))} unit="분" /> setOffer(p => ({ ...p, welfare: v }))} hint="식대·교통비 등 합산" />

표면적 연봉 차이

0 ? "#00d4aa" : "#ff6b6b", fontFamily: "monospace" }}> {(offer.salary - current.salary) > 0 ? "+" : ""}{(offer.salary - current.salary).toLocaleString()}만원

)} {step === 3 && (
{isGood ? "🎯" : "🤔"}

{isGood ? "이직 유리 판정" : "이직 불리 판정"}

{isGood ? "+" : "-"}만원/월

연간 실질 {isGood ? "이득" : "손해"}: {formatWon(Math.abs(totalBenefitYear))}

항목별 분석

{factors.map((f, i) => (
{f.label} = 0 ? "#00d4aa" : "#ff6b6b", fontFamily: "monospace" }}> {f.value >= 0 ? "+" : ""}{formatWon(f.value)}
= 0 ? "linear-gradient(90deg, #00d4aa, #00a884)" : "linear-gradient(90deg, #ff6b6b, #ff4444)", borderRadius: 999, transition: "width 0.8s ease" }} />
))}
{isGood && (

이직이 유리하다면, 이력서부터 준비해보세요

원티드 · 사람인 · 리멤버에서 무료로 시작

)}
)}

※ 추정치입니다. 실제 세금·퇴직금 산정과 다를 수 있습니다.

); }

전체 글 0