restore repo

This commit is contained in:
PanSi21 2024-11-19 02:04:30 +01:00
parent 97e8ee6eb8
commit f2a798ab18
Signed by untrusted user who does not match committer: PanSi21
GPG key ID: 755F8874C65EF462
30 changed files with 1627 additions and 2 deletions

View file

@ -0,0 +1,324 @@
import React, { useState, useEffect } from 'react';
import { View, StyleSheet, Dimensions, Text, FlatList } from 'react-native';
import * as SQLite from 'expo-sqlite';
import { LineChart } from 'react-native-chart-kit';
import { Modal, TouchableOpacity } from 'react-native';
import moment from 'moment';
import 'moment/locale/it'; // Import Italian locale for moment
const VisualizzaDati = () => {
const [data, setData] = useState([]);
const [selectedTransactions, setSelectedTransactions] = useState([]);
const [modalVisible, setModalVisible] = useState(false);
const [selectedDate, setSelectedDate] = useState('');
const [currentWeek, setCurrentWeek] = useState(moment().startOf('week'));
useEffect(() => {
const interval = setInterval(() => {
fetchData();
}, 1000); // Aggiorna ogni 1 secondi
return () => clearInterval(interval); // Pulisce l'intervallo quando il componente viene smontato
}, []);
async function fetchData() {
try {
const db = await SQLite.openDatabaseAsync('moneyAppDB');
const result = await db.getAllAsync('SELECT * FROM transactions');
const fetchedData = [];
for (const row of result) {
fetchedData.push(row);
}
// Raggruppa i dati per data e calcola la somma degli importi per il grafico
const groupedData = fetchedData.reduce((acc, curr) => {
const date = curr.date;
if (!acc[date]) {
acc[date] = 0;
}
acc[date] += curr.amount;
return acc;
}, {});
// Trasforma l'oggetto raggruppato in un array di oggetti e ordina per data
const chartDataArray = Object.keys(groupedData)
.map(date => ({
date,
amount: groupedData[date],
}))
.sort((a, b) => new Date(a.date.split('-').reverse().join('-')) - new Date(b.date.split('-').reverse().join('-')));
setData(chartDataArray);
} catch (error) {
console.error('Error fetching data:', error);
}
}
const getWeekData = () => {
const startOfWeek = currentWeek.clone().startOf('week');
const endOfWeek = currentWeek.clone().endOf('week');
const weekDates = [];
for (let i = 0; i < 7; i++) {
weekDates.push(startOfWeek.clone().add(i, 'days').format('DD-MM-YYYY'));
}
const weekData = weekDates.map(date => {
const item = data.find(d => d.date === date);
return {
date,
amount: item ? item.amount : 0,
};
});
return weekData;
};
const getCurrentWeekText = () => {
moment.locale('it'); // Set moment locale to Italian
const startOfWeek = currentWeek.clone().startOf('week').format('DD MMMM');
const endOfWeek = currentWeek.clone().endOf('week').format('DD MMMM');
return `${startOfWeek} al ${endOfWeek}`;
};
const chartData = {
labels: getWeekData().map(item => item.date),
datasets: [
{
data: getWeekData().map(item => item.amount),
},
],
};
const handleDataPointClick = async (dataPoint) => {
const date = chartData.labels[dataPoint.index];
setSelectedDate(date);
try {
const db = await SQLite.openDatabaseAsync('moneyAppDB');
const result = await db.getAllAsync(`SELECT * FROM transactions WHERE date = ?`, [date]);
setSelectedTransactions(result);
setModalVisible(true);
} catch (error) {
console.error('Error fetching transactions for selected date:', error);
}
};
const handlePrevWeek = () => {
setCurrentWeek(currentWeek.clone().subtract(1, 'week'));
};
const handleNextWeek = () => {
setCurrentWeek(currentWeek.clone().add(1, 'week'));
};
const getTotalForWeek = () => {
const weekData = getWeekData();
const total = weekData.reduce((acc, curr) => acc + curr.amount, 0);
return total;
};
return (
<FlatList
data={[{ key: 'content' }]}
renderItem={() => (
<View style={styles.container}>
{data.length === 0 ? (
<Text style={styles.noDataText}>Nessun dato disponibile</Text>
) : (
<>
<Text style={styles.weekText}>{getCurrentWeekText()}</Text>
<Text style={[styles.totalText, { color: getTotalForWeek() >= 0 ? 'green' : 'red' }]}>
Totale: {getTotalForWeek().toFixed(2)}
</Text>
<LineChart
bezier
data={chartData}
width={Dimensions.get('window').width - 20} // from react-native
height={300}
verticalLabelRotation={30}
yAxisLabel="€"
chartConfig={{
backgroundColor: '#fff',
backgroundGradientFrom: '#000',
backgroundGradientTo: '#000',
decimalPlaces: 2, // optional, defaults to 2dp
color: (opacity = 1) => `#f57242`,
labelColor: (opacity = 1) => `rgba(255, 255, 255, ${opacity})`,
style: {
borderRadius: 10,
},
propsForDots: {
r: '6',
strokeWidth: '3',
stroke: '#3956e6',
},
}}
style={{
borderRadius: 15,
}}
onDataPointClick={handleDataPointClick}
/>
<View style={styles.buttonContainer}>
<TouchableOpacity
style={styles.navButton}
onPress={handlePrevWeek}
>
<Text style={styles.navButtonText}>Settimana Precedente</Text>
</TouchableOpacity>
<TouchableOpacity
style={styles.navButton}
onPress={handleNextWeek}
>
<Text style={styles.navButtonText}>Settimana Successiva</Text>
</TouchableOpacity>
</View>
<Modal
animationType="slide"
transparent={true}
visible={modalVisible}
onRequestClose={() => setModalVisible(false)}
>
<View style={styles.centeredView}>
<View style={styles.modalView}>
<Text style={styles.modalTitle}>Transazioni del {selectedDate}</Text>
<FlatList
data={selectedTransactions}
keyExtractor={(item, index) => index.toString()}
renderItem={({ item }) => (
<View style={styles.transactionItem}>
<View><Text style={styles.transactionDescription}>{item.description}</Text></View>
<View>
<Text style={[styles.transactionAmount, { color: item.type === 'expense' ? 'red' : 'green' }]}>
{item.type === 'expense' ? '-' : '+'}{Math.abs(item.amount).toFixed(2)}
</Text>
</View>
</View>
)}
/>
<TouchableOpacity
style={styles.closeButton}
onPress={() => setModalVisible(false)}
>
<Text style={styles.closeButtonText}>Chiudi</Text>
</TouchableOpacity>
</View>
</View>
</Modal>
</>
)}
</View>
)}
keyExtractor={item => item.key}
/>
);
};
const styles = StyleSheet.create({
container: {
marginTop: 20,
padding: 10,
},
buttonContainer: {
justifyContent: 'space-between',
flexDirection: 'row',
marginVertical: 10,
},
noDataText: {
color: '#000',
fontSize: 16,
textAlign: 'center',
marginTop: 20,
},
transactionsContainer: {
},
transactionsTitle: {
fontSize: 18,
fontWeight: 'bold',
color: '#fff',
marginVertical: 15,
textAlign: 'center',
},
transactionItem: {
flexDirection: 'row',
justifyContent: 'space-between',
alignItems: 'center',
padding: 15,
marginVertical: 5,
borderRadius: 10,
width: '100%',
backgroundColor: '#1a1a1a',
},
transactionDate: {
color: '#fff',
fontSize: 14,
},
transactionDescription: {
color: '#fff',
fontSize: 16,
},
transactionAmount: {
color: 'red',
fontSize: 16,
fontWeight: 'bold',
},
centeredView: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
marginTop: 22,
},
modalView: {
margin: 20,
height: 500,
backgroundColor: '#000',
borderRadius: 20,
borderColor: '#3c3c3c',
borderWidth: 2,
padding: 20,
alignItems: 'center',
},
modalTitle: {
fontSize: 18,
fontWeight: 'bold',
marginBottom: 15,
textAlign: 'center',
color: '#fff'
},
navButton: {
padding: 10,
borderRadius: 5,
margin: 2,
backgroundColor: '#f57242',
},
navButtonText: {
color: '#000',
fontSize: 16,
},
closeButton: {
marginTop: 20,
padding: 10,
borderRadius: 5,
backgroundColor: '#fff',
},
closeButtonText: {
color: '#000',
fontSize: 16,
},
weekText: {
color: '#fff',
fontSize: 22,
textAlign: 'center',
paddingBottom: 20
},
totalText: {
fontSize: 20,
textAlign: 'center',
marginBottom: 20,
},
});
export default VisualizzaDati;