fix: prepare for beta and google verification

This commit is contained in:
Logan Reeder
2025-08-18 14:03:21 -06:00
parent 0aaafb5d08
commit 73e3fc02bf
13 changed files with 57 additions and 76 deletions

View File

@@ -14,7 +14,6 @@ import { handleUploadError, sendError, sendSuccess } from "../utils";
import { createDriveProviderRouter } from "../../hono";
import { zValidator } from "@hono/zod-validator";
import { FileService } from "./file-service";
import { Readable } from "node:stream";
const fileService = new FileService();
const filesRouter = createDriveProviderRouter()

View File

@@ -24,7 +24,7 @@ export default function PrivacyPage() {
<div className="mb-10 text-center">
<LegalHeading1>Privacy Policy</LegalHeading1>
</div>
<Card className="border-muted/30 bg-background/80 border-2 shadow-none">
<Card className="border-2 shadow-none">
<CardContent className="space-y-8 p-8 text-base leading-relaxed">
<LegalParagraph>
Your privacy is important to us. It is {COMPANY_NAME}&apos;s policy to respect your privacy and comply

View File

@@ -18,7 +18,7 @@ export default function TermsPage() {
<div className="pb-10 text-center">
<LegalHeading1>Terms of Service</LegalHeading1>
</div>
<Card className="border-muted/30 border-2 shadow-none">
<Card className="border-2 shadow-none">
<CardContent className="space-y-8 p-8 text-base leading-relaxed">
<LegalParagraph>
These Terms of Service govern your use of the website located at{" "}

View File

@@ -32,5 +32,17 @@ export default function sitemap(): MetadataRoute.Sitemap {
changeFrequency: "monthly",
priority: 0.7,
},
{
url: buildUrl("/terms"),
lastModified: now,
changeFrequency: "yearly",
priority: 0.7,
},
{
url: buildUrl("/privacy"),
lastModified: now,
changeFrequency: "yearly",
priority: 0.7,
},
];
}

View File

@@ -22,7 +22,6 @@ export function AuthProviderButtons({
onProviderClick,
isLoading: externalIsLoading,
action,
showS3Button = false,
callbackURL,
onAuthSuccess,
onS3Click,
@@ -107,7 +106,7 @@ export function AuthProviderButtons({
>
{getIsLoading("microsoft") && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
</SocialAuthButton>
{/*
{/*
<SocialAuthButton
provider="box"
action={action}

View File

@@ -1,16 +1,16 @@
"use client";
import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
import { Card, CardContent, CardFooter, CardHeader, CardTitle } from "@/components/ui/card";
import { AuthProviderButtons } from "@/components/auth/shared/auth-provider-buttons";
// import { SegmentedProgress } from "@/components/ui/segmented-progress";
import { signUpSchema, type SignUpFormData } from "@nimbus/shared";
// import { FieldError } from "@/components/ui/field-error";
// import { Separator } from "@/components/ui/separator";
import { zodResolver } from "@hookform/resolvers/zod";
import { useState, type ComponentProps } from "react";
import { useSearchParams } from "next/navigation";
import { Button } from "@/components/ui/button";
import { useSignUp } from "@/hooks/useAuth";
import { type ComponentProps } from "react";
// import { Label } from "@/components/ui/label";
// import { Input } from "@/components/ui/input";
import { useForm } from "react-hook-form";

View File

@@ -1,35 +0,0 @@
import HeroBgDark from "@/public/images/hero-dithered-black.png";
import HeroBgLight from "public/images/hero-dithered-white.png";
import { type ComponentProps } from "react";
import { cn } from "@/lib/utils";
import Image from "next/image";
type BgAngelsProps = {
className?: string;
alt?: string;
} & ComponentProps<"div">;
export default function BgAngels({ className, alt }: BgAngelsProps) {
return (
<>
<Image
src={HeroBgDark}
alt={alt ? alt : "angel"}
width={478}
height={718}
loading="eager"
className={cn(className, "hidden dark:block")}
priority
/>
<Image
src={HeroBgLight}
alt={alt ? alt : "angel"}
width={478}
height={718}
loading="eager"
className={cn(className, "block dark:hidden")}
priority
/>
</>
);
}

View File

@@ -10,10 +10,18 @@ export default function Footer() {
<div className="mx-auto flex w-full max-w-7xl flex-row items-center justify-center">
<div className="text-muted-foreground flex flex-row items-center justify-center gap-2">
<LogoIcon className="h-9 w-9" aria-hidden="true" />
<Link href="/terms" className="text-xs underline underline-offset-2 md:text-sm">
<Link
href="https://nimbus.storage/terms"
className="text-xs underline underline-offset-2 md:text-sm"
aria-label="Terms of Use"
>
Terms of Use
</Link>
<Link href="/privacy" className="text-xs underline underline-offset-2 md:text-sm">
<Link
href="https://nimbus.storage/privacy"
className="text-xs underline underline-offset-2 md:text-sm"
aria-label="Privacy Policy"
>
Privacy Policy
</Link>
</div>

View File

@@ -2,7 +2,7 @@
import { DiscordIcon, GitHubIcon, LogoIcon, XPlatformIcon } from "@/components/icons";
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
import { ModeToggle } from "@/components/mode-toggle";
import { authClient } from "@nimbus/auth/auth-client";
import { Button } from "@/components/ui/button";
import { Users } from "lucide-react";
import Link from "next/link";
@@ -31,7 +31,7 @@ export default function Header() {
</Tooltip>
<Tooltip>
<TooltipTrigger asChild>
<Button variant="ghost" aria-label="Discord" className="h-9 w-9">
<Button variant="ghost" asChild aria-label="Discord" className="h-9 w-9">
<a href="https://discord.gg/c9nWy26ubK" target="_blank" rel="noopener noreferrer">
<DiscordIcon />
</a>
@@ -59,7 +59,19 @@ export default function Header() {
</TooltipTrigger>
<TooltipContent>X (Twitter)</TooltipContent>
</Tooltip>
<ModeToggle />
{!authClient.useSession().data?.session ? (
<Button asChild aria-label="Sign in">
<Link href="/signin" className="ml-4 font-semibold">
Sign In
</Link>
</Button>
) : (
<Button asChild aria-label="Go to Nimbus dashboard">
<Link href="/dashboard" className="font-semibold">
Go to Nimbus
</Link>
</Button>
)}
</div>
</header>
);

View File

@@ -1,13 +1,12 @@
import { AnimatedGroup } from "@/components/ui/animated-group";
import BgAngels from "@/components/brand-assets/bg-angels";
import { WaitlistForm } from "@/components/home/waitlist";
import HeroLight from "@/public/images/hero-light.png";
import HeroDark from "@/public/images/hero-dark.png";
import { useIsMobile } from "@/hooks/use-mobile";
import Header from "@/components/home/header";
import { type Variants } from "motion/react";
import { Button } from "../ui/button";
import Image from "next/image";
import Footer from "./footer";
import Link from "next/link";
const transitionVariants: { item: Variants } = {
item: {
@@ -29,30 +28,16 @@ const transitionVariants: { item: Variants } = {
};
export default function Hero() {
const isMobile = useIsMobile();
return (
<div className="font-manrope flex w-full flex-1 flex-col items-center justify-center gap-12 overflow-hidden px-4 py-40 md:gap-16">
<Header />
<AnimatedGroup variants={transitionVariants} className="w-full">
<div className="relative flex w-full flex-col gap-12 px-4 md:px-6">
{isMobile && (
<BgAngels className="pointer-events-none absolute -top-40 left-40 z-0 h-auto rotate-12 opacity-50" />
)}
<div className="relative mx-auto w-full max-w-3xl sm:max-w-4xl md:max-w-5xl lg:max-w-6xl">
<div className="pointer-events-none absolute top-1/2 left-1/2 z-0 block h-[60vw] w-[120vw] -translate-x-1/2 -translate-y-1/2 bg-[radial-gradient(ellipse_at_center,rgba(255,255,255,0.7)_60%,rgba(255,255,255,0.2)_100%)] blur-[100px] sm:h-[80%] sm:w-[120%] dark:hidden" />
<div className="pointer-events-none absolute top-1/2 left-1/2 z-0 hidden h-[60vw] w-[120vw] -translate-x-1/2 -translate-y-1/2 bg-[radial-gradient(ellipse_at_center,rgba(10,10,20,0.7)_60%,rgba(10,10,20,0.2)_100%)] blur-[100px] sm:h-[80%] sm:w-[120%] dark:block" />
<div className="absolute bottom-[-100%] left-[-100px] z-0 hidden sm:block">
<BgAngels className="scale-x-[-1] -rotate-12 opacity-40" alt="angel right" />
</div>
<div className="absolute right-[-100px] bottom-[-100%] z-0 hidden sm:block">
<BgAngels className="rotate-12 opacity-40" alt="angel left" />
</div>
<div className="relative z-10 flex flex-col items-center justify-center gap-8 text-center md:gap-12 lg:gap-12">
<h1 className="text-4xl leading-[1.1] font-bold tracking-[-0.02em] sm:flex-row md:text-6xl lg:text-7xl">
Cloud you <br /> can actually{" "}
@@ -65,7 +50,18 @@ export default function Hero() {
</p>
</div>
</div>
<WaitlistForm />
<div className="mx-auto flex gap-2">
<Button variant={"ghost"} asChild className="hover:!bg-accent !bg-transparent transition-all duration-300">
<Link href="https://github.com/nimbusdotstorage/Nimbus" className="font-semibold">
Source Code
</Link>
</Button>
<Button variant={"default"} asChild className="">
<Link href="/signin" className="font-semibold">
Sign In
</Link>
</Button>
</div>
</div>
</AnimatedGroup>

View File

@@ -31,15 +31,6 @@ export function RouteGuard({ children, requireAuth = false, redirectTo = "/signi
}
}, [session, isPending, requireAuth, redirectTo, router]);
// Show loading state while checking auth
if (isPending) {
return (
<div className="flex min-h-screen w-full items-center justify-center">
<div className="border-primary h-8 w-8 animate-spin rounded-full border-b-2"></div>
</div>
);
}
// Allow rendering if no auth requirement, or if authenticated
const isAuthenticated = !!session?.user;
const shouldRender = !requireAuth || isAuthenticated;

View File

@@ -128,7 +128,7 @@
"@nimbus/db": "workspace:*",
"@nimbus/env": "workspace:*",
"@upstash/redis": "^1.35.2",
"better-auth": "^1.3.0",
"better-auth": "^1.3.4",
"drizzle-orm": "^0.44.4",
"iovalkey": "^0.3.3",
"resend": "^4.7.0",

View File

@@ -3,7 +3,6 @@ import type { Redis as UpstashRedis } from "@upstash/redis/cloudflare";
import { drizzleAdapter } from "better-auth/adapters/drizzle";
import schema, { user as userTable } from "@nimbus/db/schema";
import type { Redis as ValkeyRedis } from "iovalkey";
import { genericOAuth } from "better-auth/plugins";
import type { RedisClient } from "@nimbus/cache";
import { sendMail } from "./utils/send-mail";
import { type DB } from "@nimbus/db";