├── .expo-shared
└── assets.json
├── .github
└── FUNDING.yml
├── .gitignore
├── .idea
├── .gitignore
├── modules.xml
├── muffinMobileApp.iml
└── vcs.xml
├── App.js
├── Funds
├── Costs.js
├── Earnings.js
├── Login.js
├── Settings.js
└── Stats.js
├── README.md
├── app.json
├── assets
├── adaptive-icon.png
├── favicon.png
├── icon.png
└── splash.png
├── babel.config.js
├── context
└── context.js
├── package-lock.json
└── package.json
/.expo-shared/assets.json:
--------------------------------------------------------------------------------
1 | {
2 | "12bb71342c6255bbf50437ec8f4441c083f47cdb74bd89160c15e4f43e52a1cb": true,
3 | "40b842e832070c58deac6aa9e08fa459302ee3f9da492c7e77d93d2fbf4a56fd": true
4 | }
5 |
--------------------------------------------------------------------------------
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | # These are supported funding model platforms
2 |
3 | github: devpew
4 | patreon: johenews
5 | open_collective: # Replace with a single Open Collective username
6 | ko_fi: # Replace with a single Ko-fi username
7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
9 | liberapay: # Replace with a single Liberapay username
10 | issuehunt: # Replace with a single IssueHunt username
11 | otechie: # Replace with a single Otechie username
12 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2']
13 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/
2 | .expo/
3 | npm-debug.*
4 | *.jks
5 | *.p8
6 | *.p12
7 | *.key
8 | *.mobileprovision
9 | *.orig.*
10 | web-build/
11 |
12 | # macOS
13 | .DS_Store
14 |
--------------------------------------------------------------------------------
/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 | # Editor-based HTTP Client requests
5 | /httpRequests/
6 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/muffinMobileApp.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/App.js:
--------------------------------------------------------------------------------
1 | import { StatusBar } from 'expo-status-bar';
2 | import React, {useEffect, useState, useMemo} from 'react';
3 | import {ActivityIndicator, SafeAreaView, StyleSheet, Text, View} from 'react-native';
4 |
5 | import { createDrawerNavigator } from '@react-navigation/drawer';
6 | import { NavigationContainer } from '@react-navigation/native';
7 |
8 | import AsyncStorage from '@react-native-async-storage/async-storage';
9 |
10 | import {AuthContext} from "./context/context";
11 |
12 | import Earnings from "./Funds/Earnings";
13 | import Costs from "./Funds/Costs";
14 | import Login from './Funds/Login'
15 | import Settings from "./Funds/Settings";
16 | import Stats from './Funds/Stats'
17 |
18 | const Drawer = createDrawerNavigator();
19 |
20 | export default function App() {
21 | const [token, setToken] = useState(null)
22 | const [isLoading, setIsLoading] = useState(true)
23 |
24 | const authContent = useMemo(() => ({
25 | signIn: () => {
26 | setIsLoading(false)
27 | setToken('')
28 | },
29 | signOut: () => {
30 | setIsLoading(false)
31 | setToken(null)
32 | }
33 | }), [])
34 |
35 | useEffect(() => {
36 | AsyncStorage.getItem('token').then((value) => {
37 | if (value) {
38 | setToken(value)
39 | }
40 | })
41 | }, [])
42 |
43 | useEffect(() => {
44 | setTimeout(() => {
45 | setIsLoading(false)
46 | }, 800)
47 | }, [])
48 |
49 | if (isLoading) {
50 | return (
51 |
52 |
53 |
54 | )
55 | }
56 |
57 | return (
58 |
59 |
60 |
61 | {token !== null ? (
62 | <>
63 |
64 |
65 |
66 |
67 | >
68 | ) : (
69 | <>
70 |
71 | >
72 | )}
73 |
74 |
75 |
76 |
77 | );
78 | }
79 |
80 | const styles = StyleSheet.create({
81 | container: {
82 | flex: 1,
83 | backgroundColor: '#fff',
84 | alignItems: 'center',
85 | justifyContent: 'center',
86 | },
87 | });
88 |
--------------------------------------------------------------------------------
/Funds/Costs.js:
--------------------------------------------------------------------------------
1 | import { StatusBar } from 'expo-status-bar';
2 | import React, {useEffect, useState} from "react";
3 | import {Text, View, SafeAreaView, Button, StyleSheet, TouchableOpacity, TouchableHighlight, TextInput} from 'react-native'
4 | import dayjs from 'dayjs'
5 |
6 | import AsyncStorage from '@react-native-async-storage/async-storage';
7 | import { Picker } from "@react-native-picker/picker";
8 | import { SwipeListView } from 'react-native-swipe-list-view';
9 |
10 | export default function Costs() {
11 | const [dataArray, setDataArray] = useState([])
12 | const [isLoading, setIsLoading] = useState(false)
13 | const [token, setToken] = useState('')
14 |
15 | const [currentAmount, setCurrentAmount] = useState('')
16 | const [currentCategory, setCurrentCategory] = useState('Еда')
17 | const [currentSource, setCurrentSource] = useState('TINK')
18 |
19 | const renderItem = ({item}) => (
20 | console.log('You touched me')}
22 | style={styles.rowFront}
23 | underlayColor={'#AAA'}
24 | >
25 |
26 | {item.amount}
27 | {item.source}
28 | {item.category}
29 | {dayjs(item.datetime).format('DD MMM YYYY')}
30 |
31 |
32 | )
33 |
34 | const closeRow = (rowMap, rowKey) => {
35 | if (rowMap[rowKey]) {
36 | rowMap[rowKey].closeRow();
37 | }
38 | };
39 |
40 | const deleteRow = (rowMap, rowKey) => {
41 | closeRow(rowMap, rowKey);
42 | const newData = [...dataArray];
43 | const prevIndex = dataArray.findIndex(item => item.id === rowKey);
44 | newData.splice(prevIndex, 1);
45 | setDataArray(newData);
46 | deleteData(rowKey)
47 | };
48 |
49 | const renderHiddenItem = (data, rowMap) => (
50 |
51 | deleteRow(rowMap, data.item.id)}
54 | >
55 | Delete
56 |
57 |
58 | );
59 |
60 | useEffect(() => {
61 | AsyncStorage.getItem('token').then((value) => {
62 | if (value) {
63 | setToken(value)
64 | }
65 | })
66 | }, [])
67 |
68 | useEffect(() => {
69 | if (token !== '') {
70 | getData()
71 | }
72 | }, [token])
73 |
74 | const getData = () => {
75 | setIsLoading(true)
76 | let URL = 'http://127.0.0.1:8000/costs'
77 | fetch(URL, {
78 | headers: {
79 | 'Token': token
80 | }
81 | }).then(res => res.json()).then(res => {
82 | setDataArray(res)
83 | }).finally(() => setIsLoading(false))
84 | }
85 |
86 | function deleteData(id) {
87 | const requestOptions = {
88 | method: 'DELETE',
89 | headers: {
90 | 'Token': token
91 | },
92 | body: JSON.stringify({
93 | "id": id
94 | })
95 | }
96 |
97 | fetch('http://127.0.0.1:8000/costs/'+id, requestOptions).then((res) => {
98 | return res.json();
99 | }).then((res) => {
100 | getData()
101 | //console.log('DELETE COSTS OK')
102 | }).catch(function(error) {
103 | console.log('delete costs error: ', error)
104 | })
105 | }
106 |
107 | function sendData() {
108 | const requestOptions = {
109 | method: 'POST',
110 | headers: {
111 | 'Token': token
112 | },
113 | body: JSON.stringify({
114 | "datetime": dayjs(Date.now()).format(),
115 | "amount": Number(currentAmount),
116 | "source": currentSource,
117 | "category": currentCategory
118 | })
119 | }
120 | if (currentAmount !== '') {
121 | fetch('http://127.0.0.1:8000/costs', requestOptions).then((res) => {
122 | return res.json();
123 | }).then((res) => {
124 | getData()
125 | setCurrentAmount('')
126 | //console.log("sendData OK")
127 | }).catch(function (error) {
128 | console.log('sendData POST ERROR: ', error)
129 | })
130 | }
131 | }
132 |
133 | return (
134 |
135 |
136 | setCurrentAmount(text)}
139 | keyboardType="numeric"
140 | defaultValue={currentAmount}
141 | />
142 |
145 | setCurrentCategory(itemValue)
146 | }>
147 |
148 |
149 |
150 |
151 |
152 |
153 |
154 |
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
163 |
168 |
169 |
170 | item.id.toString()}
174 | onRefresh={getData}
175 | refreshing={isLoading}
176 | renderHiddenItem={renderHiddenItem}
177 | rightOpenValue={-75}
178 | />
179 |
180 | )
181 | }
182 |
183 | const styles = StyleSheet.create({
184 | container: {
185 | flex: 1,
186 | backgroundColor: '#fff',
187 | alignItems: 'center',
188 | justifyContent: 'center',
189 | },
190 | input: {
191 | width: 300,
192 | height: 48,
193 | padding: 10,
194 | borderWidth: 1,
195 | borderColor: 'black',
196 | marginBottom: 10,
197 | },
198 | costLineWrapper: {
199 | height: 50,
200 | flex: 1,
201 | flexDirection: 'row',
202 | },
203 | costAmount: {
204 | height: 50,
205 | lineHeight: 50,
206 | flex: 2,
207 | paddingLeft: 20,
208 | },
209 | costSource: {
210 | height: 50,
211 | lineHeight: 50,
212 | flex: 2,
213 | },
214 | costCategory: {
215 | height: 50,
216 | lineHeight: 50,
217 | flex: 4,
218 | },
219 | costDate: {
220 | height: 50,
221 | lineHeight: 50,
222 | flex: 3,
223 | paddingRight: 20,
224 | },
225 | adderblock: {
226 | paddingTop: 55,
227 | },
228 | bigtextinput: {
229 | fontSize: 20,
230 | borderWidth: 1,
231 | borderColor: 'grey',
232 | height: 50,
233 | width: 300,
234 | textAlign: 'center',
235 | alignSelf: 'center',
236 | },
237 | bigbuttonwrapper: {
238 | paddingBottom: 15
239 | },
240 | backTextWhite: {
241 | color: '#FFF',
242 | },
243 | rowFront: {
244 | alignItems: 'center',
245 | backgroundColor: '#CCC',
246 | borderBottomColor: 'black',
247 | borderBottomWidth: 1,
248 | justifyContent: 'center',
249 | height: 50,
250 | },
251 | rowBack: {
252 | alignItems: 'center',
253 | backgroundColor: '#DDD',
254 | flex: 1,
255 | flexDirection: 'row',
256 | justifyContent: 'space-between',
257 | paddingLeft: 15,
258 | },
259 | backRightBtn: {
260 | alignItems: 'center',
261 | bottom: 0,
262 | justifyContent: 'center',
263 | position: 'absolute',
264 | top: 0,
265 | width: 75,
266 | },
267 | backRightBtnLeft: {
268 | backgroundColor: 'blue',
269 | right: 75,
270 | },
271 | backRightBtnRight: {
272 | backgroundColor: 'red',
273 | right: 0,
274 | },
275 | });
276 |
--------------------------------------------------------------------------------
/Funds/Earnings.js:
--------------------------------------------------------------------------------
1 | import { StatusBar } from 'expo-status-bar';
2 | import React, {useEffect, useState} from "react";
3 | import {Text, View, SafeAreaView, Button, StyleSheet, TouchableOpacity, TouchableHighlight, TextInput} from 'react-native'
4 | import dayjs from 'dayjs'
5 |
6 | import AsyncStorage from '@react-native-async-storage/async-storage';
7 | import { Picker } from "@react-native-picker/picker";
8 | import { SwipeListView } from 'react-native-swipe-list-view';
9 |
10 | export default function Earnings() {
11 | const [dataArray, setDataArray] = useState([])
12 | const [isLoading, setIsLoading] = useState(false)
13 | const [token, setToken] = useState('')
14 |
15 | const [currentAmount, setCurrentAmount] = useState('')
16 | const [currentCategory, setCurrentCategory] = useState('Еда')
17 | const [currentSource, setCurrentSource] = useState('TINK')
18 |
19 | const renderItem = ({item}) => (
20 | console.log('You touched me')}
22 | style={styles.rowFront}
23 | underlayColor={'#AAA'}
24 | >
25 |
26 | {item.amount}
27 | {item.source}
28 | {item.category}
29 | {dayjs(item.datetime).format('DD MMM YYYY')}
30 |
31 |
32 | )
33 |
34 | const closeRow = (rowMap, rowKey) => {
35 | if (rowMap[rowKey]) {
36 | rowMap[rowKey].closeRow();
37 | }
38 | };
39 |
40 | const deleteRow = (rowMap, rowKey) => {
41 | closeRow(rowMap, rowKey);
42 | const newData = [...dataArray];
43 | const prevIndex = dataArray.findIndex(item => item.id === rowKey);
44 | newData.splice(prevIndex, 1);
45 | setDataArray(newData);
46 | deleteData(rowKey)
47 | };
48 |
49 | const renderHiddenItem = (data, rowMap) => (
50 |
51 | deleteRow(rowMap, data.item.id)}
54 | >
55 | Delete
56 |
57 |
58 | );
59 |
60 | useEffect(() => {
61 | AsyncStorage.getItem('token').then((value) => {
62 | if (value) {
63 | setToken(value)
64 | }
65 | })
66 | }, [])
67 |
68 | useEffect(() => {
69 | if (token !== '') {
70 | getData()
71 | }
72 | }, [token])
73 |
74 | const getData = () => {
75 | setIsLoading(true)
76 | let URL = 'http://127.0.0.1:8000/earnings'
77 | fetch(URL, {
78 | headers: {
79 | 'Token': token
80 | }
81 | }).then(res => res.json()).then(res => {
82 | setDataArray(res)
83 | }).finally(() => setIsLoading(false))
84 | }
85 |
86 | function deleteData(id) {
87 | const requestOptions = {
88 | method: 'DELETE',
89 | headers: {
90 | 'Token': token
91 | },
92 | body: JSON.stringify({
93 | "id": id
94 | })
95 | }
96 |
97 | fetch('http://127.0.0.1:8000/earnings/'+id, requestOptions).then((res) => {
98 | return res.json();
99 | }).then((res) => {
100 | getData()
101 | //console.log('DELETE earnings OK')
102 | }).catch(function(error) {
103 | console.log('delete earnings error: ', error)
104 | })
105 | }
106 |
107 | function sendData() {
108 | const requestOptions = {
109 | method: 'POST',
110 | headers: {
111 | 'Token': token
112 | },
113 | body: JSON.stringify({
114 | "datetime": dayjs(Date.now()).format(),
115 | "amount": Number(currentAmount),
116 | "source": currentSource,
117 | "category": currentCategory
118 | })
119 | }
120 | if (currentAmount !== '') {
121 | fetch('http://127.0.0.1:8000/earnings', requestOptions).then((res) => {
122 | return res.json();
123 | }).then((res) => {
124 | getData()
125 | setCurrentAmount('')
126 | //console.log("sendData OK")
127 | }).catch(function (error) {
128 | console.log('sendData POST ERROR: ', error)
129 | })
130 | }
131 | }
132 |
133 | return (
134 |
135 |
136 | setCurrentAmount(text)}
139 | keyboardType="numeric"
140 | defaultValue={currentAmount}
141 | />
142 |
145 | setCurrentCategory(itemValue)
146 | }>
147 |
148 |
149 |
150 |
151 |
152 |
157 |
158 |
159 | item.id.toString()}
163 | onRefresh={getData}
164 | refreshing={isLoading}
165 | renderHiddenItem={renderHiddenItem}
166 | rightOpenValue={-75}
167 | />
168 |
169 | )
170 | }
171 |
172 | const styles = StyleSheet.create({
173 | container: {
174 | flex: 1,
175 | backgroundColor: '#fff',
176 | alignItems: 'center',
177 | justifyContent: 'center',
178 | },
179 | input: {
180 | width: 300,
181 | height: 48,
182 | padding: 10,
183 | borderWidth: 1,
184 | borderColor: 'black',
185 | marginBottom: 10,
186 | },
187 | costLineWrapper: {
188 | height: 50,
189 | flex: 1,
190 | flexDirection: 'row',
191 | },
192 | costAmount: {
193 | height: 50,
194 | lineHeight: 50,
195 | flex: 2,
196 | paddingLeft: 20,
197 | },
198 | costSource: {
199 | height: 50,
200 | lineHeight: 50,
201 | flex: 2,
202 | },
203 | costCategory: {
204 | height: 50,
205 | lineHeight: 50,
206 | flex: 4,
207 | },
208 | costDate: {
209 | height: 50,
210 | lineHeight: 50,
211 | flex: 3,
212 | paddingRight: 20,
213 | },
214 | adderblock: {
215 | paddingTop: 55,
216 | },
217 | bigtextinput: {
218 | fontSize: 20,
219 | borderWidth: 1,
220 | borderColor: 'grey',
221 | height: 50,
222 | width: 300,
223 | textAlign: 'center',
224 | alignSelf: 'center',
225 | },
226 | bigbuttonwrapper: {
227 | paddingBottom: 15
228 | },
229 | backTextWhite: {
230 | color: '#FFF',
231 | },
232 | rowFront: {
233 | alignItems: 'center',
234 | backgroundColor: '#CCC',
235 | borderBottomColor: 'black',
236 | borderBottomWidth: 1,
237 | justifyContent: 'center',
238 | height: 50,
239 | },
240 | rowBack: {
241 | alignItems: 'center',
242 | backgroundColor: '#DDD',
243 | flex: 1,
244 | flexDirection: 'row',
245 | justifyContent: 'space-between',
246 | paddingLeft: 15,
247 | },
248 | backRightBtn: {
249 | alignItems: 'center',
250 | bottom: 0,
251 | justifyContent: 'center',
252 | position: 'absolute',
253 | top: 0,
254 | width: 75,
255 | },
256 | backRightBtnLeft: {
257 | backgroundColor: 'blue',
258 | right: 75,
259 | },
260 | backRightBtnRight: {
261 | backgroundColor: 'red',
262 | right: 0,
263 | },
264 | });
--------------------------------------------------------------------------------
/Funds/Login.js:
--------------------------------------------------------------------------------
1 | import React, {useState} from "react";
2 | import {Text, SafeAreaView, TextInput, Button, View, StyleSheet} from 'react-native'
3 | import AsyncStorage from '@react-native-async-storage/async-storage';
4 |
5 | import {AuthContext} from "../context/context";
6 |
7 | export default function Earnings() {
8 | const [username, setUsername] = useState('')
9 | const [password, setPassword] = useState('')
10 |
11 | const { signIn } = React.useContext(AuthContext)
12 |
13 | const storeToken = async (value) => {
14 | try {
15 | await AsyncStorage.setItem('token', value)
16 | } catch (e) {
17 | console.log('cant save token')
18 | }
19 | }
20 |
21 | async function clearToken() {
22 | AsyncStorage.removeItem('token')
23 | }
24 |
25 | function submitHandler() {
26 | const requestOptions = {
27 | method: 'POST',
28 | headers: {
29 |
30 | },
31 | body: JSON.stringify({
32 | "Username": username,
33 | "Password": password
34 | })
35 | }
36 |
37 | fetch('http://127.0.0.1:8000/login', requestOptions).then((res) => {
38 | return res.json()
39 | }).then((res) => {
40 | if (res !== '' && res !== 'error') {
41 | storeToken(res).then(() => {
42 | signIn()
43 | })
44 | console.log('GOT TOKEN')
45 | } else {
46 | console.log('GOR ERROR OR EMPTY RESULT')
47 | }
48 | }).catch(function (error) {
49 | console.log('GOT ERROR: ', error)
50 | })
51 | }
52 |
53 | return (
54 |
55 | setUsername(text)}
58 | placeholder={'Username'}
59 | style={styles.input}
60 | />
61 | setPassword(text)}
64 | placeholder={'Password'}
65 | style={styles.input}
66 | secureTextEntry={true}
67 | />
68 |
73 |
74 | )
75 | }
76 |
77 | const styles = StyleSheet.create({
78 | container: {
79 | flex: 1,
80 | backgroundColor: '#fff',
81 | alignItems: 'center',
82 | justifyContent: 'center',
83 | },
84 | input: {
85 | width: 300,
86 | height: 48,
87 | padding: 10,
88 | borderWidth: 1,
89 | borderColor: 'black',
90 | marginBottom: 10,
91 | }
92 | });
93 |
--------------------------------------------------------------------------------
/Funds/Settings.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import {Button, SafeAreaView, StyleSheet, Text, TextInput, View} from 'react-native'
3 | import AsyncStorage from "@react-native-async-storage/async-storage";
4 |
5 | import {AuthContext} from "../context/context";
6 |
7 | export default function Settings() {
8 |
9 | const {signOut} = React.useContext(AuthContext)
10 |
11 | async function clearToken() {
12 | AsyncStorage.removeItem('token')
13 | signOut()
14 | }
15 |
16 | return (
17 |
18 |
23 |
24 | )
25 | }
26 |
27 | const styles = StyleSheet.create({
28 | container: {
29 | flex: 1,
30 | backgroundColor: '#fff',
31 | alignItems: 'center',
32 | justifyContent: 'center',
33 | },
34 | input: {
35 | width: 300,
36 | height: 48,
37 | padding: 10,
38 | borderWidth: 1,
39 | borderColor: 'black',
40 | marginBottom: 10,
41 | }
42 | });
43 |
--------------------------------------------------------------------------------
/Funds/Stats.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 | import {Button, SafeAreaView, StyleSheet, Text, TextInput, View} from 'react-native'
3 | import AsyncStorage from "@react-native-async-storage/async-storage";
4 |
5 | export default function Stats() {
6 |
7 |
8 | return (
9 |
10 |
11 |
12 | )
13 | }
14 |
15 | const styles = StyleSheet.create({
16 | container: {
17 | flex: 1,
18 | backgroundColor: '#fff',
19 | alignItems: 'center',
20 | justifyContent: 'center',
21 | },
22 | input: {
23 | width: 300,
24 | height: 48,
25 | padding: 10,
26 | borderWidth: 1,
27 | borderColor: 'black',
28 | marginBottom: 10,
29 | }
30 | });
31 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Muffin React Native
2 |
3 | ### Install Expo
4 |
5 | ```
6 | npm install --global expo-cli
7 | ```
8 |
9 | ### Create a new expo project
10 |
11 | ```
12 | expo init my-project
13 | ```
14 |
15 | ### Install All Libs
16 |
17 | ```
18 | npm install @react-navigation/native
19 |
20 | expo install react-native-gesture-handler react-native-reanimated react-native-screens react-native-safe-area-context @react-native-community/masked-view
21 |
22 | npm install @react-navigation/drawer
23 |
24 | npm install @react-native-async-storage/async-storage
25 |
26 | npm install --save react-native-swipe-list-view
27 |
28 | npm install dayjs --save
29 |
30 | npm install react-native-chart-kit
31 | ```
32 |
--------------------------------------------------------------------------------
/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "expo": {
3 | "name": "muffinMobileApp",
4 | "slug": "muffinMobileApp",
5 | "version": "1.0.0",
6 | "orientation": "portrait",
7 | "icon": "./assets/icon.png",
8 | "splash": {
9 | "image": "./assets/splash.png",
10 | "resizeMode": "contain",
11 | "backgroundColor": "#ffffff"
12 | },
13 | "updates": {
14 | "fallbackToCacheTimeout": 0
15 | },
16 | "assetBundlePatterns": [
17 | "**/*"
18 | ],
19 | "ios": {
20 | "supportsTablet": true
21 | },
22 | "android": {
23 | "adaptiveIcon": {
24 | "foregroundImage": "./assets/adaptive-icon.png",
25 | "backgroundColor": "#FFFFFF"
26 | }
27 | },
28 | "web": {
29 | "favicon": "./assets/favicon.png"
30 | }
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/assets/adaptive-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devpew/muffinReactNative/61511e723e0f511014a8913fcbca592bb033efc8/assets/adaptive-icon.png
--------------------------------------------------------------------------------
/assets/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devpew/muffinReactNative/61511e723e0f511014a8913fcbca592bb033efc8/assets/favicon.png
--------------------------------------------------------------------------------
/assets/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devpew/muffinReactNative/61511e723e0f511014a8913fcbca592bb033efc8/assets/icon.png
--------------------------------------------------------------------------------
/assets/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/devpew/muffinReactNative/61511e723e0f511014a8913fcbca592bb033efc8/assets/splash.png
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = function(api) {
2 | api.cache(true);
3 | return {
4 | presets: ['babel-preset-expo'],
5 | };
6 | };
7 |
--------------------------------------------------------------------------------
/context/context.js:
--------------------------------------------------------------------------------
1 | import React from "react";
2 |
3 | export const AuthContext = React.createContext();
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "main": "node_modules/expo/AppEntry.js",
3 | "scripts": {
4 | "start": "expo start",
5 | "android": "expo start --android",
6 | "ios": "expo start --ios",
7 | "web": "expo start --web",
8 | "eject": "expo eject"
9 | },
10 | "dependencies": {
11 | "@react-native-async-storage/async-storage": "^1.15.4",
12 | "@react-native-community/masked-view": "0.1.10",
13 | "@react-native-picker/picker": "^1.15.0",
14 | "@react-navigation/drawer": "^5.12.5",
15 | "@react-navigation/native": "^5.9.4",
16 | "dayjs": "^1.10.4",
17 | "expo": "~41.0.1",
18 | "expo-status-bar": "~1.0.4",
19 | "moment": "^2.29.1",
20 | "react": "16.13.1",
21 | "react-dom": "16.13.1",
22 | "react-native": "https://github.com/expo/react-native/archive/sdk-41.0.0.tar.gz",
23 | "react-native-chart-kit": "^6.11.0",
24 | "react-native-gesture-handler": "~1.10.2",
25 | "react-native-reanimated": "~2.1.0",
26 | "react-native-safe-area-context": "3.2.0",
27 | "react-native-screens": "~3.0.0",
28 | "react-native-swipe-list-view": "^3.2.7",
29 | "react-native-web": "~0.13.12"
30 | },
31 | "devDependencies": {
32 | "@babel/core": "^7.9.0"
33 | },
34 | "private": true
35 | }
36 |
--------------------------------------------------------------------------------