diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml
index 9889a4f..8a1e9c1 100644
--- a/.gitlab-ci.yml
+++ b/.gitlab-ci.yml
@@ -25,13 +25,14 @@ stages:
lint_job:
stage: lint
- image: node
+ image: "reactnativecommunity/react-native-android:latest"
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
when: manual
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
script:
- - npm install
+ - yarn install
+ - npx expo install
- npx tsc
cache:
policy: pull-push
diff --git a/app/(tabs)/budget/_layout.tsx b/app/(tabs)/budget/_layout.tsx
index ce907f3..c0835eb 100644
--- a/app/(tabs)/budget/_layout.tsx
+++ b/app/(tabs)/budget/_layout.tsx
@@ -5,6 +5,7 @@ export default function _Layout() {
+
);
diff --git a/app/(tabs)/budget/addCategory.tsx b/app/(tabs)/budget/addCategory.tsx
index 904f37c..984d98e 100644
--- a/app/(tabs)/budget/addCategory.tsx
+++ b/app/(tabs)/budget/addCategory.tsx
@@ -1,21 +1,23 @@
import { router, useLocalSearchParams } from "expo-router";
import { useState } from "react";
import { SafeAreaView, StyleSheet, Text, TextInput, View } from "react-native";
-import { CustomColorPicker, NavigationButton, TypeSelectorSwitch } from "../../../components";
+import { AutoDecimalInput, CustomColorPicker, NavigationButton, TypeSelectorSwitch } from "../../../components";
+import { addCategory } from "../../../services/database";
import { useTheme } from "../../contexts/ThemeContext";
-const addCategory = () => {
+export default function Page() {
const {colors} = useTheme();
const parameters = useLocalSearchParams();
const [categoryName, setCategoryName] = useState("Enter Category Name...");
- const [categoryColor, setCategoryColor] = useState(null);
+ const [categoryColor, setCategoryColor] = useState('#' + Math.floor(Math.random()*16777215).toString(16));
const [selectedType, setSelectedType] = useState("expense");
+ const [amount, setAmount] = useState(0);
return (
- Category Editor
+ Add Category
@@ -24,6 +26,12 @@ const addCategory = () => {
}}/>
+
+ {
+ setAmount(!Number.isNaN(Number.parseFloat(value)) ? Number.parseFloat(value) : 0);
+ }}/>
+
+
{
@@ -32,7 +40,7 @@ const addCategory = () => {
/>
- {
+ {
setCategoryColor(color);
}}/>
@@ -42,7 +50,7 @@ const addCategory = () => {
router.back();
}}/>
{
- console.log("Implement Saving here!");
+ addCategory(categoryName, categoryColor, selectedType, amount);
router.back();
}}/>
@@ -51,8 +59,6 @@ const addCategory = () => {
);
}
-export default addCategory;
-
const styles = StyleSheet.create({
containerStyle: {
flex: 1,
@@ -82,5 +88,9 @@ const styles = StyleSheet.create({
textInputStyle: {
paddingHorizontal: 10,
fontSize: 25,
+ },
+ budgetInput: {
+ marginBottom: 10,
+ marginHorizontal: 10,
}
});
\ No newline at end of file
diff --git a/app/(tabs)/budget/category.tsx b/app/(tabs)/budget/category.tsx
index dc283bf..a58d02b 100644
--- a/app/(tabs)/budget/category.tsx
+++ b/app/(tabs)/budget/category.tsx
@@ -7,12 +7,14 @@ import { useTheme } from "../../contexts/ThemeContext";
export default function Page() {
const {colors} = useTheme();
- const {category_guid, category_name} = useLocalSearchParams();
+ const {category_guid} = useLocalSearchParams();
+
+ const {category_amount, category_color, category_name, category_type} = fetchCategoryInformation(category_guid.toString());
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");
+ router.push({pathname: "./(tabs)/budget/editCategory", params: {category_guid: category_guid, category_color: category_color, category_amount: category_amount, category_name: category_name, category_type: category_type}});
}
const handleBackButton = () => {
@@ -54,6 +56,25 @@ export default function Page() {
);
}
+const fetchCategoryInformation = (guid: string) => {
+
+ const {data} = useFetch({sql: "SELECT * FROM category WHERE guid = ?", args: [guid]});
+
+ let category_name = "";
+ let category_color = "";
+ let category_amount = 0;
+ let category_type = "";
+
+ if (data && data[0]) {
+ if ("name" in data[0]) category_name = data[0].name as string;
+ if ("color" in data[0]) category_color = data[0].color as string;
+ if ("allocated_amount" in data[0]) category_amount = data[0].allocated_amount as number;
+ if ("type" in data[0]) category_type = data[0].type as string;
+ }
+
+ return {category_name, category_color, category_amount, category_type};
+}
+
const styles = StyleSheet.create({
safeAreaView: {
flex: 1,
diff --git a/app/(tabs)/budget/editCategory.tsx b/app/(tabs)/budget/editCategory.tsx
new file mode 100644
index 0000000..b3b8ec7
--- /dev/null
+++ b/app/(tabs)/budget/editCategory.tsx
@@ -0,0 +1,96 @@
+import { router, useLocalSearchParams } from "expo-router";
+import { useState } from "react";
+import { SafeAreaView, StyleSheet, Text, TextInput, View } from "react-native";
+import { AutoDecimalInput, CustomColorPicker, NavigationButton, TypeSelectorSwitch } from "../../../components";
+import { useTheme } from "../../contexts/ThemeContext";
+
+const addCategory = () => {
+ const {colors} = useTheme();
+ const {category_guid, category_amount, category_color, category_name, category_type} = useLocalSearchParams();
+
+ const [categoryName, setCategoryName] = useState(category_name.toString());
+ const [categoryColor, setCategoryColor] = useState(category_color.toString());
+ const [selectedType, setSelectedType] = useState(category_type.toString());
+ const [amount, setAmount] = useState(Number.parseFloat(category_amount.toString()));
+
+ return (
+
+ Edit Category
+
+
+
+ {
+ setCategoryName(newName);
+ }}/>
+
+
+
+ {
+ setAmount(!Number.isNaN(Number.parseFloat(value)) ? Number.parseFloat(value) : 0);
+ }}/>
+
+
+ {
+ setSelectedType(type);
+ }}
+ />
+
+
+ {
+ setCategoryColor(color);
+ }}/>
+
+
+
+ {
+ router.back();
+ }}/>
+ {
+ console.log("Implement Saving here!");
+ router.back();
+ }}/>
+
+
+
+ );
+}
+
+export default addCategory;
+
+const styles = StyleSheet.create({
+ containerStyle: {
+ flex: 1,
+ margin: 10,
+ borderRadius: 10,
+ },
+ safeAreaViewStyle: {
+ flex: 1,
+ flexDirection: "column"
+ },
+ headingTextStyle: {
+ fontSize: 40,
+ fontWeight: "bold",
+ alignSelf: "center",
+ marginVertical: 10,
+ },
+ navigationButtonViewStyle: {
+ flexDirection: "row",
+ justifyContent: "center",
+ marginBottom: 10,
+ },
+ textInputViewStyle: {
+ borderRadius: 10,
+ paddingVertical: 10,
+ margin: 10,
+ },
+ textInputStyle: {
+ paddingHorizontal: 10,
+ fontSize: 25,
+ },
+ budgetInput: {
+ marginBottom: 10,
+ marginHorizontal: 10,
+ }
+});
\ No newline at end of file
diff --git a/app/(tabs)/budget/index.tsx b/app/(tabs)/budget/index.tsx
index 9131dc7..3f2aa97 100644
--- a/app/(tabs)/budget/index.tsx
+++ b/app/(tabs)/budget/index.tsx
@@ -38,7 +38,7 @@ export default function Page() {
};
const handleCategoryPress = (item: {[column: string]: any;}) => {
- router.push({pathname: "/(tabs)/budget/category", params: {category_guid: item.category_guid, category_name: item.category_name}})
+ router.push({pathname: "./(tabs)/budget/category", params: {category_guid: item.category_guid, category_name: item.category_name}})
}
return (
diff --git a/components/budget/categoryItem.tsx b/components/budget/categoryItem.tsx
index 6c29e14..d64a29b 100644
--- a/components/budget/categoryItem.tsx
+++ b/components/budget/categoryItem.tsx
@@ -16,12 +16,12 @@ const CategoryItem = (properties: CategoryItemProps) => {
const { colors } = useTheme();
- const subText = `${properties.total_expenses} / ${properties.allocated_amount} €`;
+ const subText = `${properties.total_expenses.toFixed(2)} / ${properties.allocated_amount} €`;
return (
-
+
{properties.category}
diff --git a/components/budget/customColorPicker.tsx b/components/budget/customColorPicker.tsx
index b78e1b4..f601f12 100644
--- a/components/budget/customColorPicker.tsx
+++ b/components/budget/customColorPicker.tsx
@@ -2,14 +2,14 @@ import { StyleSheet } from "react-native";
import ColorPicker, { BrightnessSlider, HueSlider, Preview, SaturationSlider, } from "reanimated-color-picker";
export type CustomColorPickerProperties = {
- currentColor?: string | null,
+ color: string,
handleColorChange: (color: string) => void | undefined,
}
const CustomColorPicker = (properties: CustomColorPickerProperties) => {
return (
{
properties.handleColorChange(color["hex"])
}}
@@ -30,10 +30,6 @@ const CustomColorPicker = (properties: CustomColorPickerProperties) => {
);
}
-const generateRandomColor = (): string => {
- return '#' + Math.floor(Math.random()*16777215).toString(16);
-}
-
export default CustomColorPicker;
const styles = StyleSheet.create({