setup husky prettier eslint
This commit is contained in:
@@ -1,58 +1,64 @@
|
||||
import axiosClient from "../axios/axios";
|
||||
import {
|
||||
Chainage, ChainageCreate, ChainageUpdate,
|
||||
PaginatedResponse, PaginationParams
|
||||
} from "@/types";
|
||||
import axiosClient from '../axios/axios';
|
||||
import {
|
||||
Chainage,
|
||||
ChainageCreate,
|
||||
ChainageUpdate,
|
||||
PaginatedResponse,
|
||||
PaginationParams,
|
||||
} from '@/types';
|
||||
|
||||
/**
|
||||
* Chainage Service
|
||||
*/
|
||||
export const chainageService = {
|
||||
/**
|
||||
* Fetch all chainages
|
||||
*/
|
||||
getChainages: async (params?: PaginationParams): Promise<PaginatedResponse<Chainage>> => {
|
||||
const skip = params?.skip ?? 0;
|
||||
const limit = params?.limit ?? 100;
|
||||
const response = await axiosClient.get<PaginatedResponse<Chainage>>(`/chainages/`, {
|
||||
params: { skip, limit }
|
||||
});
|
||||
return response.data;
|
||||
},
|
||||
/**
|
||||
* Fetch all chainages
|
||||
*/
|
||||
getChainages: async (params?: PaginationParams): Promise<PaginatedResponse<Chainage>> => {
|
||||
const skip = params?.skip ?? 0;
|
||||
const limit = params?.limit ?? 100;
|
||||
const response = await axiosClient.get<PaginatedResponse<Chainage>>(`/chainages/`, {
|
||||
params: { skip, limit },
|
||||
});
|
||||
return response.data;
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetch chainages filtered by package ID
|
||||
*/
|
||||
getChainagesByPackage: async (packageId: string, params?: PaginationParams): Promise<PaginatedResponse<Chainage>> => {
|
||||
const skip = params?.skip ?? 0;
|
||||
const limit = params?.limit ?? 100;
|
||||
const response = await axiosClient.get<PaginatedResponse<Chainage>>(`/chainages/`, {
|
||||
params: { package_id: packageId, skip, limit }
|
||||
});
|
||||
return response.data;
|
||||
},
|
||||
/**
|
||||
* Fetch chainages filtered by package ID
|
||||
*/
|
||||
getChainagesByPackage: async (
|
||||
packageId: string,
|
||||
params?: PaginationParams,
|
||||
): Promise<PaginatedResponse<Chainage>> => {
|
||||
const skip = params?.skip ?? 0;
|
||||
const limit = params?.limit ?? 100;
|
||||
const response = await axiosClient.get<PaginatedResponse<Chainage>>(`/chainages/`, {
|
||||
params: { package_id: packageId, skip, limit },
|
||||
});
|
||||
return response.data;
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a new chainage
|
||||
*/
|
||||
createChainage: async (data: ChainageCreate): Promise<Chainage> => {
|
||||
const response = await axiosClient.post<Chainage>("/chainages/", data);
|
||||
return response.data;
|
||||
},
|
||||
/**
|
||||
* Create a new chainage
|
||||
*/
|
||||
createChainage: async (data: ChainageCreate): Promise<Chainage> => {
|
||||
const response = await axiosClient.post<Chainage>('/chainages/', data);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
/**
|
||||
* Update an existing chainage
|
||||
*/
|
||||
updateChainage: async (chainageId: string, data: ChainageUpdate): Promise<Chainage> => {
|
||||
const response = await axiosClient.put<Chainage>(`/chainages/${chainageId}`, data);
|
||||
return response.data;
|
||||
},
|
||||
/**
|
||||
* Update an existing chainage
|
||||
*/
|
||||
updateChainage: async (chainageId: string, data: ChainageUpdate): Promise<Chainage> => {
|
||||
const response = await axiosClient.put<Chainage>(`/chainages/${chainageId}`, data);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
/**
|
||||
* Delete a chainage
|
||||
*/
|
||||
deleteChainage: async (chainageId: string): Promise<{ message: string }> => {
|
||||
const response = await axiosClient.delete<{ message: string }>(`/chainages/${chainageId}`);
|
||||
return response.data;
|
||||
}
|
||||
/**
|
||||
* Delete a chainage
|
||||
*/
|
||||
deleteChainage: async (chainageId: string): Promise<{ message: string }> => {
|
||||
const response = await axiosClient.delete<{ message: string }>(`/chainages/${chainageId}`);
|
||||
return response.data;
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,56 +1,56 @@
|
||||
import axiosClient from "../axios/axios";
|
||||
import { Detection } from "@/types";
|
||||
import { projectService } from "./project.service";
|
||||
import axiosClient from '../axios/axios';
|
||||
import { Detection } from '@/types';
|
||||
import { projectService } from './project.service';
|
||||
|
||||
/**
|
||||
* Detection Service
|
||||
*/
|
||||
export const detectionService = {
|
||||
/**
|
||||
* Fetch all detections from completed videos
|
||||
* Uses the summary endpoint to get detections for each project
|
||||
*/
|
||||
getAllDetections: async (): Promise<Detection[]> => {
|
||||
/**
|
||||
* Fetch all detections from completed videos
|
||||
* Uses the summary endpoint to get detections for each project
|
||||
*/
|
||||
getAllDetections: async (): Promise<Detection[]> => {
|
||||
try {
|
||||
// First get all projects
|
||||
const projectsResponse = await projectService.getProjects();
|
||||
const projects = projectsResponse.items;
|
||||
|
||||
// Then fetch detections for each project
|
||||
const allDetections: Detection[] = [];
|
||||
|
||||
for (const project of projects) {
|
||||
try {
|
||||
// First get all projects
|
||||
const projectsResponse = await projectService.getProjects();
|
||||
const projects = projectsResponse.items;
|
||||
const response = await axiosClient.get<{
|
||||
packages: {
|
||||
[key: string]: {
|
||||
chainages: {
|
||||
[key: string]: {
|
||||
detections: Detection[];
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
}>(`/summary/projects/${project.id}`);
|
||||
|
||||
// Then fetch detections for each project
|
||||
const allDetections: Detection[] = []
|
||||
const summary = response.data;
|
||||
|
||||
for (const project of projects) {
|
||||
try {
|
||||
const response = await axiosClient.get<{
|
||||
packages: {
|
||||
[key: string]: {
|
||||
chainages: {
|
||||
[key: string]: {
|
||||
detections: Detection[]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}>(`/summary/projects/${project.id}`);
|
||||
|
||||
const summary = response.data;
|
||||
|
||||
// Extract detections from the nested structure
|
||||
for (const pkg of Object.values(summary.packages || {})) {
|
||||
for (const loc of Object.values(pkg.chainages || {})) {
|
||||
allDetections.push(...(loc.detections || []))
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// Skip projects that fail to load
|
||||
console.warn(`Failed to load detections for project ${project.id}:`, e)
|
||||
}
|
||||
// Extract detections from the nested structure
|
||||
for (const pkg of Object.values(summary.packages || {})) {
|
||||
for (const loc of Object.values(pkg.chainages || {})) {
|
||||
allDetections.push(...(loc.detections || []));
|
||||
}
|
||||
|
||||
return allDetections;
|
||||
}
|
||||
} catch (e) {
|
||||
console.error("Failed to fetch all detections:", e)
|
||||
return []
|
||||
// Skip projects that fail to load
|
||||
console.warn(`Failed to load detections for project ${project.id}:`, e);
|
||||
}
|
||||
}
|
||||
|
||||
return allDetections;
|
||||
} catch (e) {
|
||||
console.error('Failed to fetch all detections:', e);
|
||||
return [];
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
export * from "./project.service";
|
||||
export * from "./package.service";
|
||||
export { chainageService } from "./chainage.service";
|
||||
export * from "./video.service";
|
||||
export * from "./detection.service";
|
||||
export * from "./session.service";
|
||||
export { projectDataService } from "./project.service";
|
||||
export * from './project.service';
|
||||
export * from './package.service';
|
||||
export { chainageService } from './chainage.service';
|
||||
export * from './video.service';
|
||||
export * from './detection.service';
|
||||
export * from './session.service';
|
||||
export { projectDataService } from './project.service';
|
||||
|
||||
@@ -1,58 +1,64 @@
|
||||
import axiosClient from "../axios/axios";
|
||||
import {
|
||||
Package, PackageCreate, PackageUpdate,
|
||||
PaginatedResponse, PaginationParams
|
||||
} from "@/types";
|
||||
import axiosClient from '../axios/axios';
|
||||
import {
|
||||
Package,
|
||||
PackageCreate,
|
||||
PackageUpdate,
|
||||
PaginatedResponse,
|
||||
PaginationParams,
|
||||
} from '@/types';
|
||||
|
||||
/**
|
||||
* Package Service
|
||||
*/
|
||||
export const packageService = {
|
||||
/**
|
||||
* Fetch all packages
|
||||
*/
|
||||
getPackages: async (params?: PaginationParams): Promise<PaginatedResponse<Package>> => {
|
||||
const skip = params?.skip ?? 0;
|
||||
const limit = params?.limit ?? 100;
|
||||
const response = await axiosClient.get<PaginatedResponse<Package>>(`/packages/`, {
|
||||
params: { skip, limit }
|
||||
});
|
||||
return response.data;
|
||||
},
|
||||
/**
|
||||
* Fetch all packages
|
||||
*/
|
||||
getPackages: async (params?: PaginationParams): Promise<PaginatedResponse<Package>> => {
|
||||
const skip = params?.skip ?? 0;
|
||||
const limit = params?.limit ?? 100;
|
||||
const response = await axiosClient.get<PaginatedResponse<Package>>(`/packages/`, {
|
||||
params: { skip, limit },
|
||||
});
|
||||
return response.data;
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetch packages filtered by project ID
|
||||
*/
|
||||
getPackagesByProject: async (projectId: string, params?: PaginationParams): Promise<PaginatedResponse<Package>> => {
|
||||
const skip = params?.skip ?? 0;
|
||||
const limit = params?.limit ?? 100;
|
||||
const response = await axiosClient.get<PaginatedResponse<Package>>(`/packages/`, {
|
||||
params: { project_id: projectId, skip, limit }
|
||||
});
|
||||
return response.data;
|
||||
},
|
||||
/**
|
||||
* Fetch packages filtered by project ID
|
||||
*/
|
||||
getPackagesByProject: async (
|
||||
projectId: string,
|
||||
params?: PaginationParams,
|
||||
): Promise<PaginatedResponse<Package>> => {
|
||||
const skip = params?.skip ?? 0;
|
||||
const limit = params?.limit ?? 100;
|
||||
const response = await axiosClient.get<PaginatedResponse<Package>>(`/packages/`, {
|
||||
params: { project_id: projectId, skip, limit },
|
||||
});
|
||||
return response.data;
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a new package
|
||||
*/
|
||||
createPackage: async (data: PackageCreate): Promise<Package> => {
|
||||
const response = await axiosClient.post<Package>("/packages/", data);
|
||||
return response.data;
|
||||
},
|
||||
/**
|
||||
* Create a new package
|
||||
*/
|
||||
createPackage: async (data: PackageCreate): Promise<Package> => {
|
||||
const response = await axiosClient.post<Package>('/packages/', data);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
/**
|
||||
* Update an existing package
|
||||
*/
|
||||
updatePackage: async (packageId: string, data: PackageUpdate): Promise<Package> => {
|
||||
const response = await axiosClient.put<Package>(`/packages/${packageId}`, data);
|
||||
return response.data;
|
||||
},
|
||||
/**
|
||||
* Update an existing package
|
||||
*/
|
||||
updatePackage: async (packageId: string, data: PackageUpdate): Promise<Package> => {
|
||||
const response = await axiosClient.put<Package>(`/packages/${packageId}`, data);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
/**
|
||||
* Delete a package
|
||||
*/
|
||||
deletePackage: async (packageId: string): Promise<{ message: string }> => {
|
||||
const response = await axiosClient.delete<{ message: string }>(`/packages/${packageId}`);
|
||||
return response.data;
|
||||
}
|
||||
/**
|
||||
* Delete a package
|
||||
*/
|
||||
deletePackage: async (packageId: string): Promise<{ message: string }> => {
|
||||
const response = await axiosClient.delete<{ message: string }>(`/packages/${packageId}`);
|
||||
return response.data;
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,66 +1,69 @@
|
||||
import axiosClient from "../axios/axios";
|
||||
import {
|
||||
Project, ProjectCreate, ProjectUpdate,
|
||||
PaginatedResponse, PaginationParams
|
||||
} from "@/types";
|
||||
import axiosClient from '../axios/axios';
|
||||
import {
|
||||
Project,
|
||||
ProjectCreate,
|
||||
ProjectUpdate,
|
||||
PaginatedResponse,
|
||||
PaginationParams,
|
||||
} from '@/types';
|
||||
|
||||
/**
|
||||
* Project Service
|
||||
*/
|
||||
export const projectService = {
|
||||
/**
|
||||
* Fetch all projects
|
||||
*/
|
||||
getProjects: async (params?: PaginationParams): Promise<PaginatedResponse<Project>> => {
|
||||
const skip = params?.skip ?? 0;
|
||||
const limit = params?.limit ?? 100;
|
||||
const response = await axiosClient.get<PaginatedResponse<Project>>(`/projects/`, {
|
||||
params: { skip, limit }
|
||||
});
|
||||
return response.data;
|
||||
},
|
||||
/**
|
||||
* Fetch all projects
|
||||
*/
|
||||
getProjects: async (params?: PaginationParams): Promise<PaginatedResponse<Project>> => {
|
||||
const skip = params?.skip ?? 0;
|
||||
const limit = params?.limit ?? 100;
|
||||
const response = await axiosClient.get<PaginatedResponse<Project>>(`/projects/`, {
|
||||
params: { skip, limit },
|
||||
});
|
||||
return response.data;
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a new project
|
||||
*/
|
||||
createProject: async (data: ProjectCreate): Promise<Project> => {
|
||||
const response = await axiosClient.post<Project>("/projects/", data);
|
||||
return response.data;
|
||||
},
|
||||
/**
|
||||
* Create a new project
|
||||
*/
|
||||
createProject: async (data: ProjectCreate): Promise<Project> => {
|
||||
const response = await axiosClient.post<Project>('/projects/', data);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
/**
|
||||
* Update an existing project
|
||||
*/
|
||||
updateProject: async (projectId: string, data: ProjectUpdate): Promise<Project> => {
|
||||
const response = await axiosClient.put<Project>(`/projects/${projectId}`, data);
|
||||
return response.data;
|
||||
},
|
||||
/**
|
||||
* Update an existing project
|
||||
*/
|
||||
updateProject: async (projectId: string, data: ProjectUpdate): Promise<Project> => {
|
||||
const response = await axiosClient.put<Project>(`/projects/${projectId}`, data);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
/**
|
||||
* Delete a project
|
||||
*/
|
||||
deleteProject: async (projectId: string): Promise<{ message: string }> => {
|
||||
const response = await axiosClient.delete<{ message: string }>(`/projects/${projectId}`);
|
||||
return response.data;
|
||||
},
|
||||
/**
|
||||
* Delete a project
|
||||
*/
|
||||
deleteProject: async (projectId: string): Promise<{ message: string }> => {
|
||||
const response = await axiosClient.delete<{ message: string }>(`/projects/${projectId}`);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetch project summary (detections across packages and chainages)
|
||||
*/
|
||||
getProjectSummary: async (projectId: string): Promise<any> => {
|
||||
const response = await axiosClient.get(`/summary/projects/${projectId}`);
|
||||
return response.data;
|
||||
},
|
||||
/**
|
||||
* Fetch project summary (detections across packages and chainages)
|
||||
*/
|
||||
getProjectSummary: async (projectId: string): Promise<any> => {
|
||||
const response = await axiosClient.get(`/summary/projects/${projectId}`);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
/**
|
||||
* Fetch project summary filtered by video ID
|
||||
*/
|
||||
getProjectSummaryByVideo: async (projectId: string, videoId: string): Promise<any> => {
|
||||
const response = await axiosClient.get(`/summary/projects/${projectId}`, {
|
||||
params: { video_id: videoId }
|
||||
});
|
||||
return response.data;
|
||||
}
|
||||
/**
|
||||
* Fetch project summary filtered by video ID
|
||||
*/
|
||||
getProjectSummaryByVideo: async (projectId: string, videoId: string): Promise<any> => {
|
||||
const response = await axiosClient.get(`/summary/projects/${projectId}`, {
|
||||
params: { video_id: videoId },
|
||||
});
|
||||
return response.data;
|
||||
},
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -68,33 +71,35 @@ export const projectService = {
|
||||
* Moved from legacy project-service.ts
|
||||
*/
|
||||
export const projectDataService = {
|
||||
/**
|
||||
* Extracts all detections from a project summary, optionally filtered by package and chainage
|
||||
*/
|
||||
extractDetections(
|
||||
projectSummary: any,
|
||||
selectedPackageId?: string | null,
|
||||
selectedChainageId?: string | null
|
||||
): any[] {
|
||||
if (!projectSummary) return []
|
||||
/**
|
||||
* Extracts all detections from a project summary, optionally filtered by package and chainage
|
||||
*/
|
||||
extractDetections(
|
||||
projectSummary: any,
|
||||
selectedPackageId?: string | null,
|
||||
selectedChainageId?: string | null,
|
||||
): any[] {
|
||||
if (!projectSummary) return [];
|
||||
|
||||
const detections: any[] = []
|
||||
const packagesToProcess = selectedPackageId && selectedPackageId !== "all"
|
||||
? { [selectedPackageId]: projectSummary.packages[selectedPackageId] }
|
||||
: projectSummary.packages || {}
|
||||
const detections: any[] = [];
|
||||
const packagesToProcess =
|
||||
selectedPackageId && selectedPackageId !== 'all'
|
||||
? { [selectedPackageId]: projectSummary.packages[selectedPackageId] }
|
||||
: projectSummary.packages || {};
|
||||
|
||||
for (const [pkgName, pkg] of Object.entries(packagesToProcess)) {
|
||||
const chainagesToProcess = selectedChainageId && selectedChainageId !== "all"
|
||||
? { [selectedChainageId]: (pkg as any).chainages[selectedChainageId] }
|
||||
: (pkg as any).chainages || {}
|
||||
for (const [pkgName, pkg] of Object.entries(packagesToProcess)) {
|
||||
const chainagesToProcess =
|
||||
selectedChainageId && selectedChainageId !== 'all'
|
||||
? { [selectedChainageId]: (pkg as any).chainages[selectedChainageId] }
|
||||
: (pkg as any).chainages || {};
|
||||
|
||||
for (const [chnName, chn] of Object.entries(chainagesToProcess)) {
|
||||
if (!chn) continue
|
||||
const chainageDetections = (chn as any).detections || []
|
||||
detections.push(...chainageDetections)
|
||||
}
|
||||
}
|
||||
|
||||
return detections
|
||||
for (const [chnName, chn] of Object.entries(chainagesToProcess)) {
|
||||
if (!chn) continue;
|
||||
const chainageDetections = (chn as any).detections || [];
|
||||
detections.push(...chainageDetections);
|
||||
}
|
||||
}
|
||||
|
||||
return detections;
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,73 +1,73 @@
|
||||
import { SessionContext, VideoResultData, emptySessionContext } from "@/types";
|
||||
import { SessionContext, VideoResultData, emptySessionContext } from '@/types';
|
||||
|
||||
// Session Storage Keys
|
||||
const SESSION_KEY = "visionroad_session";
|
||||
const VIDEO_DATA_KEY = "visionroad_video_data";
|
||||
const DETECTION_TYPE_KEY = "visionroad_detection_type";
|
||||
const SESSION_KEY = 'visionroad_session';
|
||||
const VIDEO_DATA_KEY = 'visionroad_video_data';
|
||||
const DETECTION_TYPE_KEY = 'visionroad_detection_type';
|
||||
|
||||
/**
|
||||
* Session Service
|
||||
*/
|
||||
export const sessionService = {
|
||||
/**
|
||||
* Save session to localStorage
|
||||
*/
|
||||
saveSession: (session: SessionContext): void => {
|
||||
if (typeof window !== "undefined") {
|
||||
localStorage.setItem(SESSION_KEY, JSON.stringify(session))
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Load session from localStorage
|
||||
*/
|
||||
loadSession: (): SessionContext => {
|
||||
if (typeof window !== "undefined") {
|
||||
const stored = localStorage.getItem(SESSION_KEY)
|
||||
if (stored) {
|
||||
return JSON.parse(stored)
|
||||
}
|
||||
}
|
||||
return emptySessionContext;
|
||||
},
|
||||
|
||||
/**
|
||||
* Clear all session data
|
||||
*/
|
||||
clearSession: (): void => {
|
||||
if (typeof window !== "undefined") {
|
||||
localStorage.removeItem(SESSION_KEY)
|
||||
localStorage.removeItem(VIDEO_DATA_KEY)
|
||||
localStorage.removeItem(DETECTION_TYPE_KEY)
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Save video result data
|
||||
*/
|
||||
saveVideoData: (data: VideoResultData): void => {
|
||||
if (typeof window !== "undefined") {
|
||||
localStorage.setItem(VIDEO_DATA_KEY, JSON.stringify(data))
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Load video result data
|
||||
*/
|
||||
loadVideoData: (): VideoResultData | null => {
|
||||
if (typeof window !== "undefined") {
|
||||
const stored = localStorage.getItem(VIDEO_DATA_KEY)
|
||||
if (stored) {
|
||||
return JSON.parse(stored)
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if session is complete
|
||||
*/
|
||||
isSessionValid: (session: SessionContext): boolean => {
|
||||
return !!(session.projectId && session.packageId && session.chainageId)
|
||||
/**
|
||||
* Save session to localStorage
|
||||
*/
|
||||
saveSession: (session: SessionContext): void => {
|
||||
if (typeof window !== 'undefined') {
|
||||
localStorage.setItem(SESSION_KEY, JSON.stringify(session));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Load session from localStorage
|
||||
*/
|
||||
loadSession: (): SessionContext => {
|
||||
if (typeof window !== 'undefined') {
|
||||
const stored = localStorage.getItem(SESSION_KEY);
|
||||
if (stored) {
|
||||
return JSON.parse(stored);
|
||||
}
|
||||
}
|
||||
return emptySessionContext;
|
||||
},
|
||||
|
||||
/**
|
||||
* Clear all session data
|
||||
*/
|
||||
clearSession: (): void => {
|
||||
if (typeof window !== 'undefined') {
|
||||
localStorage.removeItem(SESSION_KEY);
|
||||
localStorage.removeItem(VIDEO_DATA_KEY);
|
||||
localStorage.removeItem(DETECTION_TYPE_KEY);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Save video result data
|
||||
*/
|
||||
saveVideoData: (data: VideoResultData): void => {
|
||||
if (typeof window !== 'undefined') {
|
||||
localStorage.setItem(VIDEO_DATA_KEY, JSON.stringify(data));
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Load video result data
|
||||
*/
|
||||
loadVideoData: (): VideoResultData | null => {
|
||||
if (typeof window !== 'undefined') {
|
||||
const stored = localStorage.getItem(VIDEO_DATA_KEY);
|
||||
if (stored) {
|
||||
return JSON.parse(stored);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
/**
|
||||
* Check if session is complete
|
||||
*/
|
||||
isSessionValid: (session: SessionContext): boolean => {
|
||||
return !!(session.projectId && session.packageId && session.chainageId);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,79 +1,79 @@
|
||||
import axiosClient from "../axios/axios";
|
||||
import { Video, PaginationParams } from "@/types";
|
||||
import axiosClient from '../axios/axios';
|
||||
import { Video, PaginationParams } from '@/types';
|
||||
|
||||
/**
|
||||
* Video Service
|
||||
*/
|
||||
export const videoService = {
|
||||
/**
|
||||
* Fetch all videos and transform them to match the Video interface
|
||||
*/
|
||||
getVideos: async (params?: PaginationParams): Promise<Video[]> => {
|
||||
const skip = params?.skip ?? 0;
|
||||
const limit = params?.limit ?? 100;
|
||||
|
||||
const response = await axiosClient.get<{
|
||||
videos: Array<{
|
||||
video_id: string;
|
||||
status: string;
|
||||
progress: number;
|
||||
summary?: {
|
||||
unique_defected_sign_board?: number;
|
||||
unique_pothole?: number;
|
||||
unique_road_crack?: number;
|
||||
unique_damaged_road_marking?: number;
|
||||
unique_good_sign_board?: number;
|
||||
total_road_damage?: number;
|
||||
total_detections?: number;
|
||||
};
|
||||
}>;
|
||||
}>(`/videos`, {
|
||||
params: { skip, limit }
|
||||
});
|
||||
/**
|
||||
* Fetch all videos and transform them to match the Video interface
|
||||
*/
|
||||
getVideos: async (params?: PaginationParams): Promise<Video[]> => {
|
||||
const skip = params?.skip ?? 0;
|
||||
const limit = params?.limit ?? 100;
|
||||
|
||||
// Transform the response to match our Video interface
|
||||
return response.data.videos.map(v => ({
|
||||
id: v.video_id,
|
||||
filename: v.video_id,
|
||||
detection_type: "pot-sign-detection" as const,
|
||||
status: v.status as Video["status"],
|
||||
unique_defected_sign_board: v.summary?.unique_defected_sign_board,
|
||||
unique_pothole: v.summary?.unique_pothole,
|
||||
unique_road_crack: v.summary?.unique_road_crack,
|
||||
unique_damaged_road_marking: v.summary?.unique_damaged_road_marking,
|
||||
unique_good_sign_board: v.summary?.unique_good_sign_board,
|
||||
total_road_damage: v.summary?.total_road_damage,
|
||||
total_detections: v.summary?.total_detections,
|
||||
created_at: new Date().toISOString(),
|
||||
updated_at: new Date().toISOString()
|
||||
}));
|
||||
},
|
||||
const response = await axiosClient.get<{
|
||||
videos: Array<{
|
||||
video_id: string;
|
||||
status: string;
|
||||
progress: number;
|
||||
summary?: {
|
||||
unique_defected_sign_board?: number;
|
||||
unique_pothole?: number;
|
||||
unique_road_crack?: number;
|
||||
unique_damaged_road_marking?: number;
|
||||
unique_good_sign_board?: number;
|
||||
total_road_damage?: number;
|
||||
total_detections?: number;
|
||||
};
|
||||
}>;
|
||||
}>(`/videos`, {
|
||||
params: { skip, limit },
|
||||
});
|
||||
|
||||
/**
|
||||
* Upload a video for processing
|
||||
*/
|
||||
uploadVideo: async (formData: FormData): Promise<any> => {
|
||||
const response = await axiosClient.post("/upload", formData, {
|
||||
headers: {
|
||||
"Content-Type": "multipart/form-data"
|
||||
}
|
||||
});
|
||||
return response.data;
|
||||
},
|
||||
// Transform the response to match our Video interface
|
||||
return response.data.videos.map((v) => ({
|
||||
id: v.video_id,
|
||||
filename: v.video_id,
|
||||
detection_type: 'pot-sign-detection' as const,
|
||||
status: v.status as Video['status'],
|
||||
unique_defected_sign_board: v.summary?.unique_defected_sign_board,
|
||||
unique_pothole: v.summary?.unique_pothole,
|
||||
unique_road_crack: v.summary?.unique_road_crack,
|
||||
unique_damaged_road_marking: v.summary?.unique_damaged_road_marking,
|
||||
unique_good_sign_board: v.summary?.unique_good_sign_board,
|
||||
total_road_damage: v.summary?.total_road_damage,
|
||||
total_detections: v.summary?.total_detections,
|
||||
created_at: new Date().toISOString(),
|
||||
updated_at: new Date().toISOString(),
|
||||
}));
|
||||
},
|
||||
|
||||
/**
|
||||
* Get processing status of a video
|
||||
*/
|
||||
getVideoStatus: async (videoId: string): Promise<any> => {
|
||||
const response = await axiosClient.get(`/status/${videoId}`);
|
||||
return response.data;
|
||||
},
|
||||
/**
|
||||
* Upload a video for processing
|
||||
*/
|
||||
uploadVideo: async (formData: FormData): Promise<any> => {
|
||||
const response = await axiosClient.post('/upload', formData, {
|
||||
headers: {
|
||||
'Content-Type': 'multipart/form-data',
|
||||
},
|
||||
});
|
||||
return response.data;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get analysis results for a video
|
||||
*/
|
||||
getVideoResults: async (videoId: string): Promise<any> => {
|
||||
const response = await axiosClient.get(`/results/${videoId}`);
|
||||
return response.data;
|
||||
}
|
||||
/**
|
||||
* Get processing status of a video
|
||||
*/
|
||||
getVideoStatus: async (videoId: string): Promise<any> => {
|
||||
const response = await axiosClient.get(`/status/${videoId}`);
|
||||
return response.data;
|
||||
},
|
||||
|
||||
/**
|
||||
* Get analysis results for a video
|
||||
*/
|
||||
getVideoResults: async (videoId: string): Promise<any> => {
|
||||
const response = await axiosClient.get(`/results/${videoId}`);
|
||||
return response.data;
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ENV_CONSTANT } from "@/constants/secrect.constant";
|
||||
import axios from "axios";
|
||||
import { ENV_CONSTANT } from '@/constants/secrect.constant';
|
||||
import axios from 'axios';
|
||||
|
||||
const BASE_URL = ENV_CONSTANT.BASE_API_URL;
|
||||
|
||||
@@ -7,24 +7,24 @@ const axiosClient = axios.create({
|
||||
baseURL: BASE_URL,
|
||||
headers: {
|
||||
// "Content-Type": "application/json",
|
||||
"ngrok-skip-browser-warning": "true"
|
||||
'ngrok-skip-browser-warning': 'true',
|
||||
},
|
||||
});
|
||||
|
||||
// Add request interceptor to inject access token
|
||||
axiosClient.interceptors.request.use(
|
||||
(config) => {
|
||||
if (typeof window !== "undefined") {
|
||||
const token = localStorage.getItem("token");
|
||||
if (typeof window !== 'undefined') {
|
||||
const token = localStorage.getItem('token');
|
||||
if (token && config.headers) {
|
||||
config.headers["Authorization"] = `Bearer ${token}`;
|
||||
config.headers['Authorization'] = `Bearer ${token}`;
|
||||
}
|
||||
}
|
||||
return config;
|
||||
},
|
||||
(error) => {
|
||||
return Promise.reject(error);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
// Basic response interceptor
|
||||
@@ -33,12 +33,12 @@ axiosClient.interceptors.response.use(
|
||||
(error) => {
|
||||
// Standard error handling can be added here later
|
||||
return Promise.reject(error);
|
||||
}
|
||||
},
|
||||
);
|
||||
|
||||
export const axiosAuth = axios.create({
|
||||
baseURL: BASE_URL,
|
||||
headers: { "Content-Type": "application/json" },
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
});
|
||||
|
||||
export default axiosClient;
|
||||
|
||||
Reference in New Issue
Block a user