-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBookList.js
More file actions
106 lines (98 loc) · 2.54 KB
/
BookList.js
File metadata and controls
106 lines (98 loc) · 2.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
import React, { useEffect, useState } from 'react';
import { View, Text, FlatList, Image, StyleSheet, TouchableOpacity, TextInput } from 'react-native';
const BookList = ({ navigation }) => {
const [books, setBooks] = useState([]);
const [searchQuery, setSearchQuery] = useState('');
const [filteredBooks, setFilteredBooks] = useState([]);
useEffect(() => {
fetch('https://example-data.draftbit.com/books')
.then((response) => response.json())
.then((data) => {
setBooks(data);
setFilteredBooks(data);
})
.catch((error) => console.error(error));
}, []);
const handleBookPress = (book) => {
navigation.navigate('BookDetails', { book });
};
const handleSearch = (query) => {
setSearchQuery(query);
const filtered = books.filter((book) =>
book.title && book.title.toLowerCase().includes(query.toLowerCase())
);
setFilteredBooks(filtered);
};
const renderItem = ({ item }) => (
<TouchableOpacity style={styles.card} onPress={() => handleBookPress(item)}>
<Image source={{ uri: item.image_url }} style={styles.bookImage} />
<View style={styles.bookDetails}>
<Text style={styles.title}>{item.title}</Text>
<Text style={styles.authors}>Author: {item.authors}</Text>
<Text style={styles.rating}>Rating: {item.rating}</Text>
</View>
</TouchableOpacity>
);
return (
<View style={styles.container}>
<TextInput
style={styles.searchInput}
placeholder="Search for books"
value={searchQuery}
onChangeText={(text) => handleSearch(text)}
/>
<FlatList
data={filteredBooks}
renderItem={renderItem}
keyExtractor={(item) => item.id.toString()}
/>
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
backgroundColor: '#f8f8f8',
},
searchInput: {
padding: 10,
backgroundColor: 'white',
borderRadius: 8,
margin: 16,
},
card: {
flexDirection: 'row',
alignItems: 'center',
padding: 16,
margin: 8,
borderWidth: 1,
borderColor: '#ccc',
borderRadius: 8,
backgroundColor: 'white',
elevation: 1,
shadowColor: 'black',
shadowOffset: { width: 0, height: 2 },
shadowOpacity: 0.2,
shadowRadius: 4,
},
bookImage: {
width: 100,
height: 150,
marginRight: 16,
borderRadius: 6,
},
bookDetails: {
flex: 1,
},
title: {
fontSize: 18,
fontWeight: 'bold',
},
authors: {
fontSize: 16,
},
rating: {
fontSize: 16,
},
});
export default BookList;