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

Commit 4534482

Browse files
committed
update: filter tab component
1 parent de1b8a9 commit 4534482

File tree

1 file changed

+140
-9
lines changed

1 file changed

+140
-9
lines changed
Lines changed: 140 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,122 @@
1-
import { StyleSheet, Text, TouchableOpacity, View } from 'react-native';
1+
import { MaterialIcons } from '@expo/vector-icons';
2+
import React, { useState } from 'react';
3+
import {
4+
FlatList,
5+
Modal,
6+
StyleSheet,
7+
Text,
8+
TouchableOpacity,
9+
TouchableWithoutFeedback,
10+
View,
11+
} from 'react-native';
212

313
interface FilterTabsProps {
414
selectedTab: string;
515
onSelectTab: (tab: string) => void;
16+
recipients: { id: string; name: string }[];
17+
selectedRecipient: string | null;
18+
onSelectRecipient: (recipientId: string | null) => void;
619
}
720

821
export default function FilterTabs({
922
selectedTab,
1023
onSelectTab,
24+
recipients,
25+
selectedRecipient,
26+
onSelectRecipient,
1127
}: FilterTabsProps) {
12-
const tabs = ['All', 'Recipient', 'Occasion', 'Tag'];
28+
const tabs = ['All', 'Recipients'];
29+
const [showRecipientModal, setShowRecipientModal] = useState(false);
30+
31+
const selectedRecipientName =
32+
recipients.find((r) => r.id === selectedRecipient)?.name || 'Recipients';
1333

1434
return (
1535
<View style={styles.container}>
1636
{tabs.map((tab) => (
1737
<TouchableOpacity
1838
key={tab}
19-
style={[styles.tab, selectedTab === tab && styles.selectedTab]}
20-
onPress={() => onSelectTab(tab)}
39+
style={[
40+
styles.tab,
41+
tab === 'All' && styles.selectedTab,
42+
tab === 'Recipients' &&
43+
selectedRecipient &&
44+
styles.activeRecipientTab,
45+
]}
46+
onPress={() => {
47+
if (tab === 'Recipients') {
48+
setShowRecipientModal(true);
49+
}
50+
}}
2151
>
2252
<Text
23-
style={[
24-
styles.tabText,
25-
selectedTab === tab && styles.selectedTabText,
26-
]}
53+
style={[styles.tabText, tab === 'All' && styles.selectedTabText]}
2754
>
28-
{tab}
55+
{tab === 'Recipients' ? selectedRecipientName : tab}
2956
</Text>
57+
{tab === 'Recipients' && (
58+
<MaterialIcons
59+
name="filter-list"
60+
size={16}
61+
color={selectedRecipient ? '#4B6BFB' : '#666'}
62+
style={styles.filterIcon}
63+
/>
64+
)}
3065
</TouchableOpacity>
3166
))}
67+
68+
{/* Dialog chọn recipient */}
69+
<Modal
70+
visible={showRecipientModal}
71+
transparent={true}
72+
animationType="slide"
73+
onRequestClose={() => setShowRecipientModal(false)}
74+
>
75+
<TouchableWithoutFeedback onPress={() => setShowRecipientModal(false)}>
76+
<View style={styles.modalOverlay}>
77+
<TouchableWithoutFeedback>
78+
<View style={styles.modalContent}>
79+
<Text style={styles.modalTitle}>Select Recipient</Text>
80+
<FlatList
81+
data={recipients}
82+
keyExtractor={(item) => item.id}
83+
renderItem={({ item }) => (
84+
<TouchableOpacity
85+
style={[
86+
styles.option,
87+
item.id === selectedRecipient && styles.activeOption,
88+
]}
89+
onPress={() => {
90+
onSelectRecipient(item.id);
91+
setShowRecipientModal(false);
92+
}}
93+
>
94+
<Text
95+
style={[
96+
styles.optionText,
97+
item.id === selectedRecipient &&
98+
styles.activeOptionText,
99+
]}
100+
>
101+
{item.name}
102+
</Text>
103+
</TouchableOpacity>
104+
)}
105+
/>
106+
<TouchableOpacity
107+
style={styles.option}
108+
onPress={() => {
109+
onSelectRecipient(null);
110+
setShowRecipientModal(false);
111+
}}
112+
>
113+
<Text style={styles.optionText}>Clear Selection</Text>
114+
</TouchableOpacity>
115+
</View>
116+
</TouchableWithoutFeedback>
117+
</View>
118+
</TouchableWithoutFeedback>
119+
</Modal>
32120
</View>
33121
);
34122
}
@@ -41,6 +129,8 @@ const styles = StyleSheet.create({
41129
gap: 8,
42130
},
43131
tab: {
132+
flexDirection: 'row',
133+
alignItems: 'center',
44134
paddingHorizontal: 16,
45135
paddingVertical: 8,
46136
borderRadius: 20,
@@ -49,11 +139,52 @@ const styles = StyleSheet.create({
49139
selectedTab: {
50140
backgroundColor: '#e8eeff',
51141
},
142+
activeRecipientTab: {
143+
borderColor: '#4B6BFB',
144+
borderWidth: 1,
145+
},
52146
tabText: {
53147
color: '#666',
54148
fontSize: 14,
55149
},
56150
selectedTabText: {
57151
color: '#4B6BFB',
58152
},
153+
filterIcon: {
154+
marginLeft: 4,
155+
},
156+
modalOverlay: {
157+
flex: 1,
158+
backgroundColor: 'rgba(0, 0, 0, 0.5)',
159+
justifyContent: 'center',
160+
alignItems: 'center',
161+
},
162+
modalContent: {
163+
width: '80%',
164+
backgroundColor: 'white',
165+
borderRadius: 8,
166+
padding: 16,
167+
},
168+
modalTitle: {
169+
fontSize: 18,
170+
fontWeight: 'bold',
171+
marginBottom: 16,
172+
textAlign: 'center',
173+
},
174+
option: {
175+
paddingVertical: 12,
176+
borderBottomWidth: 1,
177+
borderBottomColor: '#E0E0E0',
178+
},
179+
activeOption: {
180+
backgroundColor: '#e8eeff',
181+
},
182+
optionText: {
183+
fontSize: 16,
184+
color: '#333',
185+
textAlign: 'center',
186+
},
187+
activeOptionText: {
188+
color: '#4B6BFB',
189+
},
59190
});

0 commit comments

Comments
 (0)