Files
Trey t 807dfc539b feat: add asset preferences, video research, and Remotion ad assets
- Add thumbs-down feedback modal and preference API endpoint
- Add AI UGC video platforms research doc
- Add ReflectAd Remotion composition with public flow assets
- Add gemini-ad-designer and poster-ad-designer pipeline skills
- Add research_reflect_v1.1 pipeline script

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-03 20:28:07 -05:00

106 lines
3.2 KiB
TypeScript

"use client";
import { useEffect, useState } from "react";
import Link from "next/link";
import { Plus } from "lucide-react";
import { Button } from "@/components/ui/button";
import {
Card,
CardContent,
CardDescription,
CardHeader,
CardTitle,
} from "@/components/ui/card";
interface AppItem {
id: string;
name: string;
slug: string;
description: string | null;
primaryColor: string;
accentColor: string;
createdAt: string;
_count: { campaigns: number };
}
export default function AppsPage() {
const [apps, setApps] = useState<AppItem[]>([]);
const [loading, setLoading] = useState(true);
useEffect(() => {
fetch("/api/apps")
.then((r) => r.json())
.then((data) => {
setApps(data);
setLoading(false);
})
.catch(() => setLoading(false));
}, []);
return (
<div>
<div className="mb-6 flex items-center justify-between">
<div>
<h1 className="text-2xl font-bold">Apps</h1>
<p className="text-muted-foreground">
Manage apps sharing this marketing pipeline
</p>
</div>
<Button render={<Link href="/apps/new" />}>
<Plus className="mr-2 h-4 w-4" />
Add App
</Button>
</div>
{loading ? (
<div className="text-muted-foreground">Loading...</div>
) : apps.length === 0 ? (
<Card>
<CardContent className="py-10 text-center text-muted-foreground">
No apps yet. Create one to get started.
</CardContent>
</Card>
) : (
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
{apps.map((app) => (
<Link key={app.id} href={`/apps/${app.slug}`}>
<Card className="h-full transition-shadow hover:shadow-md">
<CardHeader className="pb-3">
<div className="flex items-center gap-3">
<div
className="h-8 w-8 rounded-lg"
style={{ backgroundColor: app.primaryColor }}
/>
<div>
<CardTitle className="text-lg">{app.name}</CardTitle>
<CardDescription>/{app.slug}</CardDescription>
</div>
</div>
</CardHeader>
<CardContent>
<p className="mb-3 text-sm text-muted-foreground line-clamp-2">
{app.description || "No description"}
</p>
<div className="flex items-center gap-2 text-sm text-muted-foreground">
<div
className="h-3 w-3 rounded"
style={{ backgroundColor: app.primaryColor }}
/>
<div
className="h-3 w-3 rounded"
style={{ backgroundColor: app.accentColor }}
/>
<span className="ml-auto">
{app._count.campaigns} campaign{app._count.campaigns !== 1 ? "s" : ""}
</span>
</div>
</CardContent>
</Card>
</Link>
))}
</div>
)}
</div>
);
}