@dhiraj0720/report1chart 1.0.5 → 1.0.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/package.json +1 -1
- package/src/index.jsx +481 -461
package/package.json
CHANGED
package/src/index.jsx
CHANGED
|
@@ -19,26 +19,41 @@ const ReportChart = ({
|
|
|
19
19
|
const [reportData, setReportData] = useState(null);
|
|
20
20
|
const [loading, setLoading] = useState(false);
|
|
21
21
|
const [error, setError] = useState(null);
|
|
22
|
+
const [viewType, setViewType] = useState('default');
|
|
22
23
|
|
|
23
24
|
// Default reports if none provided
|
|
24
25
|
const defaultReports = [
|
|
25
26
|
{
|
|
26
27
|
id: 1,
|
|
27
|
-
name: 'Report
|
|
28
|
-
title: '
|
|
29
|
-
type: '
|
|
30
|
-
description: '
|
|
28
|
+
name: 'Performance Report',
|
|
29
|
+
title: 'PERFORMANS RAPORU (USD)',
|
|
30
|
+
type: 'table',
|
|
31
|
+
description: 'Fallyet Kar/Zarar tablosu - Varsayılan Görünüm'
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
id: 1.1,
|
|
35
|
+
name: 'Performance Report A',
|
|
36
|
+
title: 'PERFORMANS RAPORU (USD)',
|
|
37
|
+
type: 'table',
|
|
38
|
+
description: 'Fallyet Kar/Zarar tablosu - Kompakt Görünüm'
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
id: 1.2,
|
|
42
|
+
name: 'Performance Report B',
|
|
43
|
+
title: 'PERFORMANS RAPORU (USD)',
|
|
44
|
+
type: 'table',
|
|
45
|
+
description: 'Fallyet Kar/Zarar tablosu - Sabit Kolonlu Görünüm'
|
|
31
46
|
},
|
|
32
47
|
{
|
|
33
48
|
id: 2,
|
|
34
|
-
name: '
|
|
49
|
+
name: 'Revenue by Mode',
|
|
35
50
|
title: 'Revenue by Mode',
|
|
36
51
|
type: 'bar',
|
|
37
52
|
description: 'Revenue distribution across modes'
|
|
38
53
|
},
|
|
39
54
|
{
|
|
40
55
|
id: 3,
|
|
41
|
-
name: '
|
|
56
|
+
name: 'Shipment by Direction',
|
|
42
57
|
title: 'Shipment by Direction',
|
|
43
58
|
type: 'pie',
|
|
44
59
|
description: 'Shipment direction analysis'
|
|
@@ -52,9 +67,9 @@ const ReportChart = ({
|
|
|
52
67
|
setError(null);
|
|
53
68
|
setReportData(null);
|
|
54
69
|
setSelectedReport(report);
|
|
70
|
+
setViewType('default'); // Reset view type when selecting new report
|
|
55
71
|
|
|
56
72
|
try {
|
|
57
|
-
// Call the parent function to fetch data
|
|
58
73
|
if (onFetchReportData) {
|
|
59
74
|
const data = await onFetchReportData(report);
|
|
60
75
|
if (data) {
|
|
@@ -66,7 +81,6 @@ const ReportChart = ({
|
|
|
66
81
|
}
|
|
67
82
|
}
|
|
68
83
|
|
|
69
|
-
// Callback to parent
|
|
70
84
|
if (onReportSelect) {
|
|
71
85
|
onReportSelect(report.name);
|
|
72
86
|
}
|
|
@@ -77,57 +91,357 @@ const ReportChart = ({
|
|
|
77
91
|
}
|
|
78
92
|
};
|
|
79
93
|
|
|
80
|
-
|
|
81
|
-
const
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
94
|
+
const formatCurrency = (value) => {
|
|
95
|
+
const num = Number(value);
|
|
96
|
+
if (isNaN(num)) return '0';
|
|
97
|
+
|
|
98
|
+
if (num >= 1000000) {
|
|
99
|
+
return `${(num / 1000000).toFixed(1)}M`;
|
|
100
|
+
} else if (num >= 1000) {
|
|
101
|
+
return `${(num / 1000).toFixed(1)}K`;
|
|
102
|
+
}
|
|
103
|
+
return num.toLocaleString();
|
|
104
|
+
};
|
|
105
|
+
|
|
106
|
+
const formatNumber = (num) => {
|
|
107
|
+
return num.toLocaleString();
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const getColor = (index) => {
|
|
111
|
+
const colors = ['#4CAF50', '#2196F3', '#FF9800', '#E91E63', '#9C27B0', '#00BCD4'];
|
|
112
|
+
return colors[index % colors.length];
|
|
113
|
+
};
|
|
114
|
+
|
|
115
|
+
const handleClose = () => {
|
|
116
|
+
setSelectedReport(null);
|
|
117
|
+
setReportData(null);
|
|
118
|
+
if (onClose) onClose();
|
|
119
|
+
};
|
|
120
|
+
|
|
121
|
+
// ========== TABLE RENDERERS ==========
|
|
122
|
+
const renderTable = (data) => {
|
|
123
|
+
if (!Array.isArray(data) || data.length === 0) {
|
|
124
|
+
return (
|
|
125
|
+
<View style={styles.noDataContainer}>
|
|
126
|
+
<Text style={styles.noDataText}>No data available for this report</Text>
|
|
127
|
+
</View>
|
|
128
|
+
);
|
|
129
|
+
}
|
|
92
130
|
|
|
93
|
-
const renderChart = () => {
|
|
94
|
-
if (!reportData || !reportData.data) {
|
|
95
131
|
return (
|
|
96
|
-
<
|
|
97
|
-
<
|
|
98
|
-
|
|
132
|
+
<ScrollView horizontal showsHorizontalScrollIndicator={true}>
|
|
133
|
+
<View style={styles.table}>
|
|
134
|
+
{/* Table Header */}
|
|
135
|
+
<View style={styles.tableHeader}>
|
|
136
|
+
<View style={[styles.headerCell, styles.firstColumn]}>
|
|
137
|
+
<Text style={styles.headerText}>FALİYET KAR/ZARAR</Text>
|
|
138
|
+
</View>
|
|
139
|
+
<View style={styles.headerCell}>
|
|
140
|
+
<Text style={styles.headerText}>2024 Fiili</Text>
|
|
141
|
+
</View>
|
|
142
|
+
<View style={styles.headerCell}>
|
|
143
|
+
<Text style={styles.headerText}>2025 Fiili</Text>
|
|
144
|
+
</View>
|
|
145
|
+
<View style={styles.headerCell}>
|
|
146
|
+
<Text style={styles.headerText}>Fiili Artış %</Text>
|
|
147
|
+
</View>
|
|
148
|
+
<View style={styles.headerCell}>
|
|
149
|
+
<Text style={styles.headerText}>2025 Bütçe</Text>
|
|
150
|
+
</View>
|
|
151
|
+
<View style={styles.headerCell}>
|
|
152
|
+
<Text style={styles.headerText}>Sapma %</Text>
|
|
153
|
+
</View>
|
|
154
|
+
<View style={styles.headerCell}>
|
|
155
|
+
<Text style={styles.headerText}>BRÜT KAR %</Text>
|
|
156
|
+
</View>
|
|
157
|
+
</View>
|
|
158
|
+
|
|
159
|
+
{/* Table Rows */}
|
|
160
|
+
{data.map((item, index) => (
|
|
161
|
+
<View
|
|
162
|
+
key={index}
|
|
163
|
+
style={[
|
|
164
|
+
styles.tableRow,
|
|
165
|
+
item.isTotal ? styles.totalRow : (index % 2 === 0 ? styles.evenRow : styles.oddRow)
|
|
166
|
+
]}
|
|
167
|
+
>
|
|
168
|
+
<View style={[styles.cell, styles.firstColumn]}>
|
|
169
|
+
<Text style={item.isTotal ? styles.totalText : styles.cellText}>
|
|
170
|
+
{item.name}
|
|
171
|
+
</Text>
|
|
172
|
+
</View>
|
|
173
|
+
|
|
174
|
+
<View style={styles.cell}>
|
|
175
|
+
<Text style={styles.numberText}>
|
|
176
|
+
{formatCurrency(item.actual2024)}
|
|
177
|
+
</Text>
|
|
178
|
+
</View>
|
|
179
|
+
|
|
180
|
+
<View style={styles.cell}>
|
|
181
|
+
<Text style={styles.numberText}>
|
|
182
|
+
{formatCurrency(item.actual2025)}
|
|
183
|
+
</Text>
|
|
184
|
+
</View>
|
|
185
|
+
|
|
186
|
+
<View style={styles.cell}>
|
|
187
|
+
<Text style={[
|
|
188
|
+
styles.percentText,
|
|
189
|
+
item.yoYChangePercent >= 0 ? styles.positive : styles.negative
|
|
190
|
+
]}>
|
|
191
|
+
{item.yoYChangePercent >= 0 ? '↑' : '↓'} {Math.abs(item.yoYChangePercent)}%
|
|
192
|
+
</Text>
|
|
193
|
+
</View>
|
|
194
|
+
|
|
195
|
+
<View style={styles.cell}>
|
|
196
|
+
<Text style={styles.numberText}>
|
|
197
|
+
{formatCurrency(item.budget2025)}
|
|
198
|
+
</Text>
|
|
199
|
+
</View>
|
|
200
|
+
|
|
201
|
+
<View style={styles.cell}>
|
|
202
|
+
<Text style={[
|
|
203
|
+
styles.percentText,
|
|
204
|
+
item.budgetVariancePercent >= 0 ? styles.positive : styles.negative
|
|
205
|
+
]}>
|
|
206
|
+
{item.budgetVariancePercent >= 0 ? '↑' : '↓'} {Math.abs(item.budgetVariancePercent)}%
|
|
207
|
+
</Text>
|
|
208
|
+
</View>
|
|
209
|
+
|
|
210
|
+
<View style={styles.cell}>
|
|
211
|
+
<Text style={[
|
|
212
|
+
styles.percentText,
|
|
213
|
+
styles.grossMargin
|
|
214
|
+
]}>
|
|
215
|
+
{item.grossMarginPercent}%
|
|
216
|
+
</Text>
|
|
217
|
+
</View>
|
|
218
|
+
</View>
|
|
219
|
+
))}
|
|
220
|
+
</View>
|
|
221
|
+
</ScrollView>
|
|
99
222
|
);
|
|
100
|
-
}
|
|
223
|
+
};
|
|
101
224
|
|
|
102
|
-
const
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
return renderFreezeTable(data);
|
|
110
|
-
case 'default': // Report 1
|
|
111
|
-
default:
|
|
112
|
-
return renderTable(data); // Original table
|
|
225
|
+
const renderCompactTable = (data) => {
|
|
226
|
+
if (!Array.isArray(data) || data.length === 0) {
|
|
227
|
+
return (
|
|
228
|
+
<View style={styles.noDataContainer}>
|
|
229
|
+
<Text style={styles.noDataText}>No data available for this report</Text>
|
|
230
|
+
</View>
|
|
231
|
+
);
|
|
113
232
|
}
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
switch (type) {
|
|
117
|
-
case 'line':
|
|
118
|
-
return renderLineChart(data);
|
|
119
|
-
case 'bar':
|
|
120
|
-
return renderBarChart(data);
|
|
121
|
-
case 'pie':
|
|
122
|
-
return renderPieChart(data);
|
|
123
|
-
default:
|
|
124
|
-
return renderBarChart(data);
|
|
125
|
-
}
|
|
126
|
-
};
|
|
127
233
|
|
|
234
|
+
return (
|
|
235
|
+
<ScrollView style={styles.compactContainer}>
|
|
236
|
+
{data.map((item, index) => (
|
|
237
|
+
<View
|
|
238
|
+
key={index}
|
|
239
|
+
style={[
|
|
240
|
+
styles.compactCard,
|
|
241
|
+
item.isTotal && styles.compactTotalCard,
|
|
242
|
+
index % 2 === 0 ? styles.evenCard : styles.oddCard
|
|
243
|
+
]}
|
|
244
|
+
>
|
|
245
|
+
{/* Card Header */}
|
|
246
|
+
<View style={styles.compactHeader}>
|
|
247
|
+
<Text style={[
|
|
248
|
+
styles.compactTitle,
|
|
249
|
+
item.isTotal && styles.totalTitle
|
|
250
|
+
]}>
|
|
251
|
+
{item.name}
|
|
252
|
+
</Text>
|
|
253
|
+
<Text style={[
|
|
254
|
+
styles.compactGrossMargin,
|
|
255
|
+
styles.grossMargin
|
|
256
|
+
]}>
|
|
257
|
+
Brüt Kar: {item.grossMarginPercent}%
|
|
258
|
+
</Text>
|
|
259
|
+
</View>
|
|
260
|
+
|
|
261
|
+
{/* Card Body - Grid Layout */}
|
|
262
|
+
<View style={styles.compactGrid}>
|
|
263
|
+
{/* Column 1 */}
|
|
264
|
+
<View style={styles.compactColumn}>
|
|
265
|
+
<Text style={styles.compactLabel}>2024 Fiili</Text>
|
|
266
|
+
<Text style={styles.compactValue}>
|
|
267
|
+
{formatCurrency(item.actual2024)}
|
|
268
|
+
</Text>
|
|
269
|
+
</View>
|
|
270
|
+
|
|
271
|
+
{/* Column 2 */}
|
|
272
|
+
<View style={styles.compactColumn}>
|
|
273
|
+
<Text style={styles.compactLabel}>2025 Fiili</Text>
|
|
274
|
+
<Text style={styles.compactValue}>
|
|
275
|
+
{formatCurrency(item.actual2025)}
|
|
276
|
+
</Text>
|
|
277
|
+
</View>
|
|
278
|
+
|
|
279
|
+
{/* Column 3 */}
|
|
280
|
+
<View style={styles.compactColumn}>
|
|
281
|
+
<Text style={styles.compactLabel}>Fiili Artış</Text>
|
|
282
|
+
<View style={styles.percentBadge}>
|
|
283
|
+
<Text style={[
|
|
284
|
+
styles.percentText,
|
|
285
|
+
item.yoYChangePercent >= 0 ? styles.positive : styles.negative
|
|
286
|
+
]}>
|
|
287
|
+
{item.yoYChangePercent >= 0 ? '↑' : '↓'} {Math.abs(item.yoYChangePercent)}%
|
|
288
|
+
</Text>
|
|
289
|
+
</View>
|
|
290
|
+
</View>
|
|
291
|
+
|
|
292
|
+
{/* Column 4 */}
|
|
293
|
+
<View style={styles.compactColumn}>
|
|
294
|
+
<Text style={styles.compactLabel}>2025 Bütçe</Text>
|
|
295
|
+
<Text style={styles.compactValue}>
|
|
296
|
+
{formatCurrency(item.budget2025)}
|
|
297
|
+
</Text>
|
|
298
|
+
</View>
|
|
299
|
+
|
|
300
|
+
{/* Column 5 */}
|
|
301
|
+
<View style={styles.compactColumn}>
|
|
302
|
+
<Text style={styles.compactLabel}>Sapma</Text>
|
|
303
|
+
<View style={styles.percentBadge}>
|
|
304
|
+
<Text style={[
|
|
305
|
+
styles.percentText,
|
|
306
|
+
item.budgetVariancePercent >= 0 ? styles.positive : styles.negative
|
|
307
|
+
]}>
|
|
308
|
+
{item.budgetVariancePercent >= 0 ? '↑' : '↓'} {Math.abs(item.budgetVariancePercent)}%
|
|
309
|
+
</Text>
|
|
310
|
+
</View>
|
|
311
|
+
</View>
|
|
312
|
+
</View>
|
|
313
|
+
|
|
314
|
+
{/* Status Indicator */}
|
|
315
|
+
<View style={styles.statusIndicator}>
|
|
316
|
+
<View style={[
|
|
317
|
+
styles.statusDot,
|
|
318
|
+
(item.yoYChangePercent >= 0 && item.budgetVariancePercent >= 0)
|
|
319
|
+
? styles.statusGood
|
|
320
|
+
: styles.statusWarning
|
|
321
|
+
]} />
|
|
322
|
+
<Text style={styles.statusText}>
|
|
323
|
+
{item.yoYChangePercent >= 0 && item.budgetVariancePercent >= 0
|
|
324
|
+
? 'Performans İyi'
|
|
325
|
+
: 'İnceleme Gerekli'}
|
|
326
|
+
</Text>
|
|
327
|
+
</View>
|
|
328
|
+
</View>
|
|
329
|
+
))}
|
|
330
|
+
</ScrollView>
|
|
331
|
+
);
|
|
332
|
+
};
|
|
333
|
+
|
|
334
|
+
const renderFreezeTable = (data) => {
|
|
335
|
+
if (!Array.isArray(data) || data.length === 0) {
|
|
336
|
+
return (
|
|
337
|
+
<View style={styles.noDataContainer}>
|
|
338
|
+
<Text style={styles.noDataText}>No data available for this report</Text>
|
|
339
|
+
</View>
|
|
340
|
+
);
|
|
341
|
+
}
|
|
128
342
|
|
|
343
|
+
return (
|
|
344
|
+
<View style={styles.freezeContainer}>
|
|
345
|
+
{/* Fixed First Column */}
|
|
346
|
+
<View style={styles.freezeColumn}>
|
|
347
|
+
<View style={[styles.freezeHeader, styles.freezeFirstCell]}>
|
|
348
|
+
<Text style={styles.freezeHeaderText}>FALİYET KAR/ZARAR</Text>
|
|
349
|
+
</View>
|
|
350
|
+
{data.map((item, index) => (
|
|
351
|
+
<View
|
|
352
|
+
key={index}
|
|
353
|
+
style={[
|
|
354
|
+
styles.freezeRow,
|
|
355
|
+
item.isTotal && styles.freezeTotalRow,
|
|
356
|
+
index % 2 === 0 ? styles.evenRow : styles.oddRow
|
|
357
|
+
]}
|
|
358
|
+
>
|
|
359
|
+
<Text style={[
|
|
360
|
+
styles.freezeCellText,
|
|
361
|
+
item.isTotal && styles.freezeTotalText
|
|
362
|
+
]}>
|
|
363
|
+
{item.name}
|
|
364
|
+
</Text>
|
|
365
|
+
</View>
|
|
366
|
+
))}
|
|
367
|
+
</View>
|
|
368
|
+
|
|
369
|
+
{/* Scrollable Data Columns */}
|
|
370
|
+
<ScrollView horizontal showsHorizontalScrollIndicator={true}>
|
|
371
|
+
<View style={styles.scrollableColumns}>
|
|
372
|
+
{/* Headers for scrollable columns */}
|
|
373
|
+
<View style={styles.freezeHeaderRow}>
|
|
374
|
+
{['2024 Fiili', '2025 Fiili', 'Fiili Artış %', '2025 Bütçe', 'Sapma %', 'BRÜT KAR %'].map((header, idx) => (
|
|
375
|
+
<View key={idx} style={styles.freezeHeader}>
|
|
376
|
+
<Text style={styles.freezeHeaderText}>{header}</Text>
|
|
377
|
+
</View>
|
|
378
|
+
))}
|
|
379
|
+
</View>
|
|
380
|
+
|
|
381
|
+
{/* Data rows for scrollable columns */}
|
|
382
|
+
{data.map((item, rowIndex) => (
|
|
383
|
+
<View
|
|
384
|
+
key={rowIndex}
|
|
385
|
+
style={[
|
|
386
|
+
styles.freezeDataRow,
|
|
387
|
+
item.isTotal && styles.freezeTotalDataRow,
|
|
388
|
+
rowIndex % 2 === 0 ? styles.evenRow : styles.oddRow
|
|
389
|
+
]}
|
|
390
|
+
>
|
|
391
|
+
<View style={styles.freezeDataCell}>
|
|
392
|
+
<Text style={styles.freezeDataText}>
|
|
393
|
+
{formatCurrency(item.actual2024)}
|
|
394
|
+
</Text>
|
|
395
|
+
</View>
|
|
396
|
+
|
|
397
|
+
<View style={styles.freezeDataCell}>
|
|
398
|
+
<Text style={styles.freezeDataText}>
|
|
399
|
+
{formatCurrency(item.actual2025)}
|
|
400
|
+
</Text>
|
|
401
|
+
</View>
|
|
402
|
+
|
|
403
|
+
<View style={styles.freezeDataCell}>
|
|
404
|
+
<Text style={[
|
|
405
|
+
styles.freezePercent,
|
|
406
|
+
item.yoYChangePercent >= 0 ? styles.positive : styles.negative
|
|
407
|
+
]}>
|
|
408
|
+
{item.yoYChangePercent >= 0 ? '↑' : '↓'} {Math.abs(item.yoYChangePercent)}%
|
|
409
|
+
</Text>
|
|
410
|
+
</View>
|
|
411
|
+
|
|
412
|
+
<View style={styles.freezeDataCell}>
|
|
413
|
+
<Text style={styles.freezeDataText}>
|
|
414
|
+
{formatCurrency(item.budget2025)}
|
|
415
|
+
</Text>
|
|
416
|
+
</View>
|
|
417
|
+
|
|
418
|
+
<View style={styles.freezeDataCell}>
|
|
419
|
+
<Text style={[
|
|
420
|
+
styles.freezePercent,
|
|
421
|
+
item.budgetVariancePercent >= 0 ? styles.positive : styles.negative
|
|
422
|
+
]}>
|
|
423
|
+
{item.budgetVariancePercent >= 0 ? '↑' : '↓'} {Math.abs(item.budgetVariancePercent)}%
|
|
424
|
+
</Text>
|
|
425
|
+
</View>
|
|
426
|
+
|
|
427
|
+
<View style={styles.freezeDataCell}>
|
|
428
|
+
<Text style={[
|
|
429
|
+
styles.freezePercent,
|
|
430
|
+
styles.grossMargin
|
|
431
|
+
]}>
|
|
432
|
+
{item.grossMarginPercent}%
|
|
433
|
+
</Text>
|
|
434
|
+
</View>
|
|
435
|
+
</View>
|
|
436
|
+
))}
|
|
437
|
+
</View>
|
|
438
|
+
</ScrollView>
|
|
439
|
+
</View>
|
|
440
|
+
);
|
|
441
|
+
};
|
|
442
|
+
|
|
443
|
+
// ========== CHART RENDERERS ==========
|
|
129
444
|
const renderLineChart = (data) => {
|
|
130
|
-
// Handle both formats: { labels, values } or array format
|
|
131
445
|
const values = data.values || data.map(d => d.value || d.revenue || d.shipments || 0);
|
|
132
446
|
const labels = data.labels || data.map(d => d.label || d.month || d.mode || d.direction || '');
|
|
133
447
|
|
|
@@ -138,7 +452,7 @@ const formatCurrency = (value) => {
|
|
|
138
452
|
|
|
139
453
|
return (
|
|
140
454
|
<View style={styles.chartContainer}>
|
|
141
|
-
<Text style={styles.chartTitle}>{reportData
|
|
455
|
+
<Text style={styles.chartTitle}>{reportData?.title || ''}</Text>
|
|
142
456
|
<ScrollView horizontal showsHorizontalScrollIndicator={false}>
|
|
143
457
|
<View style={[styles.chart, { height: chartHeight, width: chartWidth }]}>
|
|
144
458
|
{values.map((value, index) => {
|
|
@@ -164,7 +478,6 @@ const formatCurrency = (value) => {
|
|
|
164
478
|
};
|
|
165
479
|
|
|
166
480
|
const renderBarChart = (data) => {
|
|
167
|
-
// Handle array format or object format
|
|
168
481
|
const isArray = Array.isArray(data);
|
|
169
482
|
const values = isArray ? data.map(d => d.revenue || d.value || d.shipments || 0) : data.values;
|
|
170
483
|
const labels = isArray ? data.map(d => d.mode || d.label || '') : data.labels;
|
|
@@ -176,7 +489,7 @@ const formatCurrency = (value) => {
|
|
|
176
489
|
|
|
177
490
|
return (
|
|
178
491
|
<View style={styles.chartContainer}>
|
|
179
|
-
<Text style={styles.chartTitle}>{reportData
|
|
492
|
+
<Text style={styles.chartTitle}>{reportData?.title || ''}</Text>
|
|
180
493
|
<ScrollView horizontal showsHorizontalScrollIndicator={false}>
|
|
181
494
|
<View style={[styles.chart, { height: chartHeight, width: chartWidth }]}>
|
|
182
495
|
{values.map((value, index) => {
|
|
@@ -201,337 +514,12 @@ const formatCurrency = (value) => {
|
|
|
201
514
|
);
|
|
202
515
|
};
|
|
203
516
|
|
|
204
|
-
const renderTable = (data) => {
|
|
205
|
-
if (!Array.isArray(data) || data.length === 0) {
|
|
206
|
-
return (
|
|
207
|
-
<View style={styles.noDataContainer}>
|
|
208
|
-
<Text style={styles.noDataText}>No data available for this report</Text>
|
|
209
|
-
</View>
|
|
210
|
-
);
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
return (
|
|
214
|
-
<ScrollView horizontal showsHorizontalScrollIndicator={true}>
|
|
215
|
-
<View style={styles.table}>
|
|
216
|
-
{/* Table Header */}
|
|
217
|
-
<View style={styles.tableHeader}>
|
|
218
|
-
<View style={[styles.headerCell, styles.firstColumn]}>
|
|
219
|
-
<Text style={styles.headerText}>FALİYET KAR/ZARAR</Text>
|
|
220
|
-
</View>
|
|
221
|
-
<View style={styles.headerCell}>
|
|
222
|
-
<Text style={styles.headerText}>2024 Fiili</Text>
|
|
223
|
-
</View>
|
|
224
|
-
<View style={styles.headerCell}>
|
|
225
|
-
<Text style={styles.headerText}>2025 Fiili</Text>
|
|
226
|
-
</View>
|
|
227
|
-
<View style={styles.headerCell}>
|
|
228
|
-
<Text style={styles.headerText}>Fiili Artış %</Text>
|
|
229
|
-
</View>
|
|
230
|
-
<View style={styles.headerCell}>
|
|
231
|
-
<Text style={styles.headerText}>2025 Bütçe</Text>
|
|
232
|
-
</View>
|
|
233
|
-
<View style={styles.headerCell}>
|
|
234
|
-
<Text style={styles.headerText}>Sapma %</Text>
|
|
235
|
-
</View>
|
|
236
|
-
<View style={styles.headerCell}>
|
|
237
|
-
<Text style={styles.headerText}>FALİYET GİD.</Text>
|
|
238
|
-
<Text style={styles.headerText}>/ BRÜT KAR %</Text>
|
|
239
|
-
</View>
|
|
240
|
-
</View>
|
|
241
|
-
|
|
242
|
-
{/* Table Rows */}
|
|
243
|
-
{data.map((item, index) => (
|
|
244
|
-
<View
|
|
245
|
-
key={index}
|
|
246
|
-
style={[
|
|
247
|
-
styles.tableRow,
|
|
248
|
-
item.isTotal ? styles.totalRow : (index % 2 === 0 ? styles.evenRow : styles.oddRow)
|
|
249
|
-
]}
|
|
250
|
-
>
|
|
251
|
-
<View style={[styles.cell, styles.firstColumn]}>
|
|
252
|
-
<Text style={item.isTotal ? styles.totalText : styles.cellText}>
|
|
253
|
-
{item.name}
|
|
254
|
-
</Text>
|
|
255
|
-
</View>
|
|
256
|
-
|
|
257
|
-
<View style={styles.cell}>
|
|
258
|
-
<Text style={styles.numberText}>
|
|
259
|
-
{formatCurrency(item.actual2024)}
|
|
260
|
-
</Text>
|
|
261
|
-
</View>
|
|
262
|
-
|
|
263
|
-
<View style={styles.cell}>
|
|
264
|
-
<Text style={styles.numberText}>
|
|
265
|
-
{formatCurrency(item.actual2025)}
|
|
266
|
-
</Text>
|
|
267
|
-
</View>
|
|
268
|
-
|
|
269
|
-
<View style={styles.cell}>
|
|
270
|
-
<Text style={[
|
|
271
|
-
styles.percentText,
|
|
272
|
-
item.yoYChangePercent >= 0 ? styles.positive : styles.negative
|
|
273
|
-
]}>
|
|
274
|
-
{item.yoYChangePercent >= 0 ? '↑' : '↓'} {Math.abs(item.yoYChangePercent)}%
|
|
275
|
-
</Text>
|
|
276
|
-
</View>
|
|
277
|
-
|
|
278
|
-
<View style={styles.cell}>
|
|
279
|
-
<Text style={styles.numberText}>
|
|
280
|
-
{formatCurrency(item.budget2025)}
|
|
281
|
-
</Text>
|
|
282
|
-
</View>
|
|
283
|
-
|
|
284
|
-
<View style={styles.cell}>
|
|
285
|
-
<Text style={[
|
|
286
|
-
styles.percentText,
|
|
287
|
-
item.budgetVariancePercent >= 0 ? styles.positive : styles.negative
|
|
288
|
-
]}>
|
|
289
|
-
{item.budgetVariancePercent >= 0 ? '↑' : '↓'} {Math.abs(item.budgetVariancePercent)}%
|
|
290
|
-
</Text>
|
|
291
|
-
</View>
|
|
292
|
-
|
|
293
|
-
<View style={styles.cell}>
|
|
294
|
-
<Text style={[
|
|
295
|
-
styles.percentText,
|
|
296
|
-
styles.grossMargin
|
|
297
|
-
]}>
|
|
298
|
-
{item.grossMarginPercent}%
|
|
299
|
-
</Text>
|
|
300
|
-
</View>
|
|
301
|
-
</View>
|
|
302
|
-
))}
|
|
303
|
-
</View>
|
|
304
|
-
</ScrollView>
|
|
305
|
-
);
|
|
306
|
-
};
|
|
307
|
-
|
|
308
|
-
const renderCompactTable = (data) => {
|
|
309
|
-
if (!Array.isArray(data) || data.length === 0) {
|
|
310
|
-
return (
|
|
311
|
-
<View style={styles.noDataContainer}>
|
|
312
|
-
<Text style={styles.noDataText}>No data available for this report</Text>
|
|
313
|
-
</View>
|
|
314
|
-
);
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
return (
|
|
318
|
-
<ScrollView style={styles.compactContainer}>
|
|
319
|
-
{data.map((item, index) => (
|
|
320
|
-
<View
|
|
321
|
-
key={index}
|
|
322
|
-
style={[
|
|
323
|
-
styles.compactCard,
|
|
324
|
-
item.isTotal && styles.compactTotalCard,
|
|
325
|
-
index % 2 === 0 ? styles.evenCard : styles.oddCard
|
|
326
|
-
]}
|
|
327
|
-
>
|
|
328
|
-
{/* Card Header */}
|
|
329
|
-
<View style={styles.compactHeader}>
|
|
330
|
-
<Text style={[
|
|
331
|
-
styles.compactTitle,
|
|
332
|
-
item.isTotal && styles.totalTitle
|
|
333
|
-
]}>
|
|
334
|
-
{item.name}
|
|
335
|
-
</Text>
|
|
336
|
-
<Text style={[
|
|
337
|
-
styles.compactGrossMargin,
|
|
338
|
-
item.grossMarginPercent >= 0 ? styles.positive : styles.negative
|
|
339
|
-
]}>
|
|
340
|
-
Brüt Kar: {item.grossMarginPercent}%
|
|
341
|
-
</Text>
|
|
342
|
-
</View>
|
|
343
|
-
|
|
344
|
-
{/* Card Body - Grid Layout */}
|
|
345
|
-
<View style={styles.compactGrid}>
|
|
346
|
-
{/* Column 1 */}
|
|
347
|
-
<View style={styles.compactColumn}>
|
|
348
|
-
<Text style={styles.compactLabel}>2024 Fiili</Text>
|
|
349
|
-
<Text style={styles.compactValue}>
|
|
350
|
-
{formatCurrency(item.actual2024)}
|
|
351
|
-
</Text>
|
|
352
|
-
</View>
|
|
353
|
-
|
|
354
|
-
{/* Column 2 */}
|
|
355
|
-
<View style={styles.compactColumn}>
|
|
356
|
-
<Text style={styles.compactLabel}>2025 Fiili</Text>
|
|
357
|
-
<Text style={styles.compactValue}>
|
|
358
|
-
{formatCurrency(item.actual2025)}
|
|
359
|
-
</Text>
|
|
360
|
-
</View>
|
|
361
|
-
|
|
362
|
-
{/* Column 3 */}
|
|
363
|
-
<View style={styles.compactColumn}>
|
|
364
|
-
<Text style={styles.compactLabel}>Fiili Artış</Text>
|
|
365
|
-
<View style={styles.percentBadge}>
|
|
366
|
-
<Text style={[
|
|
367
|
-
styles.percentText,
|
|
368
|
-
item.yoYChangePercent >= 0 ? styles.positive : styles.negative
|
|
369
|
-
]}>
|
|
370
|
-
{item.yoYChangePercent >= 0 ? '↑' : '↓'} {Math.abs(item.yoYChangePercent)}%
|
|
371
|
-
</Text>
|
|
372
|
-
</View>
|
|
373
|
-
</View>
|
|
374
|
-
|
|
375
|
-
{/* Column 4 */}
|
|
376
|
-
<View style={styles.compactColumn}>
|
|
377
|
-
<Text style={styles.compactLabel}>2025 Bütçe</Text>
|
|
378
|
-
<Text style={styles.compactValue}>
|
|
379
|
-
{formatCurrency(item.budget2025)}
|
|
380
|
-
</Text>
|
|
381
|
-
</View>
|
|
382
|
-
|
|
383
|
-
{/* Column 5 */}
|
|
384
|
-
<View style={styles.compactColumn}>
|
|
385
|
-
<Text style={styles.compactLabel}>Sapma</Text>
|
|
386
|
-
<View style={styles.percentBadge}>
|
|
387
|
-
<Text style={[
|
|
388
|
-
styles.percentText,
|
|
389
|
-
item.budgetVariancePercent >= 0 ? styles.positive : styles.negative
|
|
390
|
-
]}>
|
|
391
|
-
{item.budgetVariancePercent >= 0 ? '↑' : '↓'} {Math.abs(item.budgetVariancePercent)}%
|
|
392
|
-
</Text>
|
|
393
|
-
</View>
|
|
394
|
-
</View>
|
|
395
|
-
</View>
|
|
396
|
-
|
|
397
|
-
{/* Status Indicator */}
|
|
398
|
-
<View style={styles.statusIndicator}>
|
|
399
|
-
<View style={[
|
|
400
|
-
styles.statusDot,
|
|
401
|
-
(item.yoYChangePercent >= 0 && item.budgetVariancePercent >= 0)
|
|
402
|
-
? styles.statusGood
|
|
403
|
-
: styles.statusWarning
|
|
404
|
-
]} />
|
|
405
|
-
<Text style={styles.statusText}>
|
|
406
|
-
{item.yoYChangePercent >= 0 && item.budgetVariancePercent >= 0
|
|
407
|
-
? 'Performans İyi'
|
|
408
|
-
: 'İnceleme Gerekli'}
|
|
409
|
-
</Text>
|
|
410
|
-
</View>
|
|
411
|
-
</View>
|
|
412
|
-
))}
|
|
413
|
-
</ScrollView>
|
|
414
|
-
);
|
|
415
|
-
};
|
|
416
|
-
|
|
417
|
-
// Report 1B: Freeze First Column Table
|
|
418
|
-
const renderFreezeTable = (data) => {
|
|
419
|
-
if (!Array.isArray(data) || data.length === 0) {
|
|
420
|
-
return (
|
|
421
|
-
<View style={styles.noDataContainer}>
|
|
422
|
-
<Text style={styles.noDataText}>No data available for this report</Text>
|
|
423
|
-
</View>
|
|
424
|
-
);
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
return (
|
|
428
|
-
<View style={styles.freezeContainer}>
|
|
429
|
-
{/* Fixed First Column */}
|
|
430
|
-
<View style={styles.freezeColumn}>
|
|
431
|
-
<View style={[styles.freezeHeader, styles.freezeFirstCell]}>
|
|
432
|
-
<Text style={styles.freezeHeaderText}>FALİYET KAR/ZARAR</Text>
|
|
433
|
-
</View>
|
|
434
|
-
{data.map((item, index) => (
|
|
435
|
-
<View
|
|
436
|
-
key={index}
|
|
437
|
-
style={[
|
|
438
|
-
styles.freezeRow,
|
|
439
|
-
item.isTotal && styles.freezeTotalRow,
|
|
440
|
-
index % 2 === 0 ? styles.evenRow : styles.oddRow
|
|
441
|
-
]}
|
|
442
|
-
>
|
|
443
|
-
<Text style={[
|
|
444
|
-
styles.freezeCellText,
|
|
445
|
-
item.isTotal && styles.freezeTotalText
|
|
446
|
-
]}>
|
|
447
|
-
{item.name}
|
|
448
|
-
</Text>
|
|
449
|
-
</View>
|
|
450
|
-
))}
|
|
451
|
-
</View>
|
|
452
|
-
|
|
453
|
-
{/* Scrollable Data Columns */}
|
|
454
|
-
<ScrollView horizontal showsHorizontalScrollIndicator={true}>
|
|
455
|
-
<View style={styles.scrollableColumns}>
|
|
456
|
-
{/* Headers for scrollable columns */}
|
|
457
|
-
<View style={styles.freezeHeaderRow}>
|
|
458
|
-
{['2024 Fiili', '2025 Fiili', 'Fiili Artış %', '2025 Bütçe', 'Sapma %', 'BRÜT KAR %'].map((header, idx) => (
|
|
459
|
-
<View key={idx} style={styles.freezeHeader}>
|
|
460
|
-
<Text style={styles.freezeHeaderText}>{header}</Text>
|
|
461
|
-
</View>
|
|
462
|
-
))}
|
|
463
|
-
</View>
|
|
464
|
-
|
|
465
|
-
{/* Data rows for scrollable columns */}
|
|
466
|
-
{data.map((item, rowIndex) => (
|
|
467
|
-
<View
|
|
468
|
-
key={rowIndex}
|
|
469
|
-
style={[
|
|
470
|
-
styles.freezeDataRow,
|
|
471
|
-
item.isTotal && styles.freezeTotalDataRow,
|
|
472
|
-
rowIndex % 2 === 0 ? styles.evenRow : styles.oddRow
|
|
473
|
-
]}
|
|
474
|
-
>
|
|
475
|
-
<View style={styles.freezeDataCell}>
|
|
476
|
-
<Text style={styles.freezeDataText}>
|
|
477
|
-
{formatCurrency(item.actual2024)}
|
|
478
|
-
</Text>
|
|
479
|
-
</View>
|
|
480
|
-
|
|
481
|
-
<View style={styles.freezeDataCell}>
|
|
482
|
-
<Text style={styles.freezeDataText}>
|
|
483
|
-
{formatCurrency(item.actual2025)}
|
|
484
|
-
</Text>
|
|
485
|
-
</View>
|
|
486
|
-
|
|
487
|
-
<View style={styles.freezeDataCell}>
|
|
488
|
-
<Text style={[
|
|
489
|
-
styles.freezePercent,
|
|
490
|
-
item.yoYChangePercent >= 0 ? styles.positive : styles.negative
|
|
491
|
-
]}>
|
|
492
|
-
{item.yoYChangePercent >= 0 ? '↑' : '↓'} {Math.abs(item.yoYChangePercent)}%
|
|
493
|
-
</Text>
|
|
494
|
-
</View>
|
|
495
|
-
|
|
496
|
-
<View style={styles.freezeDataCell}>
|
|
497
|
-
<Text style={styles.freezeDataText}>
|
|
498
|
-
{formatCurrency(item.budget2025)}
|
|
499
|
-
</Text>
|
|
500
|
-
</View>
|
|
501
|
-
|
|
502
|
-
<View style={styles.freezeDataCell}>
|
|
503
|
-
<Text style={[
|
|
504
|
-
styles.freezePercent,
|
|
505
|
-
item.budgetVariancePercent >= 0 ? styles.positive : styles.negative
|
|
506
|
-
]}>
|
|
507
|
-
{item.budgetVariancePercent >= 0 ? '↑' : '↓'} {Math.abs(item.budgetVariancePercent)}%
|
|
508
|
-
</Text>
|
|
509
|
-
</View>
|
|
510
|
-
|
|
511
|
-
<View style={styles.freezeDataCell}>
|
|
512
|
-
<Text style={[
|
|
513
|
-
styles.freezePercent,
|
|
514
|
-
styles.grossMargin
|
|
515
|
-
]}>
|
|
516
|
-
{item.grossMarginPercent}%
|
|
517
|
-
</Text>
|
|
518
|
-
</View>
|
|
519
|
-
</View>
|
|
520
|
-
))}
|
|
521
|
-
</View>
|
|
522
|
-
</ScrollView>
|
|
523
|
-
</View>
|
|
524
|
-
);
|
|
525
|
-
};
|
|
526
|
-
|
|
527
|
-
|
|
528
517
|
const renderPieChart = (data) => {
|
|
529
|
-
// Data should be array of objects with label and value
|
|
530
518
|
const total = data.reduce((sum, item) => sum + (item.shipments || item.revenue || item.value || 0), 0);
|
|
531
519
|
|
|
532
520
|
return (
|
|
533
521
|
<View style={styles.chartContainer}>
|
|
534
|
-
<Text style={styles.chartTitle}>{reportData
|
|
522
|
+
<Text style={styles.chartTitle}>{reportData?.title || ''}</Text>
|
|
535
523
|
<View style={styles.pieContainer}>
|
|
536
524
|
{data.map((item, index) => {
|
|
537
525
|
const value = item.shipments || item.revenue || item.value || 0;
|
|
@@ -556,21 +544,51 @@ const renderFreezeTable = (data) => {
|
|
|
556
544
|
);
|
|
557
545
|
};
|
|
558
546
|
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
547
|
+
// ========== MAIN RENDER LOGIC ==========
|
|
548
|
+
const renderChart = () => {
|
|
549
|
+
if (!reportData || !reportData.data) {
|
|
550
|
+
return (
|
|
551
|
+
<View style={styles.noDataContainer}>
|
|
552
|
+
<Text style={styles.noDataText}>No data available for this report</Text>
|
|
553
|
+
</View>
|
|
554
|
+
);
|
|
555
|
+
}
|
|
567
556
|
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
if (
|
|
557
|
+
const { type, data } = reportData;
|
|
558
|
+
|
|
559
|
+
// For performance reports
|
|
560
|
+
if (type === 'table' && selectedReport &&
|
|
561
|
+
(selectedReport.id === 1 || selectedReport.id === 1.1 || selectedReport.id === 1.2)) {
|
|
562
|
+
switch (viewType) {
|
|
563
|
+
case 'compact':
|
|
564
|
+
return renderCompactTable(data);
|
|
565
|
+
case 'freeze':
|
|
566
|
+
return renderFreezeTable(data);
|
|
567
|
+
case 'default':
|
|
568
|
+
default:
|
|
569
|
+
return renderTable(data);
|
|
570
|
+
}
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
// For other table reports
|
|
574
|
+
if (type === 'table') {
|
|
575
|
+
return renderTable(data);
|
|
576
|
+
}
|
|
577
|
+
|
|
578
|
+
// For chart reports
|
|
579
|
+
switch (type) {
|
|
580
|
+
case 'line':
|
|
581
|
+
return renderLineChart(data);
|
|
582
|
+
case 'bar':
|
|
583
|
+
return renderBarChart(data);
|
|
584
|
+
case 'pie':
|
|
585
|
+
return renderPieChart(data);
|
|
586
|
+
default:
|
|
587
|
+
return renderBarChart(data);
|
|
588
|
+
}
|
|
572
589
|
};
|
|
573
590
|
|
|
591
|
+
// ========== RENDER SELECTED REPORT VIEW ==========
|
|
574
592
|
if (selectedReport) {
|
|
575
593
|
return (
|
|
576
594
|
<View style={styles.container}>
|
|
@@ -580,6 +598,7 @@ const renderFreezeTable = (data) => {
|
|
|
580
598
|
onPress={() => {
|
|
581
599
|
setSelectedReport(null);
|
|
582
600
|
setReportData(null);
|
|
601
|
+
setViewType('default');
|
|
583
602
|
}}
|
|
584
603
|
>
|
|
585
604
|
<Text style={styles.backText}>‹</Text>
|
|
@@ -610,7 +629,63 @@ const renderFreezeTable = (data) => {
|
|
|
610
629
|
</View>
|
|
611
630
|
) : (
|
|
612
631
|
<ScrollView style={styles.chartView}>
|
|
613
|
-
{
|
|
632
|
+
{/* View Type Selector for Performance Reports */}
|
|
633
|
+
{selectedReport &&
|
|
634
|
+
(selectedReport.id === 1 || selectedReport.id === 1.1 || selectedReport.id === 1.2) &&
|
|
635
|
+
reportData && (
|
|
636
|
+
<View style={styles.viewTypeSelector}>
|
|
637
|
+
<TouchableOpacity
|
|
638
|
+
style={[
|
|
639
|
+
styles.viewTypeButton,
|
|
640
|
+
viewType === 'default' && styles.activeViewType
|
|
641
|
+
]}
|
|
642
|
+
onPress={() => setViewType('default')}
|
|
643
|
+
>
|
|
644
|
+
<Text style={[
|
|
645
|
+
styles.viewTypeText,
|
|
646
|
+
viewType === 'default' && styles.activeViewTypeText
|
|
647
|
+
]}>Varsayılan</Text>
|
|
648
|
+
</TouchableOpacity>
|
|
649
|
+
|
|
650
|
+
<TouchableOpacity
|
|
651
|
+
style={[
|
|
652
|
+
styles.viewTypeButton,
|
|
653
|
+
viewType === 'compact' && styles.activeViewType
|
|
654
|
+
]}
|
|
655
|
+
onPress={() => setViewType('compact')}
|
|
656
|
+
>
|
|
657
|
+
<Text style={[
|
|
658
|
+
styles.viewTypeText,
|
|
659
|
+
viewType === 'compact' && styles.activeViewTypeText
|
|
660
|
+
]}>Kompakt</Text>
|
|
661
|
+
</TouchableOpacity>
|
|
662
|
+
|
|
663
|
+
<TouchableOpacity
|
|
664
|
+
style={[
|
|
665
|
+
styles.viewTypeButton,
|
|
666
|
+
viewType === 'freeze' && styles.activeViewType
|
|
667
|
+
]}
|
|
668
|
+
onPress={() => setViewType('freeze')}
|
|
669
|
+
>
|
|
670
|
+
<Text style={[
|
|
671
|
+
styles.viewTypeText,
|
|
672
|
+
viewType === 'freeze' && styles.activeViewTypeText
|
|
673
|
+
]}>Sabit Kolon</Text>
|
|
674
|
+
</TouchableOpacity>
|
|
675
|
+
</View>
|
|
676
|
+
)}
|
|
677
|
+
|
|
678
|
+
<View style={styles.chartContainer}>
|
|
679
|
+
<Text style={styles.chartTitle}>{reportData?.title || selectedReport.title}</Text>
|
|
680
|
+
{selectedReport.id === 1 || selectedReport.id === 1.1 || selectedReport.id === 1.2 ? (
|
|
681
|
+
<Text style={styles.reportSubtitle}>
|
|
682
|
+
{viewType === 'default' ? 'Varsayılan Görünüm' :
|
|
683
|
+
viewType === 'compact' ? 'Kompakt Görünüm' :
|
|
684
|
+
'Sabit Kolonlu Görünüm'}
|
|
685
|
+
</Text>
|
|
686
|
+
) : null}
|
|
687
|
+
{renderChart()}
|
|
688
|
+
</View>
|
|
614
689
|
|
|
615
690
|
{reportData && reportData.data && (
|
|
616
691
|
<View style={styles.dataInfo}>
|
|
@@ -630,6 +705,7 @@ const renderFreezeTable = (data) => {
|
|
|
630
705
|
);
|
|
631
706
|
}
|
|
632
707
|
|
|
708
|
+
// ========== RENDER REPORT LIST VIEW ==========
|
|
633
709
|
return (
|
|
634
710
|
<View style={styles.container}>
|
|
635
711
|
<View style={styles.header}>
|
|
@@ -946,7 +1022,7 @@ const styles = StyleSheet.create({
|
|
|
946
1022
|
textAlign: 'center',
|
|
947
1023
|
},
|
|
948
1024
|
|
|
949
|
-
|
|
1025
|
+
// Table Styles
|
|
950
1026
|
table: {
|
|
951
1027
|
minWidth: 700,
|
|
952
1028
|
marginBottom: 20,
|
|
@@ -1009,12 +1085,6 @@ const styles = StyleSheet.create({
|
|
|
1009
1085
|
color: '#333',
|
|
1010
1086
|
textAlign: 'center',
|
|
1011
1087
|
},
|
|
1012
|
-
totalText: {
|
|
1013
|
-
fontSize: 12,
|
|
1014
|
-
fontWeight: '700',
|
|
1015
|
-
color: '#2c3e50',
|
|
1016
|
-
textAlign: 'center',
|
|
1017
|
-
},
|
|
1018
1088
|
numberText: {
|
|
1019
1089
|
fontSize: 11,
|
|
1020
1090
|
fontWeight: '500',
|
|
@@ -1037,6 +1107,7 @@ const styles = StyleSheet.create({
|
|
|
1037
1107
|
fontWeight: '700',
|
|
1038
1108
|
},
|
|
1039
1109
|
|
|
1110
|
+
// Compact Table Styles
|
|
1040
1111
|
compactContainer: {
|
|
1041
1112
|
flex: 1,
|
|
1042
1113
|
paddingHorizontal: 8,
|
|
@@ -1151,7 +1222,7 @@ const styles = StyleSheet.create({
|
|
|
1151
1222
|
color: '#666',
|
|
1152
1223
|
},
|
|
1153
1224
|
|
|
1154
|
-
//
|
|
1225
|
+
// Freeze Table Styles
|
|
1155
1226
|
freezeContainer: {
|
|
1156
1227
|
flex: 1,
|
|
1157
1228
|
flexDirection: 'row',
|
|
@@ -1242,7 +1313,7 @@ const styles = StyleSheet.create({
|
|
|
1242
1313
|
fontFamily: 'monospace',
|
|
1243
1314
|
},
|
|
1244
1315
|
|
|
1245
|
-
//
|
|
1316
|
+
// View Type Selector
|
|
1246
1317
|
viewTypeSelector: {
|
|
1247
1318
|
flexDirection: 'row',
|
|
1248
1319
|
backgroundColor: '#f0f0f0',
|
|
@@ -1274,65 +1345,14 @@ const styles = StyleSheet.create({
|
|
|
1274
1345
|
color: '#4CAF50',
|
|
1275
1346
|
fontWeight: '600',
|
|
1276
1347
|
},
|
|
1348
|
+
reportSubtitle: {
|
|
1349
|
+
fontSize: 14,
|
|
1350
|
+
fontWeight: '600',
|
|
1351
|
+
color: '#4CAF50',
|
|
1352
|
+
textAlign: 'center',
|
|
1353
|
+
marginBottom: 16,
|
|
1354
|
+
fontStyle: 'italic',
|
|
1355
|
+
},
|
|
1277
1356
|
});
|
|
1278
1357
|
|
|
1279
|
-
// Add view type selector component in the chart view
|
|
1280
|
-
{selectedReport && (selectedReport.id === 1 || selectedReport.id === 1.1 || selectedReport.id === 1.2) && (
|
|
1281
|
-
<View style={styles.viewTypeSelector}>
|
|
1282
|
-
<TouchableOpacity
|
|
1283
|
-
style={[
|
|
1284
|
-
styles.viewTypeButton,
|
|
1285
|
-
reportData?.subType === 'default' && styles.activeViewType
|
|
1286
|
-
]}
|
|
1287
|
-
onPress={() => {
|
|
1288
|
-
setReportData({
|
|
1289
|
-
...reportData,
|
|
1290
|
-
subType: 'default'
|
|
1291
|
-
});
|
|
1292
|
-
}}
|
|
1293
|
-
>
|
|
1294
|
-
<Text style={[
|
|
1295
|
-
styles.viewTypeText,
|
|
1296
|
-
reportData?.subType === 'default' && styles.activeViewTypeText
|
|
1297
|
-
]}>Varsayılan</Text>
|
|
1298
|
-
</TouchableOpacity>
|
|
1299
|
-
|
|
1300
|
-
<TouchableOpacity
|
|
1301
|
-
style={[
|
|
1302
|
-
styles.viewTypeButton,
|
|
1303
|
-
reportData?.subType === 'compact' && styles.activeViewType
|
|
1304
|
-
]}
|
|
1305
|
-
onPress={() => {
|
|
1306
|
-
setReportData({
|
|
1307
|
-
...reportData,
|
|
1308
|
-
subType: 'compact'
|
|
1309
|
-
});
|
|
1310
|
-
}}
|
|
1311
|
-
>
|
|
1312
|
-
<Text style={[
|
|
1313
|
-
styles.viewTypeText,
|
|
1314
|
-
reportData?.subType === 'compact' && styles.activeViewTypeText
|
|
1315
|
-
]}>Kompakt</Text>
|
|
1316
|
-
</TouchableOpacity>
|
|
1317
|
-
|
|
1318
|
-
<TouchableOpacity
|
|
1319
|
-
style={[
|
|
1320
|
-
styles.viewTypeButton,
|
|
1321
|
-
reportData?.subType === 'freeze' && styles.activeViewType
|
|
1322
|
-
]}
|
|
1323
|
-
onPress={() => {
|
|
1324
|
-
setReportData({
|
|
1325
|
-
...reportData,
|
|
1326
|
-
subType: 'freeze'
|
|
1327
|
-
});
|
|
1328
|
-
}}
|
|
1329
|
-
>
|
|
1330
|
-
<Text style={[
|
|
1331
|
-
styles.viewTypeText,
|
|
1332
|
-
reportData?.subType === 'freeze' && styles.activeViewTypeText
|
|
1333
|
-
]}>Sabit Kolon</Text>
|
|
1334
|
-
</TouchableOpacity>
|
|
1335
|
-
</View>
|
|
1336
|
-
)}
|
|
1337
|
-
|
|
1338
1358
|
export default ReportChart;
|