-
Notifications
You must be signed in to change notification settings - Fork 27
Coming Soon Mode #243
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: dev
Are you sure you want to change the base?
Coming Soon Mode #243
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| import ComingSoon from "@/components/comingSoon"; | ||
|
|
||
| export default function ComingSoonPage() { | ||
| return ( | ||
| <ComingSoon | ||
| title="Coming Soon" | ||
| description="We’re still building this page. Check back soon." | ||
| /> | ||
| ); | ||
| } | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,64 @@ | ||||||||||||||||||||||||||||||||
| import Image from "next/image"; | ||||||||||||||||||||||||||||||||
| import Link from "next/link"; | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| type ComingSoonProps = { | ||||||||||||||||||||||||||||||||
| title?: string; | ||||||||||||||||||||||||||||||||
| description?: string; | ||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| export default function ComingSoon({ | ||||||||||||||||||||||||||||||||
| title = "Coming Soon", | ||||||||||||||||||||||||||||||||
| description = "We’re still building this page. Check back soon.", | ||||||||||||||||||||||||||||||||
| }: ComingSoonProps) { | ||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||
| <main className="relative flex min-h-screen items-center justify-center overflow-hidden bg-black px-6 text-white"> | ||||||||||||||||||||||||||||||||
| <div className="absolute inset-0 bg-[radial-gradient(circle_at_center,rgba(59,130,246,0.16),transparent_32%),linear-gradient(to_bottom,#04070d,#02040a)]" /> | ||||||||||||||||||||||||||||||||
| <div className="absolute inset-0 bg-[linear-gradient(to_right,rgba(255,255,255,0.03)_1px,transparent_1px),linear-gradient(to_bottom,rgba(255,255,255,0.03)_1px,transparent_1px)] bg-[size:72px_72px] opacity-20" /> | ||||||||||||||||||||||||||||||||
| <div className="absolute left-1/2 top-[45%] h-[30rem] w-[30rem] -translate-x-1/2 -translate-y-1/2 rounded-full bg-blue-500/20 blur-[120px]" /> | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| <section className="relative z-10 w-full max-w-4xl"> | ||||||||||||||||||||||||||||||||
| <div className="grid overflow-hidden rounded-3xl border border-white/10 bg-white/5 shadow-[0_20px_80px_rgba(0,0,0,0.45)] backdrop-blur-xl md:grid-cols-[1.05fr_0.95fr]"> | ||||||||||||||||||||||||||||||||
| <div className="relative flex min-h-[420px] flex-col justify-center p-8 md:p-10"> | ||||||||||||||||||||||||||||||||
| <div className="absolute inset-0 bg-[radial-gradient(circle_at_top_left,rgba(255,255,255,0.08),transparent_30%)]" /> | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| <div className="relative z-10"> | ||||||||||||||||||||||||||||||||
| <h1 className="max-w-xl text-6xl font-semibold tracking-tight"> | ||||||||||||||||||||||||||||||||
| {title} | ||||||||||||||||||||||||||||||||
| </h1> | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| <p className="mt-5 max-w-lg text-base leading-7 text-white/65 sm:text-lg"> | ||||||||||||||||||||||||||||||||
| {description} | ||||||||||||||||||||||||||||||||
| </p> | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| <div className="mt-8"> | ||||||||||||||||||||||||||||||||
| <Link | ||||||||||||||||||||||||||||||||
| href="/" | ||||||||||||||||||||||||||||||||
| className="group inline-flex items-center gap-2 rounded-xl border border-white/15 bg-white/5 px-6 py-3 text-sm font-medium text-white backdrop-blur transition-all hover:border-white/25 hover:bg-white/10" | ||||||||||||||||||||||||||||||||
| > | ||||||||||||||||||||||||||||||||
| Back to Home | ||||||||||||||||||||||||||||||||
| </Link> | ||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||
|
Comment on lines
+34
to
+40
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix inconsistent indentation. Lines 35-39 use spaces while the rest of the file uses tabs. This is likely causing the Prettier formatting warning. 🔧 Proposed fix for indentation <div className="mt-8">
<Link
- href="/"
- className="group inline-flex items-center gap-2 rounded-xl border border-white/15 bg-white/5 px-6 py-3 text-sm font-medium text-white backdrop-blur transition-all hover:border-white/25 hover:bg-white/10"
- >
- Back to Home
- </Link>
+ href="/"
+ className="group inline-flex items-center gap-2 rounded-xl border border-white/15 bg-white/5 px-6 py-3 text-sm font-medium text-white backdrop-blur transition-all hover:border-white/25 hover:bg-white/10"
+ >
+ Back to Home
+ </Link>
</div>📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| <div className="relative flex min-h-[320px] flex-col items-center justify-center p-10 md:min-h-[420px]"> | ||||||||||||||||||||||||||||||||
| <div className="absolute h-56 w-56 rounded-full bg-blue-500/25 blur-[90px]" /> | ||||||||||||||||||||||||||||||||
| <div className="relative z-10 flex flex-col items-center text-center"> | ||||||||||||||||||||||||||||||||
| <Image | ||||||||||||||||||||||||||||||||
| src="/img/logo/hackkit.svg" | ||||||||||||||||||||||||||||||||
| alt="HackKit Logo" | ||||||||||||||||||||||||||||||||
| width={110} | ||||||||||||||||||||||||||||||||
| height={110} | ||||||||||||||||||||||||||||||||
| className="opacity-95" | ||||||||||||||||||||||||||||||||
| /> | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| <p className="mt-6 max-w-xs text-sm leading-6 text-white/55"> | ||||||||||||||||||||||||||||||||
| This page is temporarily unavailable while setup is in progress. | ||||||||||||||||||||||||||||||||
| </p> | ||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||
| </div> | ||||||||||||||||||||||||||||||||
| </section> | ||||||||||||||||||||||||||||||||
| </main> | ||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -1,31 +1,42 @@ | ||||||||||||||
| import { createEnv } from "@t3-oss/env-nextjs"; | ||||||||||||||
| import { z } from "zod"; | ||||||||||||||
|
|
||||||||||||||
| const isComingSoonMode = process.env.COMING_SOON_MODE === "true"; | ||||||||||||||
|
|
||||||||||||||
| const requiredWhenLive = <T extends z.ZodTypeAny>(schema: T) => | ||||||||||||||
| isComingSoonMode ? schema.optional() : schema; | ||||||||||||||
|
|
||||||||||||||
| export const env = createEnv({ | ||||||||||||||
| server: { | ||||||||||||||
| CLERK_SECRET_KEY: z.string(), | ||||||||||||||
| INTERNAL_AUTH_KEY: z.string().min(64, { | ||||||||||||||
| message: "INTERNAL_AUTH_KEY must be at least 64 characters", | ||||||||||||||
| }), | ||||||||||||||
| BOT_API_URL: z.string(), | ||||||||||||||
| COMING_SOON_MODE: z.enum(["true", "false"]).default("false"), | ||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This env var is properly validated here but See the related comment in 🤖 Prompt for AI Agents |
||||||||||||||
|
|
||||||||||||||
| CLERK_SECRET_KEY: requiredWhenLive(z.string()), | ||||||||||||||
| INTERNAL_AUTH_KEY: requiredWhenLive( | ||||||||||||||
| z.string().min(64, { | ||||||||||||||
| message: "INTERNAL_AUTH_KEY must be at least 64 characters", | ||||||||||||||
| }), | ||||||||||||||
| ), | ||||||||||||||
| BOT_API_URL: requiredWhenLive(z.string()), | ||||||||||||||
| NODE_ENV: z | ||||||||||||||
| .enum(["development", "test", "production"]) | ||||||||||||||
| .default("development"), | ||||||||||||||
| CLOUDFLARE_ACCOUNT_ID: z.string(), | ||||||||||||||
| R2_ACCESS_KEY_ID: z.string(), | ||||||||||||||
| R2_SECRET_ACCESS_KEY: z.string(), | ||||||||||||||
| TURSO_AUTH_TOKEN: z.string(), | ||||||||||||||
| TURSO_DATABASE_URL: z.string(), | ||||||||||||||
| UPSTASH_REDIS_REST_TOKEN: z.string(), | ||||||||||||||
| UPSTASH_REDIS_REST_URL: z.string(), | ||||||||||||||
| CLOUDFLARE_ACCOUNT_ID: requiredWhenLive(z.string()), | ||||||||||||||
| R2_ACCESS_KEY_ID: requiredWhenLive(z.string()), | ||||||||||||||
| R2_SECRET_ACCESS_KEY: requiredWhenLive(z.string()), | ||||||||||||||
| TURSO_AUTH_TOKEN: requiredWhenLive(z.string()), | ||||||||||||||
| TURSO_DATABASE_URL: requiredWhenLive(z.string()), | ||||||||||||||
| UPSTASH_REDIS_REST_TOKEN: requiredWhenLive(z.string()), | ||||||||||||||
| UPSTASH_REDIS_REST_URL: requiredWhenLive(z.string()), | ||||||||||||||
| }, | ||||||||||||||
| client: { | ||||||||||||||
| NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: z.string(), | ||||||||||||||
| NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: isComingSoonMode | ||||||||||||||
| ? z.string().optional() | ||||||||||||||
| : z.string(), | ||||||||||||||
| }, | ||||||||||||||
| experimental__runtimeEnv: { | ||||||||||||||
| COMING_SOON_MODE: process.env.COMING_SOON_MODE, | ||||||||||||||
| NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY: | ||||||||||||||
| process.env.NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY, | ||||||||||||||
| }, | ||||||||||||||
| // Enable the flag to treat empty strings as undefined | ||||||||||||||
| emptyStringAsUndefined: true, | ||||||||||||||
| }); | ||||||||||||||
| }); | ||||||||||||||
|
Comment on lines
41
to
+42
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix Prettier formatting. The pipeline reports code style issues. The file appears to be missing a trailing newline. 🔧 Proposed fix emptyStringAsUndefined: true,
});
+📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,17 @@ | ||||||||||||||||||||||||||||||||||||
| export const featureFlags = { | ||||||||||||||||||||||||||||||||||||
| comingSoonMode: true | ||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||
|
Comment on lines
+1
to
+3
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Either wire this to the env var or remove the env var definition to avoid confusion. 🔧 Proposed fix to use the env var+import { env } from "@/env";
+
export const featureFlags = {
- comingSoonMode: true
+ comingSoonMode: env.COMING_SOON_MODE === "true",
};📝 Committable suggestion
Suggested change
🧰 Tools🪛 GitHub Actions: Prettier Check[warning] 1-1: Prettier formatting warning: code style issues found in this file. 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| export const comingSoonRoutes = [ | ||||||||||||||||||||||||||||||||||||
| "/faq", | ||||||||||||||||||||||||||||||||||||
| "/register", | ||||||||||||||||||||||||||||||||||||
| ] as const; | ||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||
| export function isComingSoonRoute(pathname: string) { | ||||||||||||||||||||||||||||||||||||
| return ( | ||||||||||||||||||||||||||||||||||||
| featureFlags.comingSoonMode && | ||||||||||||||||||||||||||||||||||||
| comingSoonRoutes.some( | ||||||||||||||||||||||||||||||||||||
| (route) => pathname === route || pathname.startsWith(`${route}/`), | ||||||||||||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||
|
Comment on lines
+10
to
+17
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Route matching logic and Prettier formatting. The 🔧 Proposed fix for trailing newline export function isComingSoonRoute(pathname: string) {
return (
featureFlags.comingSoonMode &&
comingSoonRoutes.some(
(route) => pathname === route || pathname.startsWith(`${route}/`),
)
);
}
+📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -4,26 +4,41 @@ import { publicRoutes } from "config"; | |||||||||||||||||||||||||||||||
| import { bannedUsers } from "db/schema"; | ||||||||||||||||||||||||||||||||
| import { db } from "db"; | ||||||||||||||||||||||||||||||||
| import { eq } from "db/drizzle"; | ||||||||||||||||||||||||||||||||
| import { isComingSoonRoute } from "@/lib/feature_flags"; | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| const isPublicRoute = createRouteMatcher(publicRoutes); | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| export default clerkMiddleware(async (auth, req) => { | ||||||||||||||||||||||||||||||||
| if (req.nextUrl.pathname.startsWith("/@")) { | ||||||||||||||||||||||||||||||||
| const pathname = req.nextUrl.pathname; | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| if (pathname.startsWith("/@")) { | ||||||||||||||||||||||||||||||||
| return NextResponse.rewrite( | ||||||||||||||||||||||||||||||||
| new URL(`/user/${req.nextUrl.pathname.replace("/@", "")}`, req.url), | ||||||||||||||||||||||||||||||||
| new URL(`/user/${pathname.replace("/@", "")}`, req.url), | ||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
| if (req.nextUrl.pathname.startsWith("/~")) { | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| if (pathname.startsWith("/~")) { | ||||||||||||||||||||||||||||||||
| return NextResponse.rewrite( | ||||||||||||||||||||||||||||||||
| new URL(`/team/${req.nextUrl.pathname.replace("/~", "")}`, req.url), | ||||||||||||||||||||||||||||||||
| new URL(`/team/${pathname.replace("/~", "")}`, req.url), | ||||||||||||||||||||||||||||||||
| ); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| if (pathname === "/coming-soon") { | ||||||||||||||||||||||||||||||||
| return NextResponse.next(); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| // rewrite selected routes to the coming soon page before auth runs | ||||||||||||||||||||||||||||||||
| if (isComingSoonRoute(pathname)) { | ||||||||||||||||||||||||||||||||
| return NextResponse.rewrite(new URL("/coming-soon", req.url)); | ||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| if (!isPublicRoute(req)) { | ||||||||||||||||||||||||||||||||
| await auth.protect(); | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| const authData = await auth(); | ||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| const isBanned = !!(await db.query.bannedUsers.findFirst({ | ||||||||||||||||||||||||||||||||
| where: eq(bannedUsers.userID, (await auth()).userId!), | ||||||||||||||||||||||||||||||||
| where: eq(bannedUsers.userID, authData.userId!), | ||||||||||||||||||||||||||||||||
| })); | ||||||||||||||||||||||||||||||||
|
Comment on lines
+38
to
42
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Non-null assertion on After 🛡️ Proposed defensive fix const authData = await auth();
+ if (!authData.userId) {
+ return NextResponse.next();
+ }
const isBanned = !!(await db.query.bannedUsers.findFirst({
- where: eq(bannedUsers.userID, authData.userId!),
+ where: eq(bannedUsers.userID, authData.userId),
}));📝 Committable suggestion
Suggested change
🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| if (isBanned) { | ||||||||||||||||||||||||||||||||
|
|
@@ -36,4 +51,4 @@ export default clerkMiddleware(async (auth, req) => { | |||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||
| export const config = { | ||||||||||||||||||||||||||||||||
| matcher: ["/((?!.*\\..*|_next).*)", "/", "/(api)(.*)"], | ||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||
|
Comment on lines
52
to
+54
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fix Prettier formatting. The pipeline reports code style issues in this file. 🤖 Prompt for AI Agents |
||||||||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Fix Prettier formatting issues.
The pipeline reports code style issues. Based on the summary, this file is missing a trailing newline.
🔧 Proposed fix
export default function ComingSoonPage() { return ( <ComingSoon title="Coming Soon" description="We're still building this page. Check back soon." /> ); } +📝 Committable suggestion
🧰 Tools
🪛 GitHub Actions: Prettier Check
[warning] 1-1: Prettier formatting warning: code style issues found in this file.
🤖 Prompt for AI Agents