Skip to content

Commit 95c4510

Browse files
committed
add error alert ui
1 parent 67b8570 commit 95c4510

File tree

4 files changed

+71
-7
lines changed

4 files changed

+71
-7
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"dev": "npx lerna run dev",
1212
"test": "npx lerna run test",
1313
"lint": "npx lerna run lint",
14-
"format": "npx lerna run format"
14+
"fix": "npx lerna run format"
1515
},
1616
"repository": {
1717
"type": "git",

packages/client/src/App.tsx

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { useState, useEffect } from 'react'
22
import { Button } from '@/components/ui/button'
33
import LoadingSkeleton from './components/LoadingSkeleton'
4+
import AlertMsg from './components/AlertMsg'
45
import Mapper from './components/Mapper'
56
import TruckCard from './components/TruckCard'
67

@@ -29,6 +30,7 @@ function App() {
2930
})
3031
const [foodTrucks, setFoodTrucks] = useState<FoodTruck[]>([])
3132
const [isLoading, setIsLoading] = useState<boolean>(false)
33+
const [error, setError] = useState<string>('')
3234
const [selectedTruckId, setSelectedTruckId] = useState<string>('')
3335

3436
const getLocation = () => {
@@ -54,9 +56,8 @@ function App() {
5456
}, [])
5557

5658
const handleClick = async () => {
57-
// handle location not there
5859
if (!location.latitude || !location.longitude) {
59-
// show error on screen!
60+
setError(`Unable to get your location.`)
6061
return
6162
}
6263
setIsLoading(true)
@@ -72,23 +73,25 @@ function App() {
7273
lon: location.longitude?.toString() || ''
7374
})
7475
const paramsString = newParams.toString()
75-
// adjust proxy to get rid of localhost
76+
// TODO: Adjust proxy to get rid of localhost
7677
const response = await fetch(`http://localhost:8080/api/trucks?${paramsString}`)
7778
const json = await response.json()
7879
const data: FoodTruck[] = json.data
7980
setFoodTrucks(data)
81+
if (data.length === 0) {
82+
setError(`Nothing nearby or open right now! Get moving!`)
83+
}
8084
setIsLoading(false)
8185
} catch (error) {
82-
// show error on screen!
83-
console.log('error', error)
86+
setError(`Unable to get any trucks right now.`)
87+
// TODO: Show error to user on screen
8488
setIsLoading(false)
8589
}
8690
}
8791

8892
const handleTruckClick = (id: string) => {
8993
const truck = foodTrucks.find((truck) => truck.id === id)
9094
if (truck) {
91-
// console.log("truck is ", truck.id)
9295
setSelectedTruckId(truck.id)
9396
}
9497
}
@@ -114,6 +117,7 @@ function App() {
114117
/>
115118
<div style={{ zIndex: 10000 }}>
116119
<div className="flex flex-col items-center justify-center space-y-4">
120+
{error && <AlertMsg error={error} />}
117121
<Button onClick={handleClick}>Find Food Trucks Open Now</Button>
118122
{isLoading ? (
119123
<div className="flex flex-col align-left space-y-4">
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { Terminal } from 'lucide-react'
2+
3+
import { Alert, AlertDescription, AlertTitle } from '@/components/ui/alert'
4+
5+
interface AlertMsgProps {
6+
error: string
7+
}
8+
9+
export default function AlertMsg({ error }: AlertMsgProps) {
10+
return (
11+
<Alert>
12+
<Terminal className="h-4 w-4" />
13+
<AlertTitle>Heads up!</AlertTitle>
14+
<AlertDescription>{error}</AlertDescription>
15+
</Alert>
16+
)
17+
}
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import * as React from 'react'
2+
import { cva, type VariantProps } from 'class-variance-authority'
3+
4+
import { cn } from '@/lib/utils'
5+
6+
const alertVariants = cva(
7+
'relative w-full rounded-lg border p-4 [&>svg~*]:pl-7 [&>svg+div]:translate-y-[-3px] [&>svg]:absolute [&>svg]:left-4 [&>svg]:top-4 [&>svg]:text-foreground',
8+
{
9+
variants: {
10+
variant: {
11+
default: 'bg-background text-foreground',
12+
destructive: 'border-destructive/50 text-destructive dark:border-destructive [&>svg]:text-destructive'
13+
}
14+
},
15+
defaultVariants: {
16+
variant: 'default'
17+
}
18+
}
19+
)
20+
21+
const Alert = React.forwardRef<
22+
HTMLDivElement,
23+
React.HTMLAttributes<HTMLDivElement> & VariantProps<typeof alertVariants>
24+
>(({ className, variant, ...props }, ref) => (
25+
<div ref={ref} role="alert" className={cn(alertVariants({ variant }), className)} {...props} />
26+
))
27+
Alert.displayName = 'Alert'
28+
29+
const AlertTitle = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLHeadingElement>>(
30+
({ className, ...props }, ref) => (
31+
<h5 ref={ref} className={cn('mb-1 font-medium leading-none tracking-tight', className)} {...props} />
32+
)
33+
)
34+
AlertTitle.displayName = 'AlertTitle'
35+
36+
const AlertDescription = React.forwardRef<HTMLParagraphElement, React.HTMLAttributes<HTMLParagraphElement>>(
37+
({ className, ...props }, ref) => (
38+
<div ref={ref} className={cn('text-sm [&_p]:leading-relaxed', className)} {...props} />
39+
)
40+
)
41+
AlertDescription.displayName = 'AlertDescription'
42+
43+
export { Alert, AlertTitle, AlertDescription }

0 commit comments

Comments
 (0)