Commit 1e3cf37d authored by Choi Ga Young's avatar Choi Ga Young
Browse files

Merge remote-tracking branch 'origin/newShyun' into rkyoung

parents a43aed94 d4207d12
...@@ -13,6 +13,7 @@ import DeptPage from './DeptPage'; ...@@ -13,6 +13,7 @@ import DeptPage from './DeptPage';
import InfoDetails from './screens/InfoDetails'; import InfoDetails from './screens/InfoDetails';
import MemoPage from './MemoPage'; import MemoPage from './MemoPage';
import MemoDetails from './screens/MemoDetails'; import MemoDetails from './screens/MemoDetails';
import EditOption from './EditOption';
const Tab = createBottomTabNavigator(); const Tab = createBottomTabNavigator();
const Stack = createStackNavigator(); const Stack = createStackNavigator();
...@@ -80,6 +81,11 @@ function App() { ...@@ -80,6 +81,11 @@ function App() {
component={MemoDetails} component={MemoDetails}
options={{ title: "상세내용" }} /> options={{ title: "상세내용" }} />
<Stack.Screen name="DetailInfo" component={DetailInfo} /> <Stack.Screen name="DetailInfo" component={DetailInfo} />
<Stack.Screen
name="EditOption"
component={EditOption}
options={{ title: "편집" }}
/>
</Stack.Navigator> </Stack.Navigator>
</NavigationContainer> </NavigationContainer>
); );
......
import React, { useEffect, useState } from 'react';
import { View, Text, StyleSheet, FlatList, Modal, Pressable } from 'react-native';
import editApi from './db/editOption.api';
import AntDesign from 'react-native-vector-icons/AntDesign';
import InputBox from './components/InputBox';
import StyledButton from './components/StyledButton';
import Accordion, { AccordionItem } from './components/Accordion';
const INIT_OPTION = { id: 0, value: '' }
const INIT_SUBOPTION = { id: 0, value: '', foreign_id: 0 }
const EditOption = ({ route }) => {
console.log('catEdit: type_id ', route.params)
const type = route.params ? 'category' : 'asset'
const type_id = route.params
const [options, setOptions] = useState([])
const [option, setOption] = useState(INIT_OPTION)
const [modalOpen, setModalOpen] = useState(false)
const modalClose = () => { setModalOpen(false); setOption(INIT_OPTION) }
const [error, setError] = useState("");
const [loading, setLoading] = useState(false);
useEffect(() => {
loadOptions()
}, [])
const loadOptions = async () => {
try {
let optionArray = []
if (type === 'asset') {
optionArray = await editApi.selectAssetsType()
} else if (type === 'category') {
optionArray = await editApi.selectCategories(type_id)
}
setOptions(optionArray)
} catch (error) {
}
}
const handleUpdate = async () => {
try {
if (type === 'asset') {
const res = await editApi.updateOption('assets_type', { id: option.id, name: 'assets', value: option.value })
console.log(res)
} else if (type === 'category') {
if (option.foreign_id && option.foreign_id > 0) {
const res = await editApi.updateOption('subcategories', { id: option.id, name: 'subcategory', value: option.value })
return console.log(res)
}
const res = await editApi.updateOption('categories', { id: option.id, name: 'category', value: option.value })
console.log(res)
}
} catch (error) {
} finally {
loadOptions()
modalClose()
}
}
const handleDelete = async (item) => {
try {
if (type === 'asset') {
const res = await editApi.deleteOption('assets_type', { id: item.id, name: 'assets' })
console.log(res)
} else if (type === 'category') {
if (item.foreign_id && item.foreign_id > 0) {
const res = await editApi.deleteOption('subcategories', { id: item.id, name: 'subcategory'})
return console.log(res)
}
const res = await editApi.deleteOption('categories', { id: item.id, name: 'category' })
console.log(res)
}
} catch (error) {
} finally {
loadOptions()
}
}
const handleAdd = async () => {
try {
if (type === 'asset') {
const res = await editApi.addOption('assets_type', { name: 'assets', value: option.value })
console.log(res)
} else if (type === 'category') {
if (option.foreign_id && option.foreign_id > 0) {
const res = await editApi.addOption('subcategories', { name: 'subcategory', value: option.value, foreign_name: 'category', foreign_id: option.foreign_id })
return console.log(res)
}
const res = await editApi.addOption('categories', { name: 'category', value: option.value, foreign_name: 'type', foreign_id: type_id })
console.log(res)
}
} catch (error) {
} finally {
loadOptions()
modalClose()
}
}
const renderAssetItem = ({ item }) => (
<View style={[style.flexRow, style.catBox]}>
<View style={style.flexRow}>
{item.deletable && <AntDesign name='minuscircle' style={style.cancelIcon} onPress={() => { handleDelete(item) }} />}
<Text style={style.optionText} >
{item.value}
</Text>
</View>
{item.deletable && <AntDesign name='edit' style={style.icon} onPress={() => { setOption(item); setModalOpen(true) }} />}
</View>
);
const renderCatItem = ({ item }) => (
<Accordion
title={item.value}
left={item.deletable && <AntDesign name='closecircle' style={style.cancelIcon} onPress={() => { handleDelete(item) }} />}
right={item.deletable && <AntDesign name='edit' style={style.icon} onPress={() => { setOption(item); setModalOpen(true) }} />}
titleStyle={style.optionText}
backgroundColor='lightgray'
>
{item.subOptions.length !== 0 &&
<FlatList
data={item.subOptions}
renderItem={({ item }) => (
<AccordionItem
title={item.value}
left={<AntDesign name='closecircle' style={style.cancelIcon} onPress={() => { handleDelete(item) }} />}
right={<AntDesign name='edit' style={style.icon} onPress={() => { setOption(item); setModalOpen(true) }} />}
titleStyle={style.optionText}
backgroundColor='#b0b0b0'
marginLeft={30}
/>
)}
keyExtractor={item => item.id.toString()}
/>
}
<Pressable
style={[style.flexRow, { backgroundColor: "#b0b0b0", paddingVertical: 10 }]}
onPress={() => {
setOption({...INIT_SUBOPTION, ['foreign_id']: item.id});
setModalOpen(true)
}}
>
<AntDesign name='plus' style={[style.addIcon, { marginLeft: 35 }]} />
<Text style={style.optionText} >추가하기</Text>
</Pressable>
</Accordion>
);
return (
<>
{console.log(option)}
<View>
<FlatList
data={options}
renderItem={type === 'asset' ? renderAssetItem : renderCatItem}
keyExtractor={item => item.id.toString()}
/>
<Pressable style={style.addButton} onPress={() => setModalOpen(true)}>
<AntDesign name='plus' style={style.icon} />
<Text style={style.optionText} >추가하기</Text>
</Pressable>
</View>
<Modal
transparent
swipeDirection="down"
animationType_id="fade"
visible={modalOpen}
onRequestClose={modalClose}
>
<View style={style.modalContainer}>
<View style={style.modalHeader}>
<View style={{ flexDirection: "row" }}>
<AntDesign name='caretleft' style={style.icon} onPress={() => modalClose()} />
<Text style={style.Font}>{option.id === 0 ? '추가' : '수정'}</Text>
</View>
</View>
<View style={style.modalBody}>
<InputBox
placeholder="이름을 입력하세요."
onChangeText={
(name) => setOption({ ...option, value: name })
}
value={option.value}
maxLength={30}
/>
<View style={style.buttonRow}>
<StyledButton
name="저장하기"
onPress={option.id === 0 ? handleAdd : handleUpdate}
style={style.submitButton}
/>
</View>
</View>
</View>
</Modal>
</>
)
}
const style = StyleSheet.create({
flexRow: {
flexDirection: 'row',
},
flexCenter: {
justifyContent: 'center',
alignItems: 'center',
},
catBox: {
justifyContent: 'space-between',
paddingVertical: 10,
backgroundColor: 'lightgray',
},
Font: {
fontSize: 24
},
icon: {
marginHorizontal: 5,
fontSize: 30,
color: 'black',
},
addIcon: {
marginHorizontal: 5,
fontSize: 25,
color: 'black',
},
cancelIcon: {
marginHorizontal: 5,
fontSize: 25,
color: 'red',
},
rightIcon: {
marginHorizontal: 5,
fontSize: 20,
color: 'black',
},
optionText: {
fontSize: 20,
marginHorizontal: 10,
},
addButton: {
flexDirection: 'row',
justifyContent: 'center',
alignItems: 'center',
paddingVertical: 10,
backgroundColor: 'gray',
margin: 15
},
modalContainer: {
flex: 1,
backgroundColor: 'white',
},
modalHeader: {
padding: 10,
},
modalBody: {
},
buttonRow: {
flexDirection: 'row',
alignItems: "center",
marginHorizontal: 10,
marginVertical: 3,
},
submitButton: {
flex: 1,
height: 50,
},
});
export default EditOption;
\ No newline at end of file
...@@ -6,69 +6,75 @@ import SelectForm from './components/SelectForm'; ...@@ -6,69 +6,75 @@ import SelectForm from './components/SelectForm';
import StyledButton from './components/StyledButton'; import StyledButton from './components/StyledButton';
import DatePicker from './components/DatePicker'; import DatePicker from './components/DatePicker';
import moneyApi from './db/postMoney.api'; import moneyApi from './db/postMoney.api';
import { getDate } from './utils/dateFunction'
const getDate = () => { const INIT_ASSETSTYPE = {
var date = new Date(); id: 1,
return (String(date.toJSON()).split(/T/)[0]) value: '',
} }
const INIT_SUBCATEGORIES = [ const INIT_CATEGORY = {
{ id: 1,
id: 1, value: '',
value: '간식', }
foreign_id: 1
}, const INIT_SUBCATEGORY = {
{ id: 1,
id: 2, value: '',
value: '외식', foreign_id: 0,
foreign_id: 1 }
},
{
id: 3,
value: '배달',
foreign_id: 1
},
{
id: 4,
value: '택시',
foreign_id: 2
},
{
id: 5,
value: '영화',
foreign_id: 3
},
{
id: 6,
value: '뮤지컬',
foreign_id: 3
},
]
const PostMoney = () => { const PostMoney = ({navigation}) => {
const [selectedIndex, setSelectedIndex] = useState(0) const [selectedIndex, setSelectedIndex] = useState(0)
const [date, setDate] = useState(getDate()) const [date, setDate] = useState(getDate())
const [contents, setContents] = useState('') const [contents, setContents] = useState('')
const [price, setPrice] = useState(0) const [price, setPrice] = useState('')
const [asset_type, setAsset_type] = useState([]) const [asset_type, setAsset_type] = useState([])
const [selected_asset_type, setSelected_asset_type] = useState(0) const [selected_asset_type, setSelected_asset_type] = useState(INIT_ASSETSTYPE)
const [selected_deposit_asset_type, setSelected_deposit_asset_type] = useState(INIT_ASSETSTYPE)
const [categories, setCategories] = useState([]) const [categories, setCategories] = useState([])
const [selected_cat, setSelected_cat] = useState(0) const [selected_cat, setSelected_cat] = useState(INIT_CATEGORY)
const [subcategories, setSubcategories] = useState(INIT_SUBCATEGORIES) const [subcategories, setSubcategories] = useState([])
const [selected_subcat, setSelected_subcat] = useState(0) const [selected_subcat, setSelected_subcat] = useState(INIT_SUBCATEGORY)
const [success, setSuccess] = useState(false)
console.log('type: ', selectedIndex, '| date: ', date, '| contents: ', contents, '| price: ', price, '| selected_asset_type: ', selected_asset_type, '| selected_cat: ', selected_cat, '| selected_subcat: ', selected_subcat) useEffect(() => {
loadCat()
loadSubCat()
loadAssetType()
initData()
}, [selectedIndex])
const insertData = async () => { const initData = () => {
try { setDate(getDate())
let type = '' setContents('')
setPrice('')
setSelected_asset_type(INIT_ASSETSTYPE)
setSelected_cat(INIT_CATEGORY)
setSelected_subcat(INIT_SUBCATEGORY)
}
if (selectedIndex === 0) { type = '수입' } console.log(
else if (selectedIndex === 1) { type = '지출' } 'type: ', selectedIndex,
else { type = '이동' } '| date: ', date,
'| contents: ', contents,
'| price: ', price,
'| selected_asset_type: ', selected_asset_type.id,
'| 이동일 때 ', (selectedIndex === 2 ? { ['selected_deposit_asset_type']: selected_deposit_asset_type.id } : null),
'| selected_cat: ', selected_cat.id,
'| selected_subcat: ', selected_subcat.id)
const result = await moneyApi.insertMoney([type, date, contents, price, selected_asset_type, selected_cat, selected_subcat]) const insertData = async () => {
console.log(result) try {
let type = selectedIndex + 1;
if (type === 3) {
await moneyApi.insertMoney([type, date, contents, -price, selected_asset_type.id, selected_cat.id, selected_subcat.id])
await moneyApi.insertMoney([type, date, contents, price, selected_deposit_asset_type.id, selected_cat.id, selected_subcat.id])
} else {
await moneyApi.insertMoney([type, date, contents, price, selected_asset_type.id, selected_cat.id, selected_subcat.id])
}
setSuccess(true)
} catch (error) { } catch (error) {
console.log('error in insert data', error) console.log('error in insert data', error)
} }
...@@ -76,14 +82,24 @@ const PostMoney = () => { ...@@ -76,14 +82,24 @@ const PostMoney = () => {
const loadCat = async () => { const loadCat = async () => {
try { try {
const catArray = await moneyApi.selectCategories() const catArray = await moneyApi.selectCategories(selectedIndex + 1)
console.log('catload', catArray) console.log('catload', catArray)
setCategories(catArray); setCategories(catArray);
} catch (error) { } catch (error) {
console.log('error in load categories ( postMoney.js )', error) console.log('error in load categories ( postMoney.js )', error)
} }
} }
const loadSubCat = async () => {
try {
const subCatArray = await moneyApi.selectSubCategories()
console.log('catload', subCatArray)
setSubcategories(subCatArray);
} catch (error) {
console.log('error in load categories ( postMoney.js )', error)
}
}
const loadAssetType = async () => { const loadAssetType = async () => {
try { try {
const assetsTypeArray = await moneyApi.selectAssetsType() const assetsTypeArray = await moneyApi.selectAssetsType()
...@@ -93,11 +109,18 @@ const PostMoney = () => { ...@@ -93,11 +109,18 @@ const PostMoney = () => {
} }
} }
const onUpdateCatPress = () => {
navigation.navigate('EditOption', selectedIndex+1)
}
useEffect(() => { const onUpdateAssetPress = () => {
loadCat() navigation.navigate('EditOption', 0)
loadAssetType() }
}, [])
if(success){
initData()
setSuccess(false)
}
return ( return (
<View> <View>
...@@ -114,6 +137,7 @@ const PostMoney = () => { ...@@ -114,6 +137,7 @@ const PostMoney = () => {
<InputBox <InputBox
inputTitle="내용" inputTitle="내용"
placeholder="내용을 입력하세요" placeholder="내용을 입력하세요"
value={contents}
onChangeText={ onChangeText={
(contents) => setContents(contents) (contents) => setContents(contents)
} }
...@@ -122,6 +146,7 @@ const PostMoney = () => { ...@@ -122,6 +146,7 @@ const PostMoney = () => {
<InputBox <InputBox
inputTitle="금액" inputTitle="금액"
placeholder="금액을 입력하세요" placeholder="금액을 입력하세요"
value={price}
onChangeText={ onChangeText={
(price) => setPrice(price) (price) => setPrice(price)
} }
...@@ -129,21 +154,32 @@ const PostMoney = () => { ...@@ -129,21 +154,32 @@ const PostMoney = () => {
maxLength={30} maxLength={30}
/> />
<SelectForm <SelectForm
inputTitle="자산" inputTitle={selectedIndex === 2 ? "출금" : "자산"}
placeholder="자산 선택" placeholder="자산 선택"
data={asset_type} data={asset_type}
selectedData={selected_asset_type} selectedData={selected_asset_type}
onValueChange={(assetId) => setSelected_asset_type(assetId)} onValueChange={(asset) => setSelected_asset_type(asset)}
onUpdateDataPress={onUpdateAssetPress}
/> />
{selectedIndex === 2 &&
<SelectForm
inputTitle="입금"
placeholder="자산 선택"
data={asset_type}
selectedData={selected_deposit_asset_type}
onValueChange={(deposit_asset) => setSelected_deposit_asset_type(deposit_asset)}
onUpdateDataPress={onUpdateAssetPress}
/>}
<SelectForm <SelectForm
inputTitle="구분" inputTitle="구분"
placeholder="카테고리 선택" placeholder="카테고리 선택"
data={categories} data={categories}
selectedData={selected_cat} selectedData={selected_cat}
onValueChange={(catId) => setSelected_cat(catId)} onValueChange={(cat) => setSelected_cat(cat)}
subData={subcategories} subData={subcategories}
selectedSubData={selected_subcat} selectedSubData={selected_subcat}
onSubValueChange={(subcatId) => setSelected_subcat(subcatId)} onSubValueChange={(subcat) => setSelected_subcat(subcat)}
onUpdateDataPress={onUpdateCatPress}
/> />
</View> </View>
<View style={style.buttonRow}> <View style={style.buttonRow}>
......
import React, { useState } from 'react';
import { Animated, Text, View, StyleSheet, Pressable } from 'react-native';
import AntDesign from 'react-native-vector-icons/AntDesign';
const Accordion = ({
title,
left,
right,
children,
titleStyle = style.text,
backgroundColor = 'lightgray',
}) => {
const [opened, setOpened] = useState(false);
const handleOpen = () => { setOpened(!opened) };
return (
<View>
<View>
<Pressable
style={[style.flexRow, style.catBox, { backgroundColor: backgroundColor }]}
onPress={handleOpen}
>
<View style={[style.flexRow, style.flexCenter]}>
{left ? left : null}
<Text style={titleStyle}>
{title}
</Text>
</View>
<View style={[style.flexRow, style.flexCenter]}>
{right ? right : null}
<AntDesign
name={opened ? 'caretup' : 'caretdown'}
color='black'
size={24}
style={style.rightIcon}
/>
</View>
</Pressable>
</View>
{opened ?
children
: null}
</View>
)
};
export const AccordionItem = ({
title,
left,
right,
titleStyle = style.text,
backgroundColor = 'lightgray',
marginLeft = 20,
}) => {
return (
<View style={[style.flexRow, style.flexCenter, style.catBox, { backgroundColor: backgroundColor }]}>
<View style={[style.flexRow, style.flexCenter, { marginLeft: marginLeft }]}>
{left ? left : null}
<Text style={titleStyle}>
{title}
</Text>
</View>
{right ? right : null}
</View>
);
};
const style = StyleSheet.create({
flexRow: {
flexDirection: 'row',
},
flexCenter: {
justifyContent: 'center',
alignItems: 'center',
},
catBox: {
justifyContent: 'space-between',
paddingVertical: 10,
},
rightIcon: {
marginHorizontal: 5,
fontSize: 20,
color: 'black',
},
text: {
fontSize: 20,
marginHorizontal: 10,
},
})
export default Accordion
\ No newline at end of file
...@@ -4,9 +4,11 @@ import { StyleSheet, Text, View, TextInput } from 'react-native'; ...@@ -4,9 +4,11 @@ import { StyleSheet, Text, View, TextInput } from 'react-native';
const InputBox = (props) => { const InputBox = (props) => {
return ( return (
<View style={style.container}> <View style={style.container}>
<View style={style.inputTitleArea}> {props.inputTitle &&
<Text style={style.inputTitle}>{props.inputTitle}</Text> <View style={style.inputTitleArea}>
</View> <Text style={style.inputTitle}>{props.inputTitle}</Text>
</View>
}
<TextInput <TextInput
underlineColorAndroid="transparent" underlineColorAndroid="transparent"
placeholder={props.placeholder} placeholder={props.placeholder}
......
import React, { useState, useEffect } from 'react'; import React, { useState, useEffect } from 'react';
import { TouchableOpacity } from 'react-native'; import { StyleSheet, TouchableOpacity, TouchableWithoutFeedback, View, Text, Modal, FlatList } from 'react-native';
import { StyleSheet, TouchableWithoutFeedback, View, Text, Modal, FlatList, Animated } from 'react-native';
import Notification from './Notification';
import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons'; import MaterialCommunityIcons from 'react-native-vector-icons/MaterialCommunityIcons';
const SelectForm = (props) => { const INIT_SUBCATEGORY = {
const [option, setOption] = useState([]) id: 1,
const [optionId, setOptionId] = useState(0) value: '',
const [optionValue, setOptionValue] = useState('') foreign_id: 0,
}
const SelectForm = ({
inputTitle,
placeholder,
data,
selectedData,
onValueChange,
subData,
selectedSubData,
onSubValueChange,
onUpdateDataPress,
}) => {
const [option, setOption] = useState([])
const [subOption, setSubOption] = useState([]) const [subOption, setSubOption] = useState([])
const [subOptionId, setSubOptionId] = useState(0)
const [text, setText] = useState('') const [selectedOption, setSelectedOption] = useState({})
const [subOptionShow, setSubOptionShow] = useState(false) const [subOptionShow, setSubOptionShow] = useState(false)
const [modalOpen, setModalOpen] = useState(false) const [modalOpen, setModalOpen] = useState(false)
const [notification, setNotification] = useState([])
const onPressSelectBox = () => { setModalOpen(true) } const onPressSelectBox = () => { setModalOpen(true) }
const modalClose = () => { setModalOpen(false); setNotification([]) } const modalClose = () => { setModalOpen(false); }
const onPressOption = (item) => { const onPressOption = (item) => {
if (item.id === 0) {
return null
}
if (subOption !== undefined) { if (subOption !== undefined) {
if (subOptionShow) { if (subOptionShow) {
setSubOptionId(item.id) onValueChange(selectedOption)
props.onValueChange(optionId) onSubValueChange(item)
props.onSubValueChange(subOptionId)
setText(optionValue + ` > ${item.value}`)
modalClose() modalClose()
} else { } else {
setOptionId(item.id) setSelectedOption(item)
setOptionValue(item.value)
setSubOptionByOptionId(item) setSubOptionByOptionId(item)
} }
} else { } else {
props.onValueChange(item.id) onValueChange(item)
setOptionId(item.id)
setOptionValue(item.value)
setText(item.value)
modalClose() modalClose()
} }
} }
const setSubOptionByOptionId = (item) => { const setSubOptionByOptionId = (item) => {
const newOption = props.subData.filter((subItem) => { const newOption = subData.filter((subItem) => {
if (subItem.foreign_id === item.id) if (subItem.foreign_id === item.id)
return true; return true;
}) })
if (newOption.length === 0) { if (newOption.length === 0) {
setNotification((prev) => [...prev, `${item.value}의 세부 카테고리가 존재하지 않습니다.`]) onValueChange(item)
onSubValueChange(INIT_SUBCATEGORY)
modalClose()
} else { } else {
setSubOption(newOption) newOption.unshift({id: 1, value: '기타'})
setSubOptionShow(true) if (newOption.length % 3 == 0) {
setSubOption(newOption)
setSubOptionShow(true)
} else {
for (let i = 0; i < (newOption.length % 3); i++) {
newOption.push(INIT_SUBCATEGORY)
}
setSubOption(newOption)
setSubOptionShow(true)
}
} }
} }
const renderOptionItem = ({ item }) => ( const renderOptionItem = ({ item }) => (
<TouchableOpacity onPress={() => onPressOption(item)} style={style.option}> <TouchableOpacity onPress={() => onPressOption(item)} style={style.option}>
<Text style={style.optionText} > <Text style={style.optionText} >
...@@ -66,8 +83,8 @@ const SelectForm = (props) => { ...@@ -66,8 +83,8 @@ const SelectForm = (props) => {
); );
useEffect(() => { useEffect(() => {
setOption(props.data) setOption(data)
setSubOption(props.subData) setSubOption(subData)
setSubOptionShow(false) setSubOptionShow(false)
}, [modalOpen]) }, [modalOpen])
...@@ -75,12 +92,16 @@ const SelectForm = (props) => { ...@@ -75,12 +92,16 @@ const SelectForm = (props) => {
<View> <View>
<View style={style.container}> <View style={style.container}>
<View style={style.inputTitleArea}> <View style={style.inputTitleArea}>
<Text style={style.inputTitle}>{props.inputTitle}</Text> <Text style={style.inputTitle}>{inputTitle}</Text>
</View> </View>
<View style={style.selectBox}> <View style={style.selectBox}>
<TouchableWithoutFeedback onPress={onPressSelectBox}> <TouchableWithoutFeedback onPress={onPressSelectBox}>
<Text style={style.textStyle}> <Text style={style.textStyle}>
{text ? text : props.placeholder} {selectedData.value ?
selectedSubData?.value ?
selectedData.value + ' < ' + selectedSubData.value
: selectedData.value
: placeholder}
</Text> </Text>
</TouchableWithoutFeedback> </TouchableWithoutFeedback>
</View> </View>
...@@ -95,25 +116,23 @@ const SelectForm = (props) => { ...@@ -95,25 +116,23 @@ const SelectForm = (props) => {
> >
<View style={style.selectModalContainer}> <View style={style.selectModalContainer}>
<TouchableWithoutFeedback onPress={modalClose}> <TouchableWithoutFeedback onPress={modalClose}>
<View style={{ flex: 1 }}> <View style={{ flex: 1 }} />
<Notification notification={notification} setNotification={setNotification} />
</View>
</TouchableWithoutFeedback> </TouchableWithoutFeedback>
<View style={style.selectModal}> <View style={style.selectModal}>
<View style={style.modalHeader}> <View style={style.modalHeader}>
{subOptionShow ? {subOptionShow ?
<View style={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'center' }} > <View style={{ flexDirection: 'row', alignItems: 'center', justifyContent: 'center' }} >
<MaterialCommunityIcons name='arrow-left' size={35} color='white' onPress={() => { setSubOptionShow(false); }} /> <MaterialCommunityIcons name='arrow-left' size={35} color='white' onPress={() => { setSubOptionShow(false); }} />
<Text style={style.modalHeaderText}>{optionValue}</Text> <Text style={style.modalHeaderText}>{selectedOption.value}</Text>
</View> </View>
: :
<Text style={style.modalHeaderText}>{props.inputTitle}</Text>} <Text style={style.modalHeaderText}>{inputTitle}</Text>}
<View style={{ flexDirection: "row" }}> <View style={{ flexDirection: "row" }}>
<MaterialCommunityIcons name='playlist-edit' size={35} color='white' onPress={() => console.log('카테고리 편집')} /> <MaterialCommunityIcons name='playlist-edit' size={35} color='white' onPress={() => { modalClose(); setTimeout(() => { onUpdateDataPress() }, 500) }} />
<MaterialCommunityIcons name='close' size={35} color='white' onPress={modalClose} /> <MaterialCommunityIcons name='close' size={35} color='white' onPress={modalClose} />
</View> </View>
</View> </View>
<View style={[style.modalBody, props.backdropStyle]}> <View style={[style.modalBody]}>
<FlatList <FlatList
data={subOptionShow ? subOption : option} data={subOptionShow ? subOption : option}
renderItem={renderOptionItem} renderItem={renderOptionItem}
......
import { DEBUG, enablePromise } from 'react-native-sqlite-storage';
import getDb from './moneyDB'
DEBUG(true);
enablePromise(true);
const CAT_LIMIT_ID = 14
const ASSET_LIMIT_ID = 10
const selectCategories = async (type_id) => {
const db = await getDb();
return new Promise((resolve, reject) => {
db.transaction(async (tx) => {
console.log("카테고리 부르기");
const [txn, results] = await tx.executeSql(
`select cat.category_id, category_name, subcat_id, subcat_name from categories as cat
left join (
SELECT category_id,
group_concat(subcategory_id, '|') as subcat_id,
group_concat(subcategory_name, '|') as subcat_name
from subcategories group by category_id
) as subcat
on cat.category_id=subcat.category_id
where cat.type_id='${type_id}'`
);
console.log('item length', results.rows.length);
const temp = [];
for (let i = 0; i < results.rows.length; i++) {
const tempId = results.rows.item(i).category_id;
const tempName = results.rows.item(i).category_name;
let deletable = (tempId < CAT_LIMIT_ID) ? false : true;
const tempSubOptions = [];
if (results.rows.item(i).subcat_id) {
const tempSubId = results.rows.item(i).subcat_id.split('|');
const tempSubValue = results.rows.item(i).subcat_name.split('|');
for (let i = 0; i < tempSubId.length; i++) {
tempSubOptions.push({ id: tempSubId[i], value: tempSubValue[i], foreign_id: tempId });
}
}
temp.push({ id: tempId, value: tempName, deletable: deletable, subOptions: tempSubOptions });
}
console.log(temp)
resolve(temp);
// console.log("카테고리 부르기");
// const [txn, results] = await tx.executeSql(`SELECT * FROM categories WHERE type_id=${type_id}`);
// console.log('item length', results.rows.length);
// const temp = [];
// for (let i = 0; i < results.rows.length; i++) {
// const tempId = results.rows.item(i).category_id;
// const tempName = results.rows.item(i).category_name;
// if (tempId < CAT_LIMIT_ID) {
// temp.push({ id: tempId, value: tempName, deletable: false });
// } else {
// temp.push({ id: tempId, value: tempName, deletable: true });
// }
// }
// console.log(temp)
// resolve(temp);
})
})
}
const selectAssetsType = async () => {
const db = await getDb();
return new Promise((resolve, reject) => {
db.transaction(async (tx) => {
console.log("자산 유형 부르기");
const [txn, results] = await tx.executeSql('SELECT * FROM assets_type');
console.log('item length', results.rows.length);
const temp = [];
for (let i = 0; i < results.rows.length; i++) {
const tempId = results.rows.item(i).assets_id;
const tempName = results.rows.item(i).assets_name;
if (tempId < ASSET_LIMIT_ID) {
temp.push({ id: tempId, value: tempName, deletable: false });
} else {
temp.push({ id: tempId, value: tempName, deletable: true });
}
}
console.log(temp)
resolve(temp);
})
})
}
const deleteOption = async (table, data) => {
const db = await getDb();
const { id, name } = data
return new Promise((resolve, reject) => {
db.transaction((tx) => {
console.log("데이터 삭제하기");
tx.executeSql(`DELETE FROM ${table} WHERE ${name}_id = ${id};`)
resolve(`${name} 데이터 삭제 완료`);
})
})
}
const updateOption = async (table, data) => {
const db = await getDb();
const { id, name, value } = data
console.log(table, id, value)
return new Promise((resolve, reject) => {
db.transaction((tx) => {
console.log("데이터 수정하기");
tx.executeSql(`UPDATE ${table} set ${name}_name =? where ${name}_id =${id};`,
[value],
(error) => console.log(error))
resolve(`${name} 데이터 변경 완료`);
})
})
};
const addOption = async (table, data) => {
const db = await getDb();
const { name, value, foreign_name = null, foreign_id } = data;
let insertQeury = '';
let queryData = [];
if (foreign_name === null) {
insertQeury = `INSERT INTO ${table} (${name}_name) VALUES (?);`
queryData = [value]
} else {
insertQeury = `INSERT INTO ${table} (${name}_name, ${foreign_name}_id) VALUES (?,?);`
queryData = [value, foreign_id]
}
// console.log(insertQuery, queryData)
return new Promise((resolve, reject) => {
db.transaction((tx) => {
console.log("데이터 삽입하기");
tx.executeSql(insertQeury,
queryData,
(error) => console.log(error))
resolve('데이터 삽입 카테고리 카테고리 완료');
})
})
};
const editApi = {
selectCategories,
selectAssetsType,
deleteOption,
updateOption,
addOption,
}
export default editApi;
\ No newline at end of file
...@@ -9,7 +9,7 @@ const insertMoney = async (moneyData) => { ...@@ -9,7 +9,7 @@ const insertMoney = async (moneyData) => {
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
db.transaction((tx) => { db.transaction((tx) => {
console.log("데이터 삽입하기"); console.log("데이터 삽입하기");
tx.executeSql('INSERT INTO Money (type, date, contents, price, asset_type, category, subcategory) VALUES (?,?,?,?,?,?,?);', tx.executeSql('INSERT INTO Money (type_id, date, contents, price, assets_id, category_id, subcategory_id) VALUES (?,?,?,?,?,?,?);',
moneyData, moneyData,
(error) => console.log(error)) (error) => console.log(error))
resolve('데이터 삽입 완료'); resolve('데이터 삽입 완료');
...@@ -17,18 +17,43 @@ const insertMoney = async (moneyData) => { ...@@ -17,18 +17,43 @@ const insertMoney = async (moneyData) => {
}) })
}; };
const selectCategories = async () => { const selectCategories = async (type_id) => {
const db = await getDb(); const db = await getDb();
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {
db.transaction(async (tx) => { db.transaction(async (tx) => {
console.log("카테고리 부르기"); console.log("카테고리 부르기");
const [txn, results] = await tx.executeSql('SELECT * FROM categories'); const [txn, results] = await tx.executeSql(`SELECT * FROM categories WHERE type_id=${type_id}`);
console.log('item length', results.rows.length);
const temp = [];
temp.push({id: 1, value:'기타'});
for (let i = 0; i < 3*(Math.ceil((results.rows.length+1)/3))-1; i++) {
if (i<results.rows.length){
const tempId = results.rows.item(i).category_id;
const tempName = results.rows.item(i).category_name;
temp.push({ id: tempId, value: tempName });
} else {
temp.push({ id: 0, value: '' });
}
}
console.log(temp)
resolve(temp);
})
})
}
const selectSubCategories = async () => {
const db = await getDb();
return new Promise((resolve, reject) => {
db.transaction(async (tx) => {
console.log("서브 카테고리 부르기");
const [txn, results] = await tx.executeSql('SELECT * FROM subcategories');
console.log('item length', results.rows.length); console.log('item length', results.rows.length);
const temp = []; const temp = [];
for (let i = 0; i < results.rows.length; i++) { for (let i = 0; i < results.rows.length; i++) {
const tempId = results.rows.item(i).category_id; const tempId = results.rows.item(i).subcategory_id;
const tempName = results.rows.item(i).category_name; const tempName = results.rows.item(i).subcategory_name;
temp.push({ id: tempId, value: tempName }); const tempCatId = results.rows.item(i).category_id;
temp.push({ id: tempId, value: tempName, foreign_id: tempCatId });
} }
console.log(temp) console.log(temp)
resolve(temp); resolve(temp);
...@@ -44,10 +69,14 @@ const selectAssetsType = async () => { ...@@ -44,10 +69,14 @@ const selectAssetsType = async () => {
const [txn, results] = await tx.executeSql('SELECT * FROM assets_type'); const [txn, results] = await tx.executeSql('SELECT * FROM assets_type');
console.log('item length', results.rows.length); console.log('item length', results.rows.length);
const temp = []; const temp = [];
for (let i = 0; i < results.rows.length; i++) { for (let i = 0; i < 3*(Math.ceil((results.rows.length)/3)); i++) {
const tempId = results.rows.item(i).assets_id; if (i<results.rows.length){
const tempName = results.rows.item(i).assets_name; const tempId = results.rows.item(i).assets_id;
temp.push({ id: tempId, value: tempName }); const tempName = results.rows.item(i).assets_name;
temp.push({ id: tempId, value: tempName });
} else {
temp.push({ id: 0, value: '' });
}
} }
console.log(temp) console.log(temp)
resolve(temp); resolve(temp);
...@@ -59,6 +88,7 @@ const selectAssetsType = async () => { ...@@ -59,6 +88,7 @@ const selectAssetsType = async () => {
const moneyApi = { const moneyApi = {
insertMoney, insertMoney,
selectCategories, selectCategories,
selectSubCategories,
selectAssetsType, selectAssetsType,
} }
......
export function getDate () {
const date = new Date();
const tempY = date.getFullYear();
let tempM = date.getMonth()+1;
tempM = tempM > 9 ? tempM : "0" + tempM;
let tempD = date.getDate();
tempD = tempD > 9 ? tempD : "0" + tempD;
console.log(`${tempY}-${tempM}-${tempD}`)
return `${tempY}-${tempM}-${tempD}`
}
\ No newline at end of file
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment