Przeglądaj źródła

feat(ui): implement multi-step workflow for cintas calendar summary processing

- Add step-by-step workflow interface with 4 distinct phases
- Implement file upload functionality with blob storage integration
- Create visual progress indicators for each workflow step
- Add state management for tracking current step and uploaded files
- Include placeholder UI for future import record creation and data processing
- Add navigation controls for moving between workflow steps
vtugulan 6 miesięcy temu
rodzic
commit
d203274d8d
1 zmienionych plików z 209 dodań i 48 usunięć
  1. 209 48
      app/cintas-calendar-summary/page.tsx

+ 209 - 48
app/cintas-calendar-summary/page.tsx

@@ -1,64 +1,225 @@
-import { Suspense } from 'react';
+"use client";
+
+import { useState } from 'react';
 import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
-import { Skeleton } from '@/components/ui/skeleton';
+import { Button } from '@/components/ui/button';
+import { Upload, FileText, Database, BarChart3, CheckCircle } from 'lucide-react';
+import { UploadForm } from '@/app/components/uploadForm';
+
+interface FileData {
+  id: string;
+  filename: string;
+  mimetype: string;
+  size: number;
+  createdAt: string;
+  updatedAt: string;
+}
 
 export default function CintasCalendarSummaryPage() {
+  const [currentStep, setCurrentStep] = useState(1);
+  const [uploadedFile, setUploadedFile] = useState<FileData | null>(null);
+  const [isProcessing, setIsProcessing] = useState(false);
+
+  const handleFileUploaded = (file: FileData) => {
+    setUploadedFile(file);
+    setCurrentStep(2);
+  };
+
+  const steps = [
+    {
+      id: 1,
+      title: 'Upload Excel File',
+      description: 'Upload the Cintas Install Calendar Excel file to blob storage',
+      icon: Upload,
+      status: currentStep >= 1 ? 'completed' : 'pending',
+    },
+    {
+      id: 2,
+      title: 'Create Import Record',
+      description: 'Create an import record with Cintas Install Calendar layout configuration',
+      icon: FileText,
+      status: currentStep >= 2 ? 'pending' : 'disabled',
+    },
+    {
+      id: 3,
+      title: 'Import Data',
+      description: 'Read the Excel file and import data into PostgreSQL database',
+      icon: Database,
+      status: currentStep >= 3 ? 'pending' : 'disabled',
+    },
+    {
+      id: 4,
+      title: 'Generate Summary',
+      description: 'Run summary calculation and display results',
+      icon: BarChart3,
+      status: currentStep >= 4 ? 'pending' : 'disabled',
+    },
+  ];
+
+  const getStepStatusColor = (status: string) => {
+    switch (status) {
+      case 'completed':
+        return 'text-green-600 bg-green-50 border-green-200';
+      case 'pending':
+        return 'text-blue-600 bg-blue-50 border-blue-200';
+      case 'disabled':
+        return 'text-gray-400 bg-gray-50 border-gray-200';
+      default:
+        return 'text-gray-600 bg-gray-50 border-gray-200';
+    }
+  };
+
   return (
-    <div className="container mx-auto py-6 px-4">
-      <div className="mb-6">
+    <div className="container mx-auto py-6 px-4 max-w-6xl">
+      <div className="mb-8">
         <h1 className="text-3xl font-bold tracking-tight">Cintas Install Calendar Summary</h1>
         <p className="text-muted-foreground">
-          Overview of installation calendar activities and summary statistics
+          Follow the workflow steps to upload and process the installation calendar data
         </p>
       </div>
 
+      {/* Workflow Steps */}
+      <div className="mb-8">
+        <div className="grid grid-cols-1 md:grid-cols-4 gap-4">
+          {steps.map((step) => {
+            const Icon = step.icon;
+            return (
+              <Card
+                key={step.id}
+                className={`border-2 ${getStepStatusColor(step.status)}`}
+              >
+                <CardHeader className="pb-3">
+                  <div className="flex items-center space-x-2">
+                    <Icon className="h-5 w-5" />
+                    <CardTitle className="text-sm font-medium">
+                      Step {step.id}: {step.title}
+                    </CardTitle>
+                  </div>
+                </CardHeader>
+                <CardContent>
+                  <CardDescription className="text-xs">
+                    {step.description}
+                  </CardDescription>
+                </CardContent>
+              </Card>
+            );
+          })}
+        </div>
+      </div>
+
+      {/* Step Content */}
       <div className="grid gap-6">
-        <Card>
-          <CardHeader>
-            <CardTitle>Installation Calendar Summary</CardTitle>
-            <CardDescription>
-              Comprehensive overview of all scheduled installations
-            </CardDescription>
-          </CardHeader>
-          <CardContent>
-            <div className="space-y-4">
-              <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
-                <Card>
-                  <CardHeader className="pb-3">
-                    <CardTitle className="text-sm font-medium">Total Installations</CardTitle>
-                  </CardHeader>
-                  <CardContent>
-                    <div className="text-2xl font-bold">--</div>
-                  </CardContent>
-                </Card>
+        {currentStep === 1 && (
+          <Card>
+            <CardHeader>
+              <CardTitle>Step 1: Upload Excel File</CardTitle>
+              <CardDescription>
+                Upload your Cintas Install Calendar Excel file to begin processing
+              </CardDescription>
+            </CardHeader>
+            <CardContent>
+              <div className="space-y-4">
+                <UploadForm onFileUploaded={handleFileUploaded} />
                 
-                <Card>
-                  <CardHeader className="pb-3">
-                    <CardTitle className="text-sm font-medium">This Week</CardTitle>
-                  </CardHeader>
-                  <CardContent>
-                    <div className="text-2xl font-bold">--</div>
-                  </CardContent>
-                </Card>
-                
-                <Card>
-                  <CardHeader className="pb-3">
-                    <CardTitle className="text-sm font-medium">Completed</CardTitle>
-                  </CardHeader>
-                  <CardContent>
-                    <div className="text-2xl font-bold">--</div>
-                  </CardContent>
-                </Card>
+                {uploadedFile && (
+                  <div className="mt-4 p-4 bg-green-50 border border-green-200 rounded-lg">
+                    <div className="flex items-center space-x-2">
+                      <CheckCircle className="h-5 w-5 text-green-600" />
+                      <div>
+                        <p className="text-sm font-medium text-green-800">File uploaded successfully!</p>
+                        <p className="text-sm text-green-600">
+                          {uploadedFile.filename} ({(uploadedFile.size / 1024 / 1024).toFixed(2)} MB)
+                        </p>
+                      </div>
+                    </div>
+                  </div>
+                )}
+              </div>
+            </CardContent>
+          </Card>
+        )}
+
+        {currentStep === 2 && (
+          <Card>
+            <CardHeader>
+              <CardTitle>Step 2: Create Import Record</CardTitle>
+              <CardDescription>
+                Creating import record with Cintas Install Calendar layout configuration
+              </CardDescription>
+            </CardHeader>
+            <CardContent>
+              <div className="space-y-4">
+                <div className="flex items-center justify-center py-8">
+                  <div className="text-center">
+                    <FileText className="h-12 w-12 text-gray-400 mx-auto mb-4" />
+                    <p className="text-muted-foreground">
+                      Import record creation functionality coming soon...
+                    </p>
+                  </div>
+                </div>
               </div>
-              
-              <div className="border rounded-lg p-4">
-                <p className="text-sm text-muted-foreground">
-                  Detailed calendar summary data will be displayed here once the backend integration is complete.
-                </p>
+            </CardContent>
+          </Card>
+        )}
+
+        {currentStep === 3 && (
+          <Card>
+            <CardHeader>
+              <CardTitle>Step 3: Import Data</CardTitle>
+              <CardDescription>
+                Processing Excel file and importing data into database
+              </CardDescription>
+            </CardHeader>
+            <CardContent>
+              <div className="flex items-center justify-center py-8">
+                <div className="text-center">
+                  <Database className="h-12 w-12 text-gray-400 mx-auto mb-4" />
+                  <p className="text-muted-foreground">
+                    Data import functionality coming soon...
+                  </p>
+                </div>
               </div>
-            </div>
-          </CardContent>
-        </Card>
+            </CardContent>
+          </Card>
+        )}
+
+        {currentStep === 4 && (
+          <Card>
+            <CardHeader>
+              <CardTitle>Step 4: Generate Summary</CardTitle>
+              <CardDescription>
+                Running summary calculations and displaying results
+              </CardDescription>
+            </CardHeader>
+            <CardContent>
+              <div className="flex items-center justify-center py-8">
+                <div className="text-center">
+                  <BarChart3 className="h-12 w-12 text-gray-400 mx-auto mb-4" />
+                  <p className="text-muted-foreground">
+                    Summary generation functionality coming soon...
+                  </p>
+                </div>
+              </div>
+            </CardContent>
+          </Card>
+        )}
+
+        {/* Navigation */}
+        <div className="flex justify-between">
+          <Button
+            variant="outline"
+            onClick={() => setCurrentStep(Math.max(1, currentStep - 1))}
+            disabled={currentStep === 1}
+          >
+            Previous
+          </Button>
+          <Button
+            onClick={() => setCurrentStep(Math.min(4, currentStep + 1))}
+            disabled={currentStep === 4 || !uploadedFile}
+          >
+            Next
+          </Button>
+        </div>
       </div>
     </div>
   );