Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
68 changes: 55 additions & 13 deletions app/(tabs)/inboxView.jsx
Original file line number Diff line number Diff line change
@@ -1,33 +1,71 @@
import CategoryScroll from '@/components/CategoryScroll';
import CategoryMainItem from '@/components/categoryView/CategoryMainItem';
import LoadingSpinner from '@/components/common/molecules/LoadingSpinner';
// import InboxTodos from '@/components/InboxTodos';
import InboxTodos from '@/components/inboxView/inboxTodos/InboxTodos';
import CalendarBottomSheet from '@/components/todayView/dailyTodos/calendarBottomSheet/CalendarBottomSheet';
import CalendarBottomSheetProvider from '@/contexts/CalendarBottomSheetProvider';
import CategoryProvider from '@/contexts/CategoryContext';
import DateProvider from '@/contexts/DateContext';
import { LoginContext } from '@/contexts/LoginContext';
import useTodoStore from '@/contexts/TodoStore';
import useCategoriesQuery from '@/hooks/api/useCategoriesQuery';
import useInboxTodoQuery from '@/hooks/api/useInboxTodoQuery';
import { handleLogEvent, INBOXVIEW_VIEW_EVENT } from '@/utils/logEvent';
import React, { useContext } from 'react';
import { SafeAreaView, StatusBar, StyleSheet, View } from 'react-native';
import { widthPercentage } from '@/utils/responsiveSize';
import { StatusBar } from 'expo-status-bar';
import React, { Suspense, useContext } from 'react';
import { useTranslation } from 'react-i18next';
import { FlatList, SafeAreaView, StyleSheet, View } from 'react-native';

const InboxView = () => {
const { i18n } = useTranslation();
const { userId } = useContext(LoginContext);
const getLoadingText = () => {
if (i18n.language === 'ko') {
return `투두`;
} else if (i18n.language === 'en') {
return `Todo`;
}
};
handleLogEvent(INBOXVIEW_VIEW_EVENT, {
time: new Date().toISOString(),
userId: userId,
});

const renderCategoriesTodo = ({ item }) => {
return (
<View style={styles.bottomContainer}>
<CategoryMainItem item={item} />
<InboxTodos todosData={todosData} categoryId={item.id} />
</View>
);
};

const { data: categoriesData } = useCategoriesQuery(userId);
const { data: todosData } = useInboxTodoQuery(userId);
const { selectedTodo } = useTodoStore();

return (
<CategoryProvider>
<DateProvider>
<SafeAreaView style={styles.container}>
<StatusBar
backgroundColor="#FFFFFF" // 원하는 배경색으로 변경하세요
barStyle="dark-content" // 또는 "light-content"
/>
<View style={[styles.content]}>
<CategoryScroll />
<InboxTodos />
</View>
</SafeAreaView>
<CalendarBottomSheetProvider>
<SafeAreaView style={styles.container}>
<StatusBar backgroundColor="#FFFFFF" barStyle="dark-content" />
<Suspense
fallback={
<View style={styles.suspenseBox}>
<LoadingSpinner loadingText={getLoadingText()} />
</View>
}
>
<FlatList
data={categoriesData}
renderItem={renderCategoriesTodo}
/>
</Suspense>
<CalendarBottomSheet isTodo={true} item={selectedTodo} />
</SafeAreaView>
</CalendarBottomSheetProvider>
</DateProvider>
</CategoryProvider>
);
Expand All @@ -38,6 +76,10 @@ export default InboxView;
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: 'white',
},
bottomContainer: {
paddingHorizontal: widthPercentage(20),
},
content: {
flex: 1,
Expand Down
112 changes: 0 additions & 112 deletions components/inboxView/inboxTodos/InboxTodos.jsx

This file was deleted.

150 changes: 150 additions & 0 deletions components/inboxView/inboxTodos/InboxTodos.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
import CalendarBottomSheetProvider from '@/contexts/CalendarBottomSheetProvider';
import { CategoryContext } from '@/contexts/CategoryContext';
import { LoginContext } from '@/contexts/LoginContext';
import { TextInputContext } from '@/contexts/textInputContext';
import {
useTodoAddMutation,
useTodoUpdateMutation,
} from '@/hooks/api/useTodoMutations';
import useFilteredInboxTodos from '@/hooks/todo/useFilteredInboxTodo';
import '@/locales/index';
import colors from '@/theme/theme.json';
import {
DEFAULT_SCROLL_EVENT_THROTTLE,
handleScroll,
} from '@/utils/handleScroll';
import { INBOXVIEW_SCROLL_EVENT } from '@/utils/logEvent';
import { heightPercentage, widthPercentage } from '@/utils/responsiveSize';
import { Icon } from '@ui-kitten/components';
import { LexoRank } from 'lexorank';
import React, { Fragment, useContext, useState } from 'react';
import { useTranslation } from 'react-i18next';
import {
KeyboardAvoidingView,
StyleSheet,
TextInput,
View,
} from 'react-native';
import DraggableFlatList, {
ScaleDecorator,
} from 'react-native-draggable-flatlist';
import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { KeyboardAccessoryView } from 'react-native-keyboard-accessory';
import InboxTodo from './inboxTodo/InboxTodo';

interface InboxTodosProps {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
todosData: any;
categoryId: number;
}

const InboxTodos: React.FC<InboxTodosProps> = ({ todosData, categoryId }) => {
const { t } = useTranslation();
const { userId } = useContext(LoginContext);
const { selectedCategory, setSelectedCategory } = useContext(CategoryContext);
setSelectedCategory(categoryId);
const inboxCurrentTodos = useFilteredInboxTodos(todosData, categoryId);
const { mutate: addInboxTodo } = useTodoAddMutation();
const { mutate: updateInboxTodo } = useTodoUpdateMutation();
const { isTextInputOpen, activatedCategoryId } = useContext(TextInputContext);
const [input, setInput] = useState('');

const renderTodo = ({ item, drag, isActive }) => {
return (
<ScaleDecorator>
<InboxTodo item={item} drag={drag} isActive={isActive} />
</ScaleDecorator>
);
};

const handleDragEnd = async ({ data }) => {
const updatedData = data.map(item => {
return {
todoId: item.id,
order: LexoRank.parse(item.order).toString(),
};
});
updateInboxTodo(updatedData);
};
//TODO: order 순서 생각해보니까 이제 서버에서 하잖아? 일단 전체 투두에서 계속 마지막으로 붙이는 식으로 구현
const handleInputSubmit = async () => {
const newTodoData = {
content: input,
categoryId: selectedCategory,
};

addInboxTodo({ todoData: newTodoData });
setInput('');
};

return (
<GestureHandlerRootView style={{ flex: 1 }}>
<Fragment>
<CalendarBottomSheetProvider>
<KeyboardAvoidingView
behavior="padding"
style={{ flex: 1, backgroundColor: 'white' }}
>
<DraggableFlatList
data={inboxCurrentTodos}
renderItem={renderTodo}
onDragEnd={handleDragEnd}
keyExtractor={item => item.id.toString()}
onScroll={() => handleScroll(INBOXVIEW_SCROLL_EVENT, userId)}
scrollEventThrottle={DEFAULT_SCROLL_EVENT_THROTTLE}
/>
</KeyboardAvoidingView>
{isTextInputOpen && categoryId === activatedCategoryId ? (
<KeyboardAccessoryView
style={styles.keyboardInputContainer}
alwaysVisible
androidAdjustResize
>
<View style={styles.inputContainer}>
<Icon
name="minus-outline"
fill={colors.Gray02}
style={styles.checkIcon}
/>
<TextInput
placeholder={t('components.dailyTodos.writeTodo')}
value={input}
onChangeText={setInput}
onSubmitEditing={handleInputSubmit}
style={styles.textInput}
/>
</View>
</KeyboardAccessoryView>
) : null}
</CalendarBottomSheetProvider>
</Fragment>
</GestureHandlerRootView>
);
};

const styles = StyleSheet.create({
touchableCheck: {
paddingTop: 0,
justifyContent: 'center',
},
checkIcon: {
width: widthPercentage(20),
height: heightPercentage(20),
},
inputContainer: {
flexDirection: 'row',
},
textInput: {
backgroundColor: colors.Gray02,
flex: 1,
borderRadius: widthPercentage(4),
marginLeft: widthPercentage(2),
paddingHorizontal: widthPercentage(4),
},
keyboardInputContainer: {
backgroundColor: 'white',
borderTopWidth: 0,
},
});

export default InboxTodos;
Loading
Loading