import React, { useState, useEffect, useRef } from 'react'; import { View, Text, ScrollView, TextInput, TouchableOpacity, StyleSheet, KeyboardAvoidingView, Platform } from 'react-native'; import { ITSM_BASE } from '../../services/api'; interface CoworkMsg { id: string; author: string; role: string; text: string; ts: string; type: 'chat' | 'action' | 'status' } const SAMPLE_MSGS: CoworkMsg[] = [ { id: '1', author: '김철수', role: 'engineer', text: 'db-01 서버 CPU 90% 넘어갔어요. 확인 부탁드립니다.', ts: '10:02', type: 'chat' }, { id: '2', author: 'AI', role: 'ai', text: '원인 분석 완료: db-01 슬로우 쿼리 20개 감지. 쿼리 최적화 또는 서버 재시작 권장.', ts: '10:02', type: 'action' }, { id: '3', author: '이영희', role: 'pm', text: 'SR 우선순위 Critical로 변경했습니다.', ts: '10:03', type: 'status' }, ]; export default function CoworkSRScreen() { const [srId] = useState('SR-2042'); const [messages, setMessages] = useState(SAMPLE_MSGS); const [input, setInput] = useState(''); const [participants] = useState([{ name: '김철수', role: 'engineer', online: true }, { name: '이영희', role: 'pm', online: true }, { name: 'AI', role: 'ai', online: true }]); const scrollRef = useRef(null); const send = async () => { if (!input.trim()) return; const msg: CoworkMsg = { id: Date.now().toString(), author: '나', role: 'engineer', text: input, ts: new Date().toLocaleTimeString('ko', { hour: '2-digit', minute: '2-digit' }), type: 'chat' }; setMessages(prev => [...prev, msg]); setInput(''); try { await fetch(`${ITSM_BASE}/api/sr-chat/${srId}/messages`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ text: input }), }); } catch {} setTimeout(() => scrollRef.current?.scrollToEnd(), 100); }; const roleColor = (role: string) => ({ engineer: '#00A0C8', pm: '#ffbb00', ai: '#44bb44', sm: '#bb44bb' })[role] || '#888'; return ( {srId} 공동 대응 {participants.map((p, i) => ( {p.name[0]} {p.online && } ))} scrollRef.current?.scrollToEnd()}> {messages.map(msg => ( {msg.author !== '나' && ( {msg.author[0]} )} {msg.author !== '나' && {msg.author}} {msg.text} {msg.ts} ))} 전송 ); } const s = StyleSheet.create({ container: { flex: 1, backgroundColor: '#0A0E1A' }, header: { flexDirection: 'row', justifyContent: 'space-between', alignItems: 'center', padding: 14, borderBottomWidth: 1, borderBottomColor: '#333' }, srTitle: { color: '#fff', fontWeight: '700', fontSize: 16 }, participants: { flexDirection: 'row', gap: 6 }, avatar: { width: 30, height: 30, borderRadius: 15, borderWidth: 1, alignItems: 'center', justifyContent: 'center', position: 'relative' }, avatarText: { fontSize: 13, fontWeight: '700' }, onlineDot: { position: 'absolute', bottom: 0, right: 0, width: 8, height: 8, borderRadius: 4, backgroundColor: '#44bb44', borderWidth: 1, borderColor: '#0A0E1A' }, messages: { flex: 1, padding: 12 }, msgRow: { flexDirection: 'row', marginBottom: 12, alignItems: 'flex-end' }, msgRowRight: { justifyContent: 'flex-end' }, msgAvatar: { width: 28, height: 28, borderRadius: 14, alignItems: 'center', justifyContent: 'center', marginRight: 8 }, msgAvatarText: { fontSize: 12, fontWeight: '700' }, msgBubble: { backgroundColor: '#1A1F2E', borderRadius: 12, padding: 10, maxWidth: '75%', borderWidth: 1, borderColor: '#333' }, msgBubbleAction: { borderColor: '#44bb44', backgroundColor: '#44bb4422' }, msgBubbleStatus: { borderColor: '#ffbb00', backgroundColor: '#ffbb0022' }, msgBubbleSelf: { backgroundColor: '#003366', borderColor: '#00A0C8' }, msgAuthor: { fontSize: 11, fontWeight: '700', marginBottom: 4 }, msgText: { color: '#fff', fontSize: 14 }, msgTs: { color: '#555', fontSize: 10, marginTop: 4, textAlign: 'right' }, inputRow: { flexDirection: 'row', padding: 12, borderTopWidth: 1, borderTopColor: '#333' }, input: { flex: 1, backgroundColor: '#1A1F2E', borderRadius: 10, color: '#fff', paddingHorizontal: 14, paddingVertical: 10, borderWidth: 1, borderColor: '#333', marginRight: 10 }, sendBtn: { backgroundColor: '#00A0C8', paddingHorizontal: 16, borderRadius: 10, justifyContent: 'center' }, sendText: { color: '#fff', fontWeight: '700' }, });