@dhiraj0720/report1chart 2.6.0 → 2.6.2

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.6.0",
3
+ "version": "2.6.2",
4
4
  "main": "src/index.jsx",
5
5
  "scripts": {
6
6
  "test": "echo 'No tests'"
@@ -1,42 +1,33 @@
1
1
  import React from 'react';
2
- import { View, Text, ScrollView, StyleSheet } from 'react-native';
2
+ import { View, Text, ScrollView, StyleSheet, Dimensions } from 'react-native';
3
+
4
+ const { width, height } = Dimensions.get('window');
3
5
 
4
6
  const Arrow = ({ value }) => (
5
- <Text
6
- style={[
7
- styles.arrow,
8
- value >= 0 ? styles.up : styles.down,
9
- ]}
10
- >
7
+ <Text style={[styles.arrow, value >= 0 ? styles.up : styles.down]}>
11
8
  {value >= 0 ? '↑' : '↓'} {Math.abs(value)}%
12
9
  </Text>
13
10
  );
14
11
 
15
12
  const Cell = ({ children, bold, frozen }) => (
16
- <View
17
- style={[
18
- styles.cell,
19
- frozen && styles.frozenCell,
20
- ]}
21
- >
22
- <Text
23
- numberOfLines={1}
24
- ellipsizeMode="tail"
25
- style={[
26
- styles.text,
27
- bold && styles.bold,
28
- ]}
29
- >
13
+ <View style={[styles.cell, frozen && styles.frozenCell]}>
14
+ <Text style={[styles.text, bold && styles.bold]} numberOfLines={1}>
30
15
  {children}
31
16
  </Text>
32
17
  </View>
33
18
  );
34
19
 
35
- const FrozenTableReport1A = ({ rows }) => {
20
+ const FrozenTableReport1A = ({ rows, isFullscreen = false }) => {
21
+ const isLandscape = width > height;
22
+
23
+ // Auto-adjust cell width in fullscreen landscape
24
+ const cellWidth = isFullscreen && isLandscape ? 160 : 110;
25
+ const frozenWidth = isFullscreen && isLandscape ? 200 : 150;
26
+ const fontSize = isFullscreen ? 14 : 12;
27
+
36
28
  return (
37
29
  <View style={styles.container}>
38
- {/* LEFT FROZEN COLUMN */}
39
- <View style={styles.frozen}>
30
+ <View style={[styles.frozen, { width: frozenWidth }]}>
40
31
  <Cell bold frozen>FAALİYET</Cell>
41
32
  {rows.map((r, i) => (
42
33
  <Cell key={i} frozen bold>
@@ -45,7 +36,6 @@ const FrozenTableReport1A = ({ rows }) => {
45
36
  ))}
46
37
  </View>
47
38
 
48
- {/* SCROLLABLE COLUMNS */}
49
39
  <ScrollView horizontal showsHorizontalScrollIndicator={false}>
50
40
  <View>
51
41
  <View style={styles.headerRow}>
@@ -58,10 +48,10 @@ const FrozenTableReport1A = ({ rows }) => {
58
48
 
59
49
  {rows.map((r, i) => (
60
50
  <View key={i} style={styles.row}>
61
- <Cell>{r.actual2024}</Cell>
62
- <Cell>{r.actual2025}</Cell>
51
+ <Cell>{r.actual2024?.toLocaleString()}</Cell>
52
+ <Cell>{r.actual2025?.toLocaleString()}</Cell>
63
53
  <Cell><Arrow value={r.actualChangePercent} /></Cell>
64
- <Cell>{r.budget2025}</Cell>
54
+ <Cell>{r.budget2025?.toLocaleString()}</Cell>
65
55
  <Cell><Arrow value={r.budgetVariancePercent} /></Cell>
66
56
  </View>
67
57
  ))}
@@ -71,11 +61,6 @@ const FrozenTableReport1A = ({ rows }) => {
71
61
  );
72
62
  };
73
63
 
74
- export default FrozenTableReport1A;
75
-
76
- /* ======================
77
- STYLES (COMPACT)
78
- ====================== */
79
64
  const styles = StyleSheet.create({
80
65
  container: {
81
66
  flexDirection: 'row',
@@ -85,55 +70,24 @@ const styles = StyleSheet.create({
85
70
  overflow: 'hidden',
86
71
  backgroundColor: '#fff',
87
72
  },
88
-
89
- frozen: {
90
- width: 150, // 👈 fixed width
91
- backgroundColor: '#f5f7fa',
92
- },
93
-
94
- frozenCell: {
95
- alignItems: 'flex-start',
96
- paddingHorizontal: 8,
97
- },
98
-
99
- headerRow: {
100
- flexDirection: 'row',
101
- backgroundColor: '#f0f0f0',
102
- },
103
-
104
- row: {
105
- flexDirection: 'row',
106
- },
107
-
73
+ frozen: { backgroundColor: '#f5f7fa' },
74
+ frozenCell: { alignItems: 'flex-start', paddingHorizontal: 10 },
75
+ headerRow: { flexDirection: 'row', backgroundColor: '#f0f0f0' },
76
+ row: { flexDirection: 'row' },
108
77
  cell: {
109
- width: 110, // 👈 compact width
110
- paddingVertical: 6, // 👈 reduced height
78
+ width: 110,
79
+ paddingVertical: 8,
111
80
  paddingHorizontal: 6,
112
81
  borderBottomWidth: 1,
113
82
  borderColor: '#eee',
114
83
  justifyContent: 'center',
115
84
  alignItems: 'center',
116
85
  },
117
-
118
- text: {
119
- fontSize: 12, // 👈 smaller text
120
- color: '#222',
121
- },
122
-
123
- bold: {
124
- fontWeight: '700',
125
- },
126
-
127
- arrow: {
128
- fontSize: 12,
129
- fontWeight: '700',
130
- },
131
-
132
- up: {
133
- color: '#2e7d32',
134
- },
135
-
136
- down: {
137
- color: '#d32f2f',
138
- },
86
+ text: { fontSize: 12, color: '#222' },
87
+ bold: { fontWeight: '700' },
88
+ arrow: { fontSize: 12, fontWeight: '700' },
89
+ up: { color: '#2e7d32' },
90
+ down: { color: '#d32f2f' },
139
91
  });
92
+
93
+ export default FrozenTableReport1A;
@@ -0,0 +1,170 @@
1
+ import React from 'react';
2
+ import { View, Text, ScrollView, StyleSheet } from 'react-native';
3
+
4
+ // Format numbers with commas: 556000000 → 556,000,000
5
+ const formatNumber = (value) => {
6
+ if (value === null || value === undefined || value === '') return '-';
7
+ return Number(value).toLocaleString('en-US');
8
+ };
9
+
10
+ // Percentage cell with arrow and color
11
+ const PercentCell = ({ value }) => {
12
+ if (value === null || value === undefined) return <Text>-</Text>;
13
+ const positive = value >= 0;
14
+ return (
15
+ <Text style={[
16
+ styles.percentText,
17
+ { color: positive ? '#2e7d32' : '#d32f2f' }
18
+ ]}>
19
+ {positive ? '↑' : '↓'} {Math.abs(value)}%
20
+ </Text>
21
+ );
22
+ };
23
+
24
+ // Reusable Cell Component
25
+ const Cell = ({ children, bold = false, highlight = false }) => (
26
+ <View style={[
27
+ styles.cell,
28
+ bold && styles.boldCell,
29
+ highlight && styles.highlightCell
30
+ ]}>
31
+ <Text style={[
32
+ styles.cellText,
33
+ bold && styles.boldText
34
+ ]}>
35
+ {children}
36
+ </Text>
37
+ </View>
38
+ );
39
+
40
+ const FrozenTableReport3A = ({ rows = [] }) => {
41
+ if (!rows || rows.length === 0) {
42
+ return <Text style={{ textAlign: 'center', padding: 20, color: '#666' }}>
43
+ No data available
44
+ </Text>;
45
+ }
46
+
47
+ return (
48
+ <View style={styles.container}>
49
+ {/* Frozen Left Column - AY */}
50
+ <View style={styles.frozenColumn}>
51
+ <Cell bold>AY</Cell>
52
+ {rows.map((row, index) => {
53
+ const isTotal = row.monthLabel === 'Total';
54
+ return (
55
+ <Cell
56
+ key={index}
57
+ bold={isTotal}
58
+ highlight={isTotal}
59
+ >
60
+ {row.monthLabel}
61
+ </Cell>
62
+ );
63
+ })}
64
+ </View>
65
+
66
+ {/* Scrollable Columns */}
67
+ <ScrollView horizontal showsHorizontalScrollIndicator={false}>
68
+ <View>
69
+ {/* Header Row */}
70
+ <View style={styles.headerRow}>
71
+ {[
72
+ '2024 Yük',
73
+ '2025 Yük',
74
+ 'Yük %',
75
+ '2024 Gelir',
76
+ '2025 Gelir',
77
+ 'Gelir %',
78
+ '2025 Bütçe',
79
+ 'Bütçe %'
80
+ ].map((header) => (
81
+ <Cell key={header} bold>
82
+ {header}
83
+ </Cell>
84
+ ))}
85
+ </View>
86
+
87
+ {/* Data Rows */}
88
+ {rows.map((row, index) => {
89
+ const isTotal = row.monthLabel === 'Total';
90
+
91
+ return (
92
+ <View key={index} style={styles.dataRow}>
93
+ <Cell highlight={isTotal}>{formatNumber(row.loadCount2024)}</Cell>
94
+ <Cell highlight={isTotal}>{formatNumber(row.loadCount2025)}</Cell>
95
+ <Cell highlight={isTotal}>
96
+ <PercentCell value={row.loadCountChangePercent} />
97
+ </Cell>
98
+
99
+ <Cell highlight={isTotal}>{formatNumber(row.revenueTl2024)}</Cell>
100
+ <Cell highlight={isTotal}>{formatNumber(row.revenueTl2025)}</Cell>
101
+ <Cell highlight={isTotal}>
102
+ <PercentCell value={row.revenueChangePercent} />
103
+ </Cell>
104
+
105
+ <Cell highlight={isTotal}>{formatNumber(row.budgetRevenueTl2025)}</Cell>
106
+ <Cell highlight={isTotal}>
107
+ <PercentCell value={row.budgetChangePercent} />
108
+ </Cell>
109
+ </View>
110
+ );
111
+ })}
112
+ </View>
113
+ </ScrollView>
114
+ </View>
115
+ );
116
+ };
117
+
118
+ export default FrozenTableReport3A;
119
+
120
+ const styles = StyleSheet.create({
121
+ container: {
122
+ flexDirection: 'row',
123
+ borderWidth: 1,
124
+ borderColor: '#ddd',
125
+ borderRadius: 10,
126
+ overflow: 'hidden',
127
+ marginVertical: 12,
128
+ backgroundColor: '#fff',
129
+ },
130
+ frozenColumn: {
131
+ width: 120,
132
+ backgroundColor: '#f4f6f8',
133
+ borderRightWidth: 1,
134
+ borderColor: '#ddd',
135
+ },
136
+ headerRow: {
137
+ flexDirection: 'row',
138
+ backgroundColor: '#f4f6f8',
139
+ },
140
+ dataRow: {
141
+ flexDirection: 'row',
142
+ },
143
+ cell: {
144
+ width: 140,
145
+ paddingVertical: 12,
146
+ paddingHorizontal: 8,
147
+ justifyContent: 'center',
148
+ borderBottomWidth: 1,
149
+ borderColor: '#e0e0e0',
150
+ },
151
+ cellText: {
152
+ fontSize: 12,
153
+ textAlign: 'center',
154
+ color: '#333',
155
+ },
156
+ boldCell: {
157
+ backgroundColor: '#e9f0f8',
158
+ },
159
+ boldText: {
160
+ fontWeight: '700',
161
+ },
162
+ highlightCell: {
163
+ backgroundColor: '#e9f0f8',
164
+ },
165
+ percentText: {
166
+ fontWeight: '700',
167
+ fontSize: 12,
168
+ textAlign: 'center',
169
+ },
170
+ });
@@ -1,45 +1,52 @@
1
1
  import React, { useEffect, useState } from 'react';
2
- import { ScrollView, Text, TouchableOpacity } from 'react-native';
2
+ import {
3
+ ScrollView,
4
+ Text,
5
+ TouchableOpacity,
6
+ Modal,
7
+ View,
8
+ StyleSheet,
9
+ Dimensions,
10
+ Alert,
11
+ } from 'react-native';
12
+ import { PinchGestureHandler, State } from 'react-native-gesture-handler';
3
13
  import fetchReport1 from '../api/report1Fetcher';
4
14
  import FrozenTableReport1A from '../components/FrozenTableReport1A';
5
15
  import Report1Card from '../components/Report1Card';
6
- import FullScreenTableModal from '../components/FullScreenTableModal';
7
16
 
8
17
  const Report1AScreen = ({ endpoint, token, onBack }) => {
9
18
  const [rows, setRows] = useState([]);
10
19
  const [fullscreen, setFullscreen] = useState(false);
20
+ const [scale, setScale] = useState(1);
11
21
 
12
22
  useEffect(() => {
13
23
  fetchReport1(endpoint, token).then(setRows);
14
- }, []);
24
+ }, [endpoint, token]);
25
+
26
+ const openFullscreen = () => {
27
+ setFullscreen(true);
28
+ setScale(1);
29
+ };
30
+
31
+ const closeFullscreen = () => {
32
+ setFullscreen(false);
33
+ setScale(1);
34
+ };
15
35
 
16
36
  return (
17
37
  <>
18
- <ScrollView style={{ padding: 16 }}>
19
- <Text onPress={onBack} style={{ marginBottom: 12 }}>‹ Back</Text>
20
-
21
- <Text style={{ fontSize: 18, fontWeight: '700', marginBottom: 12 }}>
22
- PERFORMANS RAPORU (USD)
23
- </Text>
24
-
25
- {/* FULLSCREEN BUTTON */}
26
- <TouchableOpacity
27
- onPress={() => setFullscreen(true)}
28
- style={{
29
- alignSelf: 'flex-end',
30
- marginBottom: 8,
31
- padding: 6,
32
- }}
33
- >
34
- <Text style={{ fontWeight: '700' }}>⤢ Full Screen</Text>
38
+ <ScrollView style={{ padding: 16, backgroundColor: '#f8f9fa' }}>
39
+ <Text onPress={onBack} style={styles.backButton}>‹ Back</Text>
40
+
41
+ <Text style={styles.title}>PERFORMANS RAPORU (USD)</Text>
42
+
43
+ <TouchableOpacity onPress={openFullscreen} style={styles.fullscreenBtn}>
44
+ <Text style={styles.fullscreenText}>⤢ Full Screen</Text>
35
45
  </TouchableOpacity>
36
46
 
37
47
  <FrozenTableReport1A rows={rows} />
38
48
 
39
- {/* BELOW TABLE → CARDS */}
40
- <Text style={{ marginVertical: 12, fontWeight: '700' }}>
41
- Individual Reports
42
- </Text>
49
+ <Text style={styles.sectionTitle}>Individual Reports</Text>
43
50
 
44
51
  {rows.map((r, i) => (
45
52
  <Report1Card key={i} item={r} />
@@ -47,13 +54,85 @@ const Report1AScreen = ({ endpoint, token, onBack }) => {
47
54
  </ScrollView>
48
55
 
49
56
  {/* FULL SCREEN MODAL */}
50
- <FullScreenTableModal
57
+ <Modal
51
58
  visible={fullscreen}
52
- rows={rows}
53
- onClose={() => setFullscreen(false)}
54
- />
59
+ supportedOrientations={['portrait', 'landscape']}
60
+ onRequestClose={closeFullscreen}
61
+ >
62
+ <View style={styles.modalContainer}>
63
+ {/* Header */}
64
+ <View style={styles.modalHeader}>
65
+ <TouchableOpacity
66
+ onPress={() =>
67
+ Alert.alert(
68
+ 'Rotate Device',
69
+ 'For best view, please rotate your device to landscape mode ↻',
70
+ [{ text: 'OK' }]
71
+ )
72
+ }
73
+ >
74
+ <Text style={styles.rotateHint}>↻ Rotate Device</Text>
75
+ </TouchableOpacity>
76
+
77
+ <TouchableOpacity onPress={closeFullscreen}>
78
+ <Text style={styles.closeBtn}>✕ Close</Text>
79
+ </TouchableOpacity>
80
+ </View>
81
+
82
+ {/* Zoomable Table */}
83
+ <PinchGestureHandler
84
+ onGestureEvent={(e) => setScale(e.nativeEvent.scale)}
85
+ onHandlerStateChange={(e) => {
86
+ if (e.nativeEvent.state === State.END) {
87
+ let newScale = e.nativeEvent.scale;
88
+ newScale = Math.max(0.8, Math.min(newScale, 3));
89
+ setScale(newScale);
90
+ }
91
+ }}
92
+ >
93
+ <View style={styles.zoomContainer}>
94
+ <View style={{ transform: [{ scale }] }}>
95
+ <FrozenTableReport1A rows={rows} isFullscreen />
96
+ </View>
97
+ </View>
98
+ </PinchGestureHandler>
99
+ </View>
100
+ </Modal>
55
101
  </>
56
102
  );
57
103
  };
58
104
 
59
- export default Report1AScreen;
105
+ const styles = StyleSheet.create({
106
+ backButton: { fontSize: 20, color: '#1e88e5', marginBottom: 16, fontWeight: '600' },
107
+ title: { fontSize: 18, fontWeight: '700', textAlign: 'center', marginVertical: 16 },
108
+ fullscreenBtn: {
109
+ alignSelf: 'flex-end',
110
+ backgroundColor: '#1e88e5',
111
+ paddingHorizontal: 16,
112
+ paddingVertical: 10,
113
+ borderRadius: 8,
114
+ marginBottom: 16,
115
+ },
116
+ fullscreenText: { color: '#fff', fontWeight: '700' },
117
+ sectionTitle: { fontSize: 16, fontWeight: '700', marginVertical: 16 },
118
+
119
+ modalContainer: { flex: 1, backgroundColor: '#000' },
120
+ modalHeader: {
121
+ flexDirection: 'row',
122
+ justifyContent: 'space-between',
123
+ alignItems: 'center',
124
+ padding: 16,
125
+ backgroundColor: '#111',
126
+ borderBottomWidth: 1,
127
+ borderColor: '#333',
128
+ },
129
+ rotateHint: { color: '#fff', fontSize: 16, fontWeight: '700' },
130
+ closeBtn: { color: '#fff', fontSize: 28, fontWeight: '300' },
131
+ zoomContainer: {
132
+ flex: 1,
133
+ justifyContent: 'center',
134
+ alignItems: 'center',
135
+ },
136
+ });
137
+
138
+ export default Report1AScreen;