basic layout created and welcome onboarding screen implemented
This commit is contained in:
committed by
GitHub
parent
a72a83ebe3
commit
77030fd4c2
@@ -0,0 +1,13 @@
|
||||
import { Stack } from "expo-router";
|
||||
|
||||
const AuthLayout = () => {
|
||||
return (
|
||||
<Stack>
|
||||
<Stack.Screen name="welcome" options={{ headerShown: false }} />
|
||||
<Stack.Screen name="sign-up" options={{ headerShown: false }} />
|
||||
<Stack.Screen name="sign-in" options={{ headerShown: false }} />
|
||||
</Stack>
|
||||
);
|
||||
};
|
||||
|
||||
export default AuthLayout;
|
||||
@@ -0,0 +1,12 @@
|
||||
import { Text } from "react-native";
|
||||
import { SafeAreaView } from "react-native-safe-area-context";
|
||||
|
||||
const SignIn = () => {
|
||||
return (
|
||||
<SafeAreaView>
|
||||
<Text>SignIn</Text>
|
||||
</SafeAreaView>
|
||||
);
|
||||
};
|
||||
|
||||
export default SignIn;
|
||||
@@ -0,0 +1,12 @@
|
||||
import { Text } from "react-native";
|
||||
import { SafeAreaView } from "react-native-safe-area-context";
|
||||
|
||||
const SignUp = () => {
|
||||
return (
|
||||
<SafeAreaView>
|
||||
<Text>SignUp</Text>
|
||||
</SafeAreaView>
|
||||
);
|
||||
};
|
||||
|
||||
export default SignUp;
|
||||
@@ -0,0 +1,65 @@
|
||||
import { CustomButton } from "@/components/custom-button";
|
||||
import { onboarding } from "@/constants";
|
||||
import { router } from "expo-router";
|
||||
import { useRef, useState } from "react";
|
||||
import { Image, Text, TouchableOpacity, View } from "react-native";
|
||||
import { SafeAreaView } from "react-native-safe-area-context";
|
||||
import Swiper from "react-native-swiper";
|
||||
|
||||
const Welcome = () => {
|
||||
const swiperRef = useRef<Swiper>(null);
|
||||
const [activeIndex, setActiveIndex] = useState(0);
|
||||
const isLastSlide = activeIndex === onboarding.length - 1;
|
||||
|
||||
return (
|
||||
<SafeAreaView className="flex h-full items-center justify-between bg-white">
|
||||
<TouchableOpacity
|
||||
onPress={() => router.replace("/(auth)/sign-up")}
|
||||
className="w-full flex justify-end items-end p-5"
|
||||
>
|
||||
<Text className="text-black text-base font-JakartaBold">Skip</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
<Swiper
|
||||
ref={swiperRef}
|
||||
loop={false}
|
||||
dot={<View className="w-8 h-1 mx-1 bg-[#E2E8F0] rounded-full" />}
|
||||
activeDot={<View className="w-8 h-1 mx-1 bg-[#0286FF] rounded-full" />}
|
||||
index={activeIndex}
|
||||
onIndexChanged={setActiveIndex}
|
||||
>
|
||||
{onboarding.map((item) => (
|
||||
<View key={item.id} className="flex items-center justify-center p-5">
|
||||
<Image
|
||||
source={item.image}
|
||||
className="w-full h-[300px]"
|
||||
resizeMode="contain"
|
||||
/>
|
||||
|
||||
<View className="flex flex-row items-center justify-center w-full mt-10">
|
||||
<Text className="text-black text-3xl font-bold mx-10 text-center">
|
||||
{item.title}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
<Text className="text-base font-JakartaSemiBold text-center text-[#858585] mx-10 mt-3">
|
||||
{item.description}
|
||||
</Text>
|
||||
</View>
|
||||
))}
|
||||
</Swiper>
|
||||
|
||||
<CustomButton
|
||||
onPress={() =>
|
||||
isLastSlide
|
||||
? router.replace("/(auth)/sign-up")
|
||||
: swiperRef.current?.scrollBy(1)
|
||||
}
|
||||
title={isLastSlide ? "Get Started" : "Next"}
|
||||
className="w-11/12 mt-10"
|
||||
/>
|
||||
</SafeAreaView>
|
||||
);
|
||||
};
|
||||
|
||||
export default Welcome;
|
||||
@@ -0,0 +1,12 @@
|
||||
import { Text } from "react-native";
|
||||
import { SafeAreaView } from "react-native-safe-area-context";
|
||||
|
||||
const Chat = () => {
|
||||
return (
|
||||
<SafeAreaView>
|
||||
<Text>Chat</Text>
|
||||
</SafeAreaView>
|
||||
);
|
||||
};
|
||||
|
||||
export default Chat;
|
||||
@@ -0,0 +1,12 @@
|
||||
import { Text } from "react-native";
|
||||
import { SafeAreaView } from "react-native-safe-area-context";
|
||||
|
||||
const Home = () => {
|
||||
return (
|
||||
<SafeAreaView>
|
||||
<Text>Home</Text>
|
||||
</SafeAreaView>
|
||||
);
|
||||
};
|
||||
|
||||
export default Home;
|
||||
@@ -0,0 +1,12 @@
|
||||
import { Text } from "react-native";
|
||||
import { SafeAreaView } from "react-native-safe-area-context";
|
||||
|
||||
const Profile = () => {
|
||||
return (
|
||||
<SafeAreaView>
|
||||
<Text>Profile</Text>
|
||||
</SafeAreaView>
|
||||
);
|
||||
};
|
||||
|
||||
export default Profile;
|
||||
@@ -0,0 +1,12 @@
|
||||
import { Text } from "react-native";
|
||||
import { SafeAreaView } from "react-native-safe-area-context";
|
||||
|
||||
const Rides = () => {
|
||||
return (
|
||||
<SafeAreaView>
|
||||
<Text>Rides</Text>
|
||||
</SafeAreaView>
|
||||
);
|
||||
};
|
||||
|
||||
export default Rides;
|
||||
+6
-3
@@ -7,7 +7,7 @@ import "react-native-reanimated";
|
||||
// Prevent the splash screen from auto-hiding before asset loading is complete.
|
||||
SplashScreen.preventAutoHideAsync();
|
||||
|
||||
export default function RootLayout() {
|
||||
const RootLayout = () => {
|
||||
const [loaded] = useFonts({
|
||||
"Jakarta-Bold": require("../assets/fonts/PlusJakartaSans-Bold.ttf"),
|
||||
"Jakarta-ExtraBold": require("../assets/fonts/PlusJakartaSans-ExtraBold.ttf"),
|
||||
@@ -31,7 +31,10 @@ export default function RootLayout() {
|
||||
return (
|
||||
<Stack>
|
||||
<Stack.Screen name="index" options={{ headerShown: false }} />
|
||||
<Stack.Screen name="+not-found" />
|
||||
<Stack.Screen name="(root)" options={{ headerShown: false }} />
|
||||
<Stack.Screen name="(auth)" options={{ headerShown: false }} />
|
||||
</Stack>
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
export default RootLayout;
|
||||
|
||||
+4
-9
@@ -1,12 +1,7 @@
|
||||
import { Text } from "react-native";
|
||||
import { SafeAreaView } from "react-native-safe-area-context";
|
||||
import { Redirect } from "expo-router";
|
||||
|
||||
const Home = () => {
|
||||
return (
|
||||
<SafeAreaView>
|
||||
<Text>Home</Text>
|
||||
</SafeAreaView>
|
||||
);
|
||||
const App = () => {
|
||||
return <Redirect href="/(auth)/welcome" />;
|
||||
};
|
||||
|
||||
export default Home;
|
||||
export default App;
|
||||
|
||||
@@ -0,0 +1,58 @@
|
||||
import { ButtonProps } from "@/types/type";
|
||||
import React from "react";
|
||||
import { Text, TouchableOpacity } from "react-native";
|
||||
|
||||
const getBgVariantStyle = (variant: ButtonProps["bgVariant"]) => {
|
||||
switch (variant) {
|
||||
case "secondary":
|
||||
return "bg-gray-500";
|
||||
case "danger":
|
||||
return "bg-rose-500";
|
||||
case "success":
|
||||
return "bg-emerald-500";
|
||||
case "outline":
|
||||
return "bg-transparent-500 border-neutral-300 border-[0.5px]";
|
||||
default:
|
||||
return "bg-[#0286ff]";
|
||||
}
|
||||
};
|
||||
|
||||
const getTextVariantStyle = (variant: ButtonProps["textVariant"]) => {
|
||||
switch (variant) {
|
||||
case "primary":
|
||||
return "text-black";
|
||||
case "secondary":
|
||||
return "text-gray-100";
|
||||
case "danger":
|
||||
return "text-rose-100";
|
||||
case "success":
|
||||
return "text-emerald-100";
|
||||
default:
|
||||
return "text-white";
|
||||
}
|
||||
};
|
||||
|
||||
export const CustomButton = ({
|
||||
onPress,
|
||||
title,
|
||||
bgVariant = "primary",
|
||||
textVariant = "default",
|
||||
iconLeft: IconLeft,
|
||||
iconRight: IconRight,
|
||||
className,
|
||||
...props
|
||||
}: ButtonProps) => (
|
||||
<TouchableOpacity
|
||||
onPress={onPress}
|
||||
className={`w-full rounded-full p-3 flex flex-row justify-center items-center shadow-md shadow-neutral-400/70 ${getBgVariantStyle(bgVariant)} ${className}`}
|
||||
{...props}
|
||||
>
|
||||
{IconLeft && <IconLeft />}
|
||||
|
||||
<Text className={`text-lg font-bold ${getTextVariantStyle(textVariant)}`}>
|
||||
{title}
|
||||
</Text>
|
||||
|
||||
{IconRight && <IconRight />}
|
||||
</TouchableOpacity>
|
||||
);
|
||||
@@ -0,0 +1,100 @@
|
||||
import arrowDown from "@/assets/icons/arrow-down.png";
|
||||
import arrowUp from "@/assets/icons/arrow-up.png";
|
||||
import backArrow from "@/assets/icons/back-arrow.png";
|
||||
import chat from "@/assets/icons/chat.png";
|
||||
import checkmark from "@/assets/icons/check.png";
|
||||
import close from "@/assets/icons/close.png";
|
||||
import dollar from "@/assets/icons/dollar.png";
|
||||
import email from "@/assets/icons/email.png";
|
||||
import eyecross from "@/assets/icons/eyecross.png";
|
||||
import google from "@/assets/icons/google.png";
|
||||
import home from "@/assets/icons/home.png";
|
||||
import list from "@/assets/icons/list.png";
|
||||
import lock from "@/assets/icons/lock.png";
|
||||
import map from "@/assets/icons/map.png";
|
||||
import marker from "@/assets/icons/marker.png";
|
||||
import out from "@/assets/icons/out.png";
|
||||
import person from "@/assets/icons/person.png";
|
||||
import pin from "@/assets/icons/pin.png";
|
||||
import point from "@/assets/icons/point.png";
|
||||
import profile from "@/assets/icons/profile.png";
|
||||
import search from "@/assets/icons/search.png";
|
||||
import selectedMarker from "@/assets/icons/selected-marker.png";
|
||||
import star from "@/assets/icons/star.png";
|
||||
import target from "@/assets/icons/target.png";
|
||||
import to from "@/assets/icons/to.png";
|
||||
import check from "@/assets/images/check.png";
|
||||
import getStarted from "@/assets/images/get-started.png";
|
||||
import message from "@/assets/images/message.png";
|
||||
import noResult from "@/assets/images/no-result.png";
|
||||
import onboarding1 from "@/assets/images/onboarding1.png";
|
||||
import onboarding2 from "@/assets/images/onboarding2.png";
|
||||
import onboarding3 from "@/assets/images/onboarding3.png";
|
||||
import signUpCar from "@/assets/images/signup-car.png";
|
||||
|
||||
export const images = {
|
||||
onboarding1,
|
||||
onboarding2,
|
||||
onboarding3,
|
||||
getStarted,
|
||||
signUpCar,
|
||||
check,
|
||||
noResult,
|
||||
message,
|
||||
};
|
||||
|
||||
export const icons = {
|
||||
arrowDown,
|
||||
arrowUp,
|
||||
backArrow,
|
||||
chat,
|
||||
checkmark,
|
||||
close,
|
||||
dollar,
|
||||
email,
|
||||
eyecross,
|
||||
google,
|
||||
home,
|
||||
list,
|
||||
lock,
|
||||
map,
|
||||
marker,
|
||||
out,
|
||||
person,
|
||||
pin,
|
||||
point,
|
||||
profile,
|
||||
search,
|
||||
selectedMarker,
|
||||
star,
|
||||
target,
|
||||
to,
|
||||
};
|
||||
|
||||
export const onboarding = [
|
||||
{
|
||||
id: 1,
|
||||
title: "The perfect ride is just a tap away!",
|
||||
description:
|
||||
"Your journey begins with Ryde. Find your ideal ride effortlessly.",
|
||||
image: images.onboarding1,
|
||||
},
|
||||
{
|
||||
id: 2,
|
||||
title: "Best car in your hands with Ryde",
|
||||
description:
|
||||
"Discover the convenience of finding your perfect ride with Ryde",
|
||||
image: images.onboarding2,
|
||||
},
|
||||
{
|
||||
id: 3,
|
||||
title: "Your ride, your way. Let's go!",
|
||||
description:
|
||||
"Enter your destination, sit back, and let us take care of the rest.",
|
||||
image: images.onboarding3,
|
||||
},
|
||||
];
|
||||
|
||||
export const data = {
|
||||
onboarding,
|
||||
};
|
||||
Vendored
+24
@@ -0,0 +1,24 @@
|
||||
declare module "*.png" {
|
||||
const value: any;
|
||||
export default value;
|
||||
}
|
||||
|
||||
declare module "*.jpg" {
|
||||
const value: any;
|
||||
export default value;
|
||||
}
|
||||
|
||||
declare module "*.jpeg" {
|
||||
const value: any;
|
||||
export default value;
|
||||
}
|
||||
|
||||
declare module "*.gif" {
|
||||
const value: any;
|
||||
export default value;
|
||||
}
|
||||
|
||||
declare module "*.svg" {
|
||||
const value: any;
|
||||
export default value;
|
||||
}
|
||||
Vendored
+139
@@ -0,0 +1,139 @@
|
||||
import { TextInputProps, TouchableOpacityProps } from "react-native";
|
||||
|
||||
declare interface Driver {
|
||||
driver_id: number;
|
||||
first_name: string;
|
||||
last_name: string;
|
||||
profile_image_url: string;
|
||||
car_image_url: string;
|
||||
car_seats: number;
|
||||
rating: number;
|
||||
}
|
||||
|
||||
declare interface MarkerData {
|
||||
latitude: number;
|
||||
longitude: number;
|
||||
id: number;
|
||||
title: string;
|
||||
profile_image_url: string;
|
||||
car_image_url: string;
|
||||
car_seats: number;
|
||||
rating: number;
|
||||
first_name: string;
|
||||
last_name: string;
|
||||
time?: number;
|
||||
price?: string;
|
||||
}
|
||||
|
||||
declare interface MapProps {
|
||||
destinationLatitude?: number;
|
||||
destinationLongitude?: number;
|
||||
onDriverTimesCalculated?: (driversWithTimes: MarkerData[]) => void;
|
||||
selectedDriver?: number | null;
|
||||
onMapReady?: () => void;
|
||||
}
|
||||
|
||||
declare interface Ride {
|
||||
origin_address: string;
|
||||
destination_address: string;
|
||||
origin_latitude: number;
|
||||
origin_longitude: number;
|
||||
destination_latitude: number;
|
||||
destination_longitude: number;
|
||||
ride_time: number;
|
||||
fare_price: number;
|
||||
payment_status: string;
|
||||
driver_id: number;
|
||||
user_email: string;
|
||||
created_at: string;
|
||||
driver: {
|
||||
first_name: string;
|
||||
last_name: string;
|
||||
car_seats: number;
|
||||
};
|
||||
}
|
||||
|
||||
declare interface ButtonProps extends TouchableOpacityProps {
|
||||
title: string;
|
||||
bgVariant?: "primary" | "secondary" | "danger" | "outline" | "success";
|
||||
textVariant?: "primary" | "default" | "secondary" | "danger" | "success";
|
||||
iconLeft?: React.ComponentType<any>;
|
||||
iconRight?: React.ComponentType<any>;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
declare interface GoogleInputProps {
|
||||
icon?: string;
|
||||
initialLocation?: string;
|
||||
containerStyle?: string;
|
||||
textInputBackgroundColor?: string;
|
||||
handlePress: ({
|
||||
latitude,
|
||||
longitude,
|
||||
address,
|
||||
}: {
|
||||
latitude: number;
|
||||
longitude: number;
|
||||
address: string;
|
||||
}) => void;
|
||||
}
|
||||
|
||||
declare interface InputFieldProps extends TextInputProps {
|
||||
label: string;
|
||||
icon?: any;
|
||||
secureTextEntry?: boolean;
|
||||
labelStyle?: string;
|
||||
containerStyle?: string;
|
||||
inputStyle?: string;
|
||||
iconStyle?: string;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
declare interface PaymentProps {
|
||||
fullName: string;
|
||||
email: string;
|
||||
amount: string;
|
||||
driverId: number;
|
||||
rideTime: number;
|
||||
}
|
||||
|
||||
declare interface LocationStore {
|
||||
userLatitude: number | null;
|
||||
userLongitude: number | null;
|
||||
userAddress: string | null;
|
||||
destinationLatitude: number | null;
|
||||
destinationLongitude: number | null;
|
||||
destinationAddress: string | null;
|
||||
setUserLocation: ({
|
||||
latitude,
|
||||
longitude,
|
||||
address,
|
||||
}: {
|
||||
latitude: number;
|
||||
longitude: number;
|
||||
address: string;
|
||||
}) => void;
|
||||
setDestinationLocation: ({
|
||||
latitude,
|
||||
longitude,
|
||||
address,
|
||||
}: {
|
||||
latitude: number;
|
||||
longitude: number;
|
||||
address: string;
|
||||
}) => void;
|
||||
}
|
||||
|
||||
declare interface DriverStore {
|
||||
drivers: MarkerData[];
|
||||
selectedDriver: number | null;
|
||||
setSelectedDriver: (driverId: number) => void;
|
||||
setDrivers: (drivers: MarkerData[]) => void;
|
||||
clearSelectedDriver: () => void;
|
||||
}
|
||||
|
||||
declare interface DriverCardProps {
|
||||
item: MarkerData;
|
||||
selected: number;
|
||||
setSelected: () => void;
|
||||
}
|
||||
Reference in New Issue
Block a user