UNPKG

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
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