create-zhx-monorepo 2.0.0 → 2.1.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.
- package/package.json +1 -1
- package/templates/monorepo-starter/apps/dashboard/next-env.d.ts +1 -1
- package/templates/monorepo-starter/apps/dashboard/src/components/forms/AuthForm.tsx +18 -24
- package/templates/monorepo-starter/apps/dashboard/src/components/layout/Header.tsx +1 -1
- package/templates/monorepo-starter/apps/dashboard/src/components/shared/VerifyAuthPage.tsx +1 -1
- package/templates/monorepo-starter/apps/dashboard/src/components/user/UserAccountSection.tsx +24 -32
- package/templates/monorepo-starter/packages/contracts/package.json +12 -0
- package/templates/monorepo-starter/packages/contracts/src/business/dto.ts +4 -0
- package/templates/monorepo-starter/packages/contracts/src/business/index.ts +2 -0
- package/templates/monorepo-starter/packages/contracts/src/business/schema.ts +32 -0
- package/templates/monorepo-starter/packages/contracts/src/business/types.d.ts +14 -0
- package/templates/monorepo-starter/packages/contracts/src/contact/dto.ts +18 -0
- package/templates/monorepo-starter/packages/contracts/src/contact/index.ts +2 -0
- package/templates/monorepo-starter/packages/contracts/src/contact/schema.ts +36 -0
- package/templates/monorepo-starter/packages/contracts/src/contact/types.d.ts +28 -0
- package/templates/monorepo-starter/packages/contracts/src/index.ts +2 -0
- package/templates/monorepo-starter/packages/contracts/src/lib/enums.ts +37 -0
- package/templates/monorepo-starter/packages/contracts/src/lib/prisma.ts +0 -1
- package/templates/monorepo-starter/packages/contracts/src/lib/types.d.ts +2 -2
- package/templates/monorepo-starter/packages/contracts/src/newsletter/dto.ts +18 -0
- package/templates/monorepo-starter/packages/contracts/src/newsletter/index.ts +2 -0
- package/templates/monorepo-starter/packages/contracts/src/newsletter/schema.ts +23 -0
- package/templates/monorepo-starter/packages/contracts/src/newsletter/types.d.ts +34 -0
- package/templates/monorepo-starter/packages/contracts/src/notification/schema.ts +1 -1
- package/templates/monorepo-starter/packages/contracts/tsup.config.ts +4 -1
- package/templates/monorepo-starter/packages/templates/src/email/components/actionBlock.tsx +1 -1
- package/templates/monorepo-starter/packages/templates/src/email/contactMessage.tsx +55 -0
- package/templates/monorepo-starter/packages/templates/src/email/index.ts +11 -2
- package/templates/monorepo-starter/packages/templates/src/email/newsletter.tsx +43 -0
- package/templates/monorepo-starter/packages/templates/src/email/securityAlert.tsx +8 -0
- package/templates/monorepo-starter/packages/templates/src/email/{auth/signin.tsx → signIn.tsx} +20 -19
- package/templates/monorepo-starter/packages/templates/src/email/{auth/signup.tsx → signUp.tsx} +24 -24
- package/templates/monorepo-starter/packages/templates/src/email/updateIdentifier.tsx +72 -0
- package/templates/monorepo-starter/packages/templates/src/email/updateMfa.tsx +88 -0
- package/templates/monorepo-starter/packages/templates/src/email/updatePassword.tsx +79 -0
- package/templates/monorepo-starter/packages/templates/src/email/userStatus.tsx +62 -0
- package/templates/monorepo-starter/packages/templates/src/email/{auth/verifyIdentifier.tsx → verifyIdentifier.tsx} +42 -42
- package/templates/monorepo-starter/packages/templates/src/email/verifyMfa.tsx +25 -0
- package/templates/monorepo-starter/packages/templates/src/lib/constants.ts +13 -16
- package/templates/monorepo-starter/packages/templates/src/lib/utils.ts +7 -8
- package/templates/monorepo-starter/packages/templates/src/types/global.d.ts +59 -19
- package/templates/monorepo-starter/server/prisma/schema.prisma +163 -21
- package/templates/monorepo-starter/server/src/lib/constants/index.ts +21 -16
- package/templates/monorepo-starter/server/src/modules/auth/auth.service.ts +68 -61
- package/templates/monorepo-starter/server/src/modules/auth/oauth.service.ts +6 -6
- package/templates/monorepo-starter/server/src/modules/auth/otp.service.ts +141 -16
- package/templates/monorepo-starter/server/src/modules/notification/notification.service.ts +28 -28
- package/templates/monorepo-starter/packages/contracts/src/lib/index.ts +0 -4
- package/templates/monorepo-starter/packages/templates/src/email/auth/disableMfa.tsx +0 -40
- package/templates/monorepo-starter/packages/templates/src/email/auth/index.ts +0 -10
- package/templates/monorepo-starter/packages/templates/src/email/auth/resetPassword.tsx +0 -41
- package/templates/monorepo-starter/packages/templates/src/email/auth/securityAlert.tsx +0 -21
- package/templates/monorepo-starter/packages/templates/src/email/auth/setPassword.tsx +0 -42
- package/templates/monorepo-starter/packages/templates/src/email/auth/updateIdentifier.tsx +0 -79
- package/templates/monorepo-starter/packages/templates/src/email/auth/updateMfa.tsx +0 -40
- package/templates/monorepo-starter/packages/templates/src/email/auth/verifyMfa.tsx +0 -23
- package/templates/monorepo-starter/packages/templates/src/email/service/accountReactivated.tsx +0 -31
- package/templates/monorepo-starter/packages/templates/src/email/service/accountSuspended.tsx +0 -37
- package/templates/monorepo-starter/packages/templates/src/email/service/index.ts +0 -2
- package/templates/monorepo-starter/packages/templates/src/email/test.tsx +0 -141
- /package/templates/monorepo-starter/{apps/dashboard/src/components/shared/ThemeSwitch.tsx → packages/ui/src/components/theme-toggle.tsx} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="next" />
|
|
2
2
|
/// <reference types="next/image-types/global" />
|
|
3
|
-
import "./.next/types/routes.d.ts";
|
|
3
|
+
import "./.next/dev/types/routes.d.ts";
|
|
4
4
|
|
|
5
5
|
// NOTE: This file should not be edited
|
|
6
6
|
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.
|
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
2
|
"use client";
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
7
|
-
import { useRouter } from "next/navigation";
|
|
8
|
-
import { useEffect, useState } from "react";
|
|
3
|
+
import { cn } from "@workspace/ui/lib/utils";
|
|
4
|
+
import { Button } from "@workspace/ui/components/button";
|
|
5
|
+
import { Card, CardContent } from "@workspace/ui/components/card";
|
|
6
|
+
import { FieldDescription } from "@workspace/ui/components/field";
|
|
9
7
|
import { useForm, useStore } from "@tanstack/react-form";
|
|
8
|
+
import { toast } from "sonner";
|
|
9
|
+
import { Form } from "@workspace/ui/components/form";
|
|
10
|
+
import Link from "next/link";
|
|
10
11
|
import { GalleryVerticalEnd, LoaderCircle } from "lucide-react";
|
|
11
|
-
|
|
12
|
+
import OtpModal, { type OtpMeta } from "@workspace/ui/components/otp-modal";
|
|
13
|
+
import { useEffect, useState } from "react";
|
|
12
14
|
import {
|
|
13
15
|
requestOtp,
|
|
14
16
|
resetPassword,
|
|
@@ -16,22 +18,16 @@ import {
|
|
|
16
18
|
signUp,
|
|
17
19
|
validateOtp,
|
|
18
20
|
} from "@workspace/sdk/auth";
|
|
19
|
-
|
|
21
|
+
import SocialAuthField from "./SocialAuthField";
|
|
22
|
+
import { useRouter } from "next/navigation";
|
|
23
|
+
import { InputField } from "@workspace/ui/components/input-field";
|
|
24
|
+
import z from "zod";
|
|
20
25
|
import {
|
|
21
26
|
nameSchema,
|
|
22
27
|
passwordSchema,
|
|
23
28
|
identifierSchema,
|
|
24
29
|
} from "@workspace/contracts";
|
|
25
|
-
|
|
26
|
-
import { cn } from "@workspace/ui/lib/utils";
|
|
27
|
-
import { Form } from "@workspace/ui/components/form";
|
|
28
|
-
import { Button } from "@workspace/ui/components/button";
|
|
29
|
-
import { Card, CardContent } from "@workspace/ui/components/card";
|
|
30
|
-
import { FieldDescription } from "@workspace/ui/components/field";
|
|
31
|
-
import { InputField } from "@workspace/ui/components/input-field";
|
|
32
|
-
import OtpModal, { type OtpMeta } from "@workspace/ui/components/otp-modal";
|
|
33
|
-
|
|
34
|
-
import SocialAuthField from "./SocialAuthField";
|
|
30
|
+
import Image from "next/image";
|
|
35
31
|
|
|
36
32
|
interface AuthFormProps {
|
|
37
33
|
formType: AuthFormType;
|
|
@@ -79,7 +75,7 @@ function AuthForm({ className, formType, queryParams }: AuthFormProps) {
|
|
|
79
75
|
try {
|
|
80
76
|
let message = `${formType} successfully!`;
|
|
81
77
|
if (formType === "sign-up") {
|
|
82
|
-
setOtpPurpose("
|
|
78
|
+
setOtpPurpose("verifyIdentifier");
|
|
83
79
|
const res = await signUp(value);
|
|
84
80
|
message = res.message;
|
|
85
81
|
setRedirectUrl("/auth/sign-in");
|
|
@@ -89,15 +85,13 @@ function AuthForm({ className, formType, queryParams }: AuthFormProps) {
|
|
|
89
85
|
message = res.message;
|
|
90
86
|
setRedirectUrl("/dashboard");
|
|
91
87
|
if (res.action === "verifyMfa") {
|
|
92
|
-
setOtpPurpose("
|
|
88
|
+
setOtpPurpose("verifyMfa");
|
|
93
89
|
setIsOpen(true);
|
|
94
90
|
}
|
|
95
91
|
} else if (formType.includes("password")) {
|
|
96
92
|
if (!otpMeta?.token) {
|
|
97
93
|
const nextPurpose: OtpPurpose =
|
|
98
|
-
formType === "set-password"
|
|
99
|
-
? "authSetPassword"
|
|
100
|
-
: "authResetPassword";
|
|
94
|
+
formType === "set-password" ? "setPassword" : "resetPassword";
|
|
101
95
|
setOtpPurpose(nextPurpose);
|
|
102
96
|
const res = await requestOtp({ identifier, purpose: nextPurpose });
|
|
103
97
|
message = res.message;
|
|
@@ -117,7 +111,7 @@ function AuthForm({ className, formType, queryParams }: AuthFormProps) {
|
|
|
117
111
|
} catch (err: any) {
|
|
118
112
|
console.log("err ......", err);
|
|
119
113
|
if (err.action === "verifyIdentifier") {
|
|
120
|
-
setOtpPurpose("
|
|
114
|
+
setOtpPurpose("verifyIdentifier");
|
|
121
115
|
setRedirectUrl("/auth/sign-in");
|
|
122
116
|
setIsOpen(true);
|
|
123
117
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Separator } from "@workspace/ui/components/separator";
|
|
2
2
|
import { SidebarTrigger } from "@workspace/ui/components/sidebar";
|
|
3
|
-
import ThemeSwitch from "
|
|
3
|
+
import ThemeSwitch from "@workspace/ui/components/theme-toggle";
|
|
4
4
|
|
|
5
5
|
const Header = () => {
|
|
6
6
|
return (
|
|
@@ -41,7 +41,7 @@ function VerifyAuthPage({
|
|
|
41
41
|
const verify = async () => {
|
|
42
42
|
try {
|
|
43
43
|
const isUpdateIdentifier =
|
|
44
|
-
purpose === "
|
|
44
|
+
purpose === "updateIdentifier" && newIdentifier;
|
|
45
45
|
|
|
46
46
|
const res = isUpdateIdentifier
|
|
47
47
|
? await verifyUpdateIdentifier({
|
package/templates/monorepo-starter/apps/dashboard/src/components/user/UserAccountSection.tsx
CHANGED
|
@@ -1,41 +1,33 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
2
2
|
"use client";
|
|
3
3
|
|
|
4
|
-
import
|
|
4
|
+
import { useForm } from "@tanstack/react-form";
|
|
5
5
|
import { toast } from "sonner";
|
|
6
6
|
import { useEffect, useState } from "react";
|
|
7
|
-
import { useForm } from "@tanstack/react-form";
|
|
8
7
|
import { Mail, Shield, Phone, Smartphone, Loader2 } from "lucide-react";
|
|
9
|
-
|
|
10
|
-
import {
|
|
11
|
-
identifierSchema,
|
|
12
|
-
passwordSchema,
|
|
13
|
-
MfaMethodEnum,
|
|
14
|
-
} from "@workspace/contracts";
|
|
15
|
-
|
|
8
|
+
import z from "zod";
|
|
9
|
+
import { identifierSchema, passwordSchema } from "@workspace/contracts";
|
|
16
10
|
import {
|
|
17
11
|
requestOtp,
|
|
18
12
|
resetPassword,
|
|
19
13
|
requestUpdateIdentifier,
|
|
20
14
|
updateMfa,
|
|
21
15
|
} from "@workspace/sdk/auth";
|
|
22
|
-
|
|
16
|
+
import { Form } from "@workspace/ui/components/form";
|
|
23
17
|
import {
|
|
24
18
|
Card,
|
|
25
19
|
CardContent,
|
|
26
20
|
CardHeader,
|
|
27
21
|
CardTitle,
|
|
28
22
|
} from "@workspace/ui/components/card";
|
|
29
|
-
import { Form } from "@workspace/ui/components/form";
|
|
30
|
-
|
|
31
23
|
import { Button } from "@workspace/ui/components/button";
|
|
32
|
-
import { Badge } from "@workspace/ui/components/badge";
|
|
33
24
|
import { InputField } from "@workspace/ui/components/input-field";
|
|
34
|
-
import { SelectField } from "@workspace/ui/components/select-field";
|
|
35
25
|
import OtpModal, { type OtpMeta } from "@workspace/ui/components/otp-modal";
|
|
36
|
-
|
|
37
|
-
import
|
|
26
|
+
import { SelectField } from "@workspace/ui/components/select-field";
|
|
27
|
+
import { MfaMethodEnum } from "@workspace/contracts";
|
|
28
|
+
import { Badge } from "@workspace/ui/components/badge";
|
|
38
29
|
import useUser from "@/hooks/user";
|
|
30
|
+
import UserSessions from "./UserSessions";
|
|
39
31
|
|
|
40
32
|
type IdentifierType = "email" | "phone";
|
|
41
33
|
|
|
@@ -56,7 +48,7 @@ const AccountSection = ({ user }: AccountSectionProps) => {
|
|
|
56
48
|
|
|
57
49
|
const schema = z.object({
|
|
58
50
|
newIdentifier:
|
|
59
|
-
otpPurpose === "
|
|
51
|
+
otpPurpose === "updateIdentifier"
|
|
60
52
|
? identifierSchema
|
|
61
53
|
: z.string().optional(),
|
|
62
54
|
newPassword: otpPurpose?.includes("Password")
|
|
@@ -66,12 +58,12 @@ const AccountSection = ({ user }: AccountSectionProps) => {
|
|
|
66
58
|
? passwordSchema
|
|
67
59
|
: z.string().optional(),
|
|
68
60
|
preferredMfa:
|
|
69
|
-
otpPurpose === "
|
|
61
|
+
otpPurpose === "updateMfa" ? MfaMethodEnum : MfaMethodEnum.optional(),
|
|
70
62
|
});
|
|
71
63
|
|
|
72
64
|
const form = useForm({
|
|
73
65
|
defaultValues: {
|
|
74
|
-
newIdentifier: otpPurpose === "
|
|
66
|
+
newIdentifier: otpPurpose === "updateIdentifier" ? "" : undefined,
|
|
75
67
|
newPassword: otpPurpose?.includes("Password") ? "" : undefined,
|
|
76
68
|
confirmPassword: otpPurpose?.includes("Password") ? "" : undefined,
|
|
77
69
|
preferredMfa: user.preferredMfa ?? "email",
|
|
@@ -85,7 +77,7 @@ const AccountSection = ({ user }: AccountSectionProps) => {
|
|
|
85
77
|
setIsLoading(true);
|
|
86
78
|
if (!otpMeta?.token) throw new Error("OTP token is missing");
|
|
87
79
|
|
|
88
|
-
if (otpPurpose === "
|
|
80
|
+
if (otpPurpose === "updateIdentifier") {
|
|
89
81
|
const res = await requestUpdateIdentifier({
|
|
90
82
|
identifier: primaryIdentifier!,
|
|
91
83
|
newIdentifier: value.newIdentifier!,
|
|
@@ -94,7 +86,7 @@ const AccountSection = ({ user }: AccountSectionProps) => {
|
|
|
94
86
|
});
|
|
95
87
|
|
|
96
88
|
message = res.message;
|
|
97
|
-
} else if (otpPurpose === "
|
|
89
|
+
} else if (otpPurpose === "updatePassword") {
|
|
98
90
|
const res = await resetPassword({
|
|
99
91
|
identifier: primaryIdentifier!,
|
|
100
92
|
purpose: otpPurpose,
|
|
@@ -103,7 +95,7 @@ const AccountSection = ({ user }: AccountSectionProps) => {
|
|
|
103
95
|
});
|
|
104
96
|
|
|
105
97
|
message = res.message;
|
|
106
|
-
} else if (otpPurpose === "
|
|
98
|
+
} else if (otpPurpose === "updateMfa") {
|
|
107
99
|
const res = await updateMfa({
|
|
108
100
|
identifier: primaryIdentifier!,
|
|
109
101
|
purpose: otpPurpose,
|
|
@@ -208,7 +200,7 @@ const AccountSection = ({ user }: AccountSectionProps) => {
|
|
|
208
200
|
<Button
|
|
209
201
|
variant="secondary"
|
|
210
202
|
size="sm"
|
|
211
|
-
onClick={() => handleOpen("
|
|
203
|
+
onClick={() => handleOpen("updateIdentifier", "email")}
|
|
212
204
|
disabled={isLoading}
|
|
213
205
|
>
|
|
214
206
|
{user.email ? "Change Email" : "Add Email"}
|
|
@@ -216,7 +208,7 @@ const AccountSection = ({ user }: AccountSectionProps) => {
|
|
|
216
208
|
</div>
|
|
217
209
|
|
|
218
210
|
{otpMeta?.valid &&
|
|
219
|
-
otpPurpose === "
|
|
211
|
+
otpPurpose === "updateIdentifier" &&
|
|
220
212
|
identifierType === "email" && (
|
|
221
213
|
<div className="space-y-4 p-4 border rounded-lg bg-muted/50">
|
|
222
214
|
<InputField
|
|
@@ -284,7 +276,7 @@ const AccountSection = ({ user }: AccountSectionProps) => {
|
|
|
284
276
|
<Button
|
|
285
277
|
variant="secondary"
|
|
286
278
|
size="sm"
|
|
287
|
-
onClick={() => handleOpen("
|
|
279
|
+
onClick={() => handleOpen("updateIdentifier", "phone")}
|
|
288
280
|
disabled={isLoading}
|
|
289
281
|
>
|
|
290
282
|
{user.phone ? "Change Phone" : "Add Phone"}
|
|
@@ -292,7 +284,7 @@ const AccountSection = ({ user }: AccountSectionProps) => {
|
|
|
292
284
|
</div>
|
|
293
285
|
|
|
294
286
|
{otpMeta?.valid &&
|
|
295
|
-
otpPurpose === "
|
|
287
|
+
otpPurpose === "updateIdentifier" &&
|
|
296
288
|
identifierType === "phone" && (
|
|
297
289
|
<div className="space-y-4 p-4 border rounded-lg bg-muted/50">
|
|
298
290
|
<InputField
|
|
@@ -384,7 +376,7 @@ const AccountSection = ({ user }: AccountSectionProps) => {
|
|
|
384
376
|
<Button
|
|
385
377
|
size="sm"
|
|
386
378
|
variant="secondary"
|
|
387
|
-
onClick={() => handleOpen("
|
|
379
|
+
onClick={() => handleOpen("updateMfa")}
|
|
388
380
|
>
|
|
389
381
|
Change Method
|
|
390
382
|
</Button>
|
|
@@ -392,7 +384,7 @@ const AccountSection = ({ user }: AccountSectionProps) => {
|
|
|
392
384
|
<Button
|
|
393
385
|
size="sm"
|
|
394
386
|
variant="destructive"
|
|
395
|
-
onClick={() => handleOpen("
|
|
387
|
+
onClick={() => handleOpen("disableMfa")}
|
|
396
388
|
>
|
|
397
389
|
Disable
|
|
398
390
|
</Button>
|
|
@@ -401,7 +393,7 @@ const AccountSection = ({ user }: AccountSectionProps) => {
|
|
|
401
393
|
<Button
|
|
402
394
|
size="sm"
|
|
403
395
|
variant="secondary"
|
|
404
|
-
onClick={() => handleOpen("
|
|
396
|
+
onClick={() => handleOpen("enableMfa")}
|
|
405
397
|
disabled={isLoading}
|
|
406
398
|
>
|
|
407
399
|
Enable MFA
|
|
@@ -410,7 +402,7 @@ const AccountSection = ({ user }: AccountSectionProps) => {
|
|
|
410
402
|
</div>
|
|
411
403
|
</div>
|
|
412
404
|
|
|
413
|
-
{otpMeta?.valid && otpPurpose === "
|
|
405
|
+
{otpMeta?.valid && otpPurpose === "updateMfa" && (
|
|
414
406
|
<div className="space-y-4 p-4 border rounded-lg">
|
|
415
407
|
<SelectField
|
|
416
408
|
form={form}
|
|
@@ -454,14 +446,14 @@ const AccountSection = ({ user }: AccountSectionProps) => {
|
|
|
454
446
|
<Button
|
|
455
447
|
variant="secondary"
|
|
456
448
|
size="sm"
|
|
457
|
-
onClick={() => handleOpen("
|
|
449
|
+
onClick={() => handleOpen("updatePassword")}
|
|
458
450
|
disabled={isLoading}
|
|
459
451
|
>
|
|
460
452
|
Change Password
|
|
461
453
|
</Button>
|
|
462
454
|
</div>
|
|
463
455
|
|
|
464
|
-
{otpMeta?.valid && otpPurpose === "
|
|
456
|
+
{otpMeta?.valid && otpPurpose === "updatePassword" && (
|
|
465
457
|
<div className="space-y-4 p-4 border rounded-lg">
|
|
466
458
|
<InputField
|
|
467
459
|
form={form}
|
|
@@ -22,6 +22,18 @@
|
|
|
22
22
|
"import": "./dist/admin.js",
|
|
23
23
|
"types": "./dist/admin.d.ts"
|
|
24
24
|
},
|
|
25
|
+
"./business": {
|
|
26
|
+
"import": "./dist/business.js",
|
|
27
|
+
"types": "./dist/business.d.ts"
|
|
28
|
+
},
|
|
29
|
+
"./contact": {
|
|
30
|
+
"import": "./dist/contact.js",
|
|
31
|
+
"types": "./dist/contact.d.ts"
|
|
32
|
+
},
|
|
33
|
+
"./newsletter": {
|
|
34
|
+
"import": "./dist/newsletter.js",
|
|
35
|
+
"types": "./dist/newsletter.d.ts"
|
|
36
|
+
},
|
|
25
37
|
"./user": {
|
|
26
38
|
"import": "./dist/user.js",
|
|
27
39
|
"types": "./dist/user.d.ts"
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import z from "zod";
|
|
2
|
+
import { emailSchema, phoneSchema, idSchema } from "../lib/schema";
|
|
3
|
+
|
|
4
|
+
export const businessProfileSchema = z.object({
|
|
5
|
+
name: z.string().min(1),
|
|
6
|
+
legalName: z.string(),
|
|
7
|
+
slug: z.string().min(1),
|
|
8
|
+
description: z.string(),
|
|
9
|
+
|
|
10
|
+
logoId: idSchema,
|
|
11
|
+
coverImageId: idSchema.optional(),
|
|
12
|
+
|
|
13
|
+
email: emailSchema,
|
|
14
|
+
phone: phoneSchema,
|
|
15
|
+
website: z.url(),
|
|
16
|
+
|
|
17
|
+
tiktok: z.url().optional(),
|
|
18
|
+
facebook: z.url().optional(),
|
|
19
|
+
instagram: z.url().optional(),
|
|
20
|
+
twitter: z.url().optional(),
|
|
21
|
+
linkedin: z.url().optional(),
|
|
22
|
+
youtube: z.url().optional(),
|
|
23
|
+
|
|
24
|
+
address: z.string(),
|
|
25
|
+
city: z.string(),
|
|
26
|
+
state: z.string(),
|
|
27
|
+
country: z.string(),
|
|
28
|
+
postalCode: z.string(),
|
|
29
|
+
|
|
30
|
+
metaTitle: z.string(),
|
|
31
|
+
metaDescription: z.string(),
|
|
32
|
+
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type z from "zod";
|
|
2
|
+
import type { businessProfileSchema } from "./schema";
|
|
3
|
+
import { type BusinessProfile } from "../lib/prisma";
|
|
4
|
+
|
|
5
|
+
declare global {
|
|
6
|
+
type BusinessProfileType = z.input<typeof businessProfileSchema>;
|
|
7
|
+
type BusinessProfileDto = z.output<typeof businessProfileSchema>;
|
|
8
|
+
|
|
9
|
+
interface BusinessProfileResponse extends Sanitize<BusinessProfile> {
|
|
10
|
+
logo?: MediaResponse;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { createZodDto } from "nestjs-zod";
|
|
2
|
+
import {
|
|
3
|
+
createContactMessageSchema,
|
|
4
|
+
updateContactMessageSchema,
|
|
5
|
+
contactMessageQuerySchema,
|
|
6
|
+
} from "./schema";
|
|
7
|
+
|
|
8
|
+
export class CreateContactMessageDto extends createZodDto(
|
|
9
|
+
createContactMessageSchema,
|
|
10
|
+
) {}
|
|
11
|
+
|
|
12
|
+
export class UpdateContactMessageDto extends createZodDto(
|
|
13
|
+
updateContactMessageSchema,
|
|
14
|
+
) {}
|
|
15
|
+
|
|
16
|
+
export class ContactMessageQueryDto extends createZodDto(
|
|
17
|
+
contactMessageQuerySchema,
|
|
18
|
+
) {}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import z from "zod";
|
|
2
|
+
import {
|
|
3
|
+
baseQuerySchema,
|
|
4
|
+
emailSchema,
|
|
5
|
+
isoDateSchema,
|
|
6
|
+
nameSchema,
|
|
7
|
+
phoneSchema,
|
|
8
|
+
} from "../lib/schema";
|
|
9
|
+
import {
|
|
10
|
+
ContactMessageSearchByEnum,
|
|
11
|
+
ContactMessageSortByEnum,
|
|
12
|
+
ContactMessageStatusEnum,
|
|
13
|
+
} from "../lib/enums";
|
|
14
|
+
|
|
15
|
+
export const createContactMessageSchema = z.object({
|
|
16
|
+
firstName: nameSchema,
|
|
17
|
+
lastName: nameSchema.optional(),
|
|
18
|
+
email: emailSchema,
|
|
19
|
+
phone: phoneSchema,
|
|
20
|
+
subject: z.string().optional(),
|
|
21
|
+
message: z.string(),
|
|
22
|
+
source: z.string().optional(),
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
export const updateContactMessageSchema = z.object({
|
|
26
|
+
replyNotes: z.string().optional(),
|
|
27
|
+
status: ContactMessageStatusEnum,
|
|
28
|
+
repliedAt: isoDateSchema,
|
|
29
|
+
});
|
|
30
|
+
|
|
31
|
+
export const contactMessageQuerySchema = baseQuerySchema(
|
|
32
|
+
ContactMessageSortByEnum,
|
|
33
|
+
ContactMessageSearchByEnum,
|
|
34
|
+
).extend({
|
|
35
|
+
status: ContactMessageStatusEnum.optional(),
|
|
36
|
+
});
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type z from "zod";
|
|
2
|
+
import type {
|
|
3
|
+
createContactMessageSchema,
|
|
4
|
+
updateContactMessageSchema,
|
|
5
|
+
contactMessageQuerySchema,
|
|
6
|
+
} from "./schema";
|
|
7
|
+
import { type ContactMessage } from "../lib/prisma";
|
|
8
|
+
|
|
9
|
+
declare global {
|
|
10
|
+
type CreateContactMessageType = z.input<typeof createContactMessageSchema>;
|
|
11
|
+
type CreateContactMessageDto = z.output<typeof createContactMessageSchema>;
|
|
12
|
+
|
|
13
|
+
type UpdateContactMessageType = z.input<typeof updateContactMessageSchema>;
|
|
14
|
+
type UpdateContactMessageDto = z.output<typeof updateContactMessageSchema>;
|
|
15
|
+
|
|
16
|
+
type ContactMessageQueryType = z.input<typeof contactMessageQuerySchema>;
|
|
17
|
+
type ContactMessageQueryDto = z.output<typeof contactMessageQuerySchema>;
|
|
18
|
+
|
|
19
|
+
interface ContactMessageResponse extends Sanitize<ContactMessage> {
|
|
20
|
+
repliedBy?: BaseUserResponse;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
interface ContactMessageQueryResponse extends BaseQueryResponse {
|
|
24
|
+
messages: ContactMessageResponse[];
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export {};
|
|
@@ -22,6 +22,8 @@ export const NotificationPurposeEnum = z.enum($Enums.NotificationPurpose);
|
|
|
22
22
|
export const NotificationStatusEnum = z.enum($Enums.NotificationStatus);
|
|
23
23
|
export const NotificationPriorityEnum = z.enum($Enums.NotificationPriority);
|
|
24
24
|
|
|
25
|
+
export const ContactMessageStatusEnum = z.enum($Enums.ContactMessageStatus);
|
|
26
|
+
|
|
25
27
|
/* =========================
|
|
26
28
|
SHARED - VARIABLES
|
|
27
29
|
========================= */
|
|
@@ -53,3 +55,38 @@ export const MediaVisibilityEnum = z.enum($Enums.MediaVisibility);
|
|
|
53
55
|
|
|
54
56
|
export const MediaSearchByEnum = z.enum(["id", "title"]);
|
|
55
57
|
export const MediaSortByEnum = z.enum(["size", "title", "type"]);
|
|
58
|
+
|
|
59
|
+
/* =========================
|
|
60
|
+
CONTACT MESSAGE
|
|
61
|
+
========================= */
|
|
62
|
+
export const ContactMessageSortByEnum = z.enum([
|
|
63
|
+
"name",
|
|
64
|
+
"email",
|
|
65
|
+
"phone",
|
|
66
|
+
"subject",
|
|
67
|
+
"repliedAt",
|
|
68
|
+
]);
|
|
69
|
+
|
|
70
|
+
export const ContactMessageSearchByEnum = z.enum([
|
|
71
|
+
"name",
|
|
72
|
+
"email",
|
|
73
|
+
"phone",
|
|
74
|
+
"subject",
|
|
75
|
+
"source",
|
|
76
|
+
]);
|
|
77
|
+
|
|
78
|
+
/* =========================
|
|
79
|
+
NEWSLETTER SUBSCRIBER
|
|
80
|
+
========================= */
|
|
81
|
+
export const NewsletterSubscriberSortByEnum = z.enum([
|
|
82
|
+
"name",
|
|
83
|
+
"email",
|
|
84
|
+
"subscribedAt",
|
|
85
|
+
"unsubscribedAt",
|
|
86
|
+
]);
|
|
87
|
+
|
|
88
|
+
export const NewsletterSubscriberSearchByEnum = z.enum([
|
|
89
|
+
"name",
|
|
90
|
+
"email",
|
|
91
|
+
"source",
|
|
92
|
+
]);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
2
|
import * as enums from "./enums";
|
|
3
3
|
import React from "react";
|
|
4
|
-
import {
|
|
4
|
+
import { Prisma } from "../lib/prisma";
|
|
5
5
|
|
|
6
6
|
/* ======================================================
|
|
7
7
|
GLOBAL DECLARATIONS
|
|
@@ -13,7 +13,7 @@ declare global {
|
|
|
13
13
|
-------------------- */
|
|
14
14
|
|
|
15
15
|
type Nullable<T> = T | null;
|
|
16
|
-
type DecimalInstance = InstanceType<typeof Decimal>;
|
|
16
|
+
type DecimalInstance = InstanceType<typeof Prisma.Decimal>;
|
|
17
17
|
type StrictOmit<T, K extends keyof T> = Omit<T, K>;
|
|
18
18
|
type Optional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;
|
|
19
19
|
type ArrayItem<T> = T extends any[] ? T[number] : never;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { createZodDto } from "nestjs-zod";
|
|
2
|
+
import {
|
|
3
|
+
newsletterSubscriberSchema,
|
|
4
|
+
newsletterUnSubscriberSchema,
|
|
5
|
+
newsletterSubscriberQuerySchema,
|
|
6
|
+
} from "./schema";
|
|
7
|
+
|
|
8
|
+
export class NewsletterSubscriberDto extends createZodDto(
|
|
9
|
+
newsletterSubscriberSchema,
|
|
10
|
+
) {}
|
|
11
|
+
|
|
12
|
+
export class NewsletterUnSubscriberDto extends createZodDto(
|
|
13
|
+
newsletterUnSubscriberSchema,
|
|
14
|
+
) {}
|
|
15
|
+
|
|
16
|
+
export class NewsletterSubscriberQueryDto extends createZodDto(
|
|
17
|
+
newsletterSubscriberQuerySchema,
|
|
18
|
+
) {}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import z from "zod";
|
|
2
|
+
import {
|
|
3
|
+
NewsletterSubscriberSearchByEnum,
|
|
4
|
+
NewsletterSubscriberSortByEnum,
|
|
5
|
+
} from "../lib/enums";
|
|
6
|
+
import { nameSchema, emailSchema, baseQuerySchema } from "../lib/schema";
|
|
7
|
+
|
|
8
|
+
export const newsletterSubscriberSchema = z.object({
|
|
9
|
+
name: nameSchema,
|
|
10
|
+
email: emailSchema,
|
|
11
|
+
source: z.string(),
|
|
12
|
+
});
|
|
13
|
+
|
|
14
|
+
export const newsletterUnSubscriberSchema = z.object({
|
|
15
|
+
email: emailSchema,
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
export const newsletterSubscriberQuerySchema = baseQuerySchema(
|
|
19
|
+
NewsletterSubscriberSortByEnum,
|
|
20
|
+
NewsletterSubscriberSearchByEnum,
|
|
21
|
+
).extend({
|
|
22
|
+
isActive: z.boolean().optional(),
|
|
23
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type z from "zod";
|
|
2
|
+
import type {
|
|
3
|
+
newsletterSubscriberSchema,
|
|
4
|
+
newsletterUnSubscriberSchema,
|
|
5
|
+
newsletterSubscriberQuerySchema,
|
|
6
|
+
} from "./schema";
|
|
7
|
+
import { type NewsletterSubscriber } from "../lib/prisma";
|
|
8
|
+
|
|
9
|
+
declare global {
|
|
10
|
+
type NewsletterSubscriberType = z.input<typeof newsletterSubscriberSchema>;
|
|
11
|
+
type NewsletterSubscriberDto = z.output<typeof newsletterSubscriberSchema>;
|
|
12
|
+
|
|
13
|
+
type NewsletterUnSubscriberType = z.input<
|
|
14
|
+
typeof newsletterUnSubscriberSchema
|
|
15
|
+
>;
|
|
16
|
+
type NewsletterUnSubscriberDto = z.output<
|
|
17
|
+
typeof newsletterUnSubscriberSchema
|
|
18
|
+
>;
|
|
19
|
+
|
|
20
|
+
type NewsletterSubscriberQueryType = z.input<
|
|
21
|
+
typeof newsletterSubscriberQuerySchema
|
|
22
|
+
>;
|
|
23
|
+
type NewsletterSubscriberQueryDto = z.output<
|
|
24
|
+
typeof newsletterSubscriberQuerySchema
|
|
25
|
+
>;
|
|
26
|
+
|
|
27
|
+
type NewsletterSubscriberResponse = Sanitize<NewsletterSubscriber>;
|
|
28
|
+
|
|
29
|
+
interface NewsletterSubscriberQueryResponse extends BaseQueryResponse {
|
|
30
|
+
users: NewsletterSubscriberResponse[];
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
export {};
|
|
@@ -2,12 +2,15 @@ import { defineConfig } from "tsup";
|
|
|
2
2
|
|
|
3
3
|
export default defineConfig({
|
|
4
4
|
entry: {
|
|
5
|
-
index: "src/
|
|
5
|
+
index: "src/index.ts",
|
|
6
6
|
auth: "src/auth/index.ts",
|
|
7
7
|
admin: "src/admin/index.ts",
|
|
8
|
+
business: "src/business/index.ts",
|
|
8
9
|
user: "src/user/index.ts",
|
|
9
10
|
media: "src/media/index.ts",
|
|
10
11
|
notification: "src/notification/index.ts",
|
|
12
|
+
contact: "src/contact/index.ts",
|
|
13
|
+
newsletter: "src/newsletter/index.ts",
|
|
11
14
|
},
|
|
12
15
|
outDir: "dist",
|
|
13
16
|
format: ["esm"],
|