feat(realestate): 청약 가점 현황 카드 + 매칭 가점 비교
- 내 프로필 탭: 가점 현황 카드 (무주택/부양가족/통장 프로그레스 바) - 매칭 결과 탭: 상단에 내 가점 뱃지, 각 카드에 가점 표시 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -741,6 +741,7 @@ function AnnouncementsTab() {
|
|||||||
function MatchesTab() {
|
function MatchesTab() {
|
||||||
const [items, setItems] = useState([]);
|
const [items, setItems] = useState([]);
|
||||||
const [total, setTotal] = useState(0);
|
const [total, setTotal] = useState(0);
|
||||||
|
const [myPoints, setMyPoints] = useState(null);
|
||||||
const [page, setPage] = useState(1);
|
const [page, setPage] = useState(1);
|
||||||
const [refreshing, setRefreshing] = useState(false);
|
const [refreshing, setRefreshing] = useState(false);
|
||||||
const [loading, setLoading] = useState(true);
|
const [loading, setLoading] = useState(true);
|
||||||
@@ -753,6 +754,7 @@ function MatchesTab() {
|
|||||||
const data = await apiGet(`/api/realestate/matches?page=${page}&size=${size}`);
|
const data = await apiGet(`/api/realestate/matches?page=${page}&size=${size}`);
|
||||||
setItems(data.items || []);
|
setItems(data.items || []);
|
||||||
setTotal(data.total || 0);
|
setTotal(data.total || 0);
|
||||||
|
if (data.my_points) setMyPoints(data.my_points);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.error('Matches load error:', e);
|
console.error('Matches load error:', e);
|
||||||
setItems([]);
|
setItems([]);
|
||||||
@@ -789,9 +791,20 @@ function MatchesTab() {
|
|||||||
return (
|
return (
|
||||||
<div style={{ display: 'grid', gap: 16 }}>
|
<div style={{ display: 'grid', gap: 16 }}>
|
||||||
<div className="sub-tabs-bar">
|
<div className="sub-tabs-bar">
|
||||||
|
<div style={{ display: 'flex', alignItems: 'center', gap: 12 }}>
|
||||||
<p style={{ margin: 0, fontSize: 13, color: 'var(--text-dim)' }}>
|
<p style={{ margin: 0, fontSize: 13, color: 'var(--text-dim)' }}>
|
||||||
총 {total}건의 매칭 결과
|
총 {total}건의 매칭 결과
|
||||||
</p>
|
</p>
|
||||||
|
{myPoints && (
|
||||||
|
<span className="sub-badge" style={{
|
||||||
|
color: myPoints.total >= 60 ? '#34d399' : myPoints.total >= 40 ? '#f59e0b' : '#f87171',
|
||||||
|
background: myPoints.total >= 60 ? 'rgba(52,211,153,0.1)' : myPoints.total >= 40 ? 'rgba(245,158,11,0.1)' : 'rgba(248,113,113,0.1)',
|
||||||
|
fontWeight: 700, fontSize: 12,
|
||||||
|
}}>
|
||||||
|
내 가점 {myPoints.total}/{myPoints.max_total}
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
<button
|
<button
|
||||||
className="sub-filter-btn is-active"
|
className="sub-filter-btn is-active"
|
||||||
onClick={handleRefresh}
|
onClick={handleRefresh}
|
||||||
@@ -868,7 +881,8 @@ function MatchesTab() {
|
|||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div style={{ textAlign: 'center', flexShrink: 0 }}>
|
<div style={{ textAlign: 'center', flexShrink: 0, display: 'grid', gap: 6 }}>
|
||||||
|
<div>
|
||||||
<div style={{
|
<div style={{
|
||||||
fontFamily: 'var(--font-display)',
|
fontFamily: 'var(--font-display)',
|
||||||
fontSize: 28,
|
fontSize: 28,
|
||||||
@@ -882,6 +896,17 @@ function MatchesTab() {
|
|||||||
매칭 점수
|
매칭 점수
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
{myPoints && (
|
||||||
|
<div style={{
|
||||||
|
fontSize: 11, padding: '3px 8px', borderRadius: 4,
|
||||||
|
background: myPoints.total >= 50 ? 'rgba(52,211,153,0.1)' : 'rgba(248,113,113,0.1)',
|
||||||
|
color: myPoints.total >= 50 ? '#34d399' : '#f87171',
|
||||||
|
fontWeight: 600, whiteSpace: 'nowrap',
|
||||||
|
}}>
|
||||||
|
가점 {myPoints.total}점
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
@@ -985,7 +1010,53 @@ function ProfileTab() {
|
|||||||
|
|
||||||
if (loading) return <div className="sub-empty">불러오는 중...</div>;
|
if (loading) return <div className="sub-empty">불러오는 중...</div>;
|
||||||
|
|
||||||
|
const pts = profile.subscription_points;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
<div style={{ display: 'grid', gap: 16 }}>
|
||||||
|
{/* 가점 카드 */}
|
||||||
|
{pts && pts.total > 0 && (
|
||||||
|
<div className="sub-panel">
|
||||||
|
<div className="sub-panel__head">
|
||||||
|
<div>
|
||||||
|
<p className="sub-panel__eyebrow">청약 가점</p>
|
||||||
|
<h3>내 가점 현황</h3>
|
||||||
|
</div>
|
||||||
|
<div style={{
|
||||||
|
fontFamily: 'var(--font-display)', fontSize: 36, fontWeight: 700,
|
||||||
|
color: pts.total >= 60 ? '#34d399' : pts.total >= 40 ? '#f59e0b' : '#f87171',
|
||||||
|
lineHeight: 1,
|
||||||
|
}}>
|
||||||
|
{pts.total}<span style={{ fontSize: 16, color: 'var(--text-muted)', fontWeight: 400 }}> / {pts.max_total}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="sub-panel__body" style={{ display: 'grid', gap: 12 }}>
|
||||||
|
{[
|
||||||
|
{ label: '무주택기간', data: pts.homeless_duration, color: '#00d4ff' },
|
||||||
|
{ label: '부양가족 수', data: pts.dependents, color: '#8b5cf6' },
|
||||||
|
{ label: '청약통장 가입기간', data: pts.subscription_period, color: '#f59e0b' },
|
||||||
|
].map(({ label, data, color }) => (
|
||||||
|
<div key={label} style={{ display: 'grid', gap: 4 }}>
|
||||||
|
<div style={{ display: 'flex', justifyContent: 'space-between', fontSize: 13 }}>
|
||||||
|
<span style={{ color: 'var(--text-bright)', fontWeight: 500 }}>{label}</span>
|
||||||
|
<span>
|
||||||
|
<span style={{ fontWeight: 700, color }}>{data.score}</span>
|
||||||
|
<span style={{ color: 'var(--text-dim)' }}> / {data.max}</span>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
<div style={{ height: 6, borderRadius: 3, background: 'var(--surface-raised)', overflow: 'hidden' }}>
|
||||||
|
<div style={{
|
||||||
|
height: '100%', borderRadius: 3, background: color,
|
||||||
|
width: `${(data.score / data.max) * 100}%`, transition: 'width 0.3s',
|
||||||
|
}} />
|
||||||
|
</div>
|
||||||
|
<span style={{ fontSize: 11, color: 'var(--text-muted)' }}>{data.detail}</span>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
<div className="sub-panel">
|
<div className="sub-panel">
|
||||||
<div className="sub-panel__head">
|
<div className="sub-panel__head">
|
||||||
<div>
|
<div>
|
||||||
@@ -1198,6 +1269,7 @@ function ProfileTab() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user