deepsite-project-41uyr / dashboard.html
VibeCodingStudio's picture
🐳 19/05 - 17:17 - I want you to go through every page, and I want you to add smooth transitions and interactive elements and better looking elements as well as 3D elements and designs. As well as Exp
b94499a verified
Raw
History Blame Contribute Delete
22.4 kB
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Dashboard — NSFWStudio</title>
<script src="https://cdn.tailwindcss.com"></script>
<script src="https://unpkg.com/lucide@latest"></script>
<script src="https://unpkg.com/react@18/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:opsz,wght@14..32,300..800&family=JetBrains+Mono:wght@400;500;600&display=swap" rel="stylesheet">
<script>
tailwind.config = {
theme: {
extend: {
fontFamily: { sans: ['Inter','system-ui','sans-serif'], mono: ['JetBrains Mono','monospace'] },
colors: {
bg: 'oklch(0.07 0.006 285)', surface: 'oklch(0.12 0.02 285)', 'surface-2': 'oklch(0.16 0.025 285)', 'surface-3': 'oklch(0.20 0.028 285)',
fg: 'oklch(0.97 0.005 285)', muted: 'oklch(0.55 0.02 285)', primary: 'oklch(0.70 0.28 350)', 'primary-foreground': 'oklch(0.98 0.005 285)',
secondary: 'oklch(0.75 0.15 215)', accent: 'oklch(0.80 0.18 85)', border: 'oklch(0.22 0.02 285)', ring: 'oklch(0.70 0.28 350)',
destructive: 'oklch(0.55 0.22 25)', success: 'oklch(0.65 0.2 145)',
},
},
},
}
</script>
<style>
body { background-color: oklch(0.07 0.006 285); color: oklch(0.97 0.005 285); font-family: 'Inter', system-ui, sans-serif; -webkit-font-smoothing: antialiased; }
.glass { background: oklch(0.14 0.015 285 / 0.6); backdrop-filter: blur(24px) saturate(1.2); -webkit-backdrop-filter: blur(24px) saturate(1.2); border: 1px solid oklch(0.25 0.02 285 / 0.5); }
.gradient-text { background: linear-gradient(135deg, oklch(0.70 0.28 350), oklch(0.75 0.15 215)); -webkit-background-clip: text; -webkit-text-fill-color: transparent; background-clip: text; }
::selection { background: oklch(0.70 0.28 350 / 0.3); color: white; }
body::after { content:''; position:fixed; inset:0; pointer-events:none; z-index:9999; opacity:0.025; background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='n'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23n)'/%3E%3C/svg%3E"); background-repeat:repeat; background-size:256px 256px; }
.no-scrollbar::-webkit-scrollbar { display: none; } .no-scrollbar { -ms-overflow-style: none; scrollbar-width: none; }
.tabular-nums { font-variant-numeric: tabular-nums; }
.card-3d { transition: transform 0.4s cubic-bezier(0.25, 0.46, 0.45, 0.94), box-shadow 0.4s ease; }
.card-3d:hover { transform: perspective(1000px) rotateY(-3deg) rotateX(2deg) translateZ(15px); box-shadow: 0 20px 40px rgba(0,0,0,0.35), 0 0 0 1px oklch(0.70 0.28 350 / 0.2); }
.hover-lift { transition: transform 0.3s cubic-bezier(0.34, 1.56, 0.64, 1), box-shadow 0.3s ease; }
.hover-lift:hover { transform: translateY(-6px) scale(1.02); box-shadow: 0 15px 30px rgba(0,0,0,0.3); }
.gradient-border-animated { position: relative; isolation: isolate; }
.gradient-border-animated::before { content: ''; position: absolute; inset: 0; border-radius: inherit; padding: 1.5px; background: linear-gradient(270deg, oklch(0.70 0.28 350), oklch(0.75 0.15 215), oklch(0.80 0.18 85), oklch(0.70 0.28 350)); background-size: 300% 100%; -webkit-mask: linear-gradient(#fff 0 0) content-box, linear-gradient(#fff 0 0); -webkit-mask-composite: xor; mask-composite: exclude; opacity: 0; transition: opacity 0.3s ease; }
.gradient-border-animated:hover::before { opacity: 1; }
@keyframes slideUp { from { opacity: 0; transform: translateY(20px); } to { opacity: 1; transform: translateY(0); } }
.animate-slide-up { animation: slideUp 0.5s ease-out forwards; }
.glow-ring:hover { box-shadow: 0 0 0 2px oklch(0.70 0.28 350 / 0.3), 0 0 20px oklch(0.70 0.28 350 / 0.1); }
</style>
</head>
<body class="antialiased">
<div id="root"></div>
<script type="text/babel">
const { useState } = React;
const Icon = ({ name, size = 20, className = "", strokeWidth = 2 }) => {
const ref = React.useRef(null);
React.useEffect(() => { if (ref.current) { const existing = ref.current.querySelector('svg'); if (existing) existing.remove(); const svg = lucide.createElement(lucide.icons[name]); if (svg) { svg.setAttribute('width',size); svg.setAttribute('height',size); svg.setAttribute('stroke-width',strokeWidth); ref.current.appendChild(svg); } } }, [name, size, className, strokeWidth]);
return <span ref={ref} className={`inline-flex items-center justify-center ${className}`} style={{ width: size, height: size }} />;
};
const navItems = [
{ name: 'Dashboard', icon: 'layout-dashboard', href: 'dashboard.html', active: true },
{ name: 'Generator', icon: 'sparkles', href: 'generator.html' },
{ name: 'Playground', icon: 'code', href: 'playground.html' },
{ name: 'Models', icon: 'box', href: 'models.html' },
{ name: 'Workflows', icon: 'workflow', href: 'workflows.html' },
{ name: 'Marketplace', icon: 'shopping-bag', href: 'marketplace.html' },
{ name: 'API Keys', icon: 'key', href: 'api-keys.html' },
{ divider: true },
{ name: 'Profile', icon: 'user', href: 'profile.html' },
{ name: 'Settings', icon: 'settings', href: 'settings.html' },
];
const Sidebar = ({ isOpen, setIsOpen }) => (
<>
{/* Mobile overlay */}
<div className={`fixed inset-0 z-40 lg:hidden transition-all ${isOpen ? 'opacity-100 pointer-events-auto' : 'opacity-0 pointer-events-none'}`}>
<div className="absolute inset-0 bg-black/60 backdrop-blur-sm" onClick={() => setIsOpen(false)} />
</div>
<aside className={`fixed top-0 left-0 bottom-0 z-50 w-64 bg-surface border-r border-border flex flex-col transition-transform duration-300 lg:translate-x-0 ${isOpen ? 'translate-x-0' : '-translate-x-full'}`}>
<div className="p-4 flex items-center gap-2.5 border-b border-border">
<div className="w-8 h-8 rounded-lg bg-primary flex items-center justify-center"><Icon name="sparkles" size={16} className="text-primary-foreground" /></div>
<span className="text-lg font-bold tracking-tight">NSFW<span className="text-muted">Studio</span></span>
</div>
<nav className="flex-1 p-3 space-y-1 overflow-y-auto no-scrollbar">
{navItems.map((item, i) => item.divider ? <div key={i} className="my-3 border-t border-border" /> : (
<a key={i} href={item.href} className={`flex items-center gap-3 px-3 py-2.5 rounded-xl text-sm font-medium transition-colors ${item.active ? 'bg-primary/10 text-primary border border-primary/20' : 'text-muted hover:text-fg hover:bg-surface-2 border border-transparent'}`}>
<Icon name={item.icon} size={18} />{item.name}
</a>
))}
</nav>
<div className="p-4 border-t border-border">
<a href="documentation.html" className="flex items-center gap-3 px-3 py-2.5 rounded-xl text-sm text-muted hover:text-fg hover:bg-surface-2 transition-colors">
<Icon name="book-open" size={18} />Documentation
</a>
<a href="api-reference.html" className="flex items-center gap-3 px-3 py-2.5 rounded-xl text-sm text-muted hover:text-fg hover:bg-surface-2 transition-colors">
<Icon name="file-code" size={18} />API Reference
</a>
</div>
</aside>
</>
);
const App = () => {
const [sidebarOpen, setSidebarOpen] = useState(false);
const stats = [
{ label: 'Generations', value: '12,847', change: '+14.2%', icon: 'image', color: 'text-primary', bg: 'bg-primary/10' },
{ label: 'Revenue', value: '$8,492', change: '+23.1%', icon: 'dollar-sign', color: 'text-success', bg: 'bg-success/10' },
{ label: 'Followers', value: '2,341', change: '+8.7%', icon: 'users', color: 'text-secondary', bg: 'bg-secondary/10' },
{ label: 'API Calls', value: '284K', change: '+31.5%', icon: 'activity', color: 'text-accent', bg: 'bg-accent/10' },
];
const [hoveredStat, setHoveredStat] = useState(null);
const recentGens = [
{ title: 'Crimson Seductress', model: 'EroticDream XL', time: '2m ago', status: 'completed', img: 'http://static.photos/cyberpunk/200x200/5' },
{ title: 'Dark Temptation', model: 'SinfulAnime XL', time: '5m ago', status: 'completed', img: 'http://static.photos/people/200x200/6' },
{ title: 'Velvet Dungeon', model: 'Fantasy Flesh XL', time: '8m ago', status: 'completed', img: 'http://static.photos/nature/200x200/7' },
{ title: 'Neon Curves', model: 'PhotoReal Erotica', time: '12m ago', status: 'completed', img: 'http://static.photos/technology/200x200/8' },
{ title: 'Shibari Art', model: 'DarkSeduction v3', time: '15m ago', status: 'processing', img: 'http://static.photos/people/200x200/9' },
];
const activity = [
{ text: 'New follower: @dark_pixel', time: '1m ago', icon: 'user-plus', color: 'text-secondary' },
{ text: 'Your model earned $49.00', time: '3m ago', icon: 'dollar-sign', color: 'text-success' },
{ text: 'Workflow "Auto Tag" completed', time: '7m ago', icon: 'check-circle', color: 'text-primary' },
{ text: 'Comment on "Neon Cityscape"', time: '10m ago', icon: 'message-circle', color: 'text-accent' },
{ text: 'API key rotation reminder', time: '1h ago', icon: 'key', color: 'text-muted' },
];
const topModels = [
{ name: 'DreamVision XL', runs: '45.2K', revenue: '$2,340', trend: '+12%' },
{ name: 'CyberPunk v3', runs: '28.1K', revenue: '$1,890', trend: '+8%' },
{ name: 'Anime Diffusion', runs: '19.7K', revenue: '$1,230', trend: '+21%' },
];
return (
<div className="min-h-screen bg-bg">
<Sidebar isOpen={sidebarOpen} setIsOpen={setSidebarOpen} />
<div className="lg:ml-64">
{/* Top bar */}
<header className="sticky top-0 z-30 glass border-b border-border">
<div className="flex items-center justify-between px-4 sm:px-6 h-16">
<div className="flex items-center gap-4">
<button onClick={() => setSidebarOpen(true)} className="lg:hidden p-2 rounded-lg hover:bg-surface-2 text-muted"><Icon name="menu" size={20} /></button>
<div className="hidden sm:flex items-center gap-2 px-4 py-2 rounded-xl bg-surface-2 border border-border text-muted text-sm w-72">
<Icon name="search" size={16} />
<span>Search anything...</span>
</div>
</div>
<div className="flex items-center gap-3">
<button className="p-2 rounded-lg hover:bg-surface-2 text-muted hover:text-fg transition-colors relative">
<Icon name="bell" size={20} />
<span className="absolute top-1.5 right-1.5 w-2 h-2 rounded-full bg-primary" />
</button>
<a href="generator.html" className="px-4 py-2 rounded-lg bg-primary text-primary-foreground text-sm font-semibold hover:brightness-110 transition-all">+ New</a>
<a href="profile.html" className="w-9 h-9 rounded-lg overflow-hidden border border-border">
<img src="http://static.photos/people/100x100/10" alt="" className="w-full h-full object-cover" />
</a>
</div>
</div>
</header>
<main className="p-4 sm:p-6 lg:p-8">
<div className="mb-8">
<h1 className="text-2xl sm:text-3xl font-bold mb-1">Welcome back, <span className="gradient-text">Neon</span></h1>
<p className="text-muted">Here's what's happening with your creations today.</p>
</div>
{/* Stats */}
<div className="grid grid-cols-2 lg:grid-cols-4 gap-4 mb-8">
{stats.map((s, i) => (
<div key={i} className="rounded-2xl p-5 bg-surface border border-border hover:border-primary/30 transition-all duration-500 card-3d gradient-border-animated"
style={{animationDelay: `${i * 0.1}s`, animation: 'slideUp 0.5s ease-out forwards', opacity: 0}}
onMouseEnter={() => setHoveredStat(i)} onMouseLeave={() => setHoveredStat(null)}>
<div className="flex items-center justify-between mb-3">
<div className={`w-10 h-10 rounded-xl ${s.bg} flex items-center justify-center transition-transform duration-300 ${hoveredStat === i ? 'scale-110' : ''}`}><Icon name={s.icon} size={18} className={s.color} /></div>
<span className="text-xs font-bold text-success bg-success/10 px-2.5 py-1 rounded-full border border-success/20">{s.change}</span>
</div>
<div className="text-2xl font-bold text-fg tabular-nums">{s.value}</div>
<div className="text-xs text-muted mt-1">{s.label}</div>
</div>
))}
</div>
<div className="grid lg:grid-cols-3 gap-6">
{/* Recent Generations */}
<div className="lg:col-span-2 rounded-2xl p-6 bg-surface border border-border">
<div className="flex items-center justify-between mb-5">
<h2 className="text-lg font-semibold">Recent Generations</h2>
<a href="generator.html" className="text-sm text-primary hover:underline flex items-center gap-1">View all <Icon name="arrow-right" size={14} /></a>
</div>
<div className="space-y-3">
{recentGens.map((g, i) => (
<div key={i} className="flex items-center gap-4 p-3 rounded-xl hover:bg-surface-2/50 transition-colors cursor-pointer group">
<img src={g.img} alt="" className="w-12 h-12 rounded-xl object-cover border border-border" />
<div className="flex-1 min-w-0">
<div className="text-sm font-medium text-fg truncate">{g.title}</div>
<div className="text-xs text-muted">{g.model} · {g.time}</div>
</div>
<span className={`px-2.5 py-1 rounded-full text-xs font-semibold ${g.status === 'completed' ? 'bg-success/10 text-success border border-success/20' : 'bg-primary/10 text-primary border border-primary/20'}`}>
{g.status}
</span>
</div>
))}
</div>
</div>
{/* Right column */}
<div className="space-y-6">
{/* Activity */}
<div className="rounded-2xl p-6 bg-surface border border-border">
<h2 className="text-lg font-semibold mb-4">Activity</h2>
<div className="space-y-4">
{activity.map((a, i) => (
<div key={i} className="flex items-start gap-3">
<div className={`mt-0.5 ${a.color}`}><Icon name={a.icon} size={16} /></div>
<div className="flex-1 min-w-0">
<div className="text-sm text-fg/90">{a.text}</div>
<div className="text-xs text-muted mt-0.5">{a.time}</div>
</div>
</div>
))}
</div>
</div>
{/* Top Models */}
<div className="rounded-2xl p-6 bg-surface border border-border">
<div className="flex items-center justify-between mb-4">
<h2 className="text-lg font-semibold">Top Models</h2>
<a href="models.html" className="text-xs text-primary hover:underline">See all</a>
</div>
<div className="space-y-3">
{topModels.map((m, i) => (
<div key={i} className="flex items-center justify-between p-3 rounded-xl hover:bg-surface-2/50 transition-colors cursor-pointer">
<div className="flex items-center gap-3">
<span className="w-6 h-6 rounded-full bg-surface-2 flex items-center justify-center text-xs font-bold text-muted">{i+1}</span>
<div>
<div className="text-sm font-medium text-fg">{m.name}</div>
<div className="text-xs text-muted">{m.runs} runs</div>
</div>
</div>
<div className="text-right">
<div className="text-sm font-semibold text-fg">{m.revenue}</div>
<div className="text-xs text-success">{m.trend}</div>
</div>
</div>
))}
</div>
</div>
</div>
</div>
{/* Quick Actions */}
<div className="mt-8 grid grid-cols-2 sm:grid-cols-4 gap-3">
{[
{ label: 'Generate Image', icon: 'image', color: 'text-primary', bg: 'bg-primary/10', href: 'generator.html' },
{ label: 'Create Workflow', icon: 'workflow', color: 'text-secondary', bg: 'bg-secondary/10', href: 'workflows.html' },
{ label: 'Train Model', icon: 'box', color: 'text-success', bg: 'bg-success/10', href: 'models.html' },
{ label: 'Explore Marketplace', icon: 'shopping-bag', color: 'text-accent', bg: 'bg-accent/10', href: 'marketplace.html' },
].map((a, i) => (
<a key={i} href={a.href} className="group flex flex-col items-center gap-3 p-5 rounded-2xl bg-surface border border-border hover:border-surface-3 transition-all hover:-translate-y-0.5">
<div className={`w-12 h-12 rounded-xl ${a.bg} flex items-center justify-center group-hover:scale-110 transition-transform`}><Icon name={a.icon} size={22} className={a.color} /></div>
<span className="text-sm font-medium text-fg">{a.label}</span>
</a>
))}
</div>
</main>
</div>
</div>
);
};
ReactDOM.createRoot(document.getElementById('root')).render(<App />);
</script>
</body>
</html>