Skip to content
This repository was archived by the owner on May 5, 2025. It is now read-only.

Commit 1c53539

Browse files
committed
feat: update navigation paths in DetailRecipientScreen and RecipientCard; enhance EditRecipientScreen with form fields and image upload
1 parent 0dd1301 commit 1c53539

File tree

3 files changed

+186
-8
lines changed

3 files changed

+186
-8
lines changed

src/app/recipients/detail-recipient.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ const DetailRecipientScreen = () => {
99
// Handle edit action
1010
const handleEdit = () => {
1111
router.push({
12-
pathname: './recipients/edit-recipient',
12+
pathname: '/recipients/edit-recipient',
1313
params: {
1414
id,
1515
image,
Lines changed: 184 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,189 @@
1-
import { Text, View } from 'react-native';
1+
import React, { useState, useEffect } from 'react';
2+
import { View, Text, TextInput, TouchableOpacity, StyleSheet, ScrollView, Image } from 'react-native';
3+
import * as ImagePicker from 'expo-image-picker';
4+
import { Recipient } from '@/models/Recipient';
5+
import {
6+
useNavigation,
7+
useRoute as useRouteAlias,
8+
} from '@react-navigation/native';
29

310
const EditRecipientScreen = () => {
4-
return (
5-
<View>
6-
<Text>Edit Recipient Screen</Text>
7-
</View>
8-
);
11+
const navigation = useNavigation();
12+
const route = useRouteAlias();
13+
const recipient = route.params as Recipient;
14+
const [image, setImage] = useState<string | null>(recipient.image);
15+
const [name, setName] = useState(recipient.name);
16+
const [description, setDescription] = useState(recipient.description || '');
17+
const [budget, setBudget] = useState(recipient.budget.toString());
18+
const [spent, setSpent] = useState(recipient.spent.toString());
19+
20+
useEffect(() => {
21+
if (recipient) {
22+
setImage(recipient.image);
23+
setName(recipient.name);
24+
setDescription(recipient.description || '');
25+
setBudget(recipient.budget.toString());
26+
setSpent(recipient.spent.toString());
27+
}
28+
}, [recipient]);
29+
30+
const pickImage = async () => {
31+
// Request permission
32+
const { status } = await ImagePicker.requestMediaLibraryPermissionsAsync();
33+
if (status !== 'granted') {
34+
alert('Sorry, we need camera roll permissions!');
35+
return;
36+
}
37+
38+
const result = await ImagePicker.launchImageLibraryAsync({
39+
mediaTypes: ImagePicker.MediaTypeOptions.Images,
40+
allowsEditing: true,
41+
aspect: [4, 3],
42+
quality: 1,
43+
});
44+
45+
if (!result.canceled) {
46+
setImage(result.assets[0].uri);
47+
}
48+
};
49+
50+
const handleSaveRecipient = () => {
51+
const updatedRecipient = {
52+
image: image || '',
53+
name,
54+
description,
55+
budget: parseFloat(budget),
56+
spent: parseFloat(spent),
57+
};
58+
console.log(updatedRecipient);
59+
// TODO: gửi updatedRecipient lên server hoặc lưu vào cơ sở dữ liệu
60+
// Điều hướng trở lại màn hình trước
61+
navigation.goBack();
62+
};
63+
64+
return (
65+
<ScrollView contentContainerStyle={styles.container}>
66+
{/* Upload Image */}
67+
<View style={styles.inputGroup}>
68+
<Text style={styles.label}>Profile Image</Text>
69+
<TouchableOpacity style={styles.imagePicker} onPress={pickImage}>
70+
{image ? (
71+
<Image source={{ uri: image }} style={styles.previewImage} />
72+
) : (
73+
<Text style={styles.pickImageText}>Pick an Image</Text>
74+
)}
75+
</TouchableOpacity>
76+
</View>
77+
78+
{/* Name */}
79+
<View style={styles.inputGroup}>
80+
<Text style={styles.label}>Name</Text>
81+
<TextInput
82+
style={styles.input}
83+
placeholder="Enter recipient's name"
84+
value={name}
85+
onChangeText={setName}
86+
/>
87+
</View>
88+
89+
{/* Description */}
90+
<View style={styles.inputGroup}>
91+
<Text style={styles.label}>Description (optional)</Text>
92+
<TextInput
93+
style={[styles.input, { height: 100 }]}
94+
placeholder="Enter description"
95+
value={description}
96+
onChangeText={setDescription}
97+
multiline
98+
/>
99+
</View>
100+
101+
{/* Budget */}
102+
<View style={styles.inputGroup}>
103+
<Text style={styles.label}>Budget</Text>
104+
<TextInput
105+
style={styles.input}
106+
placeholder="Enter budget"
107+
value={budget}
108+
onChangeText={setBudget}
109+
keyboardType="numeric"
110+
/>
111+
</View>
112+
113+
{/* Spent */}
114+
<View style={styles.inputGroup}>
115+
<Text style={styles.label}>Spent</Text>
116+
<TextInput
117+
style={styles.input}
118+
placeholder="Enter spent amount"
119+
value={spent}
120+
onChangeText={setSpent}
121+
keyboardType="numeric"
122+
/>
123+
</View>
124+
125+
{/* Save Button */}
126+
<TouchableOpacity style={styles.saveButton} onPress={handleSaveRecipient}>
127+
<Text style={styles.saveButtonText}>Save Recipient</Text>
128+
</TouchableOpacity>
129+
</ScrollView>
130+
);
9131
};
10132

133+
const styles = StyleSheet.create({
134+
container: {
135+
padding: 16,
136+
backgroundColor: '#F5F5F5',
137+
flexGrow: 1,
138+
},
139+
inputGroup: {
140+
marginBottom: 16,
141+
},
142+
label: {
143+
fontSize: 14,
144+
color: '#666',
145+
marginBottom: 8,
146+
},
147+
input: {
148+
borderWidth: 1,
149+
borderColor: '#E0E0E0',
150+
borderRadius: 8,
151+
paddingHorizontal: 12,
152+
paddingVertical: 10,
153+
fontSize: 15,
154+
backgroundColor: 'white',
155+
color: '#333',
156+
},
157+
imagePicker: {
158+
borderWidth: 1,
159+
borderColor: '#E0E0E0',
160+
borderRadius: 8,
161+
height: 180,
162+
alignItems: 'center',
163+
justifyContent: 'center',
164+
backgroundColor: 'white',
165+
},
166+
pickImageText: {
167+
color: '#666',
168+
fontSize: 16,
169+
},
170+
previewImage: {
171+
width: '100%',
172+
height: '100%',
173+
borderRadius: 8,
174+
},
175+
saveButton: {
176+
backgroundColor: '#007AFF',
177+
padding: 16,
178+
borderRadius: 8,
179+
alignItems: 'center',
180+
marginTop: 24,
181+
},
182+
saveButtonText: {
183+
color: 'white',
184+
fontSize: 16,
185+
fontWeight: '600',
186+
},
187+
});
188+
11189
export default EditRecipientScreen;

src/components/utils/RecipientCard.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ export default function RecipientCard({
1414

1515
const handlePress = () => {
1616
router.push({
17-
pathname: './recipients/detail-recipient',
17+
pathname: '/recipients/detail-recipient',
1818
params: { id, image, name, description, budget, spent },
1919
});
2020
};

0 commit comments

Comments
 (0)