Add dynamic footer badge marquee with admin management.

Store badges in Postgres, expose public/admin APIs, render an infinite footer slider, and ship /admin for paste-embed CRUD.
This commit is contained in:
Atakan Doğan Özban
2026-08-01 19:58:24 +02:00
parent 89c49bcd33
commit 6bf2bffc55
21 changed files with 1027 additions and 20 deletions
@@ -0,0 +1,43 @@
-- CreateTable
CREATE TABLE "FooterBadge" (
"id" TEXT NOT NULL,
"name" TEXT NOT NULL,
"embedHtml" TEXT,
"imageUrl" TEXT,
"linkUrl" TEXT,
"isActive" BOOLEAN NOT NULL DEFAULT true,
"sortOrder" INTEGER NOT NULL DEFAULT 0,
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
"updatedAt" TIMESTAMP(3) NOT NULL,
CONSTRAINT "FooterBadge_pkey" PRIMARY KEY ("id")
);
-- CreateIndex
CREATE INDEX "FooterBadge_isActive_sortOrder_idx" ON "FooterBadge"("isActive", "sortOrder");
-- Seed current Product Hunt + LaunchBuff badges
INSERT INTO "FooterBadge" ("id", "name", "embedHtml", "imageUrl", "linkUrl", "isActive", "sortOrder", "createdAt", "updatedAt")
VALUES
(
'seed_producthunt',
'Product Hunt',
'<a href="https://www.producthunt.com/products/songs2vid?embed=true&utm_source=badge-featured&utm_medium=badge&utm_campaign=badge-songs2vid" target="_blank" rel="noopener noreferrer"><img alt="Songs2VID - Bulk render audio & artworks into videos in seconds | Product Hunt" width="250" height="54" src="https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=1206681&theme=dark&t=1785422871345" /></a>',
'https://api.producthunt.com/widgets/embed-image/v1/featured.svg?post_id=1206681&theme=dark&t=1785422871345',
'https://www.producthunt.com/products/songs2vid?embed=true&utm_source=badge-featured&utm_medium=badge&utm_campaign=badge-songs2vid',
true,
0,
CURRENT_TIMESTAMP,
CURRENT_TIMESTAMP
),
(
'seed_launchbuff',
'LaunchBuff',
'<a href="https://launchbuff.com" target="_blank" rel="noopener noreferrer" title="Featured on LaunchBuff"><img src="https://launchbuff.com/badge-featured-dark.svg" alt="Featured on LaunchBuff" width="256" height="80" /></a>',
'https://launchbuff.com/badge-featured-dark.svg',
'https://launchbuff.com',
true,
1,
CURRENT_TIMESTAMP,
CURRENT_TIMESTAMP
);
+18
View File
@@ -189,3 +189,21 @@ model JobItem {
youtubeVideoId String?
error String?
}
/// Site footer badge / launch-directory embeds (managed via /admin)
model FooterBadge {
id String @id @default(cuid())
name String
/// Raw paste from Product Hunt / LaunchBuff / etc. (preferred source)
embedHtml String? @db.Text
/// Parsed or manually set image URL (used when embedHtml is empty)
imageUrl String?
/// Parsed or manually set destination URL
linkUrl String?
isActive Boolean @default(true)
sortOrder Int @default(0)
createdAt DateTime @default(now())
updatedAt DateTime @updatedAt
@@index([isActive, sortOrder])
}