@proofkit/cli 1.1.8 → 1.2.0-beta.1

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 (148) hide show
  1. package/dist/external-DCpQkgKf.js +1 -0
  2. package/dist/index.js +102 -124
  3. package/package.json +15 -10
  4. package/template/extras/config/query-provider-vite.tsx +0 -2
  5. package/template/extras/emailProviders/none/email.tsx +4 -4
  6. package/template/extras/emailProviders/plunk/email.tsx +5 -4
  7. package/template/extras/emailProviders/plunk/service.ts +1 -1
  8. package/template/extras/emailProviders/resend/email.tsx +1 -0
  9. package/template/extras/emailProviders/resend/service.ts +1 -1
  10. package/template/extras/emailTemplates/auth-code.tsx +156 -0
  11. package/template/extras/emailTemplates/generic.tsx +136 -0
  12. package/template/extras/fmaddon-auth/app/(main)/auth/profile/actions.ts +13 -9
  13. package/template/extras/fmaddon-auth/app/(main)/auth/profile/page.tsx +2 -0
  14. package/template/extras/fmaddon-auth/app/(main)/auth/profile/profile-form.tsx +7 -5
  15. package/template/extras/fmaddon-auth/app/(main)/auth/profile/reset-password-form.tsx +8 -6
  16. package/template/extras/fmaddon-auth/app/auth/forgot-password/actions.ts +7 -5
  17. package/template/extras/fmaddon-auth/app/auth/forgot-password/forgot-form.tsx +3 -2
  18. package/template/extras/fmaddon-auth/app/auth/forgot-password/page.tsx +1 -0
  19. package/template/extras/fmaddon-auth/app/auth/login/actions.ts +5 -4
  20. package/template/extras/fmaddon-auth/app/auth/login/login-form.tsx +7 -5
  21. package/template/extras/fmaddon-auth/app/auth/login/page.tsx +1 -0
  22. package/template/extras/fmaddon-auth/app/auth/reset-password/actions.ts +11 -8
  23. package/template/extras/fmaddon-auth/app/auth/reset-password/page.tsx +3 -2
  24. package/template/extras/fmaddon-auth/app/auth/reset-password/reset-password-form.tsx +5 -4
  25. package/template/extras/fmaddon-auth/app/auth/reset-password/verify-email/actions.ts +3 -2
  26. package/template/extras/fmaddon-auth/app/auth/reset-password/verify-email/page.tsx +3 -2
  27. package/template/extras/fmaddon-auth/app/auth/reset-password/verify-email/verify-email-form.tsx +3 -2
  28. package/template/extras/fmaddon-auth/app/auth/signup/actions.ts +10 -9
  29. package/template/extras/fmaddon-auth/app/auth/signup/page.tsx +1 -0
  30. package/template/extras/fmaddon-auth/app/auth/signup/signup-form.tsx +7 -6
  31. package/template/extras/fmaddon-auth/app/auth/verify-email/actions.ts +7 -8
  32. package/template/extras/fmaddon-auth/app/auth/verify-email/email-verification-form.tsx +5 -4
  33. package/template/extras/fmaddon-auth/app/auth/verify-email/page.tsx +5 -3
  34. package/template/extras/fmaddon-auth/app/auth/verify-email/resend-button.tsx +4 -2
  35. package/template/extras/fmaddon-auth/components/auth/actions.ts +4 -1
  36. package/template/extras/fmaddon-auth/components/auth/protect.tsx +2 -1
  37. package/template/extras/fmaddon-auth/components/auth/redirect.tsx +2 -2
  38. package/template/extras/fmaddon-auth/components/auth/use-user.ts +3 -2
  39. package/template/extras/fmaddon-auth/components/auth/user-menu.tsx +3 -2
  40. package/template/extras/fmaddon-auth/middleware.ts +0 -1
  41. package/template/extras/fmaddon-auth/server/auth/utils/email-verification.ts +8 -7
  42. package/template/extras/fmaddon-auth/server/auth/utils/encryption.ts +2 -2
  43. package/template/extras/fmaddon-auth/server/auth/utils/password-reset.ts +5 -4
  44. package/template/extras/fmaddon-auth/server/auth/utils/redirect.ts +1 -1
  45. package/template/extras/fmaddon-auth/server/auth/utils/session.ts +6 -7
  46. package/template/extras/fmaddon-auth/server/auth/utils/user.ts +1 -2
  47. package/template/extras/src/app/next-auth/signin/page.tsx +2 -1
  48. package/template/fm-addon/ProofKitAuth/info.json +6 -9
  49. package/template/fm-addon/ProofKitAuth/info_de.json +5 -12
  50. package/template/fm-addon/ProofKitAuth/info_es.json +5 -12
  51. package/template/fm-addon/ProofKitAuth/info_fr.json +5 -12
  52. package/template/fm-addon/ProofKitAuth/info_it.json +5 -12
  53. package/template/fm-addon/ProofKitAuth/info_ja.json +5 -12
  54. package/template/fm-addon/ProofKitAuth/info_ko.json +5 -12
  55. package/template/fm-addon/ProofKitAuth/info_nl.json +5 -12
  56. package/template/fm-addon/ProofKitAuth/info_pt.json +5 -12
  57. package/template/fm-addon/ProofKitAuth/info_sv.json +5 -12
  58. package/template/fm-addon/ProofKitAuth/info_zh.json +5 -12
  59. package/template/fm-addon/ProofKitWV/info.json +6 -9
  60. package/template/fm-addon/ProofKitWV/info_de.json +5 -12
  61. package/template/fm-addon/ProofKitWV/info_en.json +1 -5
  62. package/template/fm-addon/ProofKitWV/info_es.json +5 -12
  63. package/template/fm-addon/ProofKitWV/info_fr.json +5 -12
  64. package/template/fm-addon/ProofKitWV/info_it.json +5 -12
  65. package/template/fm-addon/ProofKitWV/info_ja.json +5 -12
  66. package/template/fm-addon/ProofKitWV/info_ko.json +5 -12
  67. package/template/fm-addon/ProofKitWV/info_nl.json +5 -12
  68. package/template/fm-addon/ProofKitWV/info_pt.json +5 -12
  69. package/template/fm-addon/ProofKitWV/info_sv.json +5 -12
  70. package/template/fm-addon/ProofKitWV/info_zh.json +5 -12
  71. package/template/{nextjs → nextjs-mantine}/proofkit.json +2 -1
  72. package/template/{nextjs → nextjs-mantine}/src/components/AppShell/internal/HeaderNavLink.tsx +5 -1
  73. package/template/{nextjs → nextjs-mantine}/src/utils/notification-helpers.ts +1 -1
  74. package/template/nextjs-mantine/tsconfig.json +27 -0
  75. package/template/nextjs-shadcn/.claude/CLAUDE.md +327 -0
  76. package/template/nextjs-shadcn/.cursor/rules/ultracite.mdc +333 -0
  77. package/template/nextjs-shadcn/.prettierrc +3 -0
  78. package/template/nextjs-shadcn/.vscode/settings.json +35 -0
  79. package/template/nextjs-shadcn/README.md +27 -0
  80. package/template/nextjs-shadcn/_gitignore +37 -0
  81. package/template/nextjs-shadcn/biome.json +43 -0
  82. package/template/nextjs-shadcn/components.json +21 -0
  83. package/template/nextjs-shadcn/next-env.d.ts +6 -0
  84. package/template/nextjs-shadcn/next.config.ts +8 -0
  85. package/template/nextjs-shadcn/package.json +35 -0
  86. package/template/nextjs-shadcn/postcss.config.mjs +5 -0
  87. package/template/nextjs-shadcn/proofkit.json +6 -0
  88. package/template/nextjs-shadcn/public/favicon.ico +0 -0
  89. package/template/nextjs-shadcn/public/proofkit.png +0 -0
  90. package/template/nextjs-shadcn/src/app/(main)/layout.tsx +6 -0
  91. package/template/nextjs-shadcn/src/app/(main)/page.tsx +124 -0
  92. package/template/nextjs-shadcn/src/app/globals.css +122 -0
  93. package/template/nextjs-shadcn/src/app/layout.tsx +35 -0
  94. package/template/nextjs-shadcn/src/app/navigation.tsx +12 -0
  95. package/template/nextjs-shadcn/src/components/AppLogo.tsx +6 -0
  96. package/template/nextjs-shadcn/src/components/AppShell/internal/AppShell.tsx +23 -0
  97. package/template/nextjs-shadcn/src/components/AppShell/internal/Header.module.css +33 -0
  98. package/template/nextjs-shadcn/src/components/AppShell/internal/Header.tsx +30 -0
  99. package/template/nextjs-shadcn/src/components/AppShell/internal/HeaderMobileMenu.tsx +25 -0
  100. package/template/nextjs-shadcn/src/components/AppShell/internal/HeaderNavLink.tsx +35 -0
  101. package/template/nextjs-shadcn/src/components/AppShell/internal/config.ts +1 -0
  102. package/template/nextjs-shadcn/src/components/AppShell/slot-header-center.tsx +13 -0
  103. package/template/nextjs-shadcn/src/components/AppShell/slot-header-left.tsx +23 -0
  104. package/template/nextjs-shadcn/src/components/AppShell/slot-header-mobile-content.tsx +43 -0
  105. package/template/nextjs-shadcn/src/components/AppShell/slot-header-right.tsx +25 -0
  106. package/template/nextjs-shadcn/src/components/providers.tsx +13 -0
  107. package/template/nextjs-shadcn/src/components/theme-provider.tsx +11 -0
  108. package/template/nextjs-shadcn/src/lib/env.ts +12 -0
  109. package/template/nextjs-shadcn/src/lib/utils.ts +6 -0
  110. package/template/{nextjs → nextjs-shadcn}/tsconfig.json +3 -2
  111. package/template/pages/nextjs/table-edit/page.tsx +5 -5
  112. package/template/pages/nextjs/table-edit/table.tsx +5 -3
  113. package/template/pages/nextjs/table-infinite/query.ts +4 -3
  114. package/template/pages/nextjs/table-infinite/table.tsx +3 -2
  115. package/template/pages/nextjs/table-infinite-edit/page.tsx +6 -6
  116. package/template/pages/nextjs/table-infinite-edit/query.ts +8 -2
  117. package/template/pages/vite-wv/table/index.tsx +5 -4
  118. package/template/pages/vite-wv/table-edit/index.tsx +6 -6
  119. package/template/vite-wv/src/main.tsx +1 -1
  120. package/template/vite-wv/src/routeTree.gen.ts +41 -41
  121. /package/template/{nextjs → nextjs-mantine}/.prettierrc +0 -0
  122. /package/template/{nextjs → nextjs-mantine}/README.md +0 -0
  123. /package/template/{nextjs → nextjs-mantine}/_gitignore +0 -0
  124. /package/template/{nextjs → nextjs-mantine}/components.json +0 -0
  125. /package/template/{nextjs → nextjs-mantine}/next.config.ts +0 -0
  126. /package/template/{nextjs → nextjs-mantine}/package.json +0 -0
  127. /package/template/{nextjs → nextjs-mantine}/postcss.config.cjs +0 -0
  128. /package/template/{nextjs → nextjs-mantine}/public/favicon.ico +0 -0
  129. /package/template/{nextjs → nextjs-mantine}/public/proofkit.png +0 -0
  130. /package/template/{nextjs → nextjs-mantine}/src/app/(main)/layout.tsx +0 -0
  131. /package/template/{nextjs → nextjs-mantine}/src/app/(main)/page.tsx +0 -0
  132. /package/template/{nextjs → nextjs-mantine}/src/app/layout.tsx +0 -0
  133. /package/template/{nextjs → nextjs-mantine}/src/app/navigation.tsx +0 -0
  134. /package/template/{nextjs → nextjs-mantine}/src/components/AppLogo.tsx +0 -0
  135. /package/template/{nextjs → nextjs-mantine}/src/components/AppShell/internal/AppShell.tsx +0 -0
  136. /package/template/{nextjs → nextjs-mantine}/src/components/AppShell/internal/Header.module.css +0 -0
  137. /package/template/{nextjs → nextjs-mantine}/src/components/AppShell/internal/Header.tsx +0 -0
  138. /package/template/{nextjs → nextjs-mantine}/src/components/AppShell/internal/HeaderMobileMenu.tsx +0 -0
  139. /package/template/{nextjs → nextjs-mantine}/src/components/AppShell/internal/config.ts +0 -0
  140. /package/template/{nextjs → nextjs-mantine}/src/components/AppShell/slot-header-center.tsx +0 -0
  141. /package/template/{nextjs → nextjs-mantine}/src/components/AppShell/slot-header-left.tsx +0 -0
  142. /package/template/{nextjs → nextjs-mantine}/src/components/AppShell/slot-header-mobile-content.tsx +0 -0
  143. /package/template/{nextjs → nextjs-mantine}/src/components/AppShell/slot-header-right.tsx +0 -0
  144. /package/template/{nextjs → nextjs-mantine}/src/config/env.ts +0 -0
  145. /package/template/{nextjs → nextjs-mantine}/src/config/theme/globals.css +0 -0
  146. /package/template/{nextjs → nextjs-mantine}/src/config/theme/mantine-theme.ts +0 -0
  147. /package/template/{nextjs → nextjs-mantine}/src/server/safe-action.ts +0 -0
  148. /package/template/{nextjs → nextjs-mantine}/src/utils/styles.ts +0 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proofkit/cli",
3
- "version": "1.1.8",
3
+ "version": "1.2.0-beta.1",
4
4
  "description": "Create web application with the ProofKit stack",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -39,6 +39,7 @@
39
39
  "node": "^20.0.0 || ^22.0.0"
40
40
  },
41
41
  "dependencies": {
42
+ "@better-fetch/fetch": "1.1.17",
42
43
  "@clack/core": "^0.3.4",
43
44
  "@clack/prompts": "^0.11.0",
44
45
  "@ianvs/prettier-plugin-sort-imports": "^4.4.1",
@@ -49,9 +50,11 @@
49
50
  "dotenv": "^16.5.0",
50
51
  "es-toolkit": "^1.15.1",
51
52
  "execa": "^9.5.1",
53
+ "fast-glob": "^3.3.3",
52
54
  "fs-extra": "^11.3.0",
53
55
  "glob": "^11.0.1",
54
56
  "gradient-string": "^2.0.2",
57
+ "handlebars": "^4.7.8",
55
58
  "jiti": "^1.21.7",
56
59
  "jsonc-parser": "^3.3.1",
57
60
  "open": "^10.1.0",
@@ -60,10 +63,11 @@
60
63
  "prettier-plugin-tailwindcss": "^0.6.5",
61
64
  "randomstring": "^1.3.0",
62
65
  "semver": "^7.7.2",
66
+ "shadcn": "^2.10.0",
63
67
  "sort-package-json": "^2.10.0",
64
68
  "ts-morph": "^26.0.0",
65
- "@proofkit/fmdapi": "5.0.2",
66
- "@proofkit/typegen": "1.0.10"
69
+ "@proofkit/typegen": "1.0.11-beta.0",
70
+ "@proofkit/fmdapi": "5.0.3-beta.0"
67
71
  },
68
72
  "devDependencies": {
69
73
  "@auth/drizzle-adapter": "^1.1.0",
@@ -98,16 +102,17 @@
98
102
  "react-dom": "^19.1.1",
99
103
  "superjson": "^2.2.1",
100
104
  "tailwindcss": "^4.1.11",
101
- "tsup": "^6.7.0",
105
+ "tsdown": "^0.14.1",
102
106
  "type-fest": "^3.13.1",
103
107
  "typescript": "^5.9.2",
104
108
  "vitest": "^3.2.4",
105
- "zod": "3.25.64"
109
+ "zod": "3.25.64",
110
+ "@proofkit/registry": "1.0.0"
106
111
  },
107
112
  "scripts": {
108
113
  "typecheck": "tsc",
109
- "build": "tsup && publint --strict",
110
- "dev": "tsup --watch",
114
+ "build": "NODE_ENV=production tsdown && publint --strict",
115
+ "dev": "tsdown --watch",
111
116
  "clean": "rm -rf dist .turbo node_modules",
112
117
  "start": "node dist/index.js",
113
118
  "lint": "eslint . --ext .ts,.tsx",
@@ -115,9 +120,9 @@
115
120
  "format": "prettier '**/*.{cjs,mjs,ts,tsx,md,json}' --ignore-path ../.gitignore --ignore-unknown --no-error-on-unmatched-pattern --write",
116
121
  "format:check": "prettier '**/*.{cjs,mjs,ts,tsx,md,json}' --ignore-path ../.gitignore --ignore-unknown --no-error-on-unmatched-pattern --check",
117
122
  "release": "changeset version",
118
- "pub:beta": "pnpm build && npm publish --tag beta --access public",
119
- "pub:next": "pnpm build && npm publish --tag next --access public",
120
- "pub:release": "pnpm build && npm publish --access public",
123
+ "pub:beta": "NODE_ENV=production pnpm build && npm publish --tag beta --access public",
124
+ "pub:next": "NODE_ENV=production pnpm build && npm publish --tag next --access public",
125
+ "pub:release": "NODE_ENV=production pnpm build && npm publish --access public",
121
126
  "test": "vitest run"
122
127
  }
123
128
  }
@@ -1,4 +1,3 @@
1
-
2
1
  import { QueryClient, QueryClientProvider } from "@tanstack/react-query";
3
2
  import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
4
3
 
@@ -9,7 +8,6 @@ export default function QueryProvider({
9
8
  }: {
10
9
  children: React.ReactNode;
11
10
  }) {
12
-
13
11
  return (
14
12
  <QueryClientProvider client={queryClient}>
15
13
  {children}
@@ -1,5 +1,5 @@
1
- import { render } from "@react-email/render";
2
1
  import { AuthCodeEmail } from "@/emails/auth-code";
2
+ import { render } from "@react-email/render";
3
3
 
4
4
  export async function sendEmail({
5
5
  to,
@@ -14,11 +14,11 @@ export async function sendEmail({
14
14
  const body = await render(
15
15
  <AuthCodeEmail validationCode={code} type={type} />
16
16
  );
17
- const subject = type === "verification" ? "Verify Your Email" : "Reset Your Password"
18
-
17
+ const subject =
18
+ type === "verification" ? "Verify Your Email" : "Reset Your Password";
19
+
19
20
  // TODO: Customize this function to actually send the email to your users
20
21
  // Learn more: https://proofkit.dev/auth/fm-addon
21
22
  console.warn("TODO: Customize this function to actually send to your users");
22
23
  console.log(`To ${to}: Your ${type} code is ${code}`);
23
24
  }
24
-
@@ -1,5 +1,6 @@
1
- import { render } from "@react-email/render";
2
1
  import { AuthCodeEmail } from "@/emails/auth-code";
2
+ import { render } from "@react-email/render";
3
+
3
4
  import { plunk } from "../services/plunk";
4
5
 
5
6
  export async function sendEmail({
@@ -15,12 +16,12 @@ export async function sendEmail({
15
16
  const body = await render(
16
17
  <AuthCodeEmail validationCode={code} type={type} />
17
18
  );
18
- const subject = type === "verification" ? "Verify Your Email" : "Reset Your Password"
19
-
19
+ const subject =
20
+ type === "verification" ? "Verify Your Email" : "Reset Your Password";
21
+
20
22
  await plunk.emails.send({
21
23
  to,
22
24
  subject,
23
25
  body,
24
26
  });
25
27
  }
26
-
@@ -1,4 +1,4 @@
1
- import Plunk from "@plunk/node";
2
1
  import { env } from "@/config/env";
2
+ import Plunk from "@plunk/node";
3
3
 
4
4
  export const plunk = new Plunk(env.PLUNK_API_KEY);
@@ -1,4 +1,5 @@
1
1
  import { AuthCodeEmail } from "@/emails/auth-code";
2
+
2
3
  import { resend } from "../services/resend";
3
4
 
4
5
  export async function sendEmail({
@@ -1,4 +1,4 @@
1
- import { Resend } from "resend";
2
1
  import { env } from "@/config/env";
2
+ import { Resend } from "resend";
3
3
 
4
4
  export const resend = new Resend(env.RESEND_API_KEY);
@@ -0,0 +1,156 @@
1
+ import {
2
+ Body,
3
+ Container,
4
+ Head,
5
+ Heading,
6
+ Html,
7
+ Img,
8
+ Section,
9
+ Text,
10
+ } from "@react-email/components";
11
+ import * as React from "react";
12
+
13
+ interface AuthCodeEmailProps {
14
+ validationCode: string;
15
+ type: "verification" | "password-reset";
16
+ }
17
+
18
+ export const AuthCodeEmail = ({ validationCode, type }: AuthCodeEmailProps) => (
19
+ <Html>
20
+ <Head />
21
+ <Body style={main}>
22
+ <Container style={container}>
23
+ <Img
24
+ // TODO: Replace with your logo
25
+ src="https://proofkit.dev/_astro/proofkit.DNcFg0_B_1JN3Dz.webp"
26
+ width="238"
27
+ height="175"
28
+ alt="ProofKit"
29
+ style={logo}
30
+ />
31
+ <Text style={tertiary}>
32
+ {type === "verification"
33
+ ? "Verify Your Email"
34
+ : "Reset Your Password"}
35
+ </Text>
36
+ <Heading style={secondary}>
37
+ Enter the following code to{" "}
38
+ {type === "verification"
39
+ ? "verify your email"
40
+ : "reset your password"}
41
+ </Heading>
42
+ <Section style={codeContainer}>
43
+ <Text style={code}>{validationCode}</Text>
44
+ </Section>
45
+ <Text style={paragraph}>
46
+ If you did not request this code, you can ignore this email.
47
+ </Text>
48
+ </Container>
49
+ </Body>
50
+ </Html>
51
+ );
52
+
53
+ AuthCodeEmail.PreviewProps = {
54
+ validationCode: "D7CU4GOV",
55
+ type: "verification",
56
+ } as AuthCodeEmailProps;
57
+
58
+ export default AuthCodeEmail;
59
+
60
+ const main = {
61
+ backgroundColor: "#ffffff",
62
+ fontFamily: "HelveticaNeue,Helvetica,Arial,sans-serif",
63
+ };
64
+
65
+ const container = {
66
+ backgroundColor: "#ffffff",
67
+ border: "1px solid #eee",
68
+ borderRadius: "5px",
69
+ boxShadow: "0 5px 10px rgba(20,50,70,.2)",
70
+ marginTop: "20px",
71
+ maxWidth: "360px",
72
+ margin: "0 auto",
73
+ padding: "68px 0 130px",
74
+ };
75
+
76
+ const logo: React.CSSProperties = {
77
+ margin: "0 auto",
78
+ };
79
+
80
+ const tertiary = {
81
+ color: "#0a85ea",
82
+ fontSize: "11px",
83
+ fontWeight: 700,
84
+ fontFamily: "HelveticaNeue,Helvetica,Arial,sans-serif",
85
+ height: "16px",
86
+ letterSpacing: "0",
87
+ lineHeight: "16px",
88
+ margin: "16px 8px 8px 8px",
89
+ textTransform: "uppercase" as const,
90
+ textAlign: "center" as const,
91
+ };
92
+
93
+ const secondary = {
94
+ color: "#000",
95
+ display: "inline-block",
96
+ fontFamily: "HelveticaNeue-Medium,Helvetica,Arial,sans-serif",
97
+ fontSize: "20px",
98
+ fontWeight: 500,
99
+ lineHeight: "24px",
100
+ marginBottom: "0",
101
+ marginTop: "0",
102
+ textAlign: "center" as const,
103
+ padding: "0 40px",
104
+ };
105
+
106
+ const codeContainer = {
107
+ background: "rgba(0,0,0,.05)",
108
+ borderRadius: "4px",
109
+ margin: "16px auto 14px",
110
+ verticalAlign: "middle",
111
+ width: "280px",
112
+ };
113
+
114
+ const code = {
115
+ color: "#000",
116
+ display: "inline-block",
117
+ fontFamily: "HelveticaNeue-Bold",
118
+ fontSize: "32px",
119
+ fontWeight: 700,
120
+ letterSpacing: "6px",
121
+ lineHeight: "40px",
122
+ paddingBottom: "8px",
123
+ paddingTop: "8px",
124
+ margin: "0 auto",
125
+ width: "100%",
126
+ textAlign: "center" as const,
127
+ };
128
+
129
+ const paragraph = {
130
+ color: "#444",
131
+ fontSize: "15px",
132
+ fontFamily: "HelveticaNeue,Helvetica,Arial,sans-serif",
133
+ letterSpacing: "0",
134
+ lineHeight: "23px",
135
+ padding: "0 40px",
136
+ margin: "0",
137
+ textAlign: "center" as const,
138
+ };
139
+
140
+ const link = {
141
+ color: "#444",
142
+ textDecoration: "underline",
143
+ };
144
+
145
+ const footer = {
146
+ color: "#000",
147
+ fontSize: "12px",
148
+ fontWeight: 800,
149
+ letterSpacing: "0",
150
+ lineHeight: "23px",
151
+ margin: "0",
152
+ marginTop: "20px",
153
+ fontFamily: "HelveticaNeue,Helvetica,Arial,sans-serif",
154
+ textAlign: "center" as const,
155
+ textTransform: "uppercase" as const,
156
+ };
@@ -0,0 +1,136 @@
1
+ import {
2
+ Body,
3
+ Button,
4
+ Container,
5
+ Head,
6
+ Heading,
7
+ Hr,
8
+ Html,
9
+ Img,
10
+ Section,
11
+ Text,
12
+ } from "@react-email/components";
13
+ import * as React from "react";
14
+
15
+ export interface GenericEmailProps {
16
+ title?: string;
17
+ description?: string;
18
+ ctaText?: string;
19
+ ctaHref?: string;
20
+ footer?: string;
21
+ }
22
+
23
+ export const GenericEmail = ({
24
+ title,
25
+ description,
26
+ ctaText,
27
+ ctaHref,
28
+ footer,
29
+ }: GenericEmailProps) => (
30
+ <Html>
31
+ <Head />
32
+ <Body style={styles.main}>
33
+ <Container style={styles.container}>
34
+ <Img
35
+ src="https://proofkit.dev/_astro/proofkit.DNcFg0_B_1JN3Dz.webp"
36
+ width="238"
37
+ height="175"
38
+ alt="ProofKit"
39
+ style={styles.logo}
40
+ />
41
+
42
+ {title ? <Heading style={styles.title}>{title}</Heading> : null}
43
+
44
+ {description ? (
45
+ <Text style={styles.description}>{description}</Text>
46
+ ) : null}
47
+
48
+ {ctaText && ctaHref ? (
49
+ <Section style={styles.ctaSection}>
50
+ <Button href={ctaHref} style={styles.ctaButton}>
51
+ {ctaText}
52
+ </Button>
53
+ </Section>
54
+ ) : null}
55
+
56
+ {(title || description || (ctaText && ctaHref)) && (
57
+ <Hr style={styles.hr} />
58
+ )}
59
+
60
+ {footer ? <Text style={styles.footer}>{footer}</Text> : null}
61
+ </Container>
62
+ </Body>
63
+ </Html>
64
+ );
65
+
66
+ GenericEmail.PreviewProps = {
67
+ title: "Welcome to ProofKit",
68
+ description:
69
+ "Thanks for trying ProofKit. This is a sample email template you can customize.",
70
+ ctaText: "Get Started",
71
+ ctaHref: "https://proofkit.dev",
72
+ footer: "You received this email because you signed up for updates.",
73
+ } as GenericEmailProps;
74
+
75
+ export default GenericEmail;
76
+
77
+ const styles = {
78
+ main: {
79
+ backgroundColor: "#ffffff",
80
+ fontFamily: "HelveticaNeue,Helvetica,Arial,sans-serif",
81
+ },
82
+ container: {
83
+ backgroundColor: "#ffffff",
84
+ border: "1px solid #eee",
85
+ borderRadius: "5px",
86
+ boxShadow: "0 5px 10px rgba(20,50,70,.2)",
87
+ marginTop: "20px",
88
+ maxWidth: "520px",
89
+ margin: "0 auto",
90
+ padding: "48px 32px 36px",
91
+ } as React.CSSProperties,
92
+ logo: {
93
+ margin: "0 auto 12px",
94
+ display: "block",
95
+ } as React.CSSProperties,
96
+ title: {
97
+ color: "#111827",
98
+ fontSize: "22px",
99
+ fontWeight: 600,
100
+ lineHeight: "28px",
101
+ margin: "8px 0 4px",
102
+ textAlign: "center" as const,
103
+ },
104
+ description: {
105
+ color: "#374151",
106
+ fontSize: "15px",
107
+ lineHeight: "22px",
108
+ margin: "8px 0 0",
109
+ textAlign: "center" as const,
110
+ },
111
+ ctaSection: {
112
+ textAlign: "center" as const,
113
+ marginTop: "20px",
114
+ },
115
+ ctaButton: {
116
+ backgroundColor: "#0a85ea",
117
+ color: "#fff",
118
+ fontSize: "14px",
119
+ fontWeight: 600,
120
+ lineHeight: "20px",
121
+ textDecoration: "none",
122
+ display: "inline-block",
123
+ padding: "10px 16px",
124
+ borderRadius: "6px",
125
+ } as React.CSSProperties,
126
+ hr: {
127
+ borderColor: "#e5e7eb",
128
+ margin: "24px 0 12px",
129
+ },
130
+ footer: {
131
+ color: "#6b7280",
132
+ fontSize: "12px",
133
+ lineHeight: "18px",
134
+ textAlign: "center" as const,
135
+ },
136
+ };
@@ -1,6 +1,14 @@
1
1
  "use server";
2
- import { actionClient } from "@/server/safe-action";
3
- import { updateEmailSchema, updatePasswordSchema } from "./schema";
2
+
3
+ import {
4
+ createEmailVerificationRequest,
5
+ sendVerificationEmail,
6
+ setEmailVerificationRequestCookie,
7
+ } from "@/server/auth/utils/email-verification";
8
+ import {
9
+ verifyPasswordHash,
10
+ verifyPasswordStrength,
11
+ } from "@/server/auth/utils/password";
4
12
  import {
5
13
  createSession,
6
14
  generateSessionToken,
@@ -13,14 +21,10 @@ import {
13
21
  updateUserPassword,
14
22
  validateLogin,
15
23
  } from "@/server/auth/utils/user";
16
- import {
17
- createEmailVerificationRequest,
18
- sendVerificationEmail,
19
- setEmailVerificationRequestCookie,
20
- } from "@/server/auth/utils/email-verification";
24
+ import { actionClient } from "@/server/safe-action";
21
25
  import { redirect } from "next/navigation";
22
- import { verifyPasswordHash } from "@/server/auth/utils/password";
23
- import { verifyPasswordStrength } from "@/server/auth/utils/password";
26
+
27
+ import { updateEmailSchema, updatePasswordSchema } from "./schema";
24
28
 
25
29
  export const updateEmailAction = actionClient
26
30
  .schema(updateEmailSchema)
@@ -1,8 +1,10 @@
1
1
  import { getCurrentSession } from "@/server/auth/utils/session";
2
2
  import { Anchor, Container, Paper, Stack, Text, Title } from "@mantine/core";
3
3
  import { redirect } from "next/navigation";
4
+
4
5
  import UpdateEmailForm from "./profile-form";
5
6
  import UpdatePasswordForm from "./reset-password-form";
7
+
6
8
  // import EmailVerificationForm from "./email-verification-form";
7
9
 
8
10
  export default async function Page() {
@@ -1,7 +1,5 @@
1
1
  "use client";
2
- import { useHookFormAction } from "@next-safe-action/adapter-react-hook-form/hooks";
3
- import { updateEmailSchema } from "./schema";
4
- import { updateEmailAction } from "./actions";
2
+
5
3
  import { zodResolver } from "@hookform/resolvers/zod";
6
4
  import {
7
5
  Anchor,
@@ -9,10 +7,14 @@ import {
9
7
  Group,
10
8
  Paper,
11
9
  PasswordInput,
10
+ Stack,
12
11
  Text,
12
+ TextInput,
13
13
  } from "@mantine/core";
14
- import { TextInput } from "@mantine/core";
15
- import { Stack } from "@mantine/core";
14
+ import { useHookFormAction } from "@next-safe-action/adapter-react-hook-form/hooks";
15
+
16
+ import { updateEmailAction } from "./actions";
17
+ import { updateEmailSchema } from "./schema";
16
18
 
17
19
  export default function UpdateEmailForm({
18
20
  currentEmail,
@@ -1,7 +1,6 @@
1
1
  "use client";
2
- import { useHookFormAction } from "@next-safe-action/adapter-react-hook-form/hooks";
3
- import { updatePasswordSchema } from "./schema";
4
- import { updatePasswordAction } from "./actions";
2
+
3
+ import { showSuccessNotification } from "@/utils/notification-helpers";
5
4
  import { zodResolver } from "@hookform/resolvers/zod";
6
5
  import {
7
6
  Anchor,
@@ -9,12 +8,15 @@ import {
9
8
  Group,
10
9
  Paper,
11
10
  PasswordInput,
11
+ Stack,
12
12
  Text,
13
+ TextInput,
13
14
  } from "@mantine/core";
14
- import { TextInput } from "@mantine/core";
15
- import { Stack } from "@mantine/core";
15
+ import { useHookFormAction } from "@next-safe-action/adapter-react-hook-form/hooks";
16
16
  import { useState } from "react";
17
- import { showSuccessNotification } from "@/utils/notification-helpers";
17
+
18
+ import { updatePasswordAction } from "./actions";
19
+ import { updatePasswordSchema } from "./schema";
18
20
 
19
21
  export default function UpdatePasswordForm() {
20
22
  const [showForm, setShowForm] = useState(false);
@@ -1,15 +1,17 @@
1
1
  "use server";
2
- import { actionClient } from "@/server/safe-action";
3
- import { forgotPasswordSchema } from "./schema";
4
- import { getUserFromEmail } from "@/server/auth/utils/user";
5
- import { generateSessionToken } from "@/server/auth/utils/session";
6
- import { redirect } from "next/navigation";
2
+
7
3
  import {
8
4
  createPasswordResetSession,
9
5
  invalidateUserPasswordResetSessions,
10
6
  sendPasswordResetEmail,
11
7
  setPasswordResetSessionTokenCookie,
12
8
  } from "@/server/auth/utils/password-reset";
9
+ import { generateSessionToken } from "@/server/auth/utils/session";
10
+ import { getUserFromEmail } from "@/server/auth/utils/user";
11
+ import { actionClient } from "@/server/safe-action";
12
+ import { redirect } from "next/navigation";
13
+
14
+ import { forgotPasswordSchema } from "./schema";
13
15
 
14
16
  export const forgotPasswordAction = actionClient
15
17
  .schema(forgotPasswordSchema)
@@ -1,8 +1,9 @@
1
1
  "use client";
2
2
 
3
- import { useHookFormAction } from "@next-safe-action/adapter-react-hook-form/hooks";
4
3
  import { zodResolver } from "@hookform/resolvers/zod";
5
- import { TextInput, Button, Stack, Paper, Text } from "@mantine/core";
4
+ import { Button, Paper, Stack, Text, TextInput } from "@mantine/core";
5
+ import { useHookFormAction } from "@next-safe-action/adapter-react-hook-form/hooks";
6
+
6
7
  import { forgotPasswordAction } from "./actions";
7
8
  import { forgotPasswordSchema } from "./schema";
8
9
 
@@ -1,4 +1,5 @@
1
1
  import { Anchor, Container, Text, Title } from "@mantine/core";
2
+
2
3
  import ForgotForm from "./forgot-form";
3
4
 
4
5
  export default async function Page() {
@@ -1,15 +1,16 @@
1
1
  "use server";
2
2
 
3
- import { actionClient } from "@/server/safe-action";
4
- import { loginSchema } from "./schema";
5
- import { validateLogin } from "@/server/auth/utils/user";
3
+ import { getRedirectCookie } from "@/server/auth/utils/redirect";
6
4
  import {
7
5
  createSession,
8
6
  generateSessionToken,
9
7
  setSessionTokenCookie,
10
8
  } from "@/server/auth/utils/session";
9
+ import { validateLogin } from "@/server/auth/utils/user";
10
+ import { actionClient } from "@/server/safe-action";
11
11
  import { redirect } from "next/navigation";
12
- import { getRedirectCookie } from "@/server/auth/utils/redirect";
12
+
13
+ import { loginSchema } from "./schema";
13
14
 
14
15
  export const loginAction = actionClient
15
16
  .schema(loginSchema)
@@ -1,7 +1,5 @@
1
1
  "use client";
2
- import { useHookFormAction } from "@next-safe-action/adapter-react-hook-form/hooks";
3
- import { loginSchema } from "./schema";
4
- import { loginAction } from "./actions";
2
+
5
3
  import { zodResolver } from "@hookform/resolvers/zod";
6
4
  import {
7
5
  Anchor,
@@ -9,10 +7,14 @@ import {
9
7
  Group,
10
8
  Paper,
11
9
  PasswordInput,
10
+ Stack,
12
11
  Text,
12
+ TextInput,
13
13
  } from "@mantine/core";
14
- import { TextInput } from "@mantine/core";
15
- import { Stack } from "@mantine/core";
14
+ import { useHookFormAction } from "@next-safe-action/adapter-react-hook-form/hooks";
15
+
16
+ import { loginAction } from "./actions";
17
+ import { loginSchema } from "./schema";
16
18
 
17
19
  export default function LoginForm() {
18
20
  const { form, handleSubmitWithAction, action } = useHookFormAction(
@@ -1,6 +1,7 @@
1
1
  import { getCurrentSession } from "@/server/auth/utils/session";
2
2
  import { Anchor, Container, Text, Title } from "@mantine/core";
3
3
  import { redirect } from "next/navigation";
4
+
4
5
  import LoginForm from "./login-form";
5
6
 
6
7
  export default async function Page() {