diff --git a/app/_layout.js b/app/_layout.js new file mode 100644 index 0000000..e8a054b --- /dev/null +++ b/app/_layout.js @@ -0,0 +1,25 @@ +import { Stack } from "expo-router"; +import { useCallback } from "react"; +import { useFonts } from "expo-font"; + +import * as SplashScreen from "expo-splash-screen"; + +SplashScreen.preventAutoHideAsync(); +const Layout = () => { + const [fontsLoaded] = useFonts({ + DMBold: require("../assets/fonts/DMSans-Bold.ttf"), + DMMedium: require("../assets/fonts/DMSans-Medium.ttf"), + DMRegular: require("../assets/fonts/DMSans-Regular.ttf"), + }); + + const onLayoutRootView = useCallback(async () => { + if (fontsLoaded) { + await SplashScreen.hideAsync(); + } + }, [fontsLoaded]); + + if (!fontsLoaded) return null; + return ; +}; + +export default Layout; diff --git a/app/index.js b/app/index.js new file mode 100644 index 0000000..b6d7459 --- /dev/null +++ b/app/index.js @@ -0,0 +1,40 @@ +import { Stack, useRouter } from "expo-router"; +import { SafeAreaView, ScrollView, View } from "react-native"; +import { COLORS, SIZES, icons, images } from "../constants"; +import { + Nearbyjobs, + Popularjobs, + ScreenHeaderBtn, + Welcome, +} from "../components"; +export default function Page() { + return ( + + ( + {}} + /> + ), + headerRight: () => ( + + ), + headerTitle: "", + }} + /> + + + + + + + + + + ); +} diff --git a/assets/adaptive-icon.png b/assets/adaptive-icon.png new file mode 100644 index 0000000..03d6f6b Binary files /dev/null and b/assets/adaptive-icon.png differ diff --git a/assets/favicon.png b/assets/favicon.png new file mode 100644 index 0000000..e75f697 Binary files /dev/null and b/assets/favicon.png differ diff --git a/assets/fonts/DMSans-Bold.ttf b/assets/fonts/DMSans-Bold.ttf new file mode 100644 index 0000000..7fd94a2 Binary files /dev/null and b/assets/fonts/DMSans-Bold.ttf differ diff --git a/assets/fonts/DMSans-Medium.ttf b/assets/fonts/DMSans-Medium.ttf new file mode 100644 index 0000000..ded3caf Binary files /dev/null and b/assets/fonts/DMSans-Medium.ttf differ diff --git a/assets/fonts/DMSans-Regular.ttf b/assets/fonts/DMSans-Regular.ttf new file mode 100644 index 0000000..b3c3eda Binary files /dev/null and b/assets/fonts/DMSans-Regular.ttf differ diff --git a/assets/icon.png b/assets/icon.png new file mode 100644 index 0000000..a0b1526 Binary files /dev/null and b/assets/icon.png differ diff --git a/assets/icons/amazon.png b/assets/icons/amazon.png new file mode 100644 index 0000000..e3bce17 Binary files /dev/null and b/assets/icons/amazon.png differ diff --git a/assets/icons/apple.png b/assets/icons/apple.png new file mode 100644 index 0000000..a9603fb Binary files /dev/null and b/assets/icons/apple.png differ diff --git a/assets/icons/chevron-left.png b/assets/icons/chevron-left.png new file mode 100644 index 0000000..07331ca Binary files /dev/null and b/assets/icons/chevron-left.png differ diff --git a/assets/icons/chevron-right.png b/assets/icons/chevron-right.png new file mode 100644 index 0000000..010db91 Binary files /dev/null and b/assets/icons/chevron-right.png differ diff --git a/assets/icons/figma.png b/assets/icons/figma.png new file mode 100644 index 0000000..c735633 Binary files /dev/null and b/assets/icons/figma.png differ diff --git a/assets/icons/filter.png b/assets/icons/filter.png new file mode 100644 index 0000000..59a355f Binary files /dev/null and b/assets/icons/filter.png differ diff --git a/assets/icons/google.png b/assets/icons/google.png new file mode 100644 index 0000000..809626e Binary files /dev/null and b/assets/icons/google.png differ diff --git a/assets/icons/heart-ol.png b/assets/icons/heart-ol.png new file mode 100644 index 0000000..65bae4a Binary files /dev/null and b/assets/icons/heart-ol.png differ diff --git a/assets/icons/heart.png b/assets/icons/heart.png new file mode 100644 index 0000000..6c5aa18 Binary files /dev/null and b/assets/icons/heart.png differ diff --git a/assets/icons/left.png b/assets/icons/left.png new file mode 100644 index 0000000..3463f7e Binary files /dev/null and b/assets/icons/left.png differ diff --git a/assets/icons/linkedin.png b/assets/icons/linkedin.png new file mode 100644 index 0000000..ee5c4e4 Binary files /dev/null and b/assets/icons/linkedin.png differ diff --git a/assets/icons/location.png b/assets/icons/location.png new file mode 100644 index 0000000..3a4c0cc Binary files /dev/null and b/assets/icons/location.png differ diff --git a/assets/icons/menu.png b/assets/icons/menu.png new file mode 100644 index 0000000..de496f4 Binary files /dev/null and b/assets/icons/menu.png differ diff --git a/assets/icons/microsoft.png b/assets/icons/microsoft.png new file mode 100644 index 0000000..2c3cc0f Binary files /dev/null and b/assets/icons/microsoft.png differ diff --git a/assets/icons/search.png b/assets/icons/search.png new file mode 100644 index 0000000..1a4e8ae Binary files /dev/null and b/assets/icons/search.png differ diff --git a/assets/icons/share.png b/assets/icons/share.png new file mode 100644 index 0000000..18575ff Binary files /dev/null and b/assets/icons/share.png differ diff --git a/assets/icons/slack.png b/assets/icons/slack.png new file mode 100644 index 0000000..6b8c0d8 Binary files /dev/null and b/assets/icons/slack.png differ diff --git a/assets/icons/spotify.png b/assets/icons/spotify.png new file mode 100644 index 0000000..a0a243b Binary files /dev/null and b/assets/icons/spotify.png differ diff --git a/assets/icons/twitch.png b/assets/icons/twitch.png new file mode 100644 index 0000000..4d22d34 Binary files /dev/null and b/assets/icons/twitch.png differ diff --git a/assets/icons/twitter.png b/assets/icons/twitter.png new file mode 100644 index 0000000..34fa889 Binary files /dev/null and b/assets/icons/twitter.png differ diff --git a/assets/icons/wattpad.png b/assets/icons/wattpad.png new file mode 100644 index 0000000..70a5150 Binary files /dev/null and b/assets/icons/wattpad.png differ diff --git a/assets/images/kemal.jpg b/assets/images/kemal.jpg new file mode 100644 index 0000000..e71877a Binary files /dev/null and b/assets/images/kemal.jpg differ diff --git a/assets/splash.png b/assets/splash.png new file mode 100644 index 0000000..0e89705 Binary files /dev/null and b/assets/splash.png differ diff --git a/babel.config.js b/babel.config.js index 078efac..73ebf58 100644 --- a/babel.config.js +++ b/babel.config.js @@ -2,6 +2,5 @@ module.exports = function (api) { api.cache(true); return { presets: ["babel-preset-expo"], - plugins: ["expo-router/babel"], }; }; diff --git a/components/common/cards/nearby/NearbyJobCard.jsx b/components/common/cards/nearby/NearbyJobCard.jsx new file mode 100644 index 0000000..7898bd9 --- /dev/null +++ b/components/common/cards/nearby/NearbyJobCard.jsx @@ -0,0 +1,14 @@ +import React from 'react' +import { View, Text } from 'react-native' + +import styles from './nearbyjobcard.style' + +const NearbyJobCard = () => { + return ( + + NearbyJobCard + + ) +} + +export default NearbyJobCard \ No newline at end of file diff --git a/components/common/cards/nearby/nearbyjobcard.style.js b/components/common/cards/nearby/nearbyjobcard.style.js new file mode 100644 index 0000000..8d579df --- /dev/null +++ b/components/common/cards/nearby/nearbyjobcard.style.js @@ -0,0 +1,47 @@ +import { StyleSheet } from "react-native"; + +import { COLORS, SHADOWS, SIZES } from "../../../../constants"; + +const styles = StyleSheet.create({ + container: { + flex: 1, + justifyContent: "space-between", + alignItems: "center", + flexDirection: "row", + padding: SIZES.medium, + borderRadius: SIZES.small, + backgroundColor: "#FFF", + ...SHADOWS.medium, + shadowColor: COLORS.white, + }, + logoContainer: { + width: 50, + height: 50, + backgroundColor: COLORS.white, + borderRadius: SIZES.medium, + justifyContent: "center", + alignItems: "center", + }, + logImage: { + width: "70%", + height: "70%", + }, + textContainer: { + flex: 1, + marginHorizontal: SIZES.medium, + }, + jobName: { + fontSize: SIZES.medium, + fontFamily: "DMBold", + color: COLORS.primary, + }, + jobType: { + fontSize: SIZES.small + 2, + fontFamily: "DMRegular", + color: COLORS.gray, + marginTop: 3, + textTransform: "capitalize", + }, +}); + +export default styles; diff --git a/components/common/cards/popular/PopularJobCard.jsx b/components/common/cards/popular/PopularJobCard.jsx new file mode 100644 index 0000000..b23a754 --- /dev/null +++ b/components/common/cards/popular/PopularJobCard.jsx @@ -0,0 +1,14 @@ +import React from 'react' +import { View, Text } from 'react-native' + +import styles from './popularjobcard.style' + +const PopularJobCard = () => { + return ( + + PopularJobCard + + ) +} + +export default PopularJobCard \ No newline at end of file diff --git a/components/common/cards/popular/popularjobcard.style.js b/components/common/cards/popular/popularjobcard.style.js new file mode 100644 index 0000000..94e6e1b --- /dev/null +++ b/components/common/cards/popular/popularjobcard.style.js @@ -0,0 +1,59 @@ +import { StyleSheet } from "react-native"; + +import { COLORS, FONT, SHADOWS, SIZES } from "../../../../constants"; + +const styles = StyleSheet.create({ + container: (selectedJob, item) => ({ + width: 250, + padding: SIZES.xLarge, + backgroundColor: selectedJob === item.job_id ? COLORS.primary : "#FFF", + borderRadius: SIZES.medium, + justifyContent: "space-between", + ...SHADOWS.medium, + shadowColor: COLORS.white, + }), + logoContainer: (selectedJob, item) => ({ + width: 50, + height: 50, + backgroundColor: selectedJob === item.job_id ? "#FFF" : COLORS.white, + borderRadius: SIZES.medium, + justifyContent: "center", + alignItems: "center", + }), + logoImage: { + width: "70%", + height: "70%", + }, + companyName: { + fontSize: SIZES.medium, + fontFamily: FONT.regular, + color: "#B3AEC6", + marginTop: SIZES.small / 1.5, + }, + infoContainer: { + marginTop: SIZES.large, + }, + jobName: (selectedJob, item) => ({ + fontSize: SIZES.large, + fontFamily: FONT.medium, + color: selectedJob === item.job_id ? COLORS.white : COLORS.primary, + }), + infoWrapper: { + flexDirection: "row", + marginTop: 5, + justifyContent: "flex-start", + alignItems: "center", + }, + publisher: (selectedJob) => ({ + fontSize: SIZES.medium - 2, + fontFamily: FONT.bold, + color: selectedJob === item.job_id ? COLORS.white : COLORS.primary, + }), + location: { + fontSize: SIZES.medium - 2, + fontFamily: FONT.regular, + color: "#B3AEC6", + }, +}); + +export default styles; diff --git a/components/common/header/ScreenHeaderBtn.jsx b/components/common/header/ScreenHeaderBtn.jsx new file mode 100644 index 0000000..55ba168 --- /dev/null +++ b/components/common/header/ScreenHeaderBtn.jsx @@ -0,0 +1,18 @@ +import React from "react"; +import { TouchableOpacity, Image } from "react-native"; + +import styles from "./screenheader.style"; + +const ScreenHeaderBtn = ({ iconUrl, handlePress, dimension }) => { + return ( + + + + ); +}; + +export default ScreenHeaderBtn; diff --git a/components/common/header/screenheader.style.js b/components/common/header/screenheader.style.js new file mode 100644 index 0000000..a623a03 --- /dev/null +++ b/components/common/header/screenheader.style.js @@ -0,0 +1,21 @@ +import { StyleSheet } from "react-native"; + +import { COLORS, SIZES } from "../../../constants"; + +const styles = StyleSheet.create({ + btnContainer: { + width: 40, + height: 40, + backgroundColor: COLORS.white, + borderRadius: SIZES.small / 1.25, + justifyContent: "center", + alignItems: "center", + }, + btnImg: (dimension) => ({ + width: dimension, + height: dimension, + borderRadius: SIZES.small / 1.25, + }), +}); + +export default styles; diff --git a/components/home/nearby/Nearbyjobs.jsx b/components/home/nearby/Nearbyjobs.jsx new file mode 100644 index 0000000..5dda963 --- /dev/null +++ b/components/home/nearby/Nearbyjobs.jsx @@ -0,0 +1,14 @@ +import React from 'react' +import { View, Text } from 'react-native' + +import styles from './nearbyjobs.style' + +const Nearbyjobs = () => { + return ( + + Nearbyjobs + + ) +} + +export default Nearbyjobs \ No newline at end of file diff --git a/components/home/nearby/nearbyjobs.style.js b/components/home/nearby/nearbyjobs.style.js new file mode 100644 index 0000000..6495d51 --- /dev/null +++ b/components/home/nearby/nearbyjobs.style.js @@ -0,0 +1,31 @@ +import { StyleSheet } from "react-native"; + +import { COLORS, FONT, SIZES } from "../../../constants"; + +const styles = StyleSheet.create({ + container: { + marginTop: SIZES.xLarge, + }, + header: { + flexDirection: "row", + justifyContent: "space-between", + alignItems: "center", + marginTop: SIZES.small, + }, + headerTitle: { + fontSize: SIZES.large, + fontFamily: FONT.medium, + color: COLORS.primary, + }, + headerBtn: { + fontSize: SIZES.medium, + fontFamily: FONT.medium, + color: COLORS.gray, + }, + cardsContainer: { + marginTop: SIZES.medium, + gap: SIZES.small, + }, +}); + +export default styles; diff --git a/components/home/popular/Popularjobs.jsx b/components/home/popular/Popularjobs.jsx new file mode 100644 index 0000000..3b42d2d --- /dev/null +++ b/components/home/popular/Popularjobs.jsx @@ -0,0 +1,14 @@ +import React from "react"; +import { View, Text } from "react-native"; + +import styles from "./popularjobs.style"; + +const Popularjobs = () => { + return ( + + + + ); +}; + +export default Popularjobs; diff --git a/components/home/popular/popularjobs.style.js b/components/home/popular/popularjobs.style.js new file mode 100644 index 0000000..29628fc --- /dev/null +++ b/components/home/popular/popularjobs.style.js @@ -0,0 +1,29 @@ +import { StyleSheet } from "react-native"; + +import { FONT, SIZES, COLORS } from "../../../constants"; + +const styles = StyleSheet.create({ + container: { + marginTop: SIZES.xLarge, + }, + header: { + flexDirection: "row", + justifyContent: "space-between", + alignItems: "center", + }, + headerTitle: { + fontSize: SIZES.large, + fontFamily: FONT.medium, + color: COLORS.primary, + }, + headerBtn: { + fontSize: SIZES.medium, + fontFamily: FONT.medium, + color: COLORS.gray, + }, + cardsContainer: { + marginTop: SIZES.medium, + }, +}); + +export default styles; diff --git a/components/home/welcome/Welcome.jsx b/components/home/welcome/Welcome.jsx new file mode 100644 index 0000000..ec6b85c --- /dev/null +++ b/components/home/welcome/Welcome.jsx @@ -0,0 +1,68 @@ +import React, { useState } from "react"; +import { View, Text, Image } from "react-native"; + +import styles from "./welcome.style"; +import { FlatList, TextInput } from "react-native-gesture-handler"; +import { TouchableOpacity } from "react-native-web"; +import { SIZES, icons } from "../../../constants"; +import { useRouter } from "expo-router"; + +const jobTypes = ["Full-time", "Part-Time", "Contractor"]; + +const Welcome = () => { + const [inputValue, setInputValue] = useState("Full-time"); + + const [activeJobType, setActiveJobType] = useState(null); + + const router = useRouter(); + return ( + + + Welcome Aladdin + Find your dream job + + + + + { + setInputValue(value.value); + }} + placeholder="what are you looking for?" + /> + + + + + + + + ( + { + setActiveJobType(item); + router.push(`/search/${item}`); + }} + > + {item} + + )} + keyExtractor={(item) => item} + contentContainerStyle={{ columnGap: SIZES.small }} + horizontal + /> + + + ); +}; + +export default Welcome; diff --git a/components/home/welcome/welcome.style.js b/components/home/welcome/welcome.style.js new file mode 100644 index 0000000..a2fb83e --- /dev/null +++ b/components/home/welcome/welcome.style.js @@ -0,0 +1,72 @@ +import { StyleSheet } from "react-native"; + +import { COLORS, FONT, SIZES } from "../../../constants"; + +const styles = StyleSheet.create({ + container: { + width: "100%", + }, + userName: { + fontFamily: FONT.regular, + fontSize: SIZES.large, + color: COLORS.secondary, + }, + welcomeMessage: { + fontFamily: FONT.bold, + fontSize: SIZES.xLarge, + color: COLORS.primary, + marginTop: 2, + }, + searchContainer: { + justifyContent: "center", + alignItems: "center", + flexDirection: "row", + marginTop: SIZES.large, + height: 50, + }, + searchWrapper: { + flex: 1, + backgroundColor: COLORS.white, + marginRight: SIZES.small, + justifyContent: "center", + alignItems: "center", + borderRadius: SIZES.medium, + height: "100%", + }, + searchInput: { + fontFamily: FONT.regular, + width: "100%", + height: "100%", + paddingHorizontal: SIZES.medium, + }, + searchBtn: { + width: 50, + height: "100%", + backgroundColor: COLORS.tertiary, + borderRadius: SIZES.medium, + justifyContent: "center", + alignItems: "center", + }, + searchBtnImage: { + width: "50%", + height: "50%", + tintColor: COLORS.white, + }, + tabsContainer: { + width: "100%", + marginTop: SIZES.medium, + }, + tab: (activeJobType, item) => ({ + paddingVertical: SIZES.small / 2, + paddingHorizontal: SIZES.small, + borderRadius: SIZES.medium, + borderWidth: 1, + borderColor: activeJobType === item ? COLORS.secondary : COLORS.gray2, + }), + tabText: (activeJobType, item) => ({ + fontFamily: FONT.medium, + color: activeJobType === item ? COLORS.secondary : COLORS.gray2, + }), +}); + +export default styles; diff --git a/components/index.js b/components/index.js new file mode 100644 index 0000000..146835d --- /dev/null +++ b/components/index.js @@ -0,0 +1,29 @@ +import ScreenHeaderBtn from "./common/header/ScreenHeaderBtn"; + +// home screen +import Welcome from "./home/welcome/Welcome"; +import Nearbyjobs from "./home/nearby/Nearbyjobs"; +import Popularjobs from "./home/popular/Popularjobs"; + +// job details screen +import Company from "./jobdetails/company/Company"; +import { default as JobTabs } from "./jobdetails/tabs/Tabs"; +import { default as JobAbout } from "./jobdetails/about/About"; +import { default as JobFooter } from "./jobdetails/footer/Footer"; +import Specifics from "./jobdetails/specifics/Specifics"; + +// common +import NearbyJobCard from "./common/cards/nearby/NearbyJobCard"; + +export { + ScreenHeaderBtn, + Welcome, + Nearbyjobs, + Popularjobs, + Company, + JobTabs, + JobAbout, + JobFooter, + Specifics, + NearbyJobCard +}; diff --git a/components/jobdetails/about/About.jsx b/components/jobdetails/about/About.jsx new file mode 100644 index 0000000..c473673 --- /dev/null +++ b/components/jobdetails/about/About.jsx @@ -0,0 +1,14 @@ +import React from 'react' +import { View, Text } from 'react-native' + +import styles from './about.style' + +const About = () => { + return ( + + About + + ) +} + +export default About \ No newline at end of file diff --git a/components/jobdetails/about/about.style.js b/components/jobdetails/about/about.style.js new file mode 100644 index 0000000..952cf57 --- /dev/null +++ b/components/jobdetails/about/about.style.js @@ -0,0 +1,28 @@ +import { StyleSheet } from "react-native"; + +import { COLORS, FONT, SIZES } from "../../../constants"; + +const styles = StyleSheet.create({ + container: { + marginTop: SIZES.large, + backgroundColor: "#FFF", + borderRadius: SIZES.medium, + padding: SIZES.medium, + }, + headText: { + fontSize: SIZES.large, + color: COLORS.primary, + fontFamily: FONT.bold, + }, + contentBox: { + marginVertical: SIZES.small, + }, + contextText: { + fontSize: SIZES.medium - 2, + color: COLORS.gray, + fontFamily: FONT.regular, + marginVertical: SIZES.small / 1.25, + }, +}); + +export default styles; diff --git a/components/jobdetails/company/Company.jsx b/components/jobdetails/company/Company.jsx new file mode 100644 index 0000000..dd40a2a --- /dev/null +++ b/components/jobdetails/company/Company.jsx @@ -0,0 +1,14 @@ +import React from 'react' +import { View, Text } from 'react-native' + +import styles from './company.style' + +const Company = () => { + return ( + + Company + + ) +} + +export default Company \ No newline at end of file diff --git a/components/jobdetails/company/company.style.js b/components/jobdetails/company/company.style.js new file mode 100644 index 0000000..356b98a --- /dev/null +++ b/components/jobdetails/company/company.style.js @@ -0,0 +1,61 @@ +import { StyleSheet } from "react-native"; + +import { COLORS, FONT, SIZES } from "../../../constants"; + +const styles = StyleSheet.create({ + container: { + marginVertical: SIZES.medium, + justifyContent: "center", + alignItems: "center", + }, + logoBox: { + width: 80, + height: 80, + justifyContent: "center", + alignItems: "center", + backgroundColor: "#FFF", + borderRadius: SIZES.large, + }, + logoImage: { + width: "80%", + height: "80%", + }, + jobTitleBox: { + marginTop: SIZES.small, + }, + jobTitle: { + fontSize: SIZES.large, + color: COLORS.primary, + fontFamily: FONT.bold, + textAlign: "center", + }, + companyInfoBox: { + marginTop: SIZES.small / 2, + flexDirection: "row", + justifyContent: "center", + alignItems: "center", + }, + companyName: { + fontSize: SIZES.medium - 2, + color: COLORS.primary, + fontFamily: FONT.medium, + }, + locationBox: { + flexDirection: "row", + justifyContent: "center", + alignItems: "center", + }, + locationImage: { + width: 14, + height: 14, + tintColor: COLORS.gray, + }, + locationName: { + fontSize: SIZES.medium - 2, + color: COLORS.gray, + fontFamily: FONT.regular, + marginLeft: 2, + }, +}); + +export default styles; diff --git a/components/jobdetails/footer/Footer.jsx b/components/jobdetails/footer/Footer.jsx new file mode 100644 index 0000000..6e0e052 --- /dev/null +++ b/components/jobdetails/footer/Footer.jsx @@ -0,0 +1,14 @@ +import React from 'react' +import { View, Text } from 'react-native' + +import styles from './footer.style' + +const Footer = () => { + return ( + + Footer + + ) +} + +export default Footer \ No newline at end of file diff --git a/components/jobdetails/footer/footer.style.js b/components/jobdetails/footer/footer.style.js new file mode 100644 index 0000000..e02c865 --- /dev/null +++ b/components/jobdetails/footer/footer.style.js @@ -0,0 +1,47 @@ +import { StyleSheet } from "react-native"; + +import { COLORS, FONT, SIZES } from "../../../constants"; + +const styles = StyleSheet.create({ + container: { + position: "absolute", + bottom: 0, + left: 0, + right: 0, + padding: SIZES.small, + backgroundColor: "#FFF", + justifyContent: "space-between", + alignItems: "center", + flexDirection: "row", + }, + likeBtn: { + width: 55, + height: 55, + borderWidth: 1, + borderColor: "#F37453", + borderRadius: SIZES.medium, + justifyContent: "center", + alignItems: "center", + }, + likeBtnImage: { + width: "40%", + height: "40%", + tintColor: "#F37453", + }, + applyBtn: { + flex: 1, + backgroundColor: "#FE7654", + height: "100%", + justifyContent: "center", + alignItems: "center", + marginLeft: SIZES.medium, + borderRadius: SIZES.medium, + }, + applyBtnText: { + fontSize: SIZES.medium, + color: COLORS.white, + fontFamily: FONT.bold, + }, +}); + +export default styles; diff --git a/components/jobdetails/specifics/Specifics.jsx b/components/jobdetails/specifics/Specifics.jsx new file mode 100644 index 0000000..ef062c5 --- /dev/null +++ b/components/jobdetails/specifics/Specifics.jsx @@ -0,0 +1,14 @@ +import React from 'react' +import { View, Text } from 'react-native' + +import styles from './specifics.style' + +const Specifics = () => { + return ( + + Specifics + + ) +} + +export default Specifics \ No newline at end of file diff --git a/components/jobdetails/specifics/specifics.style.js b/components/jobdetails/specifics/specifics.style.js new file mode 100644 index 0000000..f6533e5 --- /dev/null +++ b/components/jobdetails/specifics/specifics.style.js @@ -0,0 +1,41 @@ +import { StyleSheet } from "react-native"; + +import { COLORS, FONT, SIZES } from "../../../constants"; + +const styles = StyleSheet.create({ + container: { + marginTop: SIZES.large, + backgroundColor: "#FFF", + borderRadius: SIZES.medium, + padding: SIZES.medium, + }, + title: { + fontSize: SIZES.large, + color: COLORS.primary, + fontFamily: FONT.bold, + }, + pointsContainer: { + marginVertical: SIZES.small, + }, + pointWrapper: { + flexDirection: "row", + justifyContent: "flex-start", + alignItems: "flex-start", + marginVertical: SIZES.small / 1.25, + }, + pointDot: { + width: 6, + height: 6, + borderRadius: 6, + backgroundColor: COLORS.gray2, + marginTop: 6, + }, + pointText: { + fontSize: SIZES.medium - 2, + color: COLORS.gray, + fontFamily: FONT.regular, + marginLeft: SIZES.small, + }, +}); + +export default styles; diff --git a/components/jobdetails/tabs/Tabs.jsx b/components/jobdetails/tabs/Tabs.jsx new file mode 100644 index 0000000..51f3a78 --- /dev/null +++ b/components/jobdetails/tabs/Tabs.jsx @@ -0,0 +1,14 @@ +import React from 'react' +import { View, Text } from 'react-native' + +import styles from './tabs.style' + +const Tabs = () => { + return ( + + Tabs + + ) +} + +export default Tabs \ No newline at end of file diff --git a/components/jobdetails/tabs/tabs.style.js b/components/jobdetails/tabs/tabs.style.js new file mode 100644 index 0000000..e4f9235 --- /dev/null +++ b/components/jobdetails/tabs/tabs.style.js @@ -0,0 +1,26 @@ +import { StyleSheet } from "react-native"; + +import { COLORS, SHADOWS, SIZES } from "../../../constants"; + +const styles = StyleSheet.create({ + container: { + marginTop: SIZES.small, + marginBottom: SIZES.small / 2, + }, + btn: (name, activeTab) => ({ + paddingVertical: SIZES.medium, + paddingHorizontal: SIZES.xLarge, + backgroundColor: name === activeTab ? COLORS.primary : "#F3F4F8", + borderRadius: SIZES.medium, + marginLeft: 2, + ...SHADOWS.medium, + shadowColor: COLORS.white, + }), + btnText: (name, activeTab) => ({ + fontFamily: "DMMedium", + fontSize: SIZES.small, + color: name === activeTab ? "#C3BFCC" : "#AAA9B8", + }), +}); + +export default styles; diff --git a/constants/icons.js b/constants/icons.js new file mode 100644 index 0000000..508fb66 --- /dev/null +++ b/constants/icons.js @@ -0,0 +1,23 @@ +import heart from "../assets/icons/heart.png"; +import menu from "../assets/icons/menu.png"; +import search from "../assets/icons/search.png"; +import filter from "../assets/icons/filter.png"; +import left from "../assets/icons/left.png"; +import heartOutline from "../assets/icons/heart-ol.png"; +import share from "../assets/icons/share.png"; +import location from "../assets/icons/location.png"; +import chevronLeft from '../assets/icons/chevron-left.png' +import chevronRight from '../assets/icons/chevron-right.png' + +export default { + heart, + menu, + search, + filter, + left, + heartOutline, + share, + location, + chevronLeft, + chevronRight +}; diff --git a/constants/images.js b/constants/images.js new file mode 100644 index 0000000..5cf3c34 --- /dev/null +++ b/constants/images.js @@ -0,0 +1,5 @@ +import profile from "../assets/images/kemal.jpg"; + +export default { + profile, +}; diff --git a/constants/index.js b/constants/index.js new file mode 100644 index 0000000..6fbf2c1 --- /dev/null +++ b/constants/index.js @@ -0,0 +1,5 @@ +import images from "./images"; +import icons from "./icons"; +import { COLORS, FONT, SIZES, SHADOWS } from "./theme"; + +export { images, icons, COLORS, FONT, SIZES, SHADOWS }; diff --git a/constants/theme.js b/constants/theme.js new file mode 100644 index 0000000..efa9f4d --- /dev/null +++ b/constants/theme.js @@ -0,0 +1,51 @@ +const COLORS = { + primary: "#312651", + secondary: "#444262", + tertiary: "#FF7754", + + gray: "#83829A", + gray2: "#C1C0C8", + + white: "#F3F4F8", + lightWhite: "#FAFAFC", +}; + +const FONT = { + regular: "DMRegular", + medium: "DMMedium", + bold: "DMBold", +}; + +const SIZES = { + xSmall: 10, + small: 12, + medium: 16, + large: 20, + xLarge: 24, + xxLarge: 32, +}; + +const SHADOWS = { + small: { + shadowColor: "#000", + shadowOffset: { + width: 0, + height: 2, + }, + shadowOpacity: 0.25, + shadowRadius: 3.84, + elevation: 2, + }, + medium: { + shadowColor: "#000", + shadowOffset: { + width: 0, + height: 2, + }, + shadowOpacity: 0.25, + shadowRadius: 5.84, + elevation: 5, + }, +}; + +export { COLORS, FONT, SIZES, SHADOWS }; diff --git a/package-lock.json b/package-lock.json index 3abfc5c..0b32f56 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,8 +8,10 @@ "name": "react_native_course", "version": "1.0.0", "dependencies": { + "axios": "^1.6.8", "expo": "^50.0.1", "expo-constants": "~15.4.5", + "expo-font": "^11.10.3", "expo-linking": "~6.2.2", "expo-router": "~3.4.3", "expo-splash-screen": "~0.26.3", @@ -17,6 +19,7 @@ "react": "18.2.0", "react-dom": "18.2.0", "react-native": "0.73.2", + "react-native-dotenv": "^3.4.11", "react-native-gesture-handler": "~2.14.0", "react-native-safe-area-context": "4.8.2", "react-native-screens": "~3.29.0", @@ -6710,6 +6713,29 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/axios": { + "version": "1.6.8", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.8.tgz", + "integrity": "sha512-v/ZHtJDU39mDpyBoFVkETcd/uNdxrWRrg3bKpOKzXFA6Bvqopts6ALSMU3y6ijYxbw2B+wPrIv46egTzJXCLGQ==", + "dependencies": { + "follow-redirects": "^1.15.6", + "form-data": "^4.0.0", + "proxy-from-env": "^1.1.0" + } + }, + "node_modules/axios/node_modules/form-data": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.0.tgz", + "integrity": "sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==", + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.8", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 6" + } + }, "node_modules/babel-core": { "version": "7.0.0-bridge.0", "resolved": "https://registry.npmjs.org/babel-core/-/babel-core-7.0.0-bridge.0.tgz", @@ -8611,6 +8637,25 @@ "node": ">=0.4.0" } }, + "node_modules/follow-redirects": { + "version": "1.15.6", + "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.6.tgz", + "integrity": "sha512-wWN62YITEaOpSK584EZXJafH1AGpO8RVgElfkuXbTOrPX4fIfOyEpW/CsiNd8JdYrAoOvafRTOEnvsO++qCqFA==", + "funding": [ + { + "type": "individual", + "url": "https://github.com/sponsors/RubenVerborgh" + } + ], + "engines": { + "node": ">=4.0" + }, + "peerDependenciesMeta": { + "debug": { + "optional": true + } + } + }, "node_modules/fontfaceobserver": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/fontfaceobserver/-/fontfaceobserver-2.3.0.tgz", @@ -12031,6 +12076,11 @@ "react-is": "^16.13.1" } }, + "node_modules/proxy-from-env": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", + "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==" + }, "node_modules/pump": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/pump/-/pump-3.0.0.tgz", @@ -12264,6 +12314,28 @@ "react": "18.2.0" } }, + "node_modules/react-native-dotenv": { + "version": "3.4.11", + "resolved": "https://registry.npmjs.org/react-native-dotenv/-/react-native-dotenv-3.4.11.tgz", + "integrity": "sha512-6vnIE+WHABSeHCaYP6l3O1BOEhWxKH6nHAdV7n/wKn/sciZ64zPPp2NUdEUf1m7g4uuzlLbjgr+6uDt89q2DOg==", + "dependencies": { + "dotenv": "^16.4.5" + }, + "peerDependencies": { + "@babel/runtime": "^7.20.6" + } + }, + "node_modules/react-native-dotenv/node_modules/dotenv": { + "version": "16.4.5", + "resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.4.5.tgz", + "integrity": "sha512-ZmdL2rui+eB2YwhsWzjInR8LldtZHGDoQ1ugH85ppHKwpUHL7j7rN0Ti9NCnGiQbhaZ11FpR+7ao1dNsmduNUg==", + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://dotenvx.com" + } + }, "node_modules/react-native-gesture-handler": { "version": "2.14.1", "resolved": "https://registry.npmjs.org/react-native-gesture-handler/-/react-native-gesture-handler-2.14.1.tgz", diff --git a/package.json b/package.json index 9f0c4f2..ec2babd 100644 --- a/package.json +++ b/package.json @@ -9,8 +9,10 @@ "web": "expo start --web" }, "dependencies": { + "axios": "^1.6.8", "expo": "^50.0.1", "expo-constants": "~15.4.5", + "expo-font": "^11.10.3", "expo-linking": "~6.2.2", "expo-router": "~3.4.3", "expo-splash-screen": "~0.26.3", @@ -18,6 +20,7 @@ "react": "18.2.0", "react-dom": "18.2.0", "react-native": "0.73.2", + "react-native-dotenv": "^3.4.11", "react-native-gesture-handler": "~2.14.0", "react-native-safe-area-context": "4.8.2", "react-native-screens": "~3.29.0", diff --git a/styles/search.js b/styles/search.js new file mode 100644 index 0000000..3a4db47 --- /dev/null +++ b/styles/search.js @@ -0,0 +1,58 @@ +import { StyleSheet } from "react-native"; + +import { COLORS, FONT, SIZES } from "../constants"; + +const styles = StyleSheet.create({ + container: { + width: "100%", + }, + searchTitle: { + fontFamily: FONT.bold, + fontSize: SIZES.xLarge, + color: COLORS.primary, + }, + noOfSearchedJobs: { + marginTop: 2, + fontFamily: FONT.medium, + fontSize: SIZES.small, + color: COLORS.primary, + }, + loaderContainer: { + marginTop: SIZES.medium + }, + footerContainer: { + marginTop: SIZES.small, + justifyContent: 'center', + alignItems: 'center', + flexDirection: 'row', + gap: 10 + }, + paginationButton: { + width: 30, + height: 30, + borderRadius: 5, + justifyContent: 'center', + alignItems: 'center', + backgroundColor: COLORS.tertiary + }, + paginationImage: { + width: '60%', + height: '60%', + tintColor: COLORS.white + }, + paginationTextBox: { + width: 30, + height: 30, + borderRadius: 2, + justifyContent: 'center', + alignItems: 'center', + backgroundColor: COLORS.white + }, + paginationText: { + fontFamily: FONT.bold, + fontSize: SIZES.medium, + color: COLORS.primary + } +}); + +export default styles;