97 lines
2.9 KiB
TypeScript
97 lines
2.9 KiB
TypeScript
/**
|
|
* SRSolutionHint (#24) — 과거 유사 SR 해결책 제안
|
|
*
|
|
* GET /api/tasks/?similar_to={sr_id}&status=closed&limit=3
|
|
* "유사 해결 사례" 섹션: 각 사례의 제목 / 해결 방법 / 해결 시간 표시.
|
|
*/
|
|
import { useState, useEffect } from 'react'
|
|
import { View, Text, Pressable, StyleSheet, ActivityIndicator } from 'react-native'
|
|
import { COLORS, API_BASE } from '../constants/Config'
|
|
import { authFetch } from '../utils/auth'
|
|
|
|
interface SimilarSR {
|
|
id: number
|
|
title: string
|
|
resolution?: string
|
|
resolved_at?: string
|
|
resolution_time?: string
|
|
}
|
|
|
|
interface Props {
|
|
srId: number | string
|
|
onOpen?: (id: number) => void
|
|
}
|
|
|
|
export function SRSolutionHint({ srId, onOpen }: Props) {
|
|
const [items, setItems] = useState<SimilarSR[]>([])
|
|
const [loading, setLoading] = useState(true)
|
|
|
|
useEffect(() => {
|
|
let alive = true
|
|
;(async () => {
|
|
setLoading(true)
|
|
try {
|
|
const res = await authFetch(
|
|
`${API_BASE}/api/tasks/?similar_to=${encodeURIComponent(String(srId))}&status=closed&limit=3`,
|
|
)
|
|
if (res.ok) {
|
|
const d = await res.json()
|
|
const list: SimilarSR[] = Array.isArray(d) ? d : d.items ?? d.results ?? []
|
|
if (alive) setItems(list.slice(0, 3))
|
|
} else if (alive) {
|
|
setItems([])
|
|
}
|
|
} catch {
|
|
if (alive) setItems([])
|
|
} finally {
|
|
if (alive) setLoading(false)
|
|
}
|
|
})()
|
|
return () => {
|
|
alive = false
|
|
}
|
|
}, [srId])
|
|
|
|
if (loading) {
|
|
return (
|
|
<View style={S.wrap}>
|
|
<Text style={S.title}>🔁 유사 해결 사례</Text>
|
|
<ActivityIndicator color={COLORS.accent} style={{ marginTop: 6 }} />
|
|
</View>
|
|
)
|
|
}
|
|
if (items.length === 0) return null
|
|
|
|
return (
|
|
<View style={S.wrap}>
|
|
<Text style={S.title}>🔁 유사 해결 사례</Text>
|
|
{items.map(sr => (
|
|
<Pressable key={sr.id} style={S.card} onPress={() => onOpen?.(sr.id)}>
|
|
<Text style={S.cardTitle} numberOfLines={1}>
|
|
#{sr.id} {sr.title}
|
|
</Text>
|
|
{sr.resolution ? (
|
|
<Text style={S.cardSol} numberOfLines={3}>
|
|
💡 {sr.resolution}
|
|
</Text>
|
|
) : null}
|
|
{sr.resolution_time || sr.resolved_at ? (
|
|
<Text style={S.cardTime}>⏱ 해결 소요: {sr.resolution_time ?? sr.resolved_at}</Text>
|
|
) : null}
|
|
</Pressable>
|
|
))}
|
|
</View>
|
|
)
|
|
}
|
|
|
|
export default SRSolutionHint
|
|
|
|
const S = StyleSheet.create({
|
|
wrap: { backgroundColor: COLORS.card, borderRadius: 14, padding: 14, borderWidth: 1, borderColor: COLORS.border },
|
|
title: { fontSize: 13, fontWeight: '700', color: COLORS.text, marginBottom: 8 },
|
|
card: { backgroundColor: COLORS.light, borderRadius: 10, padding: 11, marginBottom: 6 },
|
|
cardTitle: { fontSize: 13, fontWeight: '600', color: COLORS.blue },
|
|
cardSol: { fontSize: 12, color: COLORS.text, marginTop: 4, lineHeight: 17 },
|
|
cardTime: { fontSize: 11, color: COLORS.muted, marginTop: 4 },
|
|
})
|