@dhiraj0720/report1chart 2.5.0 → 2.5.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 +1 -1
- package/src/components/FrozenTableReport1A.jsx +53 -0
- package/src/components/FullScreenTableModal.jsx +35 -0
- package/src/components/MonthSelector.jsx +1 -0
- package/src/index.jsx +14 -0
- package/src/screens/Report1AScreen.jsx +59 -0
- package/src/screens/ReportListScreen.jsx +76 -34
package/package.json
CHANGED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { View, Text, ScrollView, StyleSheet } from 'react-native';
|
|
3
|
+
|
|
4
|
+
const Arrow = ({ value }) => (
|
|
5
|
+
<Text style={{ color: value >= 0 ? 'green' : 'red', fontWeight: '700' }}>
|
|
6
|
+
{value >= 0 ? '↑' : '↓'} {Math.abs(value)}%
|
|
7
|
+
</Text>
|
|
8
|
+
);
|
|
9
|
+
|
|
10
|
+
const Cell = ({ children, bold }) => (
|
|
11
|
+
<View style={styles.cell}>
|
|
12
|
+
<Text style={[bold && styles.bold]}>{children}</Text>
|
|
13
|
+
</View>
|
|
14
|
+
);
|
|
15
|
+
|
|
16
|
+
const FrozenTableReport1A = ({ rows }) => {
|
|
17
|
+
return (
|
|
18
|
+
<View style={styles.container}>
|
|
19
|
+
{/* LEFT FROZEN COLUMN */}
|
|
20
|
+
<View style={styles.frozen}>
|
|
21
|
+
<Cell bold>FAALİYET</Cell>
|
|
22
|
+
{rows.map((r, i) => (
|
|
23
|
+
<Cell key={i} bold>{r.name}</Cell>
|
|
24
|
+
))}
|
|
25
|
+
</View>
|
|
26
|
+
|
|
27
|
+
{/* SCROLLABLE */}
|
|
28
|
+
<ScrollView horizontal>
|
|
29
|
+
<View>
|
|
30
|
+
<View style={styles.headerRow}>
|
|
31
|
+
<Cell bold>2024</Cell>
|
|
32
|
+
<Cell bold>2025</Cell>
|
|
33
|
+
<Cell bold>Artış %</Cell>
|
|
34
|
+
<Cell bold>2025 Bütçe</Cell>
|
|
35
|
+
<Cell bold>Sapma %</Cell>
|
|
36
|
+
</View>
|
|
37
|
+
|
|
38
|
+
{rows.map((r, i) => (
|
|
39
|
+
<View key={i} style={styles.row}>
|
|
40
|
+
<Cell>{r.actual2024}</Cell>
|
|
41
|
+
<Cell>{r.actual2025}</Cell>
|
|
42
|
+
<Cell><Arrow value={r.actualChangePercent} /></Cell>
|
|
43
|
+
<Cell>{r.budget2025}</Cell>
|
|
44
|
+
<Cell><Arrow value={r.budgetVariancePercent} /></Cell>
|
|
45
|
+
</View>
|
|
46
|
+
))}
|
|
47
|
+
</View>
|
|
48
|
+
</ScrollView>
|
|
49
|
+
</View>
|
|
50
|
+
);
|
|
51
|
+
};
|
|
52
|
+
|
|
53
|
+
export default FrozenTableReport1A;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import React, { useState } from 'react';
|
|
2
|
+
import { Modal, View, Text, TouchableOpacity, Dimensions } from 'react-native';
|
|
3
|
+
import FrozenTableReport1A from './FrozenTableReport1A';
|
|
4
|
+
|
|
5
|
+
const FullScreenTableModal = ({ visible, rows, onClose }) => {
|
|
6
|
+
const [landscape, setLandscape] = useState(false);
|
|
7
|
+
const { width, height } = Dimensions.get('window');
|
|
8
|
+
|
|
9
|
+
return (
|
|
10
|
+
<Modal visible={visible} animationType="slide">
|
|
11
|
+
<View style={{ flex: 1, padding: 16 }}>
|
|
12
|
+
{/* TOP BAR */}
|
|
13
|
+
<View style={{
|
|
14
|
+
flexDirection: 'row',
|
|
15
|
+
justifyContent: 'space-between',
|
|
16
|
+
marginBottom: 8,
|
|
17
|
+
}}>
|
|
18
|
+
<TouchableOpacity onPress={onClose}>
|
|
19
|
+
<Text style={{ fontSize: 18 }}>✕</Text>
|
|
20
|
+
</TouchableOpacity>
|
|
21
|
+
|
|
22
|
+
<TouchableOpacity onPress={() => setLandscape(!landscape)}>
|
|
23
|
+
<Text style={{ fontWeight: '700' }}>⟳ Rotate</Text>
|
|
24
|
+
</TouchableOpacity>
|
|
25
|
+
</View>
|
|
26
|
+
|
|
27
|
+
<View style={{ flex: 1 }}>
|
|
28
|
+
<FrozenTableReport1A rows={rows} />
|
|
29
|
+
</View>
|
|
30
|
+
</View>
|
|
31
|
+
</Modal>
|
|
32
|
+
);
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
export default FullScreenTableModal;
|
package/src/index.jsx
CHANGED
|
@@ -5,6 +5,7 @@ import ReportListScreen from './screens/ReportListScreen';
|
|
|
5
5
|
import Report1Screen from './screens/Report1Screen';
|
|
6
6
|
import Report2Screen from './screens/Report2Screen';
|
|
7
7
|
import Report3Screen from './screens/Report3Screen';
|
|
8
|
+
import Report1AScreen from './screens/Report1AScreen';
|
|
8
9
|
|
|
9
10
|
const AnalyticsReports = ({ config, onExit }) => {
|
|
10
11
|
const [active, setActive] = useState(null);
|
|
@@ -57,6 +58,19 @@ const AnalyticsReports = ({ config, onExit }) => {
|
|
|
57
58
|
);
|
|
58
59
|
}
|
|
59
60
|
|
|
61
|
+
if (active === '1A') {
|
|
62
|
+
return (
|
|
63
|
+
<SafeScreen>
|
|
64
|
+
<Report1AScreen
|
|
65
|
+
endpoint={config.report1.url}
|
|
66
|
+
token={config.token}
|
|
67
|
+
onBack={() => setActive(null)}
|
|
68
|
+
/>
|
|
69
|
+
</SafeScreen>
|
|
70
|
+
);
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
|
|
60
74
|
// 👉 REPORT 2
|
|
61
75
|
if (active === 2) {
|
|
62
76
|
return (
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import React, { useEffect, useState } from 'react';
|
|
2
|
+
import { ScrollView, Text, TouchableOpacity } from 'react-native';
|
|
3
|
+
import fetchReport1 from '../api/report1Fetcher';
|
|
4
|
+
import FrozenTableReport1A from '../components/FrozenTableReport1A';
|
|
5
|
+
import Report1Card from '../components/Report1Card';
|
|
6
|
+
import FullScreenTableModal from '../components/FullScreenTableModal';
|
|
7
|
+
|
|
8
|
+
const Report1AScreen = ({ endpoint, token, onBack }) => {
|
|
9
|
+
const [rows, setRows] = useState([]);
|
|
10
|
+
const [fullscreen, setFullscreen] = useState(false);
|
|
11
|
+
|
|
12
|
+
useEffect(() => {
|
|
13
|
+
fetchReport1(endpoint, token).then(setRows);
|
|
14
|
+
}, []);
|
|
15
|
+
|
|
16
|
+
return (
|
|
17
|
+
<>
|
|
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>
|
|
35
|
+
</TouchableOpacity>
|
|
36
|
+
|
|
37
|
+
<FrozenTableReport1A rows={rows} />
|
|
38
|
+
|
|
39
|
+
{/* BELOW TABLE → CARDS */}
|
|
40
|
+
<Text style={{ marginVertical: 12, fontWeight: '700' }}>
|
|
41
|
+
Individual Reports
|
|
42
|
+
</Text>
|
|
43
|
+
|
|
44
|
+
{rows.map((r, i) => (
|
|
45
|
+
<Report1Card key={i} item={r} />
|
|
46
|
+
))}
|
|
47
|
+
</ScrollView>
|
|
48
|
+
|
|
49
|
+
{/* FULL SCREEN MODAL */}
|
|
50
|
+
<FullScreenTableModal
|
|
51
|
+
visible={fullscreen}
|
|
52
|
+
rows={rows}
|
|
53
|
+
onClose={() => setFullscreen(false)}
|
|
54
|
+
/>
|
|
55
|
+
</>
|
|
56
|
+
);
|
|
57
|
+
};
|
|
58
|
+
|
|
59
|
+
export default Report1AScreen;
|
|
@@ -4,50 +4,75 @@ import {
|
|
|
4
4
|
Text,
|
|
5
5
|
TouchableOpacity,
|
|
6
6
|
StyleSheet,
|
|
7
|
+
ScrollView,
|
|
7
8
|
} from 'react-native';
|
|
8
9
|
|
|
10
|
+
const REPORTS = [
|
|
11
|
+
{
|
|
12
|
+
id: 1,
|
|
13
|
+
title: 'Report 1',
|
|
14
|
+
desc: 'Performans Raporu (USD)',
|
|
15
|
+
},
|
|
16
|
+
{
|
|
17
|
+
id: '1A',
|
|
18
|
+
title: 'Report 1 A',
|
|
19
|
+
desc: 'Tablo Bazlı Performans (Detaylı)',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
id: 2,
|
|
23
|
+
title: 'Report 2',
|
|
24
|
+
desc: 'Gross Profit by Company & Division',
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
id: '2A',
|
|
28
|
+
title: 'Report 2 A',
|
|
29
|
+
desc: 'Compact / Alternate View',
|
|
30
|
+
},
|
|
31
|
+
{
|
|
32
|
+
id: 3,
|
|
33
|
+
title: 'Report 3',
|
|
34
|
+
desc: 'Transportation Business Analysis',
|
|
35
|
+
},
|
|
36
|
+
{
|
|
37
|
+
id: '3A',
|
|
38
|
+
title: 'Report 3 A',
|
|
39
|
+
desc: 'Monthly & Budget Comparison',
|
|
40
|
+
},
|
|
41
|
+
];
|
|
42
|
+
|
|
9
43
|
const ReportListScreen = ({ onSelect, onExit }) => {
|
|
10
44
|
return (
|
|
11
45
|
<View style={styles.container}>
|
|
12
46
|
{/* HEADER */}
|
|
13
47
|
<View style={styles.header}>
|
|
14
|
-
<TouchableOpacity
|
|
48
|
+
<TouchableOpacity
|
|
49
|
+
onPress={onExit}
|
|
50
|
+
style={styles.backBtn}
|
|
51
|
+
hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }}
|
|
52
|
+
>
|
|
15
53
|
<Text style={styles.back}>‹</Text>
|
|
16
54
|
</TouchableOpacity>
|
|
55
|
+
|
|
17
56
|
<Text style={styles.title}>Analytics Reports</Text>
|
|
18
|
-
|
|
57
|
+
|
|
58
|
+
{/* Spacer */}
|
|
59
|
+
<View style={{ width: 28 }} />
|
|
19
60
|
</View>
|
|
20
61
|
|
|
21
|
-
{/* CARDS */}
|
|
22
|
-
<
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
>
|
|
36
|
-
<Text style={styles.cardTitle}>Report 2</Text>
|
|
37
|
-
<Text style={styles.cardDesc}>
|
|
38
|
-
Gross Profit by Company & Division
|
|
39
|
-
</Text>
|
|
40
|
-
</TouchableOpacity>
|
|
41
|
-
|
|
42
|
-
<TouchableOpacity
|
|
43
|
-
style={styles.card}
|
|
44
|
-
onPress={() => onSelect(3)}
|
|
45
|
-
>
|
|
46
|
-
<Text style={styles.cardTitle}>Report 3</Text>
|
|
47
|
-
<Text style={styles.cardDesc}>
|
|
48
|
-
Transportation Business Analysis
|
|
49
|
-
</Text>
|
|
50
|
-
</TouchableOpacity>
|
|
62
|
+
{/* REPORT CARDS */}
|
|
63
|
+
<ScrollView showsVerticalScrollIndicator={false}>
|
|
64
|
+
{REPORTS.map(report => (
|
|
65
|
+
<TouchableOpacity
|
|
66
|
+
key={report.id}
|
|
67
|
+
style={styles.card}
|
|
68
|
+
onPress={() => onSelect(report.id)}
|
|
69
|
+
activeOpacity={0.85}
|
|
70
|
+
>
|
|
71
|
+
<Text style={styles.cardTitle}>{report.title}</Text>
|
|
72
|
+
<Text style={styles.cardDesc}>{report.desc}</Text>
|
|
73
|
+
</TouchableOpacity>
|
|
74
|
+
))}
|
|
75
|
+
</ScrollView>
|
|
51
76
|
</View>
|
|
52
77
|
);
|
|
53
78
|
};
|
|
@@ -56,20 +81,27 @@ export default ReportListScreen;
|
|
|
56
81
|
|
|
57
82
|
const styles = StyleSheet.create({
|
|
58
83
|
container: {
|
|
59
|
-
padding: 16,
|
|
60
84
|
flex: 1,
|
|
61
85
|
backgroundColor: '#f4f6f8',
|
|
86
|
+
padding: 16,
|
|
62
87
|
},
|
|
63
88
|
|
|
89
|
+
/* HEADER */
|
|
64
90
|
header: {
|
|
65
91
|
flexDirection: 'row',
|
|
66
92
|
alignItems: 'center',
|
|
67
93
|
marginBottom: 20,
|
|
68
94
|
},
|
|
69
95
|
|
|
96
|
+
backBtn: {
|
|
97
|
+
width: 28,
|
|
98
|
+
alignItems: 'flex-start',
|
|
99
|
+
},
|
|
100
|
+
|
|
70
101
|
back: {
|
|
71
|
-
fontSize:
|
|
102
|
+
fontSize: 28,
|
|
72
103
|
fontWeight: '700',
|
|
104
|
+
color: '#111',
|
|
73
105
|
},
|
|
74
106
|
|
|
75
107
|
title: {
|
|
@@ -77,15 +109,23 @@ const styles = StyleSheet.create({
|
|
|
77
109
|
textAlign: 'center',
|
|
78
110
|
fontSize: 18,
|
|
79
111
|
fontWeight: '700',
|
|
112
|
+
color: '#111',
|
|
80
113
|
},
|
|
81
114
|
|
|
115
|
+
/* CARDS */
|
|
82
116
|
card: {
|
|
83
117
|
backgroundColor: '#fff',
|
|
84
118
|
padding: 18,
|
|
85
119
|
borderRadius: 14,
|
|
86
120
|
marginBottom: 14,
|
|
121
|
+
|
|
87
122
|
borderWidth: 1,
|
|
88
123
|
borderColor: '#e0e0e0',
|
|
124
|
+
|
|
125
|
+
shadowColor: '#000',
|
|
126
|
+
shadowOpacity: 0.06,
|
|
127
|
+
shadowRadius: 8,
|
|
128
|
+
shadowOffset: { width: 0, height: 3 },
|
|
89
129
|
elevation: 2,
|
|
90
130
|
},
|
|
91
131
|
|
|
@@ -93,10 +133,12 @@ const styles = StyleSheet.create({
|
|
|
93
133
|
fontSize: 16,
|
|
94
134
|
fontWeight: '700',
|
|
95
135
|
marginBottom: 6,
|
|
136
|
+
color: '#111',
|
|
96
137
|
},
|
|
97
138
|
|
|
98
139
|
cardDesc: {
|
|
99
140
|
fontSize: 13,
|
|
100
141
|
color: '#555',
|
|
142
|
+
lineHeight: 18,
|
|
101
143
|
},
|
|
102
144
|
});
|