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;