diff --git a/app/(tabs)/_layout.tsx b/app/(tabs)/_layout.tsx
index 4eb7245..79ff582 100644
--- a/app/(tabs)/_layout.tsx
+++ b/app/(tabs)/_layout.tsx
@@ -25,6 +25,7 @@ export default function Layout() {
tabBarInactiveTintColor: colors.tabIconDefault,
headerShown: false,
tabBarStyle: styles.tabBar,
+ tabBarHideOnKeyboard: true
}
if(!authState?.authenticated){
diff --git a/app/(tabs)/home/_layout.tsx b/app/(tabs)/home/_layout.tsx
index f6c2a2b..abe83bf 100644
--- a/app/(tabs)/home/_layout.tsx
+++ b/app/(tabs)/home/_layout.tsx
@@ -12,10 +12,10 @@ export default function _Layout() {
initialRouteName="index"
screenOptions={{
contentStyle: {
- backgroundColor:colors.backgroundColor,
+ backgroundColor:colors.containerColor,
},
headerStyle: {
- backgroundColor: colors.backgroundColor
+ backgroundColor: colors.containerColor
},
headerTintColor: colors.primaryText
@@ -24,7 +24,9 @@ export default function _Layout() {
title: "test",
headerShown: false,
}}/>
-
+
("");
+ const [selectorModalVisible, setSelecorModalVisible] = useState(false);
+ const [selectedCategory, setSelectedCategory] = useState()
+ const [expenseName, setExpenseName] = useState("");
+ const [datePickerShown, setDatePickerShown] = useState(false);
+ const [selectedDate, setSelectedDate] = useState(new Date())
+
+ const handleValueChange = (formatedValue: string) => {
+ setFormatedValue(formatedValue);
+ }
+
+ const handleCategorySelect = (category : Category) => {
+ setSelecorModalVisible(false);
+ setSelectedCategory(category);
+ }
+
+ const validateInput = ():boolean => {
+ if(formatedValue == "" || expenseName == "" || selectedCategory === undefined || selectedDate === null){
+ return false;
+ }
+ return true;
+ }
+
+ const submit = () => {
+ const insert = async () => {
+ await addExpense(expenseName, selectedCategory?.guid!, new SimpleDate(selectedDate).format("YYYY-MM-DD"), Number(formatedValue))
+ }
+ if(validateInput()){
+ insert();
+ router.back();
+ }else {
+ Alert.alert("Invalid input", "One of the Props is not properly defined")
+ }
+
+ }
-export default function addItem() {
return (
-
- addItem
+
+ {setSelecorModalVisible(false)}} onCategoryTap={handleCategorySelect}>
+
+ {setSelecorModalVisible(true)}} selectedCategory={selectedCategory}/>
+ setExpenseName(text)}/>
+ {setDatePickerShown(true)}}/>
+ {datePickerShown &&
+ {
+ setDatePickerShown(false);
+ if(date){
+ setSelectedDate(date);
+ }
+ }}
+ />}
+
+ Save
+
)
-}
\ No newline at end of file
+}
+
+const styles = StyleSheet.create({
+ save: {
+ marginTop: 40,
+ padding: 10,
+ },
+ container: {
+ margin: SIZES.normal,
+ display: "flex",
+ gap: 10
+ },
+
+ submitText: {
+ fontSize: SIZES.large
+ }
+
+})
\ No newline at end of file
diff --git a/app/(tabs)/home/index.tsx b/app/(tabs)/home/index.tsx
index eaa0b22..5a0a5a8 100644
--- a/app/(tabs)/home/index.tsx
+++ b/app/(tabs)/home/index.tsx
@@ -1,9 +1,9 @@
import React, { useRef, useState, useMemo } from 'react';
import { NativeScrollEvent, NativeSyntheticEvent, StyleSheet, View } from 'react-native';
import { Calendar } from 'react-native-calendars';
-import { FlatList } from 'react-native-gesture-handler';
+import { FlatList, RefreshControl } from 'react-native-gesture-handler';
import { SafeAreaView } from 'react-native-safe-area-context';
-import { ExpenseItem, LoadingSymbol, Plus, SearchBar, Welcome } from '../../../components';
+import { ExpenseItem, LoadingSymbol, Plus, TextInputBar, Welcome } from '../../../components';
import useFetch from '../../../hooks/useFetch';
import { addExpense, executeQuery } from "../../../services/database";
@@ -63,7 +63,7 @@ export default function Page() {
}
}
- const {data, isLoading, reFetch} = useFetch({sql: "SELECT e.guid AS expense_guid, c.guid AS category_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, c.type AS category_type FROM expense e JOIN category c ON e.category_guid = c.guid;", args: []});
+ const {data, isLoading, reFetch} = useFetch({sql: "SELECT e.guid AS expense_guid, c.guid AS category_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, c.type AS category_type FROM expense e JOIN category c ON e.category_guid = c.guid ORDER BY expense_datetime desc;", args: []});
const expenseDates = useMemo(()=>
constructMarkedDates(data)
@@ -74,15 +74,15 @@ export default function Page() {
return (
{plusShow && {
- // router.push("/(tabs)/home/addItem");
+ router.push("/(tabs)/home/addItem");
- executeQuery({sql: "SELECT guid FROM category", args: []}).then((result) => {
- if("rows" in result[0]) {
- newExpense("Test Title", result[0]["rows"][0]["guid"], "69.69.1234", 100).then(() => {
- reFetch();
- });
- }
- })
+ // executeQuery({sql: "SELECT guid FROM category", args: []}).then((result) => {
+ // if("rows" in result[0]) {
+ // newExpense("Test Title", result[0]["rows"][0]["guid"], "69.69.1234", 100).then(() => {
+ // reFetch();
+ // });
+ // }
+ // })
}}/>}
{isLoading && }
@@ -92,7 +92,7 @@ export default function Page() {
ListHeaderComponent={
<>
{router.push("/home/userSettings")}}/>
-
-
+
>
}
renderItem = {({item}) => }
@@ -114,6 +114,9 @@ export default function Page() {
ItemSeparatorComponent={() => {
return ();
}}
+ refreshControl={
+
+ }
onScroll={handleScroll}
scrollEventThrottle={20}
/>
@@ -124,6 +127,7 @@ export default function Page() {
const styles = StyleSheet.create({
safeAreaViewStyle: {
flex: 1,
+ paddingHorizontal: 10
},
itemSeperatorStyle: {
marginVertical: 5,
diff --git a/components/budget/budgetHeader.tsx b/components/budget/budgetHeader.tsx
index eed9624..7fe8f01 100644
--- a/components/budget/budgetHeader.tsx
+++ b/components/budget/budgetHeader.tsx
@@ -1,5 +1,5 @@
import { StyleSheet, Text, TouchableHighlight, View } from "react-native";
-import SearchBar from "../common/SearchBar";
+import TextInputBar from "../common/TextInputBar";
import { useTheme } from "../../app/contexts/ThemeContext";
type BudgetHeaderProperties = {
@@ -34,7 +34,7 @@ const BudgetHeader = (properties: BudgetHeaderProperties) => {
}}
/>
-
+
>);
}
diff --git a/components/common/AutoDecimalInput.tsx b/components/common/AutoDecimalInput.tsx
new file mode 100644
index 0000000..52821fc
--- /dev/null
+++ b/components/common/AutoDecimalInput.tsx
@@ -0,0 +1,94 @@
+import { View, Text, TouchableOpacity, TextInput, StyleSheet, NativeSyntheticEvent, TextInputKeyPressEventData } from 'react-native'
+import React, {LegacyRef, MutableRefObject, useRef, useState} from 'react'
+import { SIZES } from '../../constants/theme';
+import { useTheme } from '../../app/contexts/ThemeContext';
+
+const formatDecimal = (value: string)=>{
+ switch(value.length){
+ case 0:
+ return "";
+ case 1:
+ return "0.0"+value
+ case 2:
+ return "0."+value
+ default:
+ return value.substring(0, value.length - 2) + "." + value.substring(value.length - 2, value.length)
+ }
+}
+
+interface AutoDecimalInputProps{
+ onValueChange?: (formattedValue: string) => void | undefined
+ label: string,
+}
+
+const AutoDecimalInput: React.FC = ({onValueChange, label}) => {
+ const { colors } = useTheme();
+ const inputRef = useRef(null);
+ const [pressedNumbers, setPressedNumbers] = useState("");
+
+ const update = (newValues : string) => {
+ if(onValueChange){
+ onValueChange(formatDecimal(newValues))
+ }
+ setPressedNumbers(newValues);
+ }
+
+ const handleInput = (e: NativeSyntheticEvent)=>{
+ const pressedKey:string = e.nativeEvent.key
+ if(Number.isInteger(Number.parseInt(pressedKey))){
+ if(pressedNumbers.length === 0 && pressedKey === "0"){
+ return
+ }
+ update(pressedNumbers + pressedKey)
+ }else if(pressedKey === "Backspace"){
+ update(pressedNumbers.substring(0, pressedNumbers.length - 1))
+ }
+ }
+ return (
+ {
+ if(inputRef.current)
+ inputRef.current.focus()
+ }}>
+ {label}
+
+
+ EUR
+
+
+ )
+}
+
+const styles = StyleSheet.create({
+ inputContainer: {
+ minHeight: 50,
+ borderRadius: 20,
+ flexDirection: "row",
+ justifyContent: 'space-between',
+ alignItems: "center"
+ },
+ text:{
+ fontSize: SIZES.large,
+ marginHorizontal: 15,
+ },
+ currency: {
+ fontSize: SIZES.normal,
+ color: "#007acc",
+ marginRight: 15,
+ },
+ currencyWrapper: {
+ flexDirection:"row",
+ justifyContent: 'flex-end',
+ alignItems: "center"
+ }
+})
+
+export default AutoDecimalInput;
\ No newline at end of file
diff --git a/components/common/CategoryListItem.tsx b/components/common/CategoryListItem.tsx
new file mode 100644
index 0000000..3d432a6
--- /dev/null
+++ b/components/common/CategoryListItem.tsx
@@ -0,0 +1,66 @@
+import { StyleSheet, Text, View, Pressable } from 'react-native'
+import React from 'react'
+import { Category } from '../../types/dbItems'
+import CustomCard from './CustomCard';
+import { SIZES } from '../../constants/theme';
+import { useTheme } from '../../app/contexts/ThemeContext';
+
+interface CategoryListItemProps{
+ category: Category;
+ onPress?: (category: Category) =>void | undefined
+}
+
+
+
+const CategoryListItem: React.FC = (props: CategoryListItemProps) => {
+ const {category, onPress} = props;
+ const {colors} = useTheme();
+
+ const handlePress = ()=>{
+ if(onPress){
+ onPress(category);
+ }
+ }
+
+ return (
+
+
+
+
+ {category.name ?? "#noData#"}
+
+
+
+
+ )
+}
+
+export default CategoryListItem
+
+const styles = StyleSheet.create({
+ tile: {
+ height: 60,
+ flexDirection: "row",
+ alignItems: "center",
+ justifyContent: "space-between",
+ borderRadius: 20
+ },
+ colorTip:{
+ height: "100%",
+ width: 30,
+ borderTopLeftRadius:20,
+ borderBottomLeftRadius: 20
+ },
+ textWrapper: {
+
+ },
+ tileTail:{
+ height: "100%",
+ width: 30,
+ borderTopRightRadius:20,
+ borderBottomRightRadius: 20
+ },
+ text: {
+ fontSize: SIZES.large,
+ }
+})
\ No newline at end of file
diff --git a/components/common/CustomCard.tsx b/components/common/CustomCard.tsx
index 5358d51..a866d8c 100644
--- a/components/common/CustomCard.tsx
+++ b/components/common/CustomCard.tsx
@@ -39,10 +39,7 @@ export default function CustomCard(props : ViewProps) {
const styles = StyleSheet.create({
container:{
- flexDirection: "row",
- alignItems: "stretch",
- alignContent: "space-between",
- borderRadius: 10,
+ borderRadius: 20,
marginHorizontal: 10,
},
boxShadow: {},
diff --git a/components/common/RoundedButton.tsx b/components/common/RoundedButton.tsx
new file mode 100644
index 0000000..1852212
--- /dev/null
+++ b/components/common/RoundedButton.tsx
@@ -0,0 +1,32 @@
+import { StyleSheet, Text, View, ViewProps, TouchableOpacity } from 'react-native'
+import React from 'react'
+import { SIZES } from '../../constants/theme';
+
+interface RoundedButtonProps extends ViewProps{
+ onPress?: ()=> void | undefined;
+ color: string;
+}
+
+const RoundedButton: React.FC = (props: RoundedButtonProps) => {
+ const {onPress, color, style, ...restProps} = props;
+ return (
+
+
+ {restProps.children}
+
+
+ )
+}
+
+export default RoundedButton
+
+const styles = StyleSheet.create({
+ btn:{
+ justifyContent: 'center',
+ alignItems: 'center',
+ borderRadius: 80
+ },
+ text: {
+ fontSize: SIZES.normal
+ }
+})
\ No newline at end of file
diff --git a/components/common/SearchBar.tsx b/components/common/TextInputBar.tsx
similarity index 60%
rename from components/common/SearchBar.tsx
rename to components/common/TextInputBar.tsx
index 372d052..a2ffa84 100644
--- a/components/common/SearchBar.tsx
+++ b/components/common/TextInputBar.tsx
@@ -1,14 +1,18 @@
import { AntDesign } from '@expo/vector-icons';
-import React from 'react';
+import React, { useState } from 'react';
import { StyleSheet, TextInput, TouchableOpacity, View, ViewProps } from 'react-native';
import { SIZES } from '../../constants/theme';
import { useTheme } from '../../app/contexts/ThemeContext';
-type SearchBarProps = {placeholder: string} & ViewProps
+interface SearchBarProps extends ViewProps {
+ placeholder? : string;
+ onChangeText? : (text: string) => void | undefined
+}
-export default function SearchBar(props: SearchBarProps) {
+export default function TextInputBar(props: SearchBarProps) {
const [isActive, setIsactive] = React.useState(false);
const { colors } = useTheme();
+ const [text, setText] = useState("");
const textColor = colors
const backgroundColor = colors.elementDefaultColor;
@@ -23,6 +27,10 @@ export default function SearchBar(props: SearchBarProps) {
setIsactive(false)
}
}
+ if(props.onChangeText){
+ props.onChangeText(text)
+ }
+ setText(text)
}
// cant apply the background color otherwise
@@ -34,12 +42,12 @@ export default function SearchBar(props: SearchBarProps) {
//TODO: Handle textCancel
// changed styles.container to containerStyle
return (
-
-
+
+ handleChange(text)} onEndEditing={()=>setIsactive(false)}/>
{isActive &&
-
-
+ {handleChange("")}}>
+
}
@@ -48,8 +56,6 @@ export default function SearchBar(props: SearchBarProps) {
const styles = StyleSheet.create({
container: {
- marginHorizontal: 10,
- marginBottom: 20,
flexDirection: 'row',
justifyContent: "center",
alignItems: "center",
diff --git a/components/home/addItem/CategorySelector.tsx b/components/home/addItem/CategorySelector.tsx
new file mode 100644
index 0000000..27d5cfe
--- /dev/null
+++ b/components/home/addItem/CategorySelector.tsx
@@ -0,0 +1,60 @@
+import { StyleSheet, Text, View, TouchableOpacity } from 'react-native'
+import React, { useState } from 'react'
+import { useTheme } from '../../../app/contexts/ThemeContext'
+import { SIZES } from '../../../constants/theme';
+import { Category } from '../../../types/dbItems';
+import CategorySelectorModal from './CategorySelectorModal';
+
+interface CategorySelectorProps {
+ onPress? : () => void | undefined;
+ selectedCategory? : Category;
+}
+
+const CategorySelector: React.FC = (props : CategorySelectorProps) => {
+ const {colors} = useTheme();
+
+
+ return (
+ <>
+
+
+
+
+
+ {props.selectedCategory?.name ?? "Tap to select Categroy"}
+
+
+
+ >
+ )
+}
+
+export default CategorySelector
+
+const styles = StyleSheet.create({
+ tile: {
+ height: 60,
+ flexDirection: "row",
+ alignItems: "center",
+ justifyContent: "space-between",
+ borderRadius: 20
+ },
+ colorTip:{
+ height: "100%",
+ width: 30,
+ borderTopLeftRadius:20,
+ borderBottomLeftRadius: 20
+ },
+ textWrapper: {
+
+ },
+ tileTail:{
+ height: "100%",
+ width: 30,
+ borderTopRightRadius:20,
+ borderBottomRightRadius: 20
+ },
+ text: {
+ fontSize: SIZES.large,
+ }
+})
\ No newline at end of file
diff --git a/components/home/addItem/CategorySelectorModal.tsx b/components/home/addItem/CategorySelectorModal.tsx
new file mode 100644
index 0000000..d758669
--- /dev/null
+++ b/components/home/addItem/CategorySelectorModal.tsx
@@ -0,0 +1,93 @@
+import { Modal, NativeSyntheticEvent, StyleSheet, Text, View, FlatList } from 'react-native'
+import React, { useEffect, useMemo, useState } from 'react'
+import { Category } from '../../../types/dbItems';
+import { useTheme } from '../../../app/contexts/ThemeContext';
+import CategoryListItem from '../../common/CategoryListItem';
+import { SIZES } from '../../../constants/theme';
+import useFetch from '../../../hooks/useFetch';
+import TextInputBar from '../../common/TextInputBar';
+
+
+interface CategorySelectorModalProps{
+ visible: boolean;
+ onCategoryTap?: (category : Category) => void | undefined;
+ selectMulitple?: boolean;
+ onRequestClose?: ((event: NativeSyntheticEvent) => void) | undefined;
+}
+
+//TODO: select Multiple
+
+const CategorySelectorModal: React.FC = (props : CategorySelectorModalProps) => {
+ const {visible, onCategoryTap, selectMulitple} = props;
+ const {data, reFetch} = useFetch({sql: "SELECT * FROM category;", args:[]});
+ const {colors} = useTheme();
+ const [searchtext, setSearchtext] = useState("");
+
+ const handleSearchText = (text : string) => {
+ setSearchtext(text);
+ }
+
+ const categories = useMemo(()=>{
+ return data.map((elem) => {
+ return {name: elem["name"], color: elem["color"], guid: elem["guid"]}
+ })
+ }, [data])
+
+ const filteredCategories = categories.filter((category) => category.name?.toLowerCase().includes(searchtext.toLowerCase()))
+
+ useEffect(()=>{
+ if(visible){
+ //reFetch(); Uncomment if newly added categories do not appear
+ handleSearchText("");
+ }
+ }, [visible])
+
+ return (
+
+
+
+
+ {selectMulitple ? "Categories" : "Category"}
+
+
+ item.guid!}
+ renderItem={({item})=> }
+ ItemSeparatorComponent={() => }
+ ListFooterComponent={() => }
+ keyboardShouldPersistTaps="always"
+ >
+
+
+
+
+
+ )
+}
+
+export default CategorySelectorModal
+
+const styles = StyleSheet.create({
+ main: {
+ backgroundColor: 'rgba(0, 0, 0, 0.5)',
+ height: "100%",
+ width: "100%",
+ alignItems: "center",
+ },
+ modal: {
+ height: "70%",
+ width: "90%",
+ top: "10%",
+ borderRadius: 30,
+ paddingVertical: 20,
+ paddingHorizontal: 20
+ },
+ heading: {
+ fontSize: SIZES.xlarge,
+ fontWeight: "bold"
+ },
+ itemSeperatorStyle: {
+ paddingBottom: 10
+ }
+})
\ No newline at end of file
diff --git a/components/home/addItem/DateSelectorButton.tsx b/components/home/addItem/DateSelectorButton.tsx
new file mode 100644
index 0000000..4f07297
--- /dev/null
+++ b/components/home/addItem/DateSelectorButton.tsx
@@ -0,0 +1,38 @@
+import { View, Text, StyleSheet, TouchableOpacity, TouchableOpacityProps } from 'react-native'
+import React, { useState } from 'react'
+import { useTheme } from '../../../app/contexts/ThemeContext';
+import { SIZES } from '../../../constants/theme';
+import { SimpleDate } from '../../../util/SimpleDate';
+import { ViewProps } from 'react-native/Libraries/Components/View/ViewPropTypes';
+
+interface DateSelectorProps extends ViewProps {
+ onPress?: ()=>void | undefined;
+ selectedDate: Date
+}
+
+const DateSelectorButton:React.FC = (props: DateSelectorProps) => {
+ const {onPress, selectedDate, ...restProps} = props;
+ const {colors} = useTheme();
+
+ return (
+
+ Date:
+ {new SimpleDate(selectedDate).format("DD.MM.YYYY")}
+
+ )
+}
+const styles = StyleSheet.create({
+ inputContainer: {
+ minHeight: 50,
+ borderRadius: 20,
+ flexDirection: "row",
+ justifyContent: 'space-between',
+ alignItems: "center"
+ },
+ text:{
+ fontSize: SIZES.large,
+ marginHorizontal: 15,
+ },
+})
+
+export default DateSelectorButton
\ No newline at end of file
diff --git a/components/home/expenseItem.tsx b/components/home/expenseItem.tsx
index d541d48..ade5ccd 100644
--- a/components/home/expenseItem.tsx
+++ b/components/home/expenseItem.tsx
@@ -9,28 +9,29 @@ export default function ExpenseItem(itemProps : ExpenseItemProps) {
const { colors } = useTheme();
return (
-
-
- {itemProps.category}
- {itemProps.title}
- {itemProps.date}
-
-
- {itemProps.value}
-
-
+
+
+
+ {itemProps.category}
+ {itemProps.title}
+ {itemProps.date}
+
+
+ {itemProps.value}
+
+
)
@@ -42,6 +43,12 @@ const styles = StyleSheet.create({
borderTopLeftRadius: 20,
borderBottomLeftRadius: 20,
},
+
+ tile: {
+ flexDirection: "row",
+ alignItems: "stretch",
+ alignContent: "space-between",
+ },
textSection: {
flexDirection: "column",
diff --git a/components/index.tsx b/components/index.tsx
index f3dd44f..b20c5fd 100644
--- a/components/index.tsx
+++ b/components/index.tsx
@@ -3,14 +3,21 @@ import { ButtonSetting, ToggleSetting } from "./home/Setting"
import Welcome from "./home/Welcome"
import ExpenseItem from "./home/expenseItem"
+//home/addItem
+import CategorySelector from "./home/addItem/CategorySelector"
+import CategorySelectorModal from "./home/addItem/CategorySelectorModal"
+import DateSelectorButton from "./home/addItem/DateSelectorButton"
+
//common
import CustomCard from "./common/CustomCard"
-import SearchBar from "./common/SearchBar"
import NavigationButton from "./common/button"
import LoadingSymbol from "./common/loadingSymbol"
import Plus from "./common/plus"
+import TextInputBar from "./common/TextInputBar"
+import AutoDecimalInput from "./common/AutoDecimalInput"
+import RoundedButton from "./common/RoundedButton"
-//budget
+//login
import BudgetHeader from "./budget/budgetHeader"
import CategoryItem from "./budget/categoryItem"
import CustomColorPicker from "./budget/customColorPicker"
@@ -20,8 +27,24 @@ import TypeSelectorSwitch from "./budget/typeSelectorSwitch"
import Input from "./login/input"
export {
- BudgetHeader, ButtonSetting, CategoryItem, CustomCard, CustomColorPicker, ExpenseItem, Input,
- LoadingSymbol, NavigationButton, Plus,
- SearchBar, ToggleSetting, TypeSelectorSwitch, Welcome
+ BudgetHeader,
+ ButtonSetting,
+ CustomCard,
+ ExpenseItem,
+ Input,
+ LoadingSymbol,
+ Plus,
+ TextInputBar,
+ ToggleSetting,
+ Welcome,
+ AutoDecimalInput,
+ CategorySelector,
+ CategorySelectorModal,
+ DateSelectorButton,
+ RoundedButton,
+ CategoryItem,
+ TypeSelectorSwitch,
+ NavigationButton,
+ CustomColorPicker
}
diff --git a/package-lock.json b/package-lock.json
index 16b6032..aab706f 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -10,6 +10,7 @@
"dependencies": {
"@expo/vector-icons": "^13.0.0",
"@react-native-async-storage/async-storage": "1.18.2",
+ "@react-native-community/datetimepicker": "7.2.0",
"@react-navigation/native": "^6.0.2",
"expo": "~49.0.15",
"expo-font": "~11.4.0",
@@ -6275,6 +6276,14 @@
"resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz",
"integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A=="
},
+ "node_modules/@react-native-community/datetimepicker": {
+ "version": "7.2.0",
+ "resolved": "https://registry.npmjs.org/@react-native-community/datetimepicker/-/datetimepicker-7.2.0.tgz",
+ "integrity": "sha512-dO1sQy83M/EvnHE2egto05iwXZX7EYn5f/VDMp6afZFRFXRiRo7CzB3VFg4B55gJRJMNBv06NYMLPM3SlpnEGQ==",
+ "dependencies": {
+ "invariant": "^2.2.4"
+ }
+ },
"node_modules/@react-native/assets-registry": {
"version": "0.72.0",
"resolved": "https://registry.npmjs.org/@react-native/assets-registry/-/assets-registry-0.72.0.tgz",
diff --git a/package.json b/package.json
index abb4142..2e627b2 100644
--- a/package.json
+++ b/package.json
@@ -41,7 +41,8 @@
"react-native-screens": "~3.22.0",
"react-native-uuid": "^2.0.1",
"react-native-web": "~0.19.6",
- "reanimated-color-picker": "^2.4.2"
+ "reanimated-color-picker": "^2.4.2",
+ "@react-native-community/datetimepicker": "7.2.0"
},
"devDependencies": {
"@babel/core": "^7.20.0",
diff --git a/services/DebugMenu.tsx b/services/DebugMenu.tsx
index 896a667..29ce4e8 100644
--- a/services/DebugMenu.tsx
+++ b/services/DebugMenu.tsx
@@ -1,6 +1,6 @@
import React from 'react';
import { View, Button, Alert } from 'react-native';
-import { addCategory, addExpense, deleteExpenses, deleteCategories, DEV_populateDatabase } from './database';
+import { addCategory, addExpense, deleteExpenses, deleteCategories, DEV_populateDatabase, deleteDatabase } from './database';
import uuid from 'react-native-uuid';
const randomColors = ["red", "blue", "green", "purple", "yellow"];
@@ -19,6 +19,11 @@ const getRandomNumber = () => {
const DebugMenu = () => {
+ const deleteDBFile = () => {
+ console.warn("Deleting DB. App Restart is required")
+ return deleteDatabase();
+ }
+
const handleNukeDatabase = () => {
return deleteExpenses(), deleteCategories()
};
@@ -60,6 +65,7 @@ const DebugMenu = () => {
return (
+