Merge branch '54-categories-detailed-view-on-press' into 'main'
Resolve "Categories, detailed view on Press" Closes #54 See merge request thschleicher/interaktive-systeme!45
This commit is contained in:
commit
99f3fbcaa7
8 changed files with 105 additions and 16 deletions
|
|
@ -5,6 +5,7 @@ export default function _Layout() {
|
||||||
<Stack initialRouteName="index" screenOptions={{headerShown: false}}>
|
<Stack initialRouteName="index" screenOptions={{headerShown: false}}>
|
||||||
<Stack.Screen name="index"/>
|
<Stack.Screen name="index"/>
|
||||||
<Stack.Screen name="addCategory" options={{presentation: "modal"}}/>
|
<Stack.Screen name="addCategory" options={{presentation: "modal"}}/>
|
||||||
|
<Stack.Screen name="category" options={{headerShown: false, animation: "slide_from_right"}}/>
|
||||||
</Stack>
|
</Stack>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
@ -9,8 +9,8 @@ const addCategory = () => {
|
||||||
|
|
||||||
const parameters = useLocalSearchParams();
|
const parameters = useLocalSearchParams();
|
||||||
|
|
||||||
const [categoryName, setCartegoryName] = useState<string>("Enter Category Name...");
|
const [categoryName, setCategoryName] = useState<string>("Enter Category Name...");
|
||||||
const [categoryColor, setCartegoryColor] = useState<null|string>(null);
|
const [categoryColor, setCategoryColor] = useState<null|string>(null);
|
||||||
const [selectedType, setSelectedType] = useState<string>("expense");
|
const [selectedType, setSelectedType] = useState<string>("expense");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -20,7 +20,7 @@ const addCategory = () => {
|
||||||
<View style={[styles.containerStyle, {backgroundColor: colors.containerColor}]}>
|
<View style={[styles.containerStyle, {backgroundColor: colors.containerColor}]}>
|
||||||
<View style={[styles.textInputViewStyle, {backgroundColor: colors.elementDefaultColor}]}>
|
<View style={[styles.textInputViewStyle, {backgroundColor: colors.elementDefaultColor}]}>
|
||||||
<TextInput placeholder={categoryName} placeholderTextColor={colors.secondaryText} style={[styles.textInputStyle, {color: colors.primaryText}]} onChangeText={(newName: string) => {
|
<TextInput placeholder={categoryName} placeholderTextColor={colors.secondaryText} style={[styles.textInputStyle, {color: colors.primaryText}]} onChangeText={(newName: string) => {
|
||||||
setCartegoryName(newName);
|
setCategoryName(newName);
|
||||||
}}/>
|
}}/>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
|
|
@ -33,7 +33,7 @@ const addCategory = () => {
|
||||||
|
|
||||||
<View>
|
<View>
|
||||||
<CustomColorPicker currentColor={categoryColor} handleColorChange={(color) => {
|
<CustomColorPicker currentColor={categoryColor} handleColorChange={(color) => {
|
||||||
setCartegoryColor(color);
|
setCategoryColor(color);
|
||||||
}}/>
|
}}/>
|
||||||
</View>
|
</View>
|
||||||
|
|
||||||
|
|
|
||||||
95
app/(tabs)/budget/category.tsx
Normal file
95
app/(tabs)/budget/category.tsx
Normal file
|
|
@ -0,0 +1,95 @@
|
||||||
|
import { FontAwesome } from "@expo/vector-icons";
|
||||||
|
import { router, useLocalSearchParams } from "expo-router";
|
||||||
|
import { FlatList, SafeAreaView, StyleSheet, Text, TouchableOpacity, View } from "react-native";
|
||||||
|
import { ExpenseItem, LoadingSymbol, TextInputBar } from "../../../components";
|
||||||
|
import useFetch from "../../../hooks/useFetch";
|
||||||
|
import { useTheme } from "../../contexts/ThemeContext";
|
||||||
|
|
||||||
|
export default function Page() {
|
||||||
|
const {colors} = useTheme();
|
||||||
|
const {category_guid, category_name} = useLocalSearchParams();
|
||||||
|
|
||||||
|
const {data, isLoading, reFetch} = useFetch({sql: "SELECT e.guid AS expense_guid, e.name AS expense_name, c.name AS category_name, e.datetime AS expense_datetime, e.amount AS expense_amount, c.color AS category_color FROM expense e JOIN category c ON e.category_guid = c.guid WHERE c.guid = ? ORDER BY expense_datetime desc;", args: [category_guid]});
|
||||||
|
|
||||||
|
const handleEditCategory = () => {
|
||||||
|
console.log("edit category");
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleBackButton = () => {
|
||||||
|
router.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
return (
|
||||||
|
<SafeAreaView style={[styles.safeAreaView, {backgroundColor: colors.containerColor}]}>
|
||||||
|
<TouchableOpacity style={styles.backContainer} onPress={handleBackButton}>
|
||||||
|
<FontAwesome style={styles.iconBack} name="arrow-left" size={35} color={colors.primaryText}/>
|
||||||
|
<Text style={[styles.backText, {color: colors.secondaryText}]}>Back</Text>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<TouchableOpacity style={[styles.categoryEditTouchableOpacity, {backgroundColor: colors.elementDefaultColor}]}
|
||||||
|
onPress={handleEditCategory}>
|
||||||
|
<Text style={[styles.editButtonText, {color: colors.primaryText}]}>{category_name}</Text>
|
||||||
|
<FontAwesome style={styles.iconEdit} name="edit" size={35} color={colors.primaryText}/>
|
||||||
|
</TouchableOpacity>
|
||||||
|
|
||||||
|
<TextInputBar style={styles.searchBar} placeholder="Search..."/>
|
||||||
|
|
||||||
|
{isLoading ? (<LoadingSymbol/>) : (
|
||||||
|
<FlatList
|
||||||
|
data={data}
|
||||||
|
renderItem = {({item}) => <ExpenseItem
|
||||||
|
color={item.category_color}
|
||||||
|
category={item.category_name}
|
||||||
|
title={item.expense_name}
|
||||||
|
date={item.expense_datetime}
|
||||||
|
value={item.expense_amount}
|
||||||
|
/>}
|
||||||
|
keyExtractor={item => item.guid}
|
||||||
|
ItemSeparatorComponent={() => {
|
||||||
|
return (<View style={styles.itemSeperator}/>);
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</SafeAreaView>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const styles = StyleSheet.create({
|
||||||
|
safeAreaView: {
|
||||||
|
flex: 1,
|
||||||
|
},
|
||||||
|
itemSeperator: {
|
||||||
|
margin: 5,
|
||||||
|
},
|
||||||
|
categoryEditTouchableOpacity: {
|
||||||
|
borderRadius: 10,
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "space-around",
|
||||||
|
margin: 10,
|
||||||
|
},
|
||||||
|
editButtonText: {
|
||||||
|
fontSize: 30,
|
||||||
|
padding: 10,
|
||||||
|
fontWeight: "bold",
|
||||||
|
},
|
||||||
|
iconEdit: {
|
||||||
|
paddingVertical: 10,
|
||||||
|
paddingRight: 10,
|
||||||
|
},
|
||||||
|
searchBar: {
|
||||||
|
marginHorizontal: 10,
|
||||||
|
marginBottom:20,
|
||||||
|
},
|
||||||
|
iconBack: {
|
||||||
|
paddingLeft: 10,
|
||||||
|
paddingRight: 5,
|
||||||
|
},
|
||||||
|
backText: {
|
||||||
|
fontSize: 20,
|
||||||
|
padding: 5,
|
||||||
|
},
|
||||||
|
backContainer: {
|
||||||
|
flexDirection: "row",
|
||||||
|
justifyContent: "flex-start",
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
@ -38,7 +38,7 @@ export default function Page() {
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleCategoryPress = (item: {[column: string]: any;}) => {
|
const handleCategoryPress = (item: {[column: string]: any;}) => {
|
||||||
console.log(item.category_name);
|
router.push({pathname: "/(tabs)/budget/category", params: {category_guid: item.category_guid, category_name: item.category_name}})
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -46,7 +46,7 @@ export default function Page() {
|
||||||
<BudgetHeader selectedPage={selectedPage} handlePageSelection={handlePageSelection}/>
|
<BudgetHeader selectedPage={selectedPage} handlePageSelection={handlePageSelection}/>
|
||||||
|
|
||||||
<Plus onPress={() => {
|
<Plus onPress={() => {
|
||||||
router.push({pathname: '/(tabs)/budget/addCategory', params: { guid: '123'}}); //This needs to be changed to a regular push, without parameters
|
router.push({pathname: '/(tabs)/budget/addCategory'});
|
||||||
}}/>
|
}}/>
|
||||||
|
|
||||||
{isLoading ? (<LoadingSymbol/>) : (
|
{isLoading ? (<LoadingSymbol/>) : (
|
||||||
|
|
|
||||||
|
|
@ -53,16 +53,10 @@ export default function Page() {
|
||||||
<Widget>
|
<Widget>
|
||||||
<BudgetRemaining budget={budget} spent={spent} />
|
<BudgetRemaining budget={budget} spent={spent} />
|
||||||
</Widget>
|
</Widget>
|
||||||
<Widget text='#TODO Insert Pie-Chart' image={require('../../../assets/images/8b14el.jpg')}/>
|
<Widget title='Your Expenses so far' image={require('../../../assets/images/8b14el.jpg')}/>
|
||||||
<Widget>
|
<Widget>
|
||||||
<BudgetOverview budget={budget} spent={spent} />
|
<BudgetOverview budget={budget} spent={spent} />
|
||||||
</Widget>
|
</Widget>
|
||||||
<Widget title="Budget Progress">
|
|
||||||
<CategoryProgressBarList categories={BudgetData} />
|
|
||||||
</Widget>
|
|
||||||
<Widget title="Savings Progress">
|
|
||||||
<CategoryProgressBarList categories={SavingsData} />
|
|
||||||
</Widget>
|
|
||||||
</ScrollView>
|
</ScrollView>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ interface BudgetRemainingProps {
|
||||||
}
|
}
|
||||||
|
|
||||||
const BudgetRemaining: React.FC<BudgetRemainingProps> = ({ budget, spent }) => {
|
const BudgetRemaining: React.FC<BudgetRemainingProps> = ({ budget, spent }) => {
|
||||||
const { colors, theme } = useTheme();
|
const { colors } = useTheme();
|
||||||
|
|
||||||
const remaining = budget - spent;
|
const remaining = budget - spent;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { View, Text, Button, StyleSheet, TouchableOpacity } from 'react-native';
|
import { View, Text, Button, StyleSheet, TouchableOpacity } from 'react-native';
|
||||||
import CategoryProgressBar from './CategoryProgressBar';
|
import CategoryProgressBar from './CategoryProgressBar';
|
||||||
import { useTheme } from '../../app/contexts/ThemeContext';
|
|
||||||
|
|
||||||
interface CategoryItem {
|
interface CategoryItem {
|
||||||
name: string;
|
name: string;
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ const Widget: React.FC<WidgetProps> = ({ title, text, children, image }) => { //
|
||||||
},
|
},
|
||||||
imageStyle: {
|
imageStyle: {
|
||||||
width: '100%',
|
width: '100%',
|
||||||
height: 200,
|
height: 500,
|
||||||
borderRadius: 5,
|
borderRadius: 5,
|
||||||
marginBottom: 8,
|
marginBottom: 8,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Reference in a new issue