@dhiraj0720/report1chart 2.2.2 → 2.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dhiraj0720/report1chart",
3
- "version": "2.2.2",
3
+ "version": "2.2.3",
4
4
  "main": "src/index.jsx",
5
5
  "scripts": {
6
6
  "test": "echo 'No tests'"
@@ -22,9 +22,5 @@
22
22
  "author": "Dhiraj",
23
23
  "license": "MIT",
24
24
  "description": "A simple report chart and table package for React Native",
25
- "devDependencies": {
26
- "@babel/core": "^7.28.5",
27
- "@babel/preset-env": "^7.28.5",
28
- "@babel/preset-react": "^7.28.5"
29
- }
25
+ "devDependencies": {}
30
26
  }
@@ -0,0 +1,70 @@
1
+ import axios from 'axios';
2
+
3
+ export class ApiFetcher {
4
+ static async fetchReportData(reportConfig) {
5
+ try {
6
+ console.log('Fetching report data from:', reportConfig.apiConfig.url);
7
+
8
+ const headers = {
9
+ 'Content-Type': 'application/json',
10
+ 'Accept': 'application/json'
11
+ };
12
+
13
+ // Add token if provided
14
+ if (reportConfig.apiConfig.token) {
15
+ headers['Authorization'] = `Bearer ${reportConfig.apiConfig.token}`;
16
+ }
17
+
18
+ const response = await axios.get(reportConfig.apiConfig.url, {
19
+ timeout: 15000,
20
+ headers: headers
21
+ });
22
+
23
+ console.log('API Response received:', response.status);
24
+
25
+ // Transform data based on report type
26
+ return this.transformData(response.data, reportConfig);
27
+
28
+ } catch (error) {
29
+ console.error('API Fetch Error:', error);
30
+ throw new Error(`Failed to fetch report: ${error.message}`);
31
+ }
32
+ }
33
+
34
+ static transformData(data, reportConfig) {
35
+ // For performance reports (type 1, 1.1, 1.2)
36
+ if (reportConfig.id === 1 || reportConfig.id === 1.1 || reportConfig.id === 1.2) {
37
+ return {
38
+ data: data.data || [],
39
+ title: reportConfig.title,
40
+ type: 'table',
41
+ subType: reportConfig.subType
42
+ };
43
+ }
44
+
45
+ // For report 2 (Revenue by Mode)
46
+ if (reportConfig.id === 2) {
47
+ return {
48
+ data: Array.isArray(data) ? data : data.data || [],
49
+ title: reportConfig.title,
50
+ type: 'bar'
51
+ };
52
+ }
53
+
54
+ // For report 3 (Shipment by Direction)
55
+ if (reportConfig.id === 3) {
56
+ return {
57
+ data: Array.isArray(data) ? data : data.data || [],
58
+ title: reportConfig.title,
59
+ type: 'pie'
60
+ };
61
+ }
62
+
63
+ // Default transformation
64
+ return {
65
+ data: data,
66
+ title: reportConfig.title,
67
+ type: reportConfig.type || 'bar'
68
+ };
69
+ }
70
+ }
@@ -0,0 +1,388 @@
1
+ import React from 'react';
2
+ import {
3
+ View,
4
+ Text,
5
+ ScrollView,
6
+ Dimensions,
7
+ StyleSheet,
8
+ } from 'react-native';
9
+
10
+ const { width: screenWidth } = Dimensions.get('window');
11
+
12
+ // Helper functions
13
+ export const formatNumber = (num) => {
14
+ return num.toLocaleString();
15
+ };
16
+
17
+ export const getColor = (index) => {
18
+ const colors = ['#4CAF50', '#2196F3', '#FF9800', '#E91E63', '#9C27B0', '#00BCD4'];
19
+ return colors[index % colors.length];
20
+ };
21
+
22
+ export const renderLineChart = (data, title) => {
23
+ // Extract values and labels from data
24
+ const values = data.values || (Array.isArray(data) ? data.map(d => d.value || d.revenue || d.shipments || 0) : []);
25
+ const labels = data.labels || (Array.isArray(data) ? data.map(d => d.label || d.month || d.mode || d.direction || '') : []);
26
+
27
+ if (values.length === 0) {
28
+ return (
29
+ <View style={styles.noDataContainer}>
30
+ <Text style={styles.noDataText}>No data available for this report</Text>
31
+ </View>
32
+ );
33
+ }
34
+
35
+ const maxValue = Math.max(...values, 1);
36
+ const chartHeight = 200;
37
+ const chartWidth = Math.max(screenWidth - 64, values.length * 60);
38
+ const barWidth = Math.max(20, (chartWidth / values.length) - 10);
39
+
40
+ return (
41
+ <View style={styles.chartContainer}>
42
+ <Text style={styles.chartTitle}>{title || ''}</Text>
43
+ <ScrollView
44
+ horizontal
45
+ showsHorizontalScrollIndicator={false}
46
+ contentContainerStyle={{ width: chartWidth }}
47
+ >
48
+ <View style={[styles.chart, { height: chartHeight }]}>
49
+ {values.map((value, index) => {
50
+ const height = (value / maxValue) * chartHeight;
51
+ const label = labels[index] || `Item ${index + 1}`;
52
+
53
+ return (
54
+ <View key={index} style={[styles.linePointWrapper, { width: barWidth + 10 }]}>
55
+ <View style={[styles.linePoint, {
56
+ height: Math.max(height, 2),
57
+ width: barWidth
58
+ }]} />
59
+ <View style={styles.lineConnector} />
60
+ <Text style={styles.lineLabel} numberOfLines={1}>{label}</Text>
61
+ <Text style={styles.valueText}>{formatNumber(value)}</Text>
62
+ </View>
63
+ );
64
+ })}
65
+ </View>
66
+ </ScrollView>
67
+ </View>
68
+ );
69
+ };
70
+
71
+ export const renderBarChart = (data, title) => {
72
+ // Extract values and labels from data
73
+ const isArray = Array.isArray(data);
74
+ const values = isArray ? data.map(d => d.revenue || d.value || d.shipments || 0) : (data.values || []);
75
+ const labels = isArray ? data.map(d => d.mode || d.label || '') : (data.labels || []);
76
+
77
+ if (values.length === 0) {
78
+ return (
79
+ <View style={styles.noDataContainer}>
80
+ <Text style={styles.noDataText}>No data available for this report</Text>
81
+ </View>
82
+ );
83
+ }
84
+
85
+ const maxValue = Math.max(...values, 1);
86
+ const chartHeight = 200;
87
+ const chartWidth = Math.max(screenWidth - 64, values.length * 60);
88
+ const barWidth = Math.min(40, Math.max(20, (chartWidth / values.length) - 10));
89
+
90
+ return (
91
+ <View style={styles.chartContainer}>
92
+ <Text style={styles.chartTitle}>{title || ''}</Text>
93
+ <ScrollView
94
+ horizontal
95
+ showsHorizontalScrollIndicator={false}
96
+ contentContainerStyle={{ width: chartWidth }}
97
+ >
98
+ <View style={[styles.chart, { height: chartHeight }]}>
99
+ {values.map((value, index) => {
100
+ const height = (value / maxValue) * chartHeight;
101
+ const label = labels?.[index] || `Item ${index + 1}`;
102
+
103
+ return (
104
+ <View key={index} style={[styles.barWrapper, { width: barWidth + 20 }]}>
105
+ <View style={[styles.bar, {
106
+ height,
107
+ width: barWidth,
108
+ backgroundColor: getColor(index)
109
+ }]} />
110
+ <Text style={styles.barLabel} numberOfLines={1}>{label}</Text>
111
+ <Text style={styles.valueText}>{formatNumber(value)}</Text>
112
+ </View>
113
+ );
114
+ })}
115
+ </View>
116
+ </ScrollView>
117
+ </View>
118
+ );
119
+ };
120
+
121
+ export const renderPieChart = (data, title) => {
122
+ // Ensure data is an array
123
+ const dataArray = Array.isArray(data) ? data : [];
124
+
125
+ if (dataArray.length === 0) {
126
+ return (
127
+ <View style={styles.noDataContainer}>
128
+ <Text style={styles.noDataText}>No data available for this report</Text>
129
+ </View>
130
+ );
131
+ }
132
+
133
+ const total = dataArray.reduce((sum, item) => {
134
+ const value = item.shipments || item.revenue || item.value || 0;
135
+ return sum + value;
136
+ }, 0);
137
+
138
+ return (
139
+ <View style={styles.chartContainer}>
140
+ <Text style={styles.chartTitle}>{title || ''}</Text>
141
+ <View style={styles.pieContainer}>
142
+ {dataArray.map((item, index) => {
143
+ const value = item.shipments || item.revenue || item.value || 0;
144
+ const label = item.direction || item.mode || item.label || `Item ${index + 1}`;
145
+ const percentage = total > 0 ? ((value / total) * 100).toFixed(1) : '0';
146
+
147
+ return (
148
+ <View key={index} style={styles.pieItem}>
149
+ <View style={[styles.pieColor, { backgroundColor: getColor(index) }]} />
150
+ <Text style={styles.pieLabel}>{label}:</Text>
151
+ <Text style={styles.pieValue}>
152
+ {formatNumber(value)} ({percentage}%)
153
+ </Text>
154
+ </View>
155
+ );
156
+ })}
157
+ </View>
158
+ {total > 0 && (
159
+ <Text style={styles.totalText}>Total: {formatNumber(total)}</Text>
160
+ )}
161
+ </View>
162
+ );
163
+ };
164
+
165
+ // Additional chart renderer for Revenue Trend (line chart with different style)
166
+ export const renderRevenueTrendChart = (data, title) => {
167
+ // Handle different data formats
168
+ let values = [];
169
+ let labels = [];
170
+
171
+ if (data.values && data.labels) {
172
+ values = data.values;
173
+ labels = data.labels;
174
+ } else if (Array.isArray(data)) {
175
+ values = data.map(d => d.revenue || d.value || 0);
176
+ labels = data.map(d => d.month || d.label || '');
177
+ }
178
+
179
+ if (values.length === 0) {
180
+ return (
181
+ <View style={styles.noDataContainer}>
182
+ <Text style={styles.noDataText}>No data available for this report</Text>
183
+ </View>
184
+ );
185
+ }
186
+
187
+ const maxValue = Math.max(...values, 1);
188
+ const chartHeight = 200;
189
+ const chartWidth = Math.max(screenWidth - 64, values.length * 80);
190
+ const pointWidth = 8;
191
+
192
+ return (
193
+ <View style={styles.chartContainer}>
194
+ <Text style={styles.chartTitle}>{title || 'Revenue Trend'}</Text>
195
+ <ScrollView
196
+ horizontal
197
+ showsHorizontalScrollIndicator={false}
198
+ contentContainerStyle={{ width: chartWidth }}
199
+ >
200
+ <View style={[styles.chart, { height: chartHeight, justifyContent: 'space-around' }]}>
201
+ {values.map((value, index) => {
202
+ const height = (value / maxValue) * chartHeight;
203
+ const label = labels[index] || `Period ${index + 1}`;
204
+
205
+ return (
206
+ <View key={index} style={styles.trendPointWrapper}>
207
+ <View style={styles.trendValueContainer}>
208
+ <Text style={styles.trendValueText}>{formatNumber(value)}</Text>
209
+ </View>
210
+ <View style={[styles.trendPoint, {
211
+ height: Math.max(height, 2),
212
+ width: pointWidth,
213
+ backgroundColor: '#4CAF50'
214
+ }]} />
215
+ <View style={styles.trendLine} />
216
+ <Text style={styles.trendLabel} numberOfLines={1}>{label}</Text>
217
+ </View>
218
+ );
219
+ })}
220
+ </View>
221
+ </ScrollView>
222
+ </View>
223
+ );
224
+ };
225
+
226
+ const styles = StyleSheet.create({
227
+ chartContainer: {
228
+ backgroundColor: '#fff',
229
+ borderRadius: 12,
230
+ padding: 16,
231
+ marginBottom: 16,
232
+ borderWidth: 1,
233
+ borderColor: '#e8e8e8',
234
+ shadowColor: '#000',
235
+ shadowOffset: { width: 0, height: 1 },
236
+ shadowOpacity: 0.05,
237
+ shadowRadius: 2,
238
+ elevation: 2,
239
+ },
240
+ chartTitle: {
241
+ fontSize: 18,
242
+ fontWeight: '700',
243
+ color: '#000',
244
+ marginBottom: 20,
245
+ textAlign: 'center',
246
+ },
247
+ chart: {
248
+ flexDirection: 'row',
249
+ alignItems: 'flex-end',
250
+ paddingHorizontal: 8,
251
+ },
252
+ barWrapper: {
253
+ alignItems: 'center',
254
+ marginHorizontal: 4,
255
+ },
256
+ bar: {
257
+ borderRadius: 4,
258
+ },
259
+ barLabel: {
260
+ marginTop: 8,
261
+ fontSize: 11,
262
+ color: '#666',
263
+ textAlign: 'center',
264
+ width: 60,
265
+ },
266
+ linePointWrapper: {
267
+ alignItems: 'center',
268
+ marginHorizontal: 4,
269
+ },
270
+ linePoint: {
271
+ backgroundColor: '#2196F3',
272
+ borderRadius: 2,
273
+ },
274
+ lineConnector: {
275
+ width: 2,
276
+ backgroundColor: '#2196F3',
277
+ opacity: 0.3,
278
+ marginVertical: 2,
279
+ flex: 1,
280
+ minHeight: 20,
281
+ },
282
+ lineLabel: {
283
+ marginTop: 8,
284
+ fontSize: 11,
285
+ color: '#666',
286
+ textAlign: 'center',
287
+ width: 60,
288
+ },
289
+ trendPointWrapper: {
290
+ alignItems: 'center',
291
+ marginHorizontal: 12,
292
+ },
293
+ trendPoint: {
294
+ borderRadius: 4,
295
+ },
296
+ trendLine: {
297
+ width: 2,
298
+ backgroundColor: '#4CAF50',
299
+ opacity: 0.5,
300
+ marginVertical: 2,
301
+ flex: 1,
302
+ minHeight: 20,
303
+ },
304
+ trendLabel: {
305
+ marginTop: 8,
306
+ fontSize: 11,
307
+ color: '#666',
308
+ textAlign: 'center',
309
+ width: 80,
310
+ },
311
+ trendValueContainer: {
312
+ backgroundColor: 'rgba(76, 175, 80, 0.1)',
313
+ paddingHorizontal: 6,
314
+ paddingVertical: 2,
315
+ borderRadius: 4,
316
+ marginBottom: 4,
317
+ },
318
+ trendValueText: {
319
+ fontSize: 10,
320
+ color: '#4CAF50',
321
+ fontWeight: '600',
322
+ },
323
+ valueText: {
324
+ fontSize: 10,
325
+ color: '#999',
326
+ marginTop: 4,
327
+ fontWeight: '500',
328
+ },
329
+ pieContainer: {
330
+ padding: 10,
331
+ },
332
+ pieItem: {
333
+ flexDirection: 'row',
334
+ alignItems: 'center',
335
+ marginBottom: 12,
336
+ padding: 8,
337
+ backgroundColor: '#f9f9f9',
338
+ borderRadius: 8,
339
+ },
340
+ pieColor: {
341
+ width: 16,
342
+ height: 16,
343
+ borderRadius: 8,
344
+ marginRight: 12,
345
+ },
346
+ pieLabel: {
347
+ fontSize: 15,
348
+ fontWeight: '600',
349
+ color: '#000',
350
+ flex: 1,
351
+ },
352
+ pieValue: {
353
+ fontSize: 14,
354
+ color: '#666',
355
+ fontWeight: '500',
356
+ },
357
+ totalText: {
358
+ fontSize: 16,
359
+ fontWeight: '700',
360
+ color: '#4CAF50',
361
+ textAlign: 'center',
362
+ marginTop: 16,
363
+ paddingTop: 16,
364
+ borderTopWidth: 1,
365
+ borderTopColor: '#eee',
366
+ },
367
+ noDataContainer: {
368
+ padding: 40,
369
+ alignItems: 'center',
370
+ justifyContent: 'center',
371
+ minHeight: 200,
372
+ },
373
+ noDataText: {
374
+ fontSize: 16,
375
+ color: '#999',
376
+ textAlign: 'center',
377
+ fontStyle: 'italic',
378
+ },
379
+ });
380
+
381
+ export default {
382
+ renderLineChart,
383
+ renderBarChart,
384
+ renderPieChart,
385
+ renderRevenueTrendChart,
386
+ getColor,
387
+ formatNumber
388
+ };
@@ -0,0 +1,135 @@
1
+ import React from 'react';
2
+ import {
3
+ View,
4
+ Text,
5
+ StyleSheet,
6
+ TouchableOpacity,
7
+ ScrollView,
8
+ } from 'react-native';
9
+
10
+ const ReportList = ({ reports, onReportClick, getColor }) => {
11
+ // Default reports if none provided
12
+ const defaultReports = [
13
+ {
14
+ id: 1,
15
+ name: 'Performance Report',
16
+ title: 'PERFORMANS RAPORU (USD)',
17
+ type: 'table',
18
+ description: 'Fallyet Kar/Zarar tablosu - Varsayılan Görünüm'
19
+ },
20
+ {
21
+ id: 1.1,
22
+ name: 'Performance Report A',
23
+ title: 'PERFORMANS RAPORU (USD)',
24
+ type: 'table',
25
+ description: 'Fallyet Kar/Zarar tablosu - Kompakt Görünüm'
26
+ },
27
+ {
28
+ id: 1.2,
29
+ name: 'Performance Report B',
30
+ title: 'PERFORMANS RAPORU (USD)',
31
+ type: 'table',
32
+ description: 'Fallyet Kar/Zarar tablosu - Sabit Kolonlu Görünüm'
33
+ },
34
+ {
35
+ id: 2,
36
+ name: 'Revenue by Mode',
37
+ title: 'Revenue by Mode',
38
+ type: 'bar',
39
+ description: 'Revenue distribution across modes'
40
+ },
41
+ {
42
+ id: 3,
43
+ name: 'Shipment by Direction',
44
+ title: 'Shipment by Direction',
45
+ type: 'pie',
46
+ description: 'Shipment direction analysis'
47
+ },
48
+ ];
49
+
50
+ const reportList = reports.length > 0 ? reports : defaultReports;
51
+
52
+ return (
53
+ <ScrollView style={styles.reportsList}>
54
+ {reportList.map((report) => (
55
+ <TouchableOpacity
56
+ key={report.id}
57
+ style={styles.reportCard}
58
+ onPress={() => onReportClick(report)}
59
+ >
60
+ <View style={[styles.reportIcon, { backgroundColor: getColor(report.id) }]}>
61
+ <Text style={styles.reportIconText}>{report.id}</Text>
62
+ </View>
63
+ <View style={styles.reportInfo}>
64
+ <Text style={styles.reportName}>{report.name}</Text>
65
+ <Text style={styles.reportTitle}>{report.title}</Text>
66
+ <Text style={styles.reportDesc}>{report.description}</Text>
67
+ </View>
68
+ <Text style={styles.arrow}>›</Text>
69
+ </TouchableOpacity>
70
+ ))}
71
+ </ScrollView>
72
+ );
73
+ };
74
+
75
+ const styles = StyleSheet.create({
76
+ reportsList: {
77
+ flex: 1,
78
+ padding: 16,
79
+ },
80
+ reportCard: {
81
+ flexDirection: 'row',
82
+ alignItems: 'center',
83
+ backgroundColor: '#fff',
84
+ borderRadius: 12,
85
+ padding: 16,
86
+ marginBottom: 12,
87
+ borderWidth: 1,
88
+ borderColor: '#e8e8e8',
89
+ shadowColor: '#000',
90
+ shadowOffset: { width: 0, height: 1 },
91
+ shadowOpacity: 0.05,
92
+ shadowRadius: 2,
93
+ elevation: 2,
94
+ },
95
+ reportIcon: {
96
+ width: 44,
97
+ height: 44,
98
+ borderRadius: 22,
99
+ justifyContent: 'center',
100
+ alignItems: 'center',
101
+ marginRight: 12,
102
+ },
103
+ reportIconText: {
104
+ fontSize: 18,
105
+ fontWeight: '700',
106
+ color: '#fff',
107
+ },
108
+ reportInfo: {
109
+ flex: 1,
110
+ },
111
+ reportName: {
112
+ fontSize: 16,
113
+ fontWeight: '600',
114
+ color: '#000',
115
+ marginBottom: 2,
116
+ },
117
+ reportTitle: {
118
+ fontSize: 14,
119
+ fontWeight: '500',
120
+ color: '#4CAF50',
121
+ marginBottom: 4,
122
+ },
123
+ reportDesc: {
124
+ fontSize: 13,
125
+ color: '#666',
126
+ lineHeight: 18,
127
+ },
128
+ arrow: {
129
+ fontSize: 24,
130
+ color: '#ccc',
131
+ fontWeight: '300',
132
+ },
133
+ });
134
+
135
+ export default ReportList;
@@ -0,0 +1,93 @@
1
+ import React from 'react';
2
+ import {
3
+ View,
4
+ Text,
5
+ StyleSheet,
6
+ TouchableOpacity,
7
+ ScrollView,
8
+ } from 'react-native';
9
+
10
+ const ReportView = ({ reportData, viewType, onBack, onClose }) => {
11
+ if (!reportData) {
12
+ return (
13
+ <View style={styles.container}>
14
+ <Text style={styles.noDataText}>No report data available</Text>
15
+ </View>
16
+ );
17
+ }
18
+
19
+ return (
20
+ <View style={styles.container}>
21
+ <View style={styles.header}>
22
+ <TouchableOpacity style={styles.backButton} onPress={onBack}>
23
+ <Text style={styles.backText}>‹ Back</Text>
24
+ </TouchableOpacity>
25
+ <Text style={styles.headerTitle}>{reportData.title}</Text>
26
+ <TouchableOpacity style={styles.closeButton} onPress={onClose}>
27
+ <Text style={styles.closeText}>×</Text>
28
+ </TouchableOpacity>
29
+ </View>
30
+
31
+ <ScrollView style={styles.content}>
32
+ {/* Report content will be rendered here by parent component */}
33
+ </ScrollView>
34
+ </View>
35
+ );
36
+ };
37
+
38
+ const styles = StyleSheet.create({
39
+ container: {
40
+ flex: 1,
41
+ backgroundColor: '#f8f9fa',
42
+ },
43
+ header: {
44
+ flexDirection: 'row',
45
+ alignItems: 'center',
46
+ justifyContent: 'space-between',
47
+ backgroundColor: '#fff',
48
+ paddingHorizontal: 16,
49
+ paddingVertical: 12,
50
+ borderBottomWidth: 1,
51
+ borderBottomColor: '#e0e0e0',
52
+ },
53
+ headerTitle: {
54
+ fontSize: 18,
55
+ fontWeight: '700',
56
+ color: '#000',
57
+ flex: 1,
58
+ textAlign: 'center',
59
+ },
60
+ backButton: {
61
+ padding: 8,
62
+ },
63
+ backText: {
64
+ fontSize: 16,
65
+ color: '#4CAF50',
66
+ fontWeight: '600',
67
+ },
68
+ closeButton: {
69
+ width: 32,
70
+ height: 32,
71
+ borderRadius: 16,
72
+ backgroundColor: '#f0f0f0',
73
+ justifyContent: 'center',
74
+ alignItems: 'center',
75
+ },
76
+ closeText: {
77
+ fontSize: 20,
78
+ color: '#666',
79
+ fontWeight: '300',
80
+ },
81
+ content: {
82
+ flex: 1,
83
+ padding: 16,
84
+ },
85
+ noDataText: {
86
+ fontSize: 16,
87
+ color: '#999',
88
+ textAlign: 'center',
89
+ padding: 40,
90
+ },
91
+ });
92
+
93
+ export default ReportView;