import { useEffect, useState } from 'react' import { ScrollView, StyleSheet, Text, View, TouchableOpacity, Alert } from 'react-native' import { router } from 'expo-router' import { useTheme } from '../constants/ThemeContext' import { type ThemeTokens } from '../constants/ItmsTheme' import { Field, Btn, ErrText, SectionTitle } from '../components/ui' import { pick } from '../constants/rows' import { itmsAddReqIncident, itmsServiceCombo, listRows, itmsErrorMessage, type RowMap } from './itmsApi' /* * 서비스 요청 등록(SvcDeskReqController /srm/addReqIncident.do — body {incidentReqVo:{...}}). * 제목/내용 + (선택)서비스 선택. 백엔드 VO 컬럼명이 기관별 상이하므로 흔한 별칭을 함께 전송(방어적). * 성공 판정: resultCd===0(또는 '0'). 실패 시 resultMsg 노출. */ export default function RequestNew() { const { t } = useTheme() const s = makeStyles(t) const [title, setTitle] = useState('') const [content, setContent] = useState('') const [services, setServices] = useState([]) const [svc, setSvc] = useState(null) const [busy, setBusy] = useState(false) const [err, setErr] = useState('') useEffect(() => { let alive = true itmsServiceCombo() .then((p) => { if (alive) setServices(listRows(p)) }) .catch(() => { /* 콤보 없으면 서비스 선택 생략 */ }) return () => { alive = false } }, []) const svcId = (r: RowMap) => pick(r, ['svcSeq', 'serviceSeq', 'svcId', 'serviceId', 'inSvcSeq', 'seq']) const svcNm = (r: RowMap) => pick(r, ['svcNm', 'serviceNm', 'svcName', 'name']) const submit = async () => { if (!title.trim()) { setErr('제목을 입력하세요.'); return } if (!content.trim()) { setErr('요청 내용을 입력하세요.'); return } setBusy(true); setErr('') // 흔한 컬럼 별칭을 함께 채워 기관별 스키마 편차 흡수. const vo: RowMap = { reqTitle: title.trim(), title: title.trim(), incidentTitle: title.trim(), reqCn: content.trim(), contents: content.trim(), incidentCn: content.trim(), reqContents: content.trim(), } if (svc) { const id = svcId(svc) Object.assign(vo, { svcSeq: id, serviceSeq: id, svcId: id, serviceId: id, svcNm: svcNm(svc) }) } try { const res = await itmsAddReqIncident({ incidentReqVo: vo, fileList: [] }) const ok = res?.resultCd === 0 || res?.resultCd === '0' if (ok || res?.inIncidentSeq) { Alert.alert('완료', '서비스 요청이 등록되었습니다.', [{ text: '확인', onPress: () => router.back() }]) } else { setErr(String(res?.resultMsg || '등록에 실패했습니다.')) } } catch (e) { setErr(itmsErrorMessage(e)) } finally { setBusy(false) } } return ( {services.length > 0 && ( <> 서비스 선택 (선택) {services.slice(0, 20).map((r, i) => { const on = svc && svcId(svc) === svcId(r) return ( setSvc(on ? null : r)} > {svcNm(r) || svcId(r)} ) })} )} ) } const makeStyles = (t: ThemeTokens) => StyleSheet.create({ wrap: { flex: 1, backgroundColor: t.bg }, content: { padding: 16 }, mt: { marginTop: 20 }, chips: { flexDirection: 'row', flexWrap: 'wrap', gap: 8 }, chip: { borderWidth: 1, borderColor: t.border, borderRadius: 20, paddingHorizontal: 14, paddingVertical: 8, backgroundColor: t.card, maxWidth: '100%' }, chipText: { fontSize: 13, fontWeight: '700' }, })