feat(aerial): 위성 요청 목록 더보기 → 페이징 처리로 변경

- 더보기/접기 토글 제거
- 페이지당 5건 표시 + ◀ 1 2 ▶ 페이지 네비게이션
- "총 N건 중 1–5" 현재 범위 표시
- 필터 변경 시 전체 목록 대상 페이징 적용

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Nan Kyung Lee 2026-03-17 10:45:55 +09:00
부모 39277c1c02
커밋 8c0ada08fd

파일 보기

@ -99,7 +99,8 @@ export function SatelliteRequest() {
const [statusFilter, setStatusFilter] = useState('전체')
const [modalPhase, setModalPhase] = useState<SatModalPhase>('none')
const [selectedRequest, setSelectedRequest] = useState<SatRequest | null>(null)
const [showMoreCompleted, setShowMoreCompleted] = useState(false)
const [currentPage, setCurrentPage] = useState(1)
const PAGE_SIZE = 5
// UP42 sub-tab
const [up42SubTab, setUp42SubTab] = useState<'optical' | 'sar' | 'elevation'>('optical')
const [up42SelSat, setUp42SelSat] = useState<string | null>(null)
@ -141,9 +142,7 @@ export function SatelliteRequest() {
if (modalPhase === 'up42') loadSatPasses()
}, [modalPhase, loadSatPasses])
const allRequests = showMoreCompleted ? requests : requests.filter(r => (r.status !== '완료' && r.status !== '취소') || r.id === 'SAT-003')
const filtered = allRequests.filter(r => {
const filtered = requests.filter(r => {
if (statusFilter === '전체') return true
if (statusFilter === '대기') return r.status === '대기'
if (statusFilter === '진행') return r.status === '촬영중'
@ -151,6 +150,8 @@ export function SatelliteRequest() {
if (statusFilter === '취소') return r.status === '취소'
return true
})
const totalPages = Math.max(1, Math.ceil(filtered.length / PAGE_SIZE))
const pagedItems = filtered.slice((currentPage - 1) * PAGE_SIZE, currentPage * PAGE_SIZE)
const statusBadge = (s: SatRequest['status']) => {
if (s === '촬영중') return (
@ -257,8 +258,8 @@ export function SatelliteRequest() {
))}
</div>
{/* 데이터 행 */}
{filtered.map(r => (
{/* 데이터 행 (페이징) */}
{pagedItems.map(r => (
<div key={r.id}>
<div
onClick={() => setSelectedRequest(selectedRequest?.id === r.id ? null : r)}
@ -321,11 +322,36 @@ export function SatelliteRequest() {
</div>
))}
<div
onClick={() => setShowMoreCompleted(!showMoreCompleted)}
className="text-center py-2.5 text-[10px] text-text-3 font-korean cursor-pointer hover:text-text-2 transition-colors"
>
{showMoreCompleted ? '▲ 완료 목록 접기' : '▼ 이전 완료 목록 더보기 (6건)'}
{/* 페이징 */}
<div className="flex items-center justify-between px-4 py-2">
<div className="text-[9px] text-text-3 font-korean">
{filtered.length} {(currentPage - 1) * PAGE_SIZE + 1}{Math.min(currentPage * PAGE_SIZE, filtered.length)}
</div>
<div className="flex items-center gap-1">
<button
onClick={() => setCurrentPage(p => Math.max(1, p - 1))}
disabled={currentPage <= 1}
className="px-2 py-1 rounded text-[10px] font-mono cursor-pointer border transition-colors"
style={{ background: 'var(--bg3)', borderColor: 'var(--bd)', color: currentPage <= 1 ? 'var(--t3)' : 'var(--t1)', opacity: currentPage <= 1 ? 0.5 : 1 }}
></button>
{Array.from({ length: totalPages }, (_, i) => i + 1).map(p => (
<button
key={p}
onClick={() => setCurrentPage(p)}
className="w-7 h-7 rounded text-[10px] font-bold font-mono cursor-pointer border transition-colors"
style={currentPage === p
? { background: 'rgba(59,130,246,.15)', borderColor: 'rgba(59,130,246,.3)', color: 'var(--blue)' }
: { background: 'var(--bg3)', borderColor: 'var(--bd)', color: 'var(--t3)' }
}
>{p}</button>
))}
<button
onClick={() => setCurrentPage(p => Math.min(totalPages, p + 1))}
disabled={currentPage >= totalPages}
className="px-2 py-1 rounded text-[10px] font-mono cursor-pointer border transition-colors"
style={{ background: 'var(--bg3)', borderColor: 'var(--bd)', color: currentPage >= totalPages ? 'var(--t3)' : 'var(--t1)', opacity: currentPage >= totalPages ? 0.5 : 1 }}
></button>
</div>
</div>
</div>