170 lines
6.5 KiB
TypeScript
170 lines
6.5 KiB
TypeScript
'use client';
|
|
|
|
import React, { useState } from 'react';
|
|
import { useTranslations } from 'next-intl';
|
|
|
|
interface KeyValueItem {
|
|
label: string;
|
|
value: string;
|
|
unit?: string;
|
|
}
|
|
|
|
interface VoltageTable {
|
|
voltageLabel: string;
|
|
metaItems: KeyValueItem[];
|
|
columns: Array<{ key: string; label: string }>;
|
|
rows: Array<{ configuration: string; cells: string[] }>;
|
|
}
|
|
|
|
interface ProductTechnicalDataProps {
|
|
data: {
|
|
technicalItems: KeyValueItem[];
|
|
voltageTables: VoltageTable[];
|
|
};
|
|
}
|
|
|
|
export default function ProductTechnicalData({ data }: ProductTechnicalDataProps) {
|
|
const t = useTranslations('Products');
|
|
const [expandedTables, setExpandedTables] = useState<Record<number, boolean>>({});
|
|
|
|
if (!data) return null;
|
|
const { technicalItems = [], voltageTables = [] } = data;
|
|
|
|
const toggleTable = (idx: number) => {
|
|
setExpandedTables((prev) => ({
|
|
...prev,
|
|
[idx]: !prev[idx],
|
|
}));
|
|
};
|
|
|
|
return (
|
|
<div className="space-y-16">
|
|
{technicalItems.length > 0 && (
|
|
<div className="bg-white p-8 md:p-12 rounded-[32px] shadow-sm border border-neutral-dark/5">
|
|
<h3 className="text-2xl font-bold text-primary mb-8 flex items-center gap-3">
|
|
<div className="w-2 h-8 bg-accent rounded-full" />
|
|
General Data
|
|
</h3>
|
|
<dl className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-x-12 gap-y-8">
|
|
{technicalItems.map((item, idx) => (
|
|
<div key={idx} className="flex flex-col group">
|
|
<dt className="text-sm font-bold uppercase tracking-widest text-primary/40 mb-2 group-hover:text-accent transition-colors">
|
|
{item.label}
|
|
</dt>
|
|
<dd className="text-lg font-semibold text-text-primary">
|
|
{item.value}{' '}
|
|
{item.unit && (
|
|
<span className="text-sm font-normal text-text-secondary ml-1">
|
|
{item.unit}
|
|
</span>
|
|
)}
|
|
</dd>
|
|
</div>
|
|
))}
|
|
</dl>
|
|
</div>
|
|
)}
|
|
|
|
{voltageTables.map((table, idx) => {
|
|
const isExpanded = expandedTables[idx];
|
|
const hasManyRows = table.rows.length > 10;
|
|
|
|
return (
|
|
<div
|
|
key={idx}
|
|
className="bg-white p-8 md:p-12 rounded-[32px] shadow-sm border border-neutral-dark/5 overflow-hidden"
|
|
>
|
|
<h3 className="text-2xl font-bold text-primary mb-8 flex items-center gap-3">
|
|
<div className="w-2 h-8 bg-accent rounded-full" />
|
|
{table.voltageLabel !== 'Voltage unknown' &&
|
|
table.voltageLabel !== 'Spannung unbekannt'
|
|
? table.voltageLabel
|
|
: 'Technical Specifications'}
|
|
</h3>
|
|
|
|
{table.metaItems.length > 0 && (
|
|
<dl className="grid grid-cols-1 sm:grid-cols-2 md:grid-cols-3 lg:grid-cols-4 gap-8 mb-12 bg-neutral-light/50 p-8 rounded-2xl border border-neutral-dark/5">
|
|
{table.metaItems.map((item, mIdx) => (
|
|
<div key={mIdx}>
|
|
<dt className="text-[10px] font-black uppercase tracking-[0.2em] text-primary/40 mb-1">
|
|
{item.label}
|
|
</dt>
|
|
<dd className="font-bold text-primary">
|
|
{item.value} {item.unit}
|
|
</dd>
|
|
</div>
|
|
))}
|
|
</dl>
|
|
)}
|
|
|
|
<div className="relative">
|
|
<div
|
|
id={`voltage-table-${idx}`}
|
|
className={`overflow-x-auto -mx-8 md:-mx-12 px-8 md:px-12 transition-all duration-500 ease-in-out ${
|
|
!isExpanded && hasManyRows ? 'max-h-[400px] overflow-y-hidden' : 'max-h-[none]'
|
|
}`}
|
|
>
|
|
<table className="min-w-full border-separate border-spacing-0">
|
|
<thead>
|
|
<tr>
|
|
<th
|
|
scope="col"
|
|
className="px-3 py-3 text-left text-[10px] font-black text-primary/40 uppercase tracking-[0.2em] sticky left-0 bg-white z-10 border-b border-neutral-dark/10"
|
|
>
|
|
Config.
|
|
</th>
|
|
{table.columns.map((col, cIdx) => (
|
|
<th
|
|
key={cIdx}
|
|
scope="col"
|
|
className="px-3 py-3 text-left text-[10px] font-black text-primary/40 uppercase tracking-[0.2em] whitespace-nowrap border-b border-neutral-dark/10"
|
|
>
|
|
{col.label}
|
|
</th>
|
|
))}
|
|
</tr>
|
|
</thead>
|
|
<tbody className="divide-y divide-neutral-dark/5">
|
|
{table.rows.map((row, rIdx) => (
|
|
<tr key={rIdx} className="hover:bg-neutral-light/50 transition-colors group">
|
|
<td className="px-3 py-2 text-xs font-bold text-primary sticky left-0 bg-white group-hover:bg-neutral-light/50 z-10 whitespace-nowrap">
|
|
{row.configuration}
|
|
</td>
|
|
{row.cells.map((cell, cellIdx) => (
|
|
<td
|
|
key={cellIdx}
|
|
className="px-3 py-2 text-xs text-text-secondary whitespace-nowrap"
|
|
>
|
|
{cell}
|
|
</td>
|
|
))}
|
|
</tr>
|
|
))}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
|
|
{!isExpanded && hasManyRows && (
|
|
<div className="absolute bottom-0 left-0 right-0 h-32 bg-gradient-to-t from-white via-white/80 to-transparent z-20 pointer-events-none" />
|
|
)}
|
|
</div>
|
|
|
|
{hasManyRows && (
|
|
<div className="mt-8 flex justify-center">
|
|
<button
|
|
onClick={() => toggleTable(idx)}
|
|
aria-expanded={isExpanded}
|
|
aria-controls={`voltage-table-${idx}`}
|
|
className="px-8 py-3 rounded-full bg-primary text-white text-sm font-bold uppercase tracking-widest hover:bg-accent hover:text-primary transition-all duration-300 shadow-lg hover:shadow-accent/20"
|
|
>
|
|
{isExpanded ? t('showLess') : t('showMore')}
|
|
</button>
|
|
</div>
|
|
)}
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
);
|
|
}
|