Skip to content

Commit e43ba30

Browse files
committed
upload receipt functionality
1 parent e3e2bb2 commit e43ba30

File tree

10 files changed

+134
-49
lines changed

10 files changed

+134
-49
lines changed

.env

Lines changed: 0 additions & 3 deletions
This file was deleted.

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ npm-debug.*
88
*.mobileprovision
99
*.orig.*
1010
web-build/
11+
.env
12+
src/firebase.js
1113

1214
# macOS
1315
.DS_Store

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
"expo-app-loading": "^1.1.2",
1919
"expo-file-system": "~11.1.3",
2020
"expo-google-app-auth": "^8.2.2",
21+
"expo-image-picker": "~10.2.2",
2122
"expo-media-library": "~12.1.2",
2223
"expo-status-bar": "~1.0.4",
2324
"firebase": "8.2.3",

src/components/AddCustomerModal.js

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,19 +25,23 @@ const AddCustomerModal = ({ visible, setVisible, fun }) => {
2525
};
2626
return (
2727
<Modal
28-
// style={tw`h-full w-full z-50 justify-center`}
29-
animationType="slide"
28+
animationType="fade"
3029
transparent={true}
3130
visible={visible}
3231
onRequestClose={() => setVisible(false)}
3332
>
34-
<View
33+
<TouchableOpacity
34+
onPress={() => setVisible(false)}
3535
style={[
3636
tw`h-full w-full absolute justify-center items-center`,
3737
{ backgroundColor: "rgba(0,0,0,0.6)" },
3838
]}
3939
>
40-
<View style={tw`w-11/12 rounded-lg bg-white`}>
40+
<TouchableOpacity
41+
onPress={null}
42+
activeOpacity={1}
43+
style={tw`w-11/12 rounded-lg bg-white z-20`}
44+
>
4145
<TouchableOpacity
4246
style={tw`absolute right-4 top-4 z-10`}
4347
onPress={() => setVisible(false)}
@@ -78,8 +82,8 @@ const AddCustomerModal = ({ visible, setVisible, fun }) => {
7882
<View style={tw`mx-4 my-2 mb-4`}>
7983
<Button onPress={submitHandler} title="Submit" />
8084
</View>
81-
</View>
82-
</View>
85+
</TouchableOpacity>
86+
</TouchableOpacity>
8387
</Modal>
8488
);
8589
};

src/components/AddTransactionModal.js

Lines changed: 79 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import React, { useRef, useState } from "react";
1+
import React, { useEffect, useRef, useState } from "react";
22
import {
33
View,
44
Text,
@@ -10,12 +10,26 @@ import {
1010
} from "react-native";
1111
import { Icon } from "react-native-elements";
1212
import tw from "tailwind-react-native-classnames";
13+
import * as ImagePicker from "expo-image-picker";
1314

14-
const AddTransactionModal = ({ visible, setVisible, fun }) => {
15+
const AddTransactionModal = ({
16+
visible,
17+
setVisible,
18+
fun,
19+
transId,
20+
storage,
21+
setLoading,
22+
}) => {
1523
const [amt, setAmt] = useState(null),
1624
[desc, setDesc] = useState(""),
1725
ref1 = useRef(null),
18-
ref2 = useRef(null);
26+
ref2 = useRef(null),
27+
[image, setImage] = useState(null);
28+
29+
useEffect(() => {
30+
setLoading(true);
31+
return setLoading(false);
32+
}, []);
1933

2034
const submitHandler = (isGiving) => {
2135
if (!amt || !desc) {
@@ -24,23 +38,74 @@ const AddTransactionModal = ({ visible, setVisible, fun }) => {
2438
if (amt < 1) {
2539
return Alert.alert("Amount must be grater than 0");
2640
}
27-
fun(isGiving, Number(amt), desc);
41+
if (image) {
42+
uploadImage(isGiving);
43+
} else {
44+
fun(isGiving, Number(amt), desc, "");
45+
}
46+
};
47+
48+
const pickImage = async () => {
49+
const permission = await ImagePicker.requestMediaLibraryPermissionsAsync();
50+
51+
if (!permission.granted) {
52+
return Alert.alert("Permission to access camera roll is required");
53+
}
54+
const res = await ImagePicker.launchImageLibraryAsync({
55+
quality: 0.5,
56+
allowsEditing: true,
57+
mediaTypes: ImagePicker.MediaTypeOptions.Images,
58+
});
59+
setImage(res.uri || null);
60+
};
61+
62+
const uploadImage = async (isGiving) => {
63+
setLoading(true);
64+
const fileName = image.substring(image.lastIndexOf("/")),
65+
response = await fetch(image),
66+
blob = await response.blob(),
67+
storageRef = storage().ref(`receipts/${transId}-${fileName}`),
68+
task = storageRef.put(blob);
69+
task.on(
70+
"state_changed",
71+
function progress(snapshot) {},
72+
function error(err) {
73+
console.log(err);
74+
setLoading(false);
75+
},
76+
function complete() {
77+
storageRef
78+
.getDownloadURL()
79+
.then((url) => {
80+
setLoading(false);
81+
fun(isGiving, Number(amt), desc, url);
82+
})
83+
.catch((err) => {
84+
setLoading(false);
85+
console.log(err);
86+
});
87+
}
88+
);
2889
};
2990
return (
3091
<Modal
31-
// style={tw`h-full w-full z-50 justify-center`}
32-
animationType="slide"
92+
animationType="fade"
3393
transparent={true}
3494
visible={visible}
3595
onRequestClose={() => setVisible(false)}
3696
>
37-
<View
97+
<TouchableOpacity
98+
onPress={() => setVisible(false)}
3899
style={[
39100
tw`h-full w-full absolute justify-center items-center`,
40101
{ backgroundColor: "rgba(0,0,0,0.6)" },
41102
]}
42103
>
43-
<View style={tw`w-11/12 rounded-lg bg-white`}>
104+
<TouchableOpacity
105+
onPress={null}
106+
activeOpacity={1}
107+
style={tw`w-11/12 rounded-lg bg-white`}
108+
>
44109
<TouchableOpacity
45110
style={tw`absolute right-4 top-4 z-10`}
46111
onPress={() => setVisible(false)}
@@ -74,7 +139,10 @@ const AddTransactionModal = ({ visible, setVisible, fun }) => {
74139
value={desc}
75140
onChangeText={(text) => setDesc(text)}
76141
/>
77-
<View style={tw`flex-row items-center mx-4 mb-2`}>
142+
<View style={tw`mx-4 my-2`}>
143+
<Button onPress={pickImage} title="Add Receipt" />
144+
</View>
145+
<View style={tw`flex-row items-center mx-2 mb-2`}>
78146
<View style={tw`p-2 w-1/2`}>
79147
<Button
80148
color="rgb(185,28,28)"
@@ -90,8 +158,8 @@ const AddTransactionModal = ({ visible, setVisible, fun }) => {
90158
/>
91159
</View>
92160
</View>
93-
</View>
94-
</View>
161+
</TouchableOpacity>
162+
</TouchableOpacity>
95163
</Modal>
96164
);
97165
};

src/firebase.js

Lines changed: 0 additions & 20 deletions
This file was deleted.

src/screens/AuthScreen.js

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
import React from "react";
22
import { Image, StyleSheet, View } from "react-native";
33
import tw from "tailwind-react-native-classnames";
4-
import { ANDROID_OAUTH_KEY, IOS_OAUTH_KEY } from "@env";
4+
import {
5+
ANDROID_OAUTH_KEY,
6+
IOS_OAUTH_KEY,
7+
ANDROID_OAUTH_KEY_LOCAL,
8+
} from "@env";
59
import * as Google from "expo-google-app-auth";
610
import { GoogleSocialButton } from "react-native-social-buttons";
711
import firebase from "../firebase";
@@ -15,7 +19,7 @@ const AuthScreen = () => {
1519
try {
1620
const res = await Google.logInAsync({
1721
androidStandaloneAppClientId: ANDROID_OAUTH_KEY,
18-
androidClientId: ANDROID_OAUTH_KEY,
22+
androidClientId: ANDROID_OAUTH_KEY_LOCAL,
1923
iosClientId: IOS_OAUTH_KEY,
2024
scopes: ["profile", "email"],
2125
});

src/screens/CustomerScreen.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ import Loader from "../components/Loader";
1919
import AddButton from "../components/AddButton";
2020
import AddTransactionModal from "../components/AddTransactionModal";
2121

22-
const db = firebase.firestore;
22+
const db = firebase.firestore,
23+
storage = firebase.storage;
2324

2425
const CustomerScreen = ({ route }) => {
2526
const { customerId, customerName } = route?.params,
@@ -92,7 +93,7 @@ const CustomerScreen = ({ route }) => {
9293
setGot(tGot);
9394
}, [trans]);
9495

95-
const addTransaction = (isGiving, amount, desc) => {
96+
const addTransaction = (isGiving, amount, desc, url = "") => {
9697
setLoading(true);
9798
let amt = 0;
9899
if (isGiving) {
@@ -106,12 +107,12 @@ const CustomerScreen = ({ route }) => {
106107
timestamp: lastActivity,
107108
amount: amt,
108109
desc,
109-
receipt: "",
110+
receipt: url,
110111
});
111112
selfTransRef.set({
112113
timestamp: lastActivity,
113114
amount: -1 * amt,
114-
receipt: "",
115+
receipt: url,
115116
desc,
116117
});
117118
if (isGiving) {
@@ -156,6 +157,9 @@ const CustomerScreen = ({ route }) => {
156157
fun={addTransaction}
157158
visible={modalVisible}
158159
setVisible={setModalVisible}
160+
transId={transRef?.id}
161+
storage={storage}
162+
setLoading={setLoading}
159163
/>
160164
)}
161165
<FlatList

src/utils/common.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
1-
export const formatNumber = (number) =>
2-
new Intl.NumberFormat("en-IN", {
1+
export const formatNumber = (number) => {
2+
const maximumFractionDigits = number % 1 === 0 ? 0 : 2;
3+
return new Intl.NumberFormat("en-IN", {
34
style: "currency",
45
currency: "INR",
5-
maximumSignificantDigits: 16,
6+
minimumFractionDigits: 0,
7+
maximumFractionDigits,
68
signDisplay: false,
79
}).format(number);
10+
};

yarn.lock

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3665,6 +3665,16 @@ expo-google-app-auth@^8.2.2:
36653665
dependencies:
36663666
expo-app-auth "~10.2.2"
36673667

3668+
expo-image-picker@~10.2.2:
3669+
version "10.2.2"
3670+
resolved "https://registry.yarnpkg.com/expo-image-picker/-/expo-image-picker-10.2.2.tgz#7501a13306029f672a165f53545ee5dc5f5dc009"
3671+
integrity sha512-LCssY/wy4Y/7YsxoUO7PvjqwtQ9L84hxP86RLPnRSUSZy7s+00wnHFctrrtQ0UO4yR2i7rKTMTpkBEP6NVHv2w==
3672+
dependencies:
3673+
"@expo/config-plugins" "^3.0.0"
3674+
expo-modules-core "~0.2.0"
3675+
expo-permissions "~12.1.1"
3676+
uuid "7.0.2"
3677+
36683678
expo-keep-awake@~9.2.0:
36693679
version "9.2.0"
36703680
resolved "https://registry.yarnpkg.com/expo-keep-awake/-/expo-keep-awake-9.2.0.tgz#9cbdcc8264c943ef29a58326236cd34267e98f43"
@@ -3694,6 +3704,13 @@ expo-modules-core@~0.2.0:
36943704
resolved "https://registry.yarnpkg.com/expo-modules-core/-/expo-modules-core-0.2.0.tgz#68e5b6e53d0afbf8d131578831aed657589a2d42"
36953705
integrity sha512-inpfZ5X/BaTtbj2wG9PA9AC0MN8VyId6KSRlVuEg7+ziurHBy/kKDFxpOddUokhwiln2uhoYPSStJjR/tKypdw==
36963706

3707+
expo-permissions@~12.1.1:
3708+
version "12.1.1"
3709+
resolved "https://registry.yarnpkg.com/expo-permissions/-/expo-permissions-12.1.1.tgz#93fd8569d4106ff9dd66d67619cb69a0aa895482"
3710+
integrity sha512-fHBB4A/aWMcvdmDY79gpgQt0ufKG8F1gwTgO3+RjjudVe5kovNy5TeXdHrCa0MksFVKjktqLjJrgiBITJXjg+g==
3711+
dependencies:
3712+
expo-modules-core "~0.2.0"
3713+
36973714
expo-splash-screen@~0.11.2:
36983715
version "0.11.2"
36993716
resolved "https://registry.yarnpkg.com/expo-splash-screen/-/expo-splash-screen-0.11.2.tgz#70c69052981cc982d12030f2a1df5b35af7ee752"
@@ -7704,6 +7721,11 @@ utils-merge@1.0.1:
77047721
resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.1.tgz#9f95710f50a267947b2ccc124741c1028427e713"
77057722
integrity sha1-n5VxD1CiZ5R7LMwSR0HBAoQn5xM=
77067723

7724+
uuid@7.0.2:
7725+
version "7.0.2"
7726+
resolved "https://registry.yarnpkg.com/uuid/-/uuid-7.0.2.tgz#7ff5c203467e91f5e0d85cfcbaaf7d2ebbca9be6"
7727+
integrity sha512-vy9V/+pKG+5ZTYKf+VcphF5Oc6EFiu3W8Nv3P3zIh0EqVI80ZxOzuPfe9EHjkFNvf8+xuTHVeei4Drydlx4zjw==
7728+
77077729
uuid@^3.3.2, uuid@^3.4.0:
77087730
version "3.4.0"
77097731
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.4.0.tgz#b23e4358afa8a202fe7a100af1f5f883f02007ee"

0 commit comments

Comments
 (0)