Compare commits
2 Commits
45da7f62fe
...
login
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cf8c592c78 | ||
|
|
08d0a5a099 |
@@ -6,4 +6,4 @@ APIKEY_MAPS="AIzaSyAwfOShBqkBcS46WqmlsIVWQJ8gpdOPk_4"
|
|||||||
SUPABASE_URL="https://qsssikzgwomudkwfmgad.supabase.co"
|
SUPABASE_URL="https://qsssikzgwomudkwfmgad.supabase.co"
|
||||||
SUPABASE_KEY="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InFzc3Npa3pnd29tdWRrd2ZtZ2FkIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQzMjY1NTQsImV4cCI6MjA2OTkwMjU1NH0.BTSscdTcPP1GVmMB-H5caLpWsfuAw1V6mXiqogF8TjU"
|
SUPABASE_KEY="eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6InFzc3Npa3pnd29tdWRrd2ZtZ2FkIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NTQzMjY1NTQsImV4cCI6MjA2OTkwMjU1NH0.BTSscdTcPP1GVmMB-H5caLpWsfuAw1V6mXiqogF8TjU"
|
||||||
VITE_LOGIN_USER="test@test.com"
|
VITE_LOGIN_USER="test@test.com"
|
||||||
VITE_PASSWORD_USER=""
|
VITE_PASSWORD_USER="test"
|
||||||
41
AGENTS.md
Normal file
41
AGENTS.md
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
# AGENTS.md — findyourpilot
|
||||||
|
|
||||||
|
Project context for AI coding agents. This file defines which skill files to load
|
||||||
|
depending on the task at hand.
|
||||||
|
|
||||||
|
<!-- intent-skills:start -->
|
||||||
|
# Skill mappings - when working in these areas, load the linked skill file into context.
|
||||||
|
skills:
|
||||||
|
- task: "Building or modifying routes, loaders, search params, or navigation with TanStack Router"
|
||||||
|
load: "node_modules/.pnpm/@tanstack+router-core@1.167.5/node_modules/@tanstack/router-core/skills/router-core/SKILL.md"
|
||||||
|
|
||||||
|
- task: "Working with route search params, type-safe URL state, or Zod-validated search params"
|
||||||
|
load: "node_modules/.pnpm/@tanstack+router-core@1.167.5/node_modules/@tanstack/router-core/skills/router-core/search-params/SKILL.md"
|
||||||
|
|
||||||
|
- task: "Implementing route guards, authentication redirects, or protected routes"
|
||||||
|
load: "node_modules/.pnpm/@tanstack+router-core@1.167.5/node_modules/@tanstack/router-core/skills/router-core/auth-and-guards/SKILL.md"
|
||||||
|
|
||||||
|
- task: "Loading data in routes, using loaders, or integrating with TanStack Query"
|
||||||
|
load: "node_modules/.pnpm/@tanstack+router-core@1.167.5/node_modules/@tanstack/router-core/skills/router-core/data-loading/SKILL.md"
|
||||||
|
|
||||||
|
- task: "Creating server functions, SSR patterns, full-stack logic, or the TanStack Start execution model"
|
||||||
|
load: "node_modules/.pnpm/@tanstack+start-client-core@1.166.13/node_modules/@tanstack/start-client-core/skills/start-core/SKILL.md"
|
||||||
|
|
||||||
|
- task: "Creating or modifying createServerFn, input validation on server functions, or handling server errors"
|
||||||
|
load: "node_modules/.pnpm/@tanstack+start-client-core@1.166.13/node_modules/@tanstack/start-client-core/skills/start-core/server-functions/SKILL.md"
|
||||||
|
|
||||||
|
- task: "Creating middleware, request middleware, or passing context between server functions"
|
||||||
|
load: "node_modules/.pnpm/@tanstack+start-client-core@1.166.13/node_modules/@tanstack/start-client-core/skills/start-core/middleware/SKILL.md"
|
||||||
|
|
||||||
|
- task: "Creating API endpoints or server-only routes (server property on createFileRoute)"
|
||||||
|
load: "node_modules/.pnpm/@tanstack+start-client-core@1.166.13/node_modules/@tanstack/start-client-core/skills/start-core/server-routes/SKILL.md"
|
||||||
|
|
||||||
|
- task: "Deploying the app to Cloudflare, Vercel, Netlify, Node.js/Docker, or configuring SSR/SPA/prerendering"
|
||||||
|
load: "node_modules/.pnpm/@tanstack+start-client-core@1.166.13/node_modules/@tanstack/start-client-core/skills/start-core/deployment/SKILL.md"
|
||||||
|
|
||||||
|
- task: "Writing, reviewing, or optimising Supabase/Postgres queries, schema design, RLS policies, or migrations"
|
||||||
|
load: ".agents/skills/supabase-postgres-best-practices/SKILL.md"
|
||||||
|
|
||||||
|
- task: "Designing or improving UI layouts, dashboards, component composition, or interactive product interfaces with HeroUI"
|
||||||
|
load: ".agents/skills/interface-design/SKILL.md"
|
||||||
|
<!-- intent-skills:end -->
|
||||||
49
package.json
49
package.json
@@ -14,42 +14,45 @@
|
|||||||
"machine-translate": "inlang machine translate --project project.inlang"
|
"machine-translate": "inlang machine translate --project project.inlang"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@heroui/react": "^3.0.0-beta.8",
|
"@heroui/react": "^3.0.0-rc.1",
|
||||||
"@heroui/styles": "^3.0.0-beta.8",
|
"@heroui/styles": "^3.0.0-rc.1",
|
||||||
"@sentry/tanstackstart-react": "^10.42.0",
|
"@sentry/tanstackstart-react": "^10.45.0",
|
||||||
"@supabase/ssr": "^0.9.0",
|
"@supabase/ssr": "^0.9.0",
|
||||||
"@supabase/supabase-js": "^2.99.1",
|
"@supabase/supabase-js": "^2.99.3",
|
||||||
"@tailwindcss/vite": "^4.2.1",
|
"@tailwindcss/vite": "^4.2.2",
|
||||||
"@tanstack/react-query": "^5.90.21",
|
"@tanstack/react-query": "^5.91.2",
|
||||||
"@tanstack/react-router": "^1.166.7",
|
"@tanstack/react-router": "^1.167.5",
|
||||||
"@tanstack/react-router-ssr-query": "^1.166.7",
|
"@tanstack/react-router-ssr-query": "^1.166.9",
|
||||||
"@tanstack/react-start": "^1.166.8",
|
"@tanstack/react-start": "^1.166.17",
|
||||||
"@tanstack/router-plugin": "^1.166.7",
|
"@tanstack/router-plugin": "^1.166.14",
|
||||||
|
"clsx": "^2.1.1",
|
||||||
"lucide-react": "^0.577.0",
|
"lucide-react": "^0.577.0",
|
||||||
"maplibre-gl": "^5.19.0",
|
"maplibre-gl": "^5.20.2",
|
||||||
"nitro": "^3.0.1-alpha.2",
|
"nitro": "^3.0.1-alpha.2",
|
||||||
"react": "^19.2.4",
|
"react": "^19.2.4",
|
||||||
"react-dom": "^19.2.4",
|
"react-dom": "^19.2.4",
|
||||||
"tailwindcss": "^4.2.1",
|
"tailwind-merge": "^3.5.0",
|
||||||
"tw-animate-css": "^1.4.0"
|
"tailwindcss": "^4.2.2",
|
||||||
|
"tw-animate-css": "^1.4.0",
|
||||||
|
"zod": "^4.3.6"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "^2.4.6",
|
"@biomejs/biome": "^2.4.8",
|
||||||
"@inlang/paraglide-js": "^2.13.1",
|
"@inlang/paraglide-js": "^2.15.0",
|
||||||
"@tanstack/devtools-vite": "^0.5.5",
|
"@tanstack/devtools-vite": "^0.6.0",
|
||||||
"@tanstack/react-devtools": "^0.9.13",
|
"@tanstack/react-devtools": "^0.10.0",
|
||||||
"@tanstack/react-router-devtools": "^1.166.7",
|
|
||||||
"@tanstack/react-query-devtools": "^5.91.3",
|
"@tanstack/react-query-devtools": "^5.91.3",
|
||||||
|
"@tanstack/react-router-devtools": "^1.166.9",
|
||||||
"@testing-library/dom": "^10.4.1",
|
"@testing-library/dom": "^10.4.1",
|
||||||
"@testing-library/react": "^16.3.2",
|
"@testing-library/react": "^16.3.2",
|
||||||
"@types/node": "^22.10.2",
|
"@types/node": "^22.19.15",
|
||||||
"@types/react": "^19.2.14",
|
"@types/react": "^19.2.14",
|
||||||
"@types/react-dom": "^19.2.3",
|
"@types/react-dom": "^19.2.3",
|
||||||
"@vitejs/plugin-react": "^5.1.4",
|
"@vitejs/plugin-react": "^6.0.1",
|
||||||
"jsdom": "^28.1.0",
|
"jsdom": "^29.0.0",
|
||||||
"typescript": "^5.9.3",
|
"typescript": "^5.9.3",
|
||||||
"vite": "^7.3.1",
|
"vite": "^8.0.1",
|
||||||
"vite-tsconfig-paths": "^6.1.1",
|
"vite-tsconfig-paths": "^6.1.1",
|
||||||
"vitest": "^3.2.4"
|
"vitest": "^4.1.0"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
4050
pnpm-lock.yaml
generated
4050
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@@ -14,13 +14,14 @@ export const useLogin = () => {
|
|||||||
mutationKey: ["login"],
|
mutationKey: ["login"],
|
||||||
mutationFn: async (data: TLoginForm) => {
|
mutationFn: async (data: TLoginForm) => {
|
||||||
const response = await user.login({ data })
|
const response = await user.login({ data })
|
||||||
|
|
||||||
if (response.error) {
|
if (response.error) {
|
||||||
throw new Error(response.message)
|
throw new Error(response.message)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onSuccess: () => {
|
onSuccess: () => {
|
||||||
navigate({
|
navigate({
|
||||||
to: "/"
|
to: "/dashboard"
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,38 +1,44 @@
|
|||||||
import { toast } from "@heroui/react"
|
import { toast } from "@heroui/react"
|
||||||
import { useMutation } from "@tanstack/react-query"
|
import { useMutation } from "@tanstack/react-query"
|
||||||
import { useNavigate } from "@tanstack/react-router"
|
|
||||||
import type z from "zod"
|
import type z from "zod"
|
||||||
import { user } from "@/lib/server/user"
|
import { user } from "@/lib/server/user"
|
||||||
import { signupFormSchema } from "@/lib/validation/user"
|
import type { signupClientFormSchema } from "@/lib/validation/user"
|
||||||
|
|
||||||
type TSignupForm = z.infer<typeof signupFormSchema>
|
type TSignupClientForm = z.infer<typeof signupClientFormSchema>
|
||||||
|
|
||||||
export const useSignup = () => {
|
export const useSignup = () => {
|
||||||
const navigate = useNavigate()
|
const signupMutation = useMutation({
|
||||||
const signup = useMutation({
|
|
||||||
mutationKey: ["signup"],
|
mutationKey: ["signup"],
|
||||||
mutationFn: async (data: TSignupForm) => user.signup({ data }),
|
mutationFn: async (data: TSignupClientForm) => {
|
||||||
onSuccess: () => {
|
const { confirmPassword: _, ...serverData } = data
|
||||||
navigate({
|
const response = await user.signup({ data: serverData })
|
||||||
to: "/access/login"
|
|
||||||
})
|
if (response && "error" in response && response.error) {
|
||||||
|
throw new Error(
|
||||||
|
"message" in response
|
||||||
|
? (response.message as string)
|
||||||
|
: "Error desconocido"
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
const validateSignup = (formData: TSignupForm) => {
|
const validateSignup = (formData: TSignupClientForm) => {
|
||||||
if (!signupFormSchema.safeParse(formData).success) {
|
if (formData.password !== formData.confirmPassword) {
|
||||||
toast.danger("Signup failed. Please check your input.")
|
toast.danger("Las contraseñas no coinciden")
|
||||||
|
return
|
||||||
}
|
}
|
||||||
const promise = signup.mutateAsync(formData)
|
|
||||||
|
const promise = signupMutation.mutateAsync(formData)
|
||||||
toast.promise(promise, {
|
toast.promise(promise, {
|
||||||
loading: "Signing up...",
|
loading: "Creando tu cuenta...",
|
||||||
success: "Signup successful! Redirecting to login...",
|
success: "¡Cuenta creada! Revisa tu correo para confirmarla.",
|
||||||
error: "Signup failed!"
|
error: (error: Error) => error.message
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
signup: validateSignup,
|
signup: validateSignup,
|
||||||
isPending: signup.isPending
|
isPending: signupMutation.isPending
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,18 +1,28 @@
|
|||||||
import * as z from "zod"
|
import * as z from "zod"
|
||||||
|
|
||||||
export const loginFormSchema = z.object({
|
export const loginFormSchema = z.object({
|
||||||
email: z.email("Invalid email address"),
|
email: z.email("Introduce un correo válido"),
|
||||||
password: z.string().min(1, "Password must be at least 1 character long")
|
password: z.string().min(1, "La contraseña es obligatoria")
|
||||||
})
|
})
|
||||||
|
|
||||||
export const signupFormSchema = z.object({
|
export const signupFormSchema = z.object({
|
||||||
email: z.email("Invalid email address"),
|
email: z.email("Introduce un correo válido"),
|
||||||
password: z.string().min(6, "Password must be at least 6 characters long"),
|
password: z.string().min(6, "La contraseña debe tener al menos 6 caracteres"),
|
||||||
name: z.string().min(1, "The field is required"),
|
name: z.string().min(1, "El nombre es obligatorio"),
|
||||||
location: z.string().min(1, "The field is required"),
|
location: z.string().min(1, "La ubicación es obligatoria"),
|
||||||
redirectUrl: z.string().optional()
|
redirectUrl: z.string().optional()
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Schema extendido para el formulario cliente (incluye confirmación de contraseña)
|
||||||
|
export const signupClientFormSchema = signupFormSchema
|
||||||
|
.extend({
|
||||||
|
confirmPassword: z.string().min(6, "Confirma tu contraseña")
|
||||||
|
})
|
||||||
|
.refine((data) => data.password === data.confirmPassword, {
|
||||||
|
message: "Las contraseñas no coinciden",
|
||||||
|
path: ["confirmPassword"]
|
||||||
|
})
|
||||||
|
|
||||||
export const profileFormSchema = z.object({
|
export const profileFormSchema = z.object({
|
||||||
id: z.uuid(),
|
id: z.uuid(),
|
||||||
firstName: z.string().min(1, "First name is required"),
|
firstName: z.string().min(1, "First name is required"),
|
||||||
|
|||||||
@@ -12,17 +12,13 @@ import { Route as rootRouteImport } from './routes/__root'
|
|||||||
import { Route as LogoutRouteImport } from './routes/logout'
|
import { Route as LogoutRouteImport } from './routes/logout'
|
||||||
import { Route as LoginRouteImport } from './routes/login'
|
import { Route as LoginRouteImport } from './routes/login'
|
||||||
import { Route as AccessRouteImport } from './routes/access'
|
import { Route as AccessRouteImport } from './routes/access'
|
||||||
import { Route as AuthedRouteImport } from './routes/_authed'
|
import { Route as AuthRouteImport } from './routes/_auth'
|
||||||
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'
|
||||||
import { Route as DemoI18nRouteImport } from './routes/demo.i18n'
|
import { Route as DemoI18nRouteImport } from './routes/demo.i18n'
|
||||||
<<<<<<< HEAD
|
|
||||||
import { Route as AccessRegisterRouteImport } from './routes/access.register'
|
import { Route as AccessRegisterRouteImport } from './routes/access.register'
|
||||||
import { Route as AccessLoginRouteImport } from './routes/access.login'
|
import { Route as AccessLoginRouteImport } from './routes/access.login'
|
||||||
import { Route as AuthedDashboardRouteImport } from './routes/_authed/dashboard'
|
import { Route as AuthDashboardRouteImport } from './routes/_auth/dashboard'
|
||||||
=======
|
|
||||||
import { Route as AuthDashboardRouteImport } from './routes/auth/dashboard'
|
|
||||||
>>>>>>> main
|
|
||||||
import { Route as DemoSentryTestingRouteImport } from './routes/demo/sentry.testing'
|
import { Route as DemoSentryTestingRouteImport } from './routes/demo/sentry.testing'
|
||||||
|
|
||||||
const LogoutRoute = LogoutRouteImport.update({
|
const LogoutRoute = LogoutRouteImport.update({
|
||||||
@@ -40,8 +36,8 @@ const AccessRoute = AccessRouteImport.update({
|
|||||||
path: '/access',
|
path: '/access',
|
||||||
getParentRoute: () => rootRouteImport,
|
getParentRoute: () => rootRouteImport,
|
||||||
} as any)
|
} as any)
|
||||||
const AuthedRoute = AuthedRouteImport.update({
|
const AuthRoute = AuthRouteImport.update({
|
||||||
id: '/_authed',
|
id: '/_auth',
|
||||||
getParentRoute: () => rootRouteImport,
|
getParentRoute: () => rootRouteImport,
|
||||||
} as any)
|
} as any)
|
||||||
const IndexRoute = IndexRouteImport.update({
|
const IndexRoute = IndexRouteImport.update({
|
||||||
@@ -59,7 +55,6 @@ const DemoI18nRoute = DemoI18nRouteImport.update({
|
|||||||
path: '/demo/i18n',
|
path: '/demo/i18n',
|
||||||
getParentRoute: () => rootRouteImport,
|
getParentRoute: () => rootRouteImport,
|
||||||
} as any)
|
} as any)
|
||||||
<<<<<<< HEAD
|
|
||||||
const AccessRegisterRoute = AccessRegisterRouteImport.update({
|
const AccessRegisterRoute = AccessRegisterRouteImport.update({
|
||||||
id: '/register',
|
id: '/register',
|
||||||
path: '/register',
|
path: '/register',
|
||||||
@@ -70,16 +65,10 @@ const AccessLoginRoute = AccessLoginRouteImport.update({
|
|||||||
path: '/login',
|
path: '/login',
|
||||||
getParentRoute: () => AccessRoute,
|
getParentRoute: () => AccessRoute,
|
||||||
} as any)
|
} as any)
|
||||||
const AuthedDashboardRoute = AuthedDashboardRouteImport.update({
|
const AuthDashboardRoute = AuthDashboardRouteImport.update({
|
||||||
id: '/dashboard',
|
id: '/dashboard',
|
||||||
path: '/dashboard',
|
path: '/dashboard',
|
||||||
getParentRoute: () => AuthedRoute,
|
getParentRoute: () => AuthRoute,
|
||||||
=======
|
|
||||||
const AuthDashboardRoute = AuthDashboardRouteImport.update({
|
|
||||||
id: '/auth/dashboard',
|
|
||||||
path: '/auth/dashboard',
|
|
||||||
getParentRoute: () => rootRouteImport,
|
|
||||||
>>>>>>> main
|
|
||||||
} as any)
|
} as any)
|
||||||
const DemoSentryTestingRoute = DemoSentryTestingRouteImport.update({
|
const DemoSentryTestingRoute = DemoSentryTestingRouteImport.update({
|
||||||
id: '/demo/sentry/testing',
|
id: '/demo/sentry/testing',
|
||||||
@@ -89,34 +78,24 @@ const DemoSentryTestingRoute = DemoSentryTestingRouteImport.update({
|
|||||||
|
|
||||||
export interface FileRoutesByFullPath {
|
export interface FileRoutesByFullPath {
|
||||||
'/': typeof IndexRoute
|
'/': typeof IndexRoute
|
||||||
<<<<<<< HEAD
|
|
||||||
'/access': typeof AccessRouteWithChildren
|
'/access': typeof AccessRouteWithChildren
|
||||||
'/login': typeof LoginRoute
|
'/login': typeof LoginRoute
|
||||||
'/logout': typeof LogoutRoute
|
'/logout': typeof LogoutRoute
|
||||||
'/dashboard': typeof AuthedDashboardRoute
|
'/dashboard': typeof AuthDashboardRoute
|
||||||
'/access/login': typeof AccessLoginRoute
|
'/access/login': typeof AccessLoginRoute
|
||||||
'/access/register': typeof AccessRegisterRoute
|
'/access/register': typeof AccessRegisterRoute
|
||||||
=======
|
|
||||||
'/login': typeof LoginRouteRoute
|
|
||||||
'/auth/dashboard': typeof AuthDashboardRoute
|
|
||||||
>>>>>>> main
|
|
||||||
'/demo/i18n': typeof DemoI18nRoute
|
'/demo/i18n': typeof DemoI18nRoute
|
||||||
'/demo/tanstack-query': typeof DemoTanstackQueryRoute
|
'/demo/tanstack-query': typeof DemoTanstackQueryRoute
|
||||||
'/demo/sentry/testing': typeof DemoSentryTestingRoute
|
'/demo/sentry/testing': typeof DemoSentryTestingRoute
|
||||||
}
|
}
|
||||||
export interface FileRoutesByTo {
|
export interface FileRoutesByTo {
|
||||||
'/': typeof IndexRoute
|
'/': typeof IndexRoute
|
||||||
<<<<<<< HEAD
|
|
||||||
'/access': typeof AccessRouteWithChildren
|
'/access': typeof AccessRouteWithChildren
|
||||||
'/login': typeof LoginRoute
|
'/login': typeof LoginRoute
|
||||||
'/logout': typeof LogoutRoute
|
'/logout': typeof LogoutRoute
|
||||||
'/dashboard': typeof AuthedDashboardRoute
|
'/dashboard': typeof AuthDashboardRoute
|
||||||
'/access/login': typeof AccessLoginRoute
|
'/access/login': typeof AccessLoginRoute
|
||||||
'/access/register': typeof AccessRegisterRoute
|
'/access/register': typeof AccessRegisterRoute
|
||||||
=======
|
|
||||||
'/login': typeof LoginRouteRoute
|
|
||||||
'/auth/dashboard': typeof AuthDashboardRoute
|
|
||||||
>>>>>>> main
|
|
||||||
'/demo/i18n': typeof DemoI18nRoute
|
'/demo/i18n': typeof DemoI18nRoute
|
||||||
'/demo/tanstack-query': typeof DemoTanstackQueryRoute
|
'/demo/tanstack-query': typeof DemoTanstackQueryRoute
|
||||||
'/demo/sentry/testing': typeof DemoSentryTestingRoute
|
'/demo/sentry/testing': typeof DemoSentryTestingRoute
|
||||||
@@ -124,18 +103,13 @@ export interface FileRoutesByTo {
|
|||||||
export interface FileRoutesById {
|
export interface FileRoutesById {
|
||||||
__root__: typeof rootRouteImport
|
__root__: typeof rootRouteImport
|
||||||
'/': typeof IndexRoute
|
'/': typeof IndexRoute
|
||||||
<<<<<<< HEAD
|
'/_auth': typeof AuthRouteWithChildren
|
||||||
'/_authed': typeof AuthedRouteWithChildren
|
|
||||||
'/access': typeof AccessRouteWithChildren
|
'/access': typeof AccessRouteWithChildren
|
||||||
'/login': typeof LoginRoute
|
'/login': typeof LoginRoute
|
||||||
'/logout': typeof LogoutRoute
|
'/logout': typeof LogoutRoute
|
||||||
'/_authed/dashboard': typeof AuthedDashboardRoute
|
'/_auth/dashboard': typeof AuthDashboardRoute
|
||||||
'/access/login': typeof AccessLoginRoute
|
'/access/login': typeof AccessLoginRoute
|
||||||
'/access/register': typeof AccessRegisterRoute
|
'/access/register': typeof AccessRegisterRoute
|
||||||
=======
|
|
||||||
'/login': typeof LoginRouteRoute
|
|
||||||
'/auth/dashboard': typeof AuthDashboardRoute
|
|
||||||
>>>>>>> main
|
|
||||||
'/demo/i18n': typeof DemoI18nRoute
|
'/demo/i18n': typeof DemoI18nRoute
|
||||||
'/demo/tanstack-query': typeof DemoTanstackQueryRoute
|
'/demo/tanstack-query': typeof DemoTanstackQueryRoute
|
||||||
'/demo/sentry/testing': typeof DemoSentryTestingRoute
|
'/demo/sentry/testing': typeof DemoSentryTestingRoute
|
||||||
@@ -146,14 +120,10 @@ export interface FileRouteTypes {
|
|||||||
| '/'
|
| '/'
|
||||||
| '/access'
|
| '/access'
|
||||||
| '/login'
|
| '/login'
|
||||||
<<<<<<< HEAD
|
|
||||||
| '/logout'
|
| '/logout'
|
||||||
| '/dashboard'
|
| '/dashboard'
|
||||||
| '/access/login'
|
| '/access/login'
|
||||||
| '/access/register'
|
| '/access/register'
|
||||||
=======
|
|
||||||
| '/auth/dashboard'
|
|
||||||
>>>>>>> main
|
|
||||||
| '/demo/i18n'
|
| '/demo/i18n'
|
||||||
| '/demo/tanstack-query'
|
| '/demo/tanstack-query'
|
||||||
| '/demo/sentry/testing'
|
| '/demo/sentry/testing'
|
||||||
@@ -162,31 +132,23 @@ export interface FileRouteTypes {
|
|||||||
| '/'
|
| '/'
|
||||||
| '/access'
|
| '/access'
|
||||||
| '/login'
|
| '/login'
|
||||||
<<<<<<< HEAD
|
|
||||||
| '/logout'
|
| '/logout'
|
||||||
| '/dashboard'
|
| '/dashboard'
|
||||||
| '/access/login'
|
| '/access/login'
|
||||||
| '/access/register'
|
| '/access/register'
|
||||||
=======
|
|
||||||
| '/auth/dashboard'
|
|
||||||
>>>>>>> main
|
|
||||||
| '/demo/i18n'
|
| '/demo/i18n'
|
||||||
| '/demo/tanstack-query'
|
| '/demo/tanstack-query'
|
||||||
| '/demo/sentry/testing'
|
| '/demo/sentry/testing'
|
||||||
id:
|
id:
|
||||||
| '__root__'
|
| '__root__'
|
||||||
| '/'
|
| '/'
|
||||||
| '/_authed'
|
| '/_auth'
|
||||||
| '/access'
|
| '/access'
|
||||||
| '/login'
|
| '/login'
|
||||||
<<<<<<< HEAD
|
|
||||||
| '/logout'
|
| '/logout'
|
||||||
| '/_authed/dashboard'
|
| '/_auth/dashboard'
|
||||||
| '/access/login'
|
| '/access/login'
|
||||||
| '/access/register'
|
| '/access/register'
|
||||||
=======
|
|
||||||
| '/auth/dashboard'
|
|
||||||
>>>>>>> main
|
|
||||||
| '/demo/i18n'
|
| '/demo/i18n'
|
||||||
| '/demo/tanstack-query'
|
| '/demo/tanstack-query'
|
||||||
| '/demo/sentry/testing'
|
| '/demo/sentry/testing'
|
||||||
@@ -194,15 +156,10 @@ export interface FileRouteTypes {
|
|||||||
}
|
}
|
||||||
export interface RootRouteChildren {
|
export interface RootRouteChildren {
|
||||||
IndexRoute: typeof IndexRoute
|
IndexRoute: typeof IndexRoute
|
||||||
<<<<<<< HEAD
|
AuthRoute: typeof AuthRouteWithChildren
|
||||||
AuthedRoute: typeof AuthedRouteWithChildren
|
|
||||||
AccessRoute: typeof AccessRouteWithChildren
|
AccessRoute: typeof AccessRouteWithChildren
|
||||||
LoginRoute: typeof LoginRoute
|
LoginRoute: typeof LoginRoute
|
||||||
LogoutRoute: typeof LogoutRoute
|
LogoutRoute: typeof LogoutRoute
|
||||||
=======
|
|
||||||
LoginRouteRoute: typeof LoginRouteRoute
|
|
||||||
AuthDashboardRoute: typeof AuthDashboardRoute
|
|
||||||
>>>>>>> main
|
|
||||||
DemoI18nRoute: typeof DemoI18nRoute
|
DemoI18nRoute: typeof DemoI18nRoute
|
||||||
DemoTanstackQueryRoute: typeof DemoTanstackQueryRoute
|
DemoTanstackQueryRoute: typeof DemoTanstackQueryRoute
|
||||||
DemoSentryTestingRoute: typeof DemoSentryTestingRoute
|
DemoSentryTestingRoute: typeof DemoSentryTestingRoute
|
||||||
@@ -231,11 +188,11 @@ declare module '@tanstack/react-router' {
|
|||||||
preLoaderRoute: typeof AccessRouteImport
|
preLoaderRoute: typeof AccessRouteImport
|
||||||
parentRoute: typeof rootRouteImport
|
parentRoute: typeof rootRouteImport
|
||||||
}
|
}
|
||||||
'/_authed': {
|
'/_auth': {
|
||||||
id: '/_authed'
|
id: '/_auth'
|
||||||
path: ''
|
path: ''
|
||||||
fullPath: '/'
|
fullPath: '/'
|
||||||
preLoaderRoute: typeof AuthedRouteImport
|
preLoaderRoute: typeof AuthRouteImport
|
||||||
parentRoute: typeof rootRouteImport
|
parentRoute: typeof rootRouteImport
|
||||||
}
|
}
|
||||||
'/': {
|
'/': {
|
||||||
@@ -259,7 +216,6 @@ declare module '@tanstack/react-router' {
|
|||||||
preLoaderRoute: typeof DemoI18nRouteImport
|
preLoaderRoute: typeof DemoI18nRouteImport
|
||||||
parentRoute: typeof rootRouteImport
|
parentRoute: typeof rootRouteImport
|
||||||
}
|
}
|
||||||
<<<<<<< HEAD
|
|
||||||
'/access/register': {
|
'/access/register': {
|
||||||
id: '/access/register'
|
id: '/access/register'
|
||||||
path: '/register'
|
path: '/register'
|
||||||
@@ -274,20 +230,12 @@ declare module '@tanstack/react-router' {
|
|||||||
preLoaderRoute: typeof AccessLoginRouteImport
|
preLoaderRoute: typeof AccessLoginRouteImport
|
||||||
parentRoute: typeof AccessRoute
|
parentRoute: typeof AccessRoute
|
||||||
}
|
}
|
||||||
'/_authed/dashboard': {
|
'/_auth/dashboard': {
|
||||||
id: '/_authed/dashboard'
|
id: '/_auth/dashboard'
|
||||||
path: '/dashboard'
|
path: '/dashboard'
|
||||||
fullPath: '/dashboard'
|
fullPath: '/dashboard'
|
||||||
preLoaderRoute: typeof AuthedDashboardRouteImport
|
|
||||||
parentRoute: typeof AuthedRoute
|
|
||||||
=======
|
|
||||||
'/auth/dashboard': {
|
|
||||||
id: '/auth/dashboard'
|
|
||||||
path: '/auth/dashboard'
|
|
||||||
fullPath: '/auth/dashboard'
|
|
||||||
preLoaderRoute: typeof AuthDashboardRouteImport
|
preLoaderRoute: typeof AuthDashboardRouteImport
|
||||||
parentRoute: typeof rootRouteImport
|
parentRoute: typeof AuthRoute
|
||||||
>>>>>>> main
|
|
||||||
}
|
}
|
||||||
'/demo/sentry/testing': {
|
'/demo/sentry/testing': {
|
||||||
id: '/demo/sentry/testing'
|
id: '/demo/sentry/testing'
|
||||||
@@ -299,16 +247,15 @@ declare module '@tanstack/react-router' {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface AuthedRouteChildren {
|
interface AuthRouteChildren {
|
||||||
AuthedDashboardRoute: typeof AuthedDashboardRoute
|
AuthDashboardRoute: typeof AuthDashboardRoute
|
||||||
}
|
}
|
||||||
|
|
||||||
const AuthedRouteChildren: AuthedRouteChildren = {
|
const AuthRouteChildren: AuthRouteChildren = {
|
||||||
AuthedDashboardRoute: AuthedDashboardRoute,
|
AuthDashboardRoute: AuthDashboardRoute,
|
||||||
}
|
}
|
||||||
|
|
||||||
const AuthedRouteWithChildren =
|
const AuthRouteWithChildren = AuthRoute._addFileChildren(AuthRouteChildren)
|
||||||
AuthedRoute._addFileChildren(AuthedRouteChildren)
|
|
||||||
|
|
||||||
interface AccessRouteChildren {
|
interface AccessRouteChildren {
|
||||||
AccessLoginRoute: typeof AccessLoginRoute
|
AccessLoginRoute: typeof AccessLoginRoute
|
||||||
@@ -325,15 +272,10 @@ const AccessRouteWithChildren =
|
|||||||
|
|
||||||
const rootRouteChildren: RootRouteChildren = {
|
const rootRouteChildren: RootRouteChildren = {
|
||||||
IndexRoute: IndexRoute,
|
IndexRoute: IndexRoute,
|
||||||
<<<<<<< HEAD
|
AuthRoute: AuthRouteWithChildren,
|
||||||
AuthedRoute: AuthedRouteWithChildren,
|
|
||||||
AccessRoute: AccessRouteWithChildren,
|
AccessRoute: AccessRouteWithChildren,
|
||||||
LoginRoute: LoginRoute,
|
LoginRoute: LoginRoute,
|
||||||
LogoutRoute: LogoutRoute,
|
LogoutRoute: LogoutRoute,
|
||||||
=======
|
|
||||||
LoginRouteRoute: LoginRouteRoute,
|
|
||||||
AuthDashboardRoute: AuthDashboardRoute,
|
|
||||||
>>>>>>> main
|
|
||||||
DemoI18nRoute: DemoI18nRoute,
|
DemoI18nRoute: DemoI18nRoute,
|
||||||
DemoTanstackQueryRoute: DemoTanstackQueryRoute,
|
DemoTanstackQueryRoute: DemoTanstackQueryRoute,
|
||||||
DemoSentryTestingRoute: DemoSentryTestingRoute,
|
DemoSentryTestingRoute: DemoSentryTestingRoute,
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import { ToastProvider } from "@heroui/react"
|
||||||
import type { QueryClient } from "@tanstack/react-query"
|
import type { QueryClient } from "@tanstack/react-query"
|
||||||
import {
|
import {
|
||||||
createRootRouteWithContext,
|
createRootRouteWithContext,
|
||||||
@@ -55,6 +56,7 @@ function RootDocument({ children }: { children: React.ReactNode }) {
|
|||||||
<HeadContent />
|
<HeadContent />
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
<ToastProvider />
|
||||||
{children}
|
{children}
|
||||||
<Devtools />
|
<Devtools />
|
||||||
<Scripts />
|
<Scripts />
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import { createFileRoute, Link, Outlet } from "@tanstack/react-router"
|
import { createFileRoute, Link, Outlet } from "@tanstack/react-router"
|
||||||
|
|
||||||
export const Route = createFileRoute("/_authed")({
|
export const Route = createFileRoute("/_auth")({
|
||||||
beforeLoad: ({ context }) => {
|
beforeLoad: ({ context }) => {
|
||||||
if (context.error) {
|
if (context.user.error) {
|
||||||
throw new Error("Not authenticated")
|
throw new Error("Not authenticated")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -5,13 +5,13 @@ import { useState } from "react"
|
|||||||
import {
|
import {
|
||||||
Map as MapComponent,
|
Map as MapComponent,
|
||||||
MapMarker,
|
MapMarker,
|
||||||
MapViewport,
|
type MapViewport,
|
||||||
MarkerContent,
|
MarkerContent,
|
||||||
MarkerPopup,
|
MarkerPopup,
|
||||||
MarkerTooltip
|
MarkerTooltip
|
||||||
} from "@/components/maps/map"
|
} from "@/components/maps/map"
|
||||||
|
|
||||||
export const Route = createFileRoute("/auth/dashboard")({
|
export const Route = createFileRoute("/_auth/dashboard")({
|
||||||
component: RouteComponent
|
component: RouteComponent
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ function RouteComponent() {
|
|||||||
})
|
})
|
||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<Card className="h-[800px] p-0 overflow-hidden">
|
<Card className="h-200 p-0 overflow-hidden">
|
||||||
<MapComponent
|
<MapComponent
|
||||||
center={[40.5874827, -1.7925343]}
|
center={[40.5874827, -1.7925343]}
|
||||||
zoom={10}
|
zoom={10}
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
import { createFileRoute } from '@tanstack/react-router'
|
|
||||||
|
|
||||||
export const Route = createFileRoute('/_authed/dashboard')({
|
|
||||||
component: RouteComponent,
|
|
||||||
})
|
|
||||||
|
|
||||||
function RouteComponent() {
|
|
||||||
return <div>Hello "/_authed/dashboard"!</div>
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,13 @@
|
|||||||
import { Button, Card, Form, Input, Label, Spinner } from "@heroui/react"
|
import {
|
||||||
|
Button,
|
||||||
|
FieldError,
|
||||||
|
Fieldset,
|
||||||
|
Form,
|
||||||
|
Input,
|
||||||
|
Label,
|
||||||
|
Spinner,
|
||||||
|
TextField
|
||||||
|
} from "@heroui/react"
|
||||||
import { createFileRoute } from "@tanstack/react-router"
|
import { createFileRoute } from "@tanstack/react-router"
|
||||||
import { LogIn } from "lucide-react"
|
import { LogIn } from "lucide-react"
|
||||||
import { useLogin } from "@/lib/hooks/useLogin"
|
import { useLogin } from "@/lib/hooks/useLogin"
|
||||||
@@ -20,32 +29,41 @@ function RouteComponent() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<>
|
||||||
<Card.Content>
|
|
||||||
<Form onSubmit={handleFormSubmit} className="flex flex-col gap-4">
|
<Form onSubmit={handleFormSubmit} className="flex flex-col gap-4">
|
||||||
<Label isRequired className="ml-4 text-lg">
|
<Fieldset>
|
||||||
Correo
|
<Fieldset.Group>
|
||||||
</Label>
|
<TextField
|
||||||
<Input
|
|
||||||
placeholder="Introduce tu correo"
|
|
||||||
type="email"
|
type="email"
|
||||||
name="email"
|
name="email"
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
className="py-4 text-lg"
|
className="py-4 text-lg"
|
||||||
required
|
isRequired
|
||||||
/>
|
defaultValue={import.meta.env.VITE_LOGIN_USER}
|
||||||
|
>
|
||||||
<Label isRequired className="ml-4 text-lg">
|
<Label isRequired className="ml-4 text-lg">
|
||||||
Contraseña
|
Correo
|
||||||
</Label>
|
</Label>
|
||||||
<Input
|
<Input placeholder="Introduce tu correo" />
|
||||||
placeholder="Introduce tu contraseña"
|
<FieldError />
|
||||||
|
</TextField>
|
||||||
|
<TextField
|
||||||
type="password"
|
type="password"
|
||||||
name="password"
|
name="password"
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
className="py-4 text-lg"
|
className="py-4 text-lg"
|
||||||
required
|
isRequired
|
||||||
/>
|
defaultValue={import.meta.env.VITE_PASSWORD_USER}
|
||||||
<div className="flex justify-end">
|
>
|
||||||
|
<Label isRequired className="ml-4 text-lg">
|
||||||
|
Contraseña
|
||||||
|
</Label>
|
||||||
|
<Input placeholder="Introduce tu contraseña" />
|
||||||
|
<FieldError />
|
||||||
|
</TextField>
|
||||||
|
</Fieldset.Group>
|
||||||
|
</Fieldset>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
className="py-6 px-8 w-full text-white text-lg"
|
className="py-6 px-8 w-full text-white text-lg"
|
||||||
@@ -55,17 +73,15 @@ function RouteComponent() {
|
|||||||
{isPending ? <Spinner /> : <LogIn size={18} />}
|
{isPending ? <Spinner /> : <LogIn size={18} />}
|
||||||
Entrar
|
Entrar
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
|
||||||
</Form>
|
</Form>
|
||||||
</Card.Content>
|
<div className="flex justify-evenly w-full gap-4 mt-2">
|
||||||
<Card.Footer>
|
|
||||||
<div className="flex justify-evenly w-full gap-4">
|
|
||||||
<Button size="lg" className="w-full" variant="secondary">
|
<Button size="lg" className="w-full" variant="secondary">
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
width="16"
|
width="16"
|
||||||
height="16"
|
height="16"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
|
aria-hidden="true"
|
||||||
>
|
>
|
||||||
<g fill="none" fillRule="evenodd" clipRule="evenodd">
|
<g fill="none" fillRule="evenodd" clipRule="evenodd">
|
||||||
<path
|
<path
|
||||||
@@ -95,9 +111,10 @@ function RouteComponent() {
|
|||||||
<Button size="lg" className="w-full" variant="secondary">
|
<Button size="lg" className="w-full" variant="secondary">
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
width="256"
|
width="16"
|
||||||
height="256"
|
height="16"
|
||||||
viewBox="0 0 256 256"
|
viewBox="0 0 256 256"
|
||||||
|
aria-hidden="true"
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fill="#1877f2"
|
fill="#1877f2"
|
||||||
@@ -111,7 +128,6 @@ function RouteComponent() {
|
|||||||
Facebook
|
Facebook
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</Card.Footer>
|
</>
|
||||||
</div>
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import {
|
|||||||
TextField
|
TextField
|
||||||
} from "@heroui/react"
|
} from "@heroui/react"
|
||||||
import { createFileRoute } from "@tanstack/react-router"
|
import { createFileRoute } from "@tanstack/react-router"
|
||||||
import { LogIn } from "lucide-react"
|
import { UserPlus } from "lucide-react"
|
||||||
import { useSignup } from "@/lib/hooks/useSignup"
|
import { useSignup } from "@/lib/hooks/useSignup"
|
||||||
|
|
||||||
export const Route = createFileRoute("/access/register")({
|
export const Route = createFileRoute("/access/register")({
|
||||||
@@ -22,67 +22,105 @@ function RouteComponent() {
|
|||||||
const handleFormSubmit = (e: React.FormEvent<HTMLFormElement>) => {
|
const handleFormSubmit = (e: React.FormEvent<HTMLFormElement>) => {
|
||||||
e.preventDefault()
|
e.preventDefault()
|
||||||
const formData = new FormData(e.currentTarget)
|
const formData = new FormData(e.currentTarget)
|
||||||
const email = formData.get("email") as string
|
|
||||||
const password = formData.get("password") as string
|
|
||||||
const location = formData.get("location") as string
|
|
||||||
const name = formData.get("name") as string
|
|
||||||
|
|
||||||
signup({
|
signup({
|
||||||
email,
|
email: formData.get("email") as string,
|
||||||
password,
|
password: formData.get("password") as string,
|
||||||
location,
|
confirmPassword: formData.get("confirmPassword") as string,
|
||||||
name
|
location: formData.get("location") as string,
|
||||||
|
name: formData.get("name") as string
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<>
|
||||||
<Form onSubmit={handleFormSubmit} className="flex flex-col gap-4">
|
<Form onSubmit={handleFormSubmit} className="flex flex-col gap-4">
|
||||||
<Fieldset>
|
<Fieldset>
|
||||||
<Fieldset.Group>
|
<Fieldset.Group>
|
||||||
|
<TextField
|
||||||
|
type="text"
|
||||||
|
name="name"
|
||||||
|
variant="secondary"
|
||||||
|
className="py-2 text-lg"
|
||||||
|
isRequired
|
||||||
|
>
|
||||||
|
<Label isRequired className="ml-4 text-lg">
|
||||||
|
Nombre completo
|
||||||
|
</Label>
|
||||||
|
<Input placeholder="Tu nombre y apellidos" />
|
||||||
|
<FieldError />
|
||||||
|
</TextField>
|
||||||
<TextField
|
<TextField
|
||||||
type="email"
|
type="email"
|
||||||
name="email"
|
name="email"
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
className="py-4 text-lg"
|
className="py-2 text-lg"
|
||||||
isRequired
|
isRequired
|
||||||
>
|
>
|
||||||
<Label>Correo</Label>
|
<Label isRequired className="ml-4 text-lg">
|
||||||
<Input placeholder="Introduce tu correo" />
|
Correo electrónico
|
||||||
|
</Label>
|
||||||
|
<Input placeholder="tu@correo.com" />
|
||||||
|
<FieldError />
|
||||||
|
</TextField>
|
||||||
|
<TextField
|
||||||
|
type="text"
|
||||||
|
name="location"
|
||||||
|
variant="secondary"
|
||||||
|
className="py-2 text-lg"
|
||||||
|
isRequired
|
||||||
|
>
|
||||||
|
<Label isRequired className="ml-4 text-lg">
|
||||||
|
Ubicación
|
||||||
|
</Label>
|
||||||
|
<Input placeholder="Ciudad, País" />
|
||||||
<FieldError />
|
<FieldError />
|
||||||
</TextField>
|
</TextField>
|
||||||
</Fieldset.Group>
|
|
||||||
</Fieldset>
|
|
||||||
<TextField
|
<TextField
|
||||||
type="password"
|
type="password"
|
||||||
name="password"
|
name="password"
|
||||||
variant="secondary"
|
variant="secondary"
|
||||||
className="py-4 text-lg"
|
className="py-2 text-lg"
|
||||||
isRequired
|
isRequired
|
||||||
>
|
>
|
||||||
<Label>Contraseña</Label>
|
<Label isRequired className="ml-4 text-lg">
|
||||||
<Input placeholder="Introduce tu contraseña" />
|
Contraseña
|
||||||
|
</Label>
|
||||||
|
<Input placeholder="Mínimo 6 caracteres" />
|
||||||
<FieldError />
|
<FieldError />
|
||||||
</TextField>
|
</TextField>
|
||||||
<div className="flex justify-end">
|
<TextField
|
||||||
|
type="password"
|
||||||
|
name="confirmPassword"
|
||||||
|
variant="secondary"
|
||||||
|
className="py-2 text-lg"
|
||||||
|
isRequired
|
||||||
|
>
|
||||||
|
<Label isRequired className="ml-4 text-lg">
|
||||||
|
Confirmar contraseña
|
||||||
|
</Label>
|
||||||
|
<Input placeholder="Repite tu contraseña" />
|
||||||
|
<FieldError />
|
||||||
|
</TextField>
|
||||||
|
</Fieldset.Group>
|
||||||
|
</Fieldset>
|
||||||
<Button
|
<Button
|
||||||
type="submit"
|
type="submit"
|
||||||
className="py-6 px-8 w-full text-white text-lg"
|
className="py-6 px-8 w-full text-white text-lg"
|
||||||
size="lg"
|
size="lg"
|
||||||
isPending={isPending}
|
isPending={isPending}
|
||||||
>
|
>
|
||||||
{isPending ? <Spinner /> : <LogIn size={18} />}
|
{isPending ? <Spinner /> : <UserPlus size={18} />}
|
||||||
Entrar
|
Crear cuenta
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
|
||||||
</Form>
|
</Form>
|
||||||
<div className="flex justify-evenly w-full gap-4">
|
<div className="flex justify-evenly w-full gap-4 mt-2">
|
||||||
<Button size="lg" className="w-full" variant="secondary">
|
<Button size="lg" className="w-full" variant="secondary">
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
width="16"
|
width="16"
|
||||||
height="16"
|
height="16"
|
||||||
viewBox="0 0 16 16"
|
viewBox="0 0 16 16"
|
||||||
|
aria-hidden="true"
|
||||||
>
|
>
|
||||||
<g fill="none" fillRule="evenodd" clipRule="evenodd">
|
<g fill="none" fillRule="evenodd" clipRule="evenodd">
|
||||||
<path
|
<path
|
||||||
@@ -112,9 +150,10 @@ function RouteComponent() {
|
|||||||
<Button size="lg" className="w-full" variant="secondary">
|
<Button size="lg" className="w-full" variant="secondary">
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
width="256"
|
width="16"
|
||||||
height="256"
|
height="16"
|
||||||
viewBox="0 0 256 256"
|
viewBox="0 0 256 256"
|
||||||
|
aria-hidden="true"
|
||||||
>
|
>
|
||||||
<path
|
<path
|
||||||
fill="#1877f2"
|
fill="#1877f2"
|
||||||
@@ -128,6 +167,6 @@ function RouteComponent() {
|
|||||||
Facebook
|
Facebook
|
||||||
</Button>
|
</Button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,6 +12,8 @@ import {
|
|||||||
export const Route = createFileRoute("/")({ component: App })
|
export const Route = createFileRoute("/")({ component: App })
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
|
const navigate = Route.useNavigate()
|
||||||
|
|
||||||
const features = [
|
const features = [
|
||||||
{
|
{
|
||||||
icon: <Zap className="w-12 h-12 text-cyan-400" />,
|
icon: <Zap className="w-12 h-12 text-cyan-400" />,
|
||||||
@@ -53,7 +55,17 @@ function App() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="min-h-screen bg-linear-to-b from-slate-900 via-slate-800 to-slate-900">
|
<div className="min-h-screen bg-linear-to-b from-slate-900 via-slate-800 to-slate-900">
|
||||||
<Button> Hola</Button>
|
<Button
|
||||||
|
onPress={() => {
|
||||||
|
navigate({
|
||||||
|
to: "/login",
|
||||||
|
viewTransition: true
|
||||||
|
})
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{" "}
|
||||||
|
Hola
|
||||||
|
</Button>
|
||||||
<section className="relative py-20 px-6 text-center overflow-hidden">
|
<section className="relative py-20 px-6 text-center overflow-hidden">
|
||||||
<div className="absolute inset-0 bg-linear-to-r from-cyan-500/10 via-blue-500/10 to-purple-500/10"></div>
|
<div className="absolute inset-0 bg-linear-to-r from-cyan-500/10 via-blue-500/10 to-purple-500/10"></div>
|
||||||
<div className="relative max-w-5xl mx-auto">
|
<div className="relative max-w-5xl mx-auto">
|
||||||
|
|||||||
@@ -1,5 +1,9 @@
|
|||||||
import { createFileRoute } from "@tanstack/react-router"
|
import { createFileRoute } from "@tanstack/react-router"
|
||||||
|
import { user } from "@/lib/server/user"
|
||||||
|
|
||||||
export const Route = createFileRoute("/logout")({
|
export const Route = createFileRoute("/logout")({
|
||||||
beforeLoad: async ({ context }) => {}
|
beforeLoad: async () => {
|
||||||
|
await user.logout()
|
||||||
|
},
|
||||||
|
preload: false
|
||||||
})
|
})
|
||||||
|
|||||||
Reference in New Issue
Block a user