feat(api): restructure api with axios and chainage related changes

This commit is contained in:
2026-03-18 18:42:40 +05:30
parent 7f8854ed78
commit 598098d7e8
31 changed files with 933 additions and 931 deletions

View File

@@ -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>
)}