Skip to content

Commit

Permalink
🔄 Merge pull request #7 from steeeee0223/feature/worxpace
Browse files Browse the repository at this point in the history
Setup pages
  • Loading branch information
steeeee0223 authored Jan 24, 2024
2 parents 18ed156 + a2c9dda commit 9d9bea2
Show file tree
Hide file tree
Showing 21 changed files with 617 additions and 29 deletions.
9 changes: 9 additions & 0 deletions .env.example
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,12 @@ AUTH_SECRET='supersecret'
# @see https://next-auth.js.org/providers/discord
AUTH_DISCORD_ID=''
AUTH_DISCORD_SECRET=''

# CLERK
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=''
CLERK_SECRET_KEY=''

NEXT_PUBLIC_CLERK_SIGN_IN_URL=/sign-in
NEXT_PUBLIC_CLERK_SIGN_UP_URL=/sign-up
NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL=/
NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL=/
9 changes: 9 additions & 0 deletions apps/worxpace/next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,15 @@ const config = {
/** We already do linting and typechecking as separate tasks in CI */
eslint: { ignoreDuringBuilds: true },
typescript: { ignoreBuildErrors: true },

images: {
remotePatterns: [
{
protocol: "https",
hostname: "img.clerk.com",
},
]
}
};

export default config;
1 change: 1 addition & 0 deletions apps/worxpace/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"@acme/prisma": "workspace:*",
"@acme/ui": "workspace:^0.1.0",
"@acme/validators": "workspace:^0.1.0",
"@clerk/nextjs": "^4.29.4",
"@t3-oss/env-nextjs": "^0.7.1",
"next": "^14.0.4",
"react": "18.2.0",
Expand Down
10 changes: 6 additions & 4 deletions apps/worxpace/src/app/(marketing)/_components/heading.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
"use client";

import Link from "next/link";
import { ArrowRight } from "lucide-react";

import { Button } from "@acme/ui/components";
Expand All @@ -17,10 +18,11 @@ const Heading = () => {
Steeeee WorXpace is the connected workspace where <br />
better, faster work happens.
</h3>

<Button>
Get Started <ArrowRight className={`${theme.size.icon} ml-2`} />
</Button>
<Link href="/select-role">
<Button className="mt-4">
Get Started <ArrowRight className={`${theme.size.icon} ml-2`} />
</Button>
</Link>
</div>
);
};
Expand Down
9 changes: 9 additions & 0 deletions apps/worxpace/src/app/(platform)/(clerk)/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import { PropsWithChildren } from "react";

const ClerkLayout = ({ children }: PropsWithChildren) => {
return (
<div className="flex h-full items-center justify-center">{children}</div>
);
};

export default ClerkLayout;
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { OrganizationList } from "@clerk/nextjs";

export default function Page() {
return (
<OrganizationList
afterSelectPersonalUrl="/personal/:id"
afterSelectOrganizationUrl="/organization/:id"
afterCreateOrganizationUrl="/organization/:id"
/>
);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { SignIn } from "@clerk/nextjs";

export default function Page() {
return <SignIn />;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { SignUp } from "@clerk/nextjs";

export default function Page() {
return <SignUp />;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
interface Params {
params: { role: string; clientId: string };
}

const Client = ({ params: { role, clientId } }: Params) => {
return (
<div>
Client {role} - {clientId}
</div>
);
};

export default Client;
14 changes: 14 additions & 0 deletions apps/worxpace/src/app/(platform)/(tools)/[role]/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import { type PropsWithChildren } from "react";
import { redirect } from "next/navigation";

interface Params extends PropsWithChildren {
params: { role: string };
}

const RoleLayout = ({ children, params: { role } }: Params) => {
if (role !== "admin" && role !== "personal" && role !== "organization")
redirect("/select-role");
return <>{children}</>;
};

export default RoleLayout;
83 changes: 83 additions & 0 deletions apps/worxpace/src/app/(platform)/(tools)/_components/sidebar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/* eslint-disable jsx-a11y/no-static-element-interactions */
/* eslint-disable jsx-a11y/click-events-have-key-events */
/* eslint-disable jsx-a11y/interactive-supports-focus */
"use client";

import { useEffect } from "react";
import { usePathname } from "next/navigation";
import { ChevronsLeft, MenuIcon } from "lucide-react";

import { useNavControl } from "@acme/ui/hooks";
import { cn } from "@acme/ui/lib";

import { theme } from "~/constants/theme";

export const Sidebar = () => {
const pathname = usePathname();
const {
isMobile,
sidebarRef,
navbarRef,
isResetting,
isCollapsed,
handleMouseDown,
collapse,
resetWidth,
} = useNavControl();

useEffect(() => {
isMobile ? collapse() : resetWidth();
}, [isMobile]);

useEffect(() => {
if (isMobile) collapse();
}, [pathname, isMobile]);

return (
<>
<aside
ref={sidebarRef}
className={cn(
"group/sidebar relative z-[99999] flex h-full w-60 flex-col overflow-y-auto bg-secondary",
isResetting && "transition-all duration-300 ease-in-out",
isMobile && "w-0",
)}
>
<div
onClick={collapse}
role="button"
className={cn(
theme.bg.hover,
"absolute right-2 top-3 h-6 w-6 rounded-sm text-muted-foreground opacity-0 transition group-hover/sidebar:opacity-100",
isMobile && "opacity-100",
)}
>
<ChevronsLeft className="h-6 w-6" />
</div>
<div
onMouseDown={handleMouseDown}
onClick={resetWidth}
className="absolute right-0 top-0 h-full w-1 cursor-ew-resize bg-primary/10 opacity-0 transition group-hover/sidebar:opacity-100"
/>
</aside>
<div
ref={navbarRef}
className={cn(
"absolute left-60 top-0 z-[99999] w-[calc(100%-240px)]",
isResetting && "transition-all duration-300 ease-in-out",
isMobile && "left-0 w-full",
)}
>
<nav className="w-full bg-transparent px-3 py-2">
{isCollapsed && (
<MenuIcon
onClick={resetWidth}
role="button"
className="h-6 w-6 text-muted-foreground"
/>
)}
</nav>
</div>
</>
);
};
5 changes: 5 additions & 0 deletions apps/worxpace/src/app/(platform)/(tools)/documents/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
const Documents = () => {
return <div>This is a protected page</div>;
};

export default Documents;
19 changes: 19 additions & 0 deletions apps/worxpace/src/app/(platform)/(tools)/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import { type PropsWithChildren } from "react";
import { redirect } from "next/navigation";
import { auth } from "@clerk/nextjs";

import { Sidebar } from "./_components/sidebar";

const ToolsLayout = ({ children }: PropsWithChildren) => {
const { userId } = auth();
if (!userId) redirect("/select-role");

return (
<div className="flex h-full dark:bg-[#1F1F1F]">
<Sidebar />
<main className="h-full flex-1 overflow-y-auto">{children}</main>
</div>
);
};

export default ToolsLayout;
6 changes: 6 additions & 0 deletions apps/worxpace/src/app/(platform)/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import type { PropsWithChildren } from "react";
import { ClerkProvider } from "@clerk/nextjs";

export default function PlatformLayout({ children }: PropsWithChildren) {
return <ClerkProvider>{children}</ClerkProvider>;
}
18 changes: 16 additions & 2 deletions apps/worxpace/src/env.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,15 +23,29 @@ export const env = createEnv({
* For them to be exposed to the client, prefix them with `NEXT_PUBLIC_`.
*/
client: {
// NEXT_PUBLIC_CLIENTVAR: z.string(),
// CLERK
NEXT_PUBLIC_CLERK_SIGN_IN_URL: z.string().default("/sign-in"),
NEXT_PUBLIC_CLERK_SIGN_UP_URL: z.string().default("/sign-up"),
NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL: z.string().default("/"),
NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL: z.string().default("/"),
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: z.string(),
CLERK_SECRET_KEY: z.string()
},
/**
* Destructure all variables from `process.env` to make sure they aren't tree-shaken away.
*/
runtimeEnv: {
// NEXT
PORT: process.env.PORT,
VERCEL_URL: process.env.VERCEL_URL,
// NEXT_PUBLIC_CLIENTVAR: process.env.NEXT_PUBLIC_CLIENTVAR,
// CLERK
NEXT_PUBLIC_CLERK_SIGN_IN_URL: process.env.NEXT_PUBLIC_CLERK_SIGN_IN_URL,
NEXT_PUBLIC_CLERK_SIGN_UP_URL: process.env.NEXT_PUBLIC_CLERK_SIGN_UP_URL,
NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL: process.env.NEXT_PUBLIC_CLERK_AFTER_SIGN_IN_URL,
NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL: process.env.NEXT_PUBLIC_CLERK_AFTER_SIGN_UP_URL,
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY,
CLERK_SECRET_KEY: process.env.CLERK_SECRET_KEY

},
skipValidation:
!!process.env.CI ||
Expand Down
1 change: 1 addition & 0 deletions apps/worxpace/src/lib/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./utils";
6 changes: 6 additions & 0 deletions apps/worxpace/src/lib/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { auth } from "@clerk/nextjs";

export function isAuthenticated(): boolean {
const { userId } = auth();
return !!userId;
}
27 changes: 27 additions & 0 deletions apps/worxpace/src/middleware.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { NextResponse } from "next/server";
import { authMiddleware, redirectToSignIn } from "@clerk/nextjs";

// This example protects all routes including api/trpc routes
// Please edit this to allow other routes to be public as needed.
// See https://clerk.com/docs/references/nextjs/auth-middleware for more information about configuring your Middleware
export default authMiddleware({
publicRoutes: ["/", "/api/webhook"],
afterAuth(auth, req) {
if (auth.userId && auth.isPublicRoute) {
const path = auth.orgId
? `/organization/${auth.orgId}`
: `/personal/${auth.userId}`;
const orgSelection = new URL(path, req.url);
return NextResponse.redirect(orgSelection);
}

if (!auth.userId && !auth.isPublicRoute) {
// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return redirectToSignIn({ returnBackUrl: req.url });
}
},
});

export const config = {
matcher: ["/((?!.+\\.[\\w]+$|_next).*)", "/", "/(api|trpc)(.*)"],
};
1 change: 1 addition & 0 deletions packages/ui/src/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export * from "./use-action";
export * from "./use-fetch";
export * from "./use-nav-control";
export * from "./use-scroll-top";
Loading

0 comments on commit 9d9bea2

Please sign in to comment.