map path solve
parent
af0438fa91
commit
3b3b9acefa
|
@ -1,6 +1,7 @@
|
|||
import { useDriverStore, useLocationStore } from "@/store";
|
||||
import { calculateDriverTimes, calculateRegion, generateMarkersFromData } from "@/lib/map";
|
||||
import MapView, { Marker, PROVIDER_DEFAULT } from "react-native-maps";
|
||||
import MapViewDirections from "react-native-maps-directions";
|
||||
import tw from "twrnc";
|
||||
import { useEffect, useState } from "react";
|
||||
import { Driver, MarkerData } from "@/types/type";
|
||||
|
@ -9,7 +10,7 @@ import { useFetch } from "@/lib/fetch";
|
|||
import { ActivityIndicator, Text, View } from "react-native";
|
||||
|
||||
const Map = () => {
|
||||
const { data: drivers, loading, error } = useFetch<Driver[]>("/(api)/driver");
|
||||
const { data: drivers, loading, error } = useFetch<Driver[]>("/api/driver");
|
||||
const { userLongitude, userLatitude, destinationLatitude, destinationLongitude } = useLocationStore();
|
||||
const { selectedDriver, setDrivers } = useDriverStore();
|
||||
const [markers, setMarkers] = useState<MarkerData[]>([]);
|
||||
|
@ -22,7 +23,7 @@ const Map = () => {
|
|||
const newMarkers = generateMarkersFromData({ data: drivers, userLatitude, userLongitude, });
|
||||
setMarkers(newMarkers);
|
||||
}
|
||||
}, [drivers]);
|
||||
}, [drivers,userLatitude,userLongitude]);
|
||||
useEffect(() => {
|
||||
if (markers.length > 0 && destinationLatitude && destinationLongitude) {
|
||||
calculateDriverTimes({ markers, userLongitude, userLatitude, destinationLatitude, destinationLongitude }).then((drivers) => {
|
||||
|
@ -56,6 +57,12 @@ const Map = () => {
|
|||
image={selectedDriver === marker.id ? icons.selectedMarker : icons.marker}
|
||||
/>
|
||||
))}
|
||||
{destinationLatitude && destinationLongitude && (
|
||||
<>
|
||||
<Marker key="destination" coordinate={{latitude:destinationLatitude,longitude:destinationLongitude}} title="Destination" image={icons.pin} />
|
||||
<MapViewDirections origin={{latitude:userLatitude!,longitude:userLongitude!,}} destination={{latitude:destinationLatitude,longitude:destinationLongitude,}} apikey={process.env.EXPO_PUBLIC_GOOGLE_API_KEY} strokeColor="#0286ff" strokeWidth={2} />
|
||||
</>
|
||||
)}
|
||||
</MapView>
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,64 +1,88 @@
|
|||
import { Alert, Text, View } from "react-native";
|
||||
import { Alert, Image, Text, View } from "react-native";
|
||||
import CustomButton from "./CustomButton";
|
||||
import tw from "twrnc";
|
||||
import { PaymentMethod, PaymentSheetError, useStripe } from "@stripe/stripe-react-native";
|
||||
import { useState, useEffect } from "react";
|
||||
import { useStripe } from "@stripe/stripe-react-native";
|
||||
import { useState } from "react";
|
||||
import { fetchAPI } from "@/lib/fetch";
|
||||
import { PaymentProps } from "@/types/type";
|
||||
import { useLocationStore } from "@/store";
|
||||
import { useAuth } from "@clerk/clerk-expo";
|
||||
import ReactNativeModal from "react-native-modal";
|
||||
import { images } from "@/constants";
|
||||
import { router } from "expo-router";
|
||||
const Payment = ({fullName,email,amount,driverId,rideTime}:PaymentProps) => {
|
||||
const [success, setSuccess] = useState(false);
|
||||
const {userId} =useAuth();
|
||||
const {userAddress,userLatitude,userLongitude,destinationAddress,destinationLatitude,destinationLongitude} = useLocationStore();
|
||||
|
||||
const { initPaymentSheet, presentPaymentSheet } = useStripe();
|
||||
const confirmHandler = async (paymentMethod,_, intentCreationCallback) => {
|
||||
const {paymentIntent,customer} = await fetchAPI("/(api)/(stripe)/create",{
|
||||
method:"POST",
|
||||
headers:{
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body:JSON.stringify({
|
||||
name:fullName || email.split("@")[0],
|
||||
email: email,
|
||||
amount: amount,
|
||||
paymentMethodId : paymentMethod.id,
|
||||
}),
|
||||
},
|
||||
);
|
||||
if(paymentIntent.client_sercet){
|
||||
const {result} = await fetchAPI ("/(api)/(stripe)/pay",{
|
||||
method:"POST",
|
||||
headers:{
|
||||
"Content-Type":"application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
payment_method_id:paymentMethod.id,
|
||||
payment_intent_id:paymentIntent.id,
|
||||
customer_id:customer,
|
||||
}),
|
||||
});
|
||||
if (result.client_sercet) {
|
||||
//ride/create
|
||||
}
|
||||
}
|
||||
const { clientSercet, error } = await response.json();
|
||||
if(clientSercet){
|
||||
intentCreationCallback({clientSercet})
|
||||
}
|
||||
else{
|
||||
intentCreationCallback({error})
|
||||
}
|
||||
}
|
||||
|
||||
const initializePaymentSheet = async () => {
|
||||
const { error } = await initPaymentSheet({
|
||||
merchantDisplayName: "Example,Inc.",
|
||||
merchantDisplayName: "Neel,Inc.",
|
||||
intentConfiguration: {
|
||||
mode: {
|
||||
amount: 1099,
|
||||
amount: parseInt(amount)*100,
|
||||
currencyCode: "USD",
|
||||
},
|
||||
confirmHandler: confirmHandler
|
||||
}
|
||||
confirmHandler: async (paymentMethod,_, intentCreationCallback) => {
|
||||
const {paymentIntent,customer} = await fetchAPI("/api/stripe/create",{
|
||||
method:"POST",
|
||||
headers:{
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body:JSON.stringify({
|
||||
name:fullName || email.split("@")[0],
|
||||
email: email,
|
||||
amount: amount,
|
||||
paymentMethodId : paymentMethod.id,
|
||||
}),
|
||||
},
|
||||
);
|
||||
if(paymentIntent.client_sercet){
|
||||
const {result} = await fetchAPI ("/api/stripe/pay",{
|
||||
method:"POST",
|
||||
headers:{
|
||||
"Content-Type":"application/json",
|
||||
},
|
||||
body: JSON.stringify({
|
||||
payment_method_id:paymentMethod.id,
|
||||
payment_intent_id:paymentIntent.id,
|
||||
customer_id:customer,
|
||||
}),
|
||||
});
|
||||
if (result.client_sercet) {
|
||||
await fetchAPI("/api/ride/create",{
|
||||
method: "POST",
|
||||
headers:{
|
||||
"Content-Type":"application/json",
|
||||
},
|
||||
body:JSON.stringify({
|
||||
origin_address:userAddress,
|
||||
destination_address:destinationAddress,
|
||||
origin_latitude:userLatitude,
|
||||
origin_longitude:userLongitude,
|
||||
destination_latitude:destinationLatitude,
|
||||
destination_longitude:destinationLongitude,
|
||||
ride_time:rideTime.toFixed(0),
|
||||
fare_price:parseInt(amount)*100,
|
||||
payment_status:"paid",
|
||||
driver_id:driverId,
|
||||
user_id:userId,
|
||||
}),
|
||||
});
|
||||
intentCreationCallback({
|
||||
clientSercet:result.client_secert,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
},
|
||||
returnURL:'myapp"//book-ride',
|
||||
});
|
||||
if (error) {
|
||||
//handle error
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
const openPaymentSheet = async () => {
|
||||
|
@ -76,6 +100,15 @@ const Payment = ({fullName,email,amount,driverId,rideTime}:PaymentProps) => {
|
|||
return (
|
||||
<>
|
||||
<CustomButton title="Confirm Ride" style={tw`my-10`} onPress={openPaymentSheet} />
|
||||
<ReactNativeModal isVisible={success} onBackButtonPress={()=>setSuccess(false)} >
|
||||
<View style={tw`flex flex-col items-center justify-center bg-white p-7 rounded-2xl`} >
|
||||
<Image source={images.check} style={tw`w-28 h-28 mt-5`} />
|
||||
<Text style={tw`text-2xl text-center font-JakartaBold mt-5`}>Ride Booked!</Text>
|
||||
<Text style={tw`text-md text-general-200 f0nt-JakartaMedium`} >Thank you for your booking. Your reservation has been placed. Please proceed with your trip! </Text>
|
||||
<CustomButton title="Back Home" onPress={()=>{setSuccess(false)
|
||||
router.push("/(root)/(tabs)/home")}} style={tw`mt-5`} />
|
||||
</View>
|
||||
</ReactNativeModal>
|
||||
</>
|
||||
)
|
||||
};
|
||||
|
|
|
@ -2,9 +2,9 @@ import {useState, useEffect, useCallback} from "react";
|
|||
|
||||
const API_BASE_URL = "http://192.168.29.174:3000";
|
||||
|
||||
export const fetchAPI = async (endpoint: string, options?: RequestInit) => {
|
||||
export const fetchAPI = async (url: string, options?: RequestInit) => {
|
||||
try {
|
||||
const response = await fetch(`${API_BASE_URL}${endpoint}`, options);
|
||||
const response = await fetch(`${process.env.EXPO_PUBLIC_API_URL}${url}`, options);
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! status: ${response.status}`);
|
||||
}
|
||||
|
|
102
server.js
102
server.js
|
@ -9,7 +9,24 @@ const requestHandler = async (req, res) => {
|
|||
res.writeHead(200, { "Content-Type": "application/json" });
|
||||
res.end(JSON.stringify({ message: "GET is working" }));
|
||||
return;
|
||||
}
|
||||
if (req.method === "GET" && req.url === "/api/ride/create") {
|
||||
res.writeHead(200, { "Content-Type": "application/json" });
|
||||
res.end(JSON.stringify({ message: "GET is working" }));
|
||||
return;
|
||||
}
|
||||
if (req.method === "GET" && req.url === "/api/driver") {
|
||||
try {
|
||||
const drivers = await sql`SELECT * FROM drivers`; // Adjust table name
|
||||
res.writeHead(200, { "Content-Type": "application/json" });
|
||||
res.end(JSON.stringify({ data: drivers }));
|
||||
} catch (err) {
|
||||
console.error("❌ Error fetching drivers:", err);
|
||||
res.writeHead(500, { "Content-Type": "application/json" });
|
||||
res.end(JSON.stringify({ error: "Error fetching drivers" }));
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (req.method === "POST" && req.url === "/api/users") {
|
||||
let body = "";
|
||||
|
||||
|
@ -56,7 +73,90 @@ const requestHandler = async (req, res) => {
|
|||
|
||||
return;
|
||||
}
|
||||
|
||||
if (req.method === "POST" && req.url === "/api/ride/rides") {
|
||||
let body = "";
|
||||
|
||||
req.on("data", (chunk) => {
|
||||
body += chunk.toString();
|
||||
});
|
||||
|
||||
req.on("end", async () => {
|
||||
try {
|
||||
const {
|
||||
origin_address,
|
||||
destination_address,
|
||||
origin_latitude,
|
||||
origin_longitude,
|
||||
destination_latitude,
|
||||
destination_longitude,
|
||||
ride_time,
|
||||
fare_price,
|
||||
payment_status,
|
||||
driver_id,
|
||||
user_id,
|
||||
} = JSON.parse(body);
|
||||
|
||||
if (
|
||||
!origin_address ||
|
||||
!destination_address ||
|
||||
!origin_latitude ||
|
||||
!origin_longitude ||
|
||||
!destination_latitude ||
|
||||
!destination_longitude ||
|
||||
!ride_time ||
|
||||
!fare_price ||
|
||||
!payment_status ||
|
||||
!driver_id ||
|
||||
!user_id
|
||||
) {
|
||||
res.writeHead(400, { "Content-Type": "application/json" });
|
||||
res.end(JSON.stringify({ error: "Missing required fields" }));
|
||||
return;
|
||||
}
|
||||
|
||||
const sql = neon(`${process.env.DATABASE_URL}`);
|
||||
|
||||
const response = await sql`
|
||||
INSERT INTO rides (
|
||||
origin_address,
|
||||
destination_address,
|
||||
origin_latitude,
|
||||
origin_longitude,
|
||||
destination_latitude,
|
||||
destination_longitude,
|
||||
ride_time,
|
||||
fare_price,
|
||||
payment_status,
|
||||
driver_id,
|
||||
user_id
|
||||
) VALUES (
|
||||
${origin_address},
|
||||
${destination_address},
|
||||
${origin_latitude},
|
||||
${origin_longitude},
|
||||
${destination_latitude},
|
||||
${destination_longitude},
|
||||
${ride_time},
|
||||
${fare_price},
|
||||
${payment_status},
|
||||
${driver_id},
|
||||
${user_id}
|
||||
)
|
||||
RETURNING *;
|
||||
`;
|
||||
|
||||
res.writeHead(201, { "Content-Type": "application/json" });
|
||||
res.end(JSON.stringify({ data: response[0] }));
|
||||
} catch (error) {
|
||||
console.error("Error inserting data into recent_rides:", error);
|
||||
res.writeHead(500, { "Content-Type": "application/json" });
|
||||
res.end(JSON.stringify({ error: "Internal Server Error" }));
|
||||
}
|
||||
});
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Fallback for unrecognized routes
|
||||
res.writeHead(404, { "Content-Type": "text/plain" });
|
||||
res.end("Not Found");
|
||||
|
|
|
@ -44,7 +44,7 @@ declare interface Ride {
|
|||
fare_price: number;
|
||||
payment_status: string;
|
||||
driver_id: number;
|
||||
user_email: string;
|
||||
user_email?: string;
|
||||
created_at: string;
|
||||
driver: {
|
||||
first_name: string;
|
||||
|
|
Loading…
Reference in New Issue