Skip to content

Commit

Permalink
Merge branch 'main' into soft-delete-v2
Browse files Browse the repository at this point in the history
  • Loading branch information
steven-tey authored Oct 20, 2024
2 parents d05d650 + 484b09b commit 5aabf5d
Show file tree
Hide file tree
Showing 26 changed files with 219 additions and 245 deletions.
42 changes: 21 additions & 21 deletions apps/web/app/app.dub.co/(auth)/auth/reset-password/[token]/page.tsx
Original file line number Diff line number Diff line change
@@ -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";
Expand All @@ -13,28 +14,27 @@ interface Props {
export default async function ResetPasswordPage({ params: { token } }: Props) {
const validToken = await isValidToken(token);

if (!validToken) {
return (
<EmptyState
icon={InputPassword}
title="Invalid Reset Token"
description="The password reset token is invalid or expired. Please request a new one."
/>
);
}

return (
<div className="relative z-10 my-10 flex min-h-full w-full items-center justify-center">
<div className="flex w-full max-w-md flex-col items-center">
<Wordmark className="mb-8 h-12" />
<div className="w-full overflow-hidden border-y border-gray-200 sm:rounded-2xl sm:border sm:shadow-xl">
<div className="flex flex-col items-center justify-center space-y-3 border-b border-gray-200 bg-white px-4 py-6 pt-8 text-center sm:px-16">
<h3 className="text-xl font-semibold">Reset your password</h3>
<p className="text-sm text-gray-500">
{validToken
? "Enter new password for your account."
: "The request is invalid or expired."}
</p>
</div>
<div className="flex flex-col space-y-3 bg-gray-50 px-4 py-8 sm:px-16">
{validToken ? (
<ResetPasswordForm />
) : (
<div className="text-center">
That request is expired or invalid. Please request a new one.
</div>
)}
</div>
<div className="w-full overflow-hidden border-y border-gray-200 sm:rounded-2xl sm:border sm:shadow-xl">
<div className="flex flex-col items-center justify-center space-y-3 border-b border-gray-200 bg-white px-4 py-6 pt-8 text-center sm:px-16">
<h3 className="text-xl font-semibold">Reset your password</h3>
<p className="text-sm text-gray-500">
Enter new password for your account.
</p>
</div>
<div className="flex flex-col space-y-3 bg-gray-50 px-4 py-8 sm:px-16">
<ResetPasswordForm />
</div>
</div>
</div>
Expand Down
18 changes: 8 additions & 10 deletions apps/web/app/app.dub.co/(auth)/auth/saml/page.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,20 @@
import EmptyState from "@/ui/shared/empty-state";
import { LoadingSpinner } from "@dub/ui";
import { APP_NAME } from "@dub/utils";
import { Suspense } from "react";
import SAMLIDPForm from "./form";

export default function SAMLPage() {
return (
<div>
<>
<EmptyState
icon={LoadingSpinner}
title="SAML Authentication"
description={`${APP_NAME} is verifying your identity via SAML. This might take a few seconds...`}
/>
<Suspense>
<SAMLIDPForm />
</Suspense>
<div className="flex h-screen flex-col items-center justify-center space-y-6 text-center">
<h1 className="font-display text-4xl font-bold">Authenticating</h1>
<p className="text-lg text-gray-600">
{APP_NAME} is verifying your identity.
<br /> Please wait...
</p>
<LoadingSpinner className="h-7 w-7" />
</div>
</div>
</>
);
}
46 changes: 18 additions & 28 deletions apps/web/app/app.dub.co/(auth)/invites/[code]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,40 +1,30 @@
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 (
<>
<h1 className="font-display text-3xl font-bold sm:text-4xl">{title}</h1>
<p className="max-w-lg text-pretty text-gray-600 sm:text-lg">{message}</p>
</>
);
};

export default function InvitesPage({
export default function InitesPage({
params,
}: {
params: {
code: string;
};
}) {
return (
<div className="flex h-screen flex-col items-center justify-center space-y-6 text-center">
<Logo className="h-12 w-12" />
<div className="flex flex-col items-center justify-center gap-6 text-center">
<Suspense
fallback={
<>
<PageCopy
title="Verifying Invite"
message={`${APP_NAME} is verifying your invite link...`}
/>
<LoadingSpinner className="h-7 w-7" />
</>
<EmptyState
icon={LoadingSpinner}
title="Verifying Invite"
description={`${APP_NAME} is verifying your invite link. This might take a few seconds...`}
/>
}
>
<VerifyInvite code={params.code} />
Expand Down Expand Up @@ -82,12 +72,11 @@ async function VerifyInvite({ code }: { code: string }) {

if (!workspace) {
return (
<>
<PageCopy
title="Invalid Invite"
message="The invite link you are trying to use is invalid. Please contact the workspace owner for a new invite."
/>
</>
<EmptyState
icon={LinkBroken}
title="Invalid Invite Link"
description="The invite link you are trying to use is invalid. Please contact the workspace owner for more information."
/>
);
}

Expand All @@ -98,9 +87,10 @@ async function VerifyInvite({ code }: { code: string }) {

if (workspace._count.users >= workspace.usersLimit) {
return (
<PageCopy
<EmptyState
icon={Users6}
title="User Limit Reached"
message="The workspace you are trying to join is currently full. Please contact the workspace owner for more information."
description="The workspace you are trying to join is currently full. Please contact the workspace owner for more information."
/>
);
}
Expand Down
11 changes: 8 additions & 3 deletions apps/web/app/app.dub.co/(auth)/layout.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<Providers>
<Toolbar />
<Background />
<div className="relative z-10 flex min-h-screen w-full justify-center">
<NewBackground />
<div className="relative flex min-h-screen w-full justify-center">
<Link href="/" className="absolute left-4 top-3 z-10">
<Wordmark className="h-6" />
</Link>
{children}
</div>
</Providers>
Expand Down
10 changes: 6 additions & 4 deletions apps/web/app/app.dub.co/(auth)/oauth/authorize/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down Expand Up @@ -36,9 +36,11 @@ export default async function Authorize({

if (error || !integration) {
return (
<div className="relative z-10 mt-[calc(30vh)] h-fit w-full max-w-md overflow-hidden sm:rounded-2xl">
<EmptyState icon={Logo} title={error} />
</div>
<EmptyState
icon={CubeSettings}
title="Invalid OAuth Request"
description={error}
/>
);
}

Expand Down
5 changes: 0 additions & 5 deletions apps/web/app/app.dub.co/(auth)/welcome/page.tsx

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {
import { CircleDollar, CursorRays, Hyperlink } from "@dub/ui/src/icons";
import { cn, getFirstAndLastDay, nFormatter } from "@dub/utils";
import Link from "next/link";
import { CSSProperties, useMemo, useState } from "react";
import { CSSProperties, useMemo } from "react";
import { UsageChart } from "./usage-chart";

export default function WorkspaceBillingClient() {
Expand All @@ -41,8 +41,6 @@ export default function WorkspaceBillingClient() {
const { tags } = useTags();
const { users } = useUsers();

const [clicked, setClicked] = useState(false);

const [billingStart, billingEnd] = useMemo(() => {
if (billingCycleStart) {
const { firstDay, lastDay } = getFirstAndLastDay(billingCycleStart);
Expand Down Expand Up @@ -96,21 +94,20 @@ export default function WorkspaceBillingClient() {
conversionEnabled && "sm:grid-cols-3",
)}
>
<UsageTabCard
id="links"
icon={Hyperlink}
title="Links created"
usage={linksUsage}
limit={linksLimit}
root
/>
<UsageTabCard
id="events"
icon={CursorRays}
title="Events tracked"
usage={usage}
limit={usageLimit}
/>
<UsageTabCard
id="links"
icon={Hyperlink}
title="Links created"
usage={linksUsage}
limit={linksLimit}
/>
{conversionEnabled && (
<UsageTabCard
id="revenue"
Expand Down Expand Up @@ -202,20 +199,19 @@ function UsageTabCard({
usage: usageProp,
limit: limitProp,
unit,
root,
}: {
id: string;
icon: Icon;
title: string;
usage?: number;
limit?: number;
unit?: string;
root?: boolean;
}) {
const { searchParams, queryParams } = useRouterStuff();

const isActive =
searchParams.get("tab") === id || (!searchParams.get("tab") && root);
searchParams.get("tab") === id ||
(!searchParams.get("tab") && id === "events");

const [usage, limit] =
unit === "$" && usageProp !== undefined && limitProp !== undefined
Expand Down Expand Up @@ -265,12 +261,11 @@ function UsageTabCard({
>
<div
className={cn(
"size-full rounded-full [mask-image:linear-gradient(90deg,transparent,black_80%)]",
"size-full rounded-full bg-gradient-to-r from-blue-500/80 to-blue-600",
warning && "to-rose-500",
)}
style={{
transform: `translateX(-${100 - Math.floor((usage / Math.max(0, usage, limit)) * 100)}%)`,
backgroundImage: `linear-gradient(90deg, #D8277A, #7E3AEA)`,
}}
/>
</div>
Expand All @@ -282,7 +277,7 @@ function UsageTabCard({
<span className="text-xs leading-none text-neutral-600">
{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 })}`}
</span>
) : (
<div className="h-4 w-20 animate-pulse rounded-md bg-gray-200" />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ const resourceEmptyStates: Record<
export function UsageChart() {
const searchParams = useSearchParams();
const resource =
RESOURCES.find((r) => r === searchParams.get("tab")) ?? "links";
RESOURCES.find((r) => r === searchParams.get("tab")) ?? "events";

const { usage, loading } = useUsage({ resource });

Expand Down Expand Up @@ -95,16 +95,15 @@ export function UsageChart() {
}}
>
<LinearGradient id="usage-bar-gradient">
<stop stopColor="#7E3AEA" stopOpacity={1} offset="20%" />
<stop stopColor="#D8277A" stopOpacity={0} offset="100%" />
<stop stopColor="#2563eb" stopOpacity={1} offset="20%" />
<stop stopColor="#3b82f6" stopOpacity={0.9} offset="100%" />
</LinearGradient>
<Bars
seriesStyles={[
{
id: "usage",
barFill: "#00000019",
},
]}
<XAxis highlightLast={false} />
<YAxis
showGridLines
tickFormat={
resource === "revenue" ? (v) => `$${nFormatter(v)}` : nFormatter
}
/>
<Bars
seriesStyles={[
Expand All @@ -114,13 +113,6 @@ export function UsageChart() {
},
]}
/>
<XAxis highlightLast={false} />
<YAxis
showGridLines
tickFormat={
resource === "revenue" ? (v) => `$${nFormatter(v)}` : nFormatter
}
/>
</TimeSeriesChart>
) : (
<div className="flex size-full items-center justify-center">
Expand Down
Original file line number Diff line number Diff line change
@@ -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,
Expand Down
4 changes: 2 additions & 2 deletions apps/web/app/app.dub.co/(onboarding)/layout.tsx
Original file line number Diff line number Diff line change
@@ -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 (
<Providers>
<Background />
<NewBackground />
{children}
<Toolbar show={["help"]} />
</Providers>
Expand Down
Loading

0 comments on commit 5aabf5d

Please sign in to comment.