@dhiraj0720/report1chart 1.0.3 → 1.0.5
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 +756 -18
package/package.json
CHANGED
package/src/index.jsx
CHANGED
|
@@ -77,28 +77,54 @@ const ReportChart = ({
|
|
|
77
77
|
}
|
|
78
78
|
};
|
|
79
79
|
|
|
80
|
+
// Add currency formatter
|
|
81
|
+
const formatCurrency = (value) => {
|
|
82
|
+
const num = Number(value);
|
|
83
|
+
if (isNaN(num)) return '0';
|
|
84
|
+
|
|
85
|
+
if (num >= 1000000) {
|
|
86
|
+
return `${(num / 1000000).toFixed(1)}M`;
|
|
87
|
+
} else if (num >= 1000) {
|
|
88
|
+
return `${(num / 1000).toFixed(1)}K`;
|
|
89
|
+
}
|
|
90
|
+
return num.toString();
|
|
91
|
+
};
|
|
92
|
+
|
|
80
93
|
const renderChart = () => {
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
94
|
+
if (!reportData || !reportData.data) {
|
|
95
|
+
return (
|
|
96
|
+
<View style={styles.noDataContainer}>
|
|
97
|
+
<Text style={styles.noDataText}>No data available for this report</Text>
|
|
98
|
+
</View>
|
|
99
|
+
);
|
|
100
|
+
}
|
|
88
101
|
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
102
|
+
const { type, subType, data } = reportData;
|
|
103
|
+
|
|
104
|
+
if (type === 'table') {
|
|
105
|
+
switch (subType) {
|
|
106
|
+
case 'compact': // Report 1A
|
|
107
|
+
return renderCompactTable(data);
|
|
108
|
+
case 'freeze': // Report 1B
|
|
109
|
+
return renderFreezeTable(data);
|
|
110
|
+
case 'default': // Report 1
|
|
98
111
|
default:
|
|
99
|
-
return
|
|
112
|
+
return renderTable(data); // Original table
|
|
100
113
|
}
|
|
101
|
-
}
|
|
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
|
+
|
|
102
128
|
|
|
103
129
|
const renderLineChart = (data) => {
|
|
104
130
|
// Handle both formats: { labels, values } or array format
|
|
@@ -175,6 +201,330 @@ const ReportChart = ({
|
|
|
175
201
|
);
|
|
176
202
|
};
|
|
177
203
|
|
|
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
|
+
|
|
178
528
|
const renderPieChart = (data) => {
|
|
179
529
|
// Data should be array of objects with label and value
|
|
180
530
|
const total = data.reduce((sum, item) => sum + (item.shipments || item.revenue || item.value || 0), 0);
|
|
@@ -595,6 +945,394 @@ const styles = StyleSheet.create({
|
|
|
595
945
|
color: '#999',
|
|
596
946
|
textAlign: 'center',
|
|
597
947
|
},
|
|
948
|
+
|
|
949
|
+
// Table Styles
|
|
950
|
+
table: {
|
|
951
|
+
minWidth: 700,
|
|
952
|
+
marginBottom: 20,
|
|
953
|
+
},
|
|
954
|
+
tableHeader: {
|
|
955
|
+
flexDirection: 'row',
|
|
956
|
+
backgroundColor: '#2c3e50',
|
|
957
|
+
borderBottomWidth: 1,
|
|
958
|
+
borderBottomColor: '#ddd',
|
|
959
|
+
},
|
|
960
|
+
headerCell: {
|
|
961
|
+
flex: 1,
|
|
962
|
+
padding: 10,
|
|
963
|
+
minWidth: 100,
|
|
964
|
+
justifyContent: 'center',
|
|
965
|
+
alignItems: 'center',
|
|
966
|
+
borderRightWidth: 1,
|
|
967
|
+
borderRightColor: '#444',
|
|
968
|
+
},
|
|
969
|
+
firstColumn: {
|
|
970
|
+
flex: 1.5,
|
|
971
|
+
minWidth: 180,
|
|
972
|
+
},
|
|
973
|
+
headerText: {
|
|
974
|
+
color: '#fff',
|
|
975
|
+
fontWeight: '600',
|
|
976
|
+
fontSize: 11,
|
|
977
|
+
textAlign: 'center',
|
|
978
|
+
},
|
|
979
|
+
tableRow: {
|
|
980
|
+
flexDirection: 'row',
|
|
981
|
+
borderBottomWidth: 1,
|
|
982
|
+
borderBottomColor: '#eee',
|
|
983
|
+
minHeight: 40,
|
|
984
|
+
},
|
|
985
|
+
evenRow: {
|
|
986
|
+
backgroundColor: '#fff',
|
|
987
|
+
},
|
|
988
|
+
oddRow: {
|
|
989
|
+
backgroundColor: '#f9f9f9',
|
|
990
|
+
},
|
|
991
|
+
totalRow: {
|
|
992
|
+
backgroundColor: '#e8f5e9',
|
|
993
|
+
borderTopWidth: 2,
|
|
994
|
+
borderTopColor: '#4CAF50',
|
|
995
|
+
borderBottomWidth: 2,
|
|
996
|
+
borderBottomColor: '#4CAF50',
|
|
997
|
+
},
|
|
998
|
+
cell: {
|
|
999
|
+
flex: 1,
|
|
1000
|
+
padding: 8,
|
|
1001
|
+
minWidth: 100,
|
|
1002
|
+
justifyContent: 'center',
|
|
1003
|
+
alignItems: 'center',
|
|
1004
|
+
borderRightWidth: 1,
|
|
1005
|
+
borderRightColor: '#eee',
|
|
1006
|
+
},
|
|
1007
|
+
cellText: {
|
|
1008
|
+
fontSize: 12,
|
|
1009
|
+
color: '#333',
|
|
1010
|
+
textAlign: 'center',
|
|
1011
|
+
},
|
|
1012
|
+
totalText: {
|
|
1013
|
+
fontSize: 12,
|
|
1014
|
+
fontWeight: '700',
|
|
1015
|
+
color: '#2c3e50',
|
|
1016
|
+
textAlign: 'center',
|
|
1017
|
+
},
|
|
1018
|
+
numberText: {
|
|
1019
|
+
fontSize: 11,
|
|
1020
|
+
fontWeight: '500',
|
|
1021
|
+
fontFamily: 'monospace',
|
|
1022
|
+
color: '#333',
|
|
1023
|
+
},
|
|
1024
|
+
percentText: {
|
|
1025
|
+
fontSize: 12,
|
|
1026
|
+
fontWeight: '600',
|
|
1027
|
+
fontFamily: 'monospace',
|
|
1028
|
+
},
|
|
1029
|
+
positive: {
|
|
1030
|
+
color: '#27ae60',
|
|
1031
|
+
},
|
|
1032
|
+
negative: {
|
|
1033
|
+
color: '#e74c3c',
|
|
1034
|
+
},
|
|
1035
|
+
grossMargin: {
|
|
1036
|
+
color: '#2c3e50',
|
|
1037
|
+
fontWeight: '700',
|
|
1038
|
+
},
|
|
1039
|
+
|
|
1040
|
+
compactContainer: {
|
|
1041
|
+
flex: 1,
|
|
1042
|
+
paddingHorizontal: 8,
|
|
1043
|
+
},
|
|
1044
|
+
compactCard: {
|
|
1045
|
+
backgroundColor: '#fff',
|
|
1046
|
+
borderRadius: 12,
|
|
1047
|
+
marginBottom: 12,
|
|
1048
|
+
padding: 16,
|
|
1049
|
+
borderWidth: 1,
|
|
1050
|
+
borderColor: '#e8e8e8',
|
|
1051
|
+
shadowColor: '#000',
|
|
1052
|
+
shadowOffset: { width: 0, height: 2 },
|
|
1053
|
+
shadowOpacity: 0.1,
|
|
1054
|
+
shadowRadius: 3,
|
|
1055
|
+
elevation: 2,
|
|
1056
|
+
},
|
|
1057
|
+
compactTotalCard: {
|
|
1058
|
+
backgroundColor: '#e8f5e9',
|
|
1059
|
+
borderColor: '#4CAF50',
|
|
1060
|
+
borderWidth: 2,
|
|
1061
|
+
},
|
|
1062
|
+
evenCard: {
|
|
1063
|
+
backgroundColor: '#fff',
|
|
1064
|
+
},
|
|
1065
|
+
oddCard: {
|
|
1066
|
+
backgroundColor: '#f9f9f9',
|
|
1067
|
+
},
|
|
1068
|
+
compactHeader: {
|
|
1069
|
+
flexDirection: 'row',
|
|
1070
|
+
justifyContent: 'space-between',
|
|
1071
|
+
alignItems: 'center',
|
|
1072
|
+
marginBottom: 12,
|
|
1073
|
+
paddingBottom: 12,
|
|
1074
|
+
borderBottomWidth: 1,
|
|
1075
|
+
borderBottomColor: '#eee',
|
|
1076
|
+
},
|
|
1077
|
+
compactTitle: {
|
|
1078
|
+
fontSize: 14,
|
|
1079
|
+
fontWeight: '600',
|
|
1080
|
+
color: '#2c3e50',
|
|
1081
|
+
flex: 1,
|
|
1082
|
+
},
|
|
1083
|
+
totalTitle: {
|
|
1084
|
+
fontWeight: '700',
|
|
1085
|
+
color: '#2c3e50',
|
|
1086
|
+
fontSize: 15,
|
|
1087
|
+
},
|
|
1088
|
+
compactGrossMargin: {
|
|
1089
|
+
fontSize: 13,
|
|
1090
|
+
fontWeight: '600',
|
|
1091
|
+
paddingHorizontal: 8,
|
|
1092
|
+
paddingVertical: 4,
|
|
1093
|
+
borderRadius: 6,
|
|
1094
|
+
backgroundColor: '#f0f0f0',
|
|
1095
|
+
},
|
|
1096
|
+
compactGrid: {
|
|
1097
|
+
flexDirection: 'row',
|
|
1098
|
+
flexWrap: 'wrap',
|
|
1099
|
+
justifyContent: 'space-between',
|
|
1100
|
+
},
|
|
1101
|
+
compactColumn: {
|
|
1102
|
+
width: '48%',
|
|
1103
|
+
marginBottom: 12,
|
|
1104
|
+
backgroundColor: '#f8f9fa',
|
|
1105
|
+
padding: 10,
|
|
1106
|
+
borderRadius: 8,
|
|
1107
|
+
alignItems: 'center',
|
|
1108
|
+
},
|
|
1109
|
+
compactLabel: {
|
|
1110
|
+
fontSize: 11,
|
|
1111
|
+
color: '#666',
|
|
1112
|
+
marginBottom: 4,
|
|
1113
|
+
textAlign: 'center',
|
|
1114
|
+
},
|
|
1115
|
+
compactValue: {
|
|
1116
|
+
fontSize: 13,
|
|
1117
|
+
fontWeight: '600',
|
|
1118
|
+
color: '#2c3e50',
|
|
1119
|
+
fontFamily: 'monospace',
|
|
1120
|
+
},
|
|
1121
|
+
percentBadge: {
|
|
1122
|
+
backgroundColor: '#fff',
|
|
1123
|
+
paddingHorizontal: 10,
|
|
1124
|
+
paddingVertical: 4,
|
|
1125
|
+
borderRadius: 12,
|
|
1126
|
+
borderWidth: 1,
|
|
1127
|
+
borderColor: '#e0e0e0',
|
|
1128
|
+
},
|
|
1129
|
+
statusIndicator: {
|
|
1130
|
+
flexDirection: 'row',
|
|
1131
|
+
alignItems: 'center',
|
|
1132
|
+
marginTop: 12,
|
|
1133
|
+
paddingTop: 12,
|
|
1134
|
+
borderTopWidth: 1,
|
|
1135
|
+
borderTopColor: '#eee',
|
|
1136
|
+
},
|
|
1137
|
+
statusDot: {
|
|
1138
|
+
width: 8,
|
|
1139
|
+
height: 8,
|
|
1140
|
+
borderRadius: 4,
|
|
1141
|
+
marginRight: 8,
|
|
1142
|
+
},
|
|
1143
|
+
statusGood: {
|
|
1144
|
+
backgroundColor: '#4CAF50',
|
|
1145
|
+
},
|
|
1146
|
+
statusWarning: {
|
|
1147
|
+
backgroundColor: '#FF9800',
|
|
1148
|
+
},
|
|
1149
|
+
statusText: {
|
|
1150
|
+
fontSize: 12,
|
|
1151
|
+
color: '#666',
|
|
1152
|
+
},
|
|
1153
|
+
|
|
1154
|
+
// Report 1B: Freeze First Column Styles
|
|
1155
|
+
freezeContainer: {
|
|
1156
|
+
flex: 1,
|
|
1157
|
+
flexDirection: 'row',
|
|
1158
|
+
},
|
|
1159
|
+
freezeColumn: {
|
|
1160
|
+
width: 180,
|
|
1161
|
+
borderRightWidth: 2,
|
|
1162
|
+
borderRightColor: '#ddd',
|
|
1163
|
+
backgroundColor: '#fff',
|
|
1164
|
+
},
|
|
1165
|
+
freezeFirstCell: {
|
|
1166
|
+
backgroundColor: '#2c3e50',
|
|
1167
|
+
justifyContent: 'center',
|
|
1168
|
+
alignItems: 'center',
|
|
1169
|
+
},
|
|
1170
|
+
freezeHeader: {
|
|
1171
|
+
height: 50,
|
|
1172
|
+
justifyContent: 'center',
|
|
1173
|
+
alignItems: 'center',
|
|
1174
|
+
backgroundColor: '#2c3e50',
|
|
1175
|
+
borderBottomWidth: 1,
|
|
1176
|
+
borderBottomColor: '#444',
|
|
1177
|
+
borderRightWidth: 1,
|
|
1178
|
+
borderRightColor: '#444',
|
|
1179
|
+
minWidth: 120,
|
|
1180
|
+
},
|
|
1181
|
+
freezeHeaderRow: {
|
|
1182
|
+
flexDirection: 'row',
|
|
1183
|
+
},
|
|
1184
|
+
freezeHeaderText: {
|
|
1185
|
+
color: '#fff',
|
|
1186
|
+
fontWeight: '600',
|
|
1187
|
+
fontSize: 12,
|
|
1188
|
+
textAlign: 'center',
|
|
1189
|
+
},
|
|
1190
|
+
freezeRow: {
|
|
1191
|
+
height: 45,
|
|
1192
|
+
justifyContent: 'center',
|
|
1193
|
+
paddingHorizontal: 10,
|
|
1194
|
+
borderBottomWidth: 1,
|
|
1195
|
+
borderBottomColor: '#eee',
|
|
1196
|
+
},
|
|
1197
|
+
freezeTotalRow: {
|
|
1198
|
+
backgroundColor: '#e8f5e9',
|
|
1199
|
+
borderTopWidth: 2,
|
|
1200
|
+
borderTopColor: '#4CAF50',
|
|
1201
|
+
borderBottomWidth: 2,
|
|
1202
|
+
borderBottomColor: '#4CAF50',
|
|
1203
|
+
},
|
|
1204
|
+
freezeCellText: {
|
|
1205
|
+
fontSize: 12,
|
|
1206
|
+
color: '#333',
|
|
1207
|
+
fontWeight: '500',
|
|
1208
|
+
},
|
|
1209
|
+
freezeTotalText: {
|
|
1210
|
+
fontWeight: '700',
|
|
1211
|
+
color: '#2c3e50',
|
|
1212
|
+
},
|
|
1213
|
+
scrollableColumns: {
|
|
1214
|
+
flex: 1,
|
|
1215
|
+
},
|
|
1216
|
+
freezeDataRow: {
|
|
1217
|
+
flexDirection: 'row',
|
|
1218
|
+
height: 45,
|
|
1219
|
+
borderBottomWidth: 1,
|
|
1220
|
+
borderBottomColor: '#eee',
|
|
1221
|
+
},
|
|
1222
|
+
freezeTotalDataRow: {
|
|
1223
|
+
backgroundColor: '#e8f5e9',
|
|
1224
|
+
},
|
|
1225
|
+
freezeDataCell: {
|
|
1226
|
+
minWidth: 120,
|
|
1227
|
+
justifyContent: 'center',
|
|
1228
|
+
alignItems: 'center',
|
|
1229
|
+
borderRightWidth: 1,
|
|
1230
|
+
borderRightColor: '#eee',
|
|
1231
|
+
paddingHorizontal: 8,
|
|
1232
|
+
},
|
|
1233
|
+
freezeDataText: {
|
|
1234
|
+
fontSize: 12,
|
|
1235
|
+
fontWeight: '500',
|
|
1236
|
+
fontFamily: 'monospace',
|
|
1237
|
+
color: '#333',
|
|
1238
|
+
},
|
|
1239
|
+
freezePercent: {
|
|
1240
|
+
fontSize: 12,
|
|
1241
|
+
fontWeight: '600',
|
|
1242
|
+
fontFamily: 'monospace',
|
|
1243
|
+
},
|
|
1244
|
+
|
|
1245
|
+
// Add view type selector for performance reports
|
|
1246
|
+
viewTypeSelector: {
|
|
1247
|
+
flexDirection: 'row',
|
|
1248
|
+
backgroundColor: '#f0f0f0',
|
|
1249
|
+
borderRadius: 8,
|
|
1250
|
+
padding: 4,
|
|
1251
|
+
marginBottom: 16,
|
|
1252
|
+
alignSelf: 'center',
|
|
1253
|
+
},
|
|
1254
|
+
viewTypeButton: {
|
|
1255
|
+
paddingHorizontal: 16,
|
|
1256
|
+
paddingVertical: 8,
|
|
1257
|
+
borderRadius: 6,
|
|
1258
|
+
marginHorizontal: 2,
|
|
1259
|
+
},
|
|
1260
|
+
activeViewType: {
|
|
1261
|
+
backgroundColor: '#fff',
|
|
1262
|
+
shadowColor: '#000',
|
|
1263
|
+
shadowOffset: { width: 0, height: 1 },
|
|
1264
|
+
shadowOpacity: 0.1,
|
|
1265
|
+
shadowRadius: 2,
|
|
1266
|
+
elevation: 2,
|
|
1267
|
+
},
|
|
1268
|
+
viewTypeText: {
|
|
1269
|
+
fontSize: 13,
|
|
1270
|
+
fontWeight: '500',
|
|
1271
|
+
color: '#666',
|
|
1272
|
+
},
|
|
1273
|
+
activeViewTypeText: {
|
|
1274
|
+
color: '#4CAF50',
|
|
1275
|
+
fontWeight: '600',
|
|
1276
|
+
},
|
|
598
1277
|
});
|
|
599
1278
|
|
|
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
|
+
|
|
600
1338
|
export default ReportChart;
|