diff --git a/src/components/layout/AppLayout.tsx b/src/components/layout/AppLayout.tsx new file mode 100644 index 0000000..341e987 --- /dev/null +++ b/src/components/layout/AppLayout.tsx @@ -0,0 +1,27 @@ +import type { ReactNode } from 'react' +import { Sidebar } from './Sidebar' +import { Header } from './Header' +import { StatsGrid } from '../plans/StatsGrid' + +export function AppLayout({ children }: { children: ReactNode }) { + return ( +
+ {/* */} + +
+
+ + {/* Separación Header → Stats */} +
+
+ +
+
+ +
+ {children} +
+
+
+ ) +} diff --git a/src/components/layout/Header.tsx b/src/components/layout/Header.tsx new file mode 100644 index 0000000..f9335af --- /dev/null +++ b/src/components/layout/Header.tsx @@ -0,0 +1,18 @@ +export function Header() { + return ( +
+
+ 🎓 +
+ +
+

+ Gestión Curricular +

+

+ Sistema de Planes de Estudio +

+
+
+ ) +} diff --git a/src/components/layout/Sidebar.tsx b/src/components/layout/Sidebar.tsx new file mode 100644 index 0000000..d37ebff --- /dev/null +++ b/src/components/layout/Sidebar.tsx @@ -0,0 +1,32 @@ +import { LayoutGrid, BookOpen } from 'lucide-react' + +export function Sidebar() { + return ( + + ) +} + +function NavItem({ icon: Icon, label, active }: any) { + return ( +
+ + {label} +
+ ) +} diff --git a/src/components/plans/PlanCard.tsx b/src/components/plans/PlanCard.tsx new file mode 100644 index 0000000..d233a80 --- /dev/null +++ b/src/components/plans/PlanCard.tsx @@ -0,0 +1,26 @@ +import { StatusBadge } from "./StatusBadge"; + +export function PlanCard({ plan }: any) { + return ( +
+
+ ⚙ Ingeniería + +
+ +

+ {plan.title} +

+ +

+ {plan.subtitle} +

+ +
+ {plan.cycles} ciclos + {plan.credits} créditos + +
+
+ ) +} diff --git a/src/components/plans/PlanGrid.tsx b/src/components/plans/PlanGrid.tsx new file mode 100644 index 0000000..c6bcd65 --- /dev/null +++ b/src/components/plans/PlanGrid.tsx @@ -0,0 +1,38 @@ +import { PlanCard } from './PlanCard' + +const mockPlans = [ + { + id: 1, + name: 'Ingeniería en Sistemas', + level: 'Licenciatura', + status: 'Activo', + }, + { + id: 2, + name: 'Arquitectura', + level: 'Licenciatura', + status: 'Activo', + }, + { + id: 3, + name: 'Maestría en Educación', + level: 'Maestría', + status: 'Inactivo', + }, +] + +export function PlanGrid() { + return ( +
+

+ Planes disponibles +

+ +
+ {mockPlans.map(plan => ( + + ))} +
+
+ ) +} diff --git a/src/components/plans/StatCard.tsx b/src/components/plans/StatCard.tsx new file mode 100644 index 0000000..d108612 --- /dev/null +++ b/src/components/plans/StatCard.tsx @@ -0,0 +1,11 @@ +export function StatCard({ icon, value, label }: any) { + return ( +
+
+ {icon} + {value} +
+

{label}

+
+ ) +} diff --git a/src/components/plans/StatsGrid.tsx b/src/components/plans/StatsGrid.tsx new file mode 100644 index 0000000..ca1bf96 --- /dev/null +++ b/src/components/plans/StatsGrid.tsx @@ -0,0 +1,12 @@ +import { StatCard } from "./StatCard"; + +export function StatsGrid() { + return ( +
+ + + + +
+ ) +} diff --git a/src/components/plans/StatusBadge.tsx b/src/components/plans/StatusBadge.tsx new file mode 100644 index 0000000..9de2053 --- /dev/null +++ b/src/components/plans/StatusBadge.tsx @@ -0,0 +1,19 @@ +export function StatusBadge({ status }: { status: string }) { + const styles: any = { + revision: 'bg-blue-100 text-blue-700', + aprobado: 'bg-green-100 text-green-700', + borrador: 'bg-gray-200 text-gray-600', + } + + return ( + + {status === 'revision' + ? 'En Revisión' + : status === 'aprobado' + ? 'Aprobado' + : 'Borrador'} + + ) +} diff --git a/src/routeTree.gen.ts b/src/routeTree.gen.ts index 9858c80..60c0fe7 100644 --- a/src/routeTree.gen.ts +++ b/src/routeTree.gen.ts @@ -13,6 +13,7 @@ import { Route as PlanesRouteImport } from './routes/planes' import { Route as LoginRouteImport } from './routes/login' import { Route as DashboardRouteImport } from './routes/dashboard' import { Route as IndexRouteImport } from './routes/index' +import { Route as PlanesIndexRouteImport } from './routes/planes/index' import { Route as DemoTanstackQueryRouteImport } from './routes/demo/tanstack-query' const PlanesRoute = PlanesRouteImport.update({ @@ -35,6 +36,11 @@ const IndexRoute = IndexRouteImport.update({ path: '/', getParentRoute: () => rootRouteImport, } as any) +const PlanesIndexRoute = PlanesIndexRouteImport.update({ + id: '/planes/', + path: '/planes/', + getParentRoute: () => rootRouteImport, +} as any) const DemoTanstackQueryRoute = DemoTanstackQueryRouteImport.update({ id: '/demo/tanstack-query', path: '/demo/tanstack-query', @@ -47,6 +53,7 @@ export interface FileRoutesByFullPath { '/login': typeof LoginRoute '/planes': typeof PlanesRoute '/demo/tanstack-query': typeof DemoTanstackQueryRoute + '/planes': typeof PlanesIndexRoute } export interface FileRoutesByTo { '/': typeof IndexRoute @@ -54,6 +61,7 @@ export interface FileRoutesByTo { '/login': typeof LoginRoute '/planes': typeof PlanesRoute '/demo/tanstack-query': typeof DemoTanstackQueryRoute + '/planes': typeof PlanesIndexRoute } export interface FileRoutesById { __root__: typeof rootRouteImport @@ -62,19 +70,31 @@ export interface FileRoutesById { '/login': typeof LoginRoute '/planes': typeof PlanesRoute '/demo/tanstack-query': typeof DemoTanstackQueryRoute + '/planes/': typeof PlanesIndexRoute } export interface FileRouteTypes { fileRoutesByFullPath: FileRoutesByFullPath +<<<<<<< HEAD fullPaths: '/' | '/dashboard' | '/login' | '/planes' | '/demo/tanstack-query' fileRoutesByTo: FileRoutesByTo to: '/' | '/dashboard' | '/login' | '/planes' | '/demo/tanstack-query' +======= + fullPaths: '/' | '/dashboard' | '/login' | '/demo/tanstack-query' | '/planes' + fileRoutesByTo: FileRoutesByTo + to: '/' | '/dashboard' | '/login' | '/demo/tanstack-query' | '/planes' +>>>>>>> origin/main id: | '__root__' | '/' | '/dashboard' | '/login' +<<<<<<< HEAD | '/planes' | '/demo/tanstack-query' +======= + | '/demo/tanstack-query' + | '/planes/' +>>>>>>> origin/main fileRoutesById: FileRoutesById } export interface RootRouteChildren { @@ -83,6 +103,7 @@ export interface RootRouteChildren { LoginRoute: typeof LoginRoute PlanesRoute: typeof PlanesRoute DemoTanstackQueryRoute: typeof DemoTanstackQueryRoute + PlanesIndexRoute: typeof PlanesIndexRoute } declare module '@tanstack/react-router' { @@ -115,6 +136,13 @@ declare module '@tanstack/react-router' { preLoaderRoute: typeof IndexRouteImport parentRoute: typeof rootRouteImport } + '/planes/': { + id: '/planes/' + path: '/planes' + fullPath: '/planes' + preLoaderRoute: typeof PlanesIndexRouteImport + parentRoute: typeof rootRouteImport + } '/demo/tanstack-query': { id: '/demo/tanstack-query' path: '/demo/tanstack-query' @@ -131,6 +159,7 @@ const rootRouteChildren: RootRouteChildren = { LoginRoute: LoginRoute, PlanesRoute: PlanesRoute, DemoTanstackQueryRoute: DemoTanstackQueryRoute, + PlanesIndexRoute: PlanesIndexRoute, } export const routeTree = rootRouteImport ._addFileChildren(rootRouteChildren) diff --git a/src/routes/planes/index.tsx b/src/routes/planes/index.tsx new file mode 100644 index 0000000..096e925 --- /dev/null +++ b/src/routes/planes/index.tsx @@ -0,0 +1,15 @@ +import { createFileRoute } from '@tanstack/react-router' +import { AppLayout } from '@/components/layout/AppLayout' +import { PlanGrid } from '@/components/plans/PlanGrid' + +export const Route = createFileRoute('/planes/')({ + component: PlanesPage, +}) + +function PlanesPage() { + return ( + + + + ) +}