refactor(home): Profile 섹션 portfolio API 연동
- /api/profile/public에서 프로필·기술스택 동적 로드 - 서비스 미가동 시 하드코딩 폴백 유지 - "프로필 수정" → "포트폴리오 보기" Link로 교체 - 타임라인 섹션 제거 (포트폴리오 페이지에서 관리) Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -23,6 +23,14 @@ const Home = () => {
|
|||||||
const isMobile = useIsMobile();
|
const isMobile = useIsMobile();
|
||||||
|
|
||||||
const [todosByStatus, setTodosByStatus] = useState({ todo: [], in_progress: [], done: [] });
|
const [todosByStatus, setTodosByStatus] = useState({ todo: [], in_progress: [], done: [] });
|
||||||
|
const [portfolio, setPortfolio] = useState(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
fetch('/api/profile/public')
|
||||||
|
.then(r => r.ok ? r.json() : null)
|
||||||
|
.catch(() => null)
|
||||||
|
.then(d => setPortfolio(d));
|
||||||
|
}, []);
|
||||||
|
|
||||||
const loadTodos = useCallback(async () => {
|
const loadTodos = useCallback(async () => {
|
||||||
const data = await getTodos();
|
const data = await getTodos();
|
||||||
@@ -222,47 +230,30 @@ const Home = () => {
|
|||||||
<div className="home-profile__identity">
|
<div className="home-profile__identity">
|
||||||
<img
|
<img
|
||||||
className="home-profile__avatar"
|
className="home-profile__avatar"
|
||||||
src={myPhoto}
|
src={portfolio?.profile?.photo_url || myPhoto}
|
||||||
alt="Profile"
|
alt="Profile"
|
||||||
/>
|
/>
|
||||||
<div>
|
<div>
|
||||||
<p className="home-profile__role">Server Developer</p>
|
<p className="home-profile__role">{portfolio?.profile?.role || 'Server Developer'}</p>
|
||||||
<p className="home-profile__name">박 재 오</p>
|
<p className="home-profile__name">{portfolio?.profile?.name || '박 재 오'}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p className="home-profile__bio">
|
<p className="home-profile__bio">
|
||||||
주변 동료와 함께 소통하며 성장하는걸 좋아합니다. <br />
|
{portfolio?.profile?.bio || '주변 동료와 함께 소통하며 성장하는걸 좋아합니다.'}
|
||||||
성능 최적화, 인프라 자동화를 중요하게 생각합니다. <br />
|
|
||||||
여행과 사진, 새로운 기술 탐구를 좋아합니다.
|
|
||||||
</p>
|
</p>
|
||||||
<div className="home-profile__timeline">
|
|
||||||
<p className="home-profile__section-title">연혁</p>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
<span className="timeline-period">2023.02 - 현재</span>
|
|
||||||
<strong>Server Developer</strong>
|
|
||||||
<span>내비 TIS 교통 서버 / 현대오토에버</span>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span className="timeline-period">2020.01 - 2023.02</span>
|
|
||||||
<strong>Embedded Device SW Developer</strong>
|
|
||||||
<span>캐시비 단말기 개발 / 롯데정보통신</span>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<span className="timeline-period">2019.07 - 2019.12</span>
|
|
||||||
<strong>SSAFY - 삼성 SW Academy</strong>
|
|
||||||
<span>SSAFY 1기 수료</span>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
<div className="home-profile__tags">
|
<div className="home-profile__tags">
|
||||||
{['C++', 'Git', 'AWS', 'Jira', 'MySQL', 'Docker', 'Kubernetes', 'Linux'].map((tag) => (
|
{(portfolio?.skills || []).slice(0, 8).map((s) => (
|
||||||
|
<span key={s.id || s.name}>{s.name}</span>
|
||||||
|
))}
|
||||||
|
{!portfolio && ['C++', 'Git', 'AWS', 'Jira', 'MySQL', 'Docker', 'Kubernetes', 'Linux'].map((tag) => (
|
||||||
<span key={tag}>{tag}</span>
|
<span key={tag}>{tag}</span>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
<div className="home-profile__actions">
|
<div className="home-profile__actions">
|
||||||
<button className="button ghost">프로필 수정</button>
|
<Link className="button ghost" to="/portfolio">
|
||||||
<a className="button primary" href="mailto:bgg8988@gmail.com">
|
포트폴리오 보기
|
||||||
|
</Link>
|
||||||
|
<a className="button primary" href={`mailto:${portfolio?.profile?.email || 'bgg8988@gmail.com'}`}>
|
||||||
연락하기
|
연락하기
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user