react-native-inapp-inspector 1.1.4 → 1.1.6

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.
package/dist/esm/index.js CHANGED
@@ -227,6 +227,8 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
227
227
  const [inspectedElement, setInspectedElement] = useState(null);
228
228
  // ─── Settings state ──────────────────────────────────────────────────────────
229
229
  const [settingsPage, setSettingsPage] = useState(null);
230
+ const [settingsActiveSubTab, setSettingsActiveSubTab] = useState('module');
231
+ const [insightsActiveSubTab, setInsightsActiveSubTab] = useState('apis');
230
232
  const [tabVisibility, setTabVisibility] = useState({
231
233
  insights: true,
232
234
  apis: true,
@@ -420,6 +422,9 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
420
422
  if (!nextVal && defaultTab === key) {
421
423
  setDefaultTab('apis');
422
424
  }
425
+ if (!nextVal && insightsActiveSubTab === key) {
426
+ setInsightsActiveSubTab('apis');
427
+ }
423
428
  return newVisibility;
424
429
  });
425
430
  };
@@ -1371,267 +1376,315 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
1371
1376
  </LinearGradient>
1372
1377
 
1373
1378
  <ScrollView style={{ flex: 1 }} contentContainerStyle={{ padding: 16, gap: 12 }}>
1374
- {/* Tab list */}
1379
+ {/* Sub Tabs */}
1375
1380
  <View style={{
1381
+ flexDirection: 'row',
1376
1382
  backgroundColor: AppColors.primaryLight,
1377
- borderRadius: 12,
1383
+ borderRadius: 10,
1384
+ padding: 3,
1378
1385
  borderWidth: 1,
1379
1386
  borderColor: AppColors.grayBorderSecondary,
1380
- overflow: 'hidden',
1387
+ marginBottom: 4,
1381
1388
  }}>
1382
- {/* Table Header */}
1383
- <View style={{
1384
- flexDirection: 'row',
1385
- alignItems: 'center',
1389
+ <TouchableOpacity onPress={() => {
1390
+ animateNextLayout();
1391
+ setSettingsActiveSubTab('module');
1392
+ }} style={{
1393
+ flex: 1,
1386
1394
  paddingVertical: 8,
1387
- paddingHorizontal: 14,
1388
- backgroundColor: AppColors.grayBackground,
1389
- borderBottomWidth: 1,
1390
- borderBottomColor: AppColors.dividerColor,
1391
- gap: 12,
1395
+ alignItems: 'center',
1396
+ justifyContent: 'center',
1397
+ borderRadius: 8,
1398
+ backgroundColor: settingsActiveSubTab === 'module'
1399
+ ? AppColors.purple
1400
+ : 'transparent',
1392
1401
  }}>
1393
1402
  <Text style={{
1394
1403
  fontFamily: AppFonts.interBold,
1395
- fontSize: 10,
1396
- color: AppColors.grayTextWeak,
1397
- letterSpacing: 0.6,
1398
- flex: 1,
1404
+ fontSize: 12,
1405
+ color: settingsActiveSubTab === 'module'
1406
+ ? '#FFFFFF'
1407
+ : AppColors.grayText,
1399
1408
  }}>
1400
- MODULE
1409
+ Module
1401
1410
  </Text>
1411
+ </TouchableOpacity>
1412
+ <TouchableOpacity onPress={() => {
1413
+ animateNextLayout();
1414
+ setSettingsActiveSubTab('ui');
1415
+ }} style={{
1416
+ flex: 1,
1417
+ paddingVertical: 8,
1418
+ alignItems: 'center',
1419
+ justifyContent: 'center',
1420
+ borderRadius: 8,
1421
+ backgroundColor: settingsActiveSubTab === 'ui'
1422
+ ? AppColors.purple
1423
+ : 'transparent',
1424
+ }}>
1402
1425
  <Text style={{
1403
1426
  fontFamily: AppFonts.interBold,
1404
- fontSize: 10,
1405
- color: AppColors.grayTextWeak,
1406
- letterSpacing: 0.6,
1407
- width: 90,
1408
- textAlign: 'right',
1409
- paddingRight: 4,
1427
+ fontSize: 12,
1428
+ color: settingsActiveSubTab === 'ui'
1429
+ ? '#FFFFFF'
1430
+ : AppColors.grayText,
1410
1431
  }}>
1411
- VISIBILITY
1432
+ UI Preferences
1412
1433
  </Text>
1413
- </View>
1434
+ </TouchableOpacity>
1435
+ </View>
1414
1436
 
1415
- {settingsTabs.map((tab, idx) => {
1416
- const isVisible = tab.key === 'apis' || tabVisibility?.[tab.key];
1417
- const isLast = idx === settingsTabs.length - 1;
1418
- const isLocked = tab.key === 'apis';
1419
- return (<View key={tab.key} style={{
1420
- flexDirection: 'row',
1421
- alignItems: 'center',
1422
- paddingVertical: 10,
1423
- paddingHorizontal: 14,
1424
- borderBottomWidth: isLast ? 0 : 1,
1425
- borderBottomColor: AppColors.dividerColor,
1426
- gap: 12,
1427
- }}>
1428
- {/* Icon + Label — fills remaining space */}
1429
- <View style={{
1430
- flex: 1,
1431
- flexDirection: 'row',
1432
- alignItems: 'center',
1433
- gap: 8,
1434
- }}>
1435
- {/* Small icon tile */}
1437
+ {settingsActiveSubTab === 'module' ? (
1438
+ /* Tab list */
1439
+ <View style={{
1440
+ backgroundColor: AppColors.primaryLight,
1441
+ borderRadius: 12,
1442
+ borderWidth: 1,
1443
+ borderColor: AppColors.grayBorderSecondary,
1444
+ overflow: 'hidden',
1445
+ }}>
1446
+ {/* Table Header */}
1447
+ <View style={{
1448
+ flexDirection: 'row',
1449
+ alignItems: 'center',
1450
+ paddingVertical: 8,
1451
+ paddingHorizontal: 14,
1452
+ backgroundColor: AppColors.grayBackground,
1453
+ borderBottomWidth: 1,
1454
+ borderBottomColor: AppColors.dividerColor,
1455
+ gap: 12,
1456
+ }}>
1457
+ <Text style={{
1458
+ fontFamily: AppFonts.interBold,
1459
+ fontSize: 10,
1460
+ color: AppColors.grayTextWeak,
1461
+ letterSpacing: 0.6,
1462
+ flex: 1,
1463
+ }}>
1464
+ MODULE
1465
+ </Text>
1466
+ <Text style={{
1467
+ fontFamily: AppFonts.interBold,
1468
+ fontSize: 10,
1469
+ color: AppColors.grayTextWeak,
1470
+ letterSpacing: 0.6,
1471
+ width: 90,
1472
+ textAlign: 'right',
1473
+ paddingRight: 4,
1474
+ }}>
1475
+ VISIBILITY
1476
+ </Text>
1477
+ </View>
1478
+
1479
+ {settingsTabs.map((tab, idx) => {
1480
+ const isVisible = tab.key === 'apis' || tabVisibility?.[tab.key];
1481
+ const isLast = idx === settingsTabs.length - 1;
1482
+ const isLocked = tab.key === 'apis';
1483
+ return (<View key={tab.key} style={{
1484
+ flexDirection: 'row',
1485
+ alignItems: 'center',
1486
+ paddingVertical: 10,
1487
+ paddingHorizontal: 14,
1488
+ borderBottomWidth: isLast ? 0 : 1,
1489
+ borderBottomColor: AppColors.dividerColor,
1490
+ gap: 12,
1491
+ }}>
1492
+ {/* Icon + Label — fills remaining space */}
1436
1493
  <View style={{
1437
- width: 20,
1438
- height: 20,
1439
- borderRadius: 6,
1440
- backgroundColor: isLocked
1441
- ? AppColors.grayBorderSecondary
1442
- : AppColors.purpleShade50,
1443
- borderWidth: 1,
1444
- borderColor: isLocked
1445
- ? AppColors.dividerColor
1446
- : 'rgba(104,75,155,0.2)',
1447
- alignItems: 'center',
1448
- justifyContent: 'center',
1449
- }}>
1450
- {tab.icon === 'insights' && (<InsightsIcon color={isLocked
1451
- ? AppColors.grayTextWeak
1452
- : AppColors.purple} size={11}/>)}
1453
- {tab.icon === 'apis' && (<SignalIcon color={isLocked
1454
- ? AppColors.grayTextWeak
1455
- : AppColors.purple} size={11}/>)}
1456
- {tab.icon === 'logs' && (<TerminalIcon color={isLocked
1457
- ? AppColors.grayTextWeak
1458
- : AppColors.purple} size={11}/>)}
1459
- {tab.icon === 'analytics' && (<AnalyticsIcon color={isLocked
1460
- ? AppColors.grayTextWeak
1461
- : AppColors.purple} size={11}/>)}
1462
- {tab.icon === 'webview' && (<GlobeIcon color={isLocked
1463
- ? AppColors.grayTextWeak
1464
- : AppColors.purple} size={11}/>)}
1465
- {tab.icon === 'redux' && (<TerminalIcon color={isLocked
1466
- ? AppColors.grayTextWeak
1467
- : AppColors.purple} size={11}/>)}
1468
- </View>
1469
- {/* Label + Required badge */}
1470
- <Text style={{
1471
- fontFamily: AppFonts.interBold,
1472
- fontSize: 13,
1473
- color: isLocked
1474
- ? AppColors.grayText
1475
- : AppColors.primaryBlack,
1476
- }}>
1477
- {tab.label}
1478
- </Text>
1479
- {/* #6 — badge marks the configured default tab */}
1480
- {tab.key === defaultTab && (<View style={{
1494
+ flex: 1,
1481
1495
  flexDirection: 'row',
1482
1496
  alignItems: 'center',
1483
- backgroundColor: 'rgba(104,75,155,0.08)',
1484
- borderRadius: 20,
1485
- paddingHorizontal: 6,
1486
- paddingVertical: 2,
1497
+ gap: 8,
1498
+ }}>
1499
+ {/* Small icon tile */}
1500
+ <View style={{
1501
+ width: 20,
1502
+ height: 20,
1503
+ borderRadius: 6,
1504
+ backgroundColor: isLocked
1505
+ ? AppColors.grayBorderSecondary
1506
+ : AppColors.purpleShade50,
1487
1507
  borderWidth: 1,
1488
- borderColor: 'rgba(104,75,155,0.18)',
1489
- gap: 3,
1508
+ borderColor: isLocked
1509
+ ? AppColors.dividerColor
1510
+ : 'rgba(104,75,155,0.2)',
1511
+ alignItems: 'center',
1512
+ justifyContent: 'center',
1490
1513
  }}>
1491
- <View style={{
1492
- width: 4,
1493
- height: 4,
1494
- borderRadius: 2,
1495
- backgroundColor: AppColors.purple,
1496
- opacity: 0.7,
1497
- }}/>
1498
- <Text style={{
1514
+ {tab.icon === 'insights' && (<InsightsIcon color={isLocked
1515
+ ? AppColors.grayTextWeak
1516
+ : AppColors.purple} size={11}/>)}
1517
+ {tab.icon === 'apis' && (<SignalIcon color={isLocked
1518
+ ? AppColors.grayTextWeak
1519
+ : AppColors.purple} size={11}/>)}
1520
+ {tab.icon === 'logs' && (<TerminalIcon color={isLocked
1521
+ ? AppColors.grayTextWeak
1522
+ : AppColors.purple} size={11}/>)}
1523
+ {tab.icon === 'analytics' && (<AnalyticsIcon color={isLocked
1524
+ ? AppColors.grayTextWeak
1525
+ : AppColors.purple} size={11}/>)}
1526
+ {tab.icon === 'webview' && (<GlobeIcon color={isLocked
1527
+ ? AppColors.grayTextWeak
1528
+ : AppColors.purple} size={11}/>)}
1529
+ {tab.icon === 'redux' && (<TerminalIcon color={isLocked
1530
+ ? AppColors.grayTextWeak
1531
+ : AppColors.purple} size={11}/>)}
1532
+ </View>
1533
+ {/* Label + Required badge */}
1534
+ <Text style={{
1499
1535
  fontFamily: AppFonts.interBold,
1500
- fontSize: 8.5,
1501
- color: AppColors.purple,
1502
- letterSpacing: 0.4,
1536
+ fontSize: 13,
1537
+ color: isLocked
1538
+ ? AppColors.grayText
1539
+ : AppColors.primaryBlack,
1503
1540
  }}>
1504
- DEFAULT
1505
- </Text>
1506
- </View>)}
1507
-
1508
- {/* Settings gear icon next to label */}
1509
- <TouchableScale onPress={() => {
1510
- animateNextLayout();
1511
- setSettingsPage(tab.key);
1512
- }} hitSlop={8} style={{
1513
- marginLeft: 4,
1514
- padding: 4,
1515
- borderRadius: 6,
1516
- backgroundColor: AppColors.purpleShade50,
1517
- borderWidth: 1,
1518
- borderColor: 'rgba(104,75,155,0.15)',
1519
- alignItems: 'center',
1520
- justifyContent: 'center',
1521
- }}>
1522
- <SettingsIcon color={AppColors.purple} size={10}/>
1523
- </TouchableScale>
1524
- </View>
1541
+ {tab.label}
1542
+ </Text>
1543
+ {/* #6 — badge marks the configured default tab */}
1544
+ {tab.key === defaultTab && (<View style={{
1545
+ flexDirection: 'row',
1546
+ alignItems: 'center',
1547
+ backgroundColor: 'rgba(104,75,155,0.08)',
1548
+ borderRadius: 20,
1549
+ paddingHorizontal: 6,
1550
+ paddingVertical: 2,
1551
+ borderWidth: 1,
1552
+ borderColor: 'rgba(104,75,155,0.18)',
1553
+ gap: 3,
1554
+ }}>
1555
+ <View style={{
1556
+ width: 4,
1557
+ height: 4,
1558
+ borderRadius: 2,
1559
+ backgroundColor: AppColors.purple,
1560
+ opacity: 0.7,
1561
+ }}/>
1562
+ <Text style={{
1563
+ fontFamily: AppFonts.interBold,
1564
+ fontSize: 8.5,
1565
+ color: AppColors.purple,
1566
+ letterSpacing: 0.4,
1567
+ }}>
1568
+ DEFAULT
1569
+ </Text>
1570
+ </View>)}
1525
1571
 
1526
- {/* Visibility Switch in VISIBILITY column */}
1527
- <View style={{
1528
- width: 90,
1529
- alignItems: 'flex-end',
1530
- justifyContent: 'center',
1531
- }}>
1532
- <TouchableScale disabled={isLocked} onPress={() => toggleTabVisibility(tab.key)} style={{
1533
- width: 38,
1534
- height: 22,
1535
- borderRadius: 11,
1536
- backgroundColor: isLocked
1537
- ? AppColors.grayBackground
1538
- : isVisible
1539
- ? AppColors.purple
1540
- : AppColors.grayBorderSecondary,
1541
- borderWidth: isLocked ? 1.5 : 0,
1542
- borderColor: isLocked
1543
- ? AppColors.grayBorderSecondary
1544
- : 'transparent',
1545
- borderStyle: isLocked ? 'dashed' : 'solid',
1546
- padding: 2,
1547
- justifyContent: 'center',
1548
- alignItems: isVisible ? 'flex-end' : 'flex-start',
1549
- opacity: isLocked ? 0.9 : 1,
1550
- }}>
1551
- <View style={{
1552
- width: 18,
1553
- height: 18,
1554
- borderRadius: 9,
1555
- backgroundColor: isLocked
1556
- ? AppColors.grayBorderSecondary
1557
- : '#FFFFFF',
1558
- alignItems: 'center',
1559
- justifyContent: 'center',
1560
- shadowColor: '#000',
1561
- shadowOpacity: isLocked ? 0 : 0.15,
1562
- shadowRadius: 1.5,
1563
- shadowOffset: { width: 0, height: 1 },
1564
- }}>
1565
- {isLocked && (<Svg width={10} height={10} viewBox="0 0 24 24" fill="none">
1566
- <Path d="M7 10V7a5 5 0 0 1 10 0v3" stroke={AppColors.grayText} strokeWidth="2.2" strokeLinecap="round"/>
1567
- <Path d="M5 10h14v9a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1z" fill={AppColors.grayText}/>
1568
- </Svg>)}
1569
- </View>
1570
- </TouchableScale>
1571
- {isLocked && (<Text style={{
1572
- fontFamily: AppFonts.interBold,
1573
- fontSize: 8,
1574
- color: AppColors.grayTextWeak,
1575
- letterSpacing: 0.4,
1576
- marginTop: 3,
1572
+ {/* Settings gear icon next to label */}
1573
+ <TouchableScale onPress={() => {
1574
+ animateNextLayout();
1575
+ setSettingsPage(tab.key);
1576
+ }} hitSlop={8} style={{
1577
+ marginLeft: 4,
1578
+ padding: 4,
1579
+ borderRadius: 6,
1580
+ backgroundColor: AppColors.purpleShade50,
1581
+ borderWidth: 1,
1582
+ borderColor: 'rgba(104,75,155,0.15)',
1583
+ alignItems: 'center',
1584
+ justifyContent: 'center',
1577
1585
  }}>
1578
- REQUIRED
1579
- </Text>)}
1580
- </View>
1581
- </View>);
1582
- })}
1583
- </View>
1586
+ <SettingsIcon color={AppColors.purple} size={10}/>
1587
+ </TouchableScale>
1588
+ </View>
1584
1589
 
1585
- {/* UI Preferences Section */}
1586
- <View style={{ marginTop: 8 }}>
1587
- <Text style={{
1588
- fontFamily: AppFonts.interBold,
1589
- fontSize: 10,
1590
- color: AppColors.grayTextWeak,
1591
- letterSpacing: 0.6,
1592
- marginBottom: 8,
1593
- }}>
1594
- UI PREFERENCES
1595
- </Text>
1596
- <View style={{
1597
- backgroundColor: AppColors.primaryLight,
1598
- borderRadius: 12,
1599
- borderWidth: 1,
1600
- borderColor: AppColors.grayBorderSecondary,
1601
- overflow: 'hidden',
1602
- }}>
1590
+ {/* Visibility Switch in VISIBILITY column */}
1591
+ <View style={{
1592
+ width: 90,
1593
+ alignItems: 'flex-end',
1594
+ justifyContent: 'center',
1595
+ }}>
1596
+ <TouchableScale disabled={isLocked} onPress={() => toggleTabVisibility(tab.key)} style={{
1597
+ width: 38,
1598
+ height: 22,
1599
+ borderRadius: 11,
1600
+ backgroundColor: isLocked
1601
+ ? AppColors.grayBackground
1602
+ : isVisible
1603
+ ? AppColors.purple
1604
+ : AppColors.grayBorderSecondary,
1605
+ borderWidth: isLocked ? 1.5 : 0,
1606
+ borderColor: isLocked
1607
+ ? AppColors.grayBorderSecondary
1608
+ : 'transparent',
1609
+ borderStyle: isLocked ? 'dashed' : 'solid',
1610
+ padding: 2,
1611
+ justifyContent: 'center',
1612
+ alignItems: isVisible ? 'flex-end' : 'flex-start',
1613
+ opacity: isLocked ? 0.9 : 1,
1614
+ }}>
1615
+ <View style={{
1616
+ width: 18,
1617
+ height: 18,
1618
+ borderRadius: 9,
1619
+ backgroundColor: isLocked
1620
+ ? AppColors.grayBorderSecondary
1621
+ : '#FFFFFF',
1622
+ alignItems: 'center',
1623
+ justifyContent: 'center',
1624
+ shadowColor: '#000',
1625
+ shadowOpacity: isLocked ? 0 : 0.15,
1626
+ shadowRadius: 1.5,
1627
+ shadowOffset: { width: 0, height: 1 },
1628
+ }}>
1629
+ {isLocked && (<Svg width={10} height={10} viewBox="0 0 24 24" fill="none">
1630
+ <Path d="M7 10V7a5 5 0 0 1 10 0v3" stroke={AppColors.grayText} strokeWidth="2.2" strokeLinecap="round"/>
1631
+ <Path d="M5 10h14v9a1 1 0 0 1-1 1H6a1 1 0 0 1-1-1z" fill={AppColors.grayText}/>
1632
+ </Svg>)}
1633
+ </View>
1634
+ </TouchableScale>
1635
+ {isLocked && (<Text style={{
1636
+ fontFamily: AppFonts.interBold,
1637
+ fontSize: 8,
1638
+ color: AppColors.grayTextWeak,
1639
+ letterSpacing: 0.4,
1640
+ marginTop: 3,
1641
+ }}>
1642
+ REQUIRED
1643
+ </Text>)}
1644
+ </View>
1645
+ </View>);
1646
+ })}
1647
+ </View>) : (
1648
+ /* UI Preferences Section */
1603
1649
  <View style={{
1604
- flexDirection: 'row',
1605
- alignItems: 'center',
1606
- paddingVertical: 12,
1607
- paddingHorizontal: 14,
1608
- gap: 12,
1609
- }}>
1650
+ backgroundColor: AppColors.primaryLight,
1651
+ borderRadius: 12,
1652
+ borderWidth: 1,
1653
+ borderColor: AppColors.grayBorderSecondary,
1654
+ overflow: 'hidden',
1655
+ }}>
1656
+ <View style={{
1657
+ flexDirection: 'row',
1658
+ alignItems: 'center',
1659
+ paddingVertical: 12,
1660
+ paddingHorizontal: 14,
1661
+ gap: 12,
1662
+ }}>
1610
1663
  {/* Icon + Label */}
1611
1664
  <View style={{
1612
- flex: 1,
1613
- flexDirection: 'row',
1614
- alignItems: 'center',
1615
- gap: 8,
1616
- }}>
1665
+ flex: 1,
1666
+ flexDirection: 'row',
1667
+ alignItems: 'center',
1668
+ gap: 8,
1669
+ }}>
1617
1670
  <View style={{
1618
- width: 20,
1619
- height: 20,
1620
- borderRadius: 6,
1621
- backgroundColor: AppColors.purpleShade50,
1622
- borderWidth: 1,
1623
- borderColor: 'rgba(104,75,155,0.2)',
1624
- alignItems: 'center',
1625
- justifyContent: 'center',
1626
- }}>
1671
+ width: 20,
1672
+ height: 20,
1673
+ borderRadius: 6,
1674
+ backgroundColor: AppColors.purpleShade50,
1675
+ borderWidth: 1,
1676
+ borderColor: 'rgba(104,75,155,0.2)',
1677
+ alignItems: 'center',
1678
+ justifyContent: 'center',
1679
+ }}>
1627
1680
  {isDark ? (<SunIcon color={AppColors.purple} size={11}/>) : (<MoonIcon color={AppColors.purple} size={11}/>)}
1628
1681
  </View>
1629
1682
  <View style={{ flex: 1 }}>
1630
1683
  <Text style={{
1631
- fontFamily: AppFonts.interBold,
1632
- fontSize: 13,
1633
- color: AppColors.primaryBlack,
1634
- }}>
1684
+ fontFamily: AppFonts.interBold,
1685
+ fontSize: 13,
1686
+ color: AppColors.primaryBlack,
1687
+ }}>
1635
1688
  Dark Theme
1636
1689
  </Text>
1637
1690
  </View>
@@ -1639,75 +1692,75 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
1639
1692
 
1640
1693
  {/* Toggle Switch */}
1641
1694
  <TouchableScale onPress={() => {
1642
- const newTheme = !isDark;
1643
- setIsDark(newTheme);
1644
- toggleGlobalTheme(newTheme);
1645
- }} style={{
1646
- width: 38,
1647
- height: 22,
1648
- borderRadius: 11,
1649
- backgroundColor: isDark
1650
- ? AppColors.purple
1651
- : AppColors.grayBorderSecondary,
1652
- padding: 2,
1653
- justifyContent: 'center',
1654
- alignItems: isDark ? 'flex-end' : 'flex-start',
1655
- }}>
1695
+ const newTheme = !isDark;
1696
+ setIsDark(newTheme);
1697
+ toggleGlobalTheme(newTheme);
1698
+ }} style={{
1699
+ width: 38,
1700
+ height: 22,
1701
+ borderRadius: 11,
1702
+ backgroundColor: isDark
1703
+ ? AppColors.purple
1704
+ : AppColors.grayBorderSecondary,
1705
+ padding: 2,
1706
+ justifyContent: 'center',
1707
+ alignItems: isDark ? 'flex-end' : 'flex-start',
1708
+ }}>
1656
1709
  <View style={{
1657
- width: 18,
1658
- height: 18,
1659
- borderRadius: 9,
1660
- backgroundColor: '#FFFFFF',
1661
- shadowColor: '#000',
1662
- shadowOpacity: 0.15,
1663
- shadowRadius: 1.5,
1664
- shadowOffset: { width: 0, height: 1 },
1665
- }}/>
1710
+ width: 18,
1711
+ height: 18,
1712
+ borderRadius: 9,
1713
+ backgroundColor: '#FFFFFF',
1714
+ shadowColor: '#000',
1715
+ shadowOpacity: 0.15,
1716
+ shadowRadius: 1.5,
1717
+ shadowOffset: { width: 0, height: 1 },
1718
+ }}/>
1666
1719
  </TouchableScale>
1667
1720
  </View>
1668
1721
 
1669
1722
  {/* Divider */}
1670
1723
  <View style={{
1671
- height: 1,
1672
- backgroundColor: AppColors.dividerColor,
1673
- }}/>
1724
+ height: 1,
1725
+ backgroundColor: AppColors.dividerColor,
1726
+ }}/>
1674
1727
 
1675
1728
  {/* Modal Height */}
1676
1729
  <View style={{
1677
- paddingVertical: 12,
1678
- paddingHorizontal: 14,
1679
- }}>
1730
+ paddingVertical: 12,
1731
+ paddingHorizontal: 14,
1732
+ }}>
1680
1733
  <View style={{
1681
- flexDirection: 'row',
1682
- alignItems: 'center',
1683
- gap: 8,
1684
- }}>
1734
+ flexDirection: 'row',
1735
+ alignItems: 'center',
1736
+ gap: 8,
1737
+ }}>
1685
1738
  <View style={{
1686
- width: 20,
1687
- height: 20,
1688
- borderRadius: 6,
1689
- backgroundColor: AppColors.purpleShade50,
1690
- borderWidth: 1,
1691
- borderColor: 'rgba(104,75,155,0.2)',
1692
- alignItems: 'center',
1693
- justifyContent: 'center',
1694
- }}>
1695
- <ScreenIcon color={AppColors.purple} size={11}/>
1696
- </View>
1739
+ width: 20,
1740
+ height: 20,
1741
+ borderRadius: 6,
1742
+ backgroundColor: AppColors.purpleShade50,
1743
+ borderWidth: 1,
1744
+ borderColor: 'rgba(104,75,155,0.2)',
1745
+ alignItems: 'center',
1746
+ justifyContent: 'center',
1747
+ }}>
1748
+ <ScreenIcon color={AppColors.purple} size={11}/>
1749
+ </View>
1697
1750
  <View style={{ flex: 1 }}>
1698
1751
  <Text style={{
1699
- fontFamily: AppFonts.interBold,
1700
- fontSize: 13,
1701
- color: AppColors.primaryBlack,
1702
- }}>
1752
+ fontFamily: AppFonts.interBold,
1753
+ fontSize: 13,
1754
+ color: AppColors.primaryBlack,
1755
+ }}>
1703
1756
  Modal Height
1704
1757
  </Text>
1705
1758
  <Text style={{
1706
- fontFamily: AppFonts.interRegular,
1707
- fontSize: 11,
1708
- color: AppColors.grayText,
1709
- marginTop: 1,
1710
- }}>
1759
+ fontFamily: AppFonts.interRegular,
1760
+ fontSize: 11,
1761
+ color: AppColors.grayText,
1762
+ marginTop: 1,
1763
+ }}>
1711
1764
  Height of the inspector panel relative to the screen
1712
1765
  </Text>
1713
1766
  </View>
@@ -1715,79 +1768,79 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
1715
1768
 
1716
1769
  {/* Segmented picker */}
1717
1770
  <View style={{
1718
- flexDirection: 'row',
1719
- backgroundColor: AppColors.grayBackground,
1720
- borderRadius: 8,
1721
- padding: 2.5,
1722
- marginTop: 10,
1723
- borderWidth: 1,
1724
- borderColor: AppColors.dividerColor,
1725
- }}>
1771
+ flexDirection: 'row',
1772
+ backgroundColor: AppColors.grayBackground,
1773
+ borderRadius: 8,
1774
+ padding: 2.5,
1775
+ marginTop: 10,
1776
+ borderWidth: 1,
1777
+ borderColor: AppColors.dividerColor,
1778
+ }}>
1726
1779
  {[50, 70, 90, 100].map(opt => {
1727
- const isActive = modalHeightPercent === opt;
1728
- return (<TouchableScale key={opt} onPress={() => setModalHeightPercent(opt)} style={{
1729
- flex: 1,
1730
- paddingVertical: 6,
1731
- alignItems: 'center',
1732
- borderRadius: 6,
1733
- backgroundColor: isActive
1734
- ? AppColors.purple
1735
- : 'transparent',
1736
- }}>
1780
+ const isActive = modalHeightPercent === opt;
1781
+ return (<TouchableScale key={opt} onPress={() => setModalHeightPercent(opt)} style={{
1782
+ flex: 1,
1783
+ paddingVertical: 6,
1784
+ alignItems: 'center',
1785
+ borderRadius: 6,
1786
+ backgroundColor: isActive
1787
+ ? AppColors.purple
1788
+ : 'transparent',
1789
+ }}>
1737
1790
  <Text style={{
1738
- fontFamily: AppFonts.interBold,
1739
- fontSize: 11,
1740
- color: isActive ? '#FFFFFF' : AppColors.grayText,
1741
- }}>
1791
+ fontFamily: AppFonts.interBold,
1792
+ fontSize: 11,
1793
+ color: isActive ? '#FFFFFF' : AppColors.grayText,
1794
+ }}>
1742
1795
  {opt}%
1743
1796
  </Text>
1744
1797
  </TouchableScale>);
1745
- })}
1798
+ })}
1746
1799
  </View>
1747
1800
  </View>
1748
1801
 
1749
1802
  {/* Divider */}
1750
1803
  <View style={{
1751
- height: 1,
1752
- backgroundColor: AppColors.dividerColor,
1753
- }}/>
1804
+ height: 1,
1805
+ backgroundColor: AppColors.dividerColor,
1806
+ }}/>
1754
1807
 
1755
1808
  {/* #6 — Default Tab */}
1756
1809
  <View style={{
1757
- paddingVertical: 12,
1758
- paddingHorizontal: 14,
1759
- }}>
1810
+ paddingVertical: 12,
1811
+ paddingHorizontal: 14,
1812
+ }}>
1760
1813
  <View style={{
1761
- flexDirection: 'row',
1762
- alignItems: 'center',
1763
- gap: 8,
1764
- }}>
1814
+ flexDirection: 'row',
1815
+ alignItems: 'center',
1816
+ gap: 8,
1817
+ }}>
1765
1818
  <View style={{
1766
- width: 20,
1767
- height: 20,
1768
- borderRadius: 6,
1769
- backgroundColor: AppColors.purpleShade50,
1770
- borderWidth: 1,
1771
- borderColor: 'rgba(104,75,155,0.2)',
1772
- alignItems: 'center',
1773
- justifyContent: 'center',
1774
- }}>
1819
+ width: 20,
1820
+ height: 20,
1821
+ borderRadius: 6,
1822
+ backgroundColor: AppColors.purpleShade50,
1823
+ borderWidth: 1,
1824
+ borderColor: 'rgba(104,75,155,0.2)',
1825
+ alignItems: 'center',
1826
+ justifyContent: 'center',
1827
+ }}>
1775
1828
  <LayersIcon color={AppColors.purple} size={11}/>
1776
1829
  </View>
1777
1830
  <View style={{ flex: 1 }}>
1778
1831
  <Text style={{
1779
- fontFamily: AppFonts.interBold,
1780
- fontSize: 13,
1781
- color: AppColors.primaryBlack,
1782
- }}>
1832
+ fontFamily: AppFonts.interBold,
1833
+ fontSize: 13,
1834
+ color: AppColors.primaryBlack,
1835
+ }}>
1783
1836
  Default Tab
1784
1837
  </Text>
1785
1838
  <Text style={{
1786
- fontFamily: AppFonts.interRegular,
1787
- fontSize: 11,
1788
- color: AppColors.grayText,
1789
- marginTop: 1,
1790
- }}>
1839
+ fontFamily: AppFonts.interRegular,
1840
+ fontSize: 11,
1841
+ color: AppColors.grayText,
1842
+ marginTop: 1,
1843
+ }}>
1791
1844
  Tab shown when the inspector opens
1792
1845
  </Text>
1793
1846
  </View>
@@ -1795,36 +1848,36 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
1795
1848
 
1796
1849
  {/* Grid of Default Tab Cards */}
1797
1850
  <View style={{
1798
- flexDirection: 'row',
1799
- flexWrap: 'wrap',
1800
- gap: 8,
1801
- marginTop: 12,
1802
- }}>
1851
+ flexDirection: 'row',
1852
+ flexWrap: 'wrap',
1853
+ gap: 8,
1854
+ marginTop: 12,
1855
+ }}>
1803
1856
  {settingsTabs
1804
- .filter(tab => tab.key === 'apis' || tabVisibility?.[tab.key])
1805
- .map(tab => {
1806
- const isActive = defaultTab === tab.key;
1807
- return (<TouchableScale key={tab.key} onPress={() => setDefaultTab(tab.key)} style={{
1808
- flexDirection: 'row',
1809
- alignItems: 'center',
1810
- gap: 8,
1811
- paddingVertical: 10,
1812
- paddingHorizontal: 12,
1813
- borderRadius: 10,
1814
- borderWidth: 1.5,
1815
- borderColor: isActive ? AppColors.purple : AppColors.grayBorderSecondary,
1816
- backgroundColor: isActive ? 'rgba(104,75,155,0.06)' : AppColors.primaryLight,
1817
- minWidth: '47%',
1818
- flex: 1,
1819
- }}>
1857
+ .filter(tab => tab.key === 'apis' || tabVisibility?.[tab.key])
1858
+ .map(tab => {
1859
+ const isActive = defaultTab === tab.key;
1860
+ return (<TouchableScale key={tab.key} onPress={() => setDefaultTab(tab.key)} style={{
1861
+ flexDirection: 'row',
1862
+ alignItems: 'center',
1863
+ gap: 8,
1864
+ paddingVertical: 10,
1865
+ paddingHorizontal: 12,
1866
+ borderRadius: 10,
1867
+ borderWidth: 1.5,
1868
+ borderColor: isActive ? AppColors.purple : AppColors.grayBorderSecondary,
1869
+ backgroundColor: isActive ? 'rgba(104,75,155,0.06)' : AppColors.primaryLight,
1870
+ minWidth: '47%',
1871
+ flex: 1,
1872
+ }}>
1820
1873
  <View style={{
1821
- width: 22,
1822
- height: 22,
1823
- borderRadius: 6,
1824
- backgroundColor: isActive ? AppColors.purple : AppColors.purpleShade50,
1825
- alignItems: 'center',
1826
- justifyContent: 'center',
1827
- }}>
1874
+ width: 22,
1875
+ height: 22,
1876
+ borderRadius: 6,
1877
+ backgroundColor: isActive ? AppColors.purple : AppColors.purpleShade50,
1878
+ alignItems: 'center',
1879
+ justifyContent: 'center',
1880
+ }}>
1828
1881
  {tab.icon === 'insights' && (<InsightsIcon color={isActive ? '#FFFFFF' : AppColors.purple} size={11}/>)}
1829
1882
  {tab.icon === 'apis' && (<SignalIcon color={isActive ? '#FFFFFF' : AppColors.purple} size={11}/>)}
1830
1883
  {tab.icon === 'logs' && (<TerminalIcon color={isActive ? '#FFFFFF' : AppColors.purple} size={11}/>)}
@@ -1833,74 +1886,74 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
1833
1886
  {tab.icon === 'redux' && (<TerminalIcon color={isActive ? '#FFFFFF' : AppColors.purple} size={11}/>)}
1834
1887
  </View>
1835
1888
  <Text style={{
1836
- fontFamily: AppFonts.interBold,
1837
- fontSize: 13,
1838
- color: isActive ? AppColors.purple : AppColors.primaryBlack,
1839
- flex: 1,
1840
- }}>
1889
+ fontFamily: AppFonts.interBold,
1890
+ fontSize: 13,
1891
+ color: isActive ? AppColors.purple : AppColors.primaryBlack,
1892
+ flex: 1,
1893
+ }}>
1841
1894
  {tab.label}
1842
1895
  </Text>
1843
1896
  {isActive && (<View style={{
1844
- width: 14,
1845
- height: 14,
1846
- borderRadius: 7,
1847
- backgroundColor: AppColors.purple,
1848
- alignItems: 'center',
1849
- justifyContent: 'center',
1850
- }}>
1897
+ width: 14,
1898
+ height: 14,
1899
+ borderRadius: 7,
1900
+ backgroundColor: AppColors.purple,
1901
+ alignItems: 'center',
1902
+ justifyContent: 'center',
1903
+ }}>
1851
1904
  <CheckIcon size={8} color="#FFFFFF"/>
1852
1905
  </View>)}
1853
1906
  </TouchableScale>);
1854
- })}
1907
+ })}
1855
1908
  </View>
1856
1909
  </View>
1857
1910
 
1858
1911
  {/* Divider */}
1859
1912
  <View style={{
1860
- height: 1,
1861
- backgroundColor: AppColors.dividerColor,
1862
- }}/>
1913
+ height: 1,
1914
+ backgroundColor: AppColors.dividerColor,
1915
+ }}/>
1863
1916
 
1864
1917
  {/* #9 — Show Duplicate Logs */}
1865
1918
  <View style={{
1866
- flexDirection: 'row',
1867
- alignItems: 'center',
1868
- paddingVertical: 12,
1869
- paddingHorizontal: 14,
1870
- gap: 12,
1871
- }}>
1919
+ flexDirection: 'row',
1920
+ alignItems: 'center',
1921
+ paddingVertical: 12,
1922
+ paddingHorizontal: 14,
1923
+ gap: 12,
1924
+ }}>
1872
1925
  <View style={{
1873
- flex: 1,
1874
- flexDirection: 'row',
1875
- alignItems: 'center',
1876
- gap: 8,
1877
- }}>
1926
+ flex: 1,
1927
+ flexDirection: 'row',
1928
+ alignItems: 'center',
1929
+ gap: 8,
1930
+ }}>
1878
1931
  <View style={{
1879
- width: 20,
1880
- height: 20,
1881
- borderRadius: 6,
1882
- backgroundColor: AppColors.purpleShade50,
1883
- borderWidth: 1,
1884
- borderColor: 'rgba(104,75,155,0.2)',
1885
- alignItems: 'center',
1886
- justifyContent: 'center',
1887
- }}>
1932
+ width: 20,
1933
+ height: 20,
1934
+ borderRadius: 6,
1935
+ backgroundColor: AppColors.purpleShade50,
1936
+ borderWidth: 1,
1937
+ borderColor: 'rgba(104,75,155,0.2)',
1938
+ alignItems: 'center',
1939
+ justifyContent: 'center',
1940
+ }}>
1888
1941
  <EyeIcon color={AppColors.purple} size={11}/>
1889
1942
  </View>
1890
1943
  <View style={{ flex: 1 }}>
1891
1944
  <Text style={{
1892
- fontFamily: AppFonts.interBold,
1893
- fontSize: 13,
1894
- color: AppColors.primaryBlack,
1895
- }}>
1945
+ fontFamily: AppFonts.interBold,
1946
+ fontSize: 13,
1947
+ color: AppColors.primaryBlack,
1948
+ }}>
1896
1949
  Show Duplicate Logs
1897
1950
  </Text>
1898
1951
  <Text style={{
1899
- fontFamily: AppFonts.interRegular,
1900
- fontSize: 11,
1901
- color: AppColors.grayText,
1902
- marginTop: 1,
1903
- }}>
1952
+ fontFamily: AppFonts.interRegular,
1953
+ fontSize: 11,
1954
+ color: AppColors.grayText,
1955
+ marginTop: 1,
1956
+ }}>
1904
1957
  Off: repeated identical entries collapse into one row
1905
1958
  with a ×N count
1906
1959
  </Text>
@@ -1909,99 +1962,99 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
1909
1962
 
1910
1963
  {/* Toggle Switch */}
1911
1964
  <TouchableScale onPress={() => setShowDuplicateLogs(prev => !prev)} style={{
1912
- width: 38,
1913
- height: 22,
1914
- borderRadius: 11,
1915
- backgroundColor: showDuplicateLogs
1916
- ? AppColors.purple
1917
- : AppColors.grayBorderSecondary,
1918
- padding: 2,
1919
- justifyContent: 'center',
1920
- alignItems: showDuplicateLogs ? 'flex-end' : 'flex-start',
1921
- }}>
1965
+ width: 38,
1966
+ height: 22,
1967
+ borderRadius: 11,
1968
+ backgroundColor: showDuplicateLogs
1969
+ ? AppColors.purple
1970
+ : AppColors.grayBorderSecondary,
1971
+ padding: 2,
1972
+ justifyContent: 'center',
1973
+ alignItems: showDuplicateLogs ? 'flex-end' : 'flex-start',
1974
+ }}>
1922
1975
  <View style={{
1923
- width: 18,
1924
- height: 18,
1925
- borderRadius: 9,
1926
- backgroundColor: '#FFFFFF',
1927
- shadowColor: '#000',
1928
- shadowOpacity: 0.15,
1929
- shadowRadius: 1.5,
1930
- shadowOffset: { width: 0, height: 1 },
1931
- }}/>
1976
+ width: 18,
1977
+ height: 18,
1978
+ borderRadius: 9,
1979
+ backgroundColor: '#FFFFFF',
1980
+ shadowColor: '#000',
1981
+ shadowOpacity: 0.15,
1982
+ shadowRadius: 1.5,
1983
+ shadowOffset: { width: 0, height: 1 },
1984
+ }}/>
1932
1985
  </TouchableScale>
1933
1986
  </View>
1934
1987
 
1935
1988
  {/* Divider */}
1936
1989
  <View style={{
1937
- height: 1,
1938
- backgroundColor: AppColors.dividerColor,
1939
- }}/>
1990
+ height: 1,
1991
+ backgroundColor: AppColors.dividerColor,
1992
+ }}/>
1940
1993
 
1941
1994
  {/* Reset Settings */}
1942
1995
  <View style={{
1943
- flexDirection: 'row',
1944
- alignItems: 'center',
1945
- paddingVertical: 12,
1946
- paddingHorizontal: 14,
1947
- gap: 12,
1948
- }}>
1996
+ flexDirection: 'row',
1997
+ alignItems: 'center',
1998
+ paddingVertical: 12,
1999
+ paddingHorizontal: 14,
2000
+ gap: 12,
2001
+ }}>
1949
2002
  <View style={{
1950
- flex: 1,
1951
- flexDirection: 'row',
1952
- alignItems: 'center',
1953
- gap: 8,
1954
- }}>
2003
+ flex: 1,
2004
+ flexDirection: 'row',
2005
+ alignItems: 'center',
2006
+ gap: 8,
2007
+ }}>
1955
2008
  <View style={{
1956
- width: 20,
1957
- height: 20,
1958
- borderRadius: 6,
1959
- backgroundColor: 'rgba(239,68,68,0.08)',
1960
- borderWidth: 1,
1961
- borderColor: 'rgba(239,68,68,0.2)',
1962
- alignItems: 'center',
1963
- justifyContent: 'center',
1964
- }}>
2009
+ width: 20,
2010
+ height: 20,
2011
+ borderRadius: 6,
2012
+ backgroundColor: 'rgba(239,68,68,0.08)',
2013
+ borderWidth: 1,
2014
+ borderColor: 'rgba(239,68,68,0.2)',
2015
+ alignItems: 'center',
2016
+ justifyContent: 'center',
2017
+ }}>
1965
2018
  <TrashIcon color={AppColors.errorColor} size={11}/>
1966
2019
  </View>
1967
2020
  <View style={{ flex: 1 }}>
1968
2021
  <Text style={{
1969
- fontFamily: AppFonts.interBold,
1970
- fontSize: 13,
1971
- color: AppColors.primaryBlack,
1972
- }}>
2022
+ fontFamily: AppFonts.interBold,
2023
+ fontSize: 13,
2024
+ color: AppColors.primaryBlack,
2025
+ }}>
1973
2026
  Reset Settings
1974
2027
  </Text>
1975
2028
  <Text style={{
1976
- fontFamily: AppFonts.interRegular,
1977
- fontSize: 11,
1978
- color: AppColors.grayText,
1979
- marginTop: 1,
1980
- }}>
2029
+ fontFamily: AppFonts.interRegular,
2030
+ fontSize: 11,
2031
+ color: AppColors.grayText,
2032
+ marginTop: 1,
2033
+ }}>
1981
2034
  Wipe custom configurations and load package defaults
1982
2035
  </Text>
1983
2036
  </View>
1984
2037
  </View>
1985
2038
 
1986
2039
  <TouchableScale onPress={resetToDefaults} style={{
1987
- paddingHorizontal: 10,
1988
- paddingVertical: 5,
1989
- borderRadius: 7,
1990
- backgroundColor: 'rgba(255,46,87,0.08)',
1991
- borderWidth: 1,
1992
- borderColor: 'rgba(255,46,87,0.2)',
1993
- }}>
2040
+ paddingHorizontal: 10,
2041
+ paddingVertical: 5,
2042
+ borderRadius: 7,
2043
+ backgroundColor: 'rgba(255,46,87,0.08)',
2044
+ borderWidth: 1,
2045
+ borderColor: 'rgba(255,46,87,0.2)',
2046
+ }}>
1994
2047
  <Text style={{
1995
- fontFamily: AppFonts.interBold,
1996
- fontSize: 11,
1997
- color: AppColors.errorColor,
1998
- }}>
2048
+ fontFamily: AppFonts.interBold,
2049
+ fontSize: 11,
2050
+ color: AppColors.errorColor,
2051
+ }}>
1999
2052
  Reset
2000
2053
  </Text>
2001
2054
  </TouchableScale>
2002
2055
  </View>
2003
- </View>
2004
- </View>
2056
+ </View>)}
2057
+
2005
2058
 
2006
2059
  {/* Storage Status */}
2007
2060
  <View style={{
@@ -2843,296 +2896,403 @@ const NetworkInspector = ({ enabled = true, storage, }) => {
2843
2896
  </View>
2844
2897
  </View>
2845
2898
 
2846
- {/* Module 1: APIs */}
2847
- {tabVisibility?.apis && (<TouchableScale style={styles.dashboardModuleCard} onPress={() => switchActiveTab('apis')}>
2848
- <View style={styles.dashboardModuleHeader}>
2849
- <View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
2850
- <SignalIcon color={AppColors.purple} size={18}/>
2851
- <Text style={styles.dashboardModuleTitle}>APIs & Network</Text>
2852
- </View>
2853
- <Text style={styles.dashboardModuleGoText}>View Details →</Text>
2854
- </View>
2855
- <View style={styles.dashboardModuleGrid}>
2856
- <View style={styles.dashboardGridItem}>
2857
- <Text style={styles.dashboardGridVal}>{apiTotal}</Text>
2858
- <Text style={styles.dashboardGridLbl}>Requests</Text>
2859
- </View>
2860
- <View style={styles.dashboardGridItem}>
2861
- <Text style={[
2862
- styles.dashboardGridVal,
2863
- apiSuccessRate < 90 && { color: AppColors.warningIconGold },
2864
- ]}>
2865
- {apiSuccessRate}%
2866
- </Text>
2867
- <Text style={styles.dashboardGridLbl}>Success Rate</Text>
2868
- </View>
2869
- <View style={styles.dashboardGridItem}>
2870
- <Text style={[
2871
- styles.dashboardGridVal,
2872
- apiErrors > 0 && { color: AppColors.errorColor },
2873
- ]}>
2874
- {apiErrors}
2875
- </Text>
2876
- <Text style={styles.dashboardGridLbl}>Errors</Text>
2877
- </View>
2878
- <View style={styles.dashboardGridItem}>
2879
- <Text style={styles.dashboardGridVal}>
2880
- {avgTime != null ? `${avgTime}ms` : '—'}
2881
- </Text>
2882
- <Text style={styles.dashboardGridLbl}>Avg Latency</Text>
2883
- </View>
2884
- </View>
2885
-
2886
- {/* Status-class breakdown + latency range */}
2887
- <View style={{
2888
- marginTop: 10,
2889
- paddingTop: 10,
2890
- borderTopWidth: 1,
2891
- borderTopColor: AppColors.dividerColor,
2892
- flexDirection: 'row',
2893
- alignItems: 'center',
2894
- flexWrap: 'wrap',
2895
- gap: 6,
2896
- }}>
2897
- {[
2898
- { label: '2xx', value: status2xx, color: AppColors.greenColor },
2899
- { label: '3xx', value: status3xx, color: AppColors.skyBlue },
2899
+ {/* ── Insights Sub-Tab Selector ── */}
2900
+ {(() => {
2901
+ const insightTabs = [
2900
2902
  {
2901
- label: '4xx',
2902
- value: status4xx,
2903
- color: AppColors.warningIconGold,
2903
+ key: 'apis',
2904
+ label: 'APIs',
2905
+ icon: (c, s) => <SignalIcon color={c} size={s}/>,
2906
+ color: AppColors.purple,
2907
+ count: apiTotal,
2908
+ visible: !!tabVisibility?.apis,
2904
2909
  },
2905
- { label: '5xx', value: status5xx, color: AppColors.errorColor },
2906
- ].map(s => (<View key={s.label} style={{
2907
- flexDirection: 'row',
2908
- alignItems: 'center',
2909
- gap: 4,
2910
- backgroundColor: AppColors.grayBackground,
2911
- borderRadius: 6,
2912
- borderWidth: 1,
2913
- borderColor: AppColors.dividerColor,
2914
- paddingHorizontal: 7,
2915
- paddingVertical: 3,
2916
- }}>
2917
- <View style={{
2918
- width: 6,
2919
- height: 6,
2920
- borderRadius: 3,
2921
- backgroundColor: s.color,
2922
- }}/>
2923
- <Text style={{
2924
- fontFamily: AppFonts.interBold,
2925
- fontSize: 10,
2926
- color: AppColors.grayTextStrong,
2927
- }}>
2928
- {s.label} {s.value}
2929
- </Text>
2930
- </View>))}
2931
- {slowestTime != null && (<View style={{
2932
- marginLeft: 'auto',
2933
- flexDirection: 'row',
2934
- alignItems: 'center',
2935
- gap: 4,
2936
- }}>
2937
- <Text style={{
2938
- fontFamily: AppFonts.interRegular,
2939
- fontSize: 10,
2940
- color: AppColors.grayTextWeak,
2941
- }}>
2942
- Range
2943
- </Text>
2944
- <Text style={{
2945
- fontFamily: AppFonts.interBold,
2946
- fontSize: 10,
2947
- color: AppColors.grayTextStrong,
2910
+ {
2911
+ key: 'logs',
2912
+ label: 'Logs',
2913
+ icon: (c, s) => <TerminalIcon color={c} size={s}/>,
2914
+ color: '#0D9488',
2915
+ count: logTotal,
2916
+ visible: !!tabVisibility?.logs,
2917
+ },
2918
+ {
2919
+ key: 'analytics',
2920
+ label: 'Analytics',
2921
+ icon: (c, s) => <AnalyticsIcon color={c} size={s}/>,
2922
+ color: '#EA580C',
2923
+ count: analyticsTotal,
2924
+ visible: !!tabVisibility?.analytics,
2925
+ },
2926
+ {
2927
+ key: 'webview',
2928
+ label: 'WebView',
2929
+ icon: (c, s) => <GlobeIcon color={c} size={s}/>,
2930
+ color: '#2563EB',
2931
+ count: webviewTotal,
2932
+ visible: !!tabVisibility?.webview,
2933
+ },
2934
+ {
2935
+ key: 'redux',
2936
+ label: 'Redux',
2937
+ icon: (c, s) => <TerminalIcon color={c} size={s}/>,
2938
+ color: AppColors.purple,
2939
+ count: reduxState ? Object.keys(reduxState).length : 0,
2940
+ visible: !!tabVisibility?.redux,
2941
+ },
2942
+ ];
2943
+ const visibleTabs = insightTabs.filter(t => t.visible);
2944
+ if (visibleTabs.length === 0)
2945
+ return null;
2946
+ return (<>
2947
+ <ScrollView horizontal showsHorizontalScrollIndicator={false} contentContainerStyle={{
2948
+ paddingHorizontal: 2,
2949
+ paddingVertical: 2,
2950
+ gap: 8,
2951
+ }} style={{
2952
+ marginBottom: 12,
2953
+ flexGrow: 0,
2948
2954
  }}>
2949
- {fastestTime}–{slowestTime}ms
2950
- </Text>
2951
- </View>)}
2952
- </View>
2953
- </TouchableScale>)}
2954
- {tabVisibility?.logs && (<TouchableScale style={styles.dashboardModuleCard} onPress={() => switchActiveTab('logs')}>
2955
- <View style={styles.dashboardModuleHeader}>
2956
- <View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
2957
- <TerminalIcon color="#0D9488" size={18}/>
2958
- <Text style={styles.dashboardModuleTitle}>Console Logs</Text>
2959
- </View>
2960
- <Text style={styles.dashboardModuleGoText}>View Details →</Text>
2961
- </View>
2962
- <View style={styles.dashboardModuleGrid}>
2963
- <View style={styles.dashboardGridItem}>
2964
- <Text style={styles.dashboardGridVal}>{logTotal}</Text>
2965
- <Text style={styles.dashboardGridLbl}>Total Logs</Text>
2966
- </View>
2967
- <View style={styles.dashboardGridItem}>
2968
- <Text style={[styles.dashboardGridVal, { color: '#0D9488' }]}>
2969
- {logInfos}
2970
- </Text>
2971
- <Text style={styles.dashboardGridLbl}>Info</Text>
2972
- </View>
2973
- <View style={styles.dashboardGridItem}>
2974
- <Text style={[
2975
- styles.dashboardGridVal,
2976
- logWarns > 0 && { color: AppColors.warningIconGold },
2977
- ]}>
2978
- {logWarns}
2979
- </Text>
2980
- <Text style={styles.dashboardGridLbl}>Warnings</Text>
2981
- </View>
2982
- <View style={styles.dashboardGridItem}>
2983
- <Text style={[
2984
- styles.dashboardGridVal,
2985
- logErrors > 0 && { color: AppColors.errorColor },
2986
- ]}>
2987
- {logErrors}
2988
- </Text>
2989
- <Text style={styles.dashboardGridLbl}>Errors</Text>
2990
- </View>
2991
- </View>
2992
- </TouchableScale>)}
2993
-
2994
- {/* Module 3: Analytics */}
2995
- {tabVisibility?.analytics && (<TouchableScale style={styles.dashboardModuleCard} onPress={() => switchActiveTab('analytics')}>
2996
- <View style={styles.dashboardModuleHeader}>
2997
- <View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
2998
- <AnalyticsIcon color="#EA580C" size={18}/>
2999
- <Text style={styles.dashboardModuleTitle}>
3000
- Analytics Events
3001
- </Text>
3002
- </View>
3003
- <Text style={styles.dashboardModuleGoText}>View Details →</Text>
3004
- </View>
3005
- <View style={styles.dashboardModuleGrid}>
3006
- <View style={styles.dashboardGridItem}>
3007
- <Text style={styles.dashboardGridVal}>{analyticsTotal}</Text>
3008
- <Text style={styles.dashboardGridLbl}>Total Events</Text>
3009
- </View>
3010
- <View style={styles.dashboardGridItem}>
3011
- <Text style={[styles.dashboardGridVal, { color: '#EA580C' }]}>
3012
- {uniqueEvents}
3013
- </Text>
3014
- <Text style={styles.dashboardGridLbl}>Unique Names</Text>
3015
- </View>
3016
- <View style={styles.dashboardGridItem}>
3017
- <Text style={styles.dashboardGridVal}>{screenViews}</Text>
3018
- <Text style={styles.dashboardGridLbl}>Screen Views</Text>
3019
- </View>
3020
- <View style={styles.dashboardGridItem}>
3021
- <Text style={styles.dashboardGridVal}>
3022
- {analyticsTotal > 0
3023
- ? Math.round(analyticsTotal / Math.max(1, logs.length / 5))
3024
- : 0}
3025
- </Text>
3026
- <Text style={styles.dashboardGridLbl}>Events Ratio</Text>
3027
- </View>
3028
- </View>
3029
- </TouchableScale>)}
2955
+ {visibleTabs.map(tab => {
2956
+ const isActive = insightsActiveSubTab === tab.key;
2957
+ return (<TouchableOpacity key={tab.key} onPress={() => {
2958
+ animateNextLayout();
2959
+ setInsightsActiveSubTab(tab.key);
2960
+ }} activeOpacity={0.7} style={{
2961
+ flexDirection: 'row',
2962
+ alignItems: 'center',
2963
+ gap: 6,
2964
+ paddingHorizontal: 14,
2965
+ paddingVertical: 8,
2966
+ borderRadius: 20,
2967
+ backgroundColor: isActive
2968
+ ? tab.color
2969
+ : AppColors.primaryLight,
2970
+ borderWidth: 1,
2971
+ borderColor: isActive
2972
+ ? tab.color
2973
+ : AppColors.grayBorderSecondary,
2974
+ }}>
2975
+ {tab.icon(isActive ? '#FFFFFF' : tab.color, 14)}
2976
+ <Text style={{
2977
+ fontFamily: AppFonts.interBold,
2978
+ fontSize: 11.5,
2979
+ color: isActive ? '#FFFFFF' : AppColors.grayTextStrong,
2980
+ }}>
2981
+ {tab.label}
2982
+ </Text>
2983
+ <View style={{
2984
+ minWidth: 20,
2985
+ height: 18,
2986
+ borderRadius: 9,
2987
+ paddingHorizontal: 5,
2988
+ alignItems: 'center',
2989
+ justifyContent: 'center',
2990
+ backgroundColor: isActive
2991
+ ? 'rgba(255,255,255,0.25)'
2992
+ : AppColors.grayBackground,
2993
+ }}>
2994
+ <Text style={{
2995
+ fontFamily: AppFonts.interBold,
2996
+ fontSize: 9.5,
2997
+ color: isActive ? '#FFFFFF' : AppColors.grayTextWeak,
2998
+ }}>
2999
+ {tab.count}
3000
+ </Text>
3001
+ </View>
3002
+ </TouchableOpacity>);
3003
+ })}
3004
+ </ScrollView>
3030
3005
 
3031
- {/* Module 4: WebView */}
3032
- {tabVisibility?.webview && (<TouchableScale style={styles.dashboardModuleCard} onPress={() => switchActiveTab('webview')}>
3033
- <View style={styles.dashboardModuleHeader}>
3034
- <View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
3035
- <GlobeIcon color="#2563EB" size={18}/>
3036
- <Text style={styles.dashboardModuleTitle}>
3037
- WebView Captures
3038
- </Text>
3039
- </View>
3040
- <Text style={styles.dashboardModuleGoText}>View Details →</Text>
3041
- </View>
3042
- <View style={styles.dashboardModuleGrid}>
3043
- <View style={styles.dashboardGridItem}>
3044
- <Text style={styles.dashboardGridVal}>{webviewTotal}</Text>
3045
- <Text style={styles.dashboardGridLbl}>History Size</Text>
3046
- </View>
3047
- <View style={styles.dashboardGridItem}>
3048
- <Text style={[styles.dashboardGridVal, { color: '#16A34A' }]}>
3049
- Active
3050
- </Text>
3051
- <Text style={styles.dashboardGridLbl}>Status</Text>
3052
- </View>
3053
- <View style={styles.dashboardGridItem}>
3054
- <Text numberOfLines={1} style={styles.dashboardGridVal}>
3055
- {webviewTotal > 0
3056
- ? `${webViewNavHistory[0]?.title?.substring(0, 10) ?? ''}...`
3057
- : '—'}
3058
- </Text>
3059
- <Text style={styles.dashboardGridLbl}>Last URL</Text>
3060
- </View>
3061
- </View>
3062
- </TouchableScale>)}
3006
+ {/* ── Active Module Card ── */}
3007
+ {insightsActiveSubTab === 'apis' && tabVisibility?.apis && (<TouchableScale style={styles.dashboardModuleCard} onPress={() => switchActiveTab('apis')}>
3008
+ <View style={styles.dashboardModuleHeader}>
3009
+ <View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
3010
+ <SignalIcon color={AppColors.purple} size={18}/>
3011
+ <Text style={styles.dashboardModuleTitle}>APIs & Network</Text>
3012
+ </View>
3013
+ <Text style={styles.dashboardModuleGoText}>View Details →</Text>
3014
+ </View>
3015
+ <View style={styles.dashboardModuleGrid}>
3016
+ <View style={styles.dashboardGridItem}>
3017
+ <Text style={styles.dashboardGridVal}>{apiTotal}</Text>
3018
+ <Text style={styles.dashboardGridLbl}>Requests</Text>
3019
+ </View>
3020
+ <View style={styles.dashboardGridItem}>
3021
+ <Text style={[
3022
+ styles.dashboardGridVal,
3023
+ apiSuccessRate < 90 && { color: AppColors.warningIconGold },
3024
+ ]}>
3025
+ {apiSuccessRate}%
3026
+ </Text>
3027
+ <Text style={styles.dashboardGridLbl}>Success Rate</Text>
3028
+ </View>
3029
+ <View style={styles.dashboardGridItem}>
3030
+ <Text style={[
3031
+ styles.dashboardGridVal,
3032
+ apiErrors > 0 && { color: AppColors.errorColor },
3033
+ ]}>
3034
+ {apiErrors}
3035
+ </Text>
3036
+ <Text style={styles.dashboardGridLbl}>Errors</Text>
3037
+ </View>
3038
+ <View style={styles.dashboardGridItem}>
3039
+ <Text style={styles.dashboardGridVal}>
3040
+ {avgTime != null ? `${avgTime}ms` : '—'}
3041
+ </Text>
3042
+ <Text style={styles.dashboardGridLbl}>Avg Latency</Text>
3043
+ </View>
3044
+ </View>
3063
3045
 
3064
- {/* Module 5: Redux Store */}
3065
- {tabVisibility?.redux && (<TouchableScale style={styles.dashboardModuleCard} onPress={() => switchActiveTab('redux')}>
3066
- <View style={styles.dashboardModuleHeader}>
3067
- <View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
3068
- <TerminalIcon color={AppColors.purple} size={18}/>
3069
- <Text style={styles.dashboardModuleTitle}>
3070
- Redux Store State
3071
- </Text>
3072
- </View>
3073
- <Text style={styles.dashboardModuleGoText}>View Details →</Text>
3074
- </View>
3075
- {reduxState ? (<View style={{ paddingHorizontal: 12, paddingBottom: 12, gap: 6 }}>
3076
- <View style={{
3077
- flexDirection: 'row',
3078
- justifyContent: 'space-between',
3079
- marginBottom: 4,
3080
- }}>
3081
- <Text style={{
3082
- fontFamily: AppFonts.interBold,
3083
- fontSize: 10,
3084
- color: AppColors.grayTextWeak,
3085
- letterSpacing: 0.5,
3086
- }}>
3087
- REDUCER NAME
3088
- </Text>
3089
- <Text style={{
3090
- fontFamily: AppFonts.interBold,
3091
- fontSize: 10,
3092
- color: AppColors.grayTextWeak,
3093
- letterSpacing: 0.5,
3094
- }}>
3095
- SIZE / FIELDS
3096
- </Text>
3097
- </View>
3098
- {Object.keys(reduxState).map(key => {
3099
- const val = reduxState[key];
3100
- const fieldsCount = typeof val === 'object' && val !== null
3101
- ? Object.keys(val).length
3102
- : 0;
3103
- const sizeStr = getSize(val);
3104
- return (<View key={key} style={{
3046
+ {/* Status-class breakdown + latency range */}
3047
+ <View style={{
3048
+ marginTop: 10,
3049
+ paddingTop: 10,
3050
+ borderTopWidth: 1,
3051
+ borderTopColor: AppColors.dividerColor,
3052
+ flexDirection: 'row',
3053
+ alignItems: 'center',
3054
+ flexWrap: 'wrap',
3055
+ gap: 6,
3056
+ }}>
3057
+ {[
3058
+ { label: '2xx', value: status2xx, color: AppColors.greenColor },
3059
+ { label: '3xx', value: status3xx, color: AppColors.skyBlue },
3060
+ {
3061
+ label: '4xx',
3062
+ value: status4xx,
3063
+ color: AppColors.warningIconGold,
3064
+ },
3065
+ { label: '5xx', value: status5xx, color: AppColors.errorColor },
3066
+ ].map(s => (<View key={s.label} style={{
3105
3067
  flexDirection: 'row',
3106
- justifyContent: 'space-between',
3107
3068
  alignItems: 'center',
3108
- paddingVertical: 2,
3069
+ gap: 4,
3070
+ backgroundColor: AppColors.grayBackground,
3071
+ borderRadius: 6,
3072
+ borderWidth: 1,
3073
+ borderColor: AppColors.dividerColor,
3074
+ paddingHorizontal: 7,
3075
+ paddingVertical: 3,
3109
3076
  }}>
3110
- <Text style={{
3111
- fontFamily: AppFonts.interMedium,
3112
- fontSize: 12,
3077
+ <View style={{
3078
+ width: 6,
3079
+ height: 6,
3080
+ borderRadius: 3,
3081
+ backgroundColor: s.color,
3082
+ }}/>
3083
+ <Text style={{
3084
+ fontFamily: AppFonts.interBold,
3085
+ fontSize: 10,
3086
+ color: AppColors.grayTextStrong,
3087
+ }}>
3088
+ {s.label} {s.value}
3089
+ </Text>
3090
+ </View>))}
3091
+ {slowestTime != null && (<View style={{
3092
+ marginLeft: 'auto',
3093
+ flexDirection: 'row',
3094
+ alignItems: 'center',
3095
+ gap: 4,
3096
+ }}>
3097
+ <Text style={{
3098
+ fontFamily: AppFonts.interRegular,
3099
+ fontSize: 10,
3100
+ color: AppColors.grayTextWeak,
3101
+ }}>
3102
+ Range
3103
+ </Text>
3104
+ <Text style={{
3105
+ fontFamily: AppFonts.interBold,
3106
+ fontSize: 10,
3113
3107
  color: AppColors.grayTextStrong,
3114
3108
  }}>
3115
- {key}
3109
+ {fastestTime}–{slowestTime}ms
3110
+ </Text>
3111
+ </View>)}
3112
+ </View>
3113
+ </TouchableScale>)}
3114
+
3115
+ {insightsActiveSubTab === 'logs' && tabVisibility?.logs && (<TouchableScale style={styles.dashboardModuleCard} onPress={() => switchActiveTab('logs')}>
3116
+ <View style={styles.dashboardModuleHeader}>
3117
+ <View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
3118
+ <TerminalIcon color="#0D9488" size={18}/>
3119
+ <Text style={styles.dashboardModuleTitle}>Console Logs</Text>
3120
+ </View>
3121
+ <Text style={styles.dashboardModuleGoText}>View Details →</Text>
3122
+ </View>
3123
+ <View style={styles.dashboardModuleGrid}>
3124
+ <View style={styles.dashboardGridItem}>
3125
+ <Text style={styles.dashboardGridVal}>{logTotal}</Text>
3126
+ <Text style={styles.dashboardGridLbl}>Total Logs</Text>
3127
+ </View>
3128
+ <View style={styles.dashboardGridItem}>
3129
+ <Text style={[styles.dashboardGridVal, { color: '#0D9488' }]}>
3130
+ {logInfos}
3116
3131
  </Text>
3132
+ <Text style={styles.dashboardGridLbl}>Info</Text>
3133
+ </View>
3134
+ <View style={styles.dashboardGridItem}>
3135
+ <Text style={[
3136
+ styles.dashboardGridVal,
3137
+ logWarns > 0 && { color: AppColors.warningIconGold },
3138
+ ]}>
3139
+ {logWarns}
3140
+ </Text>
3141
+ <Text style={styles.dashboardGridLbl}>Warnings</Text>
3142
+ </View>
3143
+ <View style={styles.dashboardGridItem}>
3144
+ <Text style={[
3145
+ styles.dashboardGridVal,
3146
+ logErrors > 0 && { color: AppColors.errorColor },
3147
+ ]}>
3148
+ {logErrors}
3149
+ </Text>
3150
+ <Text style={styles.dashboardGridLbl}>Errors</Text>
3151
+ </View>
3152
+ </View>
3153
+ </TouchableScale>)}
3154
+
3155
+ {insightsActiveSubTab === 'analytics' && tabVisibility?.analytics && (<TouchableScale style={styles.dashboardModuleCard} onPress={() => switchActiveTab('analytics')}>
3156
+ <View style={styles.dashboardModuleHeader}>
3157
+ <View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
3158
+ <AnalyticsIcon color="#EA580C" size={18}/>
3159
+ <Text style={styles.dashboardModuleTitle}>
3160
+ Analytics Events
3161
+ </Text>
3162
+ </View>
3163
+ <Text style={styles.dashboardModuleGoText}>View Details →</Text>
3164
+ </View>
3165
+ <View style={styles.dashboardModuleGrid}>
3166
+ <View style={styles.dashboardGridItem}>
3167
+ <Text style={styles.dashboardGridVal}>{analyticsTotal}</Text>
3168
+ <Text style={styles.dashboardGridLbl}>Total Events</Text>
3169
+ </View>
3170
+ <View style={styles.dashboardGridItem}>
3171
+ <Text style={[styles.dashboardGridVal, { color: '#EA580C' }]}>
3172
+ {uniqueEvents}
3173
+ </Text>
3174
+ <Text style={styles.dashboardGridLbl}>Unique Names</Text>
3175
+ </View>
3176
+ <View style={styles.dashboardGridItem}>
3177
+ <Text style={styles.dashboardGridVal}>{screenViews}</Text>
3178
+ <Text style={styles.dashboardGridLbl}>Screen Views</Text>
3179
+ </View>
3180
+ <View style={styles.dashboardGridItem}>
3181
+ <Text style={styles.dashboardGridVal}>
3182
+ {analyticsTotal > 0
3183
+ ? Math.round(analyticsTotal / Math.max(1, logs.length / 5))
3184
+ : 0}
3185
+ </Text>
3186
+ <Text style={styles.dashboardGridLbl}>Events Ratio</Text>
3187
+ </View>
3188
+ </View>
3189
+ </TouchableScale>)}
3190
+
3191
+ {insightsActiveSubTab === 'webview' && tabVisibility?.webview && (<TouchableScale style={styles.dashboardModuleCard} onPress={() => switchActiveTab('webview')}>
3192
+ <View style={styles.dashboardModuleHeader}>
3193
+ <View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
3194
+ <GlobeIcon color="#2563EB" size={18}/>
3195
+ <Text style={styles.dashboardModuleTitle}>
3196
+ WebView Captures
3197
+ </Text>
3198
+ </View>
3199
+ <Text style={styles.dashboardModuleGoText}>View Details →</Text>
3200
+ </View>
3201
+ <View style={styles.dashboardModuleGrid}>
3202
+ <View style={styles.dashboardGridItem}>
3203
+ <Text style={styles.dashboardGridVal}>{webviewTotal}</Text>
3204
+ <Text style={styles.dashboardGridLbl}>History Size</Text>
3205
+ </View>
3206
+ <View style={styles.dashboardGridItem}>
3207
+ <Text style={[styles.dashboardGridVal, { color: '#16A34A' }]}>
3208
+ Active
3209
+ </Text>
3210
+ <Text style={styles.dashboardGridLbl}>Status</Text>
3211
+ </View>
3212
+ <View style={styles.dashboardGridItem}>
3213
+ <Text numberOfLines={1} style={styles.dashboardGridVal}>
3214
+ {webviewTotal > 0
3215
+ ? `${webViewNavHistory[0]?.title?.substring(0, 10) ?? ''}...`
3216
+ : '—'}
3217
+ </Text>
3218
+ <Text style={styles.dashboardGridLbl}>Last URL</Text>
3219
+ </View>
3220
+ </View>
3221
+ </TouchableScale>)}
3222
+
3223
+ {insightsActiveSubTab === 'redux' && tabVisibility?.redux && (<TouchableScale style={styles.dashboardModuleCard} onPress={() => switchActiveTab('redux')}>
3224
+ <View style={styles.dashboardModuleHeader}>
3225
+ <View style={{ flexDirection: 'row', alignItems: 'center', gap: 8 }}>
3226
+ <TerminalIcon color={AppColors.purple} size={18}/>
3227
+ <Text style={styles.dashboardModuleTitle}>
3228
+ Redux Store State
3229
+ </Text>
3230
+ </View>
3231
+ <Text style={styles.dashboardModuleGoText}>View Details →</Text>
3232
+ </View>
3233
+ {reduxState ? (<View style={{ paddingHorizontal: 12, paddingBottom: 12, gap: 6 }}>
3234
+ <View style={{
3235
+ flexDirection: 'row',
3236
+ justifyContent: 'space-between',
3237
+ marginBottom: 4,
3238
+ }}>
3239
+ <Text style={{
3240
+ fontFamily: AppFonts.interBold,
3241
+ fontSize: 10,
3242
+ color: AppColors.grayTextWeak,
3243
+ letterSpacing: 0.5,
3244
+ }}>
3245
+ REDUCER NAME
3246
+ </Text>
3247
+ <Text style={{
3248
+ fontFamily: AppFonts.interBold,
3249
+ fontSize: 10,
3250
+ color: AppColors.grayTextWeak,
3251
+ letterSpacing: 0.5,
3252
+ }}>
3253
+ SIZE / FIELDS
3254
+ </Text>
3255
+ </View>
3256
+ {Object.keys(reduxState).map(key => {
3257
+ const val = reduxState[key];
3258
+ const fieldsCount = typeof val === 'object' && val !== null
3259
+ ? Object.keys(val).length
3260
+ : 0;
3261
+ const sizeStr = getSize(val);
3262
+ return (<View key={key} style={{
3263
+ flexDirection: 'row',
3264
+ justifyContent: 'space-between',
3265
+ alignItems: 'center',
3266
+ paddingVertical: 2,
3267
+ }}>
3268
+ <Text style={{
3269
+ fontFamily: AppFonts.interMedium,
3270
+ fontSize: 12,
3271
+ color: AppColors.grayTextStrong,
3272
+ }}>
3273
+ {key}
3274
+ </Text>
3275
+ <Text style={{
3276
+ fontFamily: AppFonts.interRegular,
3277
+ fontSize: 11,
3278
+ color: AppColors.grayTextWeak,
3279
+ }}>
3280
+ {sizeStr} ({fieldsCount} fields)
3281
+ </Text>
3282
+ </View>);
3283
+ })}
3284
+ </View>) : (<View style={{ padding: 12, alignItems: 'center' }}>
3117
3285
  <Text style={{
3118
3286
  fontFamily: AppFonts.interRegular,
3119
- fontSize: 11,
3287
+ fontSize: 12,
3120
3288
  color: AppColors.grayTextWeak,
3121
3289
  }}>
3122
- {sizeStr} ({fieldsCount} fields)
3290
+ No connected Redux store.
3123
3291
  </Text>
3124
- </View>);
3125
- })}
3126
- </View>) : (<View style={{ padding: 12, alignItems: 'center' }}>
3127
- <Text style={{
3128
- fontFamily: AppFonts.interRegular,
3129
- fontSize: 12,
3130
- color: AppColors.grayTextWeak,
3131
- }}>
3132
- No connected Redux store.
3133
- </Text>
3134
- </View>)}
3135
- </TouchableScale>)}
3292
+ </View>)}
3293
+ </TouchableScale>)}
3294
+ </>);
3295
+ })()}
3136
3296
  </View>);
3137
3297
  };
3138
3298
  const renderReduxTab = () => {