@dhiraj0720/report1chart 1.0.4 → 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.
Files changed (2) hide show
  1. package/package.json +1 -1
  2. package/src/index.jsx +528 -3
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dhiraj0720/report1chart",
3
- "version": "1.0.4",
3
+ "version": "1.0.5",
4
4
  "main": "src/index.jsx",
5
5
  "publishConfig": {
6
6
  "access": "public"
package/src/index.jsx CHANGED
@@ -99,11 +99,21 @@ const formatCurrency = (value) => {
99
99
  );
100
100
  }
101
101
 
102
- const { type, data } = reportData;
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
111
+ default:
112
+ return renderTable(data); // Original table
113
+ }
114
+ }
103
115
 
104
116
  switch (type) {
105
- case 'table':
106
- return renderTable(data);
107
117
  case 'line':
108
118
  return renderLineChart(data);
109
119
  case 'bar':
@@ -295,6 +305,224 @@ const formatCurrency = (value) => {
295
305
  );
296
306
  };
297
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
+ };
298
526
 
299
527
 
300
528
  const renderPieChart = (data) => {
@@ -808,6 +1036,303 @@ const styles = StyleSheet.create({
808
1036
  color: '#2c3e50',
809
1037
  fontWeight: '700',
810
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
+ },
811
1277
  });
812
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
+
813
1338
  export default ReportChart;