From f891e201e6823528beeea374c271d436de2a9705 Mon Sep 17 00:00:00 2001 From: Steven Tey Date: Sat, 19 Oct 2024 17:17:00 -0700 Subject: [PATCH 1/3] improve auth layout --- .../auth/reset-password/[token]/page.tsx | 42 +++++------ .../app/app.dub.co/(auth)/auth/saml/page.tsx | 18 +++-- .../app.dub.co/(auth)/invites/[code]/page.tsx | 46 +++++-------- apps/web/app/app.dub.co/(auth)/layout.tsx | 11 ++- .../(auth)/oauth/authorize/page.tsx | 10 +-- .../app/app.dub.co/(auth)/welcome/page.tsx | 5 -- .../(dashboard)/[slug]/settings/layout.tsx | 2 +- .../app/app.dub.co/(onboarding)/layout.tsx | 4 +- apps/web/app/not-found.tsx | 4 +- apps/web/lib/api/oauth/actions.ts | 6 +- apps/web/lib/middleware/utils/app-redirect.ts | 1 + apps/web/ui/layout/auth-layout.tsx | 13 ++-- apps/web/ui/shared/empty-state.tsx | 2 + apps/web/ui/shared/new-background.tsx | 69 +++++++++++++++++++ packages/blocks/src/empty-state.tsx | 4 +- 15 files changed, 150 insertions(+), 87 deletions(-) delete mode 100644 apps/web/app/app.dub.co/(auth)/welcome/page.tsx create mode 100644 apps/web/ui/shared/new-background.tsx diff --git a/apps/web/app/app.dub.co/(auth)/auth/reset-password/[token]/page.tsx b/apps/web/app/app.dub.co/(auth)/auth/reset-password/[token]/page.tsx index f11bc40f3d..028ad0b876 100644 --- a/apps/web/app/app.dub.co/(auth)/auth/reset-password/[token]/page.tsx +++ b/apps/web/app/app.dub.co/(auth)/auth/reset-password/[token]/page.tsx @@ -1,5 +1,6 @@ import { prisma } from "@/lib/prisma"; -import { Wordmark } from "@dub/ui"; +import EmptyState from "@/ui/shared/empty-state"; +import { InputPassword } from "@dub/ui"; import { ResetPasswordForm } from "./form"; export const runtime = "nodejs"; @@ -13,28 +14,27 @@ interface Props { export default async function ResetPasswordPage({ params: { token } }: Props) { const validToken = await isValidToken(token); + if (!validToken) { + return ( + + ); + } + return (
-
- -
-
-

Reset your password

-

- {validToken - ? "Enter new password for your account." - : "The request is invalid or expired."} -

-
-
- {validToken ? ( - - ) : ( -
- That request is expired or invalid. Please request a new one. -
- )} -
+
+
+

Reset your password

+

+ Enter new password for your account. +

+
+
+
diff --git a/apps/web/app/app.dub.co/(auth)/auth/saml/page.tsx b/apps/web/app/app.dub.co/(auth)/auth/saml/page.tsx index f0de848c08..7eff4b839b 100644 --- a/apps/web/app/app.dub.co/(auth)/auth/saml/page.tsx +++ b/apps/web/app/app.dub.co/(auth)/auth/saml/page.tsx @@ -1,3 +1,4 @@ +import EmptyState from "@/ui/shared/empty-state"; import { LoadingSpinner } from "@dub/ui"; import { APP_NAME } from "@dub/utils"; import { Suspense } from "react"; @@ -5,18 +6,15 @@ import SAMLIDPForm from "./form"; export default function SAMLPage() { return ( -
+ <> + -
-

Authenticating

-

- {APP_NAME} is verifying your identity. -
Please wait... -

- -
-
+ ); } diff --git a/apps/web/app/app.dub.co/(auth)/invites/[code]/page.tsx b/apps/web/app/app.dub.co/(auth)/invites/[code]/page.tsx index fe70854c21..a6aef63158 100644 --- a/apps/web/app/app.dub.co/(auth)/invites/[code]/page.tsx +++ b/apps/web/app/app.dub.co/(auth)/invites/[code]/page.tsx @@ -1,22 +1,15 @@ import { getSession } from "@/lib/auth"; import { prisma } from "@/lib/prisma"; -import { LoadingSpinner, Logo } from "@dub/ui"; +import EmptyState from "@/ui/shared/empty-state"; +import { LoadingSpinner } from "@dub/ui"; +import { LinkBroken, Users6 } from "@dub/ui/src/icons"; import { APP_NAME } from "@dub/utils"; import { redirect } from "next/navigation"; import { Suspense } from "react"; export const runtime = "nodejs"; -const PageCopy = ({ title, message }: { title: string; message: string }) => { - return ( - <> -

{title}

-

{message}

- - ); -}; - -export default function InvitesPage({ +export default function InitesPage({ params, }: { params: { @@ -24,17 +17,14 @@ export default function InvitesPage({ }; }) { return ( -
- +
- - - + } > @@ -82,12 +72,11 @@ async function VerifyInvite({ code }: { code: string }) { if (!workspace) { return ( - <> - - + ); } @@ -98,9 +87,10 @@ async function VerifyInvite({ code }: { code: string }) { if (workspace._count.users >= workspace.usersLimit) { return ( - ); } diff --git a/apps/web/app/app.dub.co/(auth)/layout.tsx b/apps/web/app/app.dub.co/(auth)/layout.tsx index 5c3c735922..85ecd9816d 100644 --- a/apps/web/app/app.dub.co/(auth)/layout.tsx +++ b/apps/web/app/app.dub.co/(auth)/layout.tsx @@ -1,14 +1,19 @@ import Toolbar from "@/ui/layout/toolbar/toolbar"; -import { Background } from "@dub/ui"; +import { NewBackground } from "@/ui/shared/new-background"; +import { Wordmark } from "@dub/ui"; import Providers from "app/providers"; +import Link from "next/link"; import { ReactNode } from "react"; export default function AuthLayout({ children }: { children: ReactNode }) { return ( - -
+ +
+ + + {children}
diff --git a/apps/web/app/app.dub.co/(auth)/oauth/authorize/page.tsx b/apps/web/app/app.dub.co/(auth)/oauth/authorize/page.tsx index 2792a9e25d..22879b43ea 100644 --- a/apps/web/app/app.dub.co/(auth)/oauth/authorize/page.tsx +++ b/apps/web/app/app.dub.co/(auth)/oauth/authorize/page.tsx @@ -4,7 +4,7 @@ import z from "@/lib/zod"; import { authorizeRequestSchema } from "@/lib/zod/schemas/oauth"; import EmptyState from "@/ui/shared/empty-state"; import { BlurImage, Logo } from "@dub/ui"; -import { CircleWarning } from "@dub/ui/src/icons"; +import { CircleWarning, CubeSettings } from "@dub/ui/src/icons"; import { HOME_DOMAIN, constructMetadata } from "@dub/utils"; import { ArrowLeftRight } from "lucide-react"; import { redirect } from "next/navigation"; @@ -36,9 +36,11 @@ export default async function Authorize({ if (error || !integration) { return ( -
- -
+ ); } diff --git a/apps/web/app/app.dub.co/(auth)/welcome/page.tsx b/apps/web/app/app.dub.co/(auth)/welcome/page.tsx deleted file mode 100644 index 8e8d0645df..0000000000 --- a/apps/web/app/app.dub.co/(auth)/welcome/page.tsx +++ /dev/null @@ -1,5 +0,0 @@ -import { redirect } from "next/navigation"; - -export default function OldWelcomePage() { - redirect("/onboarding"); -} diff --git a/apps/web/app/app.dub.co/(dashboard)/[slug]/settings/layout.tsx b/apps/web/app/app.dub.co/(dashboard)/[slug]/settings/layout.tsx index 173a5c5fec..6a141bc7a4 100644 --- a/apps/web/app/app.dub.co/(dashboard)/[slug]/settings/layout.tsx +++ b/apps/web/app/app.dub.co/(dashboard)/[slug]/settings/layout.tsx @@ -1,5 +1,5 @@ +import SettingsLayout from "@/ui/layout/settings-layout"; import { ReactNode } from "react"; -import SettingsLayout from "../../../../../ui/layout/settings-layout"; export default function WorkspaceSettingsLayout({ children, diff --git a/apps/web/app/app.dub.co/(onboarding)/layout.tsx b/apps/web/app/app.dub.co/(onboarding)/layout.tsx index b831f185d5..dbf8afee15 100644 --- a/apps/web/app/app.dub.co/(onboarding)/layout.tsx +++ b/apps/web/app/app.dub.co/(onboarding)/layout.tsx @@ -1,12 +1,12 @@ import Toolbar from "@/ui/layout/toolbar/toolbar"; +import { NewBackground } from "@/ui/shared/new-background"; import Providers from "app/providers"; import { PropsWithChildren } from "react"; -import { Background } from "./background"; export default function Layout({ children }: PropsWithChildren) { return ( - + {children} diff --git a/apps/web/app/not-found.tsx b/apps/web/app/not-found.tsx index c43407af54..cc37906fb6 100644 --- a/apps/web/app/not-found.tsx +++ b/apps/web/app/not-found.tsx @@ -1,6 +1,6 @@ +import { NewBackground } from "@/ui/shared/new-background"; import { Wordmark } from "@dub/ui/src/wordmark"; import Link from "next/link"; -import { Background } from "./app.dub.co/(onboarding)/background"; export default function NotFound() { return ( @@ -19,7 +19,7 @@ export default function NotFound() { Go back home
- + ); } diff --git a/apps/web/lib/api/oauth/actions.ts b/apps/web/lib/api/oauth/actions.ts index e0f0fc3f5e..d197a689e0 100644 --- a/apps/web/lib/api/oauth/actions.ts +++ b/apps/web/lib/api/oauth/actions.ts @@ -37,7 +37,8 @@ export const vaidateAuthorizeRequest = async (params: any) => { if (!oAuthApp || !oAuthApp.integration) { return { - error: "Could not find OAuth application.", + error: + "Could not find OAuth application. Make sure you have the correct client_id.", }; } @@ -45,7 +46,8 @@ export const vaidateAuthorizeRequest = async (params: any) => { if (!redirectUris.includes(redirectUri)) { return { - error: "Invalid redirect_uri parameter for the application.", + error: + "Invalid redirect_uri parameter detected. Make sure you have allowlisted the redirect_uri in your OAuth app settings.", }; } diff --git a/apps/web/lib/middleware/utils/app-redirect.ts b/apps/web/lib/middleware/utils/app-redirect.ts index 707cd2c8c2..9c227a1bd2 100644 --- a/apps/web/lib/middleware/utils/app-redirect.ts +++ b/apps/web/lib/middleware/utils/app-redirect.ts @@ -1,5 +1,6 @@ const APP_REDIRECTS = { "/account": "/account/settings", + "/welcome": "/onboarding", }; export const appRedirect = (path: string) => { diff --git a/apps/web/ui/layout/auth-layout.tsx b/apps/web/ui/layout/auth-layout.tsx index ab8b717db2..c03a5d6cb5 100644 --- a/apps/web/ui/layout/auth-layout.tsx +++ b/apps/web/ui/layout/auth-layout.tsx @@ -1,4 +1,4 @@ -import { BlurImage, ClientOnly, Wordmark } from "@dub/ui"; +import { BlurImage, ClientOnly } from "@dub/ui"; import { Suspense } from "react"; const logos = [ @@ -26,7 +26,6 @@ export const AuthLayout = ({ children }: AuthLayoutProps) => {
- {children}
@@ -55,13 +54,13 @@ export const AuthLayout = ({ children }: AuthLayoutProps) => {
- + ); +} + +function BackgroundGradient({ className }: { className?: string }) { + return ( +
+
+
+
+ ); +} diff --git a/packages/blocks/src/empty-state.tsx b/packages/blocks/src/empty-state.tsx index 80b1203ac4..455d01623c 100644 --- a/packages/blocks/src/empty-state.tsx +++ b/packages/blocks/src/empty-state.tsx @@ -16,8 +16,8 @@ export function EmptyState({ }: EmptyStateProps) { return (
-
- +
+

{title}

{description && ( From 565538a331cc885f3d69df8686fbca14ac8bbba4 Mon Sep 17 00:00:00 2001 From: Steven Tey Date: Sat, 19 Oct 2024 17:20:52 -0700 Subject: [PATCH 2/3] show full number --- .../(dashboard)/[slug]/settings/billing/page-client.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/web/app/app.dub.co/(dashboard)/[slug]/settings/billing/page-client.tsx b/apps/web/app/app.dub.co/(dashboard)/[slug]/settings/billing/page-client.tsx index dde360c0c8..1c0678985e 100644 --- a/apps/web/app/app.dub.co/(dashboard)/[slug]/settings/billing/page-client.tsx +++ b/apps/web/app/app.dub.co/(dashboard)/[slug]/settings/billing/page-client.tsx @@ -277,7 +277,7 @@ function UsageTabCard({ {unlimited ? "Unlimited" - : `${prefix}${nFormatter(remaining, { full: remaining < 10000 })} remaining of ${prefix}${nFormatter(limit, { full: limit < 10000 })}`} + : `${prefix}${nFormatter(remaining, { full: true })} remaining of ${prefix}${nFormatter(limit, { full: limit < 1000000 })}`} ) : (
From 484b09b564da5002392840087248b7e797482292 Mon Sep 17 00:00:00 2001 From: Steven Tey Date: Sat, 19 Oct 2024 18:08:56 -0700 Subject: [PATCH 3/3] improve swr revalidate --- apps/web/ui/domains/register-domain-form.tsx | 8 ++------ apps/web/ui/modals/delete-domain-modal.tsx | 5 +++-- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/apps/web/ui/domains/register-domain-form.tsx b/apps/web/ui/domains/register-domain-form.tsx index f098f28094..d7649f601a 100644 --- a/apps/web/ui/domains/register-domain-form.tsx +++ b/apps/web/ui/domains/register-domain-form.tsx @@ -106,17 +106,13 @@ export function RegisterDomainForm({ } else { toast.success("Domain registered successfully!"); - // Mutate workspace, domains links + // Mutate workspace, domains, and links await Promise.all([ mutate(`/api/workspaces/${workspace.slug}`), mutate( (key) => typeof key === "string" && - (key.startsWith(`/api/domains?workspaceId=${workspace.id}`) || - key.startsWith(`/api/domains/count?workspaceId=${workspace.id}`)), - ), - mutate( - (key) => typeof key === "string" && key.startsWith("/api/links"), + (key.startsWith("/api/domains") || key.startsWith("/api/links")), undefined, { revalidate: true }, ), diff --git a/apps/web/ui/modals/delete-domain-modal.tsx b/apps/web/ui/modals/delete-domain-modal.tsx index 8e0c0cf067..98de227981 100644 --- a/apps/web/ui/modals/delete-domain-modal.tsx +++ b/apps/web/ui/modals/delete-domain-modal.tsx @@ -61,8 +61,9 @@ function DeleteDomainModal({ if (res.status === 200) { await mutate( (key) => - typeof key === "string" && - key.startsWith(`/api/domains?workspaceId=${id}`), + typeof key === "string" && key.startsWith("/api/domains"), + undefined, + { revalidate: true }, ); setShowDeleteDomainModal(false); toast.success("Successfully deleted domain!");