Files
LabWise/components/SDSLibrary.tsx
2026-03-18 17:10:16 -05:00

204 lines
6.8 KiB
TypeScript

import { useState } from "react";
import { Card } from "./ui/card";
import { Button } from "./ui/button";
import { Input } from "./ui/input";
import { Badge } from "./ui/badge";
import {
Search,
Download,
ExternalLink,
AlertTriangle,
Flame,
Skull,
Droplet,
FileText
} from "lucide-react";
interface SDS {
id: string;
chemicalName: string;
casNumber: string;
manufacturer: string;
revisionDate: string;
hazards: string[];
pictograms: string[];
}
export function SDSLibrary() {
const [searchQuery, setSearchQuery] = useState("");
const sdsDatabase: SDS[] = [
{
id: "1",
chemicalName: "Acetone",
casNumber: "67-64-1",
manufacturer: "Sigma-Aldrich",
revisionDate: "2024-08-15",
hazards: ["Flammable", "Eye Irritation"],
pictograms: ["flame", "exclamation"]
},
{
id: "2",
chemicalName: "Sodium Hydroxide",
casNumber: "1310-73-2",
manufacturer: "Fisher Scientific",
revisionDate: "2024-09-20",
hazards: ["Corrosive", "Skin Burns", "Eye Damage"],
pictograms: ["corrosion"]
},
{
id: "3",
chemicalName: "Benzene",
casNumber: "71-43-2",
manufacturer: "VWR",
revisionDate: "2024-07-10",
hazards: ["Carcinogenic", "Flammable", "Toxic"],
pictograms: ["flame", "health-hazard", "exclamation"]
},
{
id: "4",
chemicalName: "Hydrochloric Acid",
casNumber: "7647-01-0",
manufacturer: "Sigma-Aldrich",
revisionDate: "2024-10-05",
hazards: ["Corrosive", "Acute Toxicity"],
pictograms: ["corrosion", "exclamation"]
},
{
id: "5",
chemicalName: "Ethanol",
casNumber: "64-17-5",
manufacturer: "Fisher Scientific",
revisionDate: "2024-11-01",
hazards: ["Flammable"],
pictograms: ["flame"]
}
];
const filteredSDS = sdsDatabase.filter(sds =>
sds.chemicalName.toLowerCase().includes(searchQuery.toLowerCase()) ||
sds.casNumber.includes(searchQuery)
);
const getPictogramIcon = (pictogram: string) => {
switch (pictogram) {
case "flame": return <Flame className="w-5 h-5" />;
case "corrosion": return <Droplet className="w-5 h-5" />;
case "health-hazard": return <Skull className="w-5 h-5" />;
case "exclamation": return <AlertTriangle className="w-5 h-5" />;
default: return <AlertTriangle className="w-5 h-5" />;
}
};
return (
<div className="p-8">
<div className="max-w-6xl mx-auto">
<div className="mb-8">
<h1 className="text-foreground mb-2">Safety Data Sheets Library</h1>
<p className="text-muted-foreground">Access comprehensive safety information for chemicals in your lab</p>
</div>
{/* Search */}
<Card className="p-4 mb-6">
<div className="relative">
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 text-muted-foreground w-5 h-5" />
<Input
placeholder="Search by chemical name or CAS number..."
className="pl-10"
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
/>
</div>
</Card>
{/* Quick Stats */}
<div className="grid grid-cols-1 md:grid-cols-4 gap-4 mb-6">
<Card className="p-4">
<p className="text-muted-foreground mb-1">Total SDS</p>
<p className="text-foreground">{sdsDatabase.length}</p>
</Card>
<Card className="p-4">
<p className="text-muted-foreground mb-1">Updated This Month</p>
<p className="text-foreground">2</p>
</Card>
<Card className="p-4">
<p className="text-muted-foreground mb-1">Expiring Soon</p>
<p className="text-amber-600">1</p>
</Card>
<Card className="p-4">
<p className="text-muted-foreground mb-1">Downloads</p>
<p className="text-foreground">156</p>
</Card>
</div>
{/* SDS List */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-4">
{filteredSDS.map((sds) => (
<Card key={sds.id} className="p-6 hover:shadow-md transition-shadow">
<div className="flex items-start justify-between mb-4">
<div className="flex-1">
<h3 className="text-foreground mb-1">{sds.chemicalName}</h3>
<p className="text-muted-foreground">CAS: {sds.casNumber}</p>
</div>
<FileText className="w-6 h-6 text-muted-foreground" />
</div>
<div className="space-y-3 mb-4">
<div>
<p className="text-muted-foreground mb-1">Manufacturer</p>
<p className="text-foreground">{sds.manufacturer}</p>
</div>
<div>
<p className="text-muted-foreground mb-1">Revision Date</p>
<p className="text-foreground">{sds.revisionDate}</p>
</div>
<div>
<p className="text-muted-foreground mb-2">Hazard Pictograms</p>
<div className="flex gap-2">
{sds.pictograms.map((pictogram, idx) => (
<div
key={idx}
className="w-10 h-10 border-2 border-red-500 rounded flex items-center justify-center text-red-600"
>
{getPictogramIcon(pictogram)}
</div>
))}
</div>
</div>
<div>
<p className="text-muted-foreground mb-2">Key Hazards</p>
<div className="flex flex-wrap gap-2">
{sds.hazards.map((hazard, idx) => (
<Badge key={idx} variant="outline" className="text-orange-700 border-orange-300">
{hazard}
</Badge>
))}
</div>
</div>
</div>
<div className="flex gap-2 pt-4 border-t border-border">
<Button variant="outline" className="flex-1">
<Download className="w-4 h-4 mr-2" />
Download
</Button>
<Button variant="outline" className="flex-1">
<ExternalLink className="w-4 h-4 mr-2" />
View
</Button>
</div>
</Card>
))}
</div>
{filteredSDS.length === 0 && (
<Card className="p-12 text-center">
<FileText className="w-12 h-12 text-gray-400 mx-auto mb-4" />
<h3 className="text-gray-900 mb-2">No SDS Found</h3>
<p className="text-gray-600">Try searching with a different chemical name or CAS number</p>
</Card>
)}
</div>
</div>
);
}