@studiocubics/cms 0.0.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.
- package/.turbo/turbo-build.log +7 -0
- package/CHANGELOG.md +12 -0
- package/README.md +15 -0
- package/eslint.config.js +21 -0
- package/package.json +79 -0
- package/rollup.config.js +48 -0
- package/src/clerk/_index.ts +6 -0
- package/src/clerk/actions/_index.ts +2 -0
- package/src/clerk/actions/invitations.ts +78 -0
- package/src/clerk/actions/systemUsers.ts +94 -0
- package/src/clerk/auth.ts +34 -0
- package/src/clerk/clerk.d.ts +105 -0
- package/src/clerk/hasPermission.ts +96 -0
- package/src/clerk/rbacConfig.ts +68 -0
- package/src/clerk/schemas/_index.ts +1 -0
- package/src/clerk/schemas/invitation.ts +17 -0
- package/src/clerk/schemas/systemUser.ts +16 -0
- package/src/clerk/toClientSafeUser.ts +77 -0
- package/src/constants/_index.ts +2 -0
- package/src/constants/defaults.tsx +62 -0
- package/src/constants/pageLimits.ts +2 -0
- package/src/declaration.d.ts +5 -0
- package/src/index.ts +5 -0
- package/src/providers/CMSRootProviders.tsx +13 -0
- package/src/providers/_index.ts +1 -0
- package/src/routes.d.ts +96 -0
- package/src/ui/Inputs/ThemedMonacoEditor/ThemedMonacoEditor.module.css +4 -0
- package/src/ui/Inputs/ThemedMonacoEditor/ThemedMonacoEditor.tsx +16 -0
- package/src/ui/Inputs/_index.ts +1 -0
- package/src/ui/Layout/CMSSecurityLayout.tsx +27 -0
- package/src/ui/Layout/CMSSidebar/CMSSidebar.tsx +39 -0
- package/src/ui/Layout/CMSSidebar/CMSSidebarBody.tsx +43 -0
- package/src/ui/Layout/CMSSidebar/CMSSidebarFooter/CMSSidebarFooter.module.css +7 -0
- package/src/ui/Layout/CMSSidebar/CMSSidebarFooter/CMSSidebarFooter.tsx +59 -0
- package/src/ui/Layout/CMSSidebar/CMSSidebarHeader/CMSSidebarHeader.module.css +44 -0
- package/src/ui/Layout/CMSSidebar/CMSSidebarHeader/CMSSidebarHeader.tsx +30 -0
- package/src/ui/Layout/CMSSidebar/_index.ts +4 -0
- package/src/ui/Layout/_index.ts +2 -0
- package/src/ui/System/Auth/SignIn/SignIn.module.css +50 -0
- package/src/ui/System/Auth/SignIn/SignIn.tsx +79 -0
- package/src/ui/System/Auth/SignIn/_index.ts +2 -0
- package/src/ui/System/Auth/SignIn/useSignInForm.tsx +42 -0
- package/src/ui/System/Auth/SignUp/SignUp.module.css +48 -0
- package/src/ui/System/Auth/SignUp/SignUp.tsx +138 -0
- package/src/ui/System/Auth/SignUp/_index.ts +2 -0
- package/src/ui/System/Auth/SignUp/useSignUpForm.tsx +54 -0
- package/src/ui/System/Auth/_index.ts +2 -0
- package/src/ui/System/Invitations/InvitationList.tsx +9 -0
- package/src/ui/System/Invitations/InvitationListActions.tsx +167 -0
- package/src/ui/System/Invitations/InvitationListCard.tsx +79 -0
- package/src/ui/System/Invitations/InvitationListPage.tsx +32 -0
- package/src/ui/System/Invitations/InvitationListPagination.tsx +19 -0
- package/src/ui/System/Invitations/_index.ts +5 -0
- package/src/ui/System/Permissions/RoleListCard.tsx +33 -0
- package/src/ui/System/Permissions/RolePermissionsPage.tsx +18 -0
- package/src/ui/System/Permissions/RolePermissionsTable.tsx +36 -0
- package/src/ui/System/Permissions/_index.ts +3 -0
- package/src/ui/System/SystemUser/CurrentSystemUserButton/CurrentSystemUserButton.module.css +5 -0
- package/src/ui/System/SystemUser/CurrentSystemUserButton/CurrentSystemUserButton.tsx +102 -0
- package/src/ui/System/SystemUser/CurrentSystemUserPage.tsx +12 -0
- package/src/ui/System/SystemUser/SystemUserActions.tsx +45 -0
- package/src/ui/System/SystemUser/SystemUserDetails/SystemUserDetails.module.css +6 -0
- package/src/ui/System/SystemUser/SystemUserDetails/SystemUserDetails.tsx +71 -0
- package/src/ui/System/SystemUser/SystemUserDetailsForm/SystemUserDetailsForm.module.css +7 -0
- package/src/ui/System/SystemUser/SystemUserDetailsForm/SystemUserDetailsForm.tsx +114 -0
- package/src/ui/System/SystemUser/SystemUserList.tsx +18 -0
- package/src/ui/System/SystemUser/SystemUserListActions.tsx +17 -0
- package/src/ui/System/SystemUser/SystemUserListCard.tsx +85 -0
- package/src/ui/System/SystemUser/SystemUserListPage.tsx +33 -0
- package/src/ui/System/SystemUser/SystemUserListPagination.tsx +19 -0
- package/src/ui/System/SystemUser/SystemUserPage.tsx +30 -0
- package/src/ui/System/SystemUser/SystemUserPageContent.tsx +54 -0
- package/src/ui/System/SystemUser/SystemUserRole/SystemUserRole.module.css +17 -0
- package/src/ui/System/SystemUser/SystemUserRole/SystemUserRole.tsx +64 -0
- package/src/ui/System/SystemUser/SystemUserRoleForm/SystemUserRoleForm.tsx +51 -0
- package/src/ui/System/SystemUser/SystemUserTimestamps.tsx +56 -0
- package/src/ui/System/SystemUser/_index.ts +14 -0
- package/src/ui/System/WelcomePage/WelcomePage.module.css +18 -0
- package/src/ui/System/WelcomePage/WelcomePage.tsx +43 -0
- package/src/ui/System/_index.ts +6 -0
- package/src/ui/System/types.ts +7 -0
- package/src/ui/_index.ts +3 -0
- package/src/utils/_index.ts +1 -0
- package/src/utils/proxyFunctions.ts +37 -0
- package/tsconfig.json +32 -0
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { SectionWrapper } from "@studiocubics/ui";
|
|
2
|
+
import { SystemUserDetails } from "./SystemUserDetails/SystemUserDetails";
|
|
3
|
+
import { SystemUserRole } from "./SystemUserRole/SystemUserRole";
|
|
4
|
+
import { SystemUserTimestamps } from "./SystemUserTimestamps";
|
|
5
|
+
import Link from "next/link";
|
|
6
|
+
import type { User } from "@clerk/nextjs/server";
|
|
7
|
+
import type { Role } from "../../../clerk/rbacConfig";
|
|
8
|
+
|
|
9
|
+
export function SystemUserPageContent({
|
|
10
|
+
allowEdit,
|
|
11
|
+
user,
|
|
12
|
+
}: {
|
|
13
|
+
allowEdit: boolean;
|
|
14
|
+
user: User;
|
|
15
|
+
}) {
|
|
16
|
+
return (
|
|
17
|
+
<>
|
|
18
|
+
<SectionWrapper title={"Account Details"} noBorders>
|
|
19
|
+
<SystemUserDetails
|
|
20
|
+
editable={allowEdit}
|
|
21
|
+
id={user.id}
|
|
22
|
+
fullName={user.fullName}
|
|
23
|
+
firstName={user.firstName}
|
|
24
|
+
lastName={user.lastName}
|
|
25
|
+
imageUrl={user.imageUrl}
|
|
26
|
+
emailAddress={user.primaryEmailAddress?.emailAddress}
|
|
27
|
+
/>
|
|
28
|
+
</SectionWrapper>
|
|
29
|
+
<SectionWrapper title={"Account Timestamps"}>
|
|
30
|
+
<SystemUserTimestamps
|
|
31
|
+
createdAt={user.createdAt}
|
|
32
|
+
updatedAt={user.updatedAt}
|
|
33
|
+
lastSignInAt={user.lastSignInAt}
|
|
34
|
+
/>
|
|
35
|
+
</SectionWrapper>
|
|
36
|
+
<SectionWrapper title={"Assigned Role"}>
|
|
37
|
+
<SystemUserRole
|
|
38
|
+
role={user.publicMetadata.role as Role}
|
|
39
|
+
editable={allowEdit}
|
|
40
|
+
/>
|
|
41
|
+
</SectionWrapper>
|
|
42
|
+
<SectionWrapper
|
|
43
|
+
title={"Active Sessions"}
|
|
44
|
+
subtitle={
|
|
45
|
+
<p style={{ fontSize: "var(--fs-body2)" }}>
|
|
46
|
+
<Link href={`/dashboard/security/systemUsers/${user.id}/sessions`}>
|
|
47
|
+
View All Sessions
|
|
48
|
+
</Link>
|
|
49
|
+
</p>
|
|
50
|
+
}
|
|
51
|
+
></SectionWrapper>
|
|
52
|
+
</>
|
|
53
|
+
);
|
|
54
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
.root {
|
|
2
|
+
display: flex;
|
|
3
|
+
justify-content: space-between;
|
|
4
|
+
align-items: flex-start;
|
|
5
|
+
width: 100%;
|
|
6
|
+
}
|
|
7
|
+
.main {
|
|
8
|
+
display: flex;
|
|
9
|
+
flex: 1;
|
|
10
|
+
flex-direction: column;
|
|
11
|
+
gap: var(--spacing-gap-2);
|
|
12
|
+
align-items: flex-start;
|
|
13
|
+
p {
|
|
14
|
+
font-size: var(--fs-body2);
|
|
15
|
+
color: var(--color-on-background-faint);
|
|
16
|
+
}
|
|
17
|
+
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { toCapitalised } from "@studiocubics/utils";
|
|
4
|
+
import { Edit, User } from "lucide-react";
|
|
5
|
+
import { Button, Tooltip, TransitionAnimation } from "@studiocubics/ui";
|
|
6
|
+
import Link from "next/link";
|
|
7
|
+
import { useDisclosure } from "@studiocubics/hooks";
|
|
8
|
+
import styles from "./SystemUserRole.module.css";
|
|
9
|
+
import { RBAC_CONFIG, type Role } from "../../../../clerk/rbacConfig";
|
|
10
|
+
import type { Route } from "next";
|
|
11
|
+
import { SystemUserRoleForm } from "../SystemUserRoleForm/SystemUserRoleForm";
|
|
12
|
+
|
|
13
|
+
export interface SystemUserRoleProps {
|
|
14
|
+
role: Role;
|
|
15
|
+
editable?: boolean;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export function SystemUserRole({ role, editable }: SystemUserRoleProps) {
|
|
19
|
+
const roleDetails = RBAC_CONFIG[role];
|
|
20
|
+
const { open, handleOpen, handleClose } = useDisclosure();
|
|
21
|
+
if (!roleDetails) return null;
|
|
22
|
+
|
|
23
|
+
return (
|
|
24
|
+
<>
|
|
25
|
+
<TransitionAnimation
|
|
26
|
+
in={!open}
|
|
27
|
+
transformOrigin={"top"}
|
|
28
|
+
mountOnly
|
|
29
|
+
unmountOnExit
|
|
30
|
+
>
|
|
31
|
+
<div className={styles.root}>
|
|
32
|
+
<div className={styles.main}>
|
|
33
|
+
<Tooltip renderArrow title={"View resource permissions"}>
|
|
34
|
+
<Button
|
|
35
|
+
as={Link}
|
|
36
|
+
variant="contained"
|
|
37
|
+
color="primary"
|
|
38
|
+
startIcon={<User size={16} />}
|
|
39
|
+
size="sm"
|
|
40
|
+
href={`/dashboard/security/permissions/${role}` as Route}
|
|
41
|
+
>
|
|
42
|
+
{toCapitalised(role)}
|
|
43
|
+
</Button>
|
|
44
|
+
</Tooltip>
|
|
45
|
+
<p>{roleDetails.desc}</p>
|
|
46
|
+
</div>
|
|
47
|
+
{editable && (
|
|
48
|
+
<Button size="sm" startIcon={<Edit />} onClick={handleOpen}>
|
|
49
|
+
Edit Role
|
|
50
|
+
</Button>
|
|
51
|
+
)}
|
|
52
|
+
</div>
|
|
53
|
+
</TransitionAnimation>
|
|
54
|
+
<TransitionAnimation
|
|
55
|
+
in={open}
|
|
56
|
+
transformOrigin={"top right"}
|
|
57
|
+
mountOnly
|
|
58
|
+
unmountOnExit
|
|
59
|
+
>
|
|
60
|
+
<SystemUserRoleForm role={role} onClose={handleClose} />
|
|
61
|
+
</TransitionAnimation>
|
|
62
|
+
</>
|
|
63
|
+
);
|
|
64
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
type CardProps,
|
|
5
|
+
Card,
|
|
6
|
+
ConfirmationForm,
|
|
7
|
+
Select,
|
|
8
|
+
} from "@studiocubics/ui";
|
|
9
|
+
import { initialiseForm, toCapitalised } from "@studiocubics/utils";
|
|
10
|
+
import { type Role, roles } from "../../../../clerk/rbacConfig";
|
|
11
|
+
import { useActionState } from "react";
|
|
12
|
+
import { systemUserRoleUpdateAction } from "../../../../clerk/_index";
|
|
13
|
+
|
|
14
|
+
const initialSystemUserRoleUpdateState = initialiseForm("role");
|
|
15
|
+
|
|
16
|
+
export type SystemUserRoleUpdateState = typeof initialSystemUserRoleUpdateState;
|
|
17
|
+
|
|
18
|
+
export function SystemUserRoleForm({
|
|
19
|
+
role,
|
|
20
|
+
onClose,
|
|
21
|
+
...rest
|
|
22
|
+
}: { role: Role; onClose(): void } & CardProps) {
|
|
23
|
+
const [state, action, pending] = useActionState(
|
|
24
|
+
systemUserRoleUpdateAction.bind(null, "hello"),
|
|
25
|
+
initialSystemUserRoleUpdateState,
|
|
26
|
+
);
|
|
27
|
+
return (
|
|
28
|
+
<Card {...rest} fullWidth>
|
|
29
|
+
<ConfirmationForm
|
|
30
|
+
variant="danger"
|
|
31
|
+
confirmText="Change Role"
|
|
32
|
+
action={action}
|
|
33
|
+
formTitle="Edit Role"
|
|
34
|
+
onCancel={onClose}
|
|
35
|
+
>
|
|
36
|
+
<Select
|
|
37
|
+
label="Current role"
|
|
38
|
+
error={state.fieldErrors?.role}
|
|
39
|
+
defaultValue={role}
|
|
40
|
+
disabled={pending}
|
|
41
|
+
>
|
|
42
|
+
{roles.map((r) => (
|
|
43
|
+
<option key={r} value={r}>
|
|
44
|
+
{toCapitalised(r)}
|
|
45
|
+
</option>
|
|
46
|
+
))}
|
|
47
|
+
</Select>
|
|
48
|
+
</ConfirmationForm>
|
|
49
|
+
</Card>
|
|
50
|
+
);
|
|
51
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
|
|
3
|
+
import { useUser } from "@clerk/nextjs";
|
|
4
|
+
import type { User } from "@clerk/nextjs/server";
|
|
5
|
+
import { LabeledValue, Skeleton } from "@studiocubics/ui";
|
|
6
|
+
|
|
7
|
+
export function CurrentSystemUserTimestamps() {
|
|
8
|
+
const { user, isLoaded } = useUser();
|
|
9
|
+
// if (!user) return null;
|
|
10
|
+
return (
|
|
11
|
+
<SystemUserTimestamps
|
|
12
|
+
isLoaded={isLoaded}
|
|
13
|
+
createdAt={user?.createdAt}
|
|
14
|
+
updatedAt={user?.updatedAt}
|
|
15
|
+
lastSignInAt={user?.lastSignInAt}
|
|
16
|
+
/>
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
export interface SystemUserTimestampsProps {
|
|
20
|
+
createdAt?: User["createdAt"] | NonNullable<ClerkClientUser>["createdAt"];
|
|
21
|
+
updatedAt?: User["updatedAt"] | NonNullable<ClerkClientUser>["updatedAt"];
|
|
22
|
+
lastSignInAt?:
|
|
23
|
+
| User["lastSignInAt"]
|
|
24
|
+
| NonNullable<ClerkClientUser>["lastSignInAt"];
|
|
25
|
+
isLoaded?: boolean;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export function SystemUserTimestamps(props: SystemUserTimestampsProps) {
|
|
29
|
+
const { createdAt, updatedAt, lastSignInAt, isLoaded = true } = props;
|
|
30
|
+
const timestamps = [
|
|
31
|
+
{ stamp: "Created at", time: createdAt },
|
|
32
|
+
{ stamp: "Updated", time: updatedAt },
|
|
33
|
+
{ stamp: "Last Sign in", time: lastSignInAt },
|
|
34
|
+
];
|
|
35
|
+
|
|
36
|
+
return timestamps.map((timestamp) => {
|
|
37
|
+
let timestampTime =
|
|
38
|
+
timestamp.time && typeof timestamp.time == "number"
|
|
39
|
+
? new Date(timestamp.time)
|
|
40
|
+
: timestamp.time;
|
|
41
|
+
|
|
42
|
+
return (
|
|
43
|
+
<LabeledValue key={timestamp.stamp} label={timestamp.stamp}>
|
|
44
|
+
{isLoaded ? (
|
|
45
|
+
!timestamp.time ? (
|
|
46
|
+
"-"
|
|
47
|
+
) : (
|
|
48
|
+
timestampTime?.toLocaleString()
|
|
49
|
+
)
|
|
50
|
+
) : (
|
|
51
|
+
<Skeleton width={150} height={24} />
|
|
52
|
+
)}
|
|
53
|
+
</LabeledValue>
|
|
54
|
+
);
|
|
55
|
+
});
|
|
56
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export * from "./CurrentSystemUserButton/CurrentSystemUserButton";
|
|
2
|
+
export * from "./CurrentSystemUserPage";
|
|
3
|
+
export * from "./SystemUserActions";
|
|
4
|
+
export * from "./SystemUserDetails/SystemUserDetails";
|
|
5
|
+
export * from "./SystemUserDetailsForm/SystemUserDetailsForm";
|
|
6
|
+
export * from "./SystemUserList";
|
|
7
|
+
export * from "./SystemUserListActions";
|
|
8
|
+
export * from "./SystemUserListCard";
|
|
9
|
+
export * from "./SystemUserListPage";
|
|
10
|
+
export * from "./SystemUserListPagination";
|
|
11
|
+
export * from "./SystemUserPage";
|
|
12
|
+
export * from "./SystemUserPageContent";
|
|
13
|
+
export * from "./SystemUserRole/SystemUserRole";
|
|
14
|
+
export * from "./SystemUserTimestamps";
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
.root {
|
|
2
|
+
display: flex;
|
|
3
|
+
flex-direction: column;
|
|
4
|
+
justify-content: center;
|
|
5
|
+
align-items: center;
|
|
6
|
+
gap: var(--spacing-gap-4);
|
|
7
|
+
width: 100dvw;
|
|
8
|
+
height: 100dvh;
|
|
9
|
+
}
|
|
10
|
+
.desc {
|
|
11
|
+
max-width: 65ch;
|
|
12
|
+
text-align: center;
|
|
13
|
+
font-size: var(--fs-body);
|
|
14
|
+
color: var(--color-on-background-faint);
|
|
15
|
+
}
|
|
16
|
+
.catcall {
|
|
17
|
+
font-size: var(--fs-body2);
|
|
18
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { Button, CubicsUILogo, PoweredByBanner } from "@studiocubics/ui";
|
|
2
|
+
import styles from "./WelcomePage.module.css";
|
|
3
|
+
import Link from "next/link";
|
|
4
|
+
import { LayoutDashboardIcon, LogIn } from "lucide-react";
|
|
5
|
+
import { auth } from "../../../clerk/auth";
|
|
6
|
+
export async function WelcomePage() {
|
|
7
|
+
const { userId } = await auth();
|
|
8
|
+
const loggedOutUser = (
|
|
9
|
+
<Link href={"/auth/signIn/"}>
|
|
10
|
+
<Button variant="contained" endIcon={<LogIn />}>
|
|
11
|
+
Get Started
|
|
12
|
+
</Button>
|
|
13
|
+
</Link>
|
|
14
|
+
);
|
|
15
|
+
const loggedInUser = (
|
|
16
|
+
<Link href={"/dashboard"}>
|
|
17
|
+
<Button variant="contained" endIcon={<LayoutDashboardIcon />}>
|
|
18
|
+
Go to dashboard
|
|
19
|
+
</Button>
|
|
20
|
+
</Link>
|
|
21
|
+
);
|
|
22
|
+
return (
|
|
23
|
+
<div className={styles.root}>
|
|
24
|
+
<CubicsUILogo width={"10rem"} height={"auto"} onlyFavicon />
|
|
25
|
+
<PoweredByBanner size={"md"} />
|
|
26
|
+
<h2>Welcome to Cubics CMS!</h2>
|
|
27
|
+
<p className={styles.desc}>
|
|
28
|
+
A powerful and intuitive platform to manage your content effortlessly.
|
|
29
|
+
Streamline updates, enhance collaboration, and take full control of your
|
|
30
|
+
digital presence.
|
|
31
|
+
</p>
|
|
32
|
+
{userId ? loggedInUser : loggedOutUser}
|
|
33
|
+
{!userId && (
|
|
34
|
+
<p className={styles.catcall}>
|
|
35
|
+
Dont have an account?
|
|
36
|
+
{/* TODO add request account from admin flow.
|
|
37
|
+
//@ts-ignore */}
|
|
38
|
+
<Link href="/auth/requestAccount">Request from an admin</Link>
|
|
39
|
+
</p>
|
|
40
|
+
)}
|
|
41
|
+
</div>
|
|
42
|
+
);
|
|
43
|
+
}
|
package/src/ui/_index.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from "./proxyFunctions";
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { clerkMiddleware, createRouteMatcher } from "@clerk/nextjs/server";
|
|
2
|
+
import { NextResponse } from "next/server";
|
|
3
|
+
|
|
4
|
+
const isPublicRoute = createRouteMatcher(["/", "/auth(.*)"]);
|
|
5
|
+
|
|
6
|
+
export const cmsMiddleware = clerkMiddleware(async (auth, req) => {
|
|
7
|
+
const { userId, sessionClaims, redirectToSignIn } = await auth();
|
|
8
|
+
|
|
9
|
+
// If the user isn't signed in and the route is private, redirect to sign-in
|
|
10
|
+
if (!userId && !isPublicRoute(req)) {
|
|
11
|
+
return redirectToSignIn({ returnBackUrl: req.url });
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Catch users who do not have `onboardingComplete: true` in their publicMetadata
|
|
15
|
+
// Redirect them to the /auth/onboarding route to complete onboarding
|
|
16
|
+
if (
|
|
17
|
+
userId &&
|
|
18
|
+
!sessionClaims?.metadata?.onboardingComplete &&
|
|
19
|
+
req.nextUrl.pathname !== "/auth/onboarding"
|
|
20
|
+
) {
|
|
21
|
+
const onboardingUrl = new URL("/auth/onboarding", req.url);
|
|
22
|
+
return NextResponse.redirect(onboardingUrl);
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// If the user is logged in and the route is protected, let them view.
|
|
26
|
+
if (userId && !isPublicRoute(req)) {
|
|
27
|
+
return NextResponse.next();
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
export const cmsConfig = {
|
|
31
|
+
matcher: [
|
|
32
|
+
// Skip Next.js internals and all static files, unless found in search params
|
|
33
|
+
"/((?!_next|[^?]*\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)",
|
|
34
|
+
// Always run for API routes
|
|
35
|
+
"/(api|trpc)(.*)",
|
|
36
|
+
],
|
|
37
|
+
};
|
package/tsconfig.json
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
{
|
|
2
|
+
"compilerOptions": {
|
|
3
|
+
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
|
4
|
+
"target": "ES2022",
|
|
5
|
+
"useDefineForClassFields": true,
|
|
6
|
+
"lib": ["ES2022", "DOM", "DOM.Iterable"],
|
|
7
|
+
"module": "ESNext",
|
|
8
|
+
"resolveJsonModule": true,
|
|
9
|
+
"allowJs": true,
|
|
10
|
+
"skipLibCheck": true,
|
|
11
|
+
|
|
12
|
+
/* Bundler mode */
|
|
13
|
+
"moduleResolution": "bundler",
|
|
14
|
+
"verbatimModuleSyntax": true,
|
|
15
|
+
"moduleDetection": "force",
|
|
16
|
+
"noEmit": true,
|
|
17
|
+
"jsx": "react-jsx",
|
|
18
|
+
// Output
|
|
19
|
+
"declaration": true,
|
|
20
|
+
"outDir": "./dist",
|
|
21
|
+
"rootDir": "./src",
|
|
22
|
+
|
|
23
|
+
/* Linting */
|
|
24
|
+
"strict": true,
|
|
25
|
+
"noUnusedLocals": true,
|
|
26
|
+
"noUnusedParameters": true,
|
|
27
|
+
"erasableSyntaxOnly": true,
|
|
28
|
+
"noFallthroughCasesInSwitch": true,
|
|
29
|
+
"noUncheckedSideEffectImports": true
|
|
30
|
+
},
|
|
31
|
+
"include": ["./src", "src/clerk/clerk.d.ts"]
|
|
32
|
+
}
|