Add src/app/admin/page.tsx

This commit is contained in:
2026-03-06 12:02:11 +00:00
parent 53f5949bec
commit 56153ea13e

311
src/app/admin/page.tsx Normal file
View File

@@ -0,0 +1,311 @@
"use client";
import { useState } from "react";
import { ThemeProvider } from "@/providers/themeProvider/ThemeProvider";
import NavbarStyleApple from "@/components/navbar/NavbarStyleApple/NavbarStyleApple";
import FooterBaseReveal from "@/components/sections/footer/FooterBaseReveal";
import { BarChart3, TrendingUp, DollarSign, Eye, Plus, Edit2, Trash2, Search } from "lucide-react";
export default function AdminPage() {
const navItems = [
{ name: "Home", id: "/" },
{ name: "How It Works", id: "#how-it-works" },
{ name: "Top Products", id: "#products" },
{ name: "Admin", id: "/admin" },
{ name: "Contact", id: "#contact" },
];
const [campaigns, setCampaigns] = useState([
{
id: 1,
name: "Wireless Earbuds Campaign", status: "active", impressions: 45230,
clicks: 1240,
conversions: 89,
revenue: 4450,
ctr: 2.74,
conversionRate: 7.18,
},
{
id: 2,
name: "Power Bank Q1 Push", status: "active", impressions: 32100,
clicks: 890,
conversions: 52,
revenue: 2340,
ctr: 2.77,
conversionRate: 5.84,
},
{
id: 3,
name: "LED Lamp Bundle", status: "paused", impressions: 28900,
clicks: 720,
conversions: 41,
revenue: 1845,
ctr: 2.49,
conversionRate: 5.69,
},
]);
const totalMetrics = {
totalImpressions: campaigns.reduce((sum, c) => sum + c.impressions, 0),
totalClicks: campaigns.reduce((sum, c) => sum + c.clicks, 0),
totalConversions: campaigns.reduce((sum, c) => sum + c.conversions, 0),
totalRevenue: campaigns.reduce((sum, c) => sum + c.revenue, 0),
overallCTR: 2.67,
overallConversionRate: 6.24,
};
const [searchTerm, setSearchTerm] = useState("");
const [selectedCampaign, setSelectedCampaign] = useState<typeof campaigns[0] | null>(null);
const filteredCampaigns = campaigns.filter((campaign) =>
campaign.name.toLowerCase().includes(searchTerm.toLowerCase())
);
return (
<ThemeProvider
defaultButtonVariant="text-stagger"
defaultTextAnimation="reveal-blur"
borderRadius="rounded"
contentWidth="mediumLarge"
sizing="mediumSizeLargeTitles"
background="circleGradient"
cardStyle="glass-depth"
primaryButtonStyle="shadow"
secondaryButtonStyle="glass"
headingFontWeight="semibold"
>
<div id="nav" data-section="nav">
<NavbarStyleApple brandName="ProductHuntr" navItems={navItems} />
</div>
<div className="min-h-screen bg-background py-20 px-4">
<div className="max-w-7xl mx-auto">
{/* Header */}
<div className="mb-12">
<h1 className="text-5xl font-bold text-foreground mb-4">Ad Management Dashboard</h1>
<p className="text-lg text-foreground/70">Manage campaigns, track performance, and monitor revenue generation</p>
</div>
{/* KPI Cards */}
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-12">
<div className="bg-card border border-accent/20 rounded-lg p-6">
<div className="flex items-center justify-between mb-4">
<h3 className="text-foreground/70 text-sm font-medium">Total Revenue</h3>
<DollarSign className="w-5 h-5 text-primary-cta" />
</div>
<p className="text-4xl font-bold text-foreground">${totalMetrics.totalRevenue.toLocaleString()}</p>
<p className="text-sm text-foreground/50 mt-2">From {campaigns.length} active campaigns</p>
</div>
<div className="bg-card border border-accent/20 rounded-lg p-6">
<div className="flex items-center justify-between mb-4">
<h3 className="text-foreground/70 text-sm font-medium">Total Conversions</h3>
<TrendingUp className="w-5 h-5 text-primary-cta" />
</div>
<p className="text-4xl font-bold text-foreground">{totalMetrics.totalConversions}</p>
<p className="text-sm text-foreground/50 mt-2">Conversion rate: {totalMetrics.overallConversionRate}%</p>
</div>
<div className="bg-card border border-accent/20 rounded-lg p-6">
<div className="flex items-center justify-between mb-4">
<h3 className="text-foreground/70 text-sm font-medium">Total Impressions</h3>
<Eye className="w-5 h-5 text-primary-cta" />
</div>
<p className="text-4xl font-bold text-foreground">{(totalMetrics.totalImpressions / 1000).toFixed(1)}K</p>
<p className="text-sm text-foreground/50 mt-2">CTR: {totalMetrics.overallCTR}%</p>
</div>
<div className="bg-card border border-accent/20 rounded-lg p-6">
<div className="flex items-center justify-between mb-4">
<h3 className="text-foreground/70 text-sm font-medium">Total Clicks</h3>
<BarChart3 className="w-5 h-5 text-primary-cta" />
</div>
<p className="text-4xl font-bold text-foreground">{totalMetrics.totalClicks.toLocaleString()}</p>
<p className="text-sm text-foreground/50 mt-2">From impressions</p>
</div>
</div>
{/* Campaign Management */}
<div className="bg-card border border-accent/20 rounded-lg p-8">
<div className="flex flex-col md:flex-row justify-between items-start md:items-center gap-6 mb-8">
<h2 className="text-3xl font-bold text-foreground">Campaign Manager</h2>
<div className="flex gap-4 w-full md:w-auto">
<div className="relative flex-1 md:flex-none md:w-64">
<Search className="absolute left-3 top-1/2 transform -translate-y-1/2 w-4 h-4 text-foreground/40" />
<input
type="text"
placeholder="Search campaigns..."
value={searchTerm}
onChange={(e) => setSearchTerm(e.target.value)}
className="w-full pl-10 pr-4 py-2 bg-background border border-accent/20 rounded-lg text-foreground placeholder-foreground/40 focus:outline-none focus:border-primary-cta"
/>
</div>
<button className="px-6 py-2 bg-primary-cta text-background rounded-lg font-medium hover:opacity-90 transition-opacity flex items-center gap-2 whitespace-nowrap">
<Plus className="w-4 h-4" />
New Campaign
</button>
</div>
</div>
{/* Campaign Table */}
<div className="overflow-x-auto">
<table className="w-full text-sm">
<thead>
<tr className="border-b border-accent/20">
<th className="text-left py-4 px-4 text-foreground/70 font-semibold">Campaign Name</th>
<th className="text-left py-4 px-4 text-foreground/70 font-semibold">Status</th>
<th className="text-right py-4 px-4 text-foreground/70 font-semibold">Impressions</th>
<th className="text-right py-4 px-4 text-foreground/70 font-semibold">Clicks</th>
<th className="text-right py-4 px-4 text-foreground/70 font-semibold">CTR</th>
<th className="text-right py-4 px-4 text-foreground/70 font-semibold">Conversions</th>
<th className="text-right py-4 px-4 text-foreground/70 font-semibold">Revenue</th>
<th className="text-right py-4 px-4 text-foreground/70 font-semibold">Actions</th>
</tr>
</thead>
<tbody>
{filteredCampaigns.map((campaign) => (
<tr key={campaign.id} className="border-b border-accent/10 hover:bg-background/50 transition-colors">
<td className="py-4 px-4 text-foreground font-medium">{campaign.name}</td>
<td className="py-4 px-4">
<span
className={`px-3 py-1 rounded-full text-xs font-semibold ${
campaign.status === "active"
? "bg-green-500/20 text-green-400"
: "bg-yellow-500/20 text-yellow-400"
}`}
>
{campaign.status.charAt(0).toUpperCase() + campaign.status.slice(1)}
</span>
</td>
<td className="py-4 px-4 text-right text-foreground">{campaign.impressions.toLocaleString()}</td>
<td className="py-4 px-4 text-right text-foreground">{campaign.clicks.toLocaleString()}</td>
<td className="py-4 px-4 text-right text-foreground">{campaign.ctr}%</td>
<td className="py-4 px-4 text-right text-foreground">{campaign.conversions}</td>
<td className="py-4 px-4 text-right font-bold text-primary-cta">${campaign.revenue.toLocaleString()}</td>
<td className="py-4 px-4 text-right">
<div className="flex justify-end gap-2">
<button
onClick={() => setSelectedCampaign(campaign)}
className="p-2 hover:bg-background rounded transition-colors"
title="View Details"
>
<Eye className="w-4 h-4 text-foreground/60" />
</button>
<button className="p-2 hover:bg-background rounded transition-colors" title="Edit">
<Edit2 className="w-4 h-4 text-foreground/60" />
</button>
<button className="p-2 hover:bg-background rounded transition-colors" title="Delete">
<Trash2 className="w-4 h-4 text-foreground/60" />
</button>
</div>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
{/* Campaign Details Modal */}
{selectedCampaign && (
<div className="fixed inset-0 bg-background/80 backdrop-blur-sm flex items-center justify-center z-50 p-4">
<div className="bg-card border border-accent/20 rounded-lg p-8 max-w-2xl w-full">
<div className="flex justify-between items-start mb-6">
<div>
<h3 className="text-2xl font-bold text-foreground">{selectedCampaign.name}</h3>
<span
className={`inline-block mt-2 px-3 py-1 rounded-full text-xs font-semibold ${
selectedCampaign.status === "active"
? "bg-green-500/20 text-green-400"
: "bg-yellow-500/20 text-yellow-400"
}`}
>
{selectedCampaign.status.charAt(0).toUpperCase() + selectedCampaign.status.slice(1)}
</span>
</div>
<button
onClick={() => setSelectedCampaign(null)}
className="text-foreground/60 hover:text-foreground transition-colors text-2xl"
>
×
</button>
</div>
<div className="grid grid-cols-2 gap-6 mb-8">
<div>
<p className="text-foreground/70 text-sm mb-1">Impressions</p>
<p className="text-3xl font-bold text-foreground">{selectedCampaign.impressions.toLocaleString()}</p>
</div>
<div>
<p className="text-foreground/70 text-sm mb-1">Clicks</p>
<p className="text-3xl font-bold text-foreground">{selectedCampaign.clicks.toLocaleString()}</p>
</div>
<div>
<p className="text-foreground/70 text-sm mb-1">Conversions</p>
<p className="text-3xl font-bold text-foreground">{selectedCampaign.conversions}</p>
</div>
<div>
<p className="text-foreground/70 text-sm mb-1">Revenue</p>
<p className="text-3xl font-bold text-primary-cta">${selectedCampaign.revenue.toLocaleString()}</p>
</div>
<div>
<p className="text-foreground/70 text-sm mb-1">CTR</p>
<p className="text-3xl font-bold text-foreground">{selectedCampaign.ctr}%</p>
</div>
<div>
<p className="text-foreground/70 text-sm mb-1">Conversion Rate</p>
<p className="text-3xl font-bold text-foreground">{selectedCampaign.conversionRate}%</p>
</div>
</div>
<div className="flex gap-4 justify-end">
<button
onClick={() => setSelectedCampaign(null)}
className="px-6 py-2 bg-background border border-accent/20 text-foreground rounded-lg font-medium hover:bg-background/80 transition-colors"
>
Close
</button>
<button className="px-6 py-2 bg-primary-cta text-background rounded-lg font-medium hover:opacity-90 transition-opacity">
Edit Campaign
</button>
</div>
</div>
</div>
)}
</div>
</div>
<div id="footer" data-section="footer">
<FooterBaseReveal
columns={[
{
title: "Product", items: [
{ label: "How It Works", href: "#how-it-works" },
{ label: "Top Products", href: "#products" },
{ label: "Admin", href: "/admin" },
{ label: "Dashboard", href: "#" },
],
},
{
title: "Company", items: [
{ label: "About Us", href: "/" },
{ label: "Blog", href: "#" },
{ label: "Careers", href: "#" },
{ label: "Contact", href: "#contact" },
],
},
{
title: "Legal", items: [
{ label: "Privacy Policy", href: "#" },
{ label: "Terms of Service", href: "#" },
{ label: "Cookie Policy", href: "#" },
{ label: "Affiliate Disclosure", href: "#" },
],
},
]}
copyrightText="© 2025 ProductHuntr. All rights reserved. | Affiliate Partnerships: Amazon | Walmart | eBay | Alibaba"
/>
</div>
</ThemeProvider>
);
}