create-croissant 0.1.39 → 0.1.40
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/package.json +9 -9
- package/template/README.md +4 -4
- package/template/apps/desktop/electron-builder.yml +6 -6
- package/template/apps/desktop/electron.vite.config.ts +8 -8
- package/template/apps/desktop/package.json +5 -5
- package/template/apps/desktop/src/main/index.ts +32 -32
- package/template/apps/desktop/src/preload/index.d.ts +3 -3
- package/template/apps/desktop/src/preload/index.ts +8 -8
- package/template/apps/desktop/src/renderer/src/App.tsx +5 -5
- package/template/apps/desktop/src/renderer/src/assets/base.css +4 -4
- package/template/apps/desktop/src/renderer/src/assets/main.css +3 -3
- package/template/apps/desktop/src/renderer/src/components/Versions.tsx +4 -4
- package/template/apps/desktop/src/renderer/src/main.tsx +7 -7
- package/template/apps/desktop/tsconfig.json +1 -4
- package/template/apps/desktop/tsconfig.node.json +7 -1
- package/template/apps/desktop/tsconfig.web.json +3 -9
- package/template/apps/mobile/app/(tabs)/_layout.tsx +11 -10
- package/template/apps/mobile/app/(tabs)/explore.tsx +29 -27
- package/template/apps/mobile/app/(tabs)/index.tsx +25 -24
- package/template/apps/mobile/app/_layout.tsx +8 -8
- package/template/apps/mobile/app/modal.tsx +6 -6
- package/template/apps/mobile/components/external-link.tsx +5 -5
- package/template/apps/mobile/components/haptic-tab.tsx +4 -4
- package/template/apps/mobile/components/hello-wave.tsx +5 -4
- package/template/apps/mobile/components/parallax-scroll-view.tsx +15 -13
- package/template/apps/mobile/components/themed-text.tsx +14 -14
- package/template/apps/mobile/components/themed-view.tsx +3 -3
- package/template/apps/mobile/components/ui/collapsible.tsx +14 -13
- package/template/apps/mobile/components/ui/icon-symbol.ios.tsx +4 -4
- package/template/apps/mobile/components/ui/icon-symbol.tsx +9 -9
- package/template/apps/mobile/constants/theme.ts +19 -19
- package/template/apps/mobile/hooks/use-color-scheme.ts +1 -1
- package/template/apps/mobile/hooks/use-color-scheme.web.ts +3 -3
- package/template/apps/mobile/hooks/use-theme-color.ts +4 -4
- package/template/apps/mobile/package.json +3 -3
- package/template/apps/mobile/scripts/reset-project.js +2 -2
- package/template/apps/mobile/tsconfig.json +2 -9
- package/template/apps/platform/drizzle.config.ts +5 -5
- package/template/apps/platform/package.json +4 -4
- package/template/apps/platform/src/components/app-sidebar.tsx +60 -69
- package/template/apps/platform/src/components/login-form.tsx +32 -39
- package/template/apps/platform/src/components/search-form.tsx +5 -13
- package/template/apps/platform/src/components/signup-form.tsx +39 -49
- package/template/apps/platform/src/components/version-switcher.tsx +11 -21
- package/template/apps/platform/src/lib/auth-utils.ts +12 -14
- package/template/apps/platform/src/lib/orpc.ts +17 -17
- package/template/apps/platform/src/router.tsx +5 -5
- package/template/apps/platform/src/routes/__root.tsx +13 -15
- package/template/apps/platform/src/routes/_auth/account.tsx +61 -50
- package/template/apps/platform/src/routes/_auth/dashboard.tsx +17 -17
- package/template/apps/platform/src/routes/_auth/examples/client-orpc-auth.tsx +13 -13
- package/template/apps/platform/src/routes/_auth/examples/ssr-orpc-auth.tsx +16 -16
- package/template/apps/platform/src/routes/_auth.tsx +5 -5
- package/template/apps/platform/src/routes/_public/examples/client-orpc.tsx +108 -88
- package/template/apps/platform/src/routes/_public/examples/isr.tsx +14 -14
- package/template/apps/platform/src/routes/_public/examples/ssr-orpc.tsx +92 -75
- package/template/apps/platform/src/routes/_public/index.tsx +22 -19
- package/template/apps/platform/src/routes/_public/login.tsx +4 -4
- package/template/apps/platform/src/routes/_public/signup.tsx +6 -5
- package/template/apps/platform/src/routes/_public.tsx +5 -5
- package/template/apps/platform/src/routes/api/auth/$.ts +13 -13
- package/template/apps/platform/src/routes/api/rpc.$.ts +13 -13
- package/template/apps/platform/vite.config.ts +8 -8
- package/template/docker-compose.yml +1 -1
- package/template/package.json +24 -22
- package/template/packages/auth/package.json +9 -9
- package/template/packages/auth/src/lib/auth.ts +1 -1
- package/template/packages/db/package.json +7 -7
- package/template/packages/db/src/index.ts +4 -4
- package/template/packages/db/src/schema.ts +2 -2
- package/template/packages/orpc/package.json +6 -6
- package/template/packages/orpc/src/lib/planets.ts +39 -43
- package/template/packages/orpc/src/lib/router.ts +15 -15
- package/template/packages/ui/package.json +10 -10
- package/template/packages/ui/src/components/accordion.tsx +20 -22
- package/template/packages/ui/src/components/alert-dialog.tsx +31 -56
- package/template/packages/ui/src/components/alert.tsx +15 -23
- package/template/packages/ui/src/components/aspect-ratio.tsx +3 -3
- package/template/packages/ui/src/components/avatar.tsx +19 -35
- package/template/packages/ui/src/components/badge.tsx +13 -17
- package/template/packages/ui/src/components/breadcrumb.tsx +22 -44
- package/template/packages/ui/src/components/button-group.tsx +16 -25
- package/template/packages/ui/src/components/button.tsx +8 -9
- package/template/packages/ui/src/components/calendar.tsx +43 -82
- package/template/packages/ui/src/components/card.tsx +15 -26
- package/template/packages/ui/src/components/carousel.tsx +70 -78
- package/template/packages/ui/src/components/chart.tsx +84 -117
- package/template/packages/ui/src/components/checkbox.tsx +8 -9
- package/template/packages/ui/src/components/collapsible.tsx +5 -9
- package/template/packages/ui/src/components/combobox.tsx +44 -68
- package/template/packages/ui/src/components/command.tsx +32 -47
- package/template/packages/ui/src/components/context-menu.tsx +45 -71
- package/template/packages/ui/src/components/dialog.tsx +29 -51
- package/template/packages/ui/src/components/direction.tsx +1 -4
- package/template/packages/ui/src/components/drawer.tsx +24 -38
- package/template/packages/ui/src/components/dropdown-menu.tsx +45 -55
- package/template/packages/ui/src/components/empty.tsx +16 -27
- package/template/packages/ui/src/components/field.tsx +49 -63
- package/template/packages/ui/src/components/hover-card.tsx +9 -14
- package/template/packages/ui/src/components/input-group.tsx +40 -52
- package/template/packages/ui/src/components/input-otp.tsx +17 -18
- package/template/packages/ui/src/components/input.tsx +6 -6
- package/template/packages/ui/src/components/item.tsx +31 -44
- package/template/packages/ui/src/components/kbd.tsx +5 -5
- package/template/packages/ui/src/components/label.tsx +6 -6
- package/template/packages/ui/src/components/menubar.tsx +51 -64
- package/template/packages/ui/src/components/mode-toggle.tsx +9 -15
- package/template/packages/ui/src/components/native-select.tsx +18 -24
- package/template/packages/ui/src/components/navigation-menu.tsx +28 -35
- package/template/packages/ui/src/components/pagination.tsx +19 -31
- package/template/packages/ui/src/components/popover.tsx +13 -26
- package/template/packages/ui/src/components/progress.tsx +13 -30
- package/template/packages/ui/src/components/radio-group.tsx +7 -7
- package/template/packages/ui/src/components/resizable.tsx +12 -20
- package/template/packages/ui/src/components/scroll-area.tsx +8 -12
- package/template/packages/ui/src/components/select.tsx +31 -42
- package/template/packages/ui/src/components/separator.tsx +6 -10
- package/template/packages/ui/src/components/sheet.tsx +25 -38
- package/template/packages/ui/src/components/sidebar.tsx +137 -170
- package/template/packages/ui/src/components/skeleton.tsx +3 -3
- package/template/packages/ui/src/components/slider.tsx +5 -5
- package/template/packages/ui/src/components/sonner.tsx +20 -24
- package/template/packages/ui/src/components/spinner.tsx +10 -5
- package/template/packages/ui/src/components/switch.tsx +6 -6
- package/template/packages/ui/src/components/table.tsx +18 -45
- package/template/packages/ui/src/components/tabs.tsx +14 -22
- package/template/packages/ui/src/components/textarea.tsx +5 -5
- package/template/packages/ui/src/components/theme-provider.tsx +43 -48
- package/template/packages/ui/src/components/toggle-group.tsx +18 -20
- package/template/packages/ui/src/components/toggle.tsx +9 -10
- package/template/packages/ui/src/components/tooltip.tsx +10 -22
- package/template/packages/ui/src/hooks/use-mobile.ts +11 -11
- package/template/packages/ui/src/lib/utils.ts +4 -4
- package/template/packages/ui/src/styles/globals.css +106 -106
- package/template/turbo.json +15 -6
- package/template/.prettierignore +0 -10
- package/template/apps/desktop/.prettierignore +0 -6
- package/template/apps/desktop/eslint.config.ts +0 -11
- package/template/apps/desktop/prettier.config.ts +0 -3
- package/template/apps/mobile/eslint.config.js +0 -10
- package/template/apps/platform/eslint.config.ts +0 -11
- package/template/apps/platform/prettier.config.ts +0 -3
- package/template/packages/auth/eslint.config.ts +0 -3
- package/template/packages/auth/prettier.config.ts +0 -3
- package/template/packages/config-eslint/index.ts +0 -24
- package/template/packages/config-eslint/package.json +0 -11
- package/template/packages/config-prettier/index.ts +0 -14
- package/template/packages/config-prettier/package.json +0 -7
- package/template/packages/db/eslint.config.ts +0 -3
- package/template/packages/db/prettier.config.ts +0 -3
- package/template/packages/orpc/eslint.config.ts +0 -3
- package/template/packages/orpc/prettier.config.ts +0 -3
- package/template/packages/ui/eslint.config.ts +0 -3
- package/template/packages/ui/prettier.config.ts +0 -3
- package/template/prettier.config.ts +0 -15
|
@@ -1,28 +1,24 @@
|
|
|
1
|
-
"use client"
|
|
1
|
+
"use client";
|
|
2
2
|
|
|
3
|
-
import * as React from "react"
|
|
3
|
+
import * as React from "react";
|
|
4
4
|
|
|
5
5
|
import {
|
|
6
6
|
DropdownMenu,
|
|
7
7
|
DropdownMenuContent,
|
|
8
8
|
DropdownMenuItem,
|
|
9
9
|
DropdownMenuTrigger,
|
|
10
|
-
} from "@workspace/ui/components/dropdown-menu"
|
|
11
|
-
import {
|
|
12
|
-
|
|
13
|
-
SidebarMenuButton,
|
|
14
|
-
SidebarMenuItem,
|
|
15
|
-
} from "@workspace/ui/components/sidebar"
|
|
16
|
-
import { CheckIcon, ChevronsUpDownIcon, GalleryVerticalEndIcon } from "lucide-react"
|
|
10
|
+
} from "@workspace/ui/components/dropdown-menu";
|
|
11
|
+
import { SidebarMenu, SidebarMenuButton, SidebarMenuItem } from "@workspace/ui/components/sidebar";
|
|
12
|
+
import { CheckIcon, ChevronsUpDownIcon, GalleryVerticalEndIcon } from "lucide-react";
|
|
17
13
|
|
|
18
14
|
export function VersionSwitcher({
|
|
19
15
|
versions,
|
|
20
16
|
defaultVersion,
|
|
21
17
|
}: {
|
|
22
|
-
versions: Array<string
|
|
23
|
-
defaultVersion: string
|
|
18
|
+
versions: Array<string>;
|
|
19
|
+
defaultVersion: string;
|
|
24
20
|
}) {
|
|
25
|
-
const [selectedVersion, setSelectedVersion] = React.useState(defaultVersion)
|
|
21
|
+
const [selectedVersion, setSelectedVersion] = React.useState(defaultVersion);
|
|
26
22
|
return (
|
|
27
23
|
<SidebarMenu>
|
|
28
24
|
<SidebarMenuItem>
|
|
@@ -46,19 +42,13 @@ export function VersionSwitcher({
|
|
|
46
42
|
</DropdownMenuTrigger>
|
|
47
43
|
<DropdownMenuContent align="start">
|
|
48
44
|
{versions.map((version) => (
|
|
49
|
-
<DropdownMenuItem
|
|
50
|
-
|
|
51
|
-
onSelect={() => setSelectedVersion(version)}
|
|
52
|
-
>
|
|
53
|
-
v{version}{" "}
|
|
54
|
-
{version === selectedVersion && (
|
|
55
|
-
<CheckIcon className="ml-auto" />
|
|
56
|
-
)}
|
|
45
|
+
<DropdownMenuItem key={version} onSelect={() => setSelectedVersion(version)}>
|
|
46
|
+
v{version} {version === selectedVersion && <CheckIcon className="ml-auto" />}
|
|
57
47
|
</DropdownMenuItem>
|
|
58
48
|
))}
|
|
59
49
|
</DropdownMenuContent>
|
|
60
50
|
</DropdownMenu>
|
|
61
51
|
</SidebarMenuItem>
|
|
62
52
|
</SidebarMenu>
|
|
63
|
-
)
|
|
53
|
+
);
|
|
64
54
|
}
|
|
@@ -1,15 +1,13 @@
|
|
|
1
|
-
import { createServerFn } from "@tanstack/react-start"
|
|
2
|
-
import { getRequest } from "@tanstack/react-start/server"
|
|
3
|
-
import { auth } from "@workspace/auth/lib/auth"
|
|
1
|
+
import { createServerFn } from "@tanstack/react-start";
|
|
2
|
+
import { getRequest } from "@tanstack/react-start/server";
|
|
3
|
+
import { auth } from "@workspace/auth/lib/auth";
|
|
4
4
|
|
|
5
|
-
export const getSessionFn = createServerFn({ method: "GET" }).handler(
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
}
|
|
15
|
-
)
|
|
5
|
+
export const getSessionFn = createServerFn({ method: "GET" }).handler(async () => {
|
|
6
|
+
const request = getRequest();
|
|
7
|
+
|
|
8
|
+
const session = await auth.api.getSession({
|
|
9
|
+
headers: request.headers,
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
return session;
|
|
13
|
+
});
|
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
import { createORPCClient } from
|
|
2
|
-
import { RPCLink } from
|
|
3
|
-
import { createIsomorphicFn } from
|
|
4
|
-
import { getRequestHeaders } from
|
|
5
|
-
import { createRouterClient } from
|
|
6
|
-
import { router } from
|
|
7
|
-
import { auth } from
|
|
8
|
-
import type { RouterClient } from
|
|
1
|
+
import { createORPCClient } from "@orpc/client";
|
|
2
|
+
import { RPCLink } from "@orpc/client/fetch";
|
|
3
|
+
import { createIsomorphicFn } from "@tanstack/react-start";
|
|
4
|
+
import { getRequestHeaders } from "@tanstack/react-start/server";
|
|
5
|
+
import { createRouterClient } from "@orpc/server";
|
|
6
|
+
import { router } from "@workspace/orpc/router";
|
|
7
|
+
import { auth } from "@workspace/auth/lib/auth";
|
|
8
|
+
import type { RouterClient } from "@orpc/server";
|
|
9
9
|
|
|
10
10
|
const getORPCClient = createIsomorphicFn()
|
|
11
|
-
.server(() =>
|
|
11
|
+
.server(() =>
|
|
12
12
|
createRouterClient(router, {
|
|
13
13
|
context: async () => {
|
|
14
|
-
const headers = getRequestHeaders()
|
|
14
|
+
const headers = getRequestHeaders();
|
|
15
15
|
const session = await auth.api.getSession({
|
|
16
16
|
headers,
|
|
17
|
-
})
|
|
17
|
+
});
|
|
18
18
|
return {
|
|
19
19
|
session,
|
|
20
|
-
}
|
|
20
|
+
};
|
|
21
21
|
},
|
|
22
|
-
})
|
|
22
|
+
}),
|
|
23
23
|
)
|
|
24
24
|
.client((): RouterClient<typeof router> => {
|
|
25
25
|
const link = new RPCLink({
|
|
26
26
|
url: `${window.location.origin}/api/rpc`,
|
|
27
|
-
})
|
|
27
|
+
});
|
|
28
28
|
|
|
29
|
-
return createORPCClient(link)
|
|
30
|
-
})
|
|
29
|
+
return createORPCClient(link);
|
|
30
|
+
});
|
|
31
31
|
|
|
32
|
-
export const orpc = getORPCClient()
|
|
32
|
+
export const orpc = getORPCClient();
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createRouter as createTanStackRouter } from "@tanstack/react-router"
|
|
2
|
-
import { routeTree } from "./routeTree.gen"
|
|
1
|
+
import { createRouter as createTanStackRouter } from "@tanstack/react-router";
|
|
2
|
+
import { routeTree } from "./routeTree.gen";
|
|
3
3
|
|
|
4
4
|
export function getRouter() {
|
|
5
5
|
const router = createTanStackRouter({
|
|
@@ -8,13 +8,13 @@ export function getRouter() {
|
|
|
8
8
|
scrollRestoration: true,
|
|
9
9
|
defaultPreload: "intent",
|
|
10
10
|
defaultPreloadStaleTime: 0,
|
|
11
|
-
})
|
|
11
|
+
});
|
|
12
12
|
|
|
13
|
-
return router
|
|
13
|
+
return router;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
16
|
declare module "@tanstack/react-router" {
|
|
17
17
|
interface Register {
|
|
18
|
-
router: ReturnType<typeof getRouter
|
|
18
|
+
router: ReturnType<typeof getRouter>;
|
|
19
19
|
}
|
|
20
20
|
}
|
|
@@ -1,12 +1,11 @@
|
|
|
1
|
-
import { HeadContent, Scripts, createRootRoute } from "@tanstack/react-router"
|
|
2
|
-
import { QueryClient, QueryClientProvider } from "@tanstack/react-query"
|
|
3
|
-
import { Toaster } from "@workspace/ui/components/sonner"
|
|
4
|
-
import { ThemeProvider } from "@workspace/ui/components/theme-provider"
|
|
1
|
+
import { HeadContent, Scripts, createRootRoute } from "@tanstack/react-router";
|
|
2
|
+
import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
|
|
3
|
+
import { Toaster } from "@workspace/ui/components/sonner";
|
|
4
|
+
import { ThemeProvider } from "@workspace/ui/components/theme-provider";
|
|
5
5
|
|
|
6
|
-
import appCss from "@workspace/ui/globals.css?url"
|
|
6
|
+
import appCss from "@workspace/ui/globals.css?url";
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
const queryClient = new QueryClient()
|
|
8
|
+
const queryClient = new QueryClient();
|
|
10
9
|
|
|
11
10
|
export const Route = createRootRoute({
|
|
12
11
|
head: () => ({
|
|
@@ -30,7 +29,7 @@ export const Route = createRootRoute({
|
|
|
30
29
|
],
|
|
31
30
|
}),
|
|
32
31
|
shellComponent: RootDocument,
|
|
33
|
-
})
|
|
32
|
+
});
|
|
34
33
|
|
|
35
34
|
function RootDocument({ children }: { children: React.ReactNode }) {
|
|
36
35
|
return (
|
|
@@ -39,15 +38,14 @@ function RootDocument({ children }: { children: React.ReactNode }) {
|
|
|
39
38
|
<HeadContent />
|
|
40
39
|
</head>
|
|
41
40
|
<body>
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
</QueryClientProvider>
|
|
41
|
+
<ThemeProvider defaultTheme="system" storageKey="theme">
|
|
42
|
+
<QueryClientProvider client={queryClient}>
|
|
43
|
+
{children}
|
|
44
|
+
<Toaster />
|
|
45
|
+
</QueryClientProvider>
|
|
48
46
|
</ThemeProvider>
|
|
49
47
|
<Scripts />
|
|
50
48
|
</body>
|
|
51
49
|
</html>
|
|
52
|
-
)
|
|
50
|
+
);
|
|
53
51
|
}
|
|
@@ -1,23 +1,30 @@
|
|
|
1
|
-
import * as React from "react"
|
|
2
|
-
import { createFileRoute, redirect } from "@tanstack/react-router"
|
|
3
|
-
import { useForm } from "@tanstack/react-form"
|
|
4
|
-
import { toast } from "sonner"
|
|
5
|
-
import { Loader2, User } from "lucide-react"
|
|
6
|
-
import { type } from "arktype"
|
|
1
|
+
import * as React from "react";
|
|
2
|
+
import { createFileRoute, redirect } from "@tanstack/react-router";
|
|
3
|
+
import { useForm } from "@tanstack/react-form";
|
|
4
|
+
import { toast } from "sonner";
|
|
5
|
+
import { Loader2, User } from "lucide-react";
|
|
6
|
+
import { type } from "arktype";
|
|
7
7
|
|
|
8
|
-
import { Button } from "@workspace/ui/components/button"
|
|
9
|
-
import { Input } from "@workspace/ui/components/input"
|
|
10
|
-
import {
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
8
|
+
import { Button } from "@workspace/ui/components/button";
|
|
9
|
+
import { Input } from "@workspace/ui/components/input";
|
|
10
|
+
import {
|
|
11
|
+
Card,
|
|
12
|
+
CardContent,
|
|
13
|
+
CardDescription,
|
|
14
|
+
CardFooter,
|
|
15
|
+
CardHeader,
|
|
16
|
+
CardTitle,
|
|
17
|
+
} from "@workspace/ui/components/card";
|
|
18
|
+
import { Field, FieldError, FieldLabel } from "@workspace/ui/components/field";
|
|
19
|
+
import { Avatar, AvatarFallback, AvatarImage } from "@workspace/ui/components/avatar";
|
|
20
|
+
import { Separator } from "@workspace/ui/components/separator";
|
|
14
21
|
|
|
15
|
-
import { authClient } from "@/lib/auth-client"
|
|
16
|
-
import { getSessionFn } from "@/lib/auth-utils"
|
|
22
|
+
import { authClient } from "@/lib/auth-client";
|
|
23
|
+
import { getSessionFn } from "@/lib/auth-utils";
|
|
17
24
|
|
|
18
25
|
const profileSchema = type({
|
|
19
26
|
name: "string>0",
|
|
20
|
-
})
|
|
27
|
+
});
|
|
21
28
|
|
|
22
29
|
const passwordSchema = type({
|
|
23
30
|
currentPassword: "string>0",
|
|
@@ -28,32 +35,32 @@ const passwordSchema = type({
|
|
|
28
35
|
ctx.error({
|
|
29
36
|
message: "Passwords do not match",
|
|
30
37
|
path: ["confirmPassword"],
|
|
31
|
-
})
|
|
32
|
-
return false
|
|
38
|
+
});
|
|
39
|
+
return false;
|
|
33
40
|
}
|
|
34
|
-
return true
|
|
35
|
-
})
|
|
41
|
+
return true;
|
|
42
|
+
});
|
|
36
43
|
|
|
37
44
|
export const Route = createFileRoute("/_auth/account")({
|
|
38
45
|
beforeLoad: async () => {
|
|
39
|
-
const session = await getSessionFn()
|
|
46
|
+
const session = await getSessionFn();
|
|
40
47
|
if (!session) {
|
|
41
48
|
throw redirect({
|
|
42
49
|
to: "/login",
|
|
43
50
|
search: {
|
|
44
51
|
redirect: "/account",
|
|
45
52
|
},
|
|
46
|
-
})
|
|
53
|
+
});
|
|
47
54
|
}
|
|
48
|
-
return { session }
|
|
55
|
+
return { session };
|
|
49
56
|
},
|
|
50
57
|
component: AccountPage,
|
|
51
|
-
})
|
|
58
|
+
});
|
|
52
59
|
|
|
53
60
|
function AccountPage() {
|
|
54
|
-
const { session } = Route.useRouteContext()
|
|
55
|
-
const [loading, setLoading] = React.useState(false)
|
|
56
|
-
const user = session.user
|
|
61
|
+
const { session } = Route.useRouteContext();
|
|
62
|
+
const [loading, setLoading] = React.useState(false);
|
|
63
|
+
const user = session.user;
|
|
57
64
|
|
|
58
65
|
const profileForm = useForm({
|
|
59
66
|
defaultValues: {
|
|
@@ -63,19 +70,19 @@ function AccountPage() {
|
|
|
63
70
|
onChange: profileSchema,
|
|
64
71
|
},
|
|
65
72
|
onSubmit: async ({ value }) => {
|
|
66
|
-
setLoading(true)
|
|
73
|
+
setLoading(true);
|
|
67
74
|
const { error } = await authClient.updateUser({
|
|
68
75
|
name: value.name,
|
|
69
|
-
})
|
|
76
|
+
});
|
|
70
77
|
|
|
71
78
|
if (error) {
|
|
72
|
-
toast.error(error.message || "Failed to update profile")
|
|
79
|
+
toast.error(error.message || "Failed to update profile");
|
|
73
80
|
} else {
|
|
74
|
-
toast.success("Profile updated successfully")
|
|
81
|
+
toast.success("Profile updated successfully");
|
|
75
82
|
}
|
|
76
|
-
setLoading(false)
|
|
83
|
+
setLoading(false);
|
|
77
84
|
},
|
|
78
|
-
})
|
|
85
|
+
});
|
|
79
86
|
|
|
80
87
|
const passwordForm = useForm({
|
|
81
88
|
defaultValues: {
|
|
@@ -87,21 +94,21 @@ function AccountPage() {
|
|
|
87
94
|
onChange: passwordSchema,
|
|
88
95
|
},
|
|
89
96
|
onSubmit: async ({ value }) => {
|
|
90
|
-
setLoading(true)
|
|
97
|
+
setLoading(true);
|
|
91
98
|
const { error } = await authClient.changePassword({
|
|
92
99
|
currentPassword: value.currentPassword,
|
|
93
100
|
newPassword: value.newPassword,
|
|
94
|
-
})
|
|
101
|
+
});
|
|
95
102
|
|
|
96
103
|
if (error) {
|
|
97
|
-
toast.error(error.message || "Failed to change password")
|
|
104
|
+
toast.error(error.message || "Failed to change password");
|
|
98
105
|
} else {
|
|
99
|
-
toast.success("Password changed successfully")
|
|
100
|
-
passwordForm.reset()
|
|
106
|
+
toast.success("Password changed successfully");
|
|
107
|
+
passwordForm.reset();
|
|
101
108
|
}
|
|
102
|
-
setLoading(false)
|
|
109
|
+
setLoading(false);
|
|
103
110
|
},
|
|
104
|
-
})
|
|
111
|
+
});
|
|
105
112
|
|
|
106
113
|
return (
|
|
107
114
|
<div className="container max-w-4xl py-10">
|
|
@@ -136,9 +143,9 @@ function AccountPage() {
|
|
|
136
143
|
|
|
137
144
|
<form
|
|
138
145
|
onSubmit={(e) => {
|
|
139
|
-
e.preventDefault()
|
|
140
|
-
e.stopPropagation()
|
|
141
|
-
profileForm.handleSubmit()
|
|
146
|
+
e.preventDefault();
|
|
147
|
+
e.stopPropagation();
|
|
148
|
+
profileForm.handleSubmit();
|
|
142
149
|
}}
|
|
143
150
|
className="space-y-4"
|
|
144
151
|
>
|
|
@@ -174,9 +181,9 @@ function AccountPage() {
|
|
|
174
181
|
<CardContent>
|
|
175
182
|
<form
|
|
176
183
|
onSubmit={(e) => {
|
|
177
|
-
e.preventDefault()
|
|
178
|
-
e.stopPropagation()
|
|
179
|
-
passwordForm.handleSubmit()
|
|
184
|
+
e.preventDefault();
|
|
185
|
+
e.stopPropagation();
|
|
186
|
+
passwordForm.handleSubmit();
|
|
180
187
|
}}
|
|
181
188
|
className="space-y-4"
|
|
182
189
|
>
|
|
@@ -248,12 +255,16 @@ function AccountPage() {
|
|
|
248
255
|
<Button
|
|
249
256
|
variant="destructive"
|
|
250
257
|
onClick={async () => {
|
|
251
|
-
if (
|
|
252
|
-
|
|
258
|
+
if (
|
|
259
|
+
confirm(
|
|
260
|
+
"Are you sure you want to delete your account? This action cannot be undone.",
|
|
261
|
+
)
|
|
262
|
+
) {
|
|
263
|
+
const { error } = await authClient.deleteUser();
|
|
253
264
|
if (error) {
|
|
254
|
-
toast.error(error.message || "Failed to delete account")
|
|
265
|
+
toast.error(error.message || "Failed to delete account");
|
|
255
266
|
} else {
|
|
256
|
-
window.location.href = "/"
|
|
267
|
+
window.location.href = "/";
|
|
257
268
|
}
|
|
258
269
|
}
|
|
259
270
|
}}
|
|
@@ -265,5 +276,5 @@ function AccountPage() {
|
|
|
265
276
|
</div>
|
|
266
277
|
</div>
|
|
267
278
|
</div>
|
|
268
|
-
)
|
|
279
|
+
);
|
|
269
280
|
}
|
|
@@ -1,32 +1,32 @@
|
|
|
1
|
-
import { createFileRoute, redirect } from "@tanstack/react-router"
|
|
2
|
-
import { getSessionFn } from "@/lib/auth-utils"
|
|
3
|
-
import { authClient } from "@/lib/auth-client"
|
|
4
|
-
import { orpc } from "@/lib/orpc"
|
|
1
|
+
import { createFileRoute, redirect } from "@tanstack/react-router";
|
|
2
|
+
import { getSessionFn } from "@/lib/auth-utils";
|
|
3
|
+
import { authClient } from "@/lib/auth-client";
|
|
4
|
+
import { orpc } from "@/lib/orpc";
|
|
5
5
|
|
|
6
6
|
export const Route = createFileRoute("/_auth/dashboard")({
|
|
7
7
|
beforeLoad: async () => {
|
|
8
|
-
const session = await getSessionFn()
|
|
8
|
+
const session = await getSessionFn();
|
|
9
9
|
if (!session) {
|
|
10
10
|
throw redirect({
|
|
11
11
|
to: "/",
|
|
12
|
-
})
|
|
12
|
+
});
|
|
13
13
|
}
|
|
14
|
-
return { session }
|
|
14
|
+
return { session };
|
|
15
15
|
},
|
|
16
16
|
loader: async () => {
|
|
17
17
|
try {
|
|
18
|
-
const data = await orpc.getSecretData()
|
|
19
|
-
return { secretData: data.secret }
|
|
18
|
+
const data = await orpc.getSecretData();
|
|
19
|
+
return { secretData: data.secret };
|
|
20
20
|
} catch (err: any) {
|
|
21
|
-
return { secretData: "Error: " + (err.message || "Unknown error") }
|
|
21
|
+
return { secretData: "Error: " + (err.message || "Unknown error") };
|
|
22
22
|
}
|
|
23
23
|
},
|
|
24
24
|
component: Dashboard,
|
|
25
|
-
})
|
|
25
|
+
});
|
|
26
26
|
|
|
27
27
|
function Dashboard() {
|
|
28
|
-
const { session } = Route.useRouteContext()
|
|
29
|
-
const { secretData } = Route.useLoaderData()
|
|
28
|
+
const { session } = Route.useRouteContext();
|
|
29
|
+
const { secretData } = Route.useLoaderData();
|
|
30
30
|
|
|
31
31
|
return (
|
|
32
32
|
<div className="flex min-h-svh p-6">
|
|
@@ -35,7 +35,7 @@ function Dashboard() {
|
|
|
35
35
|
<h1 className="text-2xl font-bold">Dashboard</h1>
|
|
36
36
|
<p>Welcome, {session.user.name}!</p>
|
|
37
37
|
<p>This is a protected page. Only authenticated users can see this.</p>
|
|
38
|
-
|
|
38
|
+
|
|
39
39
|
<div className="mt-6 rounded-lg border bg-gray-50 p-4">
|
|
40
40
|
<h2 className="font-semibold mb-2">Secure oRPC Data:</h2>
|
|
41
41
|
<p className="font-mono text-xs">{secretData}</p>
|
|
@@ -44,8 +44,8 @@ function Dashboard() {
|
|
|
44
44
|
<div className="mt-4 flex gap-2">
|
|
45
45
|
<button
|
|
46
46
|
onClick={async () => {
|
|
47
|
-
await authClient.signOut()
|
|
48
|
-
window.location.href = "/"
|
|
47
|
+
await authClient.signOut();
|
|
48
|
+
window.location.href = "/";
|
|
49
49
|
}}
|
|
50
50
|
className="rounded bg-red-500 px-4 py-2 text-white hover:bg-red-600"
|
|
51
51
|
>
|
|
@@ -55,5 +55,5 @@ function Dashboard() {
|
|
|
55
55
|
</div>
|
|
56
56
|
</div>
|
|
57
57
|
</div>
|
|
58
|
-
)
|
|
58
|
+
);
|
|
59
59
|
}
|
|
@@ -1,37 +1,37 @@
|
|
|
1
|
-
import { createFileRoute, redirect } from "@tanstack/react-router"
|
|
2
|
-
import { useQuery } from "@tanstack/react-query"
|
|
3
|
-
import { getSessionFn } from "@/lib/auth-utils"
|
|
4
|
-
import { orpc } from "@/lib/orpc"
|
|
1
|
+
import { createFileRoute, redirect } from "@tanstack/react-router";
|
|
2
|
+
import { useQuery } from "@tanstack/react-query";
|
|
3
|
+
import { getSessionFn } from "@/lib/auth-utils";
|
|
4
|
+
import { orpc } from "@/lib/orpc";
|
|
5
5
|
|
|
6
6
|
export const Route = createFileRoute("/_auth/examples/client-orpc-auth")({
|
|
7
7
|
beforeLoad: async () => {
|
|
8
|
-
const session = await getSessionFn()
|
|
8
|
+
const session = await getSessionFn();
|
|
9
9
|
if (!session) {
|
|
10
10
|
throw redirect({
|
|
11
11
|
to: "/login",
|
|
12
12
|
search: {
|
|
13
13
|
redirect: "/examples/client-orpc-auth",
|
|
14
14
|
},
|
|
15
|
-
})
|
|
15
|
+
});
|
|
16
16
|
}
|
|
17
|
-
return { session }
|
|
17
|
+
return { session };
|
|
18
18
|
},
|
|
19
19
|
component: ClientORPCAuth,
|
|
20
|
-
})
|
|
20
|
+
});
|
|
21
21
|
|
|
22
22
|
function ClientORPCAuth() {
|
|
23
|
-
const { session } = Route.useRouteContext()
|
|
24
|
-
|
|
23
|
+
const { session } = Route.useRouteContext();
|
|
24
|
+
|
|
25
25
|
const { data, isLoading } = useQuery({
|
|
26
26
|
queryKey: ["secret-data"],
|
|
27
27
|
queryFn: () => orpc.getSecretData(),
|
|
28
|
-
})
|
|
28
|
+
});
|
|
29
29
|
|
|
30
30
|
return (
|
|
31
31
|
<div className="flex flex-col gap-4">
|
|
32
32
|
<h1 className="text-2xl font-bold">Client + oRPC (Authenticated)</h1>
|
|
33
33
|
<p>This page is protected and fetches secret data on the client using TanStack Query.</p>
|
|
34
|
-
|
|
34
|
+
|
|
35
35
|
<div className="rounded-lg border p-4">
|
|
36
36
|
<h2 className="font-semibold">User Session:</h2>
|
|
37
37
|
<pre className="text-xs bg-muted p-2 rounded">{JSON.stringify(session, null, 2)}</pre>
|
|
@@ -46,5 +46,5 @@ function ClientORPCAuth() {
|
|
|
46
46
|
)}
|
|
47
47
|
</div>
|
|
48
48
|
</div>
|
|
49
|
-
)
|
|
49
|
+
);
|
|
50
50
|
}
|
|
@@ -1,43 +1,43 @@
|
|
|
1
|
-
import { createFileRoute, redirect } from "@tanstack/react-router"
|
|
2
|
-
import { createServerFn } from "@tanstack/react-start"
|
|
3
|
-
import { getSessionFn } from "@/lib/auth-utils"
|
|
4
|
-
import { orpc } from "@/lib/orpc"
|
|
1
|
+
import { createFileRoute, redirect } from "@tanstack/react-router";
|
|
2
|
+
import { createServerFn } from "@tanstack/react-start";
|
|
3
|
+
import { getSessionFn } from "@/lib/auth-utils";
|
|
4
|
+
import { orpc } from "@/lib/orpc";
|
|
5
5
|
|
|
6
6
|
const getSecretData = createServerFn({ method: "GET" }).handler(async () => {
|
|
7
7
|
try {
|
|
8
|
-
const secretData = await orpc.getSecretData()
|
|
9
|
-
return { secretData }
|
|
8
|
+
const secretData = await orpc.getSecretData();
|
|
9
|
+
return { secretData };
|
|
10
10
|
} catch (err) {
|
|
11
|
-
return { secretData: null, error: "Failed to fetch secret data" }
|
|
11
|
+
return { secretData: null, error: "Failed to fetch secret data" };
|
|
12
12
|
}
|
|
13
|
-
})
|
|
13
|
+
});
|
|
14
14
|
|
|
15
15
|
export const Route = createFileRoute("/_auth/examples/ssr-orpc-auth")({
|
|
16
16
|
beforeLoad: async () => {
|
|
17
|
-
const session = await getSessionFn()
|
|
17
|
+
const session = await getSessionFn();
|
|
18
18
|
if (!session) {
|
|
19
19
|
throw redirect({
|
|
20
20
|
to: "/login",
|
|
21
21
|
search: {
|
|
22
22
|
redirect: "/examples/ssr-orpc-auth",
|
|
23
23
|
},
|
|
24
|
-
})
|
|
24
|
+
});
|
|
25
25
|
}
|
|
26
|
-
return { session }
|
|
26
|
+
return { session };
|
|
27
27
|
},
|
|
28
28
|
loader: () => getSecretData(),
|
|
29
29
|
component: SSRORPCAuth,
|
|
30
|
-
})
|
|
30
|
+
});
|
|
31
31
|
|
|
32
32
|
function SSRORPCAuth() {
|
|
33
|
-
const { session } = Route.useRouteContext()
|
|
34
|
-
const { secretData, error } = Route.useLoaderData()
|
|
33
|
+
const { session } = Route.useRouteContext();
|
|
34
|
+
const { secretData, error } = Route.useLoaderData();
|
|
35
35
|
|
|
36
36
|
return (
|
|
37
37
|
<div className="flex flex-col gap-4">
|
|
38
38
|
<h1 className="text-2xl font-bold">SSR + oRPC (Authenticated)</h1>
|
|
39
39
|
<p>This page is protected and fetches secret data on the server.</p>
|
|
40
|
-
|
|
40
|
+
|
|
41
41
|
<div className="rounded-lg border p-4">
|
|
42
42
|
<h2 className="font-semibold">User Session:</h2>
|
|
43
43
|
<pre className="text-xs bg-muted p-2 rounded">{JSON.stringify(session, null, 2)}</pre>
|
|
@@ -52,5 +52,5 @@ function SSRORPCAuth() {
|
|
|
52
52
|
)}
|
|
53
53
|
</div>
|
|
54
54
|
</div>
|
|
55
|
-
)
|
|
55
|
+
);
|
|
56
56
|
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { Outlet, createFileRoute } from "@tanstack/react-router"
|
|
2
|
-
import { SidebarProvider, SidebarTrigger } from "@workspace/ui/components/sidebar"
|
|
3
|
-
import { AuthSidebar } from "@/components/app-sidebar"
|
|
1
|
+
import { Outlet, createFileRoute } from "@tanstack/react-router";
|
|
2
|
+
import { SidebarProvider, SidebarTrigger } from "@workspace/ui/components/sidebar";
|
|
3
|
+
import { AuthSidebar } from "@/components/app-sidebar";
|
|
4
4
|
|
|
5
5
|
export const Route = createFileRoute("/_auth")({
|
|
6
6
|
component: AuthLayout,
|
|
7
|
-
})
|
|
7
|
+
});
|
|
8
8
|
|
|
9
9
|
function AuthLayout() {
|
|
10
10
|
return (
|
|
@@ -19,5 +19,5 @@ function AuthLayout() {
|
|
|
19
19
|
</div>
|
|
20
20
|
</main>
|
|
21
21
|
</SidebarProvider>
|
|
22
|
-
)
|
|
22
|
+
);
|
|
23
23
|
}
|