Some checks failed
🧪 CI (QA) / 🧪 Quality Assurance (push) Failing after 1m3s
- 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
87 lines
3.6 KiB
TypeScript
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>
|
|
);
|
|
};
|