diff --git a/app/(tabs)/stats/index.tsx b/app/(tabs)/stats/index.tsx
index b7e477d..0870688 100644
--- a/app/(tabs)/stats/index.tsx
+++ b/app/(tabs)/stats/index.tsx
@@ -6,6 +6,7 @@ import Widget from '../../../components/stats/Widget';
import CategoryProgressBarList from '../../../components/stats/CategoryProgressBarList';
import BudgetRemaining from '../../../components/stats/BudgetRemaining';
import DebugMenu from '../../../services/DebugMenu';
+import SavingsOverview from '../../../components/stats/SavingsOverview';
export default function Page() {
const { colors } = useTheme();
@@ -51,11 +52,14 @@ export default function Page() {
-
+
-
+
+
+
+
diff --git a/components/stats/BudgetOverview.tsx b/components/stats/BudgetOverview.tsx
index 5339fb3..05e89c4 100644
--- a/components/stats/BudgetOverview.tsx
+++ b/components/stats/BudgetOverview.tsx
@@ -1,31 +1,55 @@
-import React from 'react';
+import React, { useState, useEffect } from 'react';
import { View, Text, StyleSheet } from 'react-native';
import { useTheme } from '../../app/contexts/ThemeContext';
+import useFetch from '../../hooks/useFetch';
-interface StatsBudgetProps {
- spent: number;
- budget: number;
-}
-
-const BudgetOverview: React.FC = ({ spent, budget }) => {
+const BudgetOverview = () => {
const { colors } = useTheme();
+ const [spent, setSpent] = useState(0);
+ const [budget, setBudget] = useState(0);
+
+ const spentQuery = {
+ sql: "SELECT SUM(e.amount) as total FROM expense e LEFT JOIN category c ON e.category_guid = c.guid WHERE c.type = 'budget'",
+ args: []
+ };
+
+ const budgetQuery = {
+ sql: "SELECT SUM(allocated_amount) as total FROM category WHERE type = 'budget'",
+ args: []
+ };
+
+ const { data: spentData, isLoading: spentLoading } = useFetch(spentQuery);
+ const { data: budgetData, isLoading: budgetLoading } = useFetch(budgetQuery);
+
+ useEffect(() => {
+ if (spentData) {
+ setSpent(spentData[0]?.total || 0);
+ }
+ if (budgetData) {
+ setBudget(budgetData[0]?.total || 0);
+ }
+ }, [spentData, budgetData]);
const styles = StyleSheet.create({
container: {
margin: 10,
borderRadius: 5,
alignItems: 'center',
- justifyContent: 'center',
+ justifyContent: 'center'
},
text: {
fontSize: 26,
- color: colors.primaryText,
+ color: colors.primaryText
},
boldText: {
- fontWeight: 'bold',
- },
+ fontWeight: 'bold'
+ }
});
+ if (spentLoading || budgetLoading) {
+ return Loading...;
+ }
+
return (
@@ -35,4 +59,4 @@ const BudgetOverview: React.FC = ({ spent, budget }) => {
);
};
-export default BudgetOverview
+export default BudgetOverview;
diff --git a/components/stats/BudgetRemaining.tsx b/components/stats/BudgetRemaining.tsx
index 6207ead..37aa555 100644
--- a/components/stats/BudgetRemaining.tsx
+++ b/components/stats/BudgetRemaining.tsx
@@ -1,35 +1,52 @@
-import React from 'react';
+import React, { useState, useEffect } from 'react';
import { Text, StyleSheet } from 'react-native';
import { useTheme } from '../../app/contexts/ThemeContext';
+import useFetch from '../../hooks/useFetch';
-interface BudgetRemainingProps {
- budget: number;
- spent: number;
-}
+const styles = StyleSheet.create({
+ text: {
+ fontSize: 26,
+ },
+ boldText: {
+ fontWeight: 'bold',
+ },
+});
-const BudgetRemaining: React.FC = ({ budget, spent }) => {
+const BudgetRemaining = () => {
const { colors } = useTheme();
+ const [spent, setSpent] = useState(0);
+ const [budget, setBudget] = useState(0);
+
+ const spentQuery = {
+ sql: "SELECT SUM(amount) as total FROM expense",
+ args: []
+ };
+
+ const budgetQuery = {
+ sql: "SELECT SUM(allocated_amount) as total FROM category WHERE type = 'budget'",
+ args: []
+ };
+
+ const { data: spentData, isLoading: spentLoading } = useFetch(spentQuery);
+ const { data: budgetData, isLoading: budgetLoading } = useFetch(budgetQuery);
+
+ useEffect(() => {
+ if (spentData) {
+ setSpent(spentData[0]?.total || 0);
+ }
+ if (budgetData) {
+ setBudget(budgetData[0]?.total || 0);
+ }
+ }, [spentData, budgetData]);
const remaining = budget - spent;
- const styles = StyleSheet.create({
- container: {
- margin: 10,
- borderRadius: 5,
- alignItems: 'center',
- justifyContent: 'center',
- },
- text: {
- fontSize: 26,
- color: colors.primaryText,
- },
- boldText: {
- fontWeight: 'bold',
- },
- });
+ if (spentLoading || budgetLoading) {
+ return Loading...;
+ }
return (
-
+
You have {remaining.toFixed(2)}€ left.
);