Files
ArchiTools/src/app/page.tsx
Marius Tarau 4c46e8bcdd Initial commit: ArchiTools modular dashboard platform
Complete Next.js 16 application with 13 fully implemented modules:
Email Signature, Word XML Generator, Registratura, Dashboard,
Tag Manager, IT Inventory, Address Book, Password Vault,
Mini Utilities, Prompt Generator, Digital Signatures,
Word Templates, and AI Chat.

Includes core platform systems (module registry, feature flags,
storage abstraction, i18n, theming, auth stub, tagging),
16 technical documentation files, Docker deployment config,
and legacy HTML tool reference.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-17 12:50:25 +02:00

135 lines
5.1 KiB
TypeScript

'use client';
import Link from 'next/link';
import * as Icons from 'lucide-react';
import { getAllModules } from '@/core/module-registry';
import { useFeatureFlag } from '@/core/feature-flags';
import { useI18n } from '@/core/i18n';
import { EXTERNAL_TOOLS } from '@/config/external-tools';
import { Card, CardHeader, CardTitle, CardDescription, CardContent } from '@/shared/components/ui/card';
import { Badge } from '@/shared/components/ui/badge';
function DynamicIcon({ name, className }: { name: string; className?: string }) {
const pascalName = name.replace(/(^|-)([a-z])/g, (_, _p, c: string) => c.toUpperCase());
const IconComponent = (Icons as unknown as Record<string, React.ComponentType<{ className?: string }>>)[pascalName];
if (!IconComponent) return <Icons.Circle className={className} />;
return <IconComponent className={className} />;
}
function ModuleCard({ module }: { module: { id: string; name: string; description: string; icon: string; route: string; featureFlag: string } }) {
const enabled = useFeatureFlag(module.featureFlag);
if (!enabled) return null;
return (
<Link href={module.route}>
<Card className="h-full transition-colors hover:border-primary/50 hover:bg-accent/30">
<CardHeader className="flex flex-row items-center gap-4 space-y-0">
<div className="flex h-10 w-10 shrink-0 items-center justify-center rounded-md bg-primary/10">
<DynamicIcon name={module.icon} className="h-5 w-5 text-primary" />
</div>
<div>
<CardTitle className="text-base">{module.name}</CardTitle>
<CardDescription className="text-sm">{module.description}</CardDescription>
</div>
</CardHeader>
</Card>
</Link>
);
}
const CATEGORY_LABELS: Record<string, string> = {
dev: 'Dezvoltare',
tools: 'Instrumente',
monitoring: 'Monitorizare',
security: 'Securitate',
};
export default function DashboardPage() {
const { t } = useI18n();
const modules = getAllModules();
const toolCategories = Object.keys(CATEGORY_LABELS).filter(
(cat) => EXTERNAL_TOOLS.some((tool) => tool.category === cat)
);
return (
<div className="mx-auto max-w-6xl space-y-8">
<div>
<h1 className="text-3xl font-bold tracking-tight">{t('dashboard.welcome')}</h1>
<p className="mt-1 text-muted-foreground">{t('dashboard.subtitle')}</p>
</div>
{/* Quick stats */}
<div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-4">
<Card>
<CardContent className="p-4">
<p className="text-xs text-muted-foreground">Module active</p>
<p className="text-2xl font-bold">{modules.length}</p>
</CardContent>
</Card>
<Card>
<CardContent className="p-4">
<p className="text-xs text-muted-foreground">Companii</p>
<p className="text-2xl font-bold">3</p>
</CardContent>
</Card>
<Card>
<CardContent className="p-4">
<p className="text-xs text-muted-foreground">Instrumente externe</p>
<p className="text-2xl font-bold">{EXTERNAL_TOOLS.length}</p>
</CardContent>
</Card>
<Card>
<CardContent className="p-4">
<p className="text-xs text-muted-foreground">Stocare</p>
<p className="text-2xl font-bold">localStorage</p>
</CardContent>
</Card>
</div>
{/* Modules grid */}
<div>
<h2 className="mb-4 text-lg font-semibold">{t('dashboard.modules')}</h2>
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
{modules.map((m) => (
<ModuleCard key={m.id} module={m} />
))}
</div>
</div>
{/* External tools */}
<div>
<h2 className="mb-4 text-lg font-semibold">Instrumente externe</h2>
<div className="space-y-4">
{toolCategories.map((cat) => (
<div key={cat}>
<Badge variant="outline" className="mb-2">{CATEGORY_LABELS[cat]}</Badge>
<div className="grid gap-3 sm:grid-cols-2 lg:grid-cols-3">
{EXTERNAL_TOOLS.filter((tool) => tool.category === cat).map((tool) => {
const cardContent = (
<Card key={tool.id} className="transition-colors hover:bg-accent/30">
<CardHeader className="flex flex-row items-center gap-3 space-y-0 p-4">
<DynamicIcon name={tool.icon} className="h-4 w-4 text-muted-foreground" />
<div>
<p className="text-sm font-medium">{tool.name}</p>
<p className="text-xs text-muted-foreground">{tool.description}</p>
</div>
</CardHeader>
</Card>
);
if (!tool.url) return cardContent;
return (
<a key={tool.id} href={tool.url} target="_blank" rel="noopener noreferrer">
{cardContent}
</a>
);
})}
</div>
</div>
))}
</div>
</div>
</div>
);
}