From 3ccb42475ac9cd7c84423386212c072dedf4dac3 Mon Sep 17 00:00:00 2001 From: Ala'a Al-Deen Al-Haddad <41290898+proalaa@users.noreply.github.com> Date: Mon, 25 Mar 2024 16:40:07 +0300 Subject: [PATCH] build and integrate home page --- .../common/cards/nearby/NearbyJobCard.jsx | 38 ++++++++---- .../common/cards/popular/PopularJobCard.jsx | 48 +++++++++++---- .../cards/popular/popularjobcard.style.js | 4 +- components/home/nearby/Nearbyjobs.jsx | 47 ++++++++++++--- components/home/popular/Popularjobs.jsx | 58 +++++++++++++++++-- hook/useFetch.js | 47 +++++++++++++++ utils/index.js | 10 ++++ 7 files changed, 218 insertions(+), 34 deletions(-) create mode 100644 hook/useFetch.js create mode 100644 utils/index.js diff --git a/components/common/cards/nearby/NearbyJobCard.jsx b/components/common/cards/nearby/NearbyJobCard.jsx index 7898bd9..f045074 100644 --- a/components/common/cards/nearby/NearbyJobCard.jsx +++ b/components/common/cards/nearby/NearbyJobCard.jsx @@ -1,14 +1,32 @@ -import React from 'react' -import { View, Text } from 'react-native' +import { View, Text, TouchableOpacity, Image } from "react-native"; -import styles from './nearbyjobcard.style' +import styles from "./nearbyjobcard.style"; +import { checkImageURL } from "../../../../utils"; -const NearbyJobCard = () => { +const NearbyJobCard = ({ job, handleNavigate }) => { return ( - - NearbyJobCard - - ) -} + + + + -export default NearbyJobCard \ No newline at end of file + + + {job?.job_title} + + + {job?.job_employment_type} + + + ); +}; + +export default NearbyJobCard; diff --git a/components/common/cards/popular/PopularJobCard.jsx b/components/common/cards/popular/PopularJobCard.jsx index b23a754..4dd808e 100644 --- a/components/common/cards/popular/PopularJobCard.jsx +++ b/components/common/cards/popular/PopularJobCard.jsx @@ -1,14 +1,42 @@ -import React from 'react' -import { View, Text } from 'react-native' +import { View, Text, TouchableOpacity, Image } from "react-native"; -import styles from './popularjobcard.style' +import styles from "./popularjobcard.style"; +import { checkImageURL } from "../../../../utils"; -const PopularJobCard = () => { +const PopularJobCard = ({ item, selectedJob, handleCardPress }) => { return ( - - PopularJobCard - - ) -} + handleCardPress(item)} + > + + + + + {item.employer_name} + -export default PopularJobCard \ No newline at end of file + + + {item.job_title} + + + + {item?.job_publisher} - + + {item.job_country} + + + + ); +}; + +export default PopularJobCard; diff --git a/components/common/cards/popular/popularjobcard.style.js b/components/common/cards/popular/popularjobcard.style.js index 94e6e1b..72d66cc 100644 --- a/components/common/cards/popular/popularjobcard.style.js +++ b/components/common/cards/popular/popularjobcard.style.js @@ -44,9 +44,9 @@ const styles = StyleSheet.create({ justifyContent: "flex-start", alignItems: "center", }, - publisher: (selectedJob) => ({ + publisher: (selectedJob, item) => ({ fontSize: SIZES.medium - 2, - fontFamily: FONT.bold, + fontFamily: FONT.regular, color: selectedJob === item.job_id ? COLORS.white : COLORS.primary, }), location: { diff --git a/components/home/nearby/Nearbyjobs.jsx b/components/home/nearby/Nearbyjobs.jsx index 5dda963..2ce7c37 100644 --- a/components/home/nearby/Nearbyjobs.jsx +++ b/components/home/nearby/Nearbyjobs.jsx @@ -1,14 +1,45 @@ -import React from 'react' -import { View, Text } from 'react-native' +import React from "react"; +import { useRouter } from "expo-router"; +import { View, Text, TouchableOpacity, ActivityIndicator } from "react-native"; -import styles from './nearbyjobs.style' +import styles from "./nearbyjobs.style"; +import { COLORS } from "../../../constants"; +import NearbyJobCard from "../../common/cards/nearby/NearbyJobCard"; +import useFetch from "../../../hook/useFetch"; const Nearbyjobs = () => { + const router = useRouter(); + const { data, isLoading, error } = useFetch("search", { + query: "React Native developer", + num_pages: "1", + }); + return ( - - Nearbyjobs + + + Nearby jobs + + Show all + + + + + {isLoading ? ( + + ) : error ? ( + Something went wrong + ) : ( + data?.map((job) => ( + router.push(`/job-details/${job.job_id}`)} + /> + )) + )} + - ) -} + ); +}; -export default Nearbyjobs \ No newline at end of file +export default Nearbyjobs; diff --git a/components/home/popular/Popularjobs.jsx b/components/home/popular/Popularjobs.jsx index 3b42d2d..06d4efd 100644 --- a/components/home/popular/Popularjobs.jsx +++ b/components/home/popular/Popularjobs.jsx @@ -1,12 +1,62 @@ -import React from "react"; -import { View, Text } from "react-native"; +import { useState } from "react"; +import { useRouter } from "expo-router"; +import { + View, + Text, + TouchableOpacity, + FlatList, + ActivityIndicator, +} from "react-native"; import styles from "./popularjobs.style"; +import { COLORS, SIZES } from "../../../constants"; +import PopularJobCard from "../../common/cards/popular/PopularJobCard"; +import useFetch from "../../../hook/useFetch"; const Popularjobs = () => { + const router = useRouter(); + const { data, isLoading, error } = useFetch("search", { + query: "React developer", + num_pages: "1", + }); + + const [selectedJob, setSelectedJob] = useState(); + + const handleCardPress = (item) => { + router.push(`/job-details/${item.job_id}`); + setSelectedJob(item.job_id); + }; + return ( - - + + + Popular jobs + + Show all + + + + + {isLoading ? ( + + ) : error ? ( + Something went wrong + ) : ( + ( + + )} + keyExtractor={(item) => item.job_id} + contentContainerStyle={{ columnGap: SIZES.medium }} + horizontal + /> + )} + ); }; diff --git a/hook/useFetch.js b/hook/useFetch.js new file mode 100644 index 0000000..6e9b8ef --- /dev/null +++ b/hook/useFetch.js @@ -0,0 +1,47 @@ +import { useState, useEffect } from "react"; +import axios from "axios"; + +const useFetch = (endpoint, query) => { + const [data, setData] = useState([]); + const [isLoading, setIsLoading] = useState(false); + const [error, setError] = useState(null); + + const options = { + method: "GET", + url: `https://jsearch.p.rapidapi.com/${endpoint}`, + headers: { + "X-RapidAPI-Key": "8cf63f2becmsh2707d400616d579p10792ajsn93584592bd9d", + "X-RapidAPI-Host": "jsearch.p.rapidapi.com", + }, + params: { ...query }, + }; + + const fetchData = async () => { + setIsLoading(true); + + try { + const response = await axios.request(options); + + setData(response.data.data); + setIsLoading(false); + } catch (error) { + setError(error); + console.log(error); + } finally { + setIsLoading(false); + } + }; + + useEffect(() => { + fetchData(); + }, []); + + const refetch = () => { + setIsLoading(true); + fetchData(); + }; + + return { data, isLoading, error, refetch }; +}; + +export default useFetch; diff --git a/utils/index.js b/utils/index.js new file mode 100644 index 0000000..03516d0 --- /dev/null +++ b/utils/index.js @@ -0,0 +1,10 @@ +export const checkImageURL = (url) => { + if (!url) return false; + else { + const pattern = new RegExp( + "^https?:\\/\\/.+\\.(png|jpg|jpeg|bmp|gif|webp)$", + "i" + ); + return pattern.test(url); + } +};