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
13 changes: 3 additions & 10 deletions app/(app)/apps/[id]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -331,14 +331,7 @@ function ApiTab({ model }: { model: App }) {
<KeyBadge prefix={defaultKey.prefix} />
<p className="mt-2 text-[11px] text-fg-faint">
Drop this into the{" "}
<code className="text-fg-muted">Authorization</code> header below, or{" "}
<Link
href="/settings?tab=tokens"
className="text-fg-strong underline-offset-2 hover:text-fg hover:underline"
>
manage your keys
</Link>
.
<code className="text-fg-muted">Authorization</code> header below.
</p>
</div>

Expand Down Expand Up @@ -371,10 +364,10 @@ function ApiTab({ model }: { model: App }) {
Billed per request. Free tier covers your first 10,000 each month.
</span>
<Link
href="/settings?tab=billing"
href="/home"
className="text-fg-strong underline-offset-2 hover:text-fg hover:underline"
>
Add a payment provider
View usage
</Link>
</div>
</div>
Expand Down
8 changes: 4 additions & 4 deletions app/(app)/calls/page.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
import { redirect } from "next/navigation";

/**
* `/calls` folded into `/usage` for the creator pilot — the call log now
* renders underneath Spend by capability rather than as its own destination.
* `/calls` folded into `/home` for the creator pilot — the call log now
* renders on Home rather than as its own destination.
*
* The route stays as a redirect because `?request=<id>` links to a single call
* are already in the wild (the app-detail log table, the Home activity panel
* before it was removed, anything anyone bookmarked). The param carries over
* so those still open the call drawer, just on Usage.
* so those still open the call drawer, just on Home.
*/
export default async function CallsPage({
searchParams,
Expand All @@ -17,5 +17,5 @@ export default async function CallsPage({
const params = await searchParams;
const request = params.request;
const id = Array.isArray(request) ? request[0] : request;
redirect(id ? `/usage?request=${encodeURIComponent(id)}` : "/usage");
redirect(id ? `/home?request=${encodeURIComponent(id)}` : "/home");
}
3 changes: 1 addition & 2 deletions app/(app)/device/DeviceApproveForm.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
"use client";

import { useState, type ReactNode } from "react";
import { Smartphone } from "lucide-react";
import Button from "@/components/design-system/Button";
import ConsolePageHeader from "@/components/console/ConsolePageHeader";

export function DevicePageChrome({ children }: { children: ReactNode }) {
return (
<>
<ConsolePageHeader title="Device sign-in" icon={Smartphone} />
<ConsolePageHeader title="Device sign-in" />
<div className="mx-auto w-full max-w-5xl px-6 py-8">{children}</div>
</>
);
Expand Down
91 changes: 19 additions & 72 deletions app/(app)/home/page.tsx
Original file line number Diff line number Diff line change
@@ -1,86 +1,33 @@
"use client";

import { useEffect } from "react";
import { useRouter } from "next/navigation";
import { House } from "lucide-react";
import { Suspense } from "react";
import { useAuth } from "@/components/console/AuthContext";
import ConsolePageHeader from "@/components/console/ConsolePageHeader";
import HomeCommandBar from "@/components/console/HomeCommandBar";
import McpConnectPanel from "@/components/console/McpConnectPanel";

function HomePageHeader() {
return <ConsolePageHeader title="Home" icon={House} />;
}

// ─── Home Page ───
//
// One job: get the MCP endpoint into the user's agent.
//
// Home used to be an operations dashboard — a first-run checklist, a spend
// panel and a recent-activity preview. All three came out for the creator
// pilot:
//
// • the checklist walked through provisioning an API key, and the pilot
// provisions none — connecting a harness is the whole of onboarding now
// • the spend panel and activity preview restated /usage, which is one
// click away in the rail and carries the real versions
//
// What's left is deliberately sparse. A creator arriving here should be a
// couple of copies away from having Livepeer inside their agent, and the page
// should read as early — because it is.
//
// The running balance is not repeated here: it sits in the sidebar card, which
// is on screen for every route rather than only this one.
import ConsolePageSkeleton from "@/components/console/ConsolePageSkeleton";
import SignInWall from "@/components/console/SignInWall";
import UsageView from "@/components/console/UsageView";

export default function HomePage() {
const { isConnected, isLoading, user } = useAuth();
const router = useRouter();
return (
<Suspense fallback={<ConsolePageSkeleton kpiCount={4} withChart />}>
<HomeContent />
</Suspense>
);
}

// Middleware already sends signed-out requests to /login before this page
// is served (see middleware.ts). This client-side fallback only fires if
// the session lapses while the console is open.
useEffect(() => {
if (!isLoading && (!isConnected || !user)) {
router.replace("/login");
}
}, [isLoading, isConnected, user, router]);
function HomeContent() {
const { isConnected, isLoading } = useAuth();

// Avoid flashing the wall while auth hydrates.
if (isLoading) return null;

// Redirect is in flight; render nothing while it takes effect.
if (!isConnected || !user) return null;

const firstName = user.name.split(" ")[0] || "there";
// Organization-only route — logged-out users see the in-shell sign-in wall
// instead of a hard redirect.
if (!isConnected) return <SignInWall route="home" />;

return (
<main id="main-content" className="relative flex flex-1 flex-col bg-dark">
{/* Atmosphere — a faint brand-green aura bleeding from the top edge, so
the console reads as a lit panel rather than a flat page. */}
<div
className="pointer-events-none absolute inset-x-0 top-0 h-72"
style={{
background:
"radial-gradient(70% 100% at 50% 0%, color-mix(in oklab, var(--color-green-bright) 7%, transparent) 0%, transparent 72%)",
}}
aria-hidden="true"
/>

<HomePageHeader />
<div className="relative flex-1 overflow-y-auto">
<div className="mx-auto w-full max-w-5xl px-7 pb-20 pt-8">
<div className="home-rise">
<HomeCommandBar firstName={firstName} />
<p className="mt-2.5 max-w-xl text-[13.5px] leading-[1.55] text-fg-muted">
Livepeer Agent runs as an MCP server your agent runtime calls
directly. Connect one below and every capability on the network —
video, image, audio, 3D — becomes something you can just ask for.
</p>
</div>

<div className="home-rise mt-7" style={{ animationDelay: "60ms" }}>
<McpConnectPanel />
</div>
</div>
<main id="main-content" className="flex flex-1 flex-col bg-dark">
<div className="flex flex-1 flex-col">
<UsageView />
</div>
</main>
);
Expand Down
Loading