Se agrega ruta de login

This commit is contained in:
Robert
2025-12-22 14:24:53 -06:00
parent ad9e9c1619
commit b303398cd4
8 changed files with 203 additions and 3 deletions

View File

@@ -0,0 +1,35 @@
import { useState } from 'react'
//import { supabase } from '@/lib/supabase'
import { Input } from '../ui/Input'
import { SubmitButton } from '../ui/SubmitButton'
export function ExternalLoginForm() {
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const submit = async () => {
/*await supabase.auth.signInWithPassword({
email,
password,
})*/
}
return (
<form
className="space-y-4"
onSubmit={e => {
e.preventDefault()
submit()
}}
>
<Input label="Correo electrónico" value={email} onChange={setEmail} />
<Input
label="Contraseña"
type="password"
value={password}
onChange={setPassword}
/>
<SubmitButton />
</form>
)
}

View File

@@ -0,0 +1,35 @@
import { useState } from 'react'
//import { supabase } from '@/lib/supabase'
import { Input } from '../ui/Input'
import { SubmitButton } from '../ui/SubmitButton'
export function InternalLoginForm() {
const [clave, setClave] = useState('')
const [password, setPassword] = useState('')
const submit = async () => {
/*await supabase.auth.signInWithPassword({
email: `${clave}@ulsa.mx`,
password,
})*/
}
return (
<form
className="space-y-4"
onSubmit={e => {
e.preventDefault()
submit()
}}
>
<Input label="Clave ULSA" value={clave} onChange={setClave} />
<Input
label="Contraseña"
type="password"
value={password}
onChange={setPassword}
/>
<SubmitButton />
</form>
)
}

View File

@@ -0,0 +1,27 @@
import { useState } from 'react'
import { LoginTabs } from './LoginTabs.tsx'
import { InternalLoginForm } from './InternalLoginForm.tsx'
import { ExternalLoginForm } from './ExternalLoginForm.tsx'
export function LoginCard() {
const [type, setType] = useState<'internal' | 'external'>('internal')
return (
<div className="w-full max-w-md bg-white rounded-2xl shadow-xl p-8">
<h1 className="text-2xl font-semibold text-center mb-1">
Iniciar sesión
</h1>
<p className="text-sm text-gray-500 text-center mb-6">
Accede al Sistema de Planes de Estudio
</p>
<LoginTabs value={type} onChange={setType} />
{type === 'internal' ? (
<InternalLoginForm />
) : (
<ExternalLoginForm />
)}
</div>
)
}

View File

@@ -0,0 +1,28 @@
interface Props {
value: 'internal' | 'external'
onChange: (v: 'internal' | 'external') => void
}
export function LoginTabs({ value, onChange }: Props) {
return (
<div className="flex bg-gray-100 rounded-lg p-1 mb-6">
{[
{ key: 'internal', label: 'Interno' },
{ key: 'external', label: 'Externo' },
].map(tab => (
<button
key={tab.key}
onClick={() => onChange(tab.key as any)}
className={`flex-1 py-2 rounded-md text-sm font-medium transition
${
value === tab.key
? 'bg-white shadow text-gray-900'
: 'text-gray-500'
}`}
>
{tab.label}
</button>
))}
</div>
)
}

View File

@@ -0,0 +1,28 @@
interface InputProps {
label: string
value: string
onChange: (value: string) => void
type?: string
}
export function Input({
label,
value,
onChange,
type = 'text',
}: InputProps) {
return (
<div className="space-y-1">
<label className="text-sm font-medium text-gray-700">
{label}
</label>
<input
type={type}
value={value}
onChange={e => onChange(e.target.value)}
className="w-full rounded-lg border border-gray-300 px-3 py-2
focus:outline-none focus:ring-2 focus:ring-[#7b0f1d]"
/>
</div>
)
}

View File

@@ -0,0 +1,15 @@
interface Props {
text?: string
}
export function SubmitButton({ text = 'Iniciar sesión' }: Props) {
return (
<button
type="submit"
className="w-full bg-[#7b0f1d] text-white py-2 rounded-lg
font-semibold hover:opacity-90 transition"
>
{text}
</button>
)
}

View File

@@ -9,10 +9,16 @@
// 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 LoginRouteImport } from './routes/login'
import { Route as DashboardRouteImport } from './routes/dashboard'
import { Route as IndexRouteImport } from './routes/index'
import { Route as DemoTanstackQueryRouteImport } from './routes/demo/tanstack-query'
const LoginRoute = LoginRouteImport.update({
id: '/login',
path: '/login',
getParentRoute: () => rootRouteImport,
} as any)
const DashboardRoute = DashboardRouteImport.update({
id: '/dashboard',
path: '/dashboard',
@@ -32,35 +38,46 @@ const DemoTanstackQueryRoute = DemoTanstackQueryRouteImport.update({
export interface FileRoutesByFullPath {
'/': typeof IndexRoute
'/dashboard': typeof DashboardRoute
'/login': typeof LoginRoute
'/demo/tanstack-query': typeof DemoTanstackQueryRoute
}
export interface FileRoutesByTo {
'/': typeof IndexRoute
'/dashboard': typeof DashboardRoute
'/login': typeof LoginRoute
'/demo/tanstack-query': typeof DemoTanstackQueryRoute
}
export interface FileRoutesById {
__root__: typeof rootRouteImport
'/': typeof IndexRoute
'/dashboard': typeof DashboardRoute
'/login': typeof LoginRoute
'/demo/tanstack-query': typeof DemoTanstackQueryRoute
}
export interface FileRouteTypes {
fileRoutesByFullPath: FileRoutesByFullPath
fullPaths: '/' | '/dashboard' | '/demo/tanstack-query'
fullPaths: '/' | '/dashboard' | '/login' | '/demo/tanstack-query'
fileRoutesByTo: FileRoutesByTo
to: '/' | '/dashboard' | '/demo/tanstack-query'
id: '__root__' | '/' | '/dashboard' | '/demo/tanstack-query'
to: '/' | '/dashboard' | '/login' | '/demo/tanstack-query'
id: '__root__' | '/' | '/dashboard' | '/login' | '/demo/tanstack-query'
fileRoutesById: FileRoutesById
}
export interface RootRouteChildren {
IndexRoute: typeof IndexRoute
DashboardRoute: typeof DashboardRoute
LoginRoute: typeof LoginRoute
DemoTanstackQueryRoute: typeof DemoTanstackQueryRoute
}
declare module '@tanstack/react-router' {
interface FileRoutesByPath {
'/login': {
id: '/login'
path: '/login'
fullPath: '/login'
preLoaderRoute: typeof LoginRouteImport
parentRoute: typeof rootRouteImport
}
'/dashboard': {
id: '/dashboard'
path: '/dashboard'
@@ -88,6 +105,7 @@ declare module '@tanstack/react-router' {
const rootRouteChildren: RootRouteChildren = {
IndexRoute: IndexRoute,
DashboardRoute: DashboardRoute,
LoginRoute: LoginRoute,
DemoTanstackQueryRoute: DemoTanstackQueryRoute,
}
export const routeTree = rootRouteImport

14
src/routes/login.tsx Normal file
View File

@@ -0,0 +1,14 @@
import { createFileRoute } from '@tanstack/react-router'
import { LoginCard } from '@/components/auth/LoginCard'
export const Route = createFileRoute('/login')({
component: LoginPage,
})
function LoginPage() {
return (
<div className="min-h-screen bg-gradient-to-br from-[#7b0f1d] via-[#6b0d1a] to-[#3a050a] flex items-center justify-center">
<LoginCard />
</div>
)
}