|
|
@@ -1,13 +1,25 @@
|
|
|
'use client';
|
|
|
|
|
|
import { useState, useEffect, useCallback } from 'react';
|
|
|
-import { FileText, Fuel } from 'lucide-react';
|
|
|
-import { Card, CardContent } from '@/components/ui/card';
|
|
|
-import { getImportsByLayoutName } from '@/app/actions/imports';
|
|
|
+import { FileText, Fuel, Upload, Database, BarChart3, CheckCircle, Loader2, History, PlusCircle } from 'lucide-react';
|
|
|
+import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '@/components/ui/card';
|
|
|
+import { Button } from '@/components/ui/button';
|
|
|
+import { UploadForm } from '@/app/components/uploadForm';
|
|
|
+import { createTerraTechImportRecord, processTerraTechImportData } from '@/app/actions/terratech-workflow';
|
|
|
+import { getImportsByLayoutName, getTerraTechFacilitySummary } from '@/app/actions/imports';
|
|
|
import { TerraTechImportsTable } from '@/app/components/terratech/TerraTechImportsTable';
|
|
|
import { TerraTechSummaryDialog } from '@/app/components/terratech/TerraTechSummaryDialog';
|
|
|
import { useToast } from '@/hooks/use-toast';
|
|
|
|
|
|
+interface FileData {
|
|
|
+ id: string;
|
|
|
+ filename: string;
|
|
|
+ mimetype: string;
|
|
|
+ size: number;
|
|
|
+ createdAt: string;
|
|
|
+ updatedAt: string;
|
|
|
+}
|
|
|
+
|
|
|
interface Import {
|
|
|
id: number;
|
|
|
name: string;
|
|
|
@@ -30,6 +42,13 @@ interface RawImportData {
|
|
|
};
|
|
|
}
|
|
|
|
|
|
+interface SummaryData {
|
|
|
+ importId: number;
|
|
|
+ importName: string;
|
|
|
+ layoutName: string;
|
|
|
+ rows: any[];
|
|
|
+}
|
|
|
+
|
|
|
const LAYOUT_NAME = 'TerraTech - GasOilWater Summary';
|
|
|
|
|
|
export default function TerraTechFacilitySummariesPage() {
|
|
|
@@ -39,8 +58,21 @@ export default function TerraTechFacilitySummariesPage() {
|
|
|
const [selectedImportId, setSelectedImportId] = useState<number | null>(null);
|
|
|
const { toast } = useToast();
|
|
|
|
|
|
+ // Workflow state
|
|
|
+ const [viewMode, setViewMode] = useState<'imports' | 'new-import' | 'summary'>('imports');
|
|
|
+ const [currentStep, setCurrentStep] = useState(1);
|
|
|
+ const [uploadedFile, setUploadedFile] = useState<FileData | null>(null);
|
|
|
+ const [isProcessing, setIsProcessing] = useState(false);
|
|
|
+ const [importRecord, setImportRecord] = useState<Import | null>(null);
|
|
|
+ const [summaryData, setSummaryData] = useState<SummaryData | null>(null);
|
|
|
+ const [error, setError] = useState<string | null>(null);
|
|
|
+ const [selectedSummaryImport, setSelectedSummaryImport] = useState<Import | null>(null);
|
|
|
+
|
|
|
const loadImports = useCallback(async () => {
|
|
|
try {
|
|
|
+ setLoading(true);
|
|
|
+ setError(null);
|
|
|
+
|
|
|
const result = await getImportsByLayoutName(LAYOUT_NAME);
|
|
|
if (result.success && result.data) {
|
|
|
const transformedImports = result.data.map((item: RawImportData) => ({
|
|
|
@@ -79,12 +111,127 @@ export default function TerraTechFacilitySummariesPage() {
|
|
|
loadImports();
|
|
|
}, [loadImports]);
|
|
|
|
|
|
+ // Workflow handlers
|
|
|
+ const handleFileUploaded = (file: FileData) => {
|
|
|
+ setUploadedFile(file);
|
|
|
+ setCurrentStep(2);
|
|
|
+ setError(null);
|
|
|
+ };
|
|
|
+
|
|
|
+ const handleCreateImportRecord = async () => {
|
|
|
+ if (!uploadedFile) return;
|
|
|
+
|
|
|
+ setIsProcessing(true);
|
|
|
+ setError(null);
|
|
|
+
|
|
|
+ try {
|
|
|
+ const result = await createTerraTechImportRecord(uploadedFile.id, uploadedFile.filename);
|
|
|
+
|
|
|
+ if (result.success && result.data) {
|
|
|
+ const importData = result.data;
|
|
|
+
|
|
|
+ const importRecordData: Import = {
|
|
|
+ id: importData.id,
|
|
|
+ name: importData.name,
|
|
|
+ importDate: importData.importDate instanceof Date
|
|
|
+ ? importData.importDate.toISOString()
|
|
|
+ : String(importData.importDate),
|
|
|
+ layoutId: importData.layoutId,
|
|
|
+ layout: {
|
|
|
+ id: importData.layout?.id || 0,
|
|
|
+ name: importData.layout?.name || LAYOUT_NAME,
|
|
|
+ },
|
|
|
+ };
|
|
|
+
|
|
|
+ setImportRecord(importRecordData);
|
|
|
+ setCurrentStep(3);
|
|
|
+ } else {
|
|
|
+ setError(result.error || 'Failed to create import record');
|
|
|
+ }
|
|
|
+ } catch (err) {
|
|
|
+ setError(err instanceof Error ? err.message : 'Unknown error occurred');
|
|
|
+ } finally {
|
|
|
+ setIsProcessing(false);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const handleProcessImportData = async () => {
|
|
|
+ if (!importRecord) return;
|
|
|
+
|
|
|
+ setIsProcessing(true);
|
|
|
+ setError(null);
|
|
|
+
|
|
|
+ try {
|
|
|
+ const result = await processTerraTechImportData(importRecord.id);
|
|
|
+
|
|
|
+ if (result.success) {
|
|
|
+ setCurrentStep(4);
|
|
|
+ } else {
|
|
|
+ setError(result.error || 'Failed to process import data');
|
|
|
+ }
|
|
|
+ } catch (err) {
|
|
|
+ setError(err instanceof Error ? err.message : 'Unknown error occurred');
|
|
|
+ } finally {
|
|
|
+ setIsProcessing(false);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const handleGenerateSummary = async () => {
|
|
|
+ if (!importRecord) return;
|
|
|
+
|
|
|
+ setIsProcessing(true);
|
|
|
+ setError(null);
|
|
|
+
|
|
|
+ try {
|
|
|
+ const result = await getTerraTechFacilitySummary(importRecord.id);
|
|
|
+
|
|
|
+ if (result.success && result.data) {
|
|
|
+ setSummaryData(result.data);
|
|
|
+ setSelectedSummaryImport(importRecord);
|
|
|
+ setViewMode('summary');
|
|
|
+ } else {
|
|
|
+ setError(result.error || 'Failed to generate summary');
|
|
|
+ }
|
|
|
+ } catch (err) {
|
|
|
+ setError(err instanceof Error ? err.message : 'Failed to generate summary');
|
|
|
+ } finally {
|
|
|
+ setIsProcessing(false);
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ const handleStartNewImport = () => {
|
|
|
+ setViewMode('new-import');
|
|
|
+ setCurrentStep(1);
|
|
|
+ setUploadedFile(null);
|
|
|
+ setImportRecord(null);
|
|
|
+ setSummaryData(null);
|
|
|
+ setError(null);
|
|
|
+ };
|
|
|
+
|
|
|
+ const handleBackToImports = () => {
|
|
|
+ setViewMode('imports');
|
|
|
+ setSelectedSummaryImport(null);
|
|
|
+ setSummaryData(null);
|
|
|
+ loadImports();
|
|
|
+ };
|
|
|
+
|
|
|
function handleViewSummary(importRecord: Import) {
|
|
|
+ setSelectedSummaryImport(importRecord);
|
|
|
setSelectedImportId(importRecord.id);
|
|
|
setSummaryDialogOpen(true);
|
|
|
}
|
|
|
|
|
|
- if (loading) {
|
|
|
+ const formatDate = (dateString: string) => {
|
|
|
+ return new Date(dateString).toLocaleDateString('en-US', {
|
|
|
+ year: 'numeric',
|
|
|
+ month: 'short',
|
|
|
+ day: 'numeric',
|
|
|
+ hour: '2-digit',
|
|
|
+ minute: '2-digit'
|
|
|
+ });
|
|
|
+ };
|
|
|
+
|
|
|
+ if (loading && viewMode === 'imports') {
|
|
|
return (
|
|
|
<div className="min-h-screen bg-gradient-to-br from-gray-50 to-gray-100 dark:from-gray-900 dark:to-gray-800">
|
|
|
<div className="container mx-auto px-4 py-8">
|
|
|
@@ -115,25 +262,352 @@ export default function TerraTechFacilitySummariesPage() {
|
|
|
</div>
|
|
|
</div>
|
|
|
|
|
|
- {imports.length === 0 ? (
|
|
|
- <Card className="dark:bg-gray-800 dark:border-gray-700">
|
|
|
- <CardContent className="flex flex-col items-center justify-center py-12">
|
|
|
- <FileText className="h-12 w-12 text-muted-foreground mb-4" />
|
|
|
- <h3 className="text-lg font-semibold mb-2 text-gray-900 dark:text-white">No imports found</h3>
|
|
|
- <p className="text-muted-foreground mb-4 dark:text-gray-300 text-center">
|
|
|
- No imports using the "{LAYOUT_NAME}" layout configuration were found.
|
|
|
- <br />
|
|
|
- Import data using this layout to see it here.
|
|
|
- </p>
|
|
|
+ {error && (
|
|
|
+ <div className="mb-4 p-4 bg-red-50 border border-red-200 rounded-lg">
|
|
|
+ <p className="text-sm text-red-800">{error}</p>
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+
|
|
|
+ {/* Navigation Buttons */}
|
|
|
+ <div className="mb-6 flex gap-4">
|
|
|
+ <Button
|
|
|
+ variant={viewMode === 'imports' ? 'default' : 'outline'}
|
|
|
+ onClick={handleBackToImports}
|
|
|
+ className="flex items-center gap-2"
|
|
|
+ >
|
|
|
+ <History className="h-4 w-4" />
|
|
|
+ Prior Imports
|
|
|
+ </Button>
|
|
|
+ <Button
|
|
|
+ variant={viewMode === 'new-import' ? 'default' : 'outline'}
|
|
|
+ onClick={handleStartNewImport}
|
|
|
+ className="flex items-center gap-2"
|
|
|
+ >
|
|
|
+ <PlusCircle className="h-4 w-4" />
|
|
|
+ New Import
|
|
|
+ </Button>
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* Prior Imports View */}
|
|
|
+ {viewMode === 'imports' && (
|
|
|
+ <>
|
|
|
+ {imports.length === 0 ? (
|
|
|
+ <Card className="dark:bg-gray-800 dark:border-gray-700">
|
|
|
+ <CardContent className="flex flex-col items-center justify-center py-12">
|
|
|
+ <FileText className="h-12 w-12 text-muted-foreground mb-4" />
|
|
|
+ <h3 className="text-lg font-semibold mb-2 text-gray-900 dark:text-white">No imports found</h3>
|
|
|
+ <p className="text-muted-foreground mb-4 dark:text-gray-300 text-center">
|
|
|
+ No imports using the "{LAYOUT_NAME}" layout configuration were found.
|
|
|
+ <br />
|
|
|
+ Import data using this layout to see it here.
|
|
|
+ </p>
|
|
|
+ <Button onClick={handleStartNewImport}>
|
|
|
+ Create First Import
|
|
|
+ </Button>
|
|
|
+ </CardContent>
|
|
|
+ </Card>
|
|
|
+ ) : (
|
|
|
+ <div className="w-full">
|
|
|
+ <TerraTechImportsTable
|
|
|
+ data={imports}
|
|
|
+ onViewSummary={handleViewSummary}
|
|
|
+ />
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+ </>
|
|
|
+ )}
|
|
|
+
|
|
|
+ {/* New Import Workflow */}
|
|
|
+ {viewMode === 'new-import' && (
|
|
|
+ <div className="space-y-6">
|
|
|
+ {/* Workflow Steps */}
|
|
|
+ <div className="grid grid-cols-1 md:grid-cols-4 gap-4">
|
|
|
+ {[
|
|
|
+ {
|
|
|
+ id: 1,
|
|
|
+ title: 'Upload Excel File',
|
|
|
+ description: 'Upload the TerraTech GasOilWater Excel file',
|
|
|
+ icon: Upload,
|
|
|
+ status: currentStep >= 1 ? (uploadedFile ? 'completed' : 'pending') : 'pending',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 2,
|
|
|
+ title: 'Create Import Record',
|
|
|
+ description: 'Create import record with layout configuration',
|
|
|
+ icon: FileText,
|
|
|
+ status: currentStep >= 2 ? (importRecord ? 'completed' : 'pending') : 'disabled',
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 3,
|
|
|
+ title: 'Import Data',
|
|
|
+ description: 'Process Excel file and import data',
|
|
|
+ icon: Database,
|
|
|
+ status: currentStep > 3 ? 'completed' : (currentStep === 3 ? 'pending' : 'disabled'),
|
|
|
+ },
|
|
|
+ {
|
|
|
+ id: 4,
|
|
|
+ title: 'Generate Summary',
|
|
|
+ description: 'Run summary calculations and display results',
|
|
|
+ icon: BarChart3,
|
|
|
+ status: currentStep >= 4 ? (summaryData ? 'completed' : 'pending') : 'disabled',
|
|
|
+ },
|
|
|
+ ].map((step) => {
|
|
|
+ const Icon = step.icon;
|
|
|
+ const getStatusColor = (status: string) => {
|
|
|
+ switch (status) {
|
|
|
+ case 'completed':
|
|
|
+ return 'text-green-600 bg-green-50 border-green-200';
|
|
|
+ case 'pending':
|
|
|
+ return 'text-amber-600 bg-amber-50 border-amber-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 (
|
|
|
+ <Card
|
|
|
+ key={step.id}
|
|
|
+ className={`border-2 ${getStatusColor(step.status)}`}
|
|
|
+ >
|
|
|
+ <CardHeader className="pb-3">
|
|
|
+ <div className="flex items-center space-x-2">
|
|
|
+ <Icon className="h-5 w-5" />
|
|
|
+ <div>
|
|
|
+ <CardTitle className="text-sm font-medium">
|
|
|
+ Step {step.id}: {step.title}
|
|
|
+ </CardTitle>
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ </CardHeader>
|
|
|
+ <CardContent>
|
|
|
+ <CardDescription className="text-xs">
|
|
|
+ {step.description}
|
|
|
+ </CardDescription>
|
|
|
+ </CardContent>
|
|
|
+ </Card>
|
|
|
+ );
|
|
|
+ })}
|
|
|
+ </div>
|
|
|
+
|
|
|
+ {/* Step Content */}
|
|
|
+ <div className="space-y-6">
|
|
|
+ {currentStep === 1 && (
|
|
|
+ <Card>
|
|
|
+ <CardHeader>
|
|
|
+ <CardTitle>Step 1: Upload Excel File</CardTitle>
|
|
|
+ <CardDescription>
|
|
|
+ Upload your TerraTech GasOilWater Excel file to begin processing
|
|
|
+ </CardDescription>
|
|
|
+ </CardHeader>
|
|
|
+ <CardContent>
|
|
|
+ <div className="space-y-4">
|
|
|
+ <UploadForm onFileUploaded={handleFileUploaded} />
|
|
|
+ {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 TerraTech - GasOilWater Summary layout configuration
|
|
|
+ </CardDescription>
|
|
|
+ </CardHeader>
|
|
|
+ <CardContent>
|
|
|
+ <div className="space-y-4">
|
|
|
+ <p className="text-sm text-muted-foreground">
|
|
|
+ File: {uploadedFile?.filename}
|
|
|
+ </p>
|
|
|
+ <p className="text-sm text-muted-foreground">
|
|
|
+ Layout: {LAYOUT_NAME}
|
|
|
+ </p>
|
|
|
+ <Button
|
|
|
+ onClick={handleCreateImportRecord}
|
|
|
+ disabled={isProcessing}
|
|
|
+ className="w-full bg-amber-500 hover:bg-amber-600"
|
|
|
+ >
|
|
|
+ {isProcessing ? (
|
|
|
+ <>
|
|
|
+ <Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
|
|
+ Creating Import Record...
|
|
|
+ </>
|
|
|
+ ) : (
|
|
|
+ 'Create Import Record'
|
|
|
+ )}
|
|
|
+ </Button>
|
|
|
+ </div>
|
|
|
+ </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="space-y-4">
|
|
|
+ <p className="text-sm text-muted-foreground">
|
|
|
+ Import ID: {importRecord?.id}
|
|
|
+ </p>
|
|
|
+ <p className="text-sm text-muted-foreground">
|
|
|
+ Import Name: {importRecord?.name}
|
|
|
+ </p>
|
|
|
+ <Button
|
|
|
+ onClick={handleProcessImportData}
|
|
|
+ disabled={isProcessing}
|
|
|
+ className="w-full bg-amber-500 hover:bg-amber-600"
|
|
|
+ >
|
|
|
+ {isProcessing ? (
|
|
|
+ <>
|
|
|
+ <Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
|
|
+ Processing Import...
|
|
|
+ </>
|
|
|
+ ) : (
|
|
|
+ 'Process Import'
|
|
|
+ )}
|
|
|
+ </Button>
|
|
|
+ </div>
|
|
|
+ </CardContent>
|
|
|
+ </Card>
|
|
|
+ )}
|
|
|
+
|
|
|
+ {currentStep === 4 && (
|
|
|
+ <Card>
|
|
|
+ <CardHeader>
|
|
|
+ <CardTitle>Step 4: Generate Summary</CardTitle>
|
|
|
+ <CardDescription>
|
|
|
+ Running summary calculations and displaying results
|
|
|
+ </CardDescription>
|
|
|
+ </CardHeader>
|
|
|
+ <CardContent>
|
|
|
+ <div className="space-y-4">
|
|
|
+ <p className="text-sm text-muted-foreground">
|
|
|
+ Import ID: {importRecord?.id}
|
|
|
+ </p>
|
|
|
+ <Button
|
|
|
+ onClick={handleGenerateSummary}
|
|
|
+ disabled={isProcessing}
|
|
|
+ className="w-full bg-amber-500 hover:bg-amber-600"
|
|
|
+ >
|
|
|
+ {isProcessing ? (
|
|
|
+ <>
|
|
|
+ <Loader2 className="mr-2 h-4 w-4 animate-spin" />
|
|
|
+ Generating Summary...
|
|
|
+ </>
|
|
|
+ ) : (
|
|
|
+ 'Generate Summary'
|
|
|
+ )}
|
|
|
+ </Button>
|
|
|
+ </div>
|
|
|
+ </CardContent>
|
|
|
+ </Card>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
+
|
|
|
+ {/* Summary Results View */}
|
|
|
+ {viewMode === 'summary' && selectedSummaryImport && summaryData && (
|
|
|
+ <Card>
|
|
|
+ <CardHeader>
|
|
|
+ <div className="flex justify-between items-start">
|
|
|
+ <div>
|
|
|
+ <CardTitle>Summary Results</CardTitle>
|
|
|
+ <CardDescription>
|
|
|
+ {selectedSummaryImport.name} - {formatDate(selectedSummaryImport.importDate)}
|
|
|
+ </CardDescription>
|
|
|
+ </div>
|
|
|
+ <Button
|
|
|
+ variant="outline"
|
|
|
+ onClick={handleBackToImports}
|
|
|
+ className="flex items-center gap-2"
|
|
|
+ >
|
|
|
+ <History className="h-4 w-4" />
|
|
|
+ Back to Imports
|
|
|
+ </Button>
|
|
|
+ </div>
|
|
|
+ </CardHeader>
|
|
|
+ <CardContent>
|
|
|
+ {isProcessing ? (
|
|
|
+ <div className="flex justify-center py-8">
|
|
|
+ <Loader2 className="h-8 w-8 animate-spin text-amber-500" />
|
|
|
+ </div>
|
|
|
+ ) : summaryData.rows.length === 0 ? (
|
|
|
+ <div className="text-center py-8">
|
|
|
+ <p className="text-muted-foreground mb-4">No summary data available</p>
|
|
|
+ </div>
|
|
|
+ ) : (
|
|
|
+ <div className="overflow-x-auto">
|
|
|
+ <table className="min-w-full divide-y divide-gray-200 dark:divide-gray-700">
|
|
|
+ <thead className="bg-gray-50 dark:bg-gray-800">
|
|
|
+ <tr>
|
|
|
+ <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Well Name</th>
|
|
|
+ <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">CorpID</th>
|
|
|
+ <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Facility ID</th>
|
|
|
+ <th className="px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Gas</th>
|
|
|
+ <th className="px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Oil</th>
|
|
|
+ <th className="px-6 py-3 text-right text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">Water</th>
|
|
|
+ <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">State</th>
|
|
|
+ <th className="px-6 py-3 text-left text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider">County</th>
|
|
|
+ </tr>
|
|
|
+ </thead>
|
|
|
+ <tbody className="bg-white dark:bg-gray-800 divide-y divide-gray-200 dark:divide-gray-700">
|
|
|
+ {summaryData.rows.slice(0, 50).map((row, index) => (
|
|
|
+ <tr
|
|
|
+ key={`${row.wellName}-${index}`}
|
|
|
+ className={index % 2 === 0
|
|
|
+ ? 'bg-white dark:bg-gray-800'
|
|
|
+ : 'bg-gray-50 dark:bg-gray-700/50'
|
|
|
+ }
|
|
|
+ >
|
|
|
+ <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100">{row.wellName || '-'}</td>
|
|
|
+ <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100">{row.corpId || '-'}</td>
|
|
|
+ <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100">{row.facilityId || '-'}</td>
|
|
|
+ <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100 text-right">
|
|
|
+ {row.gas !== null ? row.gas.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) : '-'}
|
|
|
+ </td>
|
|
|
+ <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100 text-right">
|
|
|
+ {row.oil !== null ? row.oil.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) : '-'}
|
|
|
+ </td>
|
|
|
+ <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100 text-right">
|
|
|
+ {row.water !== null ? row.water.toLocaleString('en-US', { minimumFractionDigits: 2, maximumFractionDigits: 2 }) : '-'}
|
|
|
+ </td>
|
|
|
+ <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100">{row.state || '-'}</td>
|
|
|
+ <td className="px-6 py-4 whitespace-nowrap text-sm text-gray-900 dark:text-gray-100">{row.county || '-'}</td>
|
|
|
+ </tr>
|
|
|
+ ))}
|
|
|
+ </tbody>
|
|
|
+ </table>
|
|
|
+ {summaryData.rows.length > 50 && (
|
|
|
+ <p className="text-sm text-muted-foreground mt-4 text-center">
|
|
|
+ Showing 50 of {summaryData.rows.length} records. Use the dialog to view all records.
|
|
|
+ </p>
|
|
|
+ )}
|
|
|
+ </div>
|
|
|
+ )}
|
|
|
</CardContent>
|
|
|
</Card>
|
|
|
- ) : (
|
|
|
- <div className="w-full">
|
|
|
- <TerraTechImportsTable
|
|
|
- data={imports}
|
|
|
- onViewSummary={handleViewSummary}
|
|
|
- />
|
|
|
- </div>
|
|
|
)}
|
|
|
|
|
|
<TerraTechSummaryDialog
|