@dhiraj0720/report1chart 2.9.8 → 3.0.1

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dhiraj0720/report1chart",
3
- "version": "2.9.8",
3
+ "version": "3.0.1",
4
4
  "main": "src/index.jsx",
5
5
  "scripts": {
6
6
  "test": "echo 'No tests'"
@@ -0,0 +1,23 @@
1
+ import axios from 'axios';
2
+
3
+ const fetchReport4 = async (endpoint, token) => {
4
+ const res = await axios.get(endpoint, {
5
+ headers: { Authorization: token },
6
+ });
7
+
8
+ if (Array.isArray(res.data)) {
9
+ return res.data;
10
+ }
11
+
12
+ if (Array.isArray(res.data?.rows)) {
13
+ return res.data.rows;
14
+ }
15
+
16
+ if (Array.isArray(res.data?.data)) {
17
+ return res.data.data;
18
+ }
19
+
20
+ return [];
21
+ };
22
+
23
+ export default fetchReport4;
@@ -0,0 +1,404 @@
1
+ import React, { useMemo } from 'react';
2
+ import { ScrollView, StyleSheet, Text, View, useWindowDimensions } from 'react-native';
3
+ import { formatNumber } from '../utils/formatNumber';
4
+
5
+ const TAB_TABLE_CONFIG = {
6
+ kumule: {
7
+ title: '2025 YILI ŞİRKET ve İŞTİPİ BAZINDA BRÜT KAR & FAALİYET KAR PERFORMANS TABLOSU',
8
+ columns: [
9
+ { key: 'gross2024', label: '2024 Brüt Kar', type: 'number' },
10
+ { key: 'gross2025', label: '2025 Brüt Kar', type: 'number' },
11
+ {
12
+ key: 'grossChangePercent',
13
+ label: 'Brüt Kar Fiili Artış %',
14
+ type: 'trendPercent',
15
+ trendKey: 'grossTrend',
16
+ },
17
+ { key: 'budgetGross2025', label: '2025 Bütçe Brüt Kar', type: 'number' },
18
+ {
19
+ key: 'budgetGrossVariancePercent',
20
+ label: 'Brüt Kar Bütçe Sapma %',
21
+ type: 'trendPercent',
22
+ trendKey: 'budgetGrossTrend',
23
+ },
24
+ { key: 'fk2024', label: '2024 FK', type: 'number' },
25
+ { key: 'fk2025', label: '2025 FK', type: 'number' },
26
+ {
27
+ key: 'fkChangePercent',
28
+ label: 'Yıllık FK Fiili Artış %',
29
+ type: 'trendPercent',
30
+ trendKey: 'fkTrend',
31
+ },
32
+ { key: 'budgetFk2025', label: '2025 Bütçe FK', type: 'number' },
33
+ {
34
+ key: 'budgetFkVariancePercent',
35
+ label: 'FK Bütçe Sapma %',
36
+ type: 'trendPercent',
37
+ trendKey: 'budgetFkTrend',
38
+ },
39
+ ],
40
+ },
41
+ faaliyet: {
42
+ title: '2025 YILI ŞİRKET ve İŞTİPİ BAZINDA FAALİYET KAR / ZARAR PERFORMANS TABLOSU',
43
+ columns: [
44
+ { key: 'fk2024', label: '2024 FK', type: 'number' },
45
+ { key: 'fk2025', label: '2025 FK', type: 'number' },
46
+ {
47
+ key: 'changePercent',
48
+ label: 'Yıllık FK Fiili Artış %',
49
+ type: 'trendPercent',
50
+ trendKey: 'trend',
51
+ },
52
+ { key: 'budget2025', label: '2025 Bütçe FK', type: 'number' },
53
+ {
54
+ key: 'budgetVariancePercent',
55
+ label: 'FK Bütçe Sapma %',
56
+ type: 'trendPercent',
57
+ trendKey: 'budgetTrend',
58
+ },
59
+ ],
60
+ },
61
+ fg: {
62
+ title: 'YIL BAZINDA ŞİRKET ve İŞTİPİ BAZINDA FAALİYET GİDERİ / BRÜT KAR ORANI TABLOSU',
63
+ columns: [
64
+ { key: 'gross2024', label: '2024 Brüt Kar', type: 'number' },
65
+ { key: 'gross2025', label: '2025 Brüt Kar', type: 'number' },
66
+ { key: 'fk2024', label: '2024 FK', type: 'number' },
67
+ { key: 'fk2025', label: '2025 FK', type: 'number' },
68
+ { key: 'ratio2024', label: '2024 FG / Brüt Kar Oranı', type: 'ratio' },
69
+ { key: 'ratio2025', label: '2025 FG / Brüt Kar Oranı', type: 'ratio' },
70
+ ],
71
+ },
72
+ };
73
+
74
+ const trendUi = (trendValue) => {
75
+ if (trendValue === 1) {
76
+ return { icon: '↑', color: '#2e7d32' };
77
+ }
78
+
79
+ if (trendValue === 2) {
80
+ return { icon: '↓', color: '#c62828' };
81
+ }
82
+
83
+ if (trendValue === 0) {
84
+ return { icon: '●', color: '#c62828' };
85
+ }
86
+
87
+ return { icon: '●', color: '#e65100' };
88
+ };
89
+
90
+ const ratioTrend = (ratioValue) => {
91
+ if (ratioValue === null || ratioValue === undefined) {
92
+ return null;
93
+ }
94
+
95
+ if (ratioValue < 0) {
96
+ return 0;
97
+ }
98
+
99
+ if (ratioValue <= 50) {
100
+ return 1;
101
+ }
102
+
103
+ return 2;
104
+ };
105
+
106
+ const formatPercent = (value) => {
107
+ if (value === null || value === undefined) {
108
+ return '-';
109
+ }
110
+
111
+ return Number(value).toLocaleString('en-US');
112
+ };
113
+
114
+ const formatRatio = (value) => {
115
+ if (value === null || value === undefined) {
116
+ return '-';
117
+ }
118
+
119
+ if (value < 0) {
120
+ return `-%${Math.abs(value)}`;
121
+ }
122
+
123
+ return `%${value}`;
124
+ };
125
+
126
+ const DataCell = ({ children, rowStyle, cellStyle }) => (
127
+ <View style={[styles.dataCell, rowStyle, cellStyle]}>
128
+ {children}
129
+ </View>
130
+ );
131
+
132
+ const TrendValue = ({ value, trend }) => {
133
+ const trendStyle = trendUi(trend);
134
+
135
+ return (
136
+ <View style={styles.trendWrapper}>
137
+ <Text style={[styles.trendIcon, { color: trendStyle.color }]}>
138
+ {trendStyle.icon}
139
+ </Text>
140
+ <Text numberOfLines={1} style={styles.dataCellText}>
141
+ {value}
142
+ </Text>
143
+ </View>
144
+ );
145
+ };
146
+
147
+ const renderCellValue = (row, column) => {
148
+ if (column.type === 'number') {
149
+ return <Text style={styles.dataCellText}>{formatNumber(row[column.key])}</Text>;
150
+ }
151
+
152
+ if (column.type === 'trendPercent') {
153
+ return (
154
+ <TrendValue
155
+ value={formatPercent(row[column.key])}
156
+ trend={row[column.trendKey]}
157
+ />
158
+ );
159
+ }
160
+
161
+ if (column.type === 'ratio') {
162
+ return (
163
+ <TrendValue
164
+ value={formatRatio(row[column.key])}
165
+ trend={ratioTrend(row[column.key])}
166
+ />
167
+ );
168
+ }
169
+
170
+ return <Text style={styles.dataCellText}>-</Text>;
171
+ };
172
+
173
+ const rowTypeStyle = (row, index) => {
174
+ if (row.rowType === 1 || row.rowType === 3) {
175
+ return styles.totalRow;
176
+ }
177
+
178
+ return index % 2 === 0 ? styles.evenRow : styles.oddRow;
179
+ };
180
+
181
+ const FrozenTableReport4A = ({ rows = [], tabKey = 'kumule', isFullscreen = false }) => {
182
+ const { width: screenWidth } = useWindowDimensions();
183
+ const config = TAB_TABLE_CONFIG[tabKey] || TAB_TABLE_CONFIG.kumule;
184
+
185
+ const layout = useMemo(() => {
186
+ const safeWidth = Math.max(280, screenWidth - (isFullscreen ? 32 : 24));
187
+
188
+ const frozenColumnWidth = isFullscreen
189
+ ? Math.max(160, Math.min(220, safeWidth * 0.3))
190
+ : Math.max(128, Math.min(156, safeWidth * 0.38));
191
+
192
+ const dataColumnWidth = isFullscreen
193
+ ? Math.max(96, Math.min(142, safeWidth * 0.18))
194
+ : Math.max(92, Math.min(116, (safeWidth - frozenColumnWidth) / 2));
195
+
196
+ return {
197
+ frozenColumnWidth,
198
+ dataColumnWidth,
199
+ rowHeight: isFullscreen ? 42 : 38,
200
+ headerHeight: isFullscreen ? 54 : 46,
201
+ };
202
+ }, [isFullscreen, screenWidth]);
203
+
204
+ if (!rows.length) {
205
+ return <Text style={styles.noData}>No data available</Text>;
206
+ }
207
+
208
+ return (
209
+ <View style={[styles.wrapper, isFullscreen && styles.wrapperFullscreen]}>
210
+ <Text style={styles.tableTitle}>{config.title}</Text>
211
+
212
+ <View style={styles.tableContainer}>
213
+ <View style={[styles.frozenColumn, { width: layout.frozenColumnWidth }]}>
214
+ <View
215
+ style={[
216
+ styles.nameCell,
217
+ styles.headerCell,
218
+ { height: layout.headerHeight },
219
+ ]}
220
+ >
221
+ <Text style={styles.headerText}>ŞİRKET / İŞTİPİ</Text>
222
+ </View>
223
+
224
+ {rows.map((row, index) => {
225
+ const isTotal = row.rowType === 1 || row.rowType === 3;
226
+ return (
227
+ <View
228
+ key={`name-${row.sortOrder || index}`}
229
+ style={[
230
+ styles.nameCell,
231
+ rowTypeStyle(row, index),
232
+ { height: layout.rowHeight },
233
+ ]}
234
+ >
235
+ <View style={styles.nameCellContent}>
236
+ <Text style={styles.star}>{isTotal ? '★' : ''}</Text>
237
+ <Text
238
+ numberOfLines={1}
239
+ adjustsFontSizeToFit
240
+ minimumFontScale={0.78}
241
+ style={styles.nameText}
242
+ >
243
+ {row.name}
244
+ </Text>
245
+ </View>
246
+ </View>
247
+ );
248
+ })}
249
+ </View>
250
+
251
+ <ScrollView horizontal showsHorizontalScrollIndicator={false}>
252
+ <View>
253
+ <View style={styles.row}>
254
+ {config.columns.map((column) => (
255
+ <View
256
+ key={column.key}
257
+ style={[
258
+ styles.dataCell,
259
+ styles.headerCell,
260
+ {
261
+ width: layout.dataColumnWidth,
262
+ height: layout.headerHeight,
263
+ },
264
+ ]}
265
+ >
266
+ <Text numberOfLines={2} style={styles.headerText}>
267
+ {column.label}
268
+ </Text>
269
+ </View>
270
+ ))}
271
+ </View>
272
+
273
+ {rows.map((row, index) => {
274
+ const rowStyle = rowTypeStyle(row, index);
275
+
276
+ return (
277
+ <View key={`row-${row.sortOrder || index}`} style={styles.row}>
278
+ {config.columns.map((column) => (
279
+ <DataCell
280
+ key={`${row.sortOrder || index}-${column.key}`}
281
+ rowStyle={rowStyle}
282
+ cellStyle={{
283
+ width: layout.dataColumnWidth,
284
+ height: layout.rowHeight,
285
+ }}
286
+ >
287
+ {renderCellValue(row, column)}
288
+ </DataCell>
289
+ ))}
290
+ </View>
291
+ );
292
+ })}
293
+ </View>
294
+ </ScrollView>
295
+ </View>
296
+ </View>
297
+ );
298
+ };
299
+
300
+ export default FrozenTableReport4A;
301
+
302
+ const styles = StyleSheet.create({
303
+ wrapper: {
304
+ backgroundColor: '#f4f7fb',
305
+ borderRadius: 10,
306
+ borderWidth: 1,
307
+ borderColor: '#ccd8e4',
308
+ padding: 6,
309
+ },
310
+ wrapperFullscreen: {
311
+ padding: 8,
312
+ },
313
+ tableTitle: {
314
+ textAlign: 'center',
315
+ fontSize: 14,
316
+ fontWeight: '700',
317
+ color: '#223648',
318
+ marginBottom: 6,
319
+ },
320
+ tableContainer: {
321
+ flexDirection: 'row',
322
+ borderWidth: 1,
323
+ borderColor: '#b8c6d4',
324
+ borderRadius: 8,
325
+ overflow: 'hidden',
326
+ backgroundColor: '#e7edf3',
327
+ },
328
+ frozenColumn: {
329
+ borderRightWidth: 1,
330
+ borderRightColor: '#ecf1f6',
331
+ },
332
+ row: {
333
+ flexDirection: 'row',
334
+ },
335
+ nameCell: {
336
+ justifyContent: 'center',
337
+ borderBottomWidth: 1,
338
+ borderBottomColor: '#edf2f7',
339
+ paddingHorizontal: 6,
340
+ },
341
+ nameCellContent: {
342
+ flexDirection: 'row',
343
+ alignItems: 'center',
344
+ },
345
+ nameText: {
346
+ flex: 1,
347
+ fontSize: 11.5,
348
+ color: '#203040',
349
+ },
350
+ star: {
351
+ width: 14,
352
+ textAlign: 'center',
353
+ color: '#b7791f',
354
+ fontSize: 13,
355
+ marginRight: 2,
356
+ },
357
+ dataCell: {
358
+ justifyContent: 'center',
359
+ alignItems: 'center',
360
+ paddingHorizontal: 4,
361
+ borderBottomWidth: 1,
362
+ borderBottomColor: '#edf2f7',
363
+ },
364
+ dataCellText: {
365
+ fontSize: 11.5,
366
+ color: '#2b3d4e',
367
+ textAlign: 'center',
368
+ },
369
+ headerCell: {
370
+ backgroundColor: '#5f7f9f',
371
+ },
372
+ headerText: {
373
+ color: '#ffffff',
374
+ fontWeight: '700',
375
+ textAlign: 'center',
376
+ fontSize: 11,
377
+ },
378
+ evenRow: {
379
+ backgroundColor: '#e6eaef',
380
+ },
381
+ oddRow: {
382
+ backgroundColor: '#dde3e9',
383
+ },
384
+ totalRow: {
385
+ backgroundColor: '#a7bdd2',
386
+ },
387
+ trendWrapper: {
388
+ flexDirection: 'row',
389
+ alignItems: 'center',
390
+ justifyContent: 'center',
391
+ },
392
+ trendIcon: {
393
+ fontSize: 13,
394
+ fontWeight: '700',
395
+ marginRight: 3,
396
+ marginTop: -1,
397
+ },
398
+ noData: {
399
+ textAlign: 'center',
400
+ color: '#666',
401
+ paddingVertical: 20,
402
+ fontSize: 14,
403
+ },
404
+ });
package/src/index.jsx CHANGED
@@ -8,6 +8,7 @@ import Report3Screen from './screens/Report3Screen';
8
8
  import Report1AScreen from './screens/Report1AScreen';
9
9
  import Report2AScreen from './screens/Report2AScreen';
10
10
  import Report3AScreen from './screens/Report3AScreen';
11
+ import Report4AScreen from './screens/Report4AScreen';
11
12
 
12
13
  const AnalyticsReports = ({ config, onExit }) => {
13
14
  const [active, setActive] = useState(null);
@@ -111,7 +112,7 @@ if (active === '2A') {
111
112
  );
112
113
  }
113
114
 
114
- if (active === '3A') {
115
+ if (active === '3A') {
115
116
  return (
116
117
  <SafeScreen>
117
118
  <Report3AScreen api={config.report3} token={config.token} onBack={() => setActive(null)} />
@@ -119,6 +120,18 @@ if (active === '2A') {
119
120
  );
120
121
  }
121
122
 
123
+ if (active === '4A') {
124
+ return (
125
+ <SafeScreen>
126
+ <Report4AScreen
127
+ api={config.report4}
128
+ token={config.token}
129
+ onBack={() => setActive(null)}
130
+ />
131
+ </SafeScreen>
132
+ );
133
+ }
134
+
122
135
  return null;
123
136
  };
124
137
 
@@ -0,0 +1,330 @@
1
+ import React, { useCallback, useEffect, useMemo, useState } from 'react';
2
+ import {
3
+ ActivityIndicator,
4
+ Modal,
5
+ ScrollView,
6
+ StyleSheet,
7
+ Text,
8
+ TouchableOpacity,
9
+ View,
10
+ useWindowDimensions,
11
+ } from 'react-native';
12
+ import fetchReport4 from '../api/report4Fetcher';
13
+ import FrozenTableReport4A from '../components/FrozenTableReport4A';
14
+
15
+ const TABS = [
16
+ { key: 'kumule', label: 'KÜMÜLE' },
17
+ { key: 'faaliyet', label: 'FAALİYET KAR/ZARAR' },
18
+ { key: 'fg', label: 'FG / BRÜT KAR ORANI' },
19
+ ];
20
+
21
+ const Report4AScreen = ({ api, token, onBack }) => {
22
+ const { width, height } = useWindowDimensions();
23
+ const [activeTab, setActiveTab] = useState('kumule');
24
+ const [rowsByTab, setRowsByTab] = useState({});
25
+ const [loadedByTab, setLoadedByTab] = useState({});
26
+ const [errorByTab, setErrorByTab] = useState({});
27
+ const [loading, setLoading] = useState(false);
28
+ const [fullscreen, setFullscreen] = useState(false);
29
+
30
+ const isLandscape = width > height;
31
+
32
+ const endpointByTab = useMemo(() => ({
33
+ kumule: api?.kumule,
34
+ faaliyet: api?.faaliyetKarZarar,
35
+ fg: api?.fgBrutKarOrani,
36
+ }), [api]);
37
+
38
+ const loadTabData = useCallback(async (tabKey, force = false) => {
39
+ const endpoint = endpointByTab[tabKey];
40
+
41
+ if (!endpoint || !token) {
42
+ setErrorByTab((prev) => ({
43
+ ...prev,
44
+ [tabKey]: 'API endpoint or token missing.',
45
+ }));
46
+ return;
47
+ }
48
+
49
+ if (!force && loadedByTab[tabKey]) {
50
+ return;
51
+ }
52
+
53
+ setLoading(true);
54
+ setErrorByTab((prev) => ({ ...prev, [tabKey]: null }));
55
+
56
+ try {
57
+ const rows = await fetchReport4(endpoint, token);
58
+ const sortedRows = [...rows].sort(
59
+ (a, b) => (a.sortOrder || 0) - (b.sortOrder || 0),
60
+ );
61
+
62
+ setRowsByTab((prev) => ({ ...prev, [tabKey]: sortedRows }));
63
+ setLoadedByTab((prev) => ({ ...prev, [tabKey]: true }));
64
+ } catch (error) {
65
+ setErrorByTab((prev) => ({
66
+ ...prev,
67
+ [tabKey]: error?.message || 'Failed to load report data.',
68
+ }));
69
+ } finally {
70
+ setLoading(false);
71
+ }
72
+ }, [endpointByTab, loadedByTab, token]);
73
+
74
+ useEffect(() => {
75
+ loadTabData(activeTab);
76
+ }, [activeTab, loadTabData]);
77
+
78
+ const activeRows = rowsByTab[activeTab] || [];
79
+ const activeError = errorByTab[activeTab];
80
+ const activeLoaded = loadedByTab[activeTab];
81
+
82
+ return (
83
+ <View style={styles.container}>
84
+ <View style={styles.header}>
85
+ <TouchableOpacity onPress={onBack} style={styles.backButton}>
86
+ <Text style={styles.backIcon}>‹</Text>
87
+ </TouchableOpacity>
88
+ <Text style={styles.headerTitle}>New report Formate</Text>
89
+ </View>
90
+
91
+ <View style={styles.tabsContainer}>
92
+ <ScrollView horizontal showsHorizontalScrollIndicator={false}>
93
+ {TABS.map((tab) => {
94
+ const isActive = tab.key === activeTab;
95
+ return (
96
+ <TouchableOpacity
97
+ key={tab.key}
98
+ style={[styles.tabButton, isActive && styles.activeTabButton]}
99
+ onPress={() => setActiveTab(tab.key)}
100
+ >
101
+ <Text style={[styles.tabText, isActive && styles.activeTabText]}>
102
+ {tab.label}
103
+ </Text>
104
+ </TouchableOpacity>
105
+ );
106
+ })}
107
+ </ScrollView>
108
+ </View>
109
+
110
+ <View style={styles.content}>
111
+ {loading && !activeLoaded ? (
112
+ <View style={styles.center}>
113
+ <ActivityIndicator size="large" color="#4E79A7" />
114
+ </View>
115
+ ) : null}
116
+
117
+ {!loading && activeError && !activeRows.length ? (
118
+ <View style={styles.center}>
119
+ <Text style={styles.errorText}>{activeError}</Text>
120
+ <TouchableOpacity
121
+ style={styles.retryButton}
122
+ onPress={() => loadTabData(activeTab, true)}
123
+ >
124
+ <Text style={styles.retryText}>Retry</Text>
125
+ </TouchableOpacity>
126
+ </View>
127
+ ) : null}
128
+
129
+ {activeRows.length ? (
130
+ <ScrollView style={styles.tableScroll} contentContainerStyle={styles.tableContent}>
131
+ <View style={styles.tableToolbar}>
132
+ <TouchableOpacity
133
+ onPress={() => setFullscreen(true)}
134
+ style={styles.fullViewButton}
135
+ >
136
+ <Text style={styles.fullViewButtonText}>⤢ Full View</Text>
137
+ </TouchableOpacity>
138
+ </View>
139
+
140
+ <FrozenTableReport4A rows={activeRows} tabKey={activeTab} />
141
+ </ScrollView>
142
+ ) : null}
143
+ </View>
144
+
145
+ <Modal
146
+ visible={fullscreen}
147
+ animationType="fade"
148
+ onRequestClose={() => setFullscreen(false)}
149
+ supportedOrientations={['portrait', 'landscape-left', 'landscape-right']}
150
+ >
151
+ <View style={styles.fullModal}>
152
+ <View style={styles.fullHeader}>
153
+ <Text style={styles.fullHintText}>
154
+ Full View • Auto fit • Pinch to zoom
155
+ </Text>
156
+ <TouchableOpacity onPress={() => setFullscreen(false)}>
157
+ <Text style={styles.closeBtn}>✕</Text>
158
+ </TouchableOpacity>
159
+ </View>
160
+
161
+ <ScrollView
162
+ maximumZoomScale={3.5}
163
+ minimumZoomScale={0.45}
164
+ showsHorizontalScrollIndicator={false}
165
+ showsVerticalScrollIndicator={false}
166
+ contentContainerStyle={styles.zoomContent}
167
+ pinchGestureEnabled
168
+ bouncesZoom
169
+ >
170
+ <View style={[styles.tableWrapper, isLandscape && styles.tableWrapperLandscape]}>
171
+ <FrozenTableReport4A
172
+ rows={activeRows}
173
+ tabKey={activeTab}
174
+ isFullscreen
175
+ />
176
+ </View>
177
+ </ScrollView>
178
+ </View>
179
+ </Modal>
180
+ </View>
181
+ );
182
+ };
183
+
184
+ export default Report4AScreen;
185
+
186
+ const styles = StyleSheet.create({
187
+ container: {
188
+ flex: 1,
189
+ backgroundColor: '#eef2f6',
190
+ },
191
+ header: {
192
+ flexDirection: 'row',
193
+ alignItems: 'center',
194
+ backgroundColor: '#4E79A7',
195
+ paddingHorizontal: 14,
196
+ paddingVertical: 16,
197
+ },
198
+ backButton: {
199
+ paddingVertical: 4,
200
+ paddingRight: 10,
201
+ },
202
+ backIcon: {
203
+ fontSize: 32,
204
+ color: '#fff',
205
+ fontWeight: '700',
206
+ },
207
+ headerTitle: {
208
+ flex: 1,
209
+ color: '#fff',
210
+ fontSize: 19,
211
+ fontWeight: '700',
212
+ textAlign: 'center',
213
+ marginRight: 28,
214
+ },
215
+ tabsContainer: {
216
+ backgroundColor: '#dde3ea',
217
+ borderBottomWidth: 1,
218
+ borderBottomColor: '#c6d0da',
219
+ paddingVertical: 8,
220
+ paddingHorizontal: 8,
221
+ },
222
+ tabButton: {
223
+ paddingHorizontal: 16,
224
+ paddingVertical: 10,
225
+ borderRadius: 6,
226
+ marginHorizontal: 4,
227
+ backgroundColor: '#f2f4f7',
228
+ borderWidth: 1,
229
+ borderColor: '#d1d6dd',
230
+ },
231
+ activeTabButton: {
232
+ backgroundColor: '#ffffff',
233
+ borderColor: '#4E79A7',
234
+ },
235
+ tabText: {
236
+ fontSize: 13,
237
+ fontWeight: '600',
238
+ color: '#495057',
239
+ },
240
+ activeTabText: {
241
+ color: '#1d3550',
242
+ fontWeight: '700',
243
+ },
244
+ content: {
245
+ flex: 1,
246
+ },
247
+ center: {
248
+ flex: 1,
249
+ justifyContent: 'center',
250
+ alignItems: 'center',
251
+ paddingHorizontal: 16,
252
+ },
253
+ errorText: {
254
+ textAlign: 'center',
255
+ color: '#a23434',
256
+ marginBottom: 14,
257
+ fontSize: 14,
258
+ },
259
+ retryButton: {
260
+ backgroundColor: '#4E79A7',
261
+ borderRadius: 6,
262
+ paddingHorizontal: 16,
263
+ paddingVertical: 8,
264
+ },
265
+ retryText: {
266
+ color: '#fff',
267
+ fontWeight: '700',
268
+ fontSize: 13,
269
+ },
270
+ tableScroll: {
271
+ flex: 1,
272
+ },
273
+ tableContent: {
274
+ paddingHorizontal: 10,
275
+ paddingBottom: 16,
276
+ },
277
+ tableToolbar: {
278
+ alignItems: 'flex-end',
279
+ marginTop: 8,
280
+ marginBottom: 6,
281
+ },
282
+ fullViewButton: {
283
+ backgroundColor: '#4E79A7',
284
+ borderRadius: 7,
285
+ paddingHorizontal: 12,
286
+ paddingVertical: 7,
287
+ },
288
+ fullViewButtonText: {
289
+ color: '#fff',
290
+ fontWeight: '700',
291
+ fontSize: 12,
292
+ },
293
+ fullModal: {
294
+ flex: 1,
295
+ backgroundColor: '#f3f6fa',
296
+ },
297
+ fullHeader: {
298
+ flexDirection: 'row',
299
+ alignItems: 'center',
300
+ paddingVertical: 14,
301
+ paddingHorizontal: 14,
302
+ borderBottomWidth: 1,
303
+ borderBottomColor: '#d3dde7',
304
+ backgroundColor: '#fff',
305
+ },
306
+ fullHintText: {
307
+ flex: 1,
308
+ fontSize: 14,
309
+ fontWeight: '600',
310
+ color: '#23384a',
311
+ textAlign: 'center',
312
+ },
313
+ closeBtn: {
314
+ fontSize: 24,
315
+ color: '#1f2d3a',
316
+ paddingHorizontal: 8,
317
+ },
318
+ zoomContent: {
319
+ flexGrow: 1,
320
+ justifyContent: 'center',
321
+ alignItems: 'center',
322
+ padding: 12,
323
+ },
324
+ tableWrapper: {
325
+ width: '100%',
326
+ },
327
+ tableWrapperLandscape: {
328
+ maxWidth: '96%',
329
+ },
330
+ });
@@ -36,11 +36,16 @@ const REPORTS = [
36
36
  title: 'Transportation Business Analysis',
37
37
  desc: 'Option 1',
38
38
  },
39
- {
39
+ {
40
40
  id: 3,
41
41
  title: 'Transportation Business Analysis',
42
42
  desc: 'Option 2',
43
43
  },
44
+ {
45
+ id: '4A',
46
+ title: 'New performance Report',
47
+ desc: 'New report formate',
48
+ },
44
49
  ];
45
50
 
46
51
  const ReportListScreen = ({ onSelect, onExit }) => {