create-croissant 0.1.24 → 0.1.25

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 CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.1.24",
6
+ "version": "0.1.25",
7
7
  "description": "Scaffold a new project using the Croissant Stack",
8
8
  "repository": {
9
9
  "type": "git",
@@ -163,25 +163,25 @@ export function AppSidebar({ items = authNavItems, ...props }: AppSidebarProps)
163
163
  <span className="truncate text-xs">{user.email}</span>
164
164
  </div>
165
165
  <div className="flex items-center gap-1 ml-auto">
166
- <Link
167
- to="/account"
168
- className="p-1 rounded hover:bg-sidebar-accent-foreground/10"
166
+ <SidebarMenuButton
167
+ render={<Link to="/account" />}
168
+ className="p-1 h-auto w-auto rounded hover:bg-sidebar-accent-foreground/10"
169
169
  title="Account Settings"
170
170
  >
171
171
  <Settings className="h-4 w-4" />
172
- </Link>
173
- <button
172
+ </SidebarMenuButton>
173
+ <SidebarMenuButton
174
174
  onClick={async (e) => {
175
175
  e.preventDefault()
176
176
  e.stopPropagation()
177
177
  await authClient.signOut()
178
178
  window.location.reload()
179
179
  }}
180
- className="p-1 rounded hover:bg-sidebar-accent-foreground/10"
180
+ className="p-1 h-auto w-auto rounded hover:bg-sidebar-accent-foreground/10"
181
181
  title="Sign Out"
182
182
  >
183
183
  <LogOut className="h-4 w-4" />
184
- </button>
184
+ </SidebarMenuButton>
185
185
  </div>
186
186
  </div>
187
187
  </SidebarMenuButton>
@@ -1,7 +1,17 @@
1
1
  import { createFileRoute, redirect } from "@tanstack/react-router"
2
+ import { createServerFn } from "@tanstack/react-start"
2
3
  import { getSessionFn } from "@/lib/auth-utils"
3
4
  import { orpc } from "@/lib/orpc"
4
5
 
6
+ const getSecretData = createServerFn({ method: "GET" }).handler(async () => {
7
+ try {
8
+ const secretData = await orpc.getSecretData()
9
+ return { secretData }
10
+ } catch (err) {
11
+ return { secretData: null, error: "Failed to fetch secret data" }
12
+ }
13
+ })
14
+
5
15
  export const Route = createFileRoute("/_auth/examples/ssr-orpc-auth")({
6
16
  beforeLoad: async () => {
7
17
  const session = await getSessionFn()
@@ -15,14 +25,7 @@ export const Route = createFileRoute("/_auth/examples/ssr-orpc-auth")({
15
25
  }
16
26
  return { session }
17
27
  },
18
- loader: async () => {
19
- try {
20
- const secretData = await orpc.getSecretData()
21
- return { secretData }
22
- } catch (err) {
23
- return { secretData: null, error: "Failed to fetch secret data" }
24
- }
25
- },
28
+ loader: () => getSecretData(),
26
29
  component: SSRORPCAuth,
27
30
  })
28
31
 
@@ -1,6 +1,20 @@
1
1
  import { createFileRoute } from "@tanstack/react-router"
2
+ import { createServerFn } from "@tanstack/react-start"
2
3
  import { orpc } from "@/lib/orpc"
3
4
 
5
+ const getISRData = createServerFn({ method: "GET" }).handler(async () => {
6
+ // In a real ISR scenario, this would be cached on the server
7
+ // For this example, we'll fetch planets via oRPC
8
+ const planets = await orpc.planets.getPlanets()
9
+
10
+ return {
11
+ generatedAt: new Date().toISOString(),
12
+ planets,
13
+ message:
14
+ "This page is an example of ISR. In a production build with proper configuration, this data would be cached and updated in the background.",
15
+ }
16
+ })
17
+
4
18
  export const Route = createFileRoute("/_public/examples/isr")({
5
19
  head: () => ({
6
20
  meta: [
@@ -9,21 +23,12 @@ export const Route = createFileRoute("/_public/examples/isr")({
9
23
  },
10
24
  {
11
25
  name: "description",
12
- content: "Experience high-performance page loads with ISR in Croissant Stack.",
26
+ content:
27
+ "Experience high-performance page loads with ISR in Croissant Stack.",
13
28
  },
14
29
  ],
15
30
  }),
16
- loader: async () => {
17
- // In a real ISR scenario, this would be cached on the server
18
- // For this example, we'll fetch planets via oRPC
19
- const planets = await orpc.planets.getPlanets()
20
-
21
- return {
22
- generatedAt: new Date().toISOString(),
23
- planets,
24
- message: "This page is an example of ISR. In a production build with proper configuration, this data would be cached and updated in the background.",
25
- }
26
- },
31
+ loader: () => getISRData(),
27
32
  headers: () => ({
28
33
  // Cache at CDN for 10 seconds, allow stale content for up to 1 minute
29
34
  "Cache-Control": "public, max-age=10, s-maxage=10, stale-while-revalidate=60",
@@ -1,5 +1,6 @@
1
1
  import * as React from "react"
2
2
  import { createFileRoute, useRouter } from "@tanstack/react-router"
3
+ import { createServerFn } from "@tanstack/react-start"
3
4
  import { Check, Pencil, Plus, Trash2 } from "lucide-react"
4
5
  import { toast } from "sonner"
5
6
  import { useForm } from "@tanstack/react-form"
@@ -27,6 +28,11 @@ const planetSchema = z.object({
27
28
  diameter: z.string().refine((val) => !isNaN(parseFloat(val)), "Must be a number"),
28
29
  })
29
30
 
31
+ const getPlanets = createServerFn({ method: "GET" }).handler(async () => {
32
+ const planets = await orpc.planets.getPlanets()
33
+ return { planets }
34
+ })
35
+
30
36
  export const Route = createFileRoute("/_public/examples/ssr-orpc")({
31
37
  head: () => ({
32
38
  meta: [
@@ -35,14 +41,12 @@ export const Route = createFileRoute("/_public/examples/ssr-orpc")({
35
41
  },
36
42
  {
37
43
  name: "description",
38
- content: "Learn how to use Server-Side Rendering (SSR) with oRPC in Croissant Stack.",
44
+ content:
45
+ "Learn how to use Server-Side Rendering (SSR) with oRPC in Croissant Stack.",
39
46
  },
40
47
  ],
41
48
  }),
42
- loader: async () => {
43
- const planets = await orpc.planets.getPlanets()
44
- return { planets }
45
- },
49
+ loader: () => getPlanets(),
46
50
  component: SSRORPC,
47
51
  })
48
52
 
@@ -1,4 +1,5 @@
1
1
  import { Link, createFileRoute } from "@tanstack/react-router"
2
+ import { createServerFn } from "@tanstack/react-start"
2
3
  import { Button } from "@workspace/ui/components/button"
3
4
  import type { router } from "@workspace/orpc/router"
4
5
  import type { InferRouterOutputs } from "@orpc/server"
@@ -7,6 +8,17 @@ import { orpc } from "@/lib/orpc"
7
8
  type Outputs = InferRouterOutputs<typeof router>
8
9
  type Planet = Outputs["planets"]["getPlanets"][number]
9
10
 
11
+ const getHomeData = createServerFn({ method: "GET" }).handler(async () => {
12
+ const [helloRes, planets] = await Promise.all([
13
+ orpc.hello({ name: "Croissant Stack" }),
14
+ orpc.planets.getPlanets(),
15
+ ])
16
+ return {
17
+ message: helloRes.message,
18
+ planets,
19
+ }
20
+ })
21
+
10
22
  export const Route = createFileRoute("/_public/")({
11
23
  head: () => ({
12
24
  meta: [
@@ -15,7 +27,8 @@ export const Route = createFileRoute("/_public/")({
15
27
  },
16
28
  {
17
29
  name: "description",
18
- content: "Build full-stack applications faster with Croissant Stack. Featuring TanStack Start, oRPC, and Better Auth.",
30
+ content:
31
+ "Build full-stack applications faster with Croissant Stack. Featuring TanStack Start, oRPC, and Better Auth.",
19
32
  },
20
33
  {
21
34
  property: "og:title",
@@ -31,18 +44,10 @@ export const Route = createFileRoute("/_public/")({
31
44
  },
32
45
  ],
33
46
  }),
34
- loader: async () => {
35
- const [helloRes, planets] = await Promise.all([
36
- orpc.hello({ name: "Croissant Stack" }),
37
- orpc.planets.getPlanets(),
38
- ])
39
- return {
40
- message: helloRes.message,
41
- planets,
42
- }
43
- },
47
+ loader: () => getHomeData(),
44
48
  headers: () => ({
45
- "Cache-Control": "public, max-age=10, s-maxage=10, stale-while-revalidate=60",
49
+ "Cache-Control":
50
+ "public, max-age=10, s-maxage=10, stale-while-revalidate=60",
46
51
  }),
47
52
  component: App,
48
53
  })
@@ -506,18 +506,28 @@ function SidebarMenuButton({
506
506
  size = "default",
507
507
  tooltip,
508
508
  className,
509
+ onClick,
509
510
  ...props
510
511
  }: useRender.ComponentProps<"button"> &
511
512
  React.ComponentProps<"button"> & {
512
513
  isActive?: boolean
513
514
  tooltip?: string | React.ComponentProps<typeof TooltipContent>
514
515
  } & VariantProps<typeof sidebarMenuButtonVariants>) {
515
- const { isMobile, state } = useSidebar()
516
+ const { isMobile, state, setOpenMobile } = useSidebar()
517
+
518
+ const handleClick = (event: React.MouseEvent<HTMLButtonElement>) => {
519
+ if (isMobile) {
520
+ setOpenMobile(false)
521
+ }
522
+ onClick?.(event)
523
+ }
524
+
516
525
  const comp = useRender({
517
526
  defaultTagName: "button",
518
527
  props: mergeProps<"button">(
519
528
  {
520
529
  className: cn(sidebarMenuButtonVariants({ variant, size }), className),
530
+ onClick: handleClick,
521
531
  },
522
532
  props
523
533
  ),