fix: 프로필 preferred_regions/types 배열 변환 + 필수 입력 표시

- 쉼표 구분 문자열 → List[str] 변환 (백엔드 422 에러 수정)
- API 응답 배열 → 표시용 문자열 변환
- 매칭 필수 필드에 * 표시 (무주택, 세대주, 납입기간, 가족수, 선호지역)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-07 04:43:15 +09:00
parent 0eb55fe731
commit ff0ee3757c

View File

@@ -742,7 +742,10 @@ function ProfileTab() {
try { try {
const data = await apiGet('/api/realestate/profile'); const data = await apiGet('/api/realestate/profile');
if (data && Object.keys(data).length > 0) { if (data && Object.keys(data).length > 0) {
setProfile({ ...DEFAULT_PROFILE, ...data }); const display = { ...DEFAULT_PROFILE, ...data };
if (Array.isArray(display.preferred_regions)) display.preferred_regions = display.preferred_regions.join(', ');
if (Array.isArray(display.preferred_types)) display.preferred_types = display.preferred_types.join(', ');
setProfile(display);
} }
} catch (e) { } catch (e) {
console.error('Profile load error:', e); console.error('Profile load error:', e);
@@ -775,9 +778,24 @@ function ProfileTab() {
payload[k] = null; payload[k] = null;
} }
}); });
// Convert comma-separated strings to arrays
payload.preferred_regions = typeof payload.preferred_regions === 'string'
? payload.preferred_regions.split(',').map(s => s.trim()).filter(Boolean)
: (payload.preferred_regions || []);
payload.preferred_types = typeof payload.preferred_types === 'string'
? payload.preferred_types.split(',').map(s => s.trim()).filter(Boolean)
: (payload.preferred_types || []);
// Send empty arrays as null
if (payload.preferred_regions.length === 0) payload.preferred_regions = null;
if (payload.preferred_types.length === 0) payload.preferred_types = null;
const updated = await apiPut('/api/realestate/profile', payload); const updated = await apiPut('/api/realestate/profile', payload);
if (updated && Object.keys(updated).length > 0) { if (updated && Object.keys(updated).length > 0) {
setProfile({ ...DEFAULT_PROFILE, ...updated }); // Convert arrays back to comma-separated strings for display
const display = { ...DEFAULT_PROFILE, ...updated };
if (Array.isArray(display.preferred_regions)) display.preferred_regions = display.preferred_regions.join(', ');
if (Array.isArray(display.preferred_types)) display.preferred_types = display.preferred_types.join(', ');
setProfile(display);
} }
setMessage('저장 완료'); setMessage('저장 완료');
setTimeout(() => setMessage(''), 2000); setTimeout(() => setMessage(''), 2000);
@@ -789,6 +807,8 @@ function ProfileTab() {
} }
}; };
const reqMark = <span style={{ color: '#f43f5e', marginLeft: 2 }}>*</span>;
if (loading) return <div className="sub-empty">불러오는 ...</div>; if (loading) return <div className="sub-empty">불러오는 ...</div>;
return ( return (
@@ -797,7 +817,7 @@ function ProfileTab() {
<div> <div>
<p className="sub-panel__eyebrow">프로필</p> <p className="sub-panel__eyebrow">프로필</p>
<h3> 청약 프로필</h3> <h3> 청약 프로필</h3>
<p className="sub-panel__sub">자격 조건과 선호 조건을 설정하면 공고 매칭에 활용됩니다.</p> <p className="sub-panel__sub">자격 조건과 선호 조건을 설정하면 공고 매칭에 활용됩니다. <span style={{ color: '#f43f5e', fontSize: 11 }}>* 필수 입력</span></p>
</div> </div>
<div style={{ display: 'flex', gap: 8, alignItems: 'center' }}> <div style={{ display: 'flex', gap: 8, alignItems: 'center' }}>
{message && ( {message && (
@@ -853,11 +873,11 @@ function ProfileTab() {
<div className="sub-form-checks"> <div className="sub-form-checks">
<label className="sub-form-check"> <label className="sub-form-check">
<input type="checkbox" checked={!!profile.is_homeless} onChange={() => handleCheckbox('is_homeless')} /> <input type="checkbox" checked={!!profile.is_homeless} onChange={() => handleCheckbox('is_homeless')} />
무주택자 무주택자{reqMark}
</label> </label>
<label className="sub-form-check"> <label className="sub-form-check">
<input type="checkbox" checked={!!profile.is_householder} onChange={() => handleCheckbox('is_householder')} /> <input type="checkbox" checked={!!profile.is_householder} onChange={() => handleCheckbox('is_householder')} />
세대주 세대주{reqMark}
</label> </label>
<label className="sub-form-check"> <label className="sub-form-check">
<input type="checkbox" checked={!!profile.has_dependents} onChange={() => handleCheckbox('has_dependents')} /> <input type="checkbox" checked={!!profile.has_dependents} onChange={() => handleCheckbox('has_dependents')} />
@@ -879,7 +899,7 @@ function ProfileTab() {
<div className="sub-form-row--three" style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 12 }}> <div className="sub-form-row--three" style={{ display: 'grid', gridTemplateColumns: '1fr 1fr 1fr', gap: 12 }}>
<label className="sub-form-label"> <label className="sub-form-label">
청약 납입 기간 (개월) 청약 납입 기간 (개월){reqMark}
<input <input
className="sub-form-input" className="sub-form-input"
type="number" type="number"
@@ -899,7 +919,7 @@ function ProfileTab() {
/> />
</label> </label>
<label className="sub-form-label"> <label className="sub-form-label">
가족 가족 {reqMark}
<input <input
className="sub-form-input" className="sub-form-input"
type="number" type="number"
@@ -950,7 +970,7 @@ function ProfileTab() {
<div className="sub-form-row"> <div className="sub-form-row">
<label className="sub-form-label"> <label className="sub-form-label">
선호 지역 선호 지역{reqMark}
<input <input
className="sub-form-input" className="sub-form-input"
value={profile.preferred_regions || ''} value={profile.preferred_regions || ''}