react-native-debug-toolkit
Version:
A simple yet powerful debugging toolkit for React Native with a convenient floating UI for development
236 lines (224 loc) • 5.73 kB
JavaScript
import React, { useState } from 'react'
import {
View,
Text,
StyleSheet,
FlatList,
TouchableOpacity,
} from 'react-native'
import HttpLogDetails from './HttpLogDetails'
const SubViewHTTPLogs = ({ logs = [] }) => {
const [selectedLog, setSelectedLog] = useState(null)
const getMethodColor = (method) => {
switch (method?.toUpperCase()) {
case 'GET':
return '#0D96F2' // Standard API blue
case 'POST':
return '#49CC90' // Swagger green
case 'PUT':
return '#FCA130' // Standard PUT orange
case 'DELETE':
return '#F93E3E' // Standard DELETE red
default:
return '#666666'
}
}
const renderLogItem = ({ item }) => {
// Check both HTTP status and API success flag
const isSuccess = item.response?.success ?? item.response?.status < 400
const statusColor = !isSuccess ? '#ff4444' : '#00C851'
const methodColor = getMethodColor(item.request?.method)
return (
<TouchableOpacity
style={styles.logItem}
onPress={() => setSelectedLog(item)}>
<View style={styles.logItemContainer}>
<View
style={[styles.statusIndicator, { backgroundColor: statusColor }]}
/>
<View style={styles.logContent}>
<View style={styles.methodRow}>
<Text style={[styles.method, { color: methodColor }]}>
{(item.request?.method || 'GET').toUpperCase()}
</Text>
<Text style={[styles.status, { color: statusColor }]}>
{item.response?.status || 'Error'}
</Text>
</View>
<Text
style={[styles.url, !isSuccess && styles.failedUrl]}
numberOfLines={2}>
{item.request?.url}
</Text>
<View style={styles.logFooter}>
<Text style={styles.time}>
{item.timestamp
? new Date(item.timestamp).toLocaleTimeString()
: ''}
</Text>
{!isSuccess && item.response?.data && (
<Text style={styles.errorMessage} numberOfLines={1}>
{item.response.data.message || 'Request Failed'}
</Text>
)}
</View>
</View>
</View>
</TouchableOpacity>
)
}
// If a log is selected, show the details view with a back button
if (selectedLog) {
return (
<View style={styles.container}>
<View style={styles.detailsHeader}>
<TouchableOpacity
style={styles.backButton}
onPress={() => setSelectedLog(null)}>
<Text style={styles.backButtonText}>← Back</Text>
</TouchableOpacity>
<View style={styles.headerMethodStatus}>
<Text
style={[
styles.headerMethod,
{ color: getMethodColor(selectedLog.request?.method) },
]}>
{(selectedLog.request?.method || 'GET').toUpperCase()}
</Text>
<Text
style={[
styles.headerStatus,
{
color:
selectedLog.response?.status >= 400
? '#ff4444'
: '#00C851',
},
]}>
{selectedLog.response?.status || 'Error'}
</Text>
</View>
</View>
<HttpLogDetails log={selectedLog} />
</View>
)
}
// Otherwise show the list view
return (
<View style={styles.container}>
{logs.length === 0 ? (
<Text style={styles.emptyText}>No HTTP requests logged yet</Text>
) : (
<FlatList
data={[...logs].sort((a, b) => b.timestamp - a.timestamp)}
renderItem={renderLogItem}
keyExtractor={(item, index) => index.toString()}
style={styles.list}
/>
)}
</View>
)
}
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#fff',
},
list: {
flex: 1,
},
emptyText: {
textAlign: 'center',
color: '#999',
marginTop: 20,
},
logItem: {
borderBottomWidth: 1,
borderBottomColor: '#eee',
},
logItemContainer: {
flexDirection: 'row',
padding: 12,
},
statusIndicator: {
width: 4,
borderRadius: 2,
marginRight: 12,
},
logContent: {
flex: 1,
},
methodRow: {
flexDirection: 'row',
alignItems: 'center',
marginBottom: 6,
},
method: {
fontSize: 15,
fontWeight: 'bold',
marginRight: 8,
},
status: {
fontSize: 13,
fontWeight: '600',
},
url: {
fontSize: 13,
color: '#333',
marginBottom: 6,
lineHeight: 18,
},
failedUrl: {
color: '#ff4444',
},
logFooter: {
flexDirection: 'row',
justifyContent: 'space-between',
},
time: {
fontSize: 12,
color: '#999',
},
duration: {
fontSize: 12,
color: '#999',
},
errorMessage: {
color: '#ff4444',
fontSize: 12,
marginLeft: 8,
},
detailsHeader: {
flexDirection: 'row',
alignItems: 'center',
padding: 15,
borderBottomWidth: 1,
borderBottomColor: '#eee',
backgroundColor: '#f8f9fa',
},
backButton: {
paddingHorizontal: 10,
paddingVertical: 5,
borderRadius: 4,
backgroundColor: '#eee',
marginRight: 10,
},
backButtonText: {
color: '#333',
fontWeight: '500',
},
headerMethodStatus: {
flexDirection: 'row',
alignItems: 'center',
},
headerMethod: {
fontSize: 16,
fontWeight: 'bold',
marginRight: 10,
},
headerStatus: {
fontSize: 14,
fontWeight: '600',
},
})
export default SubViewHTTPLogs