fix(responsive): Phase 3 spec compliance 수정

- Blog: 태그 필터 칩 바 모바일 가로 스크롤 추가
- BlogMarketing: FAB 전 탭에서 표시 + 대시보드 480px 1컬럼
- Subscription: PullToRefresh refreshKey 패턴 적용, FAB→공고 목록 탭 이동
- Todo: FAB 라벨 "할일 추가"로 spec 일치

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-23 15:02:12 +09:00
parent c7cad9da61
commit 901cfd7e1b
5 changed files with 25 additions and 51 deletions

View File

@@ -4,7 +4,6 @@ import { apiGet, apiPost, apiPut, apiDelete } from '../../api';
import { useIsMobile } from '../../hooks/useIsMobile';
import PullToRefresh from '../../components/PullToRefresh';
import FAB from '../../components/FAB';
import MobileSheet from '../../components/MobileSheet';
import './Subscription.css';
// ── 상수 ───────────────────────────────────────────────────────────────────────
@@ -1302,19 +1301,18 @@ function ProfileTab() {
function Subscription() {
const isMobile = useIsMobile();
const [activeTab, setActiveTab] = useState(0);
const [filterSheetOpen, setFilterSheetOpen] = useState(false);
const [refreshKey, setRefreshKey] = useState(0);
const handleRefresh = useCallback(async () => {
setRefreshKey(k => k + 1);
}, []);
const handleFABClick = useCallback(() => {
if (activeTab === 0) {
// DashboardTab — open filter sheet or scroll to collect
setFilterSheetOpen(true);
} else {
setFilterSheetOpen(true);
}
}, [activeTab]);
setActiveTab(1); // 공고 목록 탭으로 이동
}, []);
return (
<PullToRefresh onRefresh={useCallback(async () => {}, [])}>
<PullToRefresh onRefresh={handleRefresh}>
<div className="sub">
{/* Header */}
<div className="sub-header">
@@ -1344,42 +1342,13 @@ function Subscription() {
{/* Body */}
<div className="sub-body">
{activeTab === 0 && <DashboardTab />}
{activeTab === 1 && <AnnouncementsTab />}
{activeTab === 2 && <MatchesTab />}
{activeTab === 3 && <ProfileTab />}
{activeTab === 0 && <DashboardTab key={`dash-${refreshKey}`} />}
{activeTab === 1 && <AnnouncementsTab key={`ann-${refreshKey}`} />}
{activeTab === 2 && <MatchesTab key={`match-${refreshKey}`} />}
{activeTab === 3 && <ProfileTab key={`prof-${refreshKey}`} />}
</div>
<MobileSheet
open={filterSheetOpen}
onClose={() => setFilterSheetOpen(false)}
title="필터"
snap="half"
>
<div style={{ padding: '8px 0' }}>
<p style={{ fontSize: '0.85rem', color: 'var(--text-muted)', marginBottom: 12 }}>
탭을 선택하여 원하는 화면으로 이동하세요.
</p>
{TABS.map((tab, i) => (
<button
key={tab}
onClick={() => { setActiveTab(i); setFilterSheetOpen(false); }}
style={{
display: 'block', width: '100%', padding: '12px 16px',
textAlign: 'left', background: activeTab === i ? 'rgba(244,63,94,0.1)' : 'transparent',
border: 'none', borderRadius: 8, cursor: 'pointer',
color: activeTab === i ? '#f43f5e' : 'var(--text-primary)',
fontSize: '0.9rem', fontWeight: activeTab === i ? 700 : 400,
marginBottom: 4,
}}
>
{tab}
</button>
))}
</div>
</MobileSheet>
<FAB onClick={handleFABClick} label="공고 등록" />
<FAB onClick={handleFABClick} label="공고 목록" />
</div>
</PullToRefresh>
);