This commit is contained in:
2026-03-18 17:10:16 -05:00
commit b0cd20ced5
59 changed files with 7620 additions and 0 deletions

View 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>
);
}