From 203be0c0974374fa946332d00bbdd938a714933b Mon Sep 17 00:00:00 2001 From: Jakub Satora Date: Thu, 3 Oct 2024 18:19:18 +0200 Subject: [PATCH] driver site --- .env.local | 3 +- app/(root)/(tabs)/home.tsx | 126 ++++++++++++++++++---- components/RideCard.tsx | 80 ++++++++++++++ lib/utils.ts | 46 ++++++++ types/type.d.ts | 212 ++++++++++++++++++------------------- 5 files changed, 342 insertions(+), 125 deletions(-) create mode 100644 components/RideCard.tsx create mode 100644 lib/utils.ts diff --git a/.env.local b/.env.local index 6ee300b..378b97a 100644 --- a/.env.local +++ b/.env.local @@ -1,3 +1,4 @@ EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_cHJvbXB0LW1hZ2dvdC02MC5jbGVyay5hY2NvdW50cy5kZXYk DATABASE_URL=postgresql://ryde_owner:0OwLX1QrRPqT@ep-rapid-water-a2owt30g.eu-central-1.aws.neon.tech/ryde?sslmode=require -EXPO_PUBLIC_SERVER_URL=https://uber.dev/ \ No newline at end of file +EXPO_PUBLIC_SERVER_URL=https://uber.dev/ +EXPO_PUBLIC_GEOAPIFY_API_KEY=3cee4c13411d467c8357a8eca4aa99d7 \ No newline at end of file diff --git a/app/(root)/(tabs)/home.tsx b/app/(root)/(tabs)/home.tsx index b1d3bdc..27864a4 100644 --- a/app/(root)/(tabs)/home.tsx +++ b/app/(root)/(tabs)/home.tsx @@ -1,26 +1,116 @@ -import { SignedIn, SignedOut, useUser } from '@clerk/clerk-expo' -import { Link } from 'expo-router' -import { Text, View } from 'react-native' +import RideCard from '@/components/RideCard' +import { useUser } from '@clerk/clerk-expo' +import { FlatList } from 'react-native' import { SafeAreaView } from 'react-native-safe-area-context' - +const recentRides = [ + [ + { + "ride_id": "1", + "origin_address": "Kathmandu, Nepal", + "destination_address": "Pokhara, Nepal", + "origin_latitude": "27.717245", + "origin_longitude": "85.323961", + "destination_latitude": "28.209583", + "destination_longitude": "83.985567", + "ride_time": 391, + "fare_price": "19500.00", + "payment_status": "paid", + "driver_id": 2, + "user_id": "1", + "created_at": "2024-08-12 05:19:20.620007", + "driver": { + "driver_id": "2", + "first_name": "David", + "last_name": "Brown", + "profile_image_url": "https://ucarecdn.com/6ea6d83d-ef1a-483f-9106-837a3a5b3f67/-/preview/1000x666/", + "car_image_url": "https://ucarecdn.com/a3872f80-c094-409c-82f8-c9ff38429327/-/preview/930x932/", + "car_seats": 5, + "rating": "4.60" + } + }, + { + "ride_id": "2", + "origin_address": "Jalkot, MH", + "destination_address": "Pune, Maharashtra, India", + "origin_latitude": "18.609116", + "origin_longitude": "77.165873", + "destination_latitude": "18.520430", + "destination_longitude": "73.856744", + "ride_time": 491, + "fare_price": "24500.00", + "payment_status": "paid", + "driver_id": 1, + "user_id": "1", + "created_at": "2024-08-12 06:12:17.683046", + "driver": { + "driver_id": "1", + "first_name": "James", + "last_name": "Wilson", + "profile_image_url": "https://ucarecdn.com/dae59f69-2c1f-48c3-a883-017bcf0f9950/-/preview/1000x666/", + "car_image_url": "https://ucarecdn.com/a2dc52b2-8bf7-4e49-9a36-3ffb5229ed02/-/preview/465x466/", + "car_seats": 4, + "rating": "4.80" + } + }, + { + "ride_id": "3", + "origin_address": "Zagreb, Croatia", + "destination_address": "Rijeka, Croatia", + "origin_latitude": "45.815011", + "origin_longitude": "15.981919", + "destination_latitude": "45.327063", + "destination_longitude": "14.442176", + "ride_time": 124, + "fare_price": "6200.00", + "payment_status": "paid", + "driver_id": 1, + "user_id": "1", + "created_at": "2024-08-12 08:49:01.809053", + "driver": { + "driver_id": "1", + "first_name": "James", + "last_name": "Wilson", + "profile_image_url": "https://ucarecdn.com/dae59f69-2c1f-48c3-a883-017bcf0f9950/-/preview/1000x666/", + "car_image_url": "https://ucarecdn.com/a2dc52b2-8bf7-4e49-9a36-3ffb5229ed02/-/preview/465x466/", + "car_seats": 4, + "rating": "4.80" + } + }, + { + "ride_id": "4", + "origin_address": "Okayama, Japan", + "destination_address": "Osaka, Japan", + "origin_latitude": "34.655531", + "origin_longitude": "133.919795", + "destination_latitude": "34.693725", + "destination_longitude": "135.502254", + "ride_time": 159, + "fare_price": "7900.00", + "payment_status": "paid", + "driver_id": 3, + "user_id": "1", + "created_at": "2024-08-12 18:43:54.297838", + "driver": { + "driver_id": "3", + "first_name": "Michael", + "last_name": "Johnson", + "profile_image_url": "https://ucarecdn.com/0330d85c-232e-4c30-bd04-e5e4d0e3d688/-/preview/826x822/", + "car_image_url": "https://ucarecdn.com/289764fb-55b6-4427-b1d1-f655987b4a14/-/preview/930x932/", + "car_seats": 4, + "rating": "4.70" + } + } + ] +] export default function Page() { const { user } = useUser() return ( - - - - Hello {user?.emailAddresses[0].emailAddress} - - - - Sign In - - - Sign Up - - - + + } + /> ) } \ No newline at end of file diff --git a/components/RideCard.tsx b/components/RideCard.tsx new file mode 100644 index 0000000..b2a91b6 --- /dev/null +++ b/components/RideCard.tsx @@ -0,0 +1,80 @@ +import { Image, Text, View } from "react-native"; + +import { icons } from "@/constants"; +import { formatDate, formatTime } from "@/lib/utils"; +import { Ride } from "@/types/type"; + +const RideCard = ({ ride }: { ride: Ride }) => { + return ( + + + + + + + + + + {ride.origin_address} + + + + + + + {ride.destination_address} + + + + + + + + + Date & Time + + + {formatDate(ride.created_at)}, {formatTime(ride.ride_time)} + + + + + + Driver + + + {ride.driver.first_name} {ride.driver.last_name} + + + + + + Car Seats + + + {ride.driver.car_seats} + + + + + + Payment Status + + + {ride.payment_status} + + + + + + ); +}; + +export default RideCard; \ No newline at end of file diff --git a/lib/utils.ts b/lib/utils.ts new file mode 100644 index 0000000..72764aa --- /dev/null +++ b/lib/utils.ts @@ -0,0 +1,46 @@ +import {Ride} from "@/types/type"; + +export const sortRides = (rides: Ride[]): Ride[] => { + const result = rides.sort((a, b) => { + const dateA = new Date(`${a.created_at}T${a.ride_time}`); + const dateB = new Date(`${b.created_at}T${b.ride_time}`); + return dateB.getTime() - dateA.getTime(); + }); + + return result.reverse(); +}; + +export function formatTime(minutes: number): string { + const formattedMinutes = +minutes?.toFixed(0) || 0; + + if (formattedMinutes < 60) { + return `${minutes} min`; + } else { + const hours = Math.floor(formattedMinutes / 60); + const remainingMinutes = formattedMinutes % 60; + return `${hours}h ${remainingMinutes}m`; + } +} + +export function formatDate(dateString: string): string { + const date = new Date(dateString); + const day = date.getDate(); + const monthNames = [ + "January", + "February", + "March", + "April", + "May", + "June", + "July", + "August", + "September", + "October", + "November", + "December", + ]; + const month = monthNames[date.getMonth()]; + const year = date.getFullYear(); + + return `${day < 10 ? "0" + day : day} ${month} ${year}`; +} \ No newline at end of file diff --git a/types/type.d.ts b/types/type.d.ts index 34e2d71..a751c20 100644 --- a/types/type.d.ts +++ b/types/type.d.ts @@ -1,139 +1,139 @@ -import {TextInputProps, TouchableOpacityProps} from "react-native"; +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; + 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; + 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; + 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; - }; + 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_id: 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; - IconRight?: React.ComponentType; - className?: string; + title: string; + bgVariant?: "primary" | "secondary" | "danger" | "outline" | "success"; + textVariant?: "primary" | "default" | "secondary" | "danger" | "success"; + IconLeft?: React.ComponentType; + IconRight?: React.ComponentType; + className?: string; } declare interface GoogleInputProps { - icon?: string; - initialLocation?: string; - containerStyle?: string; - textInputBackgroundColor?: string; - handlePress: ({ - latitude, - longitude, - address, - }: { - latitude: number; - longitude: number; - address: string; - }) => void; + 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; + 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; + 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; + 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; + drivers: MarkerData[]; + selectedDriver: number | null; + setSelectedDriver: (driverId: number) => void; + setDrivers: (drivers: MarkerData[]) => void; + clearSelectedDriver: () => void; } declare interface DriverCardProps { - item: MarkerData; - selected: number; - setSelected: () => void; + item: MarkerData; + selected: number; + setSelected: () => void; } \ No newline at end of file