From 3b3b9acefa2853b031fcb2d1118c3b329aff362e Mon Sep 17 00:00:00 2001 From: neel Date: Fri, 11 Apr 2025 15:57:48 +0530 Subject: [PATCH] map path solve --- components/Map.tsx | 11 +++- components/Payment.tsx | 125 ++++++++++++++++++++++++++--------------- lib/fetch.ts | 4 +- server.js | 102 ++++++++++++++++++++++++++++++++- types/type.d.ts | 2 +- 5 files changed, 192 insertions(+), 52 deletions(-) diff --git a/components/Map.tsx b/components/Map.tsx index 7783a61..6a9ed3f 100644 --- a/components/Map.tsx +++ b/components/Map.tsx @@ -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("/(api)/driver"); + const { data: drivers, loading, error } = useFetch("/api/driver"); const { userLongitude, userLatitude, destinationLatitude, destinationLongitude } = useLocationStore(); const { selectedDriver, setDrivers } = useDriverStore(); const [markers, setMarkers] = useState([]); @@ -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 && ( + <> + + + + )} ) } diff --git a/components/Payment.tsx b/components/Payment.tsx index 5ea1e0b..51e1508 100644 --- a/components/Payment.tsx +++ b/components/Payment.tsx @@ -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 ( <> + setSuccess(false)} > + + + Ride Booked! + Thank you for your booking. Your reservation has been placed. Please proceed with your trip! + {setSuccess(false) + router.push("/(root)/(tabs)/home")}} style={tw`mt-5`} /> + + ) }; diff --git a/lib/fetch.ts b/lib/fetch.ts index 85aa1ab..9b6f2df 100644 --- a/lib/fetch.ts +++ b/lib/fetch.ts @@ -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}`); } diff --git a/server.js b/server.js index 846c46e..e1a9d72 100644 --- a/server.js +++ b/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"); diff --git a/types/type.d.ts b/types/type.d.ts index 34e2d71..87d07c6 100644 --- a/types/type.d.ts +++ b/types/type.d.ts @@ -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;