Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 10 additions & 2 deletions app/(app)/ads/slots/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,15 @@ export default async function SlotsPage() {
<Link href="/ads" className="text-sm text-[var(--color-muted)]">
← Ad campaigns
</Link>
<h1 className="mt-4 text-3xl font-bold">Monetize your site</h1>
<div className="mt-4 flex items-center justify-between gap-4">
<h1 className="text-3xl font-bold">Monetize your site</h1>
{/* Always-visible way to add a site to monetize — a site is a project,
so this starts the project-creation flow. Previously the only link
to it was hidden inside the empty state. */}
<Link href="/projects/new?next=/ads/slots" className="btn btn-primary whitespace-nowrap">
Monetize a new site
</Link>
</div>
<p className="mt-2 text-[var(--color-muted)]">
Show CrawlProof network ads on your site and earn crypto for the clicks. Opt a
project in, drop one tag on your page, and add a payout wallet.
Expand All @@ -104,7 +112,7 @@ export default async function SlotsPage() {
{projects.length === 0 ? (
<div className="card mt-6 p-8 text-center text-[var(--color-muted)]">
You have no projects yet.{" "}
<Link href="/projects/new" className="text-[var(--color-accent)]">
<Link href="/projects/new?next=/ads/slots" className="text-[var(--color-accent)]">
Create one
</Link>{" "}
to enable a slot.
Expand Down
12 changes: 10 additions & 2 deletions app/(app)/projects/new/form.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@ import { useState, useTransition } from "react";
import { useRouter } from "next/navigation";
import { createProject } from "@/app/actions/createProject";

// Only honour same-site relative paths (guards against open redirects).
function safeNext(next: string | null | undefined): string | null {
return next && next.startsWith("/") && !next.startsWith("//") ? next : null;
}

function deriveName(url: string): string {
if (!url) return "";
try {
Expand All @@ -14,8 +19,11 @@ function deriveName(url: string): string {
}
}

export function NewProjectForm() {
export function NewProjectForm({ next }: { next?: string | null }) {
const router = useRouter();
// e.g. /projects/new?next=/ads/slots — return to Monetize after creating so
// the new site is right there to "Enable ads".
const nextPath = safeNext(next);
const [pending, startTransition] = useTransition();
const [name, setName] = useState("");
const [nameTouched, setNameTouched] = useState(false);
Expand All @@ -41,7 +49,7 @@ export function NewProjectForm() {
setError(res.error ?? "Could not create project.");
return;
}
router.push(`/projects/${res.id}`);
router.push(nextPath ?? `/projects/${res.id}`);
});
}

Expand Down
9 changes: 7 additions & 2 deletions app/(app)/projects/new/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,12 @@ import { NewProjectForm } from "./form";

export const metadata = { title: "New project" };

export default function NewProjectPage() {
export default async function NewProjectPage({
searchParams,
}: {
searchParams: Promise<{ next?: string }>;
}) {
const { next } = await searchParams;
return (
<div className="mx-auto max-w-xl">
<Link href="/dashboard" className="text-sm text-[var(--color-muted)]">
Expand All @@ -13,7 +18,7 @@ export default function NewProjectPage() {
<p className="mt-2 text-[var(--color-muted)]">
Group audits under one project. You can also schedule weekly re-audits on Pro.
</p>
<NewProjectForm />
<NewProjectForm next={next} />
</div>
);
}
Loading