wip
This commit is contained in:
1
.vscode/settings.json
vendored
1
.vscode/settings.json
vendored
@@ -13,6 +13,7 @@
|
|||||||
"editor.codeActionsOnSave": {
|
"editor.codeActionsOnSave": {
|
||||||
"source.fixAll.eslint": "explicit"
|
"source.fixAll.eslint": "explicit"
|
||||||
},
|
},
|
||||||
|
"editor.tabSize": 2,
|
||||||
"eslint.validate": [
|
"eslint.validate": [
|
||||||
"javascript",
|
"javascript",
|
||||||
"javascriptreact",
|
"javascriptreact",
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ const config = {
|
|||||||
semi: false,
|
semi: false,
|
||||||
singleQuote: true,
|
singleQuote: true,
|
||||||
trailingComma: 'all',
|
trailingComma: 'all',
|
||||||
|
tabWidth: 2,
|
||||||
plugins: ['prettier-plugin-tailwindcss'],
|
plugins: ['prettier-plugin-tailwindcss'],
|
||||||
tailwindFunctions: ['clsx', 'cn', 'cva'],
|
tailwindFunctions: ['clsx', 'cn', 'cva'],
|
||||||
endOfLine: 'lf',
|
endOfLine: 'lf',
|
||||||
|
|||||||
29
src/components/planes/BarraBusqueda.tsx
Normal file
29
src/components/planes/BarraBusqueda.tsx
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
import { SearchIcon } from 'lucide-react'
|
||||||
|
import { useId } from 'react'
|
||||||
|
|
||||||
|
import { Input } from '@/components/ui/input'
|
||||||
|
import { Label } from '@/components/ui/label'
|
||||||
|
|
||||||
|
const InputSearchIconDemo = () => {
|
||||||
|
const id = useId()
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="w-full max-w-xs space-y-2">
|
||||||
|
<Label htmlFor={id}>Search input with icon and button</Label>
|
||||||
|
<div className="relative">
|
||||||
|
<div className="text-muted-foreground pointer-events-none absolute inset-y-0 left-0 flex items-center justify-center pl-3 peer-disabled:opacity-50">
|
||||||
|
<SearchIcon className="size-4" />
|
||||||
|
<span className="sr-only">Search</span>
|
||||||
|
</div>
|
||||||
|
<Input
|
||||||
|
id={id}
|
||||||
|
type="search"
|
||||||
|
placeholder="Search..."
|
||||||
|
className="peer px-9 [&::-webkit-search-cancel-button]:appearance-none [&::-webkit-search-decoration]:appearance-none [&::-webkit-search-results-button]:appearance-none [&::-webkit-search-results-decoration]:appearance-none"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
export default InputSearchIconDemo
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
import { ArrowRight } from 'lucide-react'
|
import { ArrowRight } from 'lucide-react'
|
||||||
|
|
||||||
import type {LucideIcon} from 'lucide-react';
|
import type { LucideIcon } from 'lucide-react'
|
||||||
|
|
||||||
import { Badge } from '@/components/ui/badge'
|
import { Badge } from '@/components/ui/badge'
|
||||||
import { Card, CardContent, CardFooter, CardHeader } from '@/components/ui/card'
|
import { Card, CardContent, CardFooter, CardHeader } from '@/components/ui/card'
|
||||||
@@ -36,7 +36,7 @@ export default function PlanEstudiosCard({
|
|||||||
<Card
|
<Card
|
||||||
onClick={onClick}
|
onClick={onClick}
|
||||||
className={cn(
|
className={cn(
|
||||||
'group relative flex h-full cursor-pointer flex-col justify-between overflow-hidden border-l-4 transition-all hover:shadow-lg',
|
'group relative flex h-full cursor-pointer flex-col justify-between gap-2 overflow-hidden border-l-4 transition-all hover:shadow-lg',
|
||||||
)}
|
)}
|
||||||
// Aplicamos el color de la facultad dinámicamente al borde y un fondo muy sutil
|
// Aplicamos el color de la facultad dinámicamente al borde y un fondo muy sutil
|
||||||
style={{
|
style={{
|
||||||
@@ -61,14 +61,14 @@ export default function PlanEstudiosCard({
|
|||||||
</h4>
|
</h4>
|
||||||
</CardHeader>
|
</CardHeader>
|
||||||
|
|
||||||
<CardContent className="text-muted-foreground space-y-1 pb-4 text-sm">
|
<CardContent className="text-muted-foreground space-y-1 text-sm">
|
||||||
<p className="text-foreground font-medium">
|
<p className="text-foreground font-medium">
|
||||||
{nivel} • {ciclos}
|
{nivel} • {ciclos}
|
||||||
</p>
|
</p>
|
||||||
<p>{facultad}</p>
|
<p>{facultad}</p>
|
||||||
</CardContent>
|
</CardContent>
|
||||||
|
|
||||||
<CardFooter className="bg-background/50 flex items-center justify-between border-t px-6 py-3 backdrop-blur-sm">
|
<CardFooter className="bg-background/50 flex items-center justify-between border-t px-6 pb-3 backdrop-blur-sm [.border-t]:pt-3">
|
||||||
<Badge className={`text-sm font-semibold ${claseColorEstado}`}>
|
<Badge className={`text-sm font-semibold ${claseColorEstado}`}>
|
||||||
{estado}
|
{estado}
|
||||||
</Badge>
|
</Badge>
|
||||||
@@ -9,11 +9,17 @@
|
|||||||
// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
|
// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
|
||||||
|
|
||||||
import { Route as rootRouteImport } from './routes/__root'
|
import { Route as rootRouteImport } from './routes/__root'
|
||||||
|
import { Route as PlanesRouteImport } from './routes/planes'
|
||||||
import { Route as LoginRouteImport } from './routes/login'
|
import { Route as LoginRouteImport } from './routes/login'
|
||||||
import { Route as DashboardRouteImport } from './routes/dashboard'
|
import { Route as DashboardRouteImport } from './routes/dashboard'
|
||||||
import { Route as IndexRouteImport } from './routes/index'
|
import { Route as IndexRouteImport } from './routes/index'
|
||||||
import { Route as DemoTanstackQueryRouteImport } from './routes/demo/tanstack-query'
|
import { Route as DemoTanstackQueryRouteImport } from './routes/demo/tanstack-query'
|
||||||
|
|
||||||
|
const PlanesRoute = PlanesRouteImport.update({
|
||||||
|
id: '/planes',
|
||||||
|
path: '/planes',
|
||||||
|
getParentRoute: () => rootRouteImport,
|
||||||
|
} as any)
|
||||||
const LoginRoute = LoginRouteImport.update({
|
const LoginRoute = LoginRouteImport.update({
|
||||||
id: '/login',
|
id: '/login',
|
||||||
path: '/login',
|
path: '/login',
|
||||||
@@ -39,12 +45,14 @@ export interface FileRoutesByFullPath {
|
|||||||
'/': typeof IndexRoute
|
'/': typeof IndexRoute
|
||||||
'/dashboard': typeof DashboardRoute
|
'/dashboard': typeof DashboardRoute
|
||||||
'/login': typeof LoginRoute
|
'/login': typeof LoginRoute
|
||||||
|
'/planes': typeof PlanesRoute
|
||||||
'/demo/tanstack-query': typeof DemoTanstackQueryRoute
|
'/demo/tanstack-query': typeof DemoTanstackQueryRoute
|
||||||
}
|
}
|
||||||
export interface FileRoutesByTo {
|
export interface FileRoutesByTo {
|
||||||
'/': typeof IndexRoute
|
'/': typeof IndexRoute
|
||||||
'/dashboard': typeof DashboardRoute
|
'/dashboard': typeof DashboardRoute
|
||||||
'/login': typeof LoginRoute
|
'/login': typeof LoginRoute
|
||||||
|
'/planes': typeof PlanesRoute
|
||||||
'/demo/tanstack-query': typeof DemoTanstackQueryRoute
|
'/demo/tanstack-query': typeof DemoTanstackQueryRoute
|
||||||
}
|
}
|
||||||
export interface FileRoutesById {
|
export interface FileRoutesById {
|
||||||
@@ -52,25 +60,40 @@ export interface FileRoutesById {
|
|||||||
'/': typeof IndexRoute
|
'/': typeof IndexRoute
|
||||||
'/dashboard': typeof DashboardRoute
|
'/dashboard': typeof DashboardRoute
|
||||||
'/login': typeof LoginRoute
|
'/login': typeof LoginRoute
|
||||||
|
'/planes': typeof PlanesRoute
|
||||||
'/demo/tanstack-query': typeof DemoTanstackQueryRoute
|
'/demo/tanstack-query': typeof DemoTanstackQueryRoute
|
||||||
}
|
}
|
||||||
export interface FileRouteTypes {
|
export interface FileRouteTypes {
|
||||||
fileRoutesByFullPath: FileRoutesByFullPath
|
fileRoutesByFullPath: FileRoutesByFullPath
|
||||||
fullPaths: '/' | '/dashboard' | '/login' | '/demo/tanstack-query'
|
fullPaths: '/' | '/dashboard' | '/login' | '/planes' | '/demo/tanstack-query'
|
||||||
fileRoutesByTo: FileRoutesByTo
|
fileRoutesByTo: FileRoutesByTo
|
||||||
to: '/' | '/dashboard' | '/login' | '/demo/tanstack-query'
|
to: '/' | '/dashboard' | '/login' | '/planes' | '/demo/tanstack-query'
|
||||||
id: '__root__' | '/' | '/dashboard' | '/login' | '/demo/tanstack-query'
|
id:
|
||||||
|
| '__root__'
|
||||||
|
| '/'
|
||||||
|
| '/dashboard'
|
||||||
|
| '/login'
|
||||||
|
| '/planes'
|
||||||
|
| '/demo/tanstack-query'
|
||||||
fileRoutesById: FileRoutesById
|
fileRoutesById: FileRoutesById
|
||||||
}
|
}
|
||||||
export interface RootRouteChildren {
|
export interface RootRouteChildren {
|
||||||
IndexRoute: typeof IndexRoute
|
IndexRoute: typeof IndexRoute
|
||||||
DashboardRoute: typeof DashboardRoute
|
DashboardRoute: typeof DashboardRoute
|
||||||
LoginRoute: typeof LoginRoute
|
LoginRoute: typeof LoginRoute
|
||||||
|
PlanesRoute: typeof PlanesRoute
|
||||||
DemoTanstackQueryRoute: typeof DemoTanstackQueryRoute
|
DemoTanstackQueryRoute: typeof DemoTanstackQueryRoute
|
||||||
}
|
}
|
||||||
|
|
||||||
declare module '@tanstack/react-router' {
|
declare module '@tanstack/react-router' {
|
||||||
interface FileRoutesByPath {
|
interface FileRoutesByPath {
|
||||||
|
'/planes': {
|
||||||
|
id: '/planes'
|
||||||
|
path: '/planes'
|
||||||
|
fullPath: '/planes'
|
||||||
|
preLoaderRoute: typeof PlanesRouteImport
|
||||||
|
parentRoute: typeof rootRouteImport
|
||||||
|
}
|
||||||
'/login': {
|
'/login': {
|
||||||
id: '/login'
|
id: '/login'
|
||||||
path: '/login'
|
path: '/login'
|
||||||
@@ -106,6 +129,7 @@ const rootRouteChildren: RootRouteChildren = {
|
|||||||
IndexRoute: IndexRoute,
|
IndexRoute: IndexRoute,
|
||||||
DashboardRoute: DashboardRoute,
|
DashboardRoute: DashboardRoute,
|
||||||
LoginRoute: LoginRoute,
|
LoginRoute: LoginRoute,
|
||||||
|
PlanesRoute: PlanesRoute,
|
||||||
DemoTanstackQueryRoute: DemoTanstackQueryRoute,
|
DemoTanstackQueryRoute: DemoTanstackQueryRoute,
|
||||||
}
|
}
|
||||||
export const routeTree = rootRouteImport
|
export const routeTree = rootRouteImport
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import {
|
|||||||
} from 'lucide-react'
|
} from 'lucide-react'
|
||||||
|
|
||||||
import DashboardHeader from '@/components/dashboard/DashboardHeader'
|
import DashboardHeader from '@/components/dashboard/DashboardHeader'
|
||||||
import PlanEstudiosCard from '@/components/plan_estudios/PlanEstudiosCard'
|
import PlanEstudiosCard from '@/components/planes/PlanEstudiosCard'
|
||||||
|
|
||||||
export const Route = createFileRoute('/dashboard')({
|
export const Route = createFileRoute('/dashboard')({
|
||||||
component: RouteComponent,
|
component: RouteComponent,
|
||||||
|
|||||||
141
src/routes/planes.tsx
Normal file
141
src/routes/planes.tsx
Normal file
@@ -0,0 +1,141 @@
|
|||||||
|
import { createFileRoute } from '@tanstack/react-router'
|
||||||
|
import {
|
||||||
|
Activity,
|
||||||
|
BookOpenText,
|
||||||
|
Calculator,
|
||||||
|
FlaskConical,
|
||||||
|
Laptop,
|
||||||
|
PencilRuler,
|
||||||
|
Plus,
|
||||||
|
Scale,
|
||||||
|
Stethoscope,
|
||||||
|
} from 'lucide-react'
|
||||||
|
|
||||||
|
import PlanEstudiosCard from '@/components/planes/PlanEstudiosCard'
|
||||||
|
|
||||||
|
export const Route = createFileRoute('/planes')({
|
||||||
|
component: RouteComponent,
|
||||||
|
})
|
||||||
|
|
||||||
|
function RouteComponent() {
|
||||||
|
return (
|
||||||
|
<main className="bg-background min-h-screen w-full">
|
||||||
|
<div className="mx-auto flex w-full max-w-7xl flex-col gap-4 px-4 py-6 md:px-6 lg:px-8">
|
||||||
|
<div className="flex flex-col gap-4 lg:col-span-3">
|
||||||
|
<div className="flex flex-col items-stretch justify-between gap-4 sm:flex-row sm:items-center">
|
||||||
|
<div className="flex items-center gap-3">
|
||||||
|
<div className="bg-primary/10 text-primary flex h-10 w-10 items-center justify-center rounded-xl">
|
||||||
|
<BookOpenText className="h-5 w-5" strokeWidth={2} />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
<h1 className="font-display text-foreground text-2xl font-bold">
|
||||||
|
Planes de Estudio
|
||||||
|
</h1>
|
||||||
|
<p className="text-muted-foreground text-sm">
|
||||||
|
Gestiona los planes curriculares de tu institución
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
className={
|
||||||
|
'ring-offset-background focus-visible:ring-ring bg-primary text-primary-foreground hover:bg-primary/90 inline-flex h-11 items-center justify-center gap-2 rounded-md px-8 text-sm font-medium whitespace-nowrap shadow-md transition-colors focus-visible:ring-2 focus-visible:ring-offset-2 focus-visible:outline-none disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg]:h-4 [&_svg]:w-4 [&_svg]:shrink-0'
|
||||||
|
}
|
||||||
|
aria-label="Nuevo plan de estudios"
|
||||||
|
title="Nuevo plan de estudios"
|
||||||
|
>
|
||||||
|
<Plus className="" />
|
||||||
|
Nuevo plan de estudios
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4">
|
||||||
|
<PlanEstudiosCard
|
||||||
|
Icono={Laptop}
|
||||||
|
nombrePrograma="Ingeniería en Sistemas Computacionales"
|
||||||
|
nivel="Licenciatura"
|
||||||
|
ciclos="8 semestres"
|
||||||
|
facultad="Facultad de Ingeniería"
|
||||||
|
estado="Revisión expertos"
|
||||||
|
claseColorEstado="bg-amber-600"
|
||||||
|
colorFacultad="#2563eb"
|
||||||
|
onClick={() => console.log('Navegar a Sistemas...')}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<PlanEstudiosCard
|
||||||
|
Icono={Stethoscope}
|
||||||
|
nombrePrograma="Médico Cirujano"
|
||||||
|
nivel="Licenciatura"
|
||||||
|
ciclos="10 semestres"
|
||||||
|
facultad="Facultad de Medicina"
|
||||||
|
estado="Aprobado"
|
||||||
|
claseColorEstado="bg-emerald-600"
|
||||||
|
colorFacultad="#dc2626"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<PlanEstudiosCard
|
||||||
|
Icono={Calculator}
|
||||||
|
nombrePrograma="Licenciatura en Actuaría"
|
||||||
|
nivel="Licenciatura"
|
||||||
|
ciclos="9 semestres"
|
||||||
|
facultad="Facultad de Negocios"
|
||||||
|
estado="Aprobado"
|
||||||
|
claseColorEstado="bg-emerald-600"
|
||||||
|
colorFacultad="#059669"
|
||||||
|
onClick={() => console.log('Ver Actuaría')}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<PlanEstudiosCard
|
||||||
|
Icono={PencilRuler}
|
||||||
|
nombrePrograma="Licenciatura en Arquitectura"
|
||||||
|
nivel="Licenciatura"
|
||||||
|
ciclos="10 semestres"
|
||||||
|
facultad="Facultad Mexicana de Arquitectura, Diseño y Comunicación"
|
||||||
|
estado="En proceso"
|
||||||
|
claseColorEstado="bg-orange-500"
|
||||||
|
colorFacultad="#ea580c"
|
||||||
|
onClick={() => console.log('Ver Arquitectura')}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<PlanEstudiosCard
|
||||||
|
Icono={Activity}
|
||||||
|
nombrePrograma="Licenciatura en Fisioterapia"
|
||||||
|
nivel="Licenciatura"
|
||||||
|
ciclos="8 semestres"
|
||||||
|
facultad="Escuela de Altos Estudios en Salud"
|
||||||
|
estado="Revisión expertos"
|
||||||
|
claseColorEstado="bg-amber-600"
|
||||||
|
colorFacultad="#0891b2"
|
||||||
|
onClick={() => console.log('Ver Fisioterapia')}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<PlanEstudiosCard
|
||||||
|
Icono={Scale}
|
||||||
|
nombrePrograma="Licenciatura en Derecho"
|
||||||
|
nivel="Licenciatura"
|
||||||
|
ciclos="10 semestres"
|
||||||
|
facultad="Facultad de Derecho"
|
||||||
|
estado="Pendiente"
|
||||||
|
claseColorEstado="bg-yellow-500"
|
||||||
|
colorFacultad="#7c3aed"
|
||||||
|
onClick={() => console.log('Ver Derecho')}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<PlanEstudiosCard
|
||||||
|
Icono={FlaskConical}
|
||||||
|
nombrePrograma="Químico Farmacéutico Biólogo"
|
||||||
|
nivel="Licenciatura"
|
||||||
|
ciclos="9 semestres"
|
||||||
|
facultad="Facultad de Ciencias Químicas"
|
||||||
|
estado="Actualización"
|
||||||
|
claseColorEstado="bg-lime-600"
|
||||||
|
colorFacultad="#65a30d"
|
||||||
|
onClick={() => console.log('Ver QFB')}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</main>
|
||||||
|
)
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user