made compatible t take
serve frontend build
This commit is contained in:
parent
5170ab6c5a
commit
7b417be427
@ -6,6 +6,7 @@
|
||||
"scripts": {
|
||||
"dev": "vite",
|
||||
"build": "tsc && vite build",
|
||||
"build:deploy": "vite build",
|
||||
"lint": "eslint . --report-unused-disable-directives --max-warnings 0",
|
||||
"preview": "vite preview",
|
||||
"test": "jest",
|
||||
|
||||
@ -2,6 +2,8 @@ import client from './client';
|
||||
import axios from 'axios';
|
||||
import type { ConstitutionalChangeAction } from '@/lib/offboarding-actions';
|
||||
|
||||
const PUBLIC_API_BASE_URL = (import.meta as any).env?.VITE_API_URL || '/api';
|
||||
|
||||
export const API = {
|
||||
// Auth routes
|
||||
login: (data: any) => client.post('/auth/login', data),
|
||||
@ -70,8 +72,8 @@ export const API = {
|
||||
deleteDocumentConfig: (id: string) => client.delete(`/onboarding/document-configs/${id}`),
|
||||
|
||||
// Public Questionnaire
|
||||
getPublicQuestionnaire: (appId: string) => axios.get(`http://localhost:5000/api/questionnaire/public/${appId}`), // Direct axios to bypass interceptors if client has auth
|
||||
submitPublicResponse: (data: any) => axios.post('http://localhost:5000/api/questionnaire/public/submit', data),
|
||||
getPublicQuestionnaire: (appId: string) => axios.get(`${PUBLIC_API_BASE_URL}/questionnaire/public/${appId}`), // Direct axios to bypass interceptors if client has auth
|
||||
submitPublicResponse: (data: any) => axios.post(`${PUBLIC_API_BASE_URL}/questionnaire/public/submit`, data),
|
||||
|
||||
// Assessment & Interviews
|
||||
getAiSummary: (appId: string) => client.get(`/assessment/ai-summary/${appId}`),
|
||||
|
||||
@ -1,6 +1,6 @@
|
||||
import { create } from 'apisauce';
|
||||
|
||||
const API_BASE_URL = (import.meta as any).env?.VITE_API_URL || 'http://localhost:5000/api';
|
||||
const API_BASE_URL = (import.meta as any).env?.VITE_API_URL || '/api';
|
||||
|
||||
const client = create({
|
||||
baseURL: API_BASE_URL,
|
||||
|
||||
@ -59,9 +59,9 @@ const QuestionnaireForm: React.FC<QuestionnaireFormProps> = ({
|
||||
return;
|
||||
}
|
||||
|
||||
const res = await API.getLatestQuestionnaire();
|
||||
const res: any = await API.getLatestQuestionnaire();
|
||||
|
||||
if (res.data && res.data.data && res.data.data.questions) {
|
||||
if (res?.data?.data?.questions) {
|
||||
// Normalize questions
|
||||
const normalized = res.data.data.questions.map((q: any) => ({
|
||||
...q,
|
||||
|
||||
@ -1,20 +1,13 @@
|
||||
import React, { useState } from 'react';
|
||||
import React from 'react';
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogDescription,
|
||||
} from './dialog';
|
||||
import { Button } from './button';
|
||||
import {
|
||||
Eye,
|
||||
Download,
|
||||
RotateCw,
|
||||
RefreshCw,
|
||||
Plus,
|
||||
Minus,
|
||||
FileText
|
||||
} from 'lucide-react';
|
||||
import { WIDE_DIALOG_CLASS } from '../../lib/dialogStyles';
|
||||
|
||||
@ -35,9 +28,6 @@ export const DocumentPreviewModal: React.FC<DocumentPreviewModalProps> = ({
|
||||
onClose,
|
||||
document
|
||||
}) => {
|
||||
const [zoomScale, setZoomScale] = useState(1);
|
||||
const [rotation, setRotation] = useState(0);
|
||||
|
||||
const baseUrl = 'http://localhost:5000';
|
||||
const fileUrl = document ? `${baseUrl}${document.filePath.startsWith('/') ? '' : '/'}${document.filePath}` : '';
|
||||
|
||||
|
||||
@ -1,20 +1,11 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import {
|
||||
LayoutDashboard,
|
||||
Calendar,
|
||||
FileText,
|
||||
UserMinus,
|
||||
RefreshCcw,
|
||||
MapPin,
|
||||
LogOut,
|
||||
Search,
|
||||
ChevronLeft,
|
||||
ChevronRight,
|
||||
Bell,
|
||||
User,
|
||||
RefreshCw,
|
||||
HelpCircle,
|
||||
X
|
||||
} from 'lucide-react';
|
||||
import { useDispatch, useSelector } from 'react-redux';
|
||||
import { useNavigate, Routes, Route, useParams } from 'react-router-dom';
|
||||
|
||||
@ -423,12 +423,6 @@ export function FnFDetails({ fnfId, onBack, currentUser }: FnFDetailsProps) {
|
||||
|
||||
const fnfAge = calculateAge(fnfCase.submittedOn);
|
||||
|
||||
const canSendToStakeholders =
|
||||
currentUser &&
|
||||
["DD Lead", "DD Head", "NBH", "DD Admin", "Super Admin"].includes(
|
||||
currentUser.role,
|
||||
);
|
||||
|
||||
const canRespondToDepartment = (dept: any) => {
|
||||
if (!fnfCase || !dept) return false;
|
||||
const role = String(currentUser?.role || "").toLowerCase();
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
import { useState, useEffect } from 'react';
|
||||
import { IndianRupee, Calendar, Eye, Send, FileCheck, Loader2 } from 'lucide-react';
|
||||
import { IndianRupee, Calendar, Eye, FileCheck, Loader2 } from 'lucide-react';
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { Button } from '@/components/ui/button';
|
||||
@ -42,9 +42,6 @@ export function FnFPage({ currentUser, onViewDetails }: FnFPageProps) {
|
||||
const [settlements, setSettlements] = useState<any[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
const canSendToStakeholders = currentUser &&
|
||||
['DD Lead', 'DD Head', 'NBH', 'DD Admin', 'Super Admin'].includes(currentUser.role);
|
||||
|
||||
useEffect(() => {
|
||||
fetchSettlements();
|
||||
}, []);
|
||||
@ -65,11 +62,6 @@ export function FnFPage({ currentUser, onViewDetails }: FnFPageProps) {
|
||||
}
|
||||
};
|
||||
|
||||
const handleSendToStakeholders = (caseId: string) => {
|
||||
console.log('Sending to stakeholders for case:', caseId);
|
||||
toast.success('Notifications sent to all stakeholders');
|
||||
};
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<div className="flex items-center justify-center p-12">
|
||||
|
||||
@ -37,7 +37,7 @@ export const ASMDialog: React.FC<ASMDialogProps> = ({
|
||||
asmStatus, setAsmStatus, selectedASMZone, setSelectedASMZone,
|
||||
selectedASMRegion, setSelectedASMRegion, selectedASMStates, setSelectedASMStates,
|
||||
selectedASMDistricts, setSelectedASMDistricts, onSave,
|
||||
asmRoleCode, setAsmRoleCode,
|
||||
asmRoleCode,
|
||||
userAssignedData, districtsAssignedToOthers, getDistrictsForSelectedState
|
||||
}) => {
|
||||
const { zones, regionalOffices } = useSelector((state: RootState) => state.master);
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { render, screen } from "@testing-library/react"
|
||||
import { screen } from "@testing-library/react"
|
||||
import userEvent from "@testing-library/user-event"
|
||||
import { AllApplicationsPage } from "../pages/AllApplicationsPage"
|
||||
import { renderWithProviders } from "./test-utils"
|
||||
@ -10,12 +10,12 @@ describe("AllApplicationsPage - Robust Admin Verification", () => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
const renderPage = (apps = []) => {
|
||||
const renderPage = (apps: any[] = []) => {
|
||||
;(mockOnboardingService.getApplications as jest.Mock).mockResolvedValue({
|
||||
success: true,
|
||||
data: apps
|
||||
})
|
||||
return renderWithProviders(<AllApplicationsPage />, {
|
||||
return renderWithProviders(<AllApplicationsPage onViewDetails={jest.fn()} />, {
|
||||
preloadedState: {
|
||||
auth: {
|
||||
user: { id: "admin-1", role: "DD Admin" } as any,
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { render, screen, waitFor } from "@testing-library/react"
|
||||
import { screen, waitFor } from "@testing-library/react"
|
||||
import userEvent from "@testing-library/user-event"
|
||||
import { ApplicationDetails } from "../pages/ApplicationDetails"
|
||||
import { renderWithProvidersAndRoute } from "./test-utils"
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { render, screen, waitFor } from "@testing-library/react"
|
||||
import { screen } from "@testing-library/react"
|
||||
import userEvent from "@testing-library/user-event"
|
||||
import { ApplicationsPage } from "../pages/ApplicationsPage"
|
||||
import { renderWithProviders } from "./test-utils"
|
||||
@ -10,7 +10,7 @@ describe("ApplicationsPage - Robust Feature Verification", () => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
const renderPage = (apps = []) => {
|
||||
const renderPage = (apps: any[] = []) => {
|
||||
;(mockOnboardingService.getApplications as jest.Mock).mockResolvedValue({
|
||||
success: true,
|
||||
data: apps
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { render, screen, waitFor } from "@testing-library/react"
|
||||
import { screen, waitFor } from "@testing-library/react"
|
||||
import userEvent from "@testing-library/user-event"
|
||||
import { ApplicationDetails } from "../pages/ApplicationDetails"
|
||||
import { renderWithProvidersAndRoute } from "./test-utils"
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { render, screen, waitFor } from "@testing-library/react"
|
||||
import { screen, waitFor } from "@testing-library/react"
|
||||
import userEvent from "@testing-library/user-event"
|
||||
import { FDDApplicationDetails } from "../pages/FDDApplicationDetails"
|
||||
import { renderWithProvidersAndRoute } from "./test-utils"
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { render, screen } from "@testing-library/react"
|
||||
import { screen } from "@testing-library/react"
|
||||
import userEvent from "@testing-library/user-event"
|
||||
import { NonOpportunitiesPage } from "../pages/NonOpportunitiesPage"
|
||||
import { renderWithProviders } from "./test-utils"
|
||||
@ -10,7 +10,7 @@ describe("NonOpportunitiesPage - Lead generation filtering", () => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
const renderPage = (apps = []) => {
|
||||
const renderPage = (apps: any[] = []) => {
|
||||
;(mockOnboardingService.getApplications as jest.Mock).mockResolvedValue({
|
||||
success: true,
|
||||
data: apps,
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { render, screen, waitFor } from "@testing-library/react"
|
||||
import { screen, waitFor } from "@testing-library/react"
|
||||
import userEvent from "@testing-library/user-event"
|
||||
import { OpportunityRequestsPage } from "../pages/OpportunityRequestsPage"
|
||||
import { renderWithProviders } from "./test-utils"
|
||||
@ -14,12 +14,12 @@ describe("OpportunityRequestsFlow - Lead Triage Verification", () => {
|
||||
jest.clearAllMocks()
|
||||
})
|
||||
|
||||
const renderPage = (apps = []) => {
|
||||
const renderPage = (apps: any[] = []) => {
|
||||
;(mockOnboardingService.getApplications as jest.Mock).mockResolvedValue({
|
||||
success: true,
|
||||
data: apps
|
||||
})
|
||||
return renderWithProviders(<OpportunityRequestsPage />, {
|
||||
return renderWithProviders(<OpportunityRequestsPage onViewDetails={jest.fn()} />, {
|
||||
preloadedState: {
|
||||
auth: {
|
||||
user: { id: "admin-1", role: "DD Admin" } as any,
|
||||
|
||||
@ -1 +1 @@
|
||||
export const SHARED_APP_STATUSES = { SUBMITTED: "Submitted" };
|
||||
export { TEST_STRINGS, GLOBAL_MOCK_IDS, SHARED_APP_STATUSES } from "@/testing/constants";
|
||||
|
||||
@ -49,19 +49,18 @@ export const globalMockAdminService = {
|
||||
* Helper to prepare global mocks in any test file.
|
||||
*/
|
||||
export const setupUnifiedMocks = () => {
|
||||
jest.mock("@/services/onboarding.service", () => ({ onboardingService: globalMockOnboardingService }));
|
||||
jest.mock("@/services/collaboration.service", () => ({ collaborationService: globalMockCollaborationService }));
|
||||
// Mapping worknoteService to collaborationService as they share logic in this codebase
|
||||
jest.mock("@/services/worknote.service", () => ({ worknoteService: globalMockCollaborationService }));
|
||||
jest.mock("@/services/eor.service", () => ({ eorService: globalMockEORService }));
|
||||
jest.mock("@/services/admin.service", () => ({ adminService: globalMockAdminService }));
|
||||
jest.mock("@/api/API", () => ({
|
||||
return {
|
||||
onboardingService: globalMockOnboardingService,
|
||||
collaborationService: globalMockCollaborationService,
|
||||
worknoteService: globalMockCollaborationService,
|
||||
eorService: globalMockEORService,
|
||||
adminService: globalMockAdminService,
|
||||
API: {
|
||||
...globalMockOnboardingService,
|
||||
getFddAssignment: jest.fn().mockResolvedValue({ success: true, data: {} }),
|
||||
uploadDocument: jest.fn().mockResolvedValue({ success: true }),
|
||||
submitFddReport: jest.fn().mockResolvedValue({ success: true }),
|
||||
flagNonResponsive: jest.fn().mockResolvedValue({ success: true }),
|
||||
}
|
||||
}));
|
||||
},
|
||||
};
|
||||
};
|
||||
|
||||
@ -2,7 +2,6 @@ import React, { PropsWithChildren } from 'react'
|
||||
import { render } from '@testing-library/react'
|
||||
import type { RenderOptions } from '@testing-library/react'
|
||||
import { configureStore } from '@reduxjs/toolkit'
|
||||
import type { PreloadedState } from '@reduxjs/toolkit'
|
||||
import { Provider } from 'react-redux'
|
||||
import { MemoryRouter, Routes, Route } from 'react-router-dom'
|
||||
|
||||
@ -14,7 +13,7 @@ import { MEMORY_ROUTER_TEST_FUTURE } from '@/testing/reactRouterTest'
|
||||
// This type interface extends the default options for render from RTL, as well
|
||||
// as allows the user to specify other things such as initialState, store.
|
||||
interface ExtendedRenderOptions extends Omit<RenderOptions, 'queries'> {
|
||||
preloadedState?: PreloadedState<RootState>
|
||||
preloadedState?: Partial<RootState>
|
||||
store?: ReturnType<typeof setupStore>
|
||||
}
|
||||
|
||||
@ -24,13 +23,13 @@ interface ProvidersAndRouteOptions extends ExtendedRenderOptions {
|
||||
routePath: string
|
||||
}
|
||||
|
||||
export function setupStore(preloadedState?: PreloadedState<RootState>) {
|
||||
export function setupStore(preloadedState?: Partial<RootState>) {
|
||||
return configureStore({
|
||||
reducer: {
|
||||
auth: authReducer,
|
||||
master: masterReducer,
|
||||
},
|
||||
preloadedState
|
||||
} as any,
|
||||
preloadedState: preloadedState as any
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@ -30,7 +30,7 @@ const getStatusColor = (status: string) => {
|
||||
const getApiErrorMessage = (error: any, fallback: string) =>
|
||||
error?.response?.data?.message || error?.data?.message || error?.message || fallback;
|
||||
|
||||
export function DealerRelocationPage({ currentUser, onViewDetails }: DealerRelocationPageProps) {
|
||||
export function DealerRelocationPage({ onViewDetails }: DealerRelocationPageProps) {
|
||||
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
||||
const [selectedOutlet, setSelectedOutlet] = useState<any | null>(null);
|
||||
const [newCity, setNewCity] = useState('');
|
||||
@ -54,7 +54,6 @@ export function DealerRelocationPage({ currentUser, onViewDetails }: DealerReloc
|
||||
const [requests, setRequests] = useState<any[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [submitting, setSubmitting] = useState(false);
|
||||
const [profile, setProfile] = useState<any>(null);
|
||||
|
||||
useEffect(() => {
|
||||
fetchData();
|
||||
@ -73,7 +72,6 @@ export function DealerRelocationPage({ currentUser, onViewDetails }: DealerReloc
|
||||
const relocationRes = await dealerService.getRelocationRequests();
|
||||
|
||||
setOutlets(dashboard.outlets || []);
|
||||
setProfile(dashboard.profile);
|
||||
setRequests(relocationRes.requests || []);
|
||||
} catch (error) {
|
||||
console.error('Fetch relocation data error:', error);
|
||||
@ -121,11 +119,6 @@ export function DealerRelocationPage({ currentUser, onViewDetails }: DealerReloc
|
||||
}
|
||||
};
|
||||
|
||||
const handleOpenRelocationDialog = (outlet: any) => {
|
||||
setSelectedOutlet(outlet);
|
||||
setIsDialogOpen(true);
|
||||
};
|
||||
|
||||
const handleSubmitRequest = async (e: React.FormEvent) => {
|
||||
e.preventDefault();
|
||||
|
||||
|
||||
@ -1,9 +1,9 @@
|
||||
import { FileText, Plus, Eye, Calendar, User, Building2, Store, MapPin, CheckCircle, Clock, RefreshCcw, Loader2 } from 'lucide-react';
|
||||
import { FileText, Eye, Calendar, Building2, Store, MapPin, CheckCircle, Clock, Loader2 } from 'lucide-react';
|
||||
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Table, TableBody, TableCell, TableHead, TableHeader, TableRow } from '@/components/ui/table';
|
||||
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle, DialogTrigger } from '@/components/ui/dialog';
|
||||
import { Dialog, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogTitle } from '@/components/ui/dialog';
|
||||
import { Input } from '@/components/ui/input';
|
||||
import { Label } from '@/components/ui/label';
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '@/components/ui/select';
|
||||
@ -27,7 +27,7 @@ const getStatusColor = (status: string) => {
|
||||
return 'bg-slate-100 text-slate-700 border-slate-300';
|
||||
};
|
||||
|
||||
export function DealerResignationPage({ currentUser, onViewDetails }: DealerResignationPageProps) {
|
||||
export function DealerResignationPage({ onViewDetails }: DealerResignationPageProps) {
|
||||
const [isDialogOpen, setIsDialogOpen] = useState(false);
|
||||
const [selectedOutlet, setSelectedOutlet] = useState<any | null>(null);
|
||||
const [resignationType, setResignationType] = useState('');
|
||||
|
||||
@ -30,7 +30,7 @@ const getStatusColor = (status: string) => {
|
||||
return 'bg-blue-100 text-blue-700 border-blue-300';
|
||||
};
|
||||
|
||||
export function ResignationPage({ currentUser, onViewDetails }: ResignationPageProps) {
|
||||
export function ResignationPage({ onViewDetails }: ResignationPageProps) {
|
||||
const [resignations, setResignations] = useState<any[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [currentPage, setCurrentPage] = useState(1);
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
import React, { useState, useEffect } from 'react';
|
||||
import { Card, CardHeader, CardTitle, CardContent } from '@/components/ui/card';
|
||||
import { Card, CardContent } from '@/components/ui/card';
|
||||
import { Button } from '@/components/ui/button';
|
||||
import { Badge } from '@/components/ui/badge';
|
||||
import { Bell, Check, Clock, ChevronLeft, ChevronRight } from 'lucide-react';
|
||||
import { notificationService, Notification } from '@/services/notification.service';
|
||||
import { useNavigate } from 'react-router-dom';
|
||||
|
||||
@ -4,6 +4,10 @@ import { defineConfig } from "vite"
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
build: {
|
||||
outDir: "../backend/build",
|
||||
emptyOutDir: true,
|
||||
},
|
||||
resolve: {
|
||||
alias: {
|
||||
"@": path.resolve(__dirname, "./src"),
|
||||
|
||||
Loading…
Reference in New Issue
Block a user