diff --git a/src/components/layout/PageLayout/PageLayout.tsx b/src/components/layout/PageLayout/PageLayout.tsx index b1ef5b9..994481d 100644 --- a/src/components/layout/PageLayout/PageLayout.tsx +++ b/src/components/layout/PageLayout/PageLayout.tsx @@ -19,6 +19,7 @@ import { ReLogo } from '@/assets'; import notificationApi, { Notification } from '@/services/notificationApi'; import { getSocket, joinUserRoom } from '@/utils/socket'; import { formatDistanceToNow } from 'date-fns'; +import { TokenManager } from '@/utils/tokenManager'; interface PageLayoutProps { children: React.ReactNode; @@ -36,6 +37,17 @@ export function PageLayout({ children, currentPage = 'dashboard', onNavigate, on const [notificationsOpen, setNotificationsOpen] = useState(false); const { user } = useAuth(); + // Check if user is a Dealer + const isDealer = useMemo(() => { + try { + const userData = TokenManager.getUserData(); + return userData?.jobTitle === 'Dealer'; + } catch (error) { + console.error('[PageLayout] Error checking dealer status:', error); + return false; + } + }, []); + // Get user initials for avatar const getUserInitials = () => { try { @@ -63,16 +75,19 @@ export function PageLayout({ children, currentPage = 'dashboard', onNavigate, on { id: 'requests', label: 'All Requests', icon: List }, ]; - // Add remaining menu items + // Add remaining menu items (exclude "My Requests" for dealers) + if (!isDealer) { + items.push({ id: 'my-requests', label: 'My Requests', icon: User }); + } + items.push( - { id: 'my-requests', label: 'My Requests', icon: User }, { id: 'open-requests', label: 'Open Requests', icon: FileText }, { id: 'closed-requests', label: 'Closed Requests', icon: CheckCircle }, { id: 'shared-summaries', label: 'Shared Summary', icon: Share2 } ); return items; - }, []); + }, [isDealer]); const toggleSidebar = () => { setSidebarOpen(!sidebarOpen); @@ -256,16 +271,18 @@ export function PageLayout({ children, currentPage = 'dashboard', onNavigate, on {/* Quick Action in Sidebar - Right below menu items */} -
{selectedTemplate.suggestedSLA} days
-{selectedTemplate.estimatedTime}
-
diff --git a/src/dealer-claim/components/request-detail/WorkflowTab.tsx b/src/dealer-claim/components/request-detail/WorkflowTab.tsx
index c51bf3a..63c407a 100644
--- a/src/dealer-claim/components/request-detail/WorkflowTab.tsx
+++ b/src/dealer-claim/components/request-detail/WorkflowTab.tsx
@@ -395,10 +395,18 @@ export function DealerClaimWorkflowTab({
return `Step ${stepNumber} approval required.`;
};
+ // Get backend currentLevel to determine which steps are active vs waiting
+ // This needs to be calculated before mapping steps so we can use it in status normalization
+ // Convert to number to ensure proper comparison
+ const backendCurrentLevel = request?.currentLevel || request?.current_level || request?.currentStep;
+ const currentLevelNumber = backendCurrentLevel !== undefined && backendCurrentLevel !== null
+ ? Number(backendCurrentLevel)
+ : null;
+
// Transform approval flow to dealer claim workflow steps
const workflowSteps: WorkflowStep[] = approvalFlow.map((step: any, index: number) => {
- // Get actual step number from levelNumber or step field
- const actualStepNumber = step.levelNumber || step.level_number || step.step || index + 1;
+ // Get actual step number from levelNumber or step field - ensure it's a number
+ const actualStepNumber = Number(step.levelNumber || step.level_number || step.step || index + 1);
// Get levelName from the approval level if available
const levelName = step.levelName || step.level_name;
@@ -467,26 +475,75 @@ export function DealerClaimWorkflowTab({
}
}
- // Normalize status - handle "in-review" and other variations
- // Check both step.status and approval.status (approval status is more accurate after approval)
- const stepStatus = step.status || approval?.status || 'waiting';
- let normalizedStatus = stepStatus.toLowerCase();
+ // Normalize status - ALWAYS check step position first, then use approval/step status
+ // This ensures future steps are always 'waiting' regardless of approval/step status
+ let normalizedStatus: string;
- // Handle status variations
- if (normalizedStatus === 'in-review' || normalizedStatus === 'in_review' || normalizedStatus === 'in review') {
- normalizedStatus = 'in_progress';
- }
-
- // If approval exists and has a status, prefer that (it's more up-to-date)
- if (approval?.status) {
- const approvalStatus = approval.status.toLowerCase();
- // Map backend status values to frontend status values
- if (approvalStatus === 'approved') {
- normalizedStatus = 'approved';
- } else if (approvalStatus === 'rejected') {
- normalizedStatus = 'rejected';
- } else if (approvalStatus === 'pending' || approvalStatus === 'in_progress' || approvalStatus === 'in-progress') {
- normalizedStatus = 'in_progress';
+ // First, check step position relative to currentLevel (this is the source of truth)
+ // Use currentLevelNumber which is guaranteed to be a number or null
+ if (currentLevelNumber !== null && currentLevelNumber > 0) {
+ if (actualStepNumber > currentLevelNumber) {
+ // Future step - MUST be waiting (ignore approval status and step.status)
+ normalizedStatus = 'waiting';
+ } else if (actualStepNumber < currentLevelNumber) {
+ // Past step - should be approved/rejected
+ // Use approval status if available, otherwise default to waiting
+ if (approval?.status) {
+ const approvalStatus = approval.status.toLowerCase();
+ if (approvalStatus === 'approved') {
+ normalizedStatus = 'approved';
+ } else if (approvalStatus === 'rejected') {
+ normalizedStatus = 'rejected';
+ } else {
+ normalizedStatus = 'waiting'; // Past step with unexpected status
+ }
+ } else {
+ normalizedStatus = 'waiting'; // Past step with no approval
+ }
+ } else {
+ // Current step - use approval status if available, otherwise use step.status
+ if (approval?.status) {
+ const approvalStatus = approval.status.toLowerCase();
+ if (approvalStatus === 'approved') {
+ normalizedStatus = 'approved';
+ } else if (approvalStatus === 'rejected') {
+ normalizedStatus = 'rejected';
+ } else if (approvalStatus === 'pending' || approvalStatus === 'in_progress' || approvalStatus === 'in-progress') {
+ normalizedStatus = 'in_progress';
+ } else {
+ normalizedStatus = 'in_progress'; // Default for current step
+ }
+ } else {
+ // No approval object - normalize step.status
+ const stepStatus = (step.status || 'pending').toLowerCase();
+ if (stepStatus === 'in-review' || stepStatus === 'in_review' || stepStatus === 'in review' || stepStatus === 'pending') {
+ normalizedStatus = 'in_progress';
+ } else {
+ normalizedStatus = stepStatus;
+ }
+ }
+ }
+ } else {
+ // No backend currentLevel - use approval status if available, otherwise step.status
+ if (approval?.status) {
+ const approvalStatus = approval.status.toLowerCase();
+ if (approvalStatus === 'approved') {
+ normalizedStatus = 'approved';
+ } else if (approvalStatus === 'rejected') {
+ normalizedStatus = 'rejected';
+ } else if (approvalStatus === 'pending' || approvalStatus === 'in_progress' || approvalStatus === 'in-progress') {
+ normalizedStatus = 'in_progress';
+ } else {
+ normalizedStatus = (step.status || 'waiting').toLowerCase();
+ }
+ } else {
+ // No approval and no currentLevel - normalize step.status
+ const stepStatus = (step.status || 'waiting').toLowerCase();
+ if (stepStatus === 'in-review' || stepStatus === 'in_review' || stepStatus === 'in review' || stepStatus === 'pending') {
+ normalizedStatus = 'in_progress';
+ } else {
+ normalizedStatus = stepStatus;
+ }
}
}
@@ -522,10 +579,12 @@ export function DealerClaimWorkflowTab({
// IMPORTANT: Use the workflow's currentLevel from backend (most accurate)
// Fallback to finding first pending step if currentLevel not available
// Note: Status normalization already handled in workflowSteps mapping above
- const backendCurrentLevel = request?.currentLevel || request?.current_level || request?.currentStep;
+ // backendCurrentLevel is already calculated above before the map function
// Find the step that matches backend's currentLevel
- const activeStepFromBackend = workflowSteps.find(s => s.step === backendCurrentLevel);
+ const activeStepFromBackend = currentLevelNumber !== null
+ ? workflowSteps.find(s => s.step === currentLevelNumber)
+ : null;
// If backend currentLevel exists and step is pending/in_progress, use it
// Otherwise, find first pending/in_progress step
@@ -537,7 +596,7 @@ export function DealerClaimWorkflowTab({
return status === 'pending' || status === 'in_progress' || status === 'in-review' || status === 'in_review';
});
- const currentStep = activeStep ? activeStep.step : (backendCurrentLevel || request?.currentStep || 1);
+ const currentStep = activeStep ? activeStep.step : (currentLevelNumber || request?.currentStep || 1);
// Check if current user is the dealer (for steps 1 and 5)
const userEmail = (user as any)?.email?.toLowerCase() || '';
diff --git a/src/pages/Auth/Auth.tsx b/src/pages/Auth/Auth.tsx
index 5028b81..08f1498 100644
--- a/src/pages/Auth/Auth.tsx
+++ b/src/pages/Auth/Auth.tsx
@@ -89,7 +89,7 @@ export function Auth() {
) : (
<>