@dhiraj0720/report1chart 1.0.4 → 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 +718 -173
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,47 +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
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
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
|
+
);
|
|
232
|
+
}
|
|
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
|
+
}
|
|
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>
|
|
117
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>
|
|
118
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 ==========
|
|
119
444
|
const renderLineChart = (data) => {
|
|
120
|
-
// Handle both formats: { labels, values } or array format
|
|
121
445
|
const values = data.values || data.map(d => d.value || d.revenue || d.shipments || 0);
|
|
122
446
|
const labels = data.labels || data.map(d => d.label || d.month || d.mode || d.direction || '');
|
|
123
447
|
|
|
@@ -128,7 +452,7 @@ const formatCurrency = (value) => {
|
|
|
128
452
|
|
|
129
453
|
return (
|
|
130
454
|
<View style={styles.chartContainer}>
|
|
131
|
-
<Text style={styles.chartTitle}>{reportData
|
|
455
|
+
<Text style={styles.chartTitle}>{reportData?.title || ''}</Text>
|
|
132
456
|
<ScrollView horizontal showsHorizontalScrollIndicator={false}>
|
|
133
457
|
<View style={[styles.chart, { height: chartHeight, width: chartWidth }]}>
|
|
134
458
|
{values.map((value, index) => {
|
|
@@ -154,7 +478,6 @@ const formatCurrency = (value) => {
|
|
|
154
478
|
};
|
|
155
479
|
|
|
156
480
|
const renderBarChart = (data) => {
|
|
157
|
-
// Handle array format or object format
|
|
158
481
|
const isArray = Array.isArray(data);
|
|
159
482
|
const values = isArray ? data.map(d => d.revenue || d.value || d.shipments || 0) : data.values;
|
|
160
483
|
const labels = isArray ? data.map(d => d.mode || d.label || '') : data.labels;
|
|
@@ -166,7 +489,7 @@ const formatCurrency = (value) => {
|
|
|
166
489
|
|
|
167
490
|
return (
|
|
168
491
|
<View style={styles.chartContainer}>
|
|
169
|
-
<Text style={styles.chartTitle}>{reportData
|
|
492
|
+
<Text style={styles.chartTitle}>{reportData?.title || ''}</Text>
|
|
170
493
|
<ScrollView horizontal showsHorizontalScrollIndicator={false}>
|
|
171
494
|
<View style={[styles.chart, { height: chartHeight, width: chartWidth }]}>
|
|
172
495
|
{values.map((value, index) => {
|
|
@@ -191,119 +514,12 @@ const formatCurrency = (value) => {
|
|
|
191
514
|
);
|
|
192
515
|
};
|
|
193
516
|
|
|
194
|
-
const renderTable = (data) => {
|
|
195
|
-
if (!Array.isArray(data) || data.length === 0) {
|
|
196
|
-
return (
|
|
197
|
-
<View style={styles.noDataContainer}>
|
|
198
|
-
<Text style={styles.noDataText}>No data available for this report</Text>
|
|
199
|
-
</View>
|
|
200
|
-
);
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
return (
|
|
204
|
-
<ScrollView horizontal showsHorizontalScrollIndicator={true}>
|
|
205
|
-
<View style={styles.table}>
|
|
206
|
-
{/* Table Header */}
|
|
207
|
-
<View style={styles.tableHeader}>
|
|
208
|
-
<View style={[styles.headerCell, styles.firstColumn]}>
|
|
209
|
-
<Text style={styles.headerText}>FALİYET KAR/ZARAR</Text>
|
|
210
|
-
</View>
|
|
211
|
-
<View style={styles.headerCell}>
|
|
212
|
-
<Text style={styles.headerText}>2024 Fiili</Text>
|
|
213
|
-
</View>
|
|
214
|
-
<View style={styles.headerCell}>
|
|
215
|
-
<Text style={styles.headerText}>2025 Fiili</Text>
|
|
216
|
-
</View>
|
|
217
|
-
<View style={styles.headerCell}>
|
|
218
|
-
<Text style={styles.headerText}>Fiili Artış %</Text>
|
|
219
|
-
</View>
|
|
220
|
-
<View style={styles.headerCell}>
|
|
221
|
-
<Text style={styles.headerText}>2025 Bütçe</Text>
|
|
222
|
-
</View>
|
|
223
|
-
<View style={styles.headerCell}>
|
|
224
|
-
<Text style={styles.headerText}>Sapma %</Text>
|
|
225
|
-
</View>
|
|
226
|
-
<View style={styles.headerCell}>
|
|
227
|
-
<Text style={styles.headerText}>FALİYET GİD.</Text>
|
|
228
|
-
<Text style={styles.headerText}>/ BRÜT KAR %</Text>
|
|
229
|
-
</View>
|
|
230
|
-
</View>
|
|
231
|
-
|
|
232
|
-
{/* Table Rows */}
|
|
233
|
-
{data.map((item, index) => (
|
|
234
|
-
<View
|
|
235
|
-
key={index}
|
|
236
|
-
style={[
|
|
237
|
-
styles.tableRow,
|
|
238
|
-
item.isTotal ? styles.totalRow : (index % 2 === 0 ? styles.evenRow : styles.oddRow)
|
|
239
|
-
]}
|
|
240
|
-
>
|
|
241
|
-
<View style={[styles.cell, styles.firstColumn]}>
|
|
242
|
-
<Text style={item.isTotal ? styles.totalText : styles.cellText}>
|
|
243
|
-
{item.name}
|
|
244
|
-
</Text>
|
|
245
|
-
</View>
|
|
246
|
-
|
|
247
|
-
<View style={styles.cell}>
|
|
248
|
-
<Text style={styles.numberText}>
|
|
249
|
-
{formatCurrency(item.actual2024)}
|
|
250
|
-
</Text>
|
|
251
|
-
</View>
|
|
252
|
-
|
|
253
|
-
<View style={styles.cell}>
|
|
254
|
-
<Text style={styles.numberText}>
|
|
255
|
-
{formatCurrency(item.actual2025)}
|
|
256
|
-
</Text>
|
|
257
|
-
</View>
|
|
258
|
-
|
|
259
|
-
<View style={styles.cell}>
|
|
260
|
-
<Text style={[
|
|
261
|
-
styles.percentText,
|
|
262
|
-
item.yoYChangePercent >= 0 ? styles.positive : styles.negative
|
|
263
|
-
]}>
|
|
264
|
-
{item.yoYChangePercent >= 0 ? '↑' : '↓'} {Math.abs(item.yoYChangePercent)}%
|
|
265
|
-
</Text>
|
|
266
|
-
</View>
|
|
267
|
-
|
|
268
|
-
<View style={styles.cell}>
|
|
269
|
-
<Text style={styles.numberText}>
|
|
270
|
-
{formatCurrency(item.budget2025)}
|
|
271
|
-
</Text>
|
|
272
|
-
</View>
|
|
273
|
-
|
|
274
|
-
<View style={styles.cell}>
|
|
275
|
-
<Text style={[
|
|
276
|
-
styles.percentText,
|
|
277
|
-
item.budgetVariancePercent >= 0 ? styles.positive : styles.negative
|
|
278
|
-
]}>
|
|
279
|
-
{item.budgetVariancePercent >= 0 ? '↑' : '↓'} {Math.abs(item.budgetVariancePercent)}%
|
|
280
|
-
</Text>
|
|
281
|
-
</View>
|
|
282
|
-
|
|
283
|
-
<View style={styles.cell}>
|
|
284
|
-
<Text style={[
|
|
285
|
-
styles.percentText,
|
|
286
|
-
styles.grossMargin
|
|
287
|
-
]}>
|
|
288
|
-
{item.grossMarginPercent}%
|
|
289
|
-
</Text>
|
|
290
|
-
</View>
|
|
291
|
-
</View>
|
|
292
|
-
))}
|
|
293
|
-
</View>
|
|
294
|
-
</ScrollView>
|
|
295
|
-
);
|
|
296
|
-
};
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
517
|
const renderPieChart = (data) => {
|
|
301
|
-
// Data should be array of objects with label and value
|
|
302
518
|
const total = data.reduce((sum, item) => sum + (item.shipments || item.revenue || item.value || 0), 0);
|
|
303
519
|
|
|
304
520
|
return (
|
|
305
521
|
<View style={styles.chartContainer}>
|
|
306
|
-
<Text style={styles.chartTitle}>{reportData
|
|
522
|
+
<Text style={styles.chartTitle}>{reportData?.title || ''}</Text>
|
|
307
523
|
<View style={styles.pieContainer}>
|
|
308
524
|
{data.map((item, index) => {
|
|
309
525
|
const value = item.shipments || item.revenue || item.value || 0;
|
|
@@ -328,21 +544,51 @@ const formatCurrency = (value) => {
|
|
|
328
544
|
);
|
|
329
545
|
};
|
|
330
546
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
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
|
+
}
|
|
339
556
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
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
|
+
}
|
|
344
589
|
};
|
|
345
590
|
|
|
591
|
+
// ========== RENDER SELECTED REPORT VIEW ==========
|
|
346
592
|
if (selectedReport) {
|
|
347
593
|
return (
|
|
348
594
|
<View style={styles.container}>
|
|
@@ -352,6 +598,7 @@ const formatCurrency = (value) => {
|
|
|
352
598
|
onPress={() => {
|
|
353
599
|
setSelectedReport(null);
|
|
354
600
|
setReportData(null);
|
|
601
|
+
setViewType('default');
|
|
355
602
|
}}
|
|
356
603
|
>
|
|
357
604
|
<Text style={styles.backText}>‹</Text>
|
|
@@ -382,7 +629,63 @@ const formatCurrency = (value) => {
|
|
|
382
629
|
</View>
|
|
383
630
|
) : (
|
|
384
631
|
<ScrollView style={styles.chartView}>
|
|
385
|
-
{
|
|
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>
|
|
386
689
|
|
|
387
690
|
{reportData && reportData.data && (
|
|
388
691
|
<View style={styles.dataInfo}>
|
|
@@ -402,6 +705,7 @@ const formatCurrency = (value) => {
|
|
|
402
705
|
);
|
|
403
706
|
}
|
|
404
707
|
|
|
708
|
+
// ========== RENDER REPORT LIST VIEW ==========
|
|
405
709
|
return (
|
|
406
710
|
<View style={styles.container}>
|
|
407
711
|
<View style={styles.header}>
|
|
@@ -718,7 +1022,7 @@ const styles = StyleSheet.create({
|
|
|
718
1022
|
textAlign: 'center',
|
|
719
1023
|
},
|
|
720
1024
|
|
|
721
|
-
|
|
1025
|
+
// Table Styles
|
|
722
1026
|
table: {
|
|
723
1027
|
minWidth: 700,
|
|
724
1028
|
marginBottom: 20,
|
|
@@ -781,12 +1085,6 @@ const styles = StyleSheet.create({
|
|
|
781
1085
|
color: '#333',
|
|
782
1086
|
textAlign: 'center',
|
|
783
1087
|
},
|
|
784
|
-
totalText: {
|
|
785
|
-
fontSize: 12,
|
|
786
|
-
fontWeight: '700',
|
|
787
|
-
color: '#2c3e50',
|
|
788
|
-
textAlign: 'center',
|
|
789
|
-
},
|
|
790
1088
|
numberText: {
|
|
791
1089
|
fontSize: 11,
|
|
792
1090
|
fontWeight: '500',
|
|
@@ -808,6 +1106,253 @@ const styles = StyleSheet.create({
|
|
|
808
1106
|
color: '#2c3e50',
|
|
809
1107
|
fontWeight: '700',
|
|
810
1108
|
},
|
|
1109
|
+
|
|
1110
|
+
// Compact Table Styles
|
|
1111
|
+
compactContainer: {
|
|
1112
|
+
flex: 1,
|
|
1113
|
+
paddingHorizontal: 8,
|
|
1114
|
+
},
|
|
1115
|
+
compactCard: {
|
|
1116
|
+
backgroundColor: '#fff',
|
|
1117
|
+
borderRadius: 12,
|
|
1118
|
+
marginBottom: 12,
|
|
1119
|
+
padding: 16,
|
|
1120
|
+
borderWidth: 1,
|
|
1121
|
+
borderColor: '#e8e8e8',
|
|
1122
|
+
shadowColor: '#000',
|
|
1123
|
+
shadowOffset: { width: 0, height: 2 },
|
|
1124
|
+
shadowOpacity: 0.1,
|
|
1125
|
+
shadowRadius: 3,
|
|
1126
|
+
elevation: 2,
|
|
1127
|
+
},
|
|
1128
|
+
compactTotalCard: {
|
|
1129
|
+
backgroundColor: '#e8f5e9',
|
|
1130
|
+
borderColor: '#4CAF50',
|
|
1131
|
+
borderWidth: 2,
|
|
1132
|
+
},
|
|
1133
|
+
evenCard: {
|
|
1134
|
+
backgroundColor: '#fff',
|
|
1135
|
+
},
|
|
1136
|
+
oddCard: {
|
|
1137
|
+
backgroundColor: '#f9f9f9',
|
|
1138
|
+
},
|
|
1139
|
+
compactHeader: {
|
|
1140
|
+
flexDirection: 'row',
|
|
1141
|
+
justifyContent: 'space-between',
|
|
1142
|
+
alignItems: 'center',
|
|
1143
|
+
marginBottom: 12,
|
|
1144
|
+
paddingBottom: 12,
|
|
1145
|
+
borderBottomWidth: 1,
|
|
1146
|
+
borderBottomColor: '#eee',
|
|
1147
|
+
},
|
|
1148
|
+
compactTitle: {
|
|
1149
|
+
fontSize: 14,
|
|
1150
|
+
fontWeight: '600',
|
|
1151
|
+
color: '#2c3e50',
|
|
1152
|
+
flex: 1,
|
|
1153
|
+
},
|
|
1154
|
+
totalTitle: {
|
|
1155
|
+
fontWeight: '700',
|
|
1156
|
+
color: '#2c3e50',
|
|
1157
|
+
fontSize: 15,
|
|
1158
|
+
},
|
|
1159
|
+
compactGrossMargin: {
|
|
1160
|
+
fontSize: 13,
|
|
1161
|
+
fontWeight: '600',
|
|
1162
|
+
paddingHorizontal: 8,
|
|
1163
|
+
paddingVertical: 4,
|
|
1164
|
+
borderRadius: 6,
|
|
1165
|
+
backgroundColor: '#f0f0f0',
|
|
1166
|
+
},
|
|
1167
|
+
compactGrid: {
|
|
1168
|
+
flexDirection: 'row',
|
|
1169
|
+
flexWrap: 'wrap',
|
|
1170
|
+
justifyContent: 'space-between',
|
|
1171
|
+
},
|
|
1172
|
+
compactColumn: {
|
|
1173
|
+
width: '48%',
|
|
1174
|
+
marginBottom: 12,
|
|
1175
|
+
backgroundColor: '#f8f9fa',
|
|
1176
|
+
padding: 10,
|
|
1177
|
+
borderRadius: 8,
|
|
1178
|
+
alignItems: 'center',
|
|
1179
|
+
},
|
|
1180
|
+
compactLabel: {
|
|
1181
|
+
fontSize: 11,
|
|
1182
|
+
color: '#666',
|
|
1183
|
+
marginBottom: 4,
|
|
1184
|
+
textAlign: 'center',
|
|
1185
|
+
},
|
|
1186
|
+
compactValue: {
|
|
1187
|
+
fontSize: 13,
|
|
1188
|
+
fontWeight: '600',
|
|
1189
|
+
color: '#2c3e50',
|
|
1190
|
+
fontFamily: 'monospace',
|
|
1191
|
+
},
|
|
1192
|
+
percentBadge: {
|
|
1193
|
+
backgroundColor: '#fff',
|
|
1194
|
+
paddingHorizontal: 10,
|
|
1195
|
+
paddingVertical: 4,
|
|
1196
|
+
borderRadius: 12,
|
|
1197
|
+
borderWidth: 1,
|
|
1198
|
+
borderColor: '#e0e0e0',
|
|
1199
|
+
},
|
|
1200
|
+
statusIndicator: {
|
|
1201
|
+
flexDirection: 'row',
|
|
1202
|
+
alignItems: 'center',
|
|
1203
|
+
marginTop: 12,
|
|
1204
|
+
paddingTop: 12,
|
|
1205
|
+
borderTopWidth: 1,
|
|
1206
|
+
borderTopColor: '#eee',
|
|
1207
|
+
},
|
|
1208
|
+
statusDot: {
|
|
1209
|
+
width: 8,
|
|
1210
|
+
height: 8,
|
|
1211
|
+
borderRadius: 4,
|
|
1212
|
+
marginRight: 8,
|
|
1213
|
+
},
|
|
1214
|
+
statusGood: {
|
|
1215
|
+
backgroundColor: '#4CAF50',
|
|
1216
|
+
},
|
|
1217
|
+
statusWarning: {
|
|
1218
|
+
backgroundColor: '#FF9800',
|
|
1219
|
+
},
|
|
1220
|
+
statusText: {
|
|
1221
|
+
fontSize: 12,
|
|
1222
|
+
color: '#666',
|
|
1223
|
+
},
|
|
1224
|
+
|
|
1225
|
+
// Freeze Table Styles
|
|
1226
|
+
freezeContainer: {
|
|
1227
|
+
flex: 1,
|
|
1228
|
+
flexDirection: 'row',
|
|
1229
|
+
},
|
|
1230
|
+
freezeColumn: {
|
|
1231
|
+
width: 180,
|
|
1232
|
+
borderRightWidth: 2,
|
|
1233
|
+
borderRightColor: '#ddd',
|
|
1234
|
+
backgroundColor: '#fff',
|
|
1235
|
+
},
|
|
1236
|
+
freezeFirstCell: {
|
|
1237
|
+
backgroundColor: '#2c3e50',
|
|
1238
|
+
justifyContent: 'center',
|
|
1239
|
+
alignItems: 'center',
|
|
1240
|
+
},
|
|
1241
|
+
freezeHeader: {
|
|
1242
|
+
height: 50,
|
|
1243
|
+
justifyContent: 'center',
|
|
1244
|
+
alignItems: 'center',
|
|
1245
|
+
backgroundColor: '#2c3e50',
|
|
1246
|
+
borderBottomWidth: 1,
|
|
1247
|
+
borderBottomColor: '#444',
|
|
1248
|
+
borderRightWidth: 1,
|
|
1249
|
+
borderRightColor: '#444',
|
|
1250
|
+
minWidth: 120,
|
|
1251
|
+
},
|
|
1252
|
+
freezeHeaderRow: {
|
|
1253
|
+
flexDirection: 'row',
|
|
1254
|
+
},
|
|
1255
|
+
freezeHeaderText: {
|
|
1256
|
+
color: '#fff',
|
|
1257
|
+
fontWeight: '600',
|
|
1258
|
+
fontSize: 12,
|
|
1259
|
+
textAlign: 'center',
|
|
1260
|
+
},
|
|
1261
|
+
freezeRow: {
|
|
1262
|
+
height: 45,
|
|
1263
|
+
justifyContent: 'center',
|
|
1264
|
+
paddingHorizontal: 10,
|
|
1265
|
+
borderBottomWidth: 1,
|
|
1266
|
+
borderBottomColor: '#eee',
|
|
1267
|
+
},
|
|
1268
|
+
freezeTotalRow: {
|
|
1269
|
+
backgroundColor: '#e8f5e9',
|
|
1270
|
+
borderTopWidth: 2,
|
|
1271
|
+
borderTopColor: '#4CAF50',
|
|
1272
|
+
borderBottomWidth: 2,
|
|
1273
|
+
borderBottomColor: '#4CAF50',
|
|
1274
|
+
},
|
|
1275
|
+
freezeCellText: {
|
|
1276
|
+
fontSize: 12,
|
|
1277
|
+
color: '#333',
|
|
1278
|
+
fontWeight: '500',
|
|
1279
|
+
},
|
|
1280
|
+
freezeTotalText: {
|
|
1281
|
+
fontWeight: '700',
|
|
1282
|
+
color: '#2c3e50',
|
|
1283
|
+
},
|
|
1284
|
+
scrollableColumns: {
|
|
1285
|
+
flex: 1,
|
|
1286
|
+
},
|
|
1287
|
+
freezeDataRow: {
|
|
1288
|
+
flexDirection: 'row',
|
|
1289
|
+
height: 45,
|
|
1290
|
+
borderBottomWidth: 1,
|
|
1291
|
+
borderBottomColor: '#eee',
|
|
1292
|
+
},
|
|
1293
|
+
freezeTotalDataRow: {
|
|
1294
|
+
backgroundColor: '#e8f5e9',
|
|
1295
|
+
},
|
|
1296
|
+
freezeDataCell: {
|
|
1297
|
+
minWidth: 120,
|
|
1298
|
+
justifyContent: 'center',
|
|
1299
|
+
alignItems: 'center',
|
|
1300
|
+
borderRightWidth: 1,
|
|
1301
|
+
borderRightColor: '#eee',
|
|
1302
|
+
paddingHorizontal: 8,
|
|
1303
|
+
},
|
|
1304
|
+
freezeDataText: {
|
|
1305
|
+
fontSize: 12,
|
|
1306
|
+
fontWeight: '500',
|
|
1307
|
+
fontFamily: 'monospace',
|
|
1308
|
+
color: '#333',
|
|
1309
|
+
},
|
|
1310
|
+
freezePercent: {
|
|
1311
|
+
fontSize: 12,
|
|
1312
|
+
fontWeight: '600',
|
|
1313
|
+
fontFamily: 'monospace',
|
|
1314
|
+
},
|
|
1315
|
+
|
|
1316
|
+
// View Type Selector
|
|
1317
|
+
viewTypeSelector: {
|
|
1318
|
+
flexDirection: 'row',
|
|
1319
|
+
backgroundColor: '#f0f0f0',
|
|
1320
|
+
borderRadius: 8,
|
|
1321
|
+
padding: 4,
|
|
1322
|
+
marginBottom: 16,
|
|
1323
|
+
alignSelf: 'center',
|
|
1324
|
+
},
|
|
1325
|
+
viewTypeButton: {
|
|
1326
|
+
paddingHorizontal: 16,
|
|
1327
|
+
paddingVertical: 8,
|
|
1328
|
+
borderRadius: 6,
|
|
1329
|
+
marginHorizontal: 2,
|
|
1330
|
+
},
|
|
1331
|
+
activeViewType: {
|
|
1332
|
+
backgroundColor: '#fff',
|
|
1333
|
+
shadowColor: '#000',
|
|
1334
|
+
shadowOffset: { width: 0, height: 1 },
|
|
1335
|
+
shadowOpacity: 0.1,
|
|
1336
|
+
shadowRadius: 2,
|
|
1337
|
+
elevation: 2,
|
|
1338
|
+
},
|
|
1339
|
+
viewTypeText: {
|
|
1340
|
+
fontSize: 13,
|
|
1341
|
+
fontWeight: '500',
|
|
1342
|
+
color: '#666',
|
|
1343
|
+
},
|
|
1344
|
+
activeViewTypeText: {
|
|
1345
|
+
color: '#4CAF50',
|
|
1346
|
+
fontWeight: '600',
|
|
1347
|
+
},
|
|
1348
|
+
reportSubtitle: {
|
|
1349
|
+
fontSize: 14,
|
|
1350
|
+
fontWeight: '600',
|
|
1351
|
+
color: '#4CAF50',
|
|
1352
|
+
textAlign: 'center',
|
|
1353
|
+
marginBottom: 16,
|
|
1354
|
+
fontStyle: 'italic',
|
|
1355
|
+
},
|
|
811
1356
|
});
|
|
812
1357
|
|
|
813
1358
|
export default ReportChart;
|