From eb282ec00f511d29e3686c66427294da215a931b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nurullah=20U=C3=87AN?= <130992676+nucan25@users.noreply.github.com> Date: Tue, 14 May 2024 19:26:20 +0300 Subject: [PATCH 1/5] Created SearchResults page --- mobile/NBAForum/commonNavigator.js | 9 +++++- mobile/NBAForum/pages/SearchResults.js | 45 ++++++++++++++++++++++++++ mobile/NBAForum/pages/index.js | 2 ++ 3 files changed, 55 insertions(+), 1 deletion(-) create mode 100644 mobile/NBAForum/pages/SearchResults.js diff --git a/mobile/NBAForum/commonNavigator.js b/mobile/NBAForum/commonNavigator.js index 62ee3a9a..239cdd88 100644 --- a/mobile/NBAForum/commonNavigator.js +++ b/mobile/NBAForum/commonNavigator.js @@ -1,6 +1,6 @@ import React from "react"; import { createNativeStackNavigator } from '@react-navigation/native-stack'; -import { Team, Player, Search } from "./pages"; +import { Team, Player, Search, SearchResults } from "./pages"; const Stack = createNativeStackNavigator(); @@ -16,6 +16,13 @@ function CommonNavigator() { headerShown: false }} /> + { + return ( + + {results.player && ( + navigation.navigate('Player', { id: results.player.id })}> + + {results.player.name} + + )} + {results.team && ( + navigation.navigate('Team', { id: results.team.id })}> + + {results.team.name} + + )} + + ); +}; + +const styles = StyleSheet.create({ + resultsContainer: { + padding: 10, + }, + item: { + flexDirection: 'row', + alignItems: 'center', + padding: 10, + borderBottomWidth: 1, + borderBottomColor: '#ccb', + }, + image: { + width: 50, + height: 50, + marginRight: 10, + borderRadius: 25, + }, + name: { + fontSize: 18, + }, +}); + +export default SearchResults; \ No newline at end of file diff --git a/mobile/NBAForum/pages/index.js b/mobile/NBAForum/pages/index.js index 749a4dc1..59fc18f8 100644 --- a/mobile/NBAForum/pages/index.js +++ b/mobile/NBAForum/pages/index.js @@ -5,6 +5,7 @@ import HomePage from "./HomePage"; import Player from "./Player"; import Feed from "./Feed"; import Search from "./Search"; +import SearchResults from "./SearchResults" export{ Login, @@ -14,4 +15,5 @@ export{ Player, Feed, Search, + SearchResults } \ No newline at end of file From d9d26be6ab6f4d02a9d74e8c096c970a70ee00ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nurullah=20U=C3=87AN?= <130992676+nucan25@users.noreply.github.com> Date: Tue, 14 May 2024 19:27:36 +0300 Subject: [PATCH 2/5] Update Search.js --- mobile/NBAForum/pages/Search.js | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/mobile/NBAForum/pages/Search.js b/mobile/NBAForum/pages/Search.js index 96fe1b99..08f60674 100644 --- a/mobile/NBAForum/pages/Search.js +++ b/mobile/NBAForum/pages/Search.js @@ -2,11 +2,13 @@ import React, { useState, useContext } from 'react'; import { View, Text, StyleSheet, ActivityIndicator } from 'react-native'; import { Searchbar } from 'react-native-paper'; import axios from 'axios'; -import { Context } from "../globalContext/globalContext.js"; // Ensure the correct path +import { Context } from "../globalContext/globalContext.js"; +import SearchResults from './SearchResults'; // Import SearchResults component const Search = ({ navigation }) => { const [searchQuery, setSearchQuery] = useState(''); const [isLoading, setIsLoading] = useState(false); + const [results, setResults] = useState(null); // Store search results const [error, setError] = useState(''); const { baseURL } = useContext(Context); @@ -21,16 +23,10 @@ const Search = ({ navigation }) => { try { const encodedQuery = encodeURIComponent(query); const response = await axios.get(`${baseURL}/search/?query=${encodedQuery}`); - const data = response.data; setIsLoading(false); - - if (data.player) { - - // If player data is not null, navigate to the PlayerDetails screen - navigation.navigate('Player', { id: data.player.id }); - } else if (data.team) { - // If team data is not null, navigate to the TeamDetails screen - navigation.navigate('Team', { id: data.team.id }); + if (response.data && (response.data.player || response.data.team)) { + setResults(response.data); // Store results in state + console.log(results) } else { setError("No data found for the query."); } @@ -53,9 +49,10 @@ const Search = ({ navigation }) => { ) : error ? ( {error} + ) : results ? ( + ) : null} - ); }; @@ -67,4 +64,4 @@ const styles = StyleSheet.create({ }, }); -export default Search; +export default Search; \ No newline at end of file From fb0f70490dc04f64fa298309e69e7b1ed39708fc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nurullah=20U=C3=87AN?= <130992676+nucan25@users.noreply.github.com> Date: Thu, 16 May 2024 12:37:14 +0300 Subject: [PATCH 3/5] Display team and player results after search excluding pots --- mobile/NBAForum/pages/Search.js | 36 +++--- mobile/NBAForum/pages/SearchResults.js | 166 +++++++++++++++++++++---- 2 files changed, 160 insertions(+), 42 deletions(-) diff --git a/mobile/NBAForum/pages/Search.js b/mobile/NBAForum/pages/Search.js index 08f60674..aa10808b 100644 --- a/mobile/NBAForum/pages/Search.js +++ b/mobile/NBAForum/pages/Search.js @@ -3,30 +3,29 @@ import { View, Text, StyleSheet, ActivityIndicator } from 'react-native'; import { Searchbar } from 'react-native-paper'; import axios from 'axios'; import { Context } from "../globalContext/globalContext.js"; -import SearchResults from './SearchResults'; // Import SearchResults component +import { useNavigation } from '@react-navigation/native'; -const Search = ({ navigation }) => { +const Search = () => { const [searchQuery, setSearchQuery] = useState(''); const [isLoading, setIsLoading] = useState(false); - const [results, setResults] = useState(null); // Store search results const [error, setError] = useState(''); - const { baseURL } = useContext(Context); + const navigation = useNavigation(); - const handleSearch = async (query) => { - if (!query.trim()) { + const handleSearch = async () => { + if (!searchQuery.trim()) { setError("Please enter a valid search query."); return; } setIsLoading(true); setError(''); try { - const encodedQuery = encodeURIComponent(query); + const encodedQuery = encodeURIComponent(searchQuery); const response = await axios.get(`${baseURL}/search/?query=${encodedQuery}`); setIsLoading(false); - if (response.data && (response.data.player || response.data.team)) { - setResults(response.data); // Store results in state - console.log(results) + if (response.data) { + console.log(response.data) + navigation.navigate('SearchResults', { query: searchQuery, data: response.data }); } else { setError("No data found for the query."); } @@ -43,14 +42,12 @@ const Search = ({ navigation }) => { placeholder="Search for a NBA team/player!" value={searchQuery} onChangeText={setSearchQuery} - onSubmitEditing={() => handleSearch(searchQuery)} + onSubmitEditing={handleSearch} /> {isLoading ? ( - + ) : error ? ( - {error} - ) : results ? ( - + {error} ) : null} ); @@ -58,10 +55,15 @@ const Search = ({ navigation }) => { const styles = StyleSheet.create({ container: { - padding: 25, + padding: 20, flex: 1, backgroundColor: '#55A1E6', }, + error: { + color: 'red', + marginTop: 10, + fontWeight: 'bold' + } }); -export default Search; \ No newline at end of file +export default Search; diff --git a/mobile/NBAForum/pages/SearchResults.js b/mobile/NBAForum/pages/SearchResults.js index e5f5481e..ed7d6fb1 100644 --- a/mobile/NBAForum/pages/SearchResults.js +++ b/mobile/NBAForum/pages/SearchResults.js @@ -1,45 +1,161 @@ -import React from 'react'; -import { View, Text, TouchableOpacity, Image, StyleSheet } from 'react-native'; +import React, { useContext, useState, useEffect } from 'react'; +import { View, Text, Image, StyleSheet, TouchableOpacity, ScrollView, ActivityIndicator } from 'react-native'; +import axios from 'axios'; +import { Context } from '../globalContext/globalContext'; +import { useNavigation, useRoute } from '@react-navigation/native'; + +const SearchResults = () => { + const navigation = useNavigation(); + const route = useRoute(); + const { query } = route.params; + const { baseURL } = useContext(Context); + const [data, setData] = useState({ team: null, player: null, posts: [] }); + const [isLoading, setIsLoading] = useState(true); + const [error, setError] = useState(''); + + useEffect(() => { + fetchData(); + }, [query]); + + const fetchData = async () => { + setIsLoading(true); + setError(''); + try { + const response = await axios.get(`${baseURL}/search/?query=${encodeURIComponent(query)}`); + if (response.data) { + setData(response.data); + if (response.data.team) { + fetchTeamDetails(response.data.team.id); + } + if (response.data.player) { + fetchPlayerDetails(response.data.player.id); + } + } else { + setError('No results found'); + } + } catch (error) { + setError('Failed to fetch data'); + console.error('Error fetching data:', error); + } finally { + setIsLoading(false); + } + }; + + const fetchTeamDetails = async (teamId) => { + try { + const teamResponse = await axios.get(`${baseURL}/team/?id=${teamId}`); + setData(prevState => ({ + ...prevState, + team: { ...prevState.team, ...teamResponse.data } + })); + } catch (error) { + console.error('Error fetching team details:', error); + } + }; + + const fetchPlayerDetails = async (playerId) => { + try { + const playerResponse = await axios.get(`${baseURL}/player/?id=${playerId}`); + setData(prevState => ({ + ...prevState, + player: { ...prevState.player, ...playerResponse.data } + })); + } catch (error) { + console.error('Error fetching player details:', error); + } + }; + + if (isLoading) { + return ; + } + + if (error) { + return {error}; + } -const SearchResults = ({ results, navigation }) => { return ( - - {results.player && ( - navigation.navigate('Player', { id: results.player.id })}> - - {results.player.name} - + + Search Results for "{query}": + {data.team && ( + + Teams: + navigation.navigate('Team', { id: data.team.id })}> + + + {data.team.name} + + + + )} + {data.player && ( + + Players: + navigation.navigate('Player', { id: data.player.id })}> + + + {data.player.name} + + + )} - {results.team && ( - navigation.navigate('Team', { id: results.team.id })}> - - {results.team.name} - + {data.posts && data.posts.length > 0 && ( + + Related Posts: + {data.posts.map((post) => ( + {post.id} + ))} + )} - + ); }; const styles = StyleSheet.create({ - resultsContainer: { - padding: 10, + container: { + flex: 1, + padding: 20, + backgroundColor: '#55A1E6' + }, + header: { + fontSize: 22, + fontWeight: 'bold', + marginBottom: 20 + }, + subheader: { + fontSize: 18, + fontWeight: 'bold', + marginBottom: 10 }, item: { + marginBottom: 10 + }, + row: { flexDirection: 'row', alignItems: 'center', padding: 10, - borderBottomWidth: 1, - borderBottomColor: '#ccb', + backgroundColor: '#eaeaea', }, image: { - width: 50, - height: 50, + width: 70, + height: 70, marginRight: 10, - borderRadius: 25, + resizeMode: 'contain' }, - name: { - fontSize: 18, + text: { + fontSize: 20 + }, + postsContainer: { + marginTop: 20 + }, + postText: { + marginTop: 5, + fontSize: 16 }, + center: { + flex: 1, + justifyContent: 'center', + alignItems: 'center' + } }); -export default SearchResults; \ No newline at end of file +export default SearchResults; From 6f3aac281a12b8e6656c771b50696fc74f013a4e Mon Sep 17 00:00:00 2001 From: zbuseaydin Date: Thu, 16 May 2024 14:18:08 +0300 Subject: [PATCH 4/5] render links --- mobile/NBAForum/pages/Post.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/mobile/NBAForum/pages/Post.js b/mobile/NBAForum/pages/Post.js index b3056bee..a8ec9985 100644 --- a/mobile/NBAForum/pages/Post.js +++ b/mobile/NBAForum/pages/Post.js @@ -2,6 +2,7 @@ import React, { useContext, useState } from 'react'; import { Context } from "../globalContext/globalContext.js" import { View, Text, Image, TouchableOpacity, StyleSheet, TextInput } from 'react-native'; import Icon from 'react-native-vector-icons/FontAwesome'; +import RenderHTML from 'react-native-render-html'; import moment from 'moment'; import axios from 'axios'; @@ -98,14 +99,15 @@ const Post = ({ post }) => { {moment(post.created_at).fromNow()} - - {post.post} + + {post.image && ( )} + @@ -186,7 +188,7 @@ const styles = StyleSheet.create({ userInfoContainer: { flexDirection: 'row', alignItems: 'center', - marginBottom: 5, + marginBottom: 1, justifyContent: 'space-between', }, profileImage: { @@ -238,6 +240,11 @@ const styles = StyleSheet.create({ likeCount: { marginLeft: 5, }, + separator: { + height: 1, + backgroundColor: '#BCBCBC', + marginVertical: 10, + }, }); export default Post; From 5a81228851d1a687e31537a7916d08bf4cefdf86 Mon Sep 17 00:00:00 2001 From: zbuseaydin Date: Thu, 16 May 2024 14:18:25 +0300 Subject: [PATCH 5/5] show posts on search results page --- mobile/NBAForum/pages/SearchResults.js | 63 +++++++++++++++++++------- 1 file changed, 47 insertions(+), 16 deletions(-) diff --git a/mobile/NBAForum/pages/SearchResults.js b/mobile/NBAForum/pages/SearchResults.js index ed7d6fb1..75e67b28 100644 --- a/mobile/NBAForum/pages/SearchResults.js +++ b/mobile/NBAForum/pages/SearchResults.js @@ -1,6 +1,7 @@ import React, { useContext, useState, useEffect } from 'react'; -import { View, Text, Image, StyleSheet, TouchableOpacity, ScrollView, ActivityIndicator } from 'react-native'; +import { View, Text, Image, StyleSheet, TouchableOpacity, ScrollView, ActivityIndicator, FlatList } from 'react-native'; import axios from 'axios'; +import Post from './Post.js'; import { Context } from '../globalContext/globalContext'; import { useNavigation, useRoute } from '@react-navigation/native'; @@ -12,6 +13,7 @@ const SearchResults = () => { const [data, setData] = useState({ team: null, player: null, posts: [] }); const [isLoading, setIsLoading] = useState(true); const [error, setError] = useState(''); + const [postDetails, setPostDetails] = useState([]); useEffect(() => { fetchData(); @@ -30,6 +32,9 @@ const SearchResults = () => { if (response.data.player) { fetchPlayerDetails(response.data.player.id); } + if (response.data.posts) { + fetchPostDetails(response.data.posts); + } } else { setError('No results found'); } @@ -65,6 +70,18 @@ const SearchResults = () => { } }; + const fetchPostDetails = async (postIds) => { + try { + const postRequests = postIds.map(postId => axios.get(`${baseURL}/post_detail/${postId.id}/`)); + const postResponses = await Promise.all(postRequests); + const fetchedPosts = postResponses.map(response => response.data); + setPostDetails(fetchedPosts); + + } catch (error) { + console.error('Error fetching post details:', error); + } + }; + if (isLoading) { return ; } @@ -74,7 +91,7 @@ const SearchResults = () => { } return ( - + Search Results for "{query}": {data.team && ( @@ -93,28 +110,40 @@ const SearchResults = () => { navigation.navigate('Player', { id: data.player.id })}> - {data.player.name} + + {data.player.name} + {data.player.height ? data.player.height.substr(1,4) + "cm" :""} + )} {data.posts && data.posts.length > 0 && ( - - Related Posts: - {data.posts.map((post) => ( - {post.id} - ))} + + Posts: + { + ( + + )} + keyExtractor={(item) => item.post_id.toString()} + /> + } )} - + ); }; const styles = StyleSheet.create({ container: { flex: 1, - padding: 20, - backgroundColor: '#55A1E6' + position: 'relative', + backgroundColor: '#55A1E6', + padding: 5, }, header: { fontSize: 22, @@ -132,8 +161,12 @@ const styles = StyleSheet.create({ row: { flexDirection: 'row', alignItems: 'center', + backgroundColor: '#ffffff', padding: 10, - backgroundColor: '#eaeaea', + margin: 10, + borderRadius: 8, + borderWidth: 1, + borderColor: '#BCBCBC', }, image: { width: 70, @@ -142,10 +175,8 @@ const styles = StyleSheet.create({ resizeMode: 'contain' }, text: { - fontSize: 20 - }, - postsContainer: { - marginTop: 20 + fontSize: 20, + marginBottom: 5 }, postText: { marginTop: 5,