@dhiraj0720/report1chart 2.5.8 → 2.5.9

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.5.8",
3
+ "version": "2.5.9",
4
4
  "main": "src/index.jsx",
5
5
  "scripts": {
6
6
  "test": "echo 'No tests'"
@@ -1,5 +1,13 @@
1
+ // src/screens/Report2AScreen.jsx
1
2
  import React, { useEffect, useState } from 'react';
2
- import { ScrollView, Text, TouchableOpacity, View } from 'react-native';
3
+ import {
4
+ ScrollView,
5
+ Text,
6
+ TouchableOpacity,
7
+ View,
8
+ ActivityIndicator,
9
+ StyleSheet,
10
+ } from 'react-native';
3
11
  import { filterChartByMonths } from '../utils/filterChartByMonths';
4
12
  import { getDivisions, getTable, getLine, getBar } from '../api/report2Fetcher';
5
13
  import MonthFilterModal from '../components/MonthFilterModal';
@@ -20,33 +28,92 @@ const Report2AScreen = ({ api, token, onBack }) => {
20
28
  const [table, setTable] = useState(null);
21
29
  const [line, setLine] = useState(null);
22
30
  const [bar, setBar] = useState(null);
31
+ const [loading, setLoading] = useState(true);
32
+ const [error, setError] = useState(null);
23
33
 
34
+ // Fetch divisions
24
35
  useEffect(() => {
25
- getDivisions(api.divisions, token).then(d => {
26
- setDivisions(d);
27
- if (d.length > 0) setDivision(d[0]?.code);
28
- });
29
- }, [api.divisions, token]);
30
-
36
+ if (!api?.divisions || !token) return;
37
+
38
+ getDivisions(api.divisions, token)
39
+ .then((d) => {
40
+ setDivisions(d);
41
+ if (d.length > 0) {
42
+ setDivision(d[0].code);
43
+ }
44
+ })
45
+ .catch((err) => {
46
+ console.error('Failed to load divisions:', err);
47
+ setError('Failed to load divisions');
48
+ setLoading(false);
49
+ });
50
+ }, [api?.divisions, token]);
51
+
52
+ // Fetch data when division changes
31
53
  useEffect(() => {
32
- if (!division) return;
54
+ if (!division || !api || !token) return;
55
+
56
+ setLoading(true);
57
+ setError(null);
33
58
 
34
59
  Promise.all([
35
- getTable(api.table, division, token),
36
- getLine(api.line, division, token),
37
- getBar(api.bar, division, token),
38
- ]).then(([t, l, b]) => {
39
- setTable(t);
40
- setLine(l);
41
- setBar(b);
42
- setMonths(l.labels);
43
- setSelectedMonths(l.labels); // default: all selected
44
- });
60
+ getTable(api.table, division, token).catch(() => null),
61
+ getLine(api.line, division, token).catch(() => null),
62
+ getBar(api.bar, division, token).catch(() => null),
63
+ ])
64
+ .then(([t, l, b]) => {
65
+ if (!t || !l || !b) {
66
+ setError('Failed to load report data');
67
+ return;
68
+ }
69
+
70
+ setTable(t);
71
+ setLine(l);
72
+ setBar(b);
73
+ setMonths(l.labels || []);
74
+ setSelectedMonths(l.labels || []);
75
+ })
76
+ .catch((err) => {
77
+ console.error('Data fetch error:', err);
78
+ setError('Network error or data unavailable');
79
+ })
80
+ .finally(() => {
81
+ setLoading(false);
82
+ });
45
83
  }, [division, api, token]);
46
84
 
47
- if (!table || !line || !bar || !division) return null;
85
+ // Loading State
86
+ if (loading) {
87
+ return (
88
+ <View style={styles.center}>
89
+ <ActivityIndicator size="large" color="#1e88e5" />
90
+ <Text style={styles.loadingText}>Loading Report 2A...</Text>
91
+ </View>
92
+ );
93
+ }
94
+
95
+ // Error State
96
+ if (error) {
97
+ return (
98
+ <View style={styles.center}>
99
+ <Text style={styles.errorText}>{error}</Text>
100
+ <TouchableOpacity onPress={onBack}>
101
+ <Text style={styles.backLink}>← Go Back</Text>
102
+ </TouchableOpacity>
103
+ </View>
104
+ );
105
+ }
106
+
107
+ // Safety check
108
+ if (!table || !line || !bar || !division) {
109
+ return (
110
+ <View style={styles.center}>
111
+ <Text>No data available</Text>
112
+ </View>
113
+ );
114
+ }
48
115
 
49
- const filteredRows = table.rows.filter(r =>
116
+ const filteredRows = table.rows.filter((r) =>
50
117
  selectedMonths.includes(r.monthLabel)
51
118
  );
52
119
 
@@ -54,36 +121,42 @@ const Report2AScreen = ({ api, token, onBack }) => {
54
121
  const filteredBar = filterChartByMonths(bar, selectedMonths);
55
122
 
56
123
  return (
57
- <ScrollView style={{ padding: 12 }}>
58
- <Text onPress={onBack} style={{ fontSize: 18, marginBottom: 12 }}>
124
+ <ScrollView style={styles.container}>
125
+ {/* Header */}
126
+ <Text onPress={onBack} style={styles.backButton}>
59
127
  ‹ Back
60
128
  </Text>
61
129
 
62
- {/* FILTER BUTTONS */}
63
- <View style={{ flexDirection: 'row', marginVertical: 10, gap: 16 }}>
130
+ {/* Filters */}
131
+ <View style={styles.filterRow}>
64
132
  <TouchableOpacity onPress={() => setMonthsModal(true)}>
65
- <Text style={{ fontSize: 16, color: '#1e88e5' }}>Months ⛃</Text>
133
+ <Text style={styles.filterText}>Months ⛃</Text>
66
134
  </TouchableOpacity>
67
135
 
68
- <TouchableOpacity onPress={() => setDivisionModal(true)}>
69
- <Text style={{ fontSize: 16, color: '#1e88e5' }}>Divisions ⛃</Text>
136
+ <TouchableOpacity
137
+ onPress={() => setDivisionModal(true)}
138
+ style={{ marginLeft: 20 }}
139
+ >
140
+ <Text style={styles.filterText}>
141
+ Division: {divisions.find((d) => d.code === division)?.displayName || division}
142
+ </Text>
70
143
  </TouchableOpacity>
71
144
  </View>
72
145
 
73
- {/* TABLE */}
146
+ {/* Table */}
74
147
  <FrozenTableReport2A rows={filteredRows} />
75
148
 
76
- {/* LINE CHART */}
77
- <View style={{ borderWidth: 1, borderColor: '#ddd', borderRadius: 8, marginVertical: 12 }}>
149
+ {/* Line Chart */}
150
+ <View style={styles.chartContainer}>
78
151
  <SvgLineChartCompact data={filteredLine} />
79
152
  </View>
80
153
 
81
- {/* BAR + LINE CHART */}
82
- <View style={{ borderWidth: 1, borderColor: '#ddd', borderRadius: 8, marginVertical: 12 }}>
154
+ {/* Bar + Budget Chart */}
155
+ <View style={styles.chartContainer}>
83
156
  <SvgBarLineChartCompact data={filteredBar} />
84
157
  </View>
85
158
 
86
- {/* MODALS */}
159
+ {/* Modals */}
87
160
  <MonthFilterModal
88
161
  visible={monthsModal}
89
162
  months={months}
@@ -103,4 +176,54 @@ const Report2AScreen = ({ api, token, onBack }) => {
103
176
  );
104
177
  };
105
178
 
179
+ const styles = StyleSheet.create({
180
+ container: { padding: 12, backgroundColor: '#f8f9fa' },
181
+ center: {
182
+ flex: 1,
183
+ justifyContent: 'center',
184
+ alignItems: 'center',
185
+ padding: 20,
186
+ },
187
+ loadingText: {
188
+ marginTop: 12,
189
+ fontSize: 16,
190
+ color: '#555',
191
+ },
192
+ errorText: {
193
+ fontSize: 16,
194
+ color: '#d32f2f',
195
+ textAlign: 'center',
196
+ marginBottom: 20,
197
+ },
198
+ backLink: {
199
+ fontSize: 18,
200
+ color: '#1e88e5',
201
+ fontWeight: '600',
202
+ },
203
+ backButton: {
204
+ fontSize: 20,
205
+ color: '#1e88e5',
206
+ marginBottom: 16,
207
+ fontWeight: '600',
208
+ },
209
+ filterRow: {
210
+ flexDirection: 'row',
211
+ alignItems: 'center',
212
+ marginVertical: 12,
213
+ },
214
+ filterText: {
215
+ fontSize: 16,
216
+ color: '#1e88e5',
217
+ fontWeight: '600',
218
+ },
219
+ chartContainer: {
220
+ borderWidth: 1,
221
+ borderColor: '#ddd',
222
+ borderRadius: 10,
223
+ overflow: 'hidden',
224
+ marginVertical: 12,
225
+ backgroundColor: '#fff',
226
+ },
227
+ });
228
+
106
229
  export default Report2AScreen;