removed suspicious comments
This commit is contained in:
parent
08cda349f3
commit
7ae9133b98
195
src/App.tsx
195
src/App.tsx
@ -412,201 +412,6 @@ function AppRoutes({ onLogout }: AppProps) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keep the old code below for backward compatibility (local storage fallback)
|
|
||||||
// This can be removed once API integration is fully tested
|
|
||||||
/*
|
|
||||||
// Generate unique ID for the new claim request
|
|
||||||
const requestId = `RE-REQ-2024-CM-${String(dynamicRequests.length + 2).padStart(3, '0')}`;
|
|
||||||
|
|
||||||
// Create full request object
|
|
||||||
const newRequest = {
|
|
||||||
id: requestId,
|
|
||||||
title: `${claimData.activityName} - Claim Request`,
|
|
||||||
description: claimData.requestDescription,
|
|
||||||
category: 'Dealer Operations',
|
|
||||||
subcategory: 'Claim Management',
|
|
||||||
status: 'pending',
|
|
||||||
priority: 'standard',
|
|
||||||
amount: 'TBD',
|
|
||||||
slaProgress: 0,
|
|
||||||
slaRemaining: '7 days',
|
|
||||||
slaEndDate: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString(),
|
|
||||||
currentStep: 1,
|
|
||||||
totalSteps: 8,
|
|
||||||
templateType: 'claim-management',
|
|
||||||
templateName: 'Claim Management',
|
|
||||||
initiator: {
|
|
||||||
name: 'Current User',
|
|
||||||
role: 'Regional Marketing Coordinator',
|
|
||||||
department: 'Marketing',
|
|
||||||
email: 'current.user@royalenfield.com',
|
|
||||||
phone: '+91 98765 43290',
|
|
||||||
avatar: 'CU'
|
|
||||||
},
|
|
||||||
department: 'Marketing',
|
|
||||||
createdAt: new Date().toLocaleString('en-US', {
|
|
||||||
month: 'short',
|
|
||||||
day: 'numeric',
|
|
||||||
year: 'numeric',
|
|
||||||
hour: 'numeric',
|
|
||||||
minute: 'numeric',
|
|
||||||
hour12: true
|
|
||||||
}),
|
|
||||||
updatedAt: new Date().toLocaleString('en-US', {
|
|
||||||
month: 'short',
|
|
||||||
day: 'numeric',
|
|
||||||
year: 'numeric',
|
|
||||||
hour: 'numeric',
|
|
||||||
minute: 'numeric',
|
|
||||||
hour12: true
|
|
||||||
}),
|
|
||||||
dueDate: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000).toISOString(),
|
|
||||||
conclusionRemark: '',
|
|
||||||
claimDetails: {
|
|
||||||
activityName: claimData.activityName,
|
|
||||||
activityType: claimData.activityType,
|
|
||||||
activityDate: claimData.activityDate ? new Date(claimData.activityDate).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' }) : '',
|
|
||||||
location: claimData.location,
|
|
||||||
dealerCode: claimData.dealerCode,
|
|
||||||
dealerName: claimData.dealerName,
|
|
||||||
dealerEmail: claimData.dealerEmail || 'N/A',
|
|
||||||
dealerPhone: claimData.dealerPhone || 'N/A',
|
|
||||||
dealerAddress: claimData.dealerAddress || 'N/A',
|
|
||||||
requestDescription: claimData.requestDescription,
|
|
||||||
estimatedBudget: claimData.estimatedBudget || 'TBD',
|
|
||||||
periodStart: claimData.periodStartDate ? new Date(claimData.periodStartDate).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' }) : '',
|
|
||||||
periodEnd: claimData.periodEndDate ? new Date(claimData.periodEndDate).toLocaleDateString('en-US', { month: 'short', day: 'numeric', year: 'numeric' }) : ''
|
|
||||||
},
|
|
||||||
approvalFlow: claimData.workflowSteps || [
|
|
||||||
{
|
|
||||||
step: 1,
|
|
||||||
approver: `${claimData.dealerName} (Dealer)`,
|
|
||||||
role: 'Dealer - Document Upload',
|
|
||||||
status: 'pending',
|
|
||||||
tatHours: 72,
|
|
||||||
elapsedHours: 0,
|
|
||||||
assignedAt: new Date().toISOString(),
|
|
||||||
comment: null,
|
|
||||||
timestamp: null,
|
|
||||||
description: 'Dealer uploads proposal document, cost breakup, timeline for closure, and other supporting documents'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
step: 2,
|
|
||||||
approver: 'Current User (Initiator)',
|
|
||||||
role: 'Initiator Evaluation',
|
|
||||||
status: 'waiting',
|
|
||||||
tatHours: 48,
|
|
||||||
elapsedHours: 0,
|
|
||||||
assignedAt: null,
|
|
||||||
comment: null,
|
|
||||||
timestamp: null,
|
|
||||||
description: 'Initiator reviews dealer documents and approves or requests modifications'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
step: 3,
|
|
||||||
approver: 'System Auto-Process',
|
|
||||||
role: 'IO Confirmation',
|
|
||||||
status: 'waiting',
|
|
||||||
tatHours: 1,
|
|
||||||
elapsedHours: 0,
|
|
||||||
assignedAt: null,
|
|
||||||
comment: null,
|
|
||||||
timestamp: null,
|
|
||||||
description: 'Automatic IO (Internal Order) confirmation generated upon initiator approval'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
step: 4,
|
|
||||||
approver: 'Rajesh Kumar',
|
|
||||||
role: 'Department Lead Approval',
|
|
||||||
status: 'waiting',
|
|
||||||
tatHours: 72,
|
|
||||||
elapsedHours: 0,
|
|
||||||
assignedAt: null,
|
|
||||||
comment: null,
|
|
||||||
timestamp: null,
|
|
||||||
description: 'Department head approves and blocks budget in IO for this activity'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
step: 5,
|
|
||||||
approver: `${claimData.dealerName} (Dealer)`,
|
|
||||||
role: 'Dealer - Completion Documents',
|
|
||||||
status: 'waiting',
|
|
||||||
tatHours: 120,
|
|
||||||
elapsedHours: 0,
|
|
||||||
assignedAt: null,
|
|
||||||
comment: null,
|
|
||||||
timestamp: null,
|
|
||||||
description: 'Dealer submits activity completion documents and description'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
step: 6,
|
|
||||||
approver: 'Current User (Initiator)',
|
|
||||||
role: 'Initiator Verification',
|
|
||||||
status: 'waiting',
|
|
||||||
tatHours: 48,
|
|
||||||
elapsedHours: 0,
|
|
||||||
assignedAt: null,
|
|
||||||
comment: null,
|
|
||||||
timestamp: null,
|
|
||||||
description: 'Initiator verifies completion documents and can modify approved amount'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
step: 7,
|
|
||||||
approver: 'System Auto-Process',
|
|
||||||
role: 'E-Invoice Generation',
|
|
||||||
status: 'waiting',
|
|
||||||
tatHours: 1,
|
|
||||||
elapsedHours: 0,
|
|
||||||
assignedAt: null,
|
|
||||||
comment: null,
|
|
||||||
timestamp: null,
|
|
||||||
description: 'Auto-generate e-invoice based on final approved amount'
|
|
||||||
},
|
|
||||||
{
|
|
||||||
step: 8,
|
|
||||||
approver: 'Finance Team',
|
|
||||||
role: 'Credit Note Issuance',
|
|
||||||
status: 'waiting',
|
|
||||||
tatHours: 48,
|
|
||||||
elapsedHours: 0,
|
|
||||||
assignedAt: null,
|
|
||||||
comment: null,
|
|
||||||
timestamp: null,
|
|
||||||
description: 'Finance team issues credit note to dealer'
|
|
||||||
}
|
|
||||||
],
|
|
||||||
documents: [],
|
|
||||||
spectators: [],
|
|
||||||
auditTrail: [
|
|
||||||
{
|
|
||||||
type: 'created',
|
|
||||||
action: 'Request Created',
|
|
||||||
details: `Claim request for ${claimData.activityName} created`,
|
|
||||||
user: 'Current User',
|
|
||||||
timestamp: new Date().toLocaleString('en-US', {
|
|
||||||
month: 'short',
|
|
||||||
day: 'numeric',
|
|
||||||
year: 'numeric',
|
|
||||||
hour: 'numeric',
|
|
||||||
minute: 'numeric',
|
|
||||||
hour12: true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
],
|
|
||||||
tags: ['claim-management', 'new-request', claimData.activityType?.toLowerCase().replace(/\s+/g, '-')]
|
|
||||||
};
|
|
||||||
|
|
||||||
// Add to dynamic requests
|
|
||||||
setDynamicRequests(prev => [...prev, newRequest]);
|
|
||||||
|
|
||||||
// Also add to REQUEST_DATABASE for immediate viewing
|
|
||||||
(REQUEST_DATABASE as any)[requestId] = newRequest;
|
|
||||||
|
|
||||||
toast.success('Claim Request Submitted', {
|
|
||||||
description: 'Your claim management request has been created successfully.',
|
|
||||||
});
|
|
||||||
navigate('/my-requests');
|
|
||||||
*/
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -31,7 +31,7 @@ export function AnalyticsConfig() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const handleSave = () => {
|
const handleSave = () => {
|
||||||
// TODO: Implement API call to save configuration
|
|
||||||
toast.success('Analytics configuration saved successfully');
|
toast.success('Analytics configuration saved successfully');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -59,7 +59,7 @@ export function DashboardConfig() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const handleSave = () => {
|
const handleSave = () => {
|
||||||
// TODO: Implement API call to save dashboard configuration
|
|
||||||
toast.success('Dashboard layout saved successfully');
|
toast.success('Dashboard layout saved successfully');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -28,7 +28,7 @@ export function NotificationConfig() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const handleSave = () => {
|
const handleSave = () => {
|
||||||
// TODO: Implement API call to save notification configuration
|
|
||||||
toast.success('Notification configuration saved successfully');
|
toast.success('Notification configuration saved successfully');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -23,7 +23,7 @@ export function SharingConfig() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const handleSave = () => {
|
const handleSave = () => {
|
||||||
// TODO: Implement API call to save sharing configuration
|
|
||||||
toast.success('Sharing policy saved successfully');
|
toast.success('Sharing policy saved successfully');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@ -318,7 +318,7 @@ export function UserManagement() {
|
|||||||
const user = users.find(u => u.userId === userId);
|
const user = users.find(u => u.userId === userId);
|
||||||
if (!user) return;
|
if (!user) return;
|
||||||
|
|
||||||
// TODO: Implement backend API for toggling user status
|
|
||||||
toast.info('User status toggle functionality coming soon');
|
toast.info('User status toggle functionality coming soon');
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -332,7 +332,6 @@ export function UserManagement() {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Implement backend API for deleting users
|
|
||||||
toast.info('User deletion functionality coming soon');
|
toast.info('User deletion functionality coming soon');
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -515,11 +514,10 @@ export function UserManagement() {
|
|||||||
|
|
||||||
{/* Message */}
|
{/* Message */}
|
||||||
{message && (
|
{message && (
|
||||||
<div className={`border-2 rounded-lg p-4 ${
|
<div className={`border-2 rounded-lg p-4 ${message.type === 'success'
|
||||||
message.type === 'success'
|
? 'border-green-200 bg-green-50'
|
||||||
? 'border-green-200 bg-green-50'
|
: 'border-red-200 bg-red-50'
|
||||||
: 'border-red-200 bg-red-50'
|
}`}>
|
||||||
}`}>
|
|
||||||
<div className="flex items-start gap-3">
|
<div className="flex items-start gap-3">
|
||||||
{message.type === 'success' ? (
|
{message.type === 'success' ? (
|
||||||
<CheckCircle className="w-5 h-5 text-green-600 shrink-0 mt-0.5" />
|
<CheckCircle className="w-5 h-5 text-green-600 shrink-0 mt-0.5" />
|
||||||
@ -664,11 +662,10 @@ export function UserManagement() {
|
|||||||
variant={currentPage === pageNum ? "default" : "outline"}
|
variant={currentPage === pageNum ? "default" : "outline"}
|
||||||
size="sm"
|
size="sm"
|
||||||
onClick={() => handlePageChange(pageNum)}
|
onClick={() => handlePageChange(pageNum)}
|
||||||
className={`w-9 h-9 p-0 ${
|
className={`w-9 h-9 p-0 ${currentPage === pageNum
|
||||||
currentPage === pageNum
|
? 'bg-re-green hover:bg-re-green/90'
|
||||||
? 'bg-re-green hover:bg-re-green/90'
|
: ''
|
||||||
: ''
|
}`}
|
||||||
}`}
|
|
||||||
>
|
>
|
||||||
{pageNum}
|
{pageNum}
|
||||||
</Button>
|
</Button>
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@ -30,7 +30,7 @@ async function ensureConfigLoaded() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize config on first import (non-blocking)
|
// Initialize config on first import (non-blocking)
|
||||||
ensureConfigLoaded().catch(() => {});
|
ensureConfigLoaded().catch(() => { });
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if current time is within working hours
|
* Check if current time is within working hours
|
||||||
@ -54,7 +54,6 @@ export function isWorkingTime(date: Date = new Date(), priority: string = 'stand
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Add holiday check if holiday API is available
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -75,26 +75,13 @@ export const cookieUtils = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Token Manager - Handles token storage and retrieval
|
|
||||||
*
|
|
||||||
* SECURITY MODES:
|
|
||||||
* - Production: Tokens stored in httpOnly cookies by backend only
|
|
||||||
* Frontend does NOT store access/refresh tokens anywhere
|
|
||||||
* All API requests rely on cookies being sent automatically
|
|
||||||
*
|
|
||||||
* - Development: Tokens stored in localStorage for debugging
|
|
||||||
* Needed because frontend/backend run on different ports
|
|
||||||
*/
|
|
||||||
export class TokenManager {
|
export class TokenManager {
|
||||||
/**
|
/**
|
||||||
* Store access token
|
* Store access token
|
||||||
* In production: No-op (backend handles via httpOnly cookies)
|
|
||||||
* In development: Store in localStorage for Authorization header
|
|
||||||
*/
|
*/
|
||||||
static setAccessToken(token: string): void {
|
static setAccessToken(token: string): void {
|
||||||
// SECURITY: In production, don't store tokens client-side
|
|
||||||
// Backend sets httpOnly cookies that are sent automatically
|
|
||||||
if (isProduction()) {
|
if (isProduction()) {
|
||||||
return; // No-op - rely on httpOnly cookies
|
return; // No-op - rely on httpOnly cookies
|
||||||
}
|
}
|
||||||
@ -105,13 +92,12 @@ export class TokenManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get access token
|
* Get access token
|
||||||
* In production: Returns null (cookies are sent automatically)
|
*
|
||||||
* In development: Returns from localStorage
|
|
||||||
*/
|
*/
|
||||||
static getAccessToken(): string | null {
|
static getAccessToken(): string | null {
|
||||||
// SECURITY: In production, return null - cookies are used instead
|
|
||||||
if (isProduction()) {
|
if (isProduction()) {
|
||||||
return null; // API calls use cookies via withCredentials: true
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Development: Return from localStorage
|
// Development: Return from localStorage
|
||||||
@ -120,8 +106,6 @@ export class TokenManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Store refresh token
|
* Store refresh token
|
||||||
* In production: No-op (backend handles via httpOnly cookies)
|
|
||||||
* In development: Store in localStorage
|
|
||||||
*/
|
*/
|
||||||
static setRefreshToken(token: string): void {
|
static setRefreshToken(token: string): void {
|
||||||
// SECURITY: In production, don't store tokens client-side
|
// SECURITY: In production, don't store tokens client-side
|
||||||
@ -135,8 +119,6 @@ export class TokenManager {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Get refresh token
|
* Get refresh token
|
||||||
* In production: Returns null (cookies are used)
|
|
||||||
* In development: Returns from localStorage
|
|
||||||
*/
|
*/
|
||||||
static getRefreshToken(): string | null {
|
static getRefreshToken(): string | null {
|
||||||
// SECURITY: In production, return null - backend reads from cookie
|
// SECURITY: In production, return null - backend reads from cookie
|
||||||
@ -147,10 +129,6 @@ export class TokenManager {
|
|||||||
return localStorage.getItem(REFRESH_TOKEN_KEY);
|
return localStorage.getItem(REFRESH_TOKEN_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Store ID token (from Okta) - needed for logout
|
|
||||||
* Stored in sessionStorage (cleared when tab closes)
|
|
||||||
*/
|
|
||||||
static setIdToken(token: string): void {
|
static setIdToken(token: string): void {
|
||||||
// ID token is needed for Okta logout, use sessionStorage (more secure than localStorage)
|
// ID token is needed for Okta logout, use sessionStorage (more secure than localStorage)
|
||||||
sessionStorage.setItem(ID_TOKEN_KEY, token);
|
sessionStorage.setItem(ID_TOKEN_KEY, token);
|
||||||
@ -183,18 +161,7 @@ export class TokenManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Clear all tokens and user data
|
|
||||||
*
|
|
||||||
* PRODUCTION MODE:
|
|
||||||
* - Clears user data from localStorage
|
|
||||||
* - Clears ID token from sessionStorage
|
|
||||||
* - Backend logout endpoint clears httpOnly cookies
|
|
||||||
*
|
|
||||||
* DEVELOPMENT MODE:
|
|
||||||
* - Clears all localStorage and sessionStorage
|
|
||||||
* - Clears client-side cookies
|
|
||||||
*/
|
|
||||||
static clearAll(): void {
|
static clearAll(): void {
|
||||||
// CRITICAL: Set logout flag in sessionStorage FIRST (before clearing)
|
// CRITICAL: Set logout flag in sessionStorage FIRST (before clearing)
|
||||||
// This flag survives the redirect and prevents auto-authentication
|
// This flag survives the redirect and prevents auto-authentication
|
||||||
@ -296,11 +263,7 @@ export class TokenManager {
|
|||||||
return !!this.getAccessToken();
|
return !!this.getAccessToken();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if refresh token exists
|
|
||||||
* In production: Always returns true if user data exists
|
|
||||||
* In development: Checks localStorage
|
|
||||||
*/
|
|
||||||
static hasRefreshToken(): boolean {
|
static hasRefreshToken(): boolean {
|
||||||
if (isProduction()) {
|
if (isProduction()) {
|
||||||
return !!this.getUserData();
|
return !!this.getUserData();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user