@dhiraj0720/report1chart 2.2.3 → 2.2.4

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.3",
3
+ "version": "2.2.4",
4
4
  "main": "src/index.jsx",
5
5
  "scripts": {
6
6
  "test": "echo 'No tests'"
@@ -0,0 +1,27 @@
1
+ import axios from 'axios';
2
+
3
+ const fetchReport1 = async (apiEndpoint, apiToken) => {
4
+ try {
5
+ const response = await axios.get(apiEndpoint, {
6
+ headers: {
7
+ Authorization: apiToken,
8
+ Accept: 'application/json',
9
+ },
10
+ timeout: 15000,
11
+ });
12
+
13
+ if (!response.data || !response.data.rows) {
14
+ throw new Error('Invalid API response');
15
+ }
16
+
17
+ return response.data.rows;
18
+ } catch (error) {
19
+ throw new Error(
20
+ error?.response?.data?.message ||
21
+ error.message ||
22
+ 'Failed to fetch report'
23
+ );
24
+ }
25
+ };
26
+
27
+ export default fetchReport1;
@@ -0,0 +1,27 @@
1
+ import React from 'react';
2
+ import { View, StyleSheet } from 'react-native';
3
+
4
+ const ProgressBar = ({ value }) => {
5
+ const width = Math.min(Math.max(value || 0, 0), 100);
6
+
7
+ return (
8
+ <View style={styles.track}>
9
+ <View style={[styles.fill, { width: `${width}%` }]} />
10
+ </View>
11
+ );
12
+ };
13
+
14
+ export default ProgressBar;
15
+
16
+ const styles = StyleSheet.create({
17
+ track: {
18
+ height: 6,
19
+ backgroundColor: '#e0e0e0',
20
+ borderRadius: 4,
21
+ overflow: 'hidden',
22
+ },
23
+ fill: {
24
+ height: '100%',
25
+ backgroundColor: '#f57c00',
26
+ },
27
+ });
@@ -0,0 +1,99 @@
1
+ import React from 'react';
2
+ import { View, Text, StyleSheet } from 'react-native';
3
+ import ProgressBar from './ProgressBar';
4
+
5
+ const format = (num) => (num ?? 0).toLocaleString();
6
+
7
+ const Trend = ({ value }) => {
8
+ const positive = value >= 0;
9
+ return (
10
+ <Text style={[styles.trend, positive ? styles.up : styles.down]}>
11
+ {positive ? '↑' : '↓'} {Math.abs(value)}%
12
+ </Text>
13
+ );
14
+ };
15
+
16
+ const Report1Card = ({ item }) => {
17
+ return (
18
+ <View style={styles.card}>
19
+ <Text style={styles.title}>{item.name}</Text>
20
+
21
+ <Row label="2024 Actual" value={format(item.actual2024)} />
22
+ <Row label="2025 Actual" value={format(item.actual2025)} />
23
+
24
+ <View style={styles.row}>
25
+ <Text style={styles.label}>Change YoY</Text>
26
+ <Trend value={item.actualChangePercent} />
27
+ </View>
28
+
29
+ <Row label="2025 Budget" value={format(item.budget2025)} />
30
+
31
+ <View style={styles.row}>
32
+ <Text style={styles.label}>Budget Variance</Text>
33
+ <Trend value={item.budgetVariancePercent} />
34
+ </View>
35
+
36
+ {item.opexToGrossProfitPercent !== undefined && (
37
+ <>
38
+ <View style={styles.row}>
39
+ <Text style={styles.label}>OPEX / Gross Profit</Text>
40
+ <Text style={styles.value}>
41
+ {item.opexToGrossProfitPercent}%
42
+ </Text>
43
+ </View>
44
+ <ProgressBar value={item.opexToGrossProfitPercent} />
45
+ </>
46
+ )}
47
+ </View>
48
+ );
49
+ };
50
+
51
+ const Row = ({ label, value }) => (
52
+ <View style={styles.row}>
53
+ <Text style={styles.label}>{label}</Text>
54
+ <Text style={styles.value}>{value}</Text>
55
+ </View>
56
+ );
57
+
58
+ export default Report1Card;
59
+
60
+ const styles = StyleSheet.create({
61
+ card: {
62
+ backgroundColor: '#fff',
63
+ borderRadius: 12,
64
+ padding: 16,
65
+ marginBottom: 12,
66
+ borderWidth: 1,
67
+ borderColor: '#e0e0e0',
68
+ },
69
+ title: {
70
+ fontSize: 16,
71
+ fontWeight: '700',
72
+ marginBottom: 12,
73
+ color: '#000',
74
+ },
75
+ row: {
76
+ flexDirection: 'row',
77
+ justifyContent: 'space-between',
78
+ marginBottom: 6,
79
+ },
80
+ label: {
81
+ fontSize: 13,
82
+ color: '#666',
83
+ },
84
+ value: {
85
+ fontSize: 13,
86
+ fontWeight: '600',
87
+ color: '#000',
88
+ },
89
+ trend: {
90
+ fontSize: 13,
91
+ fontWeight: '700',
92
+ },
93
+ up: {
94
+ color: '#2e7d32',
95
+ },
96
+ down: {
97
+ color: '#d32f2f',
98
+ },
99
+ });
package/src/index.jsx CHANGED
@@ -1,18 +1,3 @@
1
- import React from 'react';
2
- import ReportScreen from './screens/ReportScreen';
1
+ import Report1Screen from './screens/Report1Screen';
3
2
 
4
- const ReportChart = ({
5
- onReportSelect,
6
- onClose,
7
- reports = []
8
- }) => {
9
- return (
10
- <ReportScreen
11
- reports={reports}
12
- onReportSelect={onReportSelect}
13
- onClose={onClose}
14
- />
15
- );
16
- };
17
-
18
- export default ReportChart;
3
+ export default Report1Screen;
@@ -0,0 +1,80 @@
1
+ import React, { useEffect, useState } from 'react';
2
+ import {
3
+ View,
4
+ Text,
5
+ ScrollView,
6
+ ActivityIndicator,
7
+ StyleSheet,
8
+ } from 'react-native';
9
+ import fetchReport1 from '../api/report1Fetcher';
10
+ import Report1Card from '../components/Report1Card';
11
+
12
+ const Report1Screen = ({ apiEndpoint, apiToken }) => {
13
+ const [loading, setLoading] = useState(true);
14
+ const [error, setError] = useState(null);
15
+ const [rows, setRows] = useState([]);
16
+
17
+ useEffect(() => {
18
+ const loadData = async () => {
19
+ try {
20
+ const data = await fetchReport1(apiEndpoint, apiToken);
21
+ setRows(data);
22
+ } catch (e) {
23
+ setError(e.message);
24
+ } finally {
25
+ setLoading(false);
26
+ }
27
+ };
28
+
29
+ loadData();
30
+ }, [apiEndpoint, apiToken]);
31
+
32
+ if (loading) {
33
+ return (
34
+ <View style={styles.center}>
35
+ <ActivityIndicator size="large" />
36
+ <Text style={styles.info}>Loading report...</Text>
37
+ </View>
38
+ );
39
+ }
40
+
41
+ if (error) {
42
+ return (
43
+ <View style={styles.center}>
44
+ <Text style={styles.error}>{error}</Text>
45
+ </View>
46
+ );
47
+ }
48
+
49
+ return (
50
+ <ScrollView style={styles.container}>
51
+ {rows.map((item, index) => (
52
+ <Report1Card key={index} item={item} />
53
+ ))}
54
+ </ScrollView>
55
+ );
56
+ };
57
+
58
+ export default Report1Screen;
59
+
60
+ const styles = StyleSheet.create({
61
+ container: {
62
+ backgroundColor: '#f5f5f5',
63
+ padding: 16,
64
+ },
65
+ center: {
66
+ flex: 1,
67
+ justifyContent: 'center',
68
+ alignItems: 'center',
69
+ padding: 20,
70
+ },
71
+ info: {
72
+ marginTop: 12,
73
+ color: '#666',
74
+ },
75
+ error: {
76
+ fontSize: 16,
77
+ color: '#d32f2f',
78
+ textAlign: 'center',
79
+ },
80
+ });
@@ -1,70 +0,0 @@
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
- }