mirror of
https://github.com/Sea-Haven-Industries/proposal-system.git
synced 2026-10-05 07:12:01 +00:00
113 lines
3 KiB
TypeScript
113 lines
3 KiB
TypeScript
|
|
import apiClient from './client';
|
||
|
|
|
||
|
|
export interface CreateProposalRequest {
|
||
|
|
workOrderNumber: string;
|
||
|
|
customerName: string;
|
||
|
|
customerAddress: string;
|
||
|
|
scopeOfWork: string;
|
||
|
|
serviceCategory: string;
|
||
|
|
priority: string;
|
||
|
|
notes?: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface ProposalListItem {
|
||
|
|
id: string;
|
||
|
|
proposalNumber: string;
|
||
|
|
customerName: string;
|
||
|
|
workOrderNumber: string;
|
||
|
|
serviceCategory: string;
|
||
|
|
priority: string;
|
||
|
|
status: string;
|
||
|
|
totalBidAmount: number;
|
||
|
|
submittedAt: string;
|
||
|
|
submittedByName: string | null;
|
||
|
|
assignedAdminName: string | null;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface ProposalDetail {
|
||
|
|
id: string;
|
||
|
|
proposalNumber: string;
|
||
|
|
workOrderNumber: string;
|
||
|
|
customerName: string;
|
||
|
|
customerAddress: string;
|
||
|
|
scopeOfWork: string;
|
||
|
|
refinedScope: string | null;
|
||
|
|
serviceCategory: string;
|
||
|
|
priority: string;
|
||
|
|
status: string;
|
||
|
|
totalBidAmount: number;
|
||
|
|
vendorTotalCost: number | null;
|
||
|
|
notes: string;
|
||
|
|
submittedById: string;
|
||
|
|
submittedByName: string | null;
|
||
|
|
submittedAt: string;
|
||
|
|
assignedAdminId: string | null;
|
||
|
|
approvedById: string | null;
|
||
|
|
approvedAt: string | null;
|
||
|
|
sentAt: string | null;
|
||
|
|
currentRevision: number;
|
||
|
|
parentProposalId: string | null;
|
||
|
|
createdAt: string;
|
||
|
|
updatedAt: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface PagedResponse<T> {
|
||
|
|
items: T[];
|
||
|
|
totalCount: number;
|
||
|
|
page: number;
|
||
|
|
pageSize: number;
|
||
|
|
}
|
||
|
|
|
||
|
|
export interface ProposalFilters {
|
||
|
|
search?: string;
|
||
|
|
page?: number;
|
||
|
|
pageSize?: number;
|
||
|
|
status?: string;
|
||
|
|
serviceCategory?: string;
|
||
|
|
priority?: string;
|
||
|
|
fromDate?: string;
|
||
|
|
toDate?: string;
|
||
|
|
}
|
||
|
|
|
||
|
|
export const proposalsApi = {
|
||
|
|
create: async (data: CreateProposalRequest): Promise<ProposalDetail> => {
|
||
|
|
const res = await apiClient.post('/proposals', data);
|
||
|
|
return res.data;
|
||
|
|
},
|
||
|
|
|
||
|
|
getAll: async (filters: ProposalFilters = {}): Promise<PagedResponse<ProposalListItem>> => {
|
||
|
|
const params = new URLSearchParams();
|
||
|
|
if (filters.search) params.append('search', filters.search);
|
||
|
|
if (filters.page) params.append('page', String(filters.page));
|
||
|
|
if (filters.pageSize) params.append('pageSize', String(filters.pageSize));
|
||
|
|
if (filters.status) params.append('status', filters.status);
|
||
|
|
if (filters.serviceCategory) params.append('serviceCategory', filters.serviceCategory);
|
||
|
|
if (filters.priority) params.append('priority', filters.priority);
|
||
|
|
|
||
|
|
const res = await apiClient.get(`/proposals?${params.toString()}`);
|
||
|
|
return res.data;
|
||
|
|
},
|
||
|
|
|
||
|
|
getById: async (id: string): Promise<ProposalDetail> => {
|
||
|
|
const res = await apiClient.get(`/proposals/${id}`);
|
||
|
|
return res.data;
|
||
|
|
},
|
||
|
|
|
||
|
|
uploadAttachment: async (proposalId: string, fileName: string): Promise<{ uploadUrl: string; s3Key: string }> => {
|
||
|
|
const res = await apiClient.post(`/proposals/${proposalId}/attachments?fileName=${encodeURIComponent(fileName)}`);
|
||
|
|
return res.data;
|
||
|
|
},
|
||
|
|
|
||
|
|
getStats: async (): Promise<ProposalStats> => {
|
||
|
|
const res = await apiClient.get('/proposals/stats');
|
||
|
|
return res.data;
|
||
|
|
},
|
||
|
|
};
|
||
|
|
|
||
|
|
export interface ProposalStats {
|
||
|
|
totalCount: number;
|
||
|
|
inReviewCount: number;
|
||
|
|
approvedCount: number;
|
||
|
|
sentCount: number;
|
||
|
|
}
|