diff --git a/.gitignore b/.gitignore index cb3c79d..32c41f7 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,4 @@ count.txt .vinxi todos.json data.db +public/uploads \ No newline at end of file diff --git a/bknd.config.ts b/bknd.config.ts index 874ecb4..b34aba2 100644 --- a/bknd.config.ts +++ b/bknd.config.ts @@ -1,10 +1,39 @@ -import type { NextjsBkndConfig } from "bknd/adapter/nextjs"; +import { type BkndConfig, em, entity, text, boolean } from "bknd"; + +// Unrelated to framework adapters +import { registerLocalMediaAdapter } from "bknd/adapter/node"; + +const local = registerLocalMediaAdapter(); + + +// --------------------- SCHEMA ----------------------- +// this just for testing +const schema = em({ + todos: entity("todos", { + title: text(), + done: boolean(), + }), + post:entity("posts",{ + title: text(), + content: text(), + }) +}); + +// --------------------- SCHEMA END ----------------------- export default { connection: { url: "data.db", }, - options:{ - - } -} satisfies NextjsBkndConfig; \ No newline at end of file + options: {}, + config: { + data: schema.toJSON(), + auth: { enabled: true }, + media: { + enabled: true, + adapter: local({ + path: "./public/uploads", + }), + }, + }, +} satisfies BkndConfig; diff --git a/src/bknd.ts b/src/bknd.ts index 3bdac70..7ff907d 100644 --- a/src/bknd.ts +++ b/src/bknd.ts @@ -1,8 +1,8 @@ +// Both work just fine +// import { getApp as getBkndApp } from "bknd/adapter/react-router"; import { getApp as getBkndApp } from "bknd/adapter/nextjs"; import config from "../bknd.config"; -// import { headers } from "next/headers"; - export async function getApi({ headers, verify, @@ -20,5 +20,3 @@ export async function getApi({ return app.getApi(); } - -export { config }; diff --git a/src/routes/__root.tsx b/src/routes/__root.tsx index 1810d79..f4095a8 100644 --- a/src/routes/__root.tsx +++ b/src/routes/__root.tsx @@ -1,33 +1,34 @@ -import { HeadContent, Scripts, createRootRoute } from '@tanstack/react-router' -import { TanStackRouterDevtoolsPanel } from '@tanstack/react-router-devtools' -import { TanStackDevtools } from '@tanstack/react-devtools' +import { HeadContent, Scripts, createRootRoute } from "@tanstack/react-router"; +import { TanStackRouterDevtoolsPanel } from "@tanstack/react-router-devtools"; +import { TanStackDevtools } from "@tanstack/react-devtools"; +import { ClientProvider } from "bknd/client"; -import appCss from '../styles.css?url' +import appCss from "../styles.css?url"; export const Route = createRootRoute({ head: () => ({ meta: [ { - charSet: 'utf-8', + charSet: "utf-8", }, { - name: 'viewport', - content: 'width=device-width, initial-scale=1', + name: "viewport", + content: "width=device-width, initial-scale=1", }, { - title: 'TanStack Start Starter', + title: "TanStack Start Starter", }, ], links: [ { - rel: 'stylesheet', + rel: "stylesheet", href: appCss, }, ], }), shellComponent: RootDocument, -}) +}); function RootDocument({ children }: { children: React.ReactNode }) { return ( @@ -36,14 +37,16 @@ function RootDocument({ children }: { children: React.ReactNode }) { - {children} + + {children} + , }, ]} @@ -51,5 +54,5 @@ function RootDocument({ children }: { children: React.ReactNode }) { - ) + ); } diff --git a/src/routes/admin.$.tsx b/src/routes/admin.$.tsx index d28d408..92dc2ae 100644 --- a/src/routes/admin.$.tsx +++ b/src/routes/admin.$.tsx @@ -1,41 +1,21 @@ -import { getApi } from "@/bknd"; import { createFileRoute } from "@tanstack/react-router"; -import { createServerFn } from "@tanstack/react-start"; -import { getRequestHeaders } from "@tanstack/react-start/server"; +import { useAuth } from "bknd/client"; import "bknd/dist/styles.css"; import { Admin } from "bknd/ui"; -export const getUser = createServerFn({ method: "GET" }).handler(async () => { - const headers = getRequestHeaders(); - const api = await getApi({ verify: true, headers }); - return { user: api.getUser() }; -}); export const Route = createFileRoute("/admin/$")({ component: RouteComponent, - loader: async () => { - const user = await getUser(); - return { user }; - }, }); function RouteComponent() { - const { user } = Route.useLoaderData(); - console.log(user); - + const { user } = useAuth(); return ( diff --git a/src/routes/api.$.ts b/src/routes/api.$.ts index 440ffc3..f7c0c99 100644 --- a/src/routes/api.$.ts +++ b/src/routes/api.$.ts @@ -1,25 +1,17 @@ import { createFileRoute } from "@tanstack/react-router"; -import { config } from "@/bknd"; +import config from "../../bknd.config"; + +// Works fine import { serve } from "bknd/adapter/nextjs"; const handler = serve({ ...config, - // cleanRequest: { - // depending on what name you used for the catch-all route, - // you need to change this to clean it from the request. - // searchParams: ["$"], - // }, }); export const Route = createFileRoute("/api/$")({ server: { handlers: { - ANY: async ({ request }) => { - const res = await handler(request); - // console.log("[API] ", res); - - return res; - }, + ANY: async ({ request }) => await handler(request), }, }, }); diff --git a/src/routes/index.tsx b/src/routes/index.tsx index 7eea81b..a019d28 100644 --- a/src/routes/index.tsx +++ b/src/routes/index.tsx @@ -1,27 +1,142 @@ import { createFileRoute, Link } from "@tanstack/react-router"; import "../App.css"; +import { useAuth } from "bknd/client"; +import { useState } from "react"; export const Route = createFileRoute("/")({ component: App }); function App() { + const { user, verified, register, logout, login } = useAuth(); + + const [email, setEmail] = useState(""); + const [password, setPassword] = useState(""); + const [mode, setMode] = useState<"login" | "register">("login"); + const [loading, setLoading] = useState(false); + const [error, setError] = useState(null); + + async function handleSubmit(e: React.SubmitEvent) { + e.preventDefault(); + setLoading(true); + setError(null); + try { + if (mode === "login") { + // attempt login + await login({ email, password } as any); + } else { + // attempt register + await register({ email, password } as any); + } + setEmail(""); + setPassword(""); + } catch (err: any) { + setError(err?.message ?? String(err)); + } finally { + setLoading(false); + } + } + + async function handleLogout() { + setLoading(true); + try { + await logout(); + } catch (err: any) { + setError(err?.message ?? String(err)); + } finally { + setLoading(false); + } + } + return ( -
-
- TanStack Logo - - Admin Dashboard - -
+
+
+
+ TanStack Logo +
+
+ +
+ +
+

Account

+ {user ? ( +
+
+ Signed in as: {user?.email ?? "Unknown"} +
+
+ Verified: {verified ? "Yes" : "No"} +
+
+ + + + +
+
+ ) : ( +
+
+ + +
+ + setEmail(e.target.value)} + required + style={{ + border: "1px solid white", + padding: "4px", + borderRadius: "4px" + }} + type="email" + /> + + setPassword(e.target.value)} + required + style={{ + border: "1px solid white", + padding: "4px", + borderRadius: "4px" + }} + type="password" + /> + + {error ?
{error}
: null} + + +
+ )} +
+
); }