'use client';
import { useState } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import { Building, Landmark, BookOpen, ChevronDown } from 'lucide-react';
const codeGroups = [
{
title: 'National Codes',
icon: Landmark,
color: 'bg-blue-500',
codes: [
{ name: 'NBC 2025', full: 'National Building Code', sections: '3,000+', url: 'https://nrc-publications.canada.ca/eng/view/object/?id=adf1ad94-7ea8-4b08-a19f-653ebb7f45f6' },
{ name: 'NFC 2025', full: 'National Fire Code', sections: '1,000+', url: 'https://nrc-publications.canada.ca/eng/view/object/?id=e8a18373-a824-42d5-8823-bfad854c2ebd' },
{ name: 'NPC 2025', full: 'National Plumbing Code', sections: '400+', url: 'https://nrc-publications.canada.ca/eng/view/object/?id=6e7cabf5-d83e-4efd-9a1c-6515fc7cdc71' },
{ name: 'NECB 2025', full: 'National Energy Code', sections: '500+', url: 'https://nrc-publications.canada.ca/eng/view/object/?id=0d558a8e-28fe-4b5d-bb73-35b5a3703e8b' },
],
},
{
title: 'Provincial Codes',
icon: Building,
color: 'bg-emerald-500',
codes: [
{ name: 'OBC', full: 'Ontario Building Code', sections: '4,400+', province: 'ON', url: 'https://www.publications.gov.on.ca/browse-catalogues/building-code-and-guides/2024-ontarios-building-code-compendium-updated-to-january-16-2025-two-volume-pdf-set-kit/' },
{ name: 'BCBC 2024', full: 'BC Building Code', sections: '2,700+', province: 'BC', url: 'https://www2.gov.bc.ca/gov/content/industry/construction-industry/building-codes-standards/bc-codes/2024-bc-codes' },
{ name: 'ABC', full: 'Alberta Building Code', sections: '3,000+', province: 'AB', url: 'https://nrc-publications.canada.ca/eng/view/object/?id=0316d953-0d55-4311-af69-cad55efec499' },
{ name: 'QCC', full: 'Quebec Construction Code', sections: '2,900+', province: 'QC', url: 'https://nrc-publications.canada.ca/eng/view/object/?id=fbb47c66-fcda-4d5b-a045-882dfa80ab0e' },
],
},
{
title: "User's Guides",
icon: BookOpen,
color: 'bg-amber-500',
codes: [
{ name: 'Part 9 Guide', full: 'Housing & Small Buildings', sections: '1,400+', url: 'https://nrc-publications.canada.ca/eng/view/object/?id=a7a505fa-519c-436b-a23b-6f418df87e6a' },
{ name: 'Part 4 Guide', full: 'Structural Design', sections: '400+', url: 'https://nrc-publications.canada.ca/eng/view/object/?id=b9fddc27-86f2-496b-9aa4-b66c45164ba6' },
{ name: 'NECB Guide', full: 'Energy Code Guide', sections: '100+', url: 'https://nrc-publications.canada.ca/eng/view/object/?id=c6504d98-2da4-43c5-a8f6-360d6e640f88' },
],
},
];
export default function CodeList() {
const [openAccordions, setOpenAccordions] = useState<Set<number>>(new Set([0]));
const toggleAccordion = (index: number) => {
setOpenAccordions((prev) => {
const newSet = new Set(prev);
if (newSet.has(index)) {
newSet.delete(index);
} else {
newSet.add(index);
}
return newSet;
});
};
return (
<section id="codes" className="py-24 bg-white border-t border-slate-200">
<div className="max-w-6xl mx-auto px-6">
<div className="text-center mb-16">
<span className="inline-block px-4 py-1 bg-amber-100 text-amber-700 rounded-full text-sm font-medium mb-4">
Supported Codes
</span>
<h2 className="text-3xl md:text-4xl font-bold mb-4 pb-1 bg-gradient-to-r from-cyan-500 to-blue-600 bg-clip-text text-transparent hover:from-blue-600 hover:to-cyan-500 hover:drop-shadow-[0_0_15px_rgba(6,182,212,0.5)] transition-all duration-300 cursor-default">
Comprehensive Coverage
</h2>
<p className="text-slate-600 max-w-xl mx-auto">
From National Codes to Provincial Codes and User Guides,
we support all major Canadian building codes.
</p>
</div>
{/* Desktop Grid */}
<div className="hidden md:grid md:grid-cols-3 gap-8">
{codeGroups.map((group) => (
<div key={group.title}>
<div className="bg-white rounded-2xl shadow-sm border border-slate-100 overflow-hidden h-full hover:shadow-lg hover:border-cyan-200 hover:-translate-y-1 transition-all duration-300">
{/* Header */}
<div className={`${group.color} p-4 flex items-center gap-3`}>
<group.icon className="w-6 h-6 text-white" />
<h3 className="text-lg font-bold text-white">{group.title}</h3>
</div>
{/* Code list */}
<div className="p-4 space-y-3">
{group.codes.map((code) => (
<a
key={code.name}
href={code.url}
target="_blank"
rel="noopener noreferrer"
className="block group p-3 bg-slate-50 rounded-xl hover:bg-cyan-50 hover:border-cyan-200 border border-transparent transition-all cursor-pointer"
>
<div className="flex items-center justify-between mb-1">
<span className="font-semibold text-slate-900 group-hover:text-cyan-700">
{code.name}
</span>
{'province' in code && (
<span className="text-xs bg-slate-200 text-slate-600 px-2 py-0.5 rounded">
{code.province}
</span>
)}
</div>
<div className="text-sm text-slate-500 mb-1">
{code.full}
</div>
<div className="text-xs text-slate-400">
{code.sections} sections
</div>
</a>
))}
</div>
</div>
</div>
))}
</div>
{/* Mobile Accordion */}
<div className="md:hidden space-y-3">
{codeGroups.map((group, groupIndex) => (
<div key={group.title} className="bg-white rounded-xl shadow-sm border border-slate-100 overflow-hidden">
{/* Accordion Header */}
<button
onClick={() => toggleAccordion(groupIndex)}
className={`${group.color} p-4 flex items-center justify-between w-full`}
>
<div className="flex items-center gap-3">
<group.icon className="w-5 h-5 text-white" />
<h3 className="text-base font-bold text-white">{group.title}</h3>
</div>
<ChevronDown
className={`w-5 h-5 text-white transition-transform duration-300 ${
openAccordions.has(groupIndex) ? 'rotate-180' : ''
}`}
/>
</button>
{/* Accordion Content */}
<AnimatePresence>
{openAccordions.has(groupIndex) && (
<motion.div
initial={{ height: 0, opacity: 0 }}
animate={{ height: 'auto', opacity: 1 }}
exit={{ height: 0, opacity: 0 }}
transition={{ duration: 0.3, ease: 'easeInOut' }}
className="overflow-hidden"
>
<div className="p-3 space-y-2">
{group.codes.map((code) => (
<a
key={code.name}
href={code.url}
target="_blank"
rel="noopener noreferrer"
className="block p-3 bg-slate-50 rounded-lg hover:bg-cyan-50 hover:border-cyan-200 border border-transparent transition-all"
>
<div className="flex items-center justify-between mb-1">
<span className="font-semibold text-slate-900 text-sm">
{code.name}
</span>
{'province' in code && (
<span className="text-xs bg-slate-200 text-slate-600 px-2 py-0.5 rounded">
{code.province}
</span>
)}
</div>
<div className="text-xs text-slate-500">
{code.full} • {code.sections} sections
</div>
</a>
))}
</div>
</motion.div>
)}
</AnimatePresence>
</div>
))}
</div>
</div>
</section>
);
}