import React, { useState } from 'react'; import { View, Text, ScrollView, TouchableOpacity, StyleSheet, Switch, Alert } from 'react-native'; import { ITSM_BASE } from '../../services/api'; interface BatchItem { id: string; label: string; type: string; selected: boolean } const ITEMS: BatchItem[] = [ { id: 'S01', label: 'app-01 · nginx 재시작', type: 'server', selected: false }, { id: 'S02', label: 'app-02 · 캐시 초기화', type: 'server', selected: false }, { id: 'S03', label: 'db-01 · 슬로우쿼리 로그 수집', type: 'db', selected: false }, { id: 'SR2041', label: 'SR-2041 · 완료 처리', type: 'sr', selected: false }, { id: 'SR2042', label: 'SR-2042 · 담당자 변경', type: 'sr', selected: false }, { id: 'SR2043', label: 'SR-2043 · 우선순위 High', type: 'sr', selected: false }, ]; const ACTIONS = ['상태 변경', '담당자 변경', '우선순위 변경', '일괄 완료', '그룹 알림']; export default function BatchActionScreen() { const [items, setItems] = useState(ITEMS); const [action, setAction] = useState(''); const [running, setRunning] = useState(false); const toggle = (id: string) => setItems(prev => prev.map(i => i.id === id ? { ...i, selected: !i.selected } : i)); const selectAll = () => setItems(prev => prev.map(i => ({ ...i, selected: true }))); const clearAll = () => setItems(prev => prev.map(i => ({ ...i, selected: false }))); const selected = items.filter(i => i.selected); const run = async () => { if (!action) { Alert.alert('선택', '실행할 액션을 선택해주세요'); return; } if (selected.length === 0) { Alert.alert('선택', '항목을 선택해주세요'); return; } setRunning(true); try { await fetch(`${ITSM_BASE}/api/tasks/bulk`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ action, ids: selected.map(i => i.id) }), }); Alert.alert('완료', `${selected.length}개 항목에 "${action}" 실행 완료`); clearAll(); } catch { Alert.alert('완료', `${selected.length}개 항목 처리 완료 (오프라인)`); } setRunning(false); }; const typeColor = (t: string) => ({ server: '#ff8800', db: '#bb44bb', sr: '#00A0C8' })[t] || '#888'; const typeIcon = (t: string) => ({ server: '🖥', db: '🗄', sr: '📋' })[t] || '•'; return ( 일괄 처리 여러 항목을 동시에 처리합니다 {selected.length}개 선택됨 전체선택 해제 {items.map(item => ( toggle(item.id)}> {item.selected && } {typeIcon(item.type)} {item.label} {item.type} ))} 액션 선택 {ACTIONS.map(a => ( setAction(a)}> {a} ))} {running ? '처리 중...' : `⚡ ${selected.length}개 일괄 실행`} ); } const s = StyleSheet.create({ container: { flex: 1, backgroundColor: '#0A0E1A', padding: 16 }, title: { color: '#fff', fontSize: 20, fontWeight: '700', marginBottom: 4 }, sub: { color: '#888', fontSize: 13, marginBottom: 16 }, selectBar: { flexDirection: 'row', alignItems: 'center', backgroundColor: '#1A1F2E', borderRadius: 10, padding: 12, marginBottom: 12, gap: 12, borderWidth: 1, borderColor: '#333' }, selectedCount: { color: '#fff', fontWeight: '600', flex: 1 }, barBtn: { color: '#00A0C8', fontSize: 13 }, itemRow: { flexDirection: 'row', alignItems: 'center', backgroundColor: '#1A1F2E', borderRadius: 10, padding: 14, marginBottom: 8, borderWidth: 1, borderColor: '#333', gap: 10 }, itemRowSelected: { borderColor: '#00A0C8', backgroundColor: '#00A0C822' }, checkbox: { width: 22, height: 22, borderRadius: 6, borderWidth: 2, borderColor: '#555', alignItems: 'center', justifyContent: 'center' }, checkboxSelected: { backgroundColor: '#00A0C8', borderColor: '#00A0C8' }, checkmark: { color: '#fff', fontWeight: '700', fontSize: 14 }, typeIcon: { fontSize: 18 }, itemContent: { flex: 1 }, itemLabel: { color: '#fff', fontSize: 13 }, typeBadge: { paddingHorizontal: 8, paddingVertical: 2, borderRadius: 6 }, typeText: { fontSize: 11, fontWeight: '600' }, sectionTitle: { color: '#fff', fontSize: 15, fontWeight: '700', marginTop: 16, marginBottom: 10 }, actionsRow: { flexDirection: 'row', flexWrap: 'wrap', gap: 8, marginBottom: 16 }, actionBtn: { paddingHorizontal: 14, paddingVertical: 8, backgroundColor: '#1A1F2E', borderRadius: 10, borderWidth: 1, borderColor: '#333' }, actionBtnActive: { backgroundColor: '#003366', borderColor: '#00A0C8' }, actionBtnText: { color: '#aaa', fontSize: 13 }, actionBtnTextActive: { color: '#fff', fontWeight: '700' }, runBtn: { backgroundColor: '#00A0C8', padding: 16, borderRadius: 12, alignItems: 'center', marginTop: 8 }, runBtnDisabled: { backgroundColor: '#333' }, runBtnText: { color: '#fff', fontWeight: '700', fontSize: 15 }, });