Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
683352e
feat: add YOUTUBE_UPLOAD_VISIBILITY env var, default to private (#596)
codercatdev Mar 4, 2026
45e53eb
feat: Phase A β€” scene type system, SceneRouter, ElevenLabs timestamps…
Mar 4, 2026
55f2d02
Merge branch 'main' into dev
codercatdev Mar 4, 2026
674e6a7
feat: Phase B β€” CodeMorphScene + DynamicListScene components
Mar 4, 2026
a671590
Merge branch 'main' into dev
codercatdev Mar 4, 2026
363805a
Merge feat/scene-components-phase-a into dev β€” Scene type system, Cod…
Mar 4, 2026
b62c10d
feat: add after() pattern + distribution log for error recovery
Mar 4, 2026
58af6e2
feat: Sanity-backed settings + pipeline status indicators
Mar 4, 2026
f89c607
feat: remove CSS transitions from Remotion components + wire per-scen…
Mar 4, 2026
24855da
Merge feat/pipeline-followup β€” CSS cleanup + per-scene audio wiring
Mar 4, 2026
beb2b70
feat: add NotebookLM research bridge service (CLI wrapper)
Mar 4, 2026
09c5034
feat: add trend discovery service (HN, Dev.to, blogs, YouTube, GitHub…
Mar 4, 2026
1c5a615
feat: Phase D β€” ComparisonGridScene + IsometricMockupScene components
Mar 4, 2026
d77a373
fix: address PR review β€” fail-closed auth, input validation, renderin…
Mar 4, 2026
36b843b
Merge branch 'polish/dashboard-settings-pipeline' into dev
Mar 4, 2026
ab4be6b
Merge feat/scene-components-phase-d β€” ComparisonGridScene + Isometric…
Mar 4, 2026
b18c9e9
fix: address PR review β€” dynamic year, typed YouTube response, nullab…
Mar 4, 2026
5a90d6f
Merge feat/trend-discovery-ts into dev β€” Trend discovery (5 sources) …
Mar 4, 2026
69a9e8b
feat: wire trend discovery + research into ingest cron route
Mar 4, 2026
433ceff
fix: wrap discoverTrends() in try/catch for graceful fallback
Mar 4, 2026
5bfa0e0
Merge feat/wire-trend-research into dev β€” ingest cron uses 5-source t…
Mar 4, 2026
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
7 changes: 5 additions & 2 deletions app/(dashboard)/dashboard/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ export const dynamic = "force-dynamic";

import { SectionCardsLive } from "@/components/section-cards-live";
import { RecentActivity } from "@/components/recent-activity";
import { PipelineStatus } from "@/components/pipeline-status";

export default function DashboardPage() {
return (
Expand All @@ -11,7 +12,7 @@ export default function DashboardPage() {
Content Ops Dashboard
</h1>
<p className="text-muted-foreground">
Overview of your automated content engine \u2014 videos, sponsors,
Overview of your automated content engine β€” videos, sponsors,
and pipeline health.
</p>
</div>
Expand All @@ -25,7 +26,9 @@ export default function DashboardPage() {
<p className="mt-2 text-sm text-muted-foreground">
Real-time view of content moving through the pipeline.
</p>
{/* Pipeline status will be added here */}
<div className="mt-4">
<PipelineStatus />
</div>
</div>
</div>
</div>
Expand Down
214 changes: 34 additions & 180 deletions app/(dashboard)/dashboard/settings/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,46 +5,8 @@ import {
CardHeader,
CardTitle,
} from "@/components/ui/card";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Badge } from "@/components/ui/badge";
import { Separator } from "@/components/ui/separator";

const PUBLISH_DAYS = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
const DEFAULT_PUBLISH_DAYS = ["Mon", "Wed", "Fri"];

const CONTENT_CATEGORIES = [
"JavaScript",
"TypeScript",
"React",
"Next.js",
"Angular",
"Svelte",
"Node.js",
"CSS",
"DevOps",
"AI / ML",
"Web Performance",
"Tooling",
];

const RATE_CARD_TIERS = [
{
name: "Pre-roll Mention",
description: "15-second sponsor mention at the start of the video",
price: "$200",
},
{
name: "Mid-roll Segment",
description: "60-second dedicated sponsor segment mid-video",
price: "$500",
},
{
name: "Dedicated Video",
description: "Full sponsored video with product deep-dive",
price: "$1,500",
},
];
import { SettingsForm } from "./settings-form";

const INTEGRATIONS = [
{
Expand Down Expand Up @@ -112,150 +74,42 @@ export default function SettingsPage() {
</p>
</div>

<div className="rounded-lg border border-dashed bg-muted/50 p-4 text-sm text-muted-foreground">
<strong>Note:</strong> Settings are currently read-only. Editing will be
enabled in a future phase once a settings schema is added to Sanity.
</div>

<div className="grid gap-6 md:grid-cols-2">
{/* Publishing Cadence */}
<Card>
<CardHeader>
<CardTitle>Publishing Cadence</CardTitle>
<CardDescription>
Control how often videos are published and on which days.
</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<div className="space-y-2">
<Label htmlFor="videos-per-week">Videos per week</Label>
<Input
id="videos-per-week"
type="number"
defaultValue={3}
min={1}
max={7}
disabled
className="w-24"
/>
</div>
<Separator />
<div className="space-y-2">
<Label>Preferred publish days</Label>
<div className="flex flex-wrap gap-2">
{PUBLISH_DAYS.map((day) => (
<Badge
key={day}
variant={
DEFAULT_PUBLISH_DAYS.includes(day)
? "default"
: "outline"
}
className="cursor-default"
>
{day}
</Badge>
))}
</div>
</div>
<p className="text-xs text-muted-foreground">
Settings will be stored in Sanity once a settings schema is
created.
</p>
</CardContent>
</Card>
<SettingsForm />

{/* Content Categories */}
<Card>
<CardHeader>
<CardTitle>Content Categories</CardTitle>
<CardDescription>
Categories used for content idea classification and YouTube
metadata.
</CardDescription>
</CardHeader>
<CardContent className="space-y-4">
<div className="flex flex-wrap gap-2">
{CONTENT_CATEGORIES.map((category) => (
<Badge key={category} variant="secondary">
{category}
</Badge>
))}
</div>
<p className="text-xs text-muted-foreground">
Custom category management will be available in a future phase.
</p>
</CardContent>
</Card>

{/* Sponsor Rate Card */}
<Card>
<CardHeader>
<CardTitle>Sponsor Rate Card</CardTitle>
<CardDescription>
Sponsorship tiers and pricing used by the sponsor portal and
pipeline.
</CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-3">
{RATE_CARD_TIERS.map((tier) => (
<div
key={tier.name}
className="flex items-center justify-between rounded-lg border p-3"
>
<div>
<p className="text-sm font-medium">{tier.name}</p>
<p className="text-xs text-muted-foreground">
{tier.description}
</p>
</div>
<span className="text-sm font-semibold">{tier.price}</span>
{/* Integrations Status β€” server-rendered */}
<Card>
<CardHeader>
<CardTitle>Integrations Status</CardTitle>
<CardDescription>
Connection status for external services. Green indicates the
environment variable is configured.
</CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-3">
{integrationStatus.map((integration) => (
<div
key={integration.name}
className="flex items-center gap-3"
>
<IntegrationDot connected={integration.connected} />
<div className="flex-1">
<p className="text-sm font-medium">{integration.name}</p>
<p className="text-xs text-muted-foreground">
{integration.description}
</p>
</div>
))}
</div>
<p className="mt-4 text-xs text-muted-foreground">
Rate card editing will be available once the sponsor rate card
schema is finalized.
</p>
</CardContent>
</Card>

{/* Integrations Status */}
<Card>
<CardHeader>
<CardTitle>Integrations Status</CardTitle>
<CardDescription>
Connection status for external services. Green indicates the
environment variable is configured.
</CardDescription>
</CardHeader>
<CardContent>
<div className="space-y-3">
{integrationStatus.map((integration) => (
<div
key={integration.name}
className="flex items-center gap-3"
<Badge
variant={integration.connected ? "default" : "outline"}
className="text-xs"
>
<IntegrationDot connected={integration.connected} />
<div className="flex-1">
<p className="text-sm font-medium">{integration.name}</p>
<p className="text-xs text-muted-foreground">
{integration.description}
</p>
</div>
<Badge
variant={integration.connected ? "default" : "outline"}
className="text-xs"
>
{integration.connected ? "Connected" : "Not configured"}
</Badge>
</div>
))}
</div>
</CardContent>
</Card>
</div>
{integration.connected ? "Connected" : "Not configured"}
</Badge>
</div>
))}
</div>
</CardContent>
</Card>
</div>
);
}
Loading
Loading