feat: add dashboard route and update user registration and login flows

This commit is contained in:
juan 2025-08-15 18:54:14 +02:00
parent 974337af2b
commit e1c0866cdf
11 changed files with 76 additions and 38 deletions

28
package-lock.json generated
View File

@ -17,6 +17,7 @@
"@tanstack/react-router-with-query": "^1.130.12",
"@tanstack/react-start": "^1.130.15",
"@tanstack/router-plugin": "^1.130.15",
"@vis.gl/react-google-maps": "^1.5.5",
"drizzle-orm": "^0.44.4",
"framer-motion": "^12.23.12",
"postgres": "^3.4.7",
@ -30,6 +31,7 @@
"devDependencies": {
"@biomejs/biome": "2.1.3",
"@tanstack/react-router-ssr-query": "^1.131.5",
"@types/google.maps": "^3.58.1",
"@types/react": "^19.1.9",
"@types/react-dom": "^19.1.7",
"@vitejs/plugin-react": "^4.7.0",
@ -7650,6 +7652,12 @@
"integrity": "sha512-dWHzHa2WqEXI/O1E9OjrocMTKJl2mSrEolh1Iomrv6U+JuNwaHXsXx9bLu5gG7BUWFIN0skIQJQ/L1rIex4X6w==",
"license": "MIT"
},
"node_modules/@types/google.maps": {
"version": "3.58.1",
"resolved": "https://registry.npmjs.org/@types/google.maps/-/google.maps-3.58.1.tgz",
"integrity": "sha512-X9QTSvGJ0nCfMzYOnaVs/k6/4L+7F5uCS+4iUmkLEls6J9S/Phv+m/i3mDeyc49ZBgwab3EFO1HEoBY7k98EGQ==",
"license": "MIT"
},
"node_modules/@types/node": {
"version": "24.2.0",
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.2.0.tgz",
@ -7867,6 +7875,20 @@
"url": "https://github.com/sponsors/jonschlinkert"
}
},
"node_modules/@vis.gl/react-google-maps": {
"version": "1.5.5",
"resolved": "https://registry.npmjs.org/@vis.gl/react-google-maps/-/react-google-maps-1.5.5.tgz",
"integrity": "sha512-LgHtK1AtE2/BN4dPoK05oWu0jWmeDdyX0Ffqi+mZc+M4apaHn2sUxxKXAxhPF90O9vcsiou/ntm6/XBWX+gpqw==",
"license": "MIT",
"dependencies": {
"@types/google.maps": "^3.54.10",
"fast-deep-equal": "^3.1.3"
},
"peerDependencies": {
"react": ">=16.8.0 || ^19.0 || ^19.0.0-rc",
"react-dom": ">=16.8.0 || ^19.0 || ^19.0.0-rc"
}
},
"node_modules/@vitejs/plugin-react": {
"version": "4.7.0",
"resolved": "https://registry.npmjs.org/@vitejs/plugin-react/-/plugin-react-4.7.0.tgz",
@ -9929,6 +9951,12 @@
"url": "https://github.com/sponsors/sindresorhus"
}
},
"node_modules/fast-deep-equal": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
"integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==",
"license": "MIT"
},
"node_modules/fast-fifo": {
"version": "1.3.2",
"resolved": "https://registry.npmjs.org/fast-fifo/-/fast-fifo-1.3.2.tgz",

View File

@ -23,6 +23,7 @@
"@tanstack/react-router-with-query": "^1.130.12",
"@tanstack/react-start": "^1.130.15",
"@tanstack/router-plugin": "^1.130.15",
"@vis.gl/react-google-maps": "^1.5.5",
"drizzle-orm": "^0.44.4",
"framer-motion": "^12.23.12",
"postgres": "^3.4.7",
@ -36,6 +37,7 @@
"devDependencies": {
"@biomejs/biome": "2.1.3",
"@tanstack/react-router-ssr-query": "^1.131.5",
"@types/google.maps": "^3.58.1",
"@types/react": "^19.1.9",
"@types/react-dom": "^19.1.7",
"@vitejs/plugin-react": "^4.7.0",

View File

@ -1,7 +1,6 @@
import { drizzle } from 'drizzle-orm/postgres-js'
import postgres from 'postgres'
import { users } from './db/schema'
const connectionString = process.env.DATABASE_URL!
@ -9,7 +8,3 @@ const connectionString = process.env.DATABASE_URL!
const client = postgres(connectionString, { prepare: false })
export const db = drizzle(client);
const allUsers = await db.select().from(users);
console.log(allUsers);

View File

@ -30,7 +30,7 @@ export const useLogin = () => {
onSuccess: () => {
toast.success("Login successful! Redirecting to posts..", { id: "login" })
navigate({
to: "/post"
to: "/dashboard"
})
},
onError: (error) => {

View File

@ -19,12 +19,13 @@ export const getUser = createServerFn().handler(async () => {
message: error?.message ?? "Unknown error"
}
}
console.log(data)
return {
user: {
id: data.user.id,
email: data.user.email,
name: data.user.user_metadata.name || ""
name: data.user.user_metadata.name || "",
location: data.user.user_metadata.location || ""
},
error: false
}
@ -76,7 +77,13 @@ export const signupUser = createServerFn({ method: "POST" })
const supabase = getSupabaseServerClient()
const { error } = await supabase.auth.signUp({
email: data.email,
password: data.password
password: data.password,
options: {
data: {
name: data.name,
location: data.location
}
}
})
if (error) {
return {

View File

@ -8,6 +8,8 @@ export const loginFormSchema = z.object({
export const signupFormSchema = z.object({
email: z.email("Invalid email address"),
password: z.string().min(6, "Password must be at least 6 characters long"),
name: z.string().min(1, "The field is required"),
location: z.string().min(1, "The field is required"),
redirectUrl: z.string().optional()
})

View File

@ -15,7 +15,7 @@ import { Route as LoginRouteImport } from './routes/login'
import { Route as AuthedRouteImport } from './routes/_authed'
import { Route as IndexRouteImport } from './routes/index'
import { Route as AuthedRegisterRouteImport } from './routes/_authed/register'
import { Route as AuthedPostRouteImport } from './routes/_authed/post'
import { Route as AuthedDashboardRouteImport } from './routes/_authed/dashboard'
const SignupRoute = SignupRouteImport.update({
id: '/signup',
@ -46,9 +46,9 @@ const AuthedRegisterRoute = AuthedRegisterRouteImport.update({
path: '/register',
getParentRoute: () => AuthedRoute,
} as any)
const AuthedPostRoute = AuthedPostRouteImport.update({
id: '/post',
path: '/post',
const AuthedDashboardRoute = AuthedDashboardRouteImport.update({
id: '/dashboard',
path: '/dashboard',
getParentRoute: () => AuthedRoute,
} as any)
@ -57,7 +57,7 @@ export interface FileRoutesByFullPath {
'/login': typeof LoginRoute
'/logout': typeof LogoutRoute
'/signup': typeof SignupRoute
'/post': typeof AuthedPostRoute
'/dashboard': typeof AuthedDashboardRoute
'/register': typeof AuthedRegisterRoute
}
export interface FileRoutesByTo {
@ -65,7 +65,7 @@ export interface FileRoutesByTo {
'/login': typeof LoginRoute
'/logout': typeof LogoutRoute
'/signup': typeof SignupRoute
'/post': typeof AuthedPostRoute
'/dashboard': typeof AuthedDashboardRoute
'/register': typeof AuthedRegisterRoute
}
export interface FileRoutesById {
@ -75,14 +75,14 @@ export interface FileRoutesById {
'/login': typeof LoginRoute
'/logout': typeof LogoutRoute
'/signup': typeof SignupRoute
'/_authed/post': typeof AuthedPostRoute
'/_authed/dashboard': typeof AuthedDashboardRoute
'/_authed/register': typeof AuthedRegisterRoute
}
export interface FileRouteTypes {
fileRoutesByFullPath: FileRoutesByFullPath
fullPaths: '/' | '/login' | '/logout' | '/signup' | '/post' | '/register'
fullPaths: '/' | '/login' | '/logout' | '/signup' | '/dashboard' | '/register'
fileRoutesByTo: FileRoutesByTo
to: '/' | '/login' | '/logout' | '/signup' | '/post' | '/register'
to: '/' | '/login' | '/logout' | '/signup' | '/dashboard' | '/register'
id:
| '__root__'
| '/'
@ -90,7 +90,7 @@ export interface FileRouteTypes {
| '/login'
| '/logout'
| '/signup'
| '/_authed/post'
| '/_authed/dashboard'
| '/_authed/register'
fileRoutesById: FileRoutesById
}
@ -146,23 +146,23 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof AuthedRegisterRouteImport
parentRoute: typeof AuthedRoute
}
'/_authed/post': {
id: '/_authed/post'
path: '/post'
fullPath: '/post'
preLoaderRoute: typeof AuthedPostRouteImport
'/_authed/dashboard': {
id: '/_authed/dashboard'
path: '/dashboard'
fullPath: '/dashboard'
preLoaderRoute: typeof AuthedDashboardRouteImport
parentRoute: typeof AuthedRoute
}
}
}
interface AuthedRouteChildren {
AuthedPostRoute: typeof AuthedPostRoute
AuthedDashboardRoute: typeof AuthedDashboardRoute
AuthedRegisterRoute: typeof AuthedRegisterRoute
}
const AuthedRouteChildren: AuthedRouteChildren = {
AuthedPostRoute: AuthedPostRoute,
AuthedDashboardRoute: AuthedDashboardRoute,
AuthedRegisterRoute: AuthedRegisterRoute,
}

View File

@ -3,13 +3,14 @@ import { useQuery } from "@tanstack/react-query"
import { createFileRoute } from "@tanstack/react-router"
import { getAllUsers, getProfile } from "@/lib/server/user"
export const Route = createFileRoute("/_authed/post")({
export const Route = createFileRoute("/_authed/dashboard")({
component: RouteComponent
})
function RouteComponent() {
const navigate = Route.useNavigate()
const { user } = Route.useRouteContext()
console.log("User in dashboard:", user)
const { data } = useQuery({
queryKey: ["users"],
queryFn: async () => {
@ -29,7 +30,7 @@ function RouteComponent() {
return (
<div>
Hello "/_authed/post"!{" "}
Hello "/_authed/dashboard"!{" "}
<div>
{" "}
<Button

View File

@ -1,4 +1,4 @@
import { Button, Form, Input, Textarea } from "@heroui/react"
import { Button, Form, Input, Slider, Textarea } from "@heroui/react"
import { createFileRoute } from "@tanstack/react-router"
import type { FormEvent } from "react"
import { useProfile } from "@/lib/hooks/user/useCreateUser"
@ -26,17 +26,16 @@ function RouteComponent() {
validationErrors={errors}
>
<Input name="name" label="Nombre completo" isRequired />
<Input name="location" label="Lugar" />
<Input name="company" label="Empresa" />
<Input name="role" label="Cargo" />
<Textarea name="description" label="Descripción" />
<Textarea name="differentiator" label="¿Qué te hace diferente?" />
<Input name="coverage_areas" label="Areas de cobertura" />
<Input name="services" label="Servicios" />
projects text[] (proyectos destacados)
contact text (número de teléfono u otro medio)
email text
<Button isLoading={isPending} type="submit">Crear usuario</Button>
<Slider name="coverage_areas" label="Areas de cobertura" />
<Input name="services" label="Servicios" />{" "}
{/* Crear varios checkboxes */}
<Button isLoading={isPending} type="submit">
Crear usuario
</Button>
</Form>
</div>
)

View File

@ -7,7 +7,7 @@ export const Route = createFileRoute("/login")({
beforeLoad: ({ context }) => {
if (!context?.error) {
throw redirect({
to: "/post"
to: "/dashboard"
})
// TODO: Redirect to login page
}

View File

@ -17,7 +17,9 @@ function SignupComp() {
signup({
email: formData.get("email") as string,
password: formData.get("password") as string
password: formData.get("password") as string,
name: formData.get("nombre") as string,
location: formData.get("location") as string
})
}
@ -31,6 +33,8 @@ function SignupComp() {
>
<Input name="email" type="email" label="Email" />
<Input name="password" type="password" label="Password" />
<Input name="nombre" label="Name" />
<Input name="location" label="Location" />
<Button type="submit" isLoading={isPending}>
Enviar
</Button>