@jonsoc/web 1.1.34
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +3 -0
- package/components.json +24 -0
- package/index.html +13 -0
- package/package.json +48 -0
- package/public/apple-touch-icon-v3.png +1 -0
- package/public/apple-touch-icon.png +1 -0
- package/public/favicon-96x96-v3.png +1 -0
- package/public/favicon-96x96.png +1 -0
- package/public/favicon-v3.ico +1 -0
- package/public/favicon-v3.svg +1 -0
- package/public/favicon.ico +1 -0
- package/public/favicon.svg +1 -0
- package/public/robots.txt +6 -0
- package/public/site.webmanifest +1 -0
- package/public/social-share-zen.png +1 -0
- package/public/social-share.png +1 -0
- package/public/theme.json +183 -0
- package/public/web-app-manifest-192x192.png +1 -0
- package/public/web-app-manifest-512x512.png +1 -0
- package/src/components/header.tsx +30 -0
- package/src/components/loader.tsx +9 -0
- package/src/components/mode-toggle.tsx +24 -0
- package/src/components/sign-in-form.tsx +123 -0
- package/src/components/sign-up-form.tsx +148 -0
- package/src/components/theme-provider.tsx +8 -0
- package/src/components/ui/button.tsx +51 -0
- package/src/components/ui/card.tsx +72 -0
- package/src/components/ui/checkbox.tsx +26 -0
- package/src/components/ui/dropdown-menu.tsx +235 -0
- package/src/components/ui/input.tsx +20 -0
- package/src/components/ui/label.tsx +20 -0
- package/src/components/ui/skeleton.tsx +7 -0
- package/src/components/ui/sonner.tsx +39 -0
- package/src/components/user-menu.tsx +50 -0
- package/src/index.css +127 -0
- package/src/lib/auth-client.ts +8 -0
- package/src/lib/utils.ts +6 -0
- package/src/main.tsx +42 -0
- package/src/routeTree.gen.ts +77 -0
- package/src/routes/__root.tsx +47 -0
- package/src/routes/dashboard.tsx +39 -0
- package/src/routes/index.tsx +46 -0
- package/tsconfig.json +18 -0
- package/vite.config.ts +17 -0
package/src/main.tsx
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { ConvexBetterAuthProvider } from "@convex-dev/better-auth/react"
|
|
2
|
+
import { env } from "@jonsoc/env/web"
|
|
3
|
+
import { RouterProvider, createRouter } from "@tanstack/react-router"
|
|
4
|
+
import { ConvexReactClient } from "convex/react"
|
|
5
|
+
import ReactDOM from "react-dom/client"
|
|
6
|
+
|
|
7
|
+
import { authClient } from "@/lib/auth-client"
|
|
8
|
+
|
|
9
|
+
import Loader from "./components/loader"
|
|
10
|
+
import { routeTree } from "./routeTree.gen"
|
|
11
|
+
const convex = new ConvexReactClient(env.VITE_CONVEX_URL)
|
|
12
|
+
|
|
13
|
+
const router = createRouter({
|
|
14
|
+
routeTree,
|
|
15
|
+
defaultPreload: "intent",
|
|
16
|
+
defaultPendingComponent: () => <Loader />,
|
|
17
|
+
context: {},
|
|
18
|
+
Wrap: function WrapComponent({ children }: { children: React.ReactNode }) {
|
|
19
|
+
return (
|
|
20
|
+
<ConvexBetterAuthProvider client={convex} authClient={authClient}>
|
|
21
|
+
{children}
|
|
22
|
+
</ConvexBetterAuthProvider>
|
|
23
|
+
)
|
|
24
|
+
},
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
declare module "@tanstack/react-router" {
|
|
28
|
+
interface Register {
|
|
29
|
+
router: typeof router
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const rootElement = document.getElementById("app")
|
|
34
|
+
|
|
35
|
+
if (!rootElement) {
|
|
36
|
+
throw new Error("Root element not found")
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
if (!rootElement.innerHTML) {
|
|
40
|
+
const root = ReactDOM.createRoot(rootElement)
|
|
41
|
+
root.render(<RouterProvider router={router} />)
|
|
42
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
/* eslint-disable */
|
|
2
|
+
|
|
3
|
+
// @ts-nocheck
|
|
4
|
+
|
|
5
|
+
// noinspection JSUnusedGlobalSymbols
|
|
6
|
+
|
|
7
|
+
// This file was automatically generated by TanStack Router.
|
|
8
|
+
// You should NOT make any changes in this file as it will be overwritten.
|
|
9
|
+
// Additionally, you should also exclude this file from your linter and/or formatter to prevent it from being checked or modified.
|
|
10
|
+
|
|
11
|
+
import { Route as rootRouteImport } from './routes/__root'
|
|
12
|
+
import { Route as DashboardRouteImport } from './routes/dashboard'
|
|
13
|
+
import { Route as IndexRouteImport } from './routes/index'
|
|
14
|
+
|
|
15
|
+
const DashboardRoute = DashboardRouteImport.update({
|
|
16
|
+
id: '/dashboard',
|
|
17
|
+
path: '/dashboard',
|
|
18
|
+
getParentRoute: () => rootRouteImport,
|
|
19
|
+
} as any)
|
|
20
|
+
const IndexRoute = IndexRouteImport.update({
|
|
21
|
+
id: '/',
|
|
22
|
+
path: '/',
|
|
23
|
+
getParentRoute: () => rootRouteImport,
|
|
24
|
+
} as any)
|
|
25
|
+
|
|
26
|
+
export interface FileRoutesByFullPath {
|
|
27
|
+
'/': typeof IndexRoute
|
|
28
|
+
'/dashboard': typeof DashboardRoute
|
|
29
|
+
}
|
|
30
|
+
export interface FileRoutesByTo {
|
|
31
|
+
'/': typeof IndexRoute
|
|
32
|
+
'/dashboard': typeof DashboardRoute
|
|
33
|
+
}
|
|
34
|
+
export interface FileRoutesById {
|
|
35
|
+
__root__: typeof rootRouteImport
|
|
36
|
+
'/': typeof IndexRoute
|
|
37
|
+
'/dashboard': typeof DashboardRoute
|
|
38
|
+
}
|
|
39
|
+
export interface FileRouteTypes {
|
|
40
|
+
fileRoutesByFullPath: FileRoutesByFullPath
|
|
41
|
+
fullPaths: '/' | '/dashboard'
|
|
42
|
+
fileRoutesByTo: FileRoutesByTo
|
|
43
|
+
to: '/' | '/dashboard'
|
|
44
|
+
id: '__root__' | '/' | '/dashboard'
|
|
45
|
+
fileRoutesById: FileRoutesById
|
|
46
|
+
}
|
|
47
|
+
export interface RootRouteChildren {
|
|
48
|
+
IndexRoute: typeof IndexRoute
|
|
49
|
+
DashboardRoute: typeof DashboardRoute
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
declare module '@tanstack/react-router' {
|
|
53
|
+
interface FileRoutesByPath {
|
|
54
|
+
'/dashboard': {
|
|
55
|
+
id: '/dashboard'
|
|
56
|
+
path: '/dashboard'
|
|
57
|
+
fullPath: '/dashboard'
|
|
58
|
+
preLoaderRoute: typeof DashboardRouteImport
|
|
59
|
+
parentRoute: typeof rootRouteImport
|
|
60
|
+
}
|
|
61
|
+
'/': {
|
|
62
|
+
id: '/'
|
|
63
|
+
path: '/'
|
|
64
|
+
fullPath: '/'
|
|
65
|
+
preLoaderRoute: typeof IndexRouteImport
|
|
66
|
+
parentRoute: typeof rootRouteImport
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const rootRouteChildren: RootRouteChildren = {
|
|
72
|
+
IndexRoute: IndexRoute,
|
|
73
|
+
DashboardRoute: DashboardRoute,
|
|
74
|
+
}
|
|
75
|
+
export const routeTree = rootRouteImport
|
|
76
|
+
._addFileChildren(rootRouteChildren)
|
|
77
|
+
._addFileTypes<FileRouteTypes>()
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { HeadContent, Outlet, createRootRouteWithContext } from "@tanstack/react-router"
|
|
2
|
+
import { TanStackRouterDevtools } from "@tanstack/react-router-devtools"
|
|
3
|
+
|
|
4
|
+
import Header from "@/components/header"
|
|
5
|
+
import { ThemeProvider } from "@/components/theme-provider"
|
|
6
|
+
import { Toaster } from "@/components/ui/sonner"
|
|
7
|
+
|
|
8
|
+
import "../index.css"
|
|
9
|
+
|
|
10
|
+
export interface RouterAppContext {}
|
|
11
|
+
|
|
12
|
+
export const Route = createRootRouteWithContext<RouterAppContext>()({
|
|
13
|
+
component: RootComponent,
|
|
14
|
+
head: () => ({
|
|
15
|
+
meta: [
|
|
16
|
+
{
|
|
17
|
+
title: "jonsoc",
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
name: "description",
|
|
21
|
+
content: "jonsoc web application",
|
|
22
|
+
},
|
|
23
|
+
],
|
|
24
|
+
links: [
|
|
25
|
+
{
|
|
26
|
+
rel: "icon",
|
|
27
|
+
href: "/favicon.ico",
|
|
28
|
+
},
|
|
29
|
+
],
|
|
30
|
+
}),
|
|
31
|
+
})
|
|
32
|
+
|
|
33
|
+
function RootComponent() {
|
|
34
|
+
return (
|
|
35
|
+
<>
|
|
36
|
+
<HeadContent />
|
|
37
|
+
<ThemeProvider attribute="class" defaultTheme="dark" disableTransitionOnChange storageKey="vite-ui-theme">
|
|
38
|
+
<div className="grid grid-rows-[auto_1fr] h-svh">
|
|
39
|
+
<Header />
|
|
40
|
+
<Outlet />
|
|
41
|
+
</div>
|
|
42
|
+
<Toaster richColors />
|
|
43
|
+
</ThemeProvider>
|
|
44
|
+
<TanStackRouterDevtools position="bottom-left" />
|
|
45
|
+
</>
|
|
46
|
+
)
|
|
47
|
+
}
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
import { api } from "@jonsoc/convex"
|
|
2
|
+
import { createFileRoute } from "@tanstack/react-router"
|
|
3
|
+
import { Authenticated, AuthLoading, Unauthenticated, useQuery } from "convex/react"
|
|
4
|
+
import { useState } from "react"
|
|
5
|
+
|
|
6
|
+
import SignInForm from "@/components/sign-in-form"
|
|
7
|
+
import SignUpForm from "@/components/sign-up-form"
|
|
8
|
+
import UserMenu from "@/components/user-menu"
|
|
9
|
+
|
|
10
|
+
export const Route = createFileRoute("/dashboard")({
|
|
11
|
+
component: RouteComponent,
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
function RouteComponent() {
|
|
15
|
+
const [showSignIn, setShowSignIn] = useState(false)
|
|
16
|
+
const privateData = useQuery(api.privateData.get)
|
|
17
|
+
|
|
18
|
+
return (
|
|
19
|
+
<>
|
|
20
|
+
<Authenticated>
|
|
21
|
+
<div>
|
|
22
|
+
<h1>Dashboard</h1>
|
|
23
|
+
<p>privateData: {privateData?.message}</p>
|
|
24
|
+
<UserMenu />
|
|
25
|
+
</div>
|
|
26
|
+
</Authenticated>
|
|
27
|
+
<Unauthenticated>
|
|
28
|
+
{showSignIn ? (
|
|
29
|
+
<SignInForm onSwitchToSignUp={() => setShowSignIn(false)} />
|
|
30
|
+
) : (
|
|
31
|
+
<SignUpForm onSwitchToSignIn={() => setShowSignIn(true)} />
|
|
32
|
+
)}
|
|
33
|
+
</Unauthenticated>
|
|
34
|
+
<AuthLoading>
|
|
35
|
+
<div>Loading...</div>
|
|
36
|
+
</AuthLoading>
|
|
37
|
+
</>
|
|
38
|
+
)
|
|
39
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { api } from "@jonsoc/convex"
|
|
2
|
+
import { createFileRoute } from "@tanstack/react-router"
|
|
3
|
+
import { useQuery } from "convex/react"
|
|
4
|
+
|
|
5
|
+
export const Route = createFileRoute("/")({
|
|
6
|
+
component: HomeComponent,
|
|
7
|
+
})
|
|
8
|
+
|
|
9
|
+
const TITLE_TEXT = `
|
|
10
|
+
██████╗ ███████╗████████╗████████╗███████╗██████╗
|
|
11
|
+
██╔══██╗██╔════╝╚══██╔══╝╚══██╔══╝██╔════╝██╔══██╗
|
|
12
|
+
██████╔╝█████╗ ██║ ██║ █████╗ ██████╔╝
|
|
13
|
+
██╔══██╗██╔══╝ ██║ ██║ ██╔══╝ ██╔══██╗
|
|
14
|
+
██████╔╝███████╗ ██║ ██║ ███████╗██║ ██║
|
|
15
|
+
╚═════╝ ╚══════╝ ╚═╝ ╚═╝ ╚══════╝╚═╝ ╚═╝
|
|
16
|
+
|
|
17
|
+
████████╗ ███████╗████████╗ █████╗ ██████╗██╗ ██╗
|
|
18
|
+
╚══██╔══╝ ██╔════╝╚══██╔══╝██╔══██╗██╔════╝██║ ██╔╝
|
|
19
|
+
██║ ███████╗ ██║ ███████║██║ █████╔╝
|
|
20
|
+
██║ ╚════██║ ██║ ██╔══██║██║ ██╔═██╗
|
|
21
|
+
██║ ███████║ ██║ ██║ ██║╚██████╗██║ ██╗
|
|
22
|
+
╚═╝ ╚══════╝ ╚═╝ ╚═╝ ╚═╝ ╚═════╝╚═╝ ╚═╝
|
|
23
|
+
`
|
|
24
|
+
|
|
25
|
+
function HomeComponent() {
|
|
26
|
+
const healthCheck = useQuery(api.healthCheck.get)
|
|
27
|
+
|
|
28
|
+
return (
|
|
29
|
+
<div className="container mx-auto max-w-3xl px-4 py-2">
|
|
30
|
+
<pre className="overflow-x-auto font-mono text-sm">{TITLE_TEXT}</pre>
|
|
31
|
+
<div className="grid gap-6">
|
|
32
|
+
<section className="rounded-lg border p-4">
|
|
33
|
+
<h2 className="mb-2 font-medium">API Status</h2>
|
|
34
|
+
<div className="flex items-center gap-2">
|
|
35
|
+
<div
|
|
36
|
+
className={`h-2 w-2 rounded-full ${healthCheck === "OK" ? "bg-green-500" : healthCheck === undefined ? "bg-orange-400" : "bg-red-500"}`}
|
|
37
|
+
/>
|
|
38
|
+
<span className="text-sm text-muted-foreground">
|
|
39
|
+
{healthCheck === undefined ? "Checking..." : healthCheck === "OK" ? "Connected" : "Error"}
|
|
40
|
+
</span>
|
|
41
|
+
</div>
|
|
42
|
+
</section>
|
|
43
|
+
</div>
|
|
44
|
+
</div>
|
|
45
|
+
)
|
|
46
|
+
}
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"strict": true,
|
|
4
|
+
"esModuleInterop": true,
|
|
5
|
+
"jsx": "react-jsx",
|
|
6
|
+
"target": "ESNext",
|
|
7
|
+
"module": "ESNext",
|
|
8
|
+
"moduleResolution": "Bundler",
|
|
9
|
+
"verbatimModuleSyntax": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
"types": ["vite/client"],
|
|
12
|
+
"rootDirs": ["."],
|
|
13
|
+
"baseUrl": ".",
|
|
14
|
+
"paths": {
|
|
15
|
+
"@/*": ["./src/*"]
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
}
|
package/vite.config.ts
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import tailwindcss from "@tailwindcss/vite"
|
|
2
|
+
import { tanstackRouter } from "@tanstack/router-plugin/vite"
|
|
3
|
+
import react from "@vitejs/plugin-react"
|
|
4
|
+
import path from "node:path"
|
|
5
|
+
import { defineConfig } from "vite"
|
|
6
|
+
|
|
7
|
+
export default defineConfig({
|
|
8
|
+
plugins: [tailwindcss(), tanstackRouter({}), react()],
|
|
9
|
+
resolve: {
|
|
10
|
+
alias: {
|
|
11
|
+
"@": path.resolve(__dirname, "./src"),
|
|
12
|
+
},
|
|
13
|
+
},
|
|
14
|
+
server: {
|
|
15
|
+
port: 3001,
|
|
16
|
+
},
|
|
17
|
+
})
|