react-native-inapp-inspector 2.0.5 → 2.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (85) hide show
  1. package/android/src/main/java/com/inappinspector/NetworkInspectorModule.kt +11 -0
  2. package/dist/commonjs/components/Inspector/AuditTab.d.ts +3 -0
  3. package/dist/commonjs/components/Inspector/AuditTab.js +741 -0
  4. package/dist/commonjs/components/Inspector/DeviceTab.d.ts +3 -0
  5. package/dist/commonjs/components/Inspector/DeviceTab.js +717 -0
  6. package/dist/commonjs/components/Inspector/FirstTimeWalkthroughModal.d.ts +7 -0
  7. package/dist/commonjs/components/Inspector/FirstTimeWalkthroughModal.js +600 -0
  8. package/dist/commonjs/components/Inspector/InspectorHeader.js +28 -25
  9. package/dist/commonjs/components/Inspector/MainScreen.js +19 -2
  10. package/dist/commonjs/components/Inspector/NetworkDetail.js +15 -0
  11. package/dist/commonjs/components/Inspector/PerformanceHud.d.ts +7 -0
  12. package/dist/commonjs/components/Inspector/PerformanceHud.js +210 -0
  13. package/dist/commonjs/components/Inspector/PerformanceTab.js +30 -18
  14. package/dist/commonjs/components/Inspector/RequestReplayModal.d.ts +9 -0
  15. package/dist/commonjs/components/Inspector/RequestReplayModal.js +792 -0
  16. package/dist/commonjs/components/Inspector/RequestReplayView.d.ts +8 -0
  17. package/dist/commonjs/components/Inspector/RequestReplayView.js +871 -0
  18. package/dist/commonjs/components/Inspector/SettingsPanel.js +448 -49
  19. package/dist/commonjs/components/Inspector/StorageTab.d.ts +3 -0
  20. package/dist/commonjs/components/Inspector/StorageTab.js +610 -0
  21. package/dist/commonjs/components/Inspector/TabBar.js +23 -2
  22. package/dist/commonjs/components/NetworkIcons.d.ts +12 -0
  23. package/dist/commonjs/components/NetworkIcons.js +72 -3
  24. package/dist/commonjs/constants/version.d.ts +1 -1
  25. package/dist/commonjs/constants/version.js +1 -1
  26. package/dist/commonjs/customHooks/storageInspector.d.ts +13 -0
  27. package/dist/commonjs/customHooks/storageInspector.js +179 -0
  28. package/dist/commonjs/helpers/deviceInfo.d.ts +4 -0
  29. package/dist/commonjs/helpers/deviceInfo.js +94 -0
  30. package/dist/commonjs/helpers/index.d.ts +2 -0
  31. package/dist/commonjs/helpers/index.js +12 -1
  32. package/dist/commonjs/helpers/packageAuditor.d.ts +5 -0
  33. package/dist/commonjs/helpers/packageAuditor.js +182 -0
  34. package/dist/commonjs/helpers/settingsStore.d.ts +1 -1
  35. package/dist/commonjs/helpers/settingsStore.js +4 -2
  36. package/dist/commonjs/i18n/locales/en.json +3 -2
  37. package/dist/commonjs/index.d.ts +1 -0
  38. package/dist/commonjs/index.js +127 -9
  39. package/dist/commonjs/native/NativeInspector.d.ts +1 -0
  40. package/dist/commonjs/types/enums.d.ts +7 -0
  41. package/dist/commonjs/types/enums.js +7 -0
  42. package/dist/commonjs/types/interfaces.d.ts +77 -0
  43. package/dist/esm/components/Inspector/AuditTab.d.ts +3 -0
  44. package/dist/esm/components/Inspector/AuditTab.js +702 -0
  45. package/dist/esm/components/Inspector/DeviceTab.d.ts +3 -0
  46. package/dist/esm/components/Inspector/DeviceTab.js +678 -0
  47. package/dist/esm/components/Inspector/FirstTimeWalkthroughModal.d.ts +7 -0
  48. package/dist/esm/components/Inspector/FirstTimeWalkthroughModal.js +560 -0
  49. package/dist/esm/components/Inspector/InspectorHeader.js +28 -25
  50. package/dist/esm/components/Inspector/MainScreen.js +19 -2
  51. package/dist/esm/components/Inspector/NetworkDetail.js +16 -1
  52. package/dist/esm/components/Inspector/PerformanceHud.d.ts +7 -0
  53. package/dist/esm/components/Inspector/PerformanceHud.js +170 -0
  54. package/dist/esm/components/Inspector/PerformanceTab.js +31 -19
  55. package/dist/esm/components/Inspector/RequestReplayModal.d.ts +9 -0
  56. package/dist/esm/components/Inspector/RequestReplayModal.js +752 -0
  57. package/dist/esm/components/Inspector/RequestReplayView.d.ts +8 -0
  58. package/dist/esm/components/Inspector/RequestReplayView.js +831 -0
  59. package/dist/esm/components/Inspector/SettingsPanel.js +449 -50
  60. package/dist/esm/components/Inspector/StorageTab.d.ts +3 -0
  61. package/dist/esm/components/Inspector/StorageTab.js +571 -0
  62. package/dist/esm/components/Inspector/TabBar.js +24 -3
  63. package/dist/esm/components/NetworkIcons.d.ts +12 -0
  64. package/dist/esm/components/NetworkIcons.js +57 -0
  65. package/dist/esm/constants/version.d.ts +1 -1
  66. package/dist/esm/constants/version.js +1 -1
  67. package/dist/esm/customHooks/storageInspector.d.ts +13 -0
  68. package/dist/esm/customHooks/storageInspector.js +170 -0
  69. package/dist/esm/helpers/deviceInfo.d.ts +4 -0
  70. package/dist/esm/helpers/deviceInfo.js +89 -0
  71. package/dist/esm/helpers/index.d.ts +2 -0
  72. package/dist/esm/helpers/index.js +10 -0
  73. package/dist/esm/helpers/packageAuditor.d.ts +5 -0
  74. package/dist/esm/helpers/packageAuditor.js +173 -0
  75. package/dist/esm/helpers/settingsStore.d.ts +1 -1
  76. package/dist/esm/helpers/settingsStore.js +4 -2
  77. package/dist/esm/i18n/locales/en.json +3 -2
  78. package/dist/esm/index.d.ts +1 -0
  79. package/dist/esm/index.js +123 -8
  80. package/dist/esm/native/NativeInspector.d.ts +1 -0
  81. package/dist/esm/types/enums.d.ts +7 -0
  82. package/dist/esm/types/enums.js +7 -0
  83. package/dist/esm/types/interfaces.d.ts +77 -0
  84. package/ios/NetworkInspectorModule.mm +12 -5
  85. package/package.json +4 -1
@@ -0,0 +1,702 @@
1
+ import React, { useState, useMemo } from 'react';
2
+ import { Platform, ScrollView, StyleSheet, Text, TextInput, View, } from 'react-native';
3
+ import { useInspector } from './InspectorContext';
4
+ import TouchableScale from '../TouchableScale';
5
+ import { AppColors } from '../../styles/AppColors';
6
+ import { AppFonts } from '../../styles/AppFonts';
7
+ import { copyToClipboard } from '../../helpers';
8
+ import { showToast } from '../../helpers/toast';
9
+ import { ShieldCheckIcon, SparklesIcon, CopyIcon, SearchIcon, ClearIcon, TerminalIcon, PackageIcon, CodeIcon, } from '../NetworkIcons';
10
+ export const AuditTab = React.memo(() => {
11
+ const { auditReport, refreshAuditReport } = useInspector();
12
+ const [activeSubTab, setActiveSubTab] = useState('all');
13
+ const [selectedSeverity, setSelectedSeverity] = useState('all');
14
+ const [search, setSearch] = useState('');
15
+ const subTabs = [
16
+ { key: 'all', label: 'All Issues', icon: 'shield' },
17
+ { key: 'packages', label: 'Packages & Peers', icon: 'package' },
18
+ { key: 'runtime', label: 'Runtime & Types', icon: 'code' },
19
+ { key: 'bestpractices', label: 'Best Practices', icon: 'sparkles' },
20
+ { key: 'raw', label: 'Raw Report', icon: 'copy' },
21
+ ];
22
+ const optimalCount = useMemo(() => {
23
+ return (auditReport.issues || []).filter(i => i.severity === 'optimal').length;
24
+ }, [auditReport.issues]);
25
+ const severityFilters = [
26
+ { key: 'all', label: 'All', count: auditReport.totalIssues },
27
+ { key: 'critical', label: 'Critical', count: auditReport.criticalCount },
28
+ { key: 'warning', label: 'Warnings', count: auditReport.warningCount },
29
+ { key: 'optimal', label: 'Passed / Optimal', count: optimalCount + auditReport.infoCount },
30
+ ];
31
+ const handleCopyReport = () => {
32
+ copyToClipboard(JSON.stringify(auditReport, null, 2), 'Code Quality Audit Report');
33
+ showToast('Copied full audit report!');
34
+ };
35
+ const handleCopyFix = (cmd) => {
36
+ if (!cmd)
37
+ return;
38
+ copyToClipboard(cmd, 'Fix Command');
39
+ showToast('Copied fix command to clipboard!');
40
+ };
41
+ // Filtered issues based on sub-tab, severity, and search text
42
+ const filteredIssues = useMemo(() => {
43
+ let list = auditReport.issues || [];
44
+ // Filter by subtab
45
+ if (activeSubTab === 'packages') {
46
+ list = list.filter(i => i.category === 'dependency' || i.category === 'peer');
47
+ }
48
+ else if (activeSubTab === 'runtime') {
49
+ list = list.filter(i => i.category === 'typescript');
50
+ }
51
+ else if (activeSubTab === 'bestpractices') {
52
+ list = list.filter(i => i.category === 'performance' || i.category === 'security');
53
+ }
54
+ // Filter by severity
55
+ if (selectedSeverity !== 'all') {
56
+ if (selectedSeverity === 'optimal') {
57
+ list = list.filter(i => i.severity === 'optimal' || i.severity === 'info');
58
+ }
59
+ else {
60
+ list = list.filter(i => i.severity === selectedSeverity);
61
+ }
62
+ }
63
+ // Filter by search query
64
+ if (search.trim().length > 0) {
65
+ const q = search.toLowerCase();
66
+ list = list.filter(i => i.title.toLowerCase().includes(q) ||
67
+ i.message.toLowerCase().includes(q) ||
68
+ i.packageName?.toLowerCase().includes(q) ||
69
+ i.category.toLowerCase().includes(q));
70
+ }
71
+ return list;
72
+ }, [auditReport.issues, activeSubTab, selectedSeverity, search]);
73
+ const getSeverityBadgeStyle = (sev) => {
74
+ switch (sev) {
75
+ case 'critical':
76
+ return {
77
+ bg: `${AppColors.errorColor}15`,
78
+ border: `${AppColors.errorColor}40`,
79
+ text: AppColors.errorColor,
80
+ label: 'CRITICAL',
81
+ };
82
+ case 'warning':
83
+ return {
84
+ bg: `${AppColors.warningIconGold}18`,
85
+ border: `${AppColors.warningIconGold}40`,
86
+ text: '#D97706',
87
+ label: 'WARNING',
88
+ };
89
+ case 'info':
90
+ return {
91
+ bg: `${AppColors.purple}15`,
92
+ border: `${AppColors.purple}40`,
93
+ text: AppColors.purple,
94
+ label: 'INFO',
95
+ };
96
+ default:
97
+ return {
98
+ bg: `${AppColors.greenColor}15`,
99
+ border: `${AppColors.greenColor}40`,
100
+ text: AppColors.greenColor,
101
+ label: 'OPTIMAL',
102
+ };
103
+ }
104
+ };
105
+ const getScoreColor = (score) => {
106
+ if (score >= 90)
107
+ return AppColors.greenColor;
108
+ if (score >= 70)
109
+ return '#D97706';
110
+ return AppColors.errorColor;
111
+ };
112
+ return (<View style={styles.container}>
113
+ {/* ─── Top Sub-Tab Navigation Bar with Vector Icons ──────────────────────── */}
114
+ <View style={styles.tabBarWrapper}>
115
+ <ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={styles.subTabBarContainer}>
116
+ {subTabs.map(tab => {
117
+ const isActive = activeSubTab === tab.key;
118
+ const iconColor = isActive ? AppColors.white : AppColors.grayText;
119
+ return (<TouchableScale key={tab.key} onPress={() => setActiveSubTab(tab.key)} style={[
120
+ styles.subTabButton,
121
+ isActive && styles.subTabButtonActive,
122
+ ]}>
123
+ <View style={styles.subTabInnerRow}>
124
+ {tab.icon === 'shield' && <ShieldCheckIcon size={12} color={iconColor}/>}
125
+ {tab.icon === 'package' && <PackageIcon size={12} color={iconColor}/>}
126
+ {tab.icon === 'code' && <CodeIcon size={12} color={iconColor}/>}
127
+ {tab.icon === 'sparkles' && <SparklesIcon size={12} color={iconColor}/>}
128
+ {tab.icon === 'copy' && <CopyIcon size={12} color={iconColor}/>}
129
+ <Text style={[
130
+ styles.subTabText,
131
+ isActive && styles.subTabTextActive,
132
+ ]}>
133
+ {tab.label}
134
+ </Text>
135
+ </View>
136
+ </TouchableScale>);
137
+ })}
138
+ </ScrollView>
139
+ </View>
140
+
141
+ <ScrollView style={styles.scrollArea} contentContainerStyle={styles.contentContainer} showsVerticalScrollIndicator={false}>
142
+ {/* ─── Health Score Hero Banner ────────────────────────────────────────── */}
143
+ <View style={styles.heroCard}>
144
+ <View style={styles.heroTopRow}>
145
+ {/* Health Score Gauge */}
146
+ <View style={[
147
+ styles.scoreBadgeBox,
148
+ {
149
+ borderColor: `${getScoreColor(auditReport.score)}40`,
150
+ backgroundColor: `${getScoreColor(auditReport.score)}10`,
151
+ },
152
+ ]}>
153
+ <Text style={[
154
+ styles.scoreText,
155
+ { color: getScoreColor(auditReport.score) },
156
+ ]}>
157
+ {auditReport.score}%
158
+ </Text>
159
+ <Text style={[
160
+ styles.gradeText,
161
+ { color: getScoreColor(auditReport.score) },
162
+ ]}>
163
+ GRADE {auditReport.grade}
164
+ </Text>
165
+ </View>
166
+
167
+ {/* Title & Diagnostic Overview */}
168
+ <View style={styles.heroTitleBox}>
169
+ <View style={styles.heroBadgeRow}>
170
+ <ShieldCheckIcon size={15} color={getScoreColor(auditReport.score)}/>
171
+ <Text style={styles.heroStatusText}>
172
+ {auditReport.score >= 90
173
+ ? 'Optimal Health'
174
+ : auditReport.score >= 70
175
+ ? 'Warnings Found'
176
+ : 'Attention Needed'}
177
+ </Text>
178
+ </View>
179
+ <Text style={styles.heroSubText}>
180
+ {auditReport.totalIssues} diagnostic checks across packages, runtime & security
181
+ </Text>
182
+ </View>
183
+ </View>
184
+
185
+ {/* Action Row */}
186
+ <View style={styles.heroActionRow}>
187
+ <TouchableScale onPress={refreshAuditReport} style={styles.refreshAuditBtn}>
188
+ <SparklesIcon size={12} color={AppColors.purple}/>
189
+ <Text style={styles.refreshAuditText}>Re-Scan</Text>
190
+ </TouchableScale>
191
+ <TouchableScale onPress={handleCopyReport} style={styles.copyReportBtn}>
192
+ <CopyIcon size={12} color={AppColors.white}/>
193
+ <Text style={styles.copyReportText}>Copy Report</Text>
194
+ </TouchableScale>
195
+ </View>
196
+
197
+ {/* Quick Metrics Bar */}
198
+ <View style={styles.metricsBar}>
199
+ <View style={styles.metricItem}>
200
+ <Text style={[styles.metricCount, { color: AppColors.errorColor }]}>
201
+ {auditReport.criticalCount}
202
+ </Text>
203
+ <Text style={styles.metricLabel}>Critical</Text>
204
+ </View>
205
+ <View style={styles.metricDivider}/>
206
+ <View style={styles.metricItem}>
207
+ <Text style={[styles.metricCount, { color: '#D97706' }]}>
208
+ {auditReport.warningCount}
209
+ </Text>
210
+ <Text style={styles.metricLabel}>Warnings</Text>
211
+ </View>
212
+ <View style={styles.metricDivider}/>
213
+ <View style={styles.metricItem}>
214
+ <Text style={[styles.metricCount, { color: AppColors.greenColor }]}>
215
+ {optimalCount + auditReport.infoCount}
216
+ </Text>
217
+ <Text style={styles.metricLabel}>Passed / Optimal</Text>
218
+ </View>
219
+ </View>
220
+ </View>
221
+
222
+ {/* ─── Search & Severity Filter Bar ────────────────────────────────────── */}
223
+ {activeSubTab !== 'raw' && (<View style={styles.filterSection}>
224
+ <View style={styles.searchBox}>
225
+ <SearchIcon size={13} color={AppColors.grayTextWeak}/>
226
+ <TextInput style={styles.searchInput} value={search} onChangeText={setSearch} placeholder="Search packages, issues, rules..." placeholderTextColor={AppColors.grayTextWeak} autoCapitalize="none" autoCorrect={false}/>
227
+ {search.length > 0 && (<TouchableScale onPress={() => setSearch('')}>
228
+ <ClearIcon size={14} color={AppColors.grayTextWeak}/>
229
+ </TouchableScale>)}
230
+ </View>
231
+
232
+ <ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={styles.severityFilterRow}>
233
+ {severityFilters.map(sf => {
234
+ const isSelected = selectedSeverity === sf.key;
235
+ return (<TouchableScale key={sf.key} onPress={() => setSelectedSeverity(sf.key)} style={[
236
+ styles.severityChip,
237
+ isSelected && styles.severityChipActive,
238
+ ]}>
239
+ <Text style={[
240
+ styles.severityChipText,
241
+ isSelected && styles.severityChipTextActive,
242
+ ]}>
243
+ {sf.label} {sf.count !== undefined ? `(${sf.count})` : ''}
244
+ </Text>
245
+ </TouchableScale>);
246
+ })}
247
+ </ScrollView>
248
+ </View>)}
249
+
250
+ {/* ─── Issues Feed ─────────────────────────────────────────────────────── */}
251
+ {activeSubTab !== 'raw' && (<View style={styles.issuesList}>
252
+ {filteredIssues.length === 0 ? (<View style={styles.emptyStateCard}>
253
+ <ShieldCheckIcon size={32} color={AppColors.greenColor}/>
254
+ <Text style={styles.emptyTitle}>No Issues in this Category</Text>
255
+ <Text style={styles.emptySub}>
256
+ {search.length > 0
257
+ ? 'No checks matched your search query.'
258
+ : 'All scanned package dependencies and code standards passed successfully!'}
259
+ </Text>
260
+ </View>) : (filteredIssues.map(issue => {
261
+ const badge = getSeverityBadgeStyle(issue.severity);
262
+ return (<View key={issue.id} style={styles.issueCard}>
263
+ <View style={styles.issueHeader}>
264
+ <View style={styles.issueHeaderLeft}>
265
+ <View style={[
266
+ styles.severityBadge,
267
+ { backgroundColor: badge.bg, borderColor: badge.border },
268
+ ]}>
269
+ <Text style={[styles.severityBadgeText, { color: badge.text }]}>
270
+ {badge.label}
271
+ </Text>
272
+ </View>
273
+ <View style={styles.categoryBadge}>
274
+ <Text style={styles.categoryBadgeText}>
275
+ {issue.category.toUpperCase()}
276
+ </Text>
277
+ </View>
278
+ </View>
279
+
280
+ {issue.packageName && (<View style={styles.packageTag}>
281
+ <PackageIcon size={11} color={AppColors.purple}/>
282
+ <Text style={styles.packageTagText}>
283
+ {issue.packageName}
284
+ {issue.currentVersion ? ` @ ${issue.currentVersion}` : ''}
285
+ </Text>
286
+ </View>)}
287
+ </View>
288
+
289
+ <Text style={styles.issueTitle}>{issue.title}</Text>
290
+ <Text style={styles.issueMessage}>{issue.message}</Text>
291
+
292
+ {/* Actionable Fix Command Bar */}
293
+ {issue.fixCommand && (<View style={styles.fixCommandBox}>
294
+ <View style={styles.fixLeft}>
295
+ <TerminalIcon size={12} color={AppColors.purple}/>
296
+ <Text style={styles.fixCommandText} numberOfLines={1}>
297
+ {issue.fixCommand}
298
+ </Text>
299
+ </View>
300
+ <TouchableScale onPress={() => handleCopyFix(issue.fixCommand)} style={styles.fixCopyBtn}>
301
+ <CopyIcon size={11} color={AppColors.purple}/>
302
+ <Text style={styles.fixCopyText}>Copy Fix</Text>
303
+ </TouchableScale>
304
+ </View>)}
305
+ </View>);
306
+ }))}
307
+ </View>)}
308
+
309
+ {/* ─── Raw JSON Sub-Tab ────────────────────────────────────────────────── */}
310
+ {activeSubTab === 'raw' && (<View style={styles.rawCard}>
311
+ <View style={styles.rawHeader}>
312
+ <Text style={styles.rawTitle}>RAW AUDIT JSON REPORT</Text>
313
+ <TouchableScale onPress={handleCopyReport} style={styles.copyReportBtn}>
314
+ <CopyIcon size={11} color={AppColors.white}/>
315
+ <Text style={styles.copyReportText}>Copy All</Text>
316
+ </TouchableScale>
317
+ </View>
318
+ <ScrollView horizontal style={styles.rawScroll}>
319
+ <Text style={styles.rawText} selectable>
320
+ {JSON.stringify(auditReport, null, 2)}
321
+ </Text>
322
+ </ScrollView>
323
+ </View>)}
324
+
325
+ <View style={{ height: 40 }}/>
326
+ </ScrollView>
327
+ </View>);
328
+ });
329
+ const styles = StyleSheet.create({
330
+ container: {
331
+ flex: 1,
332
+ backgroundColor: AppColors.grayBackground,
333
+ },
334
+ tabBarWrapper: {
335
+ backgroundColor: AppColors.contentBg,
336
+ borderBottomWidth: 1,
337
+ borderBottomColor: AppColors.grayBorderSecondary,
338
+ paddingVertical: 8,
339
+ },
340
+ subTabBarContainer: {
341
+ paddingHorizontal: 12,
342
+ flexDirection: 'row',
343
+ gap: 8,
344
+ alignItems: 'center',
345
+ },
346
+ subTabButton: {
347
+ paddingHorizontal: 12,
348
+ paddingVertical: 7,
349
+ borderRadius: 20,
350
+ backgroundColor: AppColors.grayBackground,
351
+ borderWidth: 1,
352
+ borderColor: AppColors.grayBorderSecondary,
353
+ },
354
+ subTabButtonActive: {
355
+ backgroundColor: AppColors.purple,
356
+ borderColor: AppColors.purple,
357
+ },
358
+ subTabInnerRow: {
359
+ flexDirection: 'row',
360
+ alignItems: 'center',
361
+ gap: 5,
362
+ },
363
+ subTabText: {
364
+ fontSize: 12,
365
+ fontFamily: AppFonts.interMedium,
366
+ color: AppColors.grayText,
367
+ },
368
+ subTabTextActive: {
369
+ color: AppColors.white,
370
+ fontFamily: AppFonts.interBold,
371
+ },
372
+ scrollArea: {
373
+ flex: 1,
374
+ },
375
+ contentContainer: {
376
+ padding: 12,
377
+ },
378
+ heroCard: {
379
+ backgroundColor: AppColors.contentBg,
380
+ borderRadius: 14,
381
+ padding: 14,
382
+ marginBottom: 12,
383
+ borderWidth: 1,
384
+ borderColor: AppColors.grayBorderSecondary,
385
+ gap: 12,
386
+ },
387
+ heroTopRow: {
388
+ flexDirection: 'row',
389
+ alignItems: 'center',
390
+ gap: 12,
391
+ },
392
+ scoreBadgeBox: {
393
+ width: 60,
394
+ height: 60,
395
+ borderRadius: 12,
396
+ borderWidth: 1.5,
397
+ alignItems: 'center',
398
+ justifyContent: 'center',
399
+ },
400
+ scoreText: {
401
+ fontSize: 17,
402
+ fontFamily: AppFonts.interBold,
403
+ },
404
+ gradeText: {
405
+ fontSize: 8.5,
406
+ fontFamily: AppFonts.interBold,
407
+ letterSpacing: 0.5,
408
+ marginTop: 1,
409
+ },
410
+ heroTitleBox: {
411
+ flex: 1,
412
+ gap: 2,
413
+ },
414
+ heroBadgeRow: {
415
+ flexDirection: 'row',
416
+ alignItems: 'center',
417
+ gap: 6,
418
+ },
419
+ heroStatusText: {
420
+ fontSize: 14,
421
+ fontFamily: AppFonts.interBold,
422
+ color: AppColors.black,
423
+ },
424
+ heroSubText: {
425
+ fontSize: 11,
426
+ fontFamily: AppFonts.interMedium,
427
+ color: AppColors.grayText,
428
+ lineHeight: 15,
429
+ },
430
+ heroActionRow: {
431
+ flexDirection: 'row',
432
+ alignItems: 'center',
433
+ gap: 8,
434
+ },
435
+ refreshAuditBtn: {
436
+ flex: 1,
437
+ flexDirection: 'row',
438
+ alignItems: 'center',
439
+ justifyContent: 'center',
440
+ gap: 5,
441
+ backgroundColor: `${AppColors.purple}12`,
442
+ paddingVertical: 7,
443
+ borderRadius: 8,
444
+ borderWidth: 1,
445
+ borderColor: `${AppColors.purple}30`,
446
+ },
447
+ refreshAuditText: {
448
+ fontSize: 11.5,
449
+ fontFamily: AppFonts.interBold,
450
+ color: AppColors.purple,
451
+ },
452
+ copyReportBtn: {
453
+ flex: 1,
454
+ flexDirection: 'row',
455
+ alignItems: 'center',
456
+ justifyContent: 'center',
457
+ gap: 5,
458
+ backgroundColor: AppColors.purple,
459
+ paddingVertical: 7,
460
+ borderRadius: 8,
461
+ },
462
+ copyReportText: {
463
+ fontSize: 11.5,
464
+ fontFamily: AppFonts.interBold,
465
+ color: AppColors.white,
466
+ },
467
+ metricsBar: {
468
+ flexDirection: 'row',
469
+ alignItems: 'center',
470
+ backgroundColor: AppColors.grayBackground,
471
+ borderRadius: 10,
472
+ paddingVertical: 8,
473
+ paddingHorizontal: 12,
474
+ },
475
+ metricItem: {
476
+ flex: 1,
477
+ alignItems: 'center',
478
+ },
479
+ metricCount: {
480
+ fontSize: 14,
481
+ fontFamily: AppFonts.interBold,
482
+ },
483
+ metricLabel: {
484
+ fontSize: 9.5,
485
+ fontFamily: AppFonts.interMedium,
486
+ color: AppColors.grayText,
487
+ marginTop: 1,
488
+ },
489
+ metricDivider: {
490
+ width: 1,
491
+ height: 22,
492
+ backgroundColor: AppColors.grayBorderSecondary,
493
+ },
494
+ filterSection: {
495
+ marginBottom: 12,
496
+ gap: 8,
497
+ },
498
+ searchBox: {
499
+ flexDirection: 'row',
500
+ alignItems: 'center',
501
+ gap: 6,
502
+ backgroundColor: AppColors.contentBg,
503
+ borderRadius: 10,
504
+ paddingHorizontal: 10,
505
+ paddingVertical: 6,
506
+ borderWidth: 1,
507
+ borderColor: AppColors.grayBorderSecondary,
508
+ },
509
+ searchInput: {
510
+ flex: 1,
511
+ fontSize: 12,
512
+ fontFamily: AppFonts.interRegular,
513
+ color: AppColors.black,
514
+ paddingVertical: 0,
515
+ },
516
+ severityFilterRow: {
517
+ flexDirection: 'row',
518
+ gap: 6,
519
+ },
520
+ severityChip: {
521
+ paddingHorizontal: 12,
522
+ paddingVertical: 5,
523
+ borderRadius: 16,
524
+ backgroundColor: AppColors.contentBg,
525
+ borderWidth: 1,
526
+ borderColor: AppColors.grayBorderSecondary,
527
+ },
528
+ severityChipActive: {
529
+ backgroundColor: AppColors.purple,
530
+ borderColor: AppColors.purple,
531
+ },
532
+ severityChipText: {
533
+ fontSize: 11,
534
+ fontFamily: AppFonts.interMedium,
535
+ color: AppColors.grayText,
536
+ },
537
+ severityChipTextActive: {
538
+ color: AppColors.white,
539
+ fontFamily: AppFonts.interBold,
540
+ },
541
+ issuesList: {
542
+ gap: 10,
543
+ },
544
+ issueCard: {
545
+ backgroundColor: AppColors.contentBg,
546
+ borderRadius: 12,
547
+ padding: 12,
548
+ borderWidth: 1,
549
+ borderColor: AppColors.grayBorderSecondary,
550
+ },
551
+ issueHeader: {
552
+ flexDirection: 'row',
553
+ alignItems: 'center',
554
+ justifyContent: 'space-between',
555
+ marginBottom: 8,
556
+ },
557
+ issueHeaderLeft: {
558
+ flexDirection: 'row',
559
+ alignItems: 'center',
560
+ gap: 6,
561
+ },
562
+ severityBadge: {
563
+ paddingHorizontal: 6,
564
+ paddingVertical: 2,
565
+ borderRadius: 4,
566
+ borderWidth: 1,
567
+ },
568
+ severityBadgeText: {
569
+ fontSize: 9,
570
+ fontFamily: AppFonts.interBold,
571
+ letterSpacing: 0.5,
572
+ },
573
+ categoryBadge: {
574
+ backgroundColor: AppColors.grayBackground,
575
+ paddingHorizontal: 6,
576
+ paddingVertical: 2,
577
+ borderRadius: 4,
578
+ },
579
+ categoryBadgeText: {
580
+ fontSize: 9,
581
+ fontFamily: AppFonts.interBold,
582
+ color: AppColors.grayTextWeak,
583
+ },
584
+ packageTag: {
585
+ flexDirection: 'row',
586
+ alignItems: 'center',
587
+ gap: 4,
588
+ backgroundColor: `${AppColors.purple}10`,
589
+ paddingHorizontal: 6,
590
+ paddingVertical: 2,
591
+ borderRadius: 4,
592
+ },
593
+ packageTagText: {
594
+ fontSize: 10,
595
+ fontFamily: AppFonts.interMedium,
596
+ color: AppColors.purple,
597
+ },
598
+ issueTitle: {
599
+ fontSize: 13,
600
+ fontFamily: AppFonts.interBold,
601
+ color: AppColors.black,
602
+ marginBottom: 4,
603
+ },
604
+ issueMessage: {
605
+ fontSize: 12,
606
+ fontFamily: AppFonts.interRegular,
607
+ color: AppColors.grayText,
608
+ lineHeight: 17,
609
+ },
610
+ fixCommandBox: {
611
+ marginTop: 8,
612
+ flexDirection: 'row',
613
+ alignItems: 'center',
614
+ justifyContent: 'space-between',
615
+ backgroundColor: AppColors.grayBackground,
616
+ borderRadius: 8,
617
+ paddingHorizontal: 8,
618
+ paddingVertical: 6,
619
+ borderWidth: 1,
620
+ borderColor: AppColors.grayBorderSecondary,
621
+ },
622
+ fixLeft: {
623
+ flexDirection: 'row',
624
+ alignItems: 'center',
625
+ gap: 6,
626
+ flex: 1,
627
+ },
628
+ fixCommandText: {
629
+ fontSize: 11,
630
+ fontFamily: Platform.OS === 'ios' ? 'Menlo' : 'monospace',
631
+ color: AppColors.black,
632
+ flex: 1,
633
+ },
634
+ fixCopyBtn: {
635
+ flexDirection: 'row',
636
+ alignItems: 'center',
637
+ gap: 3,
638
+ backgroundColor: `${AppColors.purple}15`,
639
+ paddingHorizontal: 6,
640
+ paddingVertical: 3,
641
+ borderRadius: 4,
642
+ },
643
+ fixCopyText: {
644
+ fontSize: 10,
645
+ fontFamily: AppFonts.interBold,
646
+ color: AppColors.purple,
647
+ },
648
+ emptyStateCard: {
649
+ backgroundColor: AppColors.contentBg,
650
+ borderRadius: 14,
651
+ padding: 24,
652
+ alignItems: 'center',
653
+ justifyContent: 'center',
654
+ borderWidth: 1,
655
+ borderColor: AppColors.grayBorderSecondary,
656
+ },
657
+ emptyTitle: {
658
+ fontSize: 15,
659
+ fontFamily: AppFonts.interBold,
660
+ color: AppColors.black,
661
+ marginTop: 10,
662
+ },
663
+ emptySub: {
664
+ fontSize: 12,
665
+ fontFamily: AppFonts.interRegular,
666
+ color: AppColors.grayText,
667
+ textAlign: 'center',
668
+ marginTop: 4,
669
+ lineHeight: 18,
670
+ },
671
+ rawCard: {
672
+ backgroundColor: AppColors.contentBg,
673
+ borderRadius: 14,
674
+ padding: 14,
675
+ borderWidth: 1,
676
+ borderColor: AppColors.grayBorderSecondary,
677
+ },
678
+ rawHeader: {
679
+ flexDirection: 'row',
680
+ alignItems: 'center',
681
+ justifyContent: 'space-between',
682
+ marginBottom: 10,
683
+ },
684
+ rawTitle: {
685
+ fontSize: 12,
686
+ fontFamily: AppFonts.interBold,
687
+ color: AppColors.grayTextWeak,
688
+ letterSpacing: 0.5,
689
+ },
690
+ rawScroll: {
691
+ backgroundColor: AppColors.grayBackground,
692
+ borderRadius: 8,
693
+ padding: 10,
694
+ },
695
+ rawText: {
696
+ fontSize: 11,
697
+ fontFamily: Platform.OS === 'ios' ? 'Menlo' : 'monospace',
698
+ color: AppColors.black,
699
+ lineHeight: 16,
700
+ },
701
+ });
702
+ export default AuditTab;
@@ -0,0 +1,3 @@
1
+ import React from 'react';
2
+ export declare const DeviceTab: React.MemoExoticComponent<() => React.JSX.Element>;
3
+ export default DeviceTab;