import axios from "axios"; import type { Account, AcctSummary, ApprovalQueue, Attendance, AuditLog, ClientContact, Company, Contract, ContractFile, Dashboard, Department, IncentiveConfig, LeaveBalance, LeaveRequest, Me, Member, MyIncentive, NavItem, Notification, OvertimeRequest, PaymentSplit, PaymentStage, Product, Project, ProjectMember, ProjectTask, Settlement, SimResult, TaxRecord, Timesheet, Transaction, UserIncentive, Version, WorkPolicy, WorkStatusEvent, WorkStatusKind, } from "@/types"; export const api = axios.create({ baseURL: "/api", headers: { "Content-Type": "application/json" }, }); // In dev, ?as=user can be appended to simulate a non-admin (see backend auth). const asParam = new URLSearchParams(window.location.search).get("as"); if (asParam === "user") api.defaults.params = { as: "user" }; /* ---- identity / nav ---- */ export const getMe = () => api.get("/me").then((r) => r.data); export const getNav = () => api.get("/me/nav").then((r) => r.data); export const getDashboard = () => api.get("/dashboard").then((r) => r.data); /* ---- inbox / notifications ---- */ export const getNotifications = (unread?: boolean) => api.get("/notifications", { params: { unread } }).then((r) => r.data); export const getUnreadCount = () => api.get<{ count: number }>("/notifications/unread-count").then((r) => r.data.count); export const markNotificationRead = (id: string) => api.post(`/notifications/${id}/read`).then((r) => r.data); export const markAllNotificationsRead = () => api.post("/notifications/read-all").then((r) => r.data); /* ---- profile photo ---- */ export const uploadAvatar = (file: File) => { const form = new FormData(); form.append("file", file); return api.post("/me/avatar", form, { headers: { "Content-Type": "multipart/form-data" } }).then((r) => r.data); }; // Avatar image URL (cache-busted by avatarKey). Empty avatarKey → no image. export const avatarUrl = (memberId?: string, avatarKey?: string) => memberId && avatarKey ? `/api/members/${memberId}/avatar?v=${encodeURIComponent(avatarKey)}` : ""; /* ---- members / org ---- */ export const getMembers = () => api.get("/members").then((r) => r.data); export const getMember = (id: string) => api.get(`/members/${id}`).then((r) => r.data); export const createMember = (b: Partial) => api.post("/members", b).then((r) => r.data); export const updateMember = (id: string, b: Partial) => api.patch(`/members/${id}`, b).then((r) => r.data); export const deleteMember = (id: string) => api.delete(`/members/${id}`).then((r) => r.data); export const getDepartments = () => api.get("/departments").then((r) => r.data); export const createDepartment = (b: Partial) => api.post("/departments", b).then((r) => r.data); export const updateDepartment = (id: string, b: Partial) => api.patch(`/departments/${id}`, b).then((r) => r.data); export const deleteDepartment = (id: string) => api.delete(`/departments/${id}`).then((r) => r.data); export const getAudit = () => api.get("/audit").then((r) => r.data); /* ---- attendance ---- */ export const getAttendance = (params: { month?: string; email?: string }) => api.get("/attendance", { params }).then((r) => r.data); export const punch = () => api.post("/attendance/punch").then((r) => r.data); export const setWorkStatus = (status: WorkStatusKind, note?: string) => api.post("/attendance/status", { status, note }).then((r) => r.data); export const getWorkStatusLog = (params?: { email?: string; date?: string }) => api.get("/attendance/status", { params }).then((r) => r.data); export const getLeaveBalance = (params?: { year?: number; email?: string }) => api.get("/leave/balance", { params }).then((r) => r.data); export const getTimesheet = (params: { year?: number; month?: number; email?: string }) => api.get("/attendance/timesheet", { params }).then((r) => r.data); export const getLeave = (params?: { status?: string; email?: string }) => api.get("/leave", { params }).then((r) => r.data); export const createLeave = (b: Partial) => api.post("/leave", b).then((r) => r.data); export const decideLeave = (id: string, approve: boolean, memo?: string) => api.post(`/leave/${id}/decide`, { approve, memo }).then((r) => r.data); export const cancelLeave = (id: string) => api.post(`/leave/${id}/cancel`).then((r) => r.data); export const getOvertime = (params?: { email?: string }) => api.get("/overtime", { params }).then((r) => r.data); export const createOvertime = (b: Partial) => api.post("/overtime", b).then((r) => r.data); export const decideOvertime = (id: string, approve: boolean, memo?: string) => api.post(`/overtime/${id}/decide`, { approve, memo }).then((r) => r.data); export const getWorkPolicy = () => api.get("/work-policy").then((r) => r.data); export const putWorkPolicy = (b: Partial) => api.put("/work-policy", b).then((r) => r.data); export const getApprovals = () => api.get("/approvals").then((r) => r.data); /* ---- projects ---- */ export const getCompanies = () => api.get("/companies").then((r) => r.data); export const createCompany = (b: Partial) => api.post("/companies", b).then((r) => r.data); export const getProducts = (companyId?: string) => api.get("/products", { params: { companyId } }).then((r) => r.data); export const createProduct = (b: Partial) => api.post("/products", b).then((r) => r.data); export const getVersions = (productId?: string) => api.get("/versions", { params: { productId } }).then((r) => r.data); export const createVersion = (b: Partial) => api.post("/versions", b).then((r) => r.data); export const getProjects = (params?: { companyId?: string; status?: string; scope?: "mine" }) => api.get("/projects", { params }).then((r) => r.data); export const getProject = (id: string) => api.get(`/projects/${id}`).then((r) => r.data); export const createProject = (b: Partial) => api.post("/projects", b).then((r) => r.data); export const updateProject = (id: string, b: Partial) => api.patch(`/projects/${id}`, b).then((r) => r.data); export const deleteProject = (id: string) => api.delete(`/projects/${id}`).then((r) => r.data); export const getProjectMembers = (id: string) => api.get(`/projects/${id}/members`).then((r) => r.data); export const upsertProjectMember = (id: string, b: Partial) => api.post(`/projects/${id}/members`, b).then((r) => r.data); export const deleteProjectMember = (pmId: string) => api.delete(`/project-members/${pmId}`).then((r) => r.data); export const getContacts = (id: string) => api.get(`/projects/${id}/contacts`).then((r) => r.data); export const upsertContact = (id: string, b: Partial) => api.post(`/projects/${id}/contacts`, b).then((r) => r.data); export const deleteContact = (cId: string) => api.delete(`/contacts/${cId}`).then((r) => r.data); export const getTasks = (id: string) => api.get(`/projects/${id}/tasks`).then((r) => r.data); export const createTask = (id: string, b: Partial) => api.post(`/projects/${id}/tasks`, b).then((r) => r.data); export const updateTask = (tId: string, b: Partial) => api.patch(`/tasks/${tId}`, b).then((r) => r.data); export const deleteTask = (tId: string) => api.delete(`/tasks/${tId}`).then((r) => r.data); /* ---- contract (admin) ---- */ export const getContract = (id: string) => api.get(`/projects/${id}/contract`).then((r) => r.data); export const putContract = (id: string, b: Partial) => api.put(`/projects/${id}/contract`, b).then((r) => r.data); export const getContractFiles = (id: string) => api.get(`/projects/${id}/files`).then((r) => r.data); export const uploadContractFile = (id: string, file: File, kind = "contract") => { const form = new FormData(); form.append("file", file); form.append("kind", kind); return api .post(`/projects/${id}/files`, form, { headers: { "Content-Type": "multipart/form-data" } }) .then((r) => r.data); }; export const getFileDownloadUrl = (fId: string) => api.get<{ url: string }>(`/files/${fId}/download`).then((r) => r.data.url); export const deleteContractFile = (fId: string) => api.delete(`/files/${fId}`).then((r) => r.data); export const getPayments = (id: string) => api.get(`/projects/${id}/payments`).then((r) => r.data); export const createPayment = (id: string, b: Partial) => api.post(`/projects/${id}/payments`, b).then((r) => r.data); export const updatePayment = (payId: string, b: Partial) => api.patch(`/payments/${payId}`, b).then((r) => r.data); export const deletePayment = (payId: string) => api.delete(`/payments/${payId}`).then((r) => r.data); /* ---- incentive ---- */ export const getIncentiveConfig = (year?: number) => api.get("/incentive/config", { params: { year } }).then((r) => r.data); export const putIncentiveConfig = (b: Partial) => api.put("/incentive/config", b).then((r) => r.data); export const getMyIncentive = (params?: { year?: number; email?: string }) => api.get("/incentive/me", { params }).then((r) => r.data); export const getStages = (projectId: string) => api.get("/incentive/stages", { params: { projectId } }).then((r) => r.data); export const recomputeProject = (id: string, year?: number) => api.post(`/incentive/projects/${id}/recompute`, null, { params: { year } }).then((r) => r.data); export const setStageStatus = (stId: string, status: string, fixedDate?: string) => api.post(`/incentive/stages/${stId}/status`, { status, fixedDate }).then((r) => r.data); export const getUserIncentives = (params: { projectId?: string; email?: string }) => api.get("/incentive/user-incentives", { params }).then((r) => r.data); export const patchUserIncentive = (uiId: string, b: Partial) => api.patch(`/incentive/user-incentives/${uiId}`, b).then((r) => r.data); export const getSettlements = (year?: number) => api.get("/incentive/settlements", { params: { year } }).then((r) => r.data); export const runSettlement = (year: number, quarter: number) => api.post("/incentive/settlements/run", { year, quarter }).then((r) => r.data); export const fixSettlement = (sId: string) => api.post(`/incentive/settlements/${sId}/fix`).then((r) => r.data); export const simulate = (b: { total: number; be: number; members: { email: string; portion: number; isPartner: boolean }[]; config?: Partial; }) => api.post("/incentive/simulate", b).then((r) => r.data); /* ---- accounting ---- */ export const getAccounts = () => api.get("/accounts").then((r) => r.data); export const createAccount = (b: Partial) => api.post("/accounts", b).then((r) => r.data); export const getTransactions = (params?: { kind?: string; projectId?: string; from?: string; to?: string }) => api.get("/transactions", { params }).then((r) => r.data); export const createTransaction = (b: Partial) => api.post("/transactions", b).then((r) => r.data); export const updateTransaction = (txId: string, b: Partial) => api.patch(`/transactions/${txId}`, b).then((r) => r.data); export const deleteTransaction = (txId: string) => api.delete(`/transactions/${txId}`).then((r) => r.data); export const getTaxes = () => api.get("/taxes").then((r) => r.data); export const createTax = (b: Partial) => api.post("/taxes", b).then((r) => r.data); export const updateTax = (taxId: string, b: Partial) => api.patch(`/taxes/${taxId}`, b).then((r) => r.data); export const getAccountingSummary = (year?: number) => api.get("/accounting/summary", { params: { year } }).then((r) => r.data);