Major refactoring: navigation does not break anymore. the user can now navigate between the tabs without loosing context
This commit is contained in:
parent
457b098883
commit
1beee68bff
23 changed files with 137 additions and 80 deletions
|
|
@ -1,133 +0,0 @@
|
|||
import React, { useMemo, useRef, useState } from 'react';
|
||||
import { NativeScrollEvent, NativeSyntheticEvent, StyleSheet, View } from 'react-native';
|
||||
import { Calendar } from 'react-native-calendars';
|
||||
import { FlatList, RefreshControl } from 'react-native-gesture-handler';
|
||||
import { SafeAreaView } from 'react-native-safe-area-context';
|
||||
import { ExpenseItem, LoadingSymbol, Plus, TextInputBar, Welcome } from '../../../components';
|
||||
import useFetch from '../../../hooks/useFetch';
|
||||
|
||||
import { useRouter } from "expo-router";
|
||||
import { addExpense } from "../../../services/database";
|
||||
import { SimpleDate } from '../../../util/SimpleDate';
|
||||
import { useTheme } from '../../contexts/ThemeContext';
|
||||
|
||||
|
||||
interface MarkingProps {
|
||||
dots?:{color:string, selectedColor?:string, key?:string}[];
|
||||
}
|
||||
|
||||
type MarkedDates = {
|
||||
[key: string]: MarkingProps;
|
||||
}
|
||||
|
||||
const constructMarkedDates = (data : {[column: string]: any}) => {
|
||||
let markedDates: MarkedDates = {};
|
||||
data.forEach((value: any) => {
|
||||
const dateKey: string = String(value["expense_datetime"]).split(" ")[0]
|
||||
|
||||
if(markedDates[dateKey] === undefined){
|
||||
markedDates[dateKey] = {dots: []}
|
||||
}
|
||||
markedDates[dateKey].dots?.push({color: value["category_color"]})
|
||||
})
|
||||
return markedDates;
|
||||
}
|
||||
|
||||
export default function Page() {
|
||||
const { colors, theme } = useTheme()
|
||||
|
||||
|
||||
|
||||
const router = useRouter();
|
||||
const [plusShow, setPlusShow] = useState(true);
|
||||
const prevOffset = useRef(0);
|
||||
|
||||
|
||||
const profile = require("../../../assets/images/profile.jpg")
|
||||
|
||||
const handleScroll = (event: NativeSyntheticEvent<NativeScrollEvent>)=>{
|
||||
const currentOffset = event.nativeEvent.contentOffset.y >= 0 ? event.nativeEvent.contentOffset.y : 0
|
||||
const isScrollingUp : boolean = currentOffset <= prevOffset.current;
|
||||
const isTop : boolean = currentOffset === 0
|
||||
prevOffset.current = currentOffset
|
||||
setPlusShow(isScrollingUp || isTop)
|
||||
}
|
||||
|
||||
const newExpense = async (title: string, category_guid: string, date: string, amount: number) => {
|
||||
try {
|
||||
await addExpense(title, category_guid, date, amount);
|
||||
} catch (error: any) {
|
||||
console.error("Adding new expense has failed: ", error);
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
, [data])
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<SafeAreaView edges={["left", "right", "top"]} style={[styles.safeAreaViewStyle, {backgroundColor: colors.containerColor}]}>
|
||||
{plusShow && <Plus onPress={()=>{
|
||||
router.push("/(tabs)/home/expense/new");
|
||||
|
||||
// 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 && <LoadingSymbol/>}
|
||||
|
||||
<FlatList
|
||||
data={data}
|
||||
ListHeaderComponent={
|
||||
<>
|
||||
<Welcome name="My Dude" image={profile} onPress={() => {router.push("/home/userSettings")}}/>
|
||||
<Calendar key={theme} maxDate={SimpleDate.now().format("YYYY-MM-DD")} style={{borderRadius: 20, padding:10}} theme={{
|
||||
dayTextColor: colors.primaryText,
|
||||
textDisabledColor: colors.secondaryText,
|
||||
todayTextColor: colors.accentColor,
|
||||
calendarBackground: colors.containerColor,
|
||||
arrowColor: colors.accentColor,
|
||||
monthTextColor: colors.accentColor
|
||||
|
||||
}}
|
||||
markingType='multi-dot'
|
||||
markedDates={expenseDates}
|
||||
>
|
||||
|
||||
</Calendar>
|
||||
<TextInputBar placeholder='Type to Search...' style={{marginBottom: 20}}></TextInputBar>
|
||||
</>
|
||||
}
|
||||
renderItem = {({item}) => <ExpenseItem category={item.category_name} color={item.category_color} date={item.expense_datetime} title={item.expense_name} value={item.expense_amount} guid={item.expense_guid} onPress={(guid) => {router.push(`/(tabs)/home/expense/${guid}`)}}/>}
|
||||
keyExtractor={item => item.expense_guid}
|
||||
ItemSeparatorComponent={() => {
|
||||
return (<View style={styles.itemSeperatorStyle}/>);
|
||||
}}
|
||||
refreshControl={
|
||||
<RefreshControl refreshing={isLoading} onRefresh={reFetch}/>
|
||||
}
|
||||
onScroll={handleScroll}
|
||||
scrollEventThrottle={20}
|
||||
/>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
safeAreaViewStyle: {
|
||||
flex: 1,
|
||||
paddingHorizontal: 10
|
||||
},
|
||||
itemSeperatorStyle: {
|
||||
marginVertical: 5,
|
||||
}
|
||||
});
|
||||
Reference in a new issue