summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authoromagdy7 <omar.professional8777@gmail.com>2023-12-22 20:32:40 +0200
committeromagdy7 <omar.professional8777@gmail.com>2023-12-22 20:32:40 +0200
commit2548273d89e55efc24a2df101b621b06a6a83313 (patch)
treef53432affb67df53357fb0633e5073ebe642aef3
parente97dbb11b30d0fe51b2ca1660e9f0d27a99a73e3 (diff)
downloadcarpool-2548273d89e55efc24a2df101b621b06a6a83313.tar.xz
carpool-2548273d89e55efc24a2df101b621b06a6a83313.zip
Added rendering passenger requests
-rw-r--r--driver/package.json1
-rw-r--r--driver/pnpm-lock.yaml80
-rw-r--r--driver/src/components/RideDialog.tsx48
-rw-r--r--driver/src/components/ui/toast.tsx127
-rw-r--r--driver/src/components/ui/toaster.tsx33
-rw-r--r--driver/src/components/ui/use-toast.ts192
-rw-r--r--driver/src/pages/Home.tsx44
-rw-r--r--driver/src/utils/fetchRideRequests.ts38
-rw-r--r--driver/src/utils/fetchUserDetails.ts8
9 files changed, 555 insertions, 16 deletions
diff --git a/driver/package.json b/driver/package.json
index 9853e7c..5ec615d 100644
--- a/driver/package.json
+++ b/driver/package.json
@@ -14,6 +14,7 @@
"@radix-ui/react-dialog": "^1.0.5",
"@radix-ui/react-label": "^2.0.2",
"@radix-ui/react-slot": "^1.0.2",
+ "@radix-ui/react-toast": "^1.1.5",
"class-variance-authority": "^0.7.0",
"clsx": "^2.0.0",
"firebase": "^10.7.1",
diff --git a/driver/pnpm-lock.yaml b/driver/pnpm-lock.yaml
index 21624a2..cb5722b 100644
--- a/driver/pnpm-lock.yaml
+++ b/driver/pnpm-lock.yaml
@@ -17,6 +17,9 @@ dependencies:
'@radix-ui/react-slot':
specifier: ^1.0.2
version: 1.0.2(@types/react@18.2.45)(react@18.2.0)
+ '@radix-ui/react-toast':
+ specifier: ^1.1.5
+ version: 1.1.5(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0)
class-variance-authority:
specifier: ^0.7.0
version: 0.7.0
@@ -1181,6 +1184,30 @@ packages:
react-dom: 18.2.0(react@18.2.0)
dev: false
+ /@radix-ui/react-collection@1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.23.6
+ '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.45)(react@18.2.0)
+ '@radix-ui/react-context': 1.0.1(@types/react@18.2.45)(react@18.2.0)
+ '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-slot': 1.0.2(@types/react@18.2.45)(react@18.2.0)
+ '@types/react': 18.2.45
+ '@types/react-dom': 18.2.18
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ dev: false
+
/@radix-ui/react-compose-refs@1.0.1(@types/react@18.2.45)(react@18.2.0):
resolution: {integrity: sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==}
peerDependencies:
@@ -1420,6 +1447,38 @@ packages:
react: 18.2.0
dev: false
+ /@radix-ui/react-toast@1.1.5(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-fRLn227WHIBRSzuRzGJ8W+5YALxofH23y0MlPLddaIpLpCDqdE0NZlS2NRQDRiptfxDeeCjgFIpexB1/zkxDlw==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.23.6
+ '@radix-ui/primitive': 1.0.1
+ '@radix-ui/react-collection': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.45)(react@18.2.0)
+ '@radix-ui/react-context': 1.0.1(@types/react@18.2.45)(react@18.2.0)
+ '@radix-ui/react-dismissable-layer': 1.0.5(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-portal': 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-presence': 1.0.1(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0)
+ '@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.45)(react@18.2.0)
+ '@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.45)(react@18.2.0)
+ '@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.45)(react@18.2.0)
+ '@radix-ui/react-visually-hidden': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0)
+ '@types/react': 18.2.45
+ '@types/react-dom': 18.2.18
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ dev: false
+
/@radix-ui/react-use-callback-ref@1.0.1(@types/react@18.2.45)(react@18.2.0):
resolution: {integrity: sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==}
peerDependencies:
@@ -1478,6 +1537,27 @@ packages:
react: 18.2.0
dev: false
+ /@radix-ui/react-visually-hidden@1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0):
+ resolution: {integrity: sha512-D4w41yN5YRKtu464TLnByKzMDG/JlMPHtfZgQAu9v6mNakUqGUI9vUrfQKz8NK41VMm/xbZbh76NUTVtIYqOMA==}
+ peerDependencies:
+ '@types/react': '*'
+ '@types/react-dom': '*'
+ react: ^16.8 || ^17.0 || ^18.0
+ react-dom: ^16.8 || ^17.0 || ^18.0
+ peerDependenciesMeta:
+ '@types/react':
+ optional: true
+ '@types/react-dom':
+ optional: true
+ dependencies:
+ '@babel/runtime': 7.23.6
+ '@radix-ui/react-primitive': 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.45)(react-dom@18.2.0)(react@18.2.0)
+ '@types/react': 18.2.45
+ '@types/react-dom': 18.2.18
+ react: 18.2.0
+ react-dom: 18.2.0(react@18.2.0)
+ dev: false
+
/@remix-run/router@1.14.0:
resolution: {integrity: sha512-WOHih+ClN7N8oHk9N4JUiMxQJmRVaOxcg8w7F/oHUXzJt920ekASLI/7cYX8XkntDWRhLZtsk6LbGrkgOAvi5A==}
engines: {node: '>=14.0.0'}
diff --git a/driver/src/components/RideDialog.tsx b/driver/src/components/RideDialog.tsx
index da7767b..ff3aa98 100644
--- a/driver/src/components/RideDialog.tsx
+++ b/driver/src/components/RideDialog.tsx
@@ -1,6 +1,5 @@
-import { addDoc, collection, doc, getDoc } from "firebase/firestore"
+import { addDoc, collection } from "firebase/firestore"
import { db } from "../firebase/firebase_config"
-import { auth } from "../firebase/firebase_config"
import { Button } from "@/components/ui/button"
import {
Dialog,
@@ -14,6 +13,8 @@ import {
import { Input } from "@/components/ui/input"
import { Label } from "@/components/ui/label"
import { useState } from "react"
+import { useToast } from "./ui/use-toast"
+import { ToastAction } from "./ui/toast"
interface RideOrder {
driverName: string
@@ -28,15 +29,21 @@ interface RideOrder {
}
-function RideDialog({ name, brand, model, color, plateNumber }: any) {
+function RideDialog({ name, brand, model, color, plateNumber, phoneNumber }: any) {
+ const { toast } = useToast()
- const [status, _setStatus] = useState<string>('Pending')
+ const [status, _setStatus] = useState<string>('Unreserved')
const [orderTime, _setOrderTime] = useState<Date>(new Date())
const [pickUpLocation, setPickUpLocation] = useState<string>()
const [dropOffLocation, setDropOffLocation] = useState<string>()
+ const [isRideAdded, setIsRideAdded] = useState(true)
+ const [cost, setCost] = useState('')
const addRideOrderToFirestore = async () => {
+ if (isRideAdded) {
+ return;
+ }
try {
// Get a reference to the 'rideOrders' collection
const rideOrdersCollection = collection(db, 'Rides');
@@ -44,16 +51,19 @@ function RideDialog({ name, brand, model, color, plateNumber }: any) {
// Add a new document to the 'rideOrders' collection with the data from the RideOrder object
const newRideOrderRef = await addDoc(rideOrdersCollection, {
driverName: name,
+ phoneNumber: phoneNumber,
carModel: model,
carBrand: brand,
carColor: color,
plateNumber: plateNumber,
+ cost: parseInt(cost),
status: status,
orderTime: orderTime,
fromLocation: pickUpLocation,
toLocation: dropOffLocation,
});
+ setIsRideAdded(true)
console.log('Ride order added with ID:', newRideOrderRef.id);
// 'newRideOrderRef.id' will give you the document ID of the added ride order
} catch (error) {
@@ -61,6 +71,10 @@ function RideDialog({ name, brand, model, color, plateNumber }: any) {
}
};
+ const cancelRide = () => {
+ setIsRideAdded(false)
+ }
+
return (
<div>
<Dialog>
@@ -97,9 +111,33 @@ function RideDialog({ name, brand, model, color, plateNumber }: any) {
onChange={(e) => setPickUpLocation(e.target.value)}
/>
</div>
+ <div className="grid grid-cols-4 items-center gap-4">
+ <Label htmlFor="From location" className="text-right">
+ Cost
+ </Label>
+ <Input
+ id="From location"
+ defaultValue=""
+ className="col-span-3"
+ onChange={(e) => setCost(e.target.value)}
+ />
+ </div>
</div>
<DialogFooter>
- <Button className="bg-green-500 text-black" type="submit" onClick={addRideOrderToFirestore}>Submit</Button>
+ <Button className="bg-green-500 text-black" type="submit" onClick={() => {
+ if (isRideAdded) {
+ console.log("Hello")
+ toast({
+ title: "Cannot add another ride",
+ description: "You already have a ride in place",
+ })
+ } else {
+ addRideOrderToFirestore
+ toast({
+ description: "Ride was added successfully",
+ })
+ }
+ }}>Submit</Button>
</DialogFooter>
</DialogContent>
</Dialog>
diff --git a/driver/src/components/ui/toast.tsx b/driver/src/components/ui/toast.tsx
new file mode 100644
index 0000000..a822477
--- /dev/null
+++ b/driver/src/components/ui/toast.tsx
@@ -0,0 +1,127 @@
+import * as React from "react"
+import * as ToastPrimitives from "@radix-ui/react-toast"
+import { cva, type VariantProps } from "class-variance-authority"
+import { X } from "lucide-react"
+
+import { cn } from "@/lib/utils"
+
+const ToastProvider = ToastPrimitives.Provider
+
+const ToastViewport = React.forwardRef<
+ React.ElementRef<typeof ToastPrimitives.Viewport>,
+ React.ComponentPropsWithoutRef<typeof ToastPrimitives.Viewport>
+>(({ className, ...props }, ref) => (
+ <ToastPrimitives.Viewport
+ ref={ref}
+ className={cn(
+ "fixed top-0 z-[100] flex max-h-screen w-full flex-col-reverse p-4 sm:bottom-0 sm:right-0 sm:top-auto sm:flex-col md:max-w-[420px]",
+ className
+ )}
+ {...props}
+ />
+))
+ToastViewport.displayName = ToastPrimitives.Viewport.displayName
+
+const toastVariants = cva(
+ "group pointer-events-auto relative flex w-full items-center justify-between space-x-4 overflow-hidden rounded-md border p-6 pr-8 shadow-lg transition-all data-[swipe=cancel]:translate-x-0 data-[swipe=end]:translate-x-[var(--radix-toast-swipe-end-x)] data-[swipe=move]:translate-x-[var(--radix-toast-swipe-move-x)] data-[swipe=move]:transition-none data-[state=open]:animate-in data-[state=closed]:animate-out data-[swipe=end]:animate-out data-[state=closed]:fade-out-80 data-[state=closed]:slide-out-to-right-full data-[state=open]:slide-in-from-top-full data-[state=open]:sm:slide-in-from-bottom-full",
+ {
+ variants: {
+ variant: {
+ default: "border bg-background text-foreground",
+ destructive:
+ "destructive group border-destructive bg-destructive text-destructive-foreground",
+ },
+ },
+ defaultVariants: {
+ variant: "default",
+ },
+ }
+)
+
+const Toast = React.forwardRef<
+ React.ElementRef<typeof ToastPrimitives.Root>,
+ React.ComponentPropsWithoutRef<typeof ToastPrimitives.Root> &
+ VariantProps<typeof toastVariants>
+>(({ className, variant, ...props }, ref) => {
+ return (
+ <ToastPrimitives.Root
+ ref={ref}
+ className={cn(toastVariants({ variant }), className)}
+ {...props}
+ />
+ )
+})
+Toast.displayName = ToastPrimitives.Root.displayName
+
+const ToastAction = React.forwardRef<
+ React.ElementRef<typeof ToastPrimitives.Action>,
+ React.ComponentPropsWithoutRef<typeof ToastPrimitives.Action>
+>(({ className, ...props }, ref) => (
+ <ToastPrimitives.Action
+ ref={ref}
+ className={cn(
+ "inline-flex h-8 shrink-0 items-center justify-center rounded-md border bg-transparent px-3 text-sm font-medium ring-offset-background transition-colors hover:bg-secondary focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 group-[.destructive]:border-muted/40 group-[.destructive]:hover:border-destructive/30 group-[.destructive]:hover:bg-destructive group-[.destructive]:hover:text-destructive-foreground group-[.destructive]:focus:ring-destructive",
+ className
+ )}
+ {...props}
+ />
+))
+ToastAction.displayName = ToastPrimitives.Action.displayName
+
+const ToastClose = React.forwardRef<
+ React.ElementRef<typeof ToastPrimitives.Close>,
+ React.ComponentPropsWithoutRef<typeof ToastPrimitives.Close>
+>(({ className, ...props }, ref) => (
+ <ToastPrimitives.Close
+ ref={ref}
+ className={cn(
+ "absolute right-2 top-2 rounded-md p-1 text-foreground/50 opacity-0 transition-opacity hover:text-foreground focus:opacity-100 focus:outline-none focus:ring-2 group-hover:opacity-100 group-[.destructive]:text-red-300 group-[.destructive]:hover:text-red-50 group-[.destructive]:focus:ring-red-400 group-[.destructive]:focus:ring-offset-red-600",
+ className
+ )}
+ toast-close=""
+ {...props}
+ >
+ <X className="h-4 w-4" />
+ </ToastPrimitives.Close>
+))
+ToastClose.displayName = ToastPrimitives.Close.displayName
+
+const ToastTitle = React.forwardRef<
+ React.ElementRef<typeof ToastPrimitives.Title>,
+ React.ComponentPropsWithoutRef<typeof ToastPrimitives.Title>
+>(({ className, ...props }, ref) => (
+ <ToastPrimitives.Title
+ ref={ref}
+ className={cn("text-sm font-semibold", className)}
+ {...props}
+ />
+))
+ToastTitle.displayName = ToastPrimitives.Title.displayName
+
+const ToastDescription = React.forwardRef<
+ React.ElementRef<typeof ToastPrimitives.Description>,
+ React.ComponentPropsWithoutRef<typeof ToastPrimitives.Description>
+>(({ className, ...props }, ref) => (
+ <ToastPrimitives.Description
+ ref={ref}
+ className={cn("text-sm opacity-90", className)}
+ {...props}
+ />
+))
+ToastDescription.displayName = ToastPrimitives.Description.displayName
+
+type ToastProps = React.ComponentPropsWithoutRef<typeof Toast>
+
+type ToastActionElement = React.ReactElement<typeof ToastAction>
+
+export {
+ type ToastProps,
+ type ToastActionElement,
+ ToastProvider,
+ ToastViewport,
+ Toast,
+ ToastTitle,
+ ToastDescription,
+ ToastClose,
+ ToastAction,
+}
diff --git a/driver/src/components/ui/toaster.tsx b/driver/src/components/ui/toaster.tsx
new file mode 100644
index 0000000..a2209ba
--- /dev/null
+++ b/driver/src/components/ui/toaster.tsx
@@ -0,0 +1,33 @@
+import {
+ Toast,
+ ToastClose,
+ ToastDescription,
+ ToastProvider,
+ ToastTitle,
+ ToastViewport,
+} from "@/components/ui/toast"
+import { useToast } from "@/components/ui/use-toast"
+
+export function Toaster() {
+ const { toasts } = useToast()
+
+ return (
+ <ToastProvider>
+ {toasts.map(function ({ id, title, description, action, ...props }) {
+ return (
+ <Toast key={id} {...props}>
+ <div className="grid gap-1">
+ {title && <ToastTitle>{title}</ToastTitle>}
+ {description && (
+ <ToastDescription>{description}</ToastDescription>
+ )}
+ </div>
+ {action}
+ <ToastClose />
+ </Toast>
+ )
+ })}
+ <ToastViewport />
+ </ToastProvider>
+ )
+}
diff --git a/driver/src/components/ui/use-toast.ts b/driver/src/components/ui/use-toast.ts
new file mode 100644
index 0000000..1671307
--- /dev/null
+++ b/driver/src/components/ui/use-toast.ts
@@ -0,0 +1,192 @@
+// Inspired by react-hot-toast library
+import * as React from "react"
+
+import type {
+ ToastActionElement,
+ ToastProps,
+} from "@/components/ui/toast"
+
+const TOAST_LIMIT = 1
+const TOAST_REMOVE_DELAY = 1000000
+
+type ToasterToast = ToastProps & {
+ id: string
+ title?: React.ReactNode
+ description?: React.ReactNode
+ action?: ToastActionElement
+}
+
+const actionTypes = {
+ ADD_TOAST: "ADD_TOAST",
+ UPDATE_TOAST: "UPDATE_TOAST",
+ DISMISS_TOAST: "DISMISS_TOAST",
+ REMOVE_TOAST: "REMOVE_TOAST",
+} as const
+
+let count = 0
+
+function genId() {
+ count = (count + 1) % Number.MAX_SAFE_INTEGER
+ return count.toString()
+}
+
+type ActionType = typeof actionTypes
+
+type Action =
+ | {
+ type: ActionType["ADD_TOAST"]
+ toast: ToasterToast
+ }
+ | {
+ type: ActionType["UPDATE_TOAST"]
+ toast: Partial<ToasterToast>
+ }
+ | {
+ type: ActionType["DISMISS_TOAST"]
+ toastId?: ToasterToast["id"]
+ }
+ | {
+ type: ActionType["REMOVE_TOAST"]
+ toastId?: ToasterToast["id"]
+ }
+
+interface State {
+ toasts: ToasterToast[]
+}
+
+const toastTimeouts = new Map<string, ReturnType<typeof setTimeout>>()
+
+const addToRemoveQueue = (toastId: string) => {
+ if (toastTimeouts.has(toastId)) {
+ return
+ }
+
+ const timeout = setTimeout(() => {
+ toastTimeouts.delete(toastId)
+ dispatch({
+ type: "REMOVE_TOAST",
+ toastId: toastId,
+ })
+ }, TOAST_REMOVE_DELAY)
+
+ toastTimeouts.set(toastId, timeout)
+}
+
+export const reducer = (state: State, action: Action): State => {
+ switch (action.type) {
+ case "ADD_TOAST":
+ return {
+ ...state,
+ toasts: [action.toast, ...state.toasts].slice(0, TOAST_LIMIT),
+ }
+
+ case "UPDATE_TOAST":
+ return {
+ ...state,
+ toasts: state.toasts.map((t) =>
+ t.id === action.toast.id ? { ...t, ...action.toast } : t
+ ),
+ }
+
+ case "DISMISS_TOAST": {
+ const { toastId } = action
+
+ // ! Side effects ! - This could be extracted into a dismissToast() action,
+ // but I'll keep it here for simplicity
+ if (toastId) {
+ addToRemoveQueue(toastId)
+ } else {
+ state.toasts.forEach((toast) => {
+ addToRemoveQueue(toast.id)
+ })
+ }
+
+ return {
+ ...state,
+ toasts: state.toasts.map((t) =>
+ t.id === toastId || toastId === undefined
+ ? {
+ ...t,
+ open: false,
+ }
+ : t
+ ),
+ }
+ }
+ case "REMOVE_TOAST":
+ if (action.toastId === undefined) {
+ return {
+ ...state,
+ toasts: [],
+ }
+ }
+ return {
+ ...state,
+ toasts: state.toasts.filter((t) => t.id !== action.toastId),
+ }
+ }
+}
+
+const listeners: Array<(state: State) => void> = []
+
+let memoryState: State = { toasts: [] }
+
+function dispatch(action: Action) {
+ memoryState = reducer(memoryState, action)
+ listeners.forEach((listener) => {
+ listener(memoryState)
+ })
+}
+
+type Toast = Omit<ToasterToast, "id">
+
+function toast({ ...props }: Toast) {
+ const id = genId()
+
+ const update = (props: ToasterToast) =>
+ dispatch({
+ type: "UPDATE_TOAST",
+ toast: { ...props, id },
+ })
+ const dismiss = () => dispatch({ type: "DISMISS_TOAST", toastId: id })
+
+ dispatch({
+ type: "ADD_TOAST",
+ toast: {
+ ...props,
+ id,
+ open: true,
+ onOpenChange: (open) => {
+ if (!open) dismiss()
+ },
+ },
+ })
+
+ return {
+ id: id,
+ dismiss,
+ update,
+ }
+}
+
+function useToast() {
+ const [state, setState] = React.useState<State>(memoryState)
+
+ React.useEffect(() => {
+ listeners.push(setState)
+ return () => {
+ const index = listeners.indexOf(setState)
+ if (index > -1) {
+ listeners.splice(index, 1)
+ }
+ }
+ }, [state])
+
+ return {
+ ...state,
+ toast,
+ dismiss: (toastId?: string) => dispatch({ type: "DISMISS_TOAST", toastId }),
+ }
+}
+
+export { useToast, toast }
diff --git a/driver/src/pages/Home.tsx b/driver/src/pages/Home.tsx
index 81f1fb9..5a2d981 100644
--- a/driver/src/pages/Home.tsx
+++ b/driver/src/pages/Home.tsx
@@ -5,9 +5,10 @@ import { Button } from "@/components/ui/button"
import { CardTitle, CardHeader, CardContent, Card } from "@/components/ui/card"
import { auth, db } from "@/firebase/firebase_config"
import { fetchUserDetails } from "@/utils/fetchUserDetails"
-import { DocumentData, collection, doc, getDoc, getDocs, query, where } from "firebase/firestore"
+import { Toaster } from "@/components/ui/toaster"
import { useEffect, useState } from "react"
import { Navigate } from "react-router-dom"
+import { fetchRideRequests } from "@/utils/fetchRideRequests"
interface IDriver {
uid: string,
@@ -21,6 +22,8 @@ interface IDriver {
interface IPassengerRequest {
passengerName: string,
+ phoneNumber: string,
+ status: string,
pickUp: string,
dropOff: string,
}
@@ -30,13 +33,19 @@ interface ITrip {
dropOff: string,
}
-function PassengerRequestCard({ passengerName, pickUp, dropOff }: IPassengerRequest) {
+function PassengerRequestCard({ passengerName, pickUp, dropOff, status, phoneNumber }: IPassengerRequest) {
return (
<li className="py-2">
<p>
<strong>Passenger:</strong> {passengerName}
</p>
<p>
+ <strong>Phone number:</strong> {phoneNumber}
+ </p>
+ <p>
+ <strong>Status:</strong> {status}
+ </p>
+ <p>
<strong>Pickup:</strong> {pickUp}
</p>
<p>
@@ -57,13 +66,18 @@ function PassengerRequestCard({ passengerName, pickUp, dropOff }: IPassengerRequ
export default function Home() {
const [driverData, setDriverData] = useState<IDriver | null | undefined>()
+ const [rideRequests, setRideRequests] = useState<any[] | undefined>([])
const [currentTrip, setCurrentTrip] = useState<ITrip>()
-
useEffect(() => {
+ const user = auth.currentUser;
async function fetchData() {
- const data: IDriver | null | undefined = await fetchUserDetails();
+ const data: IDriver | null | undefined = await fetchUserDetails(user?.uid);
+ const rideReqs = await fetchRideRequests()
+ console.log("RideRequests:", rideReqs)
setDriverData(data)
+ setRideRequests(rideReqs)
+ console.log("Length: ", rideRequests?.length)
}
fetchData()
}, [auth.currentUser, db]);
@@ -134,16 +148,34 @@ export default function Home() {
</CardHeader>
<CardContent className="mt-3">
<ul className="divide-y divide-gray-600">
- <PassengerRequestCard passengerName="Jane doe" pickUp="Gate 3/4" dropOff="5th Settelment" />
+ {rideRequests?.map((rideReq) => {
+ return (
+ < PassengerRequestCard
+ passengerName={rideReq?.name}
+ pickUp={rideReq?.pickUp}
+ dropOff={rideReq?.dropOff}
+ phoneNumber={rideReq?.phoneNumber}
+ status={rideReq?.status}
+ />
+ )
+ })}
</ul>
</CardContent>
</Card>
</section>
<div className="flex justify-end items-center mt-6">
- <RideDialog />
+ <RideDialog
+ name={driverData?.name}
+ model={driverData?.carModel}
+ brand={driverData?.carBrand}
+ plateNumber={driverData?.plateNumber}
+ phoneNumber={driverData?.phoneNumber}
+ color={driverData?.carColor}
+ />
</div>
<footer className="mt-auto">
</footer>
+ <Toaster />
</main>
)
)
diff --git a/driver/src/utils/fetchRideRequests.ts b/driver/src/utils/fetchRideRequests.ts
new file mode 100644
index 0000000..ec28471
--- /dev/null
+++ b/driver/src/utils/fetchRideRequests.ts
@@ -0,0 +1,38 @@
+import { auth, db } from "@/firebase/firebase_config";
+import { DocumentData, collection, getDocs, query, where } from "firebase/firestore";
+import { fetchUserDetails } from "./fetchUserDetails";
+
+
+export const fetchRideRequests = async () => {
+ const user = auth.currentUser;
+ console.log(user)
+ try {
+ let data: any[] = []
+ if (user) {
+ const usersRef = collection(db, "RideRequest")
+ const q = query(usersRef, where("status", "==", "Pending"))
+ const querySnapshot = await getDocs(q);
+ querySnapshot.forEach((doc: DocumentData) => {
+ data.push(doc.data())
+ console.log(doc.id, " => ", doc.data());
+ });
+ const rideReqs = data?.map(async (rideReq) => {
+ const passengerData: any = await fetchUserDetails(rideReq.passengerID);
+ return {
+ name: passengerData?.name,
+ phoneNumber: passengerData?.phoneNumber,
+ status: rideReq.status,
+ pickUp: rideReq.pickUp,
+ dropOff: rideReq.dropOff
+ }
+ })
+ const rides = await Promise.all(rideReqs)
+ return rides;
+ } else {
+ console.log("There is no user");
+ return [];
+ }
+ } catch (error) {
+ console.error('Error fetching ride requests', error);
+ }
+};
diff --git a/driver/src/utils/fetchUserDetails.ts b/driver/src/utils/fetchUserDetails.ts
index 949a4ab..a2d5cb6 100644
--- a/driver/src/utils/fetchUserDetails.ts
+++ b/driver/src/utils/fetchUserDetails.ts
@@ -2,18 +2,16 @@ import { auth, db } from "@/firebase/firebase_config";
import { DocumentData, collection, getDocs, query, where } from "firebase/firestore";
-export const fetchUserDetails = async () => {
- const user = auth.currentUser;
- console.log(user)
+export const fetchUserDetails = async (uid) => {
try {
+ const user = auth.currentUser;
let data = null
if (user) {
const usersRef = collection(db, "users")
- const q = query(usersRef, where("uid", "==", user.uid))
+ const q = query(usersRef, where("uid", "==", uid))
const querySnapshot = await getDocs(q);
querySnapshot.forEach((doc: DocumentData) => {
data = doc.data()
- // setDriverData(doc.data())
console.log(doc.id, " => ", doc.data());
});
return data;