Files
mintel.me/apps/web/src/components/FileExamplesList.tsx
Marc Mintel 103d71851c
Some checks failed
🧪 CI (QA) / 🧪 Quality Assurance (push) Failing after 1m3s
chore: overhaul infrastructure and integrate @mintel packages
- Restructure to pnpm monorepo (site moved to apps/web)
- Integrate @mintel/tsconfig, @mintel/eslint-config, @mintel/husky-config
- Implement Docker service architecture (Varnish, Directus, Gatekeeper)
- Setup environment-aware Gitea Actions deployment
2026-02-05 14:18:51 +01:00

87 lines
3.6 KiB
TypeScript

'use client';
import React, { useState } from 'react';
import { FileExample } from './FileExample';
import type { FileExampleGroup } from '../data/fileExamples';
interface FileExamplesListProps {
groups: FileExampleGroup[];
}
export const FileExamplesList: React.FC<FileExamplesListProps> = ({ groups }) => {
const [expandedGroups, setExpandedGroups] = useState<Record<string, boolean>>({});
const toggleAllInGroup = (groupId: string, files: any[]) => {
const isAnyExpanded = files.some(f => expandedGroups[f.id]);
const newExpanded = { ...expandedGroups };
files.forEach(f => {
newExpanded[f.id] = !isAnyExpanded;
});
setExpandedGroups(newExpanded);
};
if (groups.length === 0) {
return (
<div className="bg-slate-50 border border-slate-200 rounded-lg px-4 py-6 text-center">
<svg className="w-6 h-6 mx-auto text-slate-300 mb-2" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth={1.5} d="M9 12h6m-6 4h6m2 5H7a2 2 0 01-2-2V5a2 2 0 012-2h5.586a1 1 0 01.707.293l5.414 5.414a1 1 0 01.293.707V19a2 2 0 01-2 2z" />
</svg>
<p className="text-slate-500 text-sm">No files found</p>
</div>
);
}
return (
<div className="space-y-3">
{groups.map((group) => (
<section
key={group.groupId}
className="not-prose bg-white border border-slate-200/80 rounded-lg w-full overflow-hidden"
data-file-examples-group
>
<header className="px-3 py-2 grid grid-cols-[1fr_auto] items-center gap-3 border-b border-slate-200/80 bg-white">
<h3 className="m-0 text-xs font-semibold text-slate-900 truncate tracking-tight leading-none">{group.title}</h3>
<div className="flex items-center gap-2">
<span className="text-[11px] text-slate-600 bg-slate-100/80 border border-slate-200/60 rounded-full px-2 py-0.5 tabular-nums">
{group.files.length} files
</span>
<button
type="button"
className="toggle-all-btn h-8 w-8 inline-flex items-center justify-center rounded-full border border-slate-200 bg-white text-slate-400 hover:text-slate-900 hover:border-slate-400 hover:bg-slate-50 transition-all duration-500 ease-[cubic-bezier(0.23,1,0.32,1)] hover:-translate-y-0.5 hover:shadow-lg hover:shadow-slate-100"
title="Toggle all"
onClick={() => toggleAllInGroup(group.groupId, group.files)}
>
{group.files.some(f => expandedGroups[f.id]) ? (
<svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M5 15l7-7 7 7" />
</svg>
) : (
<svg className="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24" aria-hidden="true">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M19 9l-7 7-7-7" />
</svg>
)}
</button>
</div>
</header>
<div className="px-2 py-2 space-y-2">
{group.files.map((file) => (
<FileExample
key={file.id}
filename={file.filename}
content={file.content}
language={file.language}
description={file.description}
tags={file.tags}
id={file.id}
/>
))}
</div>
</section>
))}
</div>
);
};