feat(api): restructure api with axios and chainage related changes
This commit is contained in:
@@ -6,15 +6,11 @@ import { Button } from "@/components/ui/button"
|
||||
import { Label } from "@/components/ui/label"
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select"
|
||||
import { Loader2, Check } from "lucide-react"
|
||||
import {
|
||||
fetchProjects,
|
||||
fetchPackagesByProject,
|
||||
fetchLocationsByPackage,
|
||||
} from "@/lib/api"
|
||||
import { projectService, packageService, chainageService } from "@/services/api"
|
||||
import {
|
||||
Project,
|
||||
Package as PackageType,
|
||||
Location,
|
||||
Chainage,
|
||||
SessionContext
|
||||
} from "@/types"
|
||||
import { cn } from "@/lib/utils"
|
||||
@@ -27,17 +23,17 @@ export function ProjectSelectionSection({ onSelectionComplete }: ProjectSelectio
|
||||
// Data states
|
||||
const [projects, setProjects] = useState<Project[]>([])
|
||||
const [packages, setPackages] = useState<PackageType[]>([])
|
||||
const [locations, setLocations] = useState<Location[]>([])
|
||||
const [chainages, setChainages] = useState<Chainage[]>([])
|
||||
|
||||
// Selection states
|
||||
const [selectedProject, setSelectedProject] = useState<Project | null>(null)
|
||||
const [selectedPackage, setSelectedPackage] = useState<PackageType | null>(null)
|
||||
const [selectedLocation, setSelectedLocation] = useState<Location | null>(null)
|
||||
const [selectedChainage, setSelectedChainage] = useState<Chainage | null>(null)
|
||||
|
||||
// Loading states
|
||||
const [loadingProjects, setLoadingProjects] = useState(true)
|
||||
const [loadingPackages, setLoadingPackages] = useState(false)
|
||||
const [loadingLocations, setLoadingLocations] = useState(false)
|
||||
const [loadingChainages, setLoadingChainages] = useState(false)
|
||||
|
||||
// Error state
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
@@ -48,7 +44,7 @@ export function ProjectSelectionSection({ onSelectionComplete }: ProjectSelectio
|
||||
try {
|
||||
setLoadingProjects(true)
|
||||
setError(null)
|
||||
const data = await fetchProjects()
|
||||
const data = await projectService.getProjects()
|
||||
setProjects(data.items)
|
||||
} catch (err) {
|
||||
console.error("Failed to load projects:", err)
|
||||
@@ -73,9 +69,9 @@ export function ProjectSelectionSection({ onSelectionComplete }: ProjectSelectio
|
||||
setLoadingPackages(true)
|
||||
setError(null)
|
||||
setSelectedPackage(null)
|
||||
setSelectedLocation(null)
|
||||
setLocations([])
|
||||
const data = await fetchPackagesByProject(selectedProject.id)
|
||||
setSelectedChainage(null)
|
||||
setChainages([])
|
||||
const data = await packageService.getPackagesByProject(selectedProject.id)
|
||||
setPackages(data.items)
|
||||
} catch (err) {
|
||||
console.error("Failed to load packages:", err)
|
||||
@@ -87,29 +83,29 @@ export function ProjectSelectionSection({ onSelectionComplete }: ProjectSelectio
|
||||
loadPackages()
|
||||
}, [selectedProject])
|
||||
|
||||
// Load locations when package changes
|
||||
// Load chainages when package changes
|
||||
useEffect(() => {
|
||||
if (!selectedPackage) {
|
||||
setLocations([])
|
||||
setSelectedLocation(null)
|
||||
setChainages([])
|
||||
setSelectedChainage(null)
|
||||
return
|
||||
}
|
||||
|
||||
const loadLocations = async () => {
|
||||
const loadChainages = async () => {
|
||||
try {
|
||||
setLoadingLocations(true)
|
||||
setLoadingChainages(true)
|
||||
setError(null)
|
||||
setSelectedLocation(null)
|
||||
const data = await fetchLocationsByPackage(selectedPackage.id)
|
||||
setLocations(data.items)
|
||||
setSelectedChainage(null)
|
||||
const data = await chainageService.getChainagesByPackage(selectedPackage.id)
|
||||
setChainages(data.items)
|
||||
} catch (err) {
|
||||
console.error("Failed to load locations:", err)
|
||||
setError("Failed to load locations for the selected package.")
|
||||
console.error("Failed to load chainages:", err)
|
||||
setError("Failed to load chainages for the selected package.")
|
||||
} finally {
|
||||
setLoadingLocations(false)
|
||||
setLoadingChainages(false)
|
||||
}
|
||||
}
|
||||
loadLocations()
|
||||
loadChainages()
|
||||
}, [selectedPackage])
|
||||
|
||||
const handleProjectChange = (projectId: string) => {
|
||||
@@ -122,31 +118,31 @@ export function ProjectSelectionSection({ onSelectionComplete }: ProjectSelectio
|
||||
setSelectedPackage(pkg)
|
||||
}
|
||||
|
||||
const handleLocationChange = (locationId: string) => {
|
||||
const location = locations.find(l => l.id === locationId) || null
|
||||
setSelectedLocation(location)
|
||||
const handleChainageChange = (chainageId: string) => {
|
||||
const chainage = chainages.find(chn => chn.id === chainageId) || null
|
||||
setSelectedChainage(chainage)
|
||||
}
|
||||
|
||||
const handleProceed = () => {
|
||||
if (selectedProject && selectedPackage && selectedLocation) {
|
||||
if (selectedProject && selectedPackage && selectedChainage) {
|
||||
onSelectionComplete({
|
||||
projectId: selectedProject.id,
|
||||
projectName: selectedProject.name,
|
||||
packageId: selectedPackage.id,
|
||||
packageName: selectedPackage.name,
|
||||
locationId: selectedLocation.id,
|
||||
locationName: selectedLocation.segment_name
|
||||
chainageId: selectedChainage.id,
|
||||
chainageName: selectedChainage.segment_name
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
const isComplete = selectedProject && selectedPackage && selectedLocation
|
||||
const isComplete = selectedProject && selectedPackage && selectedChainage
|
||||
|
||||
// Step status helpers
|
||||
const getStepStatus = (step: number) => {
|
||||
if (step === 1) return selectedProject ? 'completed' : 'active'
|
||||
if (step === 2) return selectedPackage ? 'completed' : selectedProject ? 'active' : 'pending'
|
||||
if (step === 3) return selectedLocation ? 'completed' : selectedPackage ? 'active' : 'pending'
|
||||
if (step === 3) return selectedChainage ? 'completed' : selectedPackage ? 'active' : 'pending'
|
||||
return 'pending'
|
||||
}
|
||||
|
||||
@@ -155,9 +151,9 @@ export function ProjectSelectionSection({ onSelectionComplete }: ProjectSelectio
|
||||
<CardHeader className="pb-6">
|
||||
<div className="flex flex-col gap-6">
|
||||
<div>
|
||||
<CardTitle className="text-2xl font-bold">Select Project Location</CardTitle>
|
||||
<CardTitle className="text-2xl font-bold">Select Project Chainage</CardTitle>
|
||||
<CardDescription className="mt-2 text-base">
|
||||
Select Project, Package & Location to begin intelligent road analysis.
|
||||
Select Project, Package & Chainage to begin intelligent road analysis.
|
||||
</CardDescription>
|
||||
</div>
|
||||
|
||||
@@ -165,7 +161,7 @@ export function ProjectSelectionSection({ onSelectionComplete }: ProjectSelectio
|
||||
<div className="flex items-center justify-center pt-2">
|
||||
{[1, 2, 3].map((step, index) => {
|
||||
const status = getStepStatus(step)
|
||||
const labels = ['Project', 'Package', 'Location']
|
||||
const labels = ['Project', 'Package', 'Chainage']
|
||||
return (
|
||||
<div key={step} className="flex items-center">
|
||||
<div className="flex flex-col items-center">
|
||||
@@ -268,30 +264,35 @@ export function ProjectSelectionSection({ onSelectionComplete }: ProjectSelectio
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
{/* Location Dropdown */}
|
||||
{/* Chainage Dropdown */}
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="location" className="text-sm font-semibold">
|
||||
Location
|
||||
<Label htmlFor="chainage" className="text-sm font-semibold">
|
||||
Chainage
|
||||
</Label>
|
||||
<Select
|
||||
value={selectedLocation?.id || ""}
|
||||
onValueChange={handleLocationChange}
|
||||
disabled={!selectedPackage || loadingLocations}
|
||||
value={selectedChainage?.id || ""}
|
||||
onValueChange={handleChainageChange}
|
||||
disabled={!selectedPackage || loadingChainages}
|
||||
>
|
||||
<SelectTrigger id="location" className="h-11">
|
||||
{loadingLocations ? (
|
||||
<SelectTrigger id="chainage" className="h-11">
|
||||
{loadingChainages ? (
|
||||
<div className="flex items-center gap-2">
|
||||
<Loader2 className="h-4 w-4 animate-spin" />
|
||||
<span>Loading...</span>
|
||||
</div>
|
||||
) : (
|
||||
<SelectValue placeholder={selectedPackage ? "Select location" : "Select package first"} />
|
||||
<SelectValue placeholder={selectedPackage ? "Select chainage" : "Select package first"} />
|
||||
)}
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{locations.map((location) => (
|
||||
<SelectItem key={location.id} value={location.id}>
|
||||
{location.segment_name}
|
||||
{chainages.map((chn) => (
|
||||
<SelectItem key={chn.id} value={chn.id}>
|
||||
<div className="flex flex-col">
|
||||
<span>{chn.segment_name}</span>
|
||||
<span className="text-[10px] text-muted-foreground">
|
||||
{chn.chainage_start_km}-{chn.chainage_end_km} km | {chn.direction}
|
||||
</span>
|
||||
</div>
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
@@ -308,7 +309,7 @@ export function ProjectSelectionSection({ onSelectionComplete }: ProjectSelectio
|
||||
<span>/</span>
|
||||
<span className="text-foreground">{selectedPackage?.name}</span>
|
||||
<span>/</span>
|
||||
<span className="text-foreground">{selectedLocation?.segment_name}</span>
|
||||
<span className="text-foreground">{selectedChainage?.segment_name}</span>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user