Files
plagiat/src/widgets/cabinet/ui/index.tsx
nabijonovdavronbek619@gmail.com db0fad7e00 profile page ui complated
2026-04-06 17:55:54 +05:00

118 lines
3.7 KiB
TypeScript

'use client';
import React from 'react';
import dynamic from 'next/dynamic';
import { AnimatePresence, motion } from 'framer-motion';
import { Sidebar } from './Sidebar';
import { CabinetNav } from './CabinetNav';
import { Dashboard } from './dashboard';
import { useCabinet } from '../lib/hooks/useCabinet';
import {
MOCK_USER,
MOCK_STATS,
MOCK_PLAGIAT,
MOCK_SI,
MOCK_PAYMENTS,
} from '../lib/mock';
import type { CabinetSection } from '../lib/types';
// ─── Lazy sections (separate JS chunks) ───────────────────────────────────────
const Skeleton = () => (
<div className="space-y-3">
{Array.from({ length: 4 }).map((_, i) => (
<div key={i} className="h-12 bg-slate-100 rounded-xl animate-pulse" />
))}
</div>
);
const PlagiatTable = dynamic(
() =>
import('./tables/PlagiatTable').then((m) => ({ default: m.PlagiatTable })),
{ loading: Skeleton },
);
const SiTable = dynamic(
() => import('./tables/SiTable').then((m) => ({ default: m.SiTable })),
{ loading: Skeleton },
);
const PaymentsTable = dynamic(
() =>
import('./tables/PaymentsTable').then((m) => ({
default: m.PaymentsTable,
})),
{ loading: Skeleton },
);
const ProfileSection = dynamic(
() => import('./profile').then((m) => ({ default: m.ProfileSection })),
{ loading: Skeleton },
);
// ─── Section switcher ──────────────────────────────────────────────────────────
function SectionContent({
section,
onNavigate,
}: {
section: CabinetSection;
onNavigate: (s: CabinetSection) => void;
}) {
switch (section) {
case 'dashboard':
return (
<Dashboard
stats={MOCK_STATS}
onNavigate={onNavigate}
userName={MOCK_USER.name}
/>
);
case 'plagiat':
return <PlagiatTable data={MOCK_PLAGIAT} />;
case 'si':
return <SiTable data={MOCK_SI} />;
case 'payments':
return <PaymentsTable data={MOCK_PAYMENTS} />;
case 'profile':
return <ProfileSection user={MOCK_USER} stats={MOCK_STATS} />;
}
}
// ─── Animation ────────────────────────────────────────────────────────────────
const FADE = {
initial: { opacity: 0, y: 10 },
animate: { opacity: 1, y: 0 },
exit: { opacity: 0, y: -6 },
transition: { duration: 0.18, ease: 'easeOut' },
} as const;
// ─── CabinetLayout ────────────────────────────────────────────────────────────
export const CabinetLayout: React.FC = () => {
const { activeSection, navigate, isSidebarOpen, toggleSidebar } =
useCabinet();
const fullName = `${MOCK_USER.name} ${MOCK_USER.surname}`;
return (
<div className="flex bg-slate-50 min-h-screen">
<Sidebar
active={activeSection}
onNavigate={navigate}
isOpen={isSidebarOpen}
onClose={toggleSidebar}
userName={fullName}
/>
<div className="flex-1 flex flex-col min-w-0">
<CabinetNav activeSection={activeSection} onMenuClick={toggleSidebar} />
<main className="flex-1 p-4 md:p-6 lg:p-8 max-w-6xl mx-auto w-full">
<AnimatePresence mode="wait">
<motion.div key={activeSection} {...FADE}>
<SectionContent section={activeSection} onNavigate={navigate} />
</motion.div>
</AnimatePresence>
</main>
</div>
</div>
);
};