create-croissant 0.1.23 → 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.23",
6
+ "version": "0.1.25",
7
7
  "description": "Scaffold a new project using the Croissant Stack",
8
8
  "repository": {
9
9
  "type": "git",
@@ -114,7 +114,7 @@ export function AppSidebar({ items = authNavItems, ...props }: AppSidebarProps)
114
114
  <Sidebar {...props}>
115
115
  <SidebarHeader>
116
116
  <div className="flex items-center gap-2 px-4 py-2">
117
- <span className="font-bold">LLM Trust</span>
117
+ <span className="font-bold">Croissant Stack</span>
118
118
  </div>
119
119
  </SidebarHeader>
120
120
  <SidebarContent>
@@ -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>
@@ -17,7 +17,7 @@ export const Route = createRootRoute({
17
17
  content: "width=device-width, initial-scale=1",
18
18
  },
19
19
  {
20
- title: "TanStack Start Starter",
20
+ title: "Croissant Stack Starter",
21
21
  },
22
22
  ],
23
23
  links: [
@@ -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
 
@@ -30,6 +30,17 @@ const planetSchema = z.object({
30
30
  })
31
31
 
32
32
  export const Route = createFileRoute("/_public/examples/client-orpc")({
33
+ head: () => ({
34
+ meta: [
35
+ {
36
+ title: "Client + oRPC Example | Croissant Stack",
37
+ },
38
+ {
39
+ name: "description",
40
+ content: "Explore client-side data fetching and mutations with oRPC in Croissant Stack.",
41
+ },
42
+ ],
43
+ }),
33
44
  component: ClientORPC,
34
45
  })
35
46
 
@@ -1,18 +1,34 @@
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
- loader: 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: "This page is an example of ISR. In a production build with proper configuration, this data would be cached and updated in the background.",
14
- }
15
- },
19
+ head: () => ({
20
+ meta: [
21
+ {
22
+ title: "Incremental Static Regeneration (ISR) Example | Croissant Stack",
23
+ },
24
+ {
25
+ name: "description",
26
+ content:
27
+ "Experience high-performance page loads with ISR in Croissant Stack.",
28
+ },
29
+ ],
30
+ }),
31
+ loader: () => getISRData(),
16
32
  headers: () => ({
17
33
  // Cache at CDN for 10 seconds, allow stale content for up to 1 minute
18
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,11 +28,25 @@ 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
- loader: async () => {
32
- const planets = await orpc.planets.getPlanets()
33
- return { planets }
34
- },
37
+ head: () => ({
38
+ meta: [
39
+ {
40
+ title: "SSR + oRPC Example | Croissant Stack",
41
+ },
42
+ {
43
+ name: "description",
44
+ content:
45
+ "Learn how to use Server-Side Rendering (SSR) with oRPC in Croissant Stack.",
46
+ },
47
+ ],
48
+ }),
49
+ loader: () => getPlanets(),
35
50
  component: SSRORPC,
36
51
  })
37
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,19 +8,46 @@ 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
- loader: 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
- },
23
+ head: () => ({
24
+ meta: [
25
+ {
26
+ title: "Croissant Stack - The Ultimate TanStack Starter",
27
+ },
28
+ {
29
+ name: "description",
30
+ content:
31
+ "Build full-stack applications faster with Croissant Stack. Featuring TanStack Start, oRPC, and Better Auth.",
32
+ },
33
+ {
34
+ property: "og:title",
35
+ content: "Croissant Stack - The Ultimate TanStack Starter",
36
+ },
37
+ {
38
+ property: "og:description",
39
+ content: "Build full-stack applications faster with Croissant Stack.",
40
+ },
41
+ {
42
+ property: "og:image",
43
+ content: "/og-image.png",
44
+ },
45
+ ],
46
+ }),
47
+ loader: () => getHomeData(),
21
48
  headers: () => ({
22
- "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",
23
51
  }),
24
52
  component: App,
25
53
  })
@@ -2,6 +2,21 @@ import { createFileRoute } from "@tanstack/react-router"
2
2
  import { LoginForm } from "@/components/login-form"
3
3
 
4
4
  export const Route = createFileRoute("/_public/login")({
5
+ head: () => ({
6
+ meta: [
7
+ {
8
+ title: "Sign In | Croissant Stack",
9
+ },
10
+ {
11
+ name: "description",
12
+ content: "Sign in to your Croissant Stack account.",
13
+ },
14
+ {
15
+ name: "robots",
16
+ content: "noindex, follow",
17
+ },
18
+ ],
19
+ }),
5
20
  headers: () => ({
6
21
  "Cache-Control": "public, max-age=3600, s-maxage=3600, stale-while-revalidate=86400",
7
22
  }),
@@ -2,6 +2,17 @@ import { createFileRoute } from "@tanstack/react-router"
2
2
  import { SignupForm } from "@/components/signup-form"
3
3
 
4
4
  export const Route = createFileRoute("/_public/signup")({
5
+ head: () => ({
6
+ meta: [
7
+ {
8
+ title: "Create an Account | Croissant Stack",
9
+ },
10
+ {
11
+ name: "description",
12
+ content: "Join Croissant Stack today. Create an account to start building with the best stack.",
13
+ },
14
+ ],
15
+ }),
5
16
  headers: () => ({
6
17
  "Cache-Control": "public, max-age=3600, s-maxage=3600, stale-while-revalidate=86400",
7
18
  }),
@@ -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
  ),