-
Notifications
You must be signed in to change notification settings - Fork 354
Open
Description

Here is how i use it:
"use client"
import { useState, useEffect } from "react"
import { Card, CardContent } from "@/components/ui/card"
import { Button } from "@/components/ui/button"
import { ChevronLeft, ChevronRight, Loader2, Copy } from "lucide-react"
import Image from "next/image"
import styles from './inspection-items-viewer.module.sass'
import toast, { Toaster } from 'react-hot-toast';
const notifyAboutCopying = () => toast.success('Copied to clipboard!');
interface InspectionItem {
car_inspection_item_id: number
reviewer_note: string
car_make: string
car_model: string
car_color: string
car_plate_number: string
driver_name: string
file_path: string
inspection_item_type_description: string
inspection_item_type_name: string
}
export function InspectionItemsViewer() {
const [items, setItems] = useState<InspectionItem[]>([])
const [loading, setLoading] = useState(true)
const [currentPage, setCurrentPage] = useState(1)
const [totalPages, setTotalPages] = useState(0)
const [error, setError] = useState<string | null>(null)
const fetchItems = async (page: number) => {
setLoading(true)
setError(null)
try {
const response = await fetch(`/api/inspection-items?page=${page}`)
if (!response.ok) {
throw new Error("Failed to fetch inspection items")
}
const data = await response.json()
setItems(data.items)
setTotalPages(data.totalPages)
} catch (err) {
setError(err instanceof Error ? err.message : "An error occurred")
} finally {
setLoading(false)
}
}
useEffect(() => {
fetchItems(currentPage)
}, [currentPage])
const handlePrevPage = () => {
if (currentPage > 1) {
setCurrentPage(currentPage - 1)
}
}
const handleNextPage = () => {
if (currentPage < totalPages) {
setCurrentPage(currentPage + 1)
}
}
if (error) {
return (
<div className={styles.errorContainer}>
<p className={styles.errorText}>Error: {error}</p>
<Button onClick={() => fetchItems(currentPage)} className={styles.retryButton}>
Retry
</Button>
</div>
)
}
return (
<div className={styles.wrapper}>
{/* Pagination Controls */}
<div className={styles.paginationControls}>
<Button onClick={handlePrevPage} disabled={currentPage === 1 || loading} variant="outline">
<ChevronLeft className={`${styles.icon} ${styles.iconLeft}`} />
Previous
</Button>
<span className={styles.pageInfo}>
Page {currentPage} of {totalPages}
</span>
<Button onClick={handleNextPage} disabled={currentPage === totalPages || loading} variant="outline">
Next
<ChevronRight className={`${styles.icon} ${styles.iconRight}`} />
</Button>
</div>
{/* Loading State */}
{loading && (
<div className={styles.loadingContainer}>
<Loader2 className={styles.spinner} />
</div>
)}
{/* Inspection Items Grid */}
{!loading && (
<div className={styles.itemsGrid}>
{items.map((item) => (
<Card key={item.car_inspection_item_id} className={styles.card}>
<div className={styles.imageContainer}>
<Image
src={`/api/images/${item.file_path}`}
alt={`Inspection item ${item.car_inspection_item_id}`}
fill
className={styles.image}
sizes="1319px"
/>
</div>
<CardContent className={styles.cardContent}>
<div className={styles.itemId}>
<Copy className={styles.copyIcon} onClick={() => {
navigator.clipboard.writeText(item.car_inspection_item_id.toString())
notifyAboutCopying()
}} />
<p className={styles.itemId}>{item.car_inspection_item_id}</p>
<Toaster position="top-center" reverseOrder={false} />
</div>
<div className={styles.itemType}>
{item.inspection_item_type_description}{" "}
<span className={styles.typeName}>({item.inspection_item_type_name})</span>
</div>
<div className={styles.reviewerNote}>{item.reviewer_note}</div>
<div className={styles.carDetails}>
<div className={styles.carModel}>
{item.car_make} {item.car_model}
</div>
<div className={styles.carInfo}>Color: {item.car_color}</div>
<div className={styles.carInfo}>Plate: {item.car_plate_number}</div>
<div className={styles.carInfo}>Driver: {item.driver_name}</div>
</div>
</CardContent>
</Card>
))}
</div>
)}
{/* Empty State */}
{!loading && items.length === 0 && (
<div className={styles.emptyState}>
<p className={styles.emptyText}>No inspection items found.</p>
</div>
)}
</div>
)
}
Metadata
Metadata
Assignees
Labels
No labels