initial
This commit is contained in:
287
components/EHSDocumentation.tsx
Normal file
287
components/EHSDocumentation.tsx
Normal file
@@ -0,0 +1,287 @@
|
||||
import { useState } from "react";
|
||||
import { Card } from "./ui/card";
|
||||
import { Button } from "./ui/button";
|
||||
import { Input } from "./ui/input";
|
||||
import { Label } from "./ui/label";
|
||||
import { Textarea } from "./ui/textarea";
|
||||
import { Badge } from "./ui/badge";
|
||||
import {
|
||||
FileText,
|
||||
CheckCircle2,
|
||||
Clock,
|
||||
AlertCircle,
|
||||
Plus,
|
||||
Calendar
|
||||
} from "lucide-react";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
DialogTrigger,
|
||||
} from "./ui/dialog";
|
||||
import {
|
||||
Select,
|
||||
SelectContent,
|
||||
SelectItem,
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "./ui/select";
|
||||
|
||||
interface Document {
|
||||
id: string;
|
||||
title: string;
|
||||
type: string;
|
||||
status: "complete" | "pending" | "overdue";
|
||||
dueDate: string;
|
||||
lastModified: string;
|
||||
}
|
||||
|
||||
export function EHSDocumentation() {
|
||||
const [selectedDoc, setSelectedDoc] = useState<Document | null>(null);
|
||||
|
||||
const documents: Document[] = [
|
||||
{
|
||||
id: "1",
|
||||
title: "Quarterly Chemical Inventory Report",
|
||||
type: "Inventory Report",
|
||||
status: "complete",
|
||||
dueDate: "2024-12-01",
|
||||
lastModified: "2024-11-20"
|
||||
},
|
||||
{
|
||||
id: "2",
|
||||
title: "Hazardous Waste Disposal Form",
|
||||
type: "Waste Disposal",
|
||||
status: "pending",
|
||||
dueDate: "2024-11-30",
|
||||
lastModified: "2024-11-22"
|
||||
},
|
||||
{
|
||||
id: "3",
|
||||
title: "Lab Safety Inspection Checklist",
|
||||
type: "Inspection",
|
||||
status: "overdue",
|
||||
dueDate: "2024-11-15",
|
||||
lastModified: "2024-10-30"
|
||||
},
|
||||
{
|
||||
id: "4",
|
||||
title: "Annual Training Documentation",
|
||||
type: "Training",
|
||||
status: "complete",
|
||||
dueDate: "2024-09-30",
|
||||
lastModified: "2024-09-28"
|
||||
}
|
||||
];
|
||||
|
||||
const getStatusBadge = (status: string) => {
|
||||
switch (status) {
|
||||
case "complete":
|
||||
return (
|
||||
<Badge className="bg-accent text-primary">
|
||||
<CheckCircle2 className="w-3 h-3 mr-1" />
|
||||
Complete
|
||||
</Badge>
|
||||
);
|
||||
case "pending":
|
||||
return (
|
||||
<Badge className="bg-secondary text-primary">
|
||||
<Clock className="w-3 h-3 mr-1" />
|
||||
Pending
|
||||
</Badge>
|
||||
);
|
||||
case "overdue":
|
||||
return (
|
||||
<Badge className="bg-red-100 text-red-700">
|
||||
<AlertCircle className="w-3 h-3 mr-1" />
|
||||
Overdue
|
||||
</Badge>
|
||||
);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="p-8">
|
||||
<div className="max-w-6xl mx-auto">
|
||||
<div className="flex items-center justify-between mb-8">
|
||||
<div>
|
||||
<h1 className="text-foreground mb-2">EHS Documentation</h1>
|
||||
<p className="text-muted-foreground">Manage and track your Environmental Health & Safety documentation</p>
|
||||
</div>
|
||||
<Dialog>
|
||||
<DialogTrigger asChild>
|
||||
<Button className="bg-primary hover:bg-primary/90">
|
||||
<Plus className="w-4 h-4 mr-2" />
|
||||
New Document
|
||||
</Button>
|
||||
</DialogTrigger>
|
||||
<DialogContent className="max-w-2xl">
|
||||
<DialogHeader>
|
||||
<DialogTitle>Create EHS Document</DialogTitle>
|
||||
<DialogDescription>
|
||||
AI-assisted form filling using your inventory history
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div className="space-y-4 py-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="doc-type">Document Type</Label>
|
||||
<Select>
|
||||
<SelectTrigger id="doc-type">
|
||||
<SelectValue placeholder="Select document type" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="inventory">Chemical Inventory Report</SelectItem>
|
||||
<SelectItem value="waste">Waste Disposal Form</SelectItem>
|
||||
<SelectItem value="inspection">Safety Inspection</SelectItem>
|
||||
<SelectItem value="incident">Incident Report</SelectItem>
|
||||
<SelectItem value="training">Training Documentation</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="doc-title">Document Title</Label>
|
||||
<Input id="doc-title" placeholder="Enter document title" />
|
||||
</div>
|
||||
|
||||
<div className="bg-accent border border-border rounded-lg p-4">
|
||||
<div className="flex items-start gap-3">
|
||||
<CheckCircle2 className="w-5 h-5 text-primary mt-0.5" />
|
||||
<div>
|
||||
<p className="text-foreground mb-1">AI Assistant Ready</p>
|
||||
<p className="text-muted-foreground">
|
||||
I can auto-fill this form using data from your inventory history, recent chemical usage, and previous documentation.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="description">Description</Label>
|
||||
<Textarea
|
||||
id="description"
|
||||
placeholder="Describe the purpose or scope of this document..."
|
||||
rows={4}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="grid grid-cols-2 gap-4">
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="due-date">Due Date</Label>
|
||||
<Input id="due-date" type="date" />
|
||||
</div>
|
||||
<div className="space-y-2">
|
||||
<Label htmlFor="responsible">Responsible Person</Label>
|
||||
<Input id="responsible" placeholder="Name" />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex gap-2">
|
||||
<Button className="flex-1 bg-primary hover:bg-primary/90">
|
||||
Create & AI Fill
|
||||
</Button>
|
||||
<Button variant="outline" className="flex-1">
|
||||
Create Empty
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
</div>
|
||||
|
||||
{/* Summary Cards */}
|
||||
<div className="grid grid-cols-1 md:grid-cols-4 gap-4 mb-8">
|
||||
<Card className="p-6">
|
||||
<p className="text-muted-foreground mb-1">Total Documents</p>
|
||||
<p className="text-foreground">{documents.length}</p>
|
||||
</Card>
|
||||
<Card className="p-6">
|
||||
<p className="text-muted-foreground mb-1">Complete</p>
|
||||
<p className="text-primary">
|
||||
{documents.filter(d => d.status === "complete").length}
|
||||
</p>
|
||||
</Card>
|
||||
<Card className="p-6">
|
||||
<p className="text-muted-foreground mb-1">Pending</p>
|
||||
<p className="text-[#7ab5a0]">
|
||||
{documents.filter(d => d.status === "pending").length}
|
||||
</p>
|
||||
</Card>
|
||||
<Card className="p-6">
|
||||
<p className="text-muted-foreground mb-1">Overdue</p>
|
||||
<p className="text-red-600">
|
||||
{documents.filter(d => d.status === "overdue").length}
|
||||
</p>
|
||||
</Card>
|
||||
</div>
|
||||
|
||||
{/* Documents List */}
|
||||
<div className="space-y-4">
|
||||
{documents.map((doc) => (
|
||||
<Card
|
||||
key={doc.id}
|
||||
className="p-6 hover:shadow-md transition-shadow cursor-pointer"
|
||||
onClick={() => setSelectedDoc(doc)}
|
||||
>
|
||||
<div className="flex items-start justify-between">
|
||||
<div className="flex items-start gap-4 flex-1">
|
||||
<div className="p-3 bg-muted rounded-lg">
|
||||
<FileText className="w-6 h-6 text-primary" />
|
||||
</div>
|
||||
<div className="flex-1">
|
||||
<div className="flex items-center gap-3 mb-2">
|
||||
<h3 className="text-foreground">{doc.title}</h3>
|
||||
{getStatusBadge(doc.status)}
|
||||
</div>
|
||||
<p className="text-muted-foreground mb-3">{doc.type}</p>
|
||||
<div className="flex items-center gap-6 text-muted-foreground">
|
||||
<div className="flex items-center gap-2">
|
||||
<Calendar className="w-4 h-4" />
|
||||
<span>Due: {doc.dueDate}</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<Clock className="w-4 h-4" />
|
||||
<span>Modified: {doc.lastModified}</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Button variant="outline">View</Button>
|
||||
</div>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* AI Features Info */}
|
||||
<Card className="p-6 mt-8 bg-gradient-to-r from-accent to-secondary border-border">
|
||||
<div className="flex items-start gap-4">
|
||||
<div className="p-3 bg-card rounded-lg">
|
||||
<CheckCircle2 className="w-6 h-6 text-primary" />
|
||||
</div>
|
||||
<div>
|
||||
<h3 className="text-foreground mb-2">AI-Powered Documentation</h3>
|
||||
<p className="text-muted-foreground mb-3">
|
||||
Labwise uses your inventory history and chemical usage data to automatically fill out EHS forms, saving you hours of tedious paperwork.
|
||||
</p>
|
||||
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
|
||||
<div>
|
||||
<p className="text-primary">✓ Auto-fill from inventory</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-primary">✓ Suggest compliance requirements</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-primary">✓ Track submission deadlines</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user