create-lx2-app 0.7.0

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.
Files changed (54) hide show
  1. package/README.md +151 -0
  2. package/dist/index.js +68 -0
  3. package/package.json +92 -0
  4. package/template/base/README.md +57 -0
  5. package/template/base/_gitignore +41 -0
  6. package/template/base/next-env.d.ts +5 -0
  7. package/template/base/next.config.mjs +12 -0
  8. package/template/base/package.json +20 -0
  9. package/template/base/postcss.config.mjs +5 -0
  10. package/template/base/public/favicon.ico +0 -0
  11. package/template/base/src/env.js +40 -0
  12. package/template/packages/config/eslint.config.mjs +16 -0
  13. package/template/packages/config/payload/with-postgres.ts +39 -0
  14. package/template/packages/config/payload/with-sqlite.ts +42 -0
  15. package/template/packages/config/prettier.config.mjs +23 -0
  16. package/template/packages/config/tsconfig/base.json +42 -0
  17. package/template/packages/config/tsconfig/with-payload.json +43 -0
  18. package/template/packages/prisma/schema/base.prisma +21 -0
  19. package/template/packages/prisma/schema/with-authjs.prisma +86 -0
  20. package/template/packages/prisma/schema/with-better-auth.prisma +85 -0
  21. package/template/packages/src/app/(payload)/admin/[[...segments]]/not-found.tsx +27 -0
  22. package/template/packages/src/app/(payload)/admin/[[...segments]]/page.tsx +27 -0
  23. package/template/packages/src/app/(payload)/admin/importMap.js +1 -0
  24. package/template/packages/src/app/(payload)/api/[...slug]/route.ts +20 -0
  25. package/template/packages/src/app/(payload)/api/graphql/route.ts +8 -0
  26. package/template/packages/src/app/(payload)/api/graphql-playground/route.ts +8 -0
  27. package/template/packages/src/app/(payload)/custom.scss +0 -0
  28. package/template/packages/src/app/(payload)/layout.tsx +35 -0
  29. package/template/packages/src/app/api/auth/[...betterauth]/route.ts +5 -0
  30. package/template/packages/src/app/api/auth/[...nextauth]/route.ts +3 -0
  31. package/template/packages/src/app/globals/base.css +27 -0
  32. package/template/packages/src/app/layout/base.tsx +35 -0
  33. package/template/packages/src/app/page/base.tsx +98 -0
  34. package/template/packages/src/app/page/with-authjs-prisma.tsx +221 -0
  35. package/template/packages/src/app/page/with-authjs.tsx +126 -0
  36. package/template/packages/src/app/page/with-better-auth-prisma.tsx +245 -0
  37. package/template/packages/src/app/page/with-better-auth.tsx +151 -0
  38. package/template/packages/src/app/page/with-payload.tsx +136 -0
  39. package/template/packages/src/app/page/with-prisma.tsx +177 -0
  40. package/template/packages/src/env/with-authjs-db.js +52 -0
  41. package/template/packages/src/env/with-authjs.js +51 -0
  42. package/template/packages/src/env/with-better-auth-db.js +51 -0
  43. package/template/packages/src/env/with-better-auth.js +48 -0
  44. package/template/packages/src/env/with-db.js +44 -0
  45. package/template/packages/src/env/with-payload.js +46 -0
  46. package/template/packages/src/lib/auth/better-auth-client.ts +9 -0
  47. package/template/packages/src/payload/collections/Media.ts +16 -0
  48. package/template/packages/src/payload/collections/Users.ts +13 -0
  49. package/template/packages/src/server/auth/authjs.ts +5 -0
  50. package/template/packages/src/server/auth/config/authjs-with-prisma.ts +30 -0
  51. package/template/packages/src/server/auth/config/authjs.ts +27 -0
  52. package/template/packages/src/server/auth/config/better-auth-with-prisma.ts +21 -0
  53. package/template/packages/src/server/auth/config/better-auth.ts +16 -0
  54. package/template/packages/src/server/db/db-prisma.ts +23 -0
@@ -0,0 +1,221 @@
1
+ import { fileURLToPath } from "url"
2
+ import { revalidatePath } from "next/cache"
3
+
4
+ import { auth, signIn, signOut } from "@/server/auth"
5
+ import { db } from "@/server/db"
6
+
7
+ export default async function HomePage() {
8
+ const session = await auth()
9
+ const user = session?.user
10
+
11
+ const posts = await db.post.findMany()
12
+
13
+ const fileURL = `vscode://file/${fileURLToPath(import.meta.url)}`
14
+
15
+ return (
16
+ <main className="mx-auto flex h-screen max-w-5xl flex-col items-center justify-between overflow-hidden p-6 sm:p-[45px]">
17
+ <header className="ml-auto">
18
+ {user ? (
19
+ <button
20
+ onClick={async () => {
21
+ "use server"
22
+ await signOut()
23
+ }}
24
+ className="cursor-pointer rounded-md bg-rose-400 px-4 py-2"
25
+ >
26
+ Sign Out
27
+ </button>
28
+ ) : (
29
+ <button
30
+ onClick={async () => {
31
+ "use server"
32
+ await signIn("discord")
33
+ }}
34
+ className="cursor-pointer rounded-md bg-purple-400 px-4 py-2"
35
+ >
36
+ Sign In
37
+ </button>
38
+ )}
39
+ </header>
40
+
41
+ <div className="flex grow flex-col items-center justify-center">
42
+ {/* Logo */}
43
+ <picture className="relative">
44
+ <div className="absolute inset-0 animate-pulse rounded-xl bg-gradient-to-r from-purple-500 to-cyan-500 opacity-20 blur-xl dark:from-purple-800 dark:to-cyan-800" />
45
+ <source srcSet="https://github.com/SlickYeet/create-lx2-app/blob/main/docs/public/logo.light.png?raw=true" />
46
+ <img
47
+ src="https://github.com/SlickYeet/create-lx2-app/blob/main/docs/public/logo.light.png?raw=true"
48
+ alt="Logo"
49
+ width={65}
50
+ height={65}
51
+ className="block h-auto max-w-full"
52
+ />
53
+ </picture>
54
+
55
+ <h1 className="mt-6 bg-gradient-to-r from-purple-500 to-cyan-500 bg-clip-text text-center text-4xl leading-10 text-transparent sm:text-5xl sm:leading-14 md:text-6xl md:leading-20 lg:mt-10 lg:text-7xl lg:font-bold">
56
+ Lx2 Next.js App
57
+ </h1>
58
+ <p className="mt-4 text-center text-lg text-neutral-700 md:text-xl lg:mt-6 dark:text-neutral-300">
59
+ Build modern web applications with today&apos;s most popular tools
60
+ </p>
61
+
62
+ <div className="mt-12 flex items-center gap-3">
63
+ <a
64
+ href="https://create.lx2.dev"
65
+ target="_blank"
66
+ rel="noopener noreferrer"
67
+ className="flex items-center rounded-md border border-white px-2 py-1 outline-none focus:opacity-80 active:opacity-70"
68
+ >
69
+ Website
70
+ <svg
71
+ xmlns="http://www.w3.org/2000/svg"
72
+ viewBox="0 0 24 24"
73
+ strokeLinecap="round"
74
+ strokeLinejoin="round"
75
+ className="mb-1.5 size-4 fill-none stroke-current stroke-2"
76
+ >
77
+ <path d="M7 7h10v10" />
78
+ <path d="M7 17 17 7" />
79
+ </svg>
80
+ </a>
81
+ <a
82
+ href="https://create.lx2.dev/docs"
83
+ target="_blank"
84
+ rel="noopener noreferrer"
85
+ className="flex items-center rounded-md border border-white px-2 py-1 outline-none focus:opacity-80 active:opacity-70"
86
+ >
87
+ Docs
88
+ <svg
89
+ xmlns="http://www.w3.org/2000/svg"
90
+ viewBox="0 0 24 24"
91
+ strokeLinecap="round"
92
+ strokeLinejoin="round"
93
+ className="mb-1.5 size-4 fill-none stroke-current stroke-2"
94
+ >
95
+ <path d="M7 7h10v10" />
96
+ <path d="M7 17 17 7" />
97
+ </svg>
98
+ </a>
99
+ <a
100
+ href="https://github.com/SlickYeet/create-lx2-app"
101
+ target="_blank"
102
+ rel="noopener noreferrer"
103
+ className="flex items-center rounded-md border border-white px-2 py-1 outline-none focus:opacity-80 active:opacity-70"
104
+ >
105
+ GitHub
106
+ <svg
107
+ xmlns="http://www.w3.org/2000/svg"
108
+ viewBox="0 0 24 24"
109
+ strokeLinecap="round"
110
+ strokeLinejoin="round"
111
+ className="mb-1.5 size-4 fill-none stroke-current stroke-2"
112
+ >
113
+ <path d="M7 7h10v10" />
114
+ <path d="M7 17 17 7" />
115
+ </svg>
116
+ </a>
117
+ </div>
118
+
119
+ <div className="mt-12 flex flex-col items-center gap-3">
120
+ <div className="mb-4">
121
+ <h1 className="mb-4 text-center">
122
+ <span className="text-2xl text-neutral-700 dark:text-neutral-300">
123
+ Posts {posts.length}
124
+ </span>
125
+ </h1>
126
+
127
+ {user && (
128
+ <form
129
+ action={async (formData: FormData) => {
130
+ "use server"
131
+
132
+ if (!user) throw new Error("Unauthorized")
133
+
134
+ const name =
135
+ formData.get("name")?.toString() ||
136
+ `New Post ${posts.length + 1}`
137
+
138
+ await db.post.create({
139
+ data: {
140
+ id: crypto.randomUUID(),
141
+ name,
142
+ createdBy: {
143
+ connect: {
144
+ id: user.id,
145
+ },
146
+ },
147
+ },
148
+ })
149
+
150
+ revalidatePath("/")
151
+ }}
152
+ >
153
+ <input
154
+ type="text"
155
+ name="name"
156
+ placeholder="New Post"
157
+ className="h-8 rounded-md border border-neutral-300 px-2 outline-none dark:border-neutral-700 dark:bg-neutral-800"
158
+ />
159
+ <button
160
+ type="submit"
161
+ className="ml-2 size-8 cursor-pointer rounded-md bg-neutral-200 outline-none hover:opacity-80 focus:opacity-80 dark:bg-neutral-800"
162
+ >
163
+ +
164
+ </button>
165
+ </form>
166
+ )}
167
+ </div>
168
+
169
+ <div className="grid w-full grid-cols-1 gap-2 space-y-2 sm:grid-cols-2">
170
+ {posts.map((post) => (
171
+ <div
172
+ key={post.id}
173
+ className="flex h-10 max-w-40 items-center rounded-md bg-neutral-200 px-2 py-1 dark:bg-neutral-800"
174
+ >
175
+ <span className="truncate text-sm text-neutral-700 dark:text-neutral-300">
176
+ {post.name}
177
+ </span>
178
+ {user && (
179
+ <form
180
+ action={async () => {
181
+ "use server"
182
+
183
+ if (!user) throw new Error("Unauthorized")
184
+
185
+ await db.post.delete({
186
+ where: {
187
+ id: post.id,
188
+ createdById: user.id,
189
+ },
190
+ })
191
+
192
+ revalidatePath("/")
193
+ }}
194
+ className="ml-auto"
195
+ >
196
+ <button
197
+ type="submit"
198
+ className="ml-2 cursor-pointer rounded-md text-rose-500 outline-none hover:opacity-80 focus:opacity-80"
199
+ >
200
+ x
201
+ </button>
202
+ </form>
203
+ )}
204
+ </div>
205
+ ))}
206
+ </div>
207
+ </div>
208
+ </div>
209
+
210
+ <div className="flex flex-col items-center gap-1 text-sm text-neutral-600 lg:flex-row lg:gap-2 dark:text-neutral-400">
211
+ <p className="m-0">Get started by editing </p>
212
+ <a
213
+ href={fileURL}
214
+ className="rounded-md bg-neutral-200 px-2 py-1 dark:bg-neutral-800"
215
+ >
216
+ <code>src/app/page.tsx</code>
217
+ </a>
218
+ </div>
219
+ </main>
220
+ )
221
+ }
@@ -0,0 +1,126 @@
1
+ import { fileURLToPath } from "url"
2
+
3
+ import { auth, signIn, signOut } from "@/server/auth"
4
+
5
+ export default async function HomePage() {
6
+ const session = await auth()
7
+ const user = session?.user
8
+
9
+ const fileURL = `vscode://file/${fileURLToPath(import.meta.url)}`
10
+
11
+ return (
12
+ <main className="mx-auto flex h-screen max-w-5xl flex-col items-center justify-between overflow-hidden p-6 sm:p-[45px]">
13
+ <header className="ml-auto">
14
+ {user ? (
15
+ <button
16
+ onClick={async () => {
17
+ "use server"
18
+ await signOut()
19
+ }}
20
+ className="cursor-pointer rounded-md bg-rose-400 px-4 py-2"
21
+ >
22
+ Sign Out
23
+ </button>
24
+ ) : (
25
+ <button
26
+ onClick={async () => {
27
+ "use server"
28
+ await signIn("discord")
29
+ }}
30
+ className="cursor-pointer rounded-md bg-purple-400 px-4 py-2"
31
+ >
32
+ Sign In
33
+ </button>
34
+ )}
35
+ </header>
36
+
37
+ <div className="flex grow flex-col items-center justify-center">
38
+ {/* Logo */}
39
+ <picture className="relative">
40
+ <div className="absolute inset-0 animate-pulse rounded-xl bg-gradient-to-r from-purple-500 to-cyan-500 opacity-20 blur-xl dark:from-purple-800 dark:to-cyan-800" />
41
+ <source srcSet="https://github.com/SlickYeet/create-lx2-app/blob/main/docs/public/logo.light.png?raw=true" />
42
+ <img
43
+ src="https://github.com/SlickYeet/create-lx2-app/blob/main/docs/public/logo.light.png?raw=true"
44
+ alt="Logo"
45
+ width={65}
46
+ height={65}
47
+ className="block h-auto max-w-full"
48
+ />
49
+ </picture>
50
+
51
+ <h1 className="mt-6 bg-gradient-to-r from-purple-500 to-cyan-500 bg-clip-text text-center text-4xl leading-10 text-transparent sm:text-5xl sm:leading-14 md:text-6xl md:leading-20 lg:mt-10 lg:text-7xl lg:font-bold">
52
+ Lx2 Next.js App
53
+ </h1>
54
+ <p className="mt-4 text-center text-lg text-neutral-700 md:text-xl lg:mt-6 dark:text-neutral-300">
55
+ Build modern web applications with today&apos;s most popular tools
56
+ </p>
57
+
58
+ <div className="mt-12 flex items-center gap-3">
59
+ <a
60
+ href="https://create.lx2.dev"
61
+ target="_blank"
62
+ rel="noopener noreferrer"
63
+ className="flex items-center rounded-md border border-white px-2 py-1 outline-none focus:opacity-80 active:opacity-70"
64
+ >
65
+ Website
66
+ <svg
67
+ xmlns="http://www.w3.org/2000/svg"
68
+ viewBox="0 0 24 24"
69
+ strokeLinecap="round"
70
+ strokeLinejoin="round"
71
+ className="mb-1.5 size-4 fill-none stroke-current stroke-2"
72
+ >
73
+ <path d="M7 7h10v10" />
74
+ <path d="M7 17 17 7" />
75
+ </svg>
76
+ </a>
77
+ <a
78
+ href="https://create.lx2.dev/docs"
79
+ target="_blank"
80
+ rel="noopener noreferrer"
81
+ className="flex items-center rounded-md border border-white px-2 py-1 outline-none focus:opacity-80 active:opacity-70"
82
+ >
83
+ Docs
84
+ <svg
85
+ xmlns="http://www.w3.org/2000/svg"
86
+ viewBox="0 0 24 24"
87
+ strokeLinecap="round"
88
+ strokeLinejoin="round"
89
+ className="mb-1.5 size-4 fill-none stroke-current stroke-2"
90
+ >
91
+ <path d="M7 7h10v10" />
92
+ <path d="M7 17 17 7" />
93
+ </svg>
94
+ </a>
95
+ <a
96
+ href="https://github.com/SlickYeet/create-lx2-app"
97
+ target="_blank"
98
+ rel="noopener noreferrer"
99
+ className="flex items-center rounded-md border border-white px-2 py-1 outline-none focus:opacity-80 active:opacity-70"
100
+ >
101
+ GitHub
102
+ <svg
103
+ xmlns="http://www.w3.org/2000/svg"
104
+ viewBox="0 0 24 24"
105
+ strokeLinecap="round"
106
+ strokeLinejoin="round"
107
+ className="mb-1.5 size-4 fill-none stroke-current stroke-2"
108
+ >
109
+ <path d="M7 7h10v10" />
110
+ <path d="M7 17 17 7" />
111
+ </svg>
112
+ </a>
113
+ </div>
114
+ </div>
115
+ <div className="flex flex-col items-center gap-1 text-sm text-neutral-600 lg:flex-row lg:gap-2 dark:text-neutral-400">
116
+ <p className="m-0">Get started by editing </p>
117
+ <a
118
+ href={fileURL}
119
+ className="rounded-md bg-neutral-200 px-2 py-1 dark:bg-neutral-800"
120
+ >
121
+ <code>src/app/page.tsx</code>
122
+ </a>
123
+ </div>
124
+ </main>
125
+ )
126
+ }
@@ -0,0 +1,245 @@
1
+ import { fileURLToPath } from "url"
2
+ import { revalidatePath } from "next/cache"
3
+ import { headers } from "next/headers"
4
+ import { redirect } from "next/navigation"
5
+
6
+ import { auth } from "@/server/auth"
7
+ import { db } from "@/server/db"
8
+
9
+ export default async function HomePage() {
10
+ const session = await auth.api.getSession({
11
+ headers: await headers(),
12
+ })
13
+ const user = session?.user
14
+
15
+ const posts = await db.post.findMany()
16
+
17
+ const fileURL = `vscode://file/${fileURLToPath(import.meta.url)}`
18
+
19
+ return (
20
+ <main className="mx-auto flex h-screen max-w-5xl flex-col items-center justify-between overflow-hidden p-6 sm:p-[45px]">
21
+ <header className="ml-auto">
22
+ {user ? (
23
+ <button
24
+ onClick={async () => {
25
+ "use server"
26
+ await auth.api.signOut({
27
+ headers: await headers(),
28
+ })
29
+ }}
30
+ className="cursor-pointer rounded-md bg-rose-400 px-4 py-2"
31
+ >
32
+ Sign Out
33
+ </button>
34
+ ) : (
35
+ <button
36
+ onClick={async () => {
37
+ "use server"
38
+ const response = await auth.api.signInSocial({
39
+ body: {
40
+ provider: "discord",
41
+ },
42
+ })
43
+ if (!response) {
44
+ throw new Error("Failed to sign in")
45
+ }
46
+ if (response.url) {
47
+ redirect(response.url)
48
+ }
49
+ }}
50
+ className="cursor-pointer rounded-md bg-purple-400 px-4 py-2"
51
+ >
52
+ Sign In
53
+ </button>
54
+ )}
55
+ </header>
56
+
57
+ <div className="flex grow flex-col items-center justify-center">
58
+ {/* Logo */}
59
+ <picture className="relative">
60
+ <div className="absolute inset-0 animate-pulse rounded-xl bg-gradient-to-r from-purple-500 to-cyan-500 opacity-20 blur-xl dark:from-purple-800 dark:to-cyan-800" />
61
+ <source srcSet="https://github.com/SlickYeet/create-lx2-app/blob/main/docs/public/logo.light.png?raw=true" />
62
+ <img
63
+ src="https://github.com/SlickYeet/create-lx2-app/blob/main/docs/public/logo.light.png?raw=true"
64
+ alt="Logo"
65
+ width={65}
66
+ height={65}
67
+ className="block h-auto max-w-full"
68
+ />
69
+ </picture>
70
+
71
+ {user ? (
72
+ <h1 className="mt-6 bg-gradient-to-r from-purple-500 to-cyan-500 bg-clip-text text-center text-4xl leading-10 text-transparent sm:text-5xl sm:leading-14 md:text-6xl md:leading-20 lg:mt-10 lg:text-7xl lg:font-bold">
73
+ Welcome, <span className="capitalize">{user.name}</span>!
74
+ </h1>
75
+ ) : (
76
+ <>
77
+ <h1 className="mt-6 bg-gradient-to-r from-purple-500 to-cyan-500 bg-clip-text text-center text-4xl leading-10 text-transparent sm:text-5xl sm:leading-14 md:text-6xl md:leading-20 lg:mt-10 lg:text-7xl lg:font-bold">
78
+ Lx2 Next.js App
79
+ </h1>
80
+ <p className="mt-4 text-center text-lg text-neutral-700 md:text-xl lg:mt-6 dark:text-neutral-300">
81
+ Build modern web applications with today&apos;s most popular tools
82
+ </p>
83
+ </>
84
+ )}
85
+
86
+ <div className="mt-12 flex items-center gap-3">
87
+ <a
88
+ href="https://create.lx2.dev"
89
+ target="_blank"
90
+ rel="noopener noreferrer"
91
+ className="flex items-center rounded-md border border-white px-2 py-1 outline-none focus:opacity-80 active:opacity-70"
92
+ >
93
+ Website
94
+ <svg
95
+ xmlns="http://www.w3.org/2000/svg"
96
+ viewBox="0 0 24 24"
97
+ strokeLinecap="round"
98
+ strokeLinejoin="round"
99
+ className="mb-1.5 size-4 fill-none stroke-current stroke-2"
100
+ >
101
+ <path d="M7 7h10v10" />
102
+ <path d="M7 17 17 7" />
103
+ </svg>
104
+ </a>
105
+ <a
106
+ href="https://create.lx2.dev/docs"
107
+ target="_blank"
108
+ rel="noopener noreferrer"
109
+ className="flex items-center rounded-md border border-white px-2 py-1 outline-none focus:opacity-80 active:opacity-70"
110
+ >
111
+ Docs
112
+ <svg
113
+ xmlns="http://www.w3.org/2000/svg"
114
+ viewBox="0 0 24 24"
115
+ strokeLinecap="round"
116
+ strokeLinejoin="round"
117
+ className="mb-1.5 size-4 fill-none stroke-current stroke-2"
118
+ >
119
+ <path d="M7 7h10v10" />
120
+ <path d="M7 17 17 7" />
121
+ </svg>
122
+ </a>
123
+ <a
124
+ href="https://github.com/SlickYeet/create-lx2-app"
125
+ target="_blank"
126
+ rel="noopener noreferrer"
127
+ className="flex items-center rounded-md border border-white px-2 py-1 outline-none focus:opacity-80 active:opacity-70"
128
+ >
129
+ GitHub
130
+ <svg
131
+ xmlns="http://www.w3.org/2000/svg"
132
+ viewBox="0 0 24 24"
133
+ strokeLinecap="round"
134
+ strokeLinejoin="round"
135
+ className="mb-1.5 size-4 fill-none stroke-current stroke-2"
136
+ >
137
+ <path d="M7 7h10v10" />
138
+ <path d="M7 17 17 7" />
139
+ </svg>
140
+ </a>
141
+ </div>
142
+
143
+ <div className="mt-12 flex flex-col items-center gap-3">
144
+ <div className="mb-4">
145
+ <h1 className="mb-4 text-center">
146
+ <span className="text-2xl text-neutral-700 dark:text-neutral-300">
147
+ Posts {posts.length}
148
+ </span>
149
+ </h1>
150
+
151
+ {user && (
152
+ <form
153
+ action={async (formData: FormData) => {
154
+ "use server"
155
+
156
+ if (!user) throw new Error("Unauthorized")
157
+
158
+ const name =
159
+ formData.get("name")?.toString() ||
160
+ `New Post ${posts.length + 1}`
161
+
162
+ await db.post.create({
163
+ data: {
164
+ id: crypto.randomUUID(),
165
+ name,
166
+ createdBy: {
167
+ connect: {
168
+ id: user.id,
169
+ },
170
+ },
171
+ },
172
+ })
173
+
174
+ revalidatePath("/")
175
+ }}
176
+ >
177
+ <input
178
+ type="text"
179
+ name="name"
180
+ placeholder="New Post"
181
+ className="h-8 rounded-md border border-neutral-300 px-2 outline-none dark:border-neutral-700 dark:bg-neutral-800"
182
+ />
183
+ <button
184
+ type="submit"
185
+ className="ml-2 size-8 cursor-pointer rounded-md bg-neutral-200 outline-none hover:opacity-80 focus:opacity-80 dark:bg-neutral-800"
186
+ >
187
+ +
188
+ </button>
189
+ </form>
190
+ )}
191
+ </div>
192
+
193
+ <div className="grid w-full grid-cols-1 gap-2 space-y-2 sm:grid-cols-2">
194
+ {posts.map((post) => (
195
+ <div
196
+ key={post.id}
197
+ className="flex h-10 max-w-40 items-center rounded-md bg-neutral-200 px-2 py-1 dark:bg-neutral-800"
198
+ >
199
+ <span className="truncate text-sm text-neutral-700 dark:text-neutral-300">
200
+ {post.name}
201
+ </span>
202
+ {user && (
203
+ <form
204
+ action={async () => {
205
+ "use server"
206
+
207
+ if (!user) throw new Error("Unauthorized")
208
+
209
+ await db.post.delete({
210
+ where: {
211
+ id: post.id,
212
+ createdById: user.id,
213
+ },
214
+ })
215
+
216
+ revalidatePath("/")
217
+ }}
218
+ className="ml-auto"
219
+ >
220
+ <button
221
+ type="submit"
222
+ className="ml-2 cursor-pointer rounded-md text-rose-500 outline-none hover:opacity-80 focus:opacity-80"
223
+ >
224
+ x
225
+ </button>
226
+ </form>
227
+ )}
228
+ </div>
229
+ ))}
230
+ </div>
231
+ </div>
232
+ </div>
233
+
234
+ <div className="flex flex-col items-center gap-1 text-sm text-neutral-600 lg:flex-row lg:gap-2 dark:text-neutral-400">
235
+ <p className="m-0">Get started by editing </p>
236
+ <a
237
+ href={fileURL}
238
+ className="rounded-md bg-neutral-200 px-2 py-1 dark:bg-neutral-800"
239
+ >
240
+ <code>src/app/page.tsx</code>
241
+ </a>
242
+ </div>
243
+ </main>
244
+ )
245
+ }