Skip to content
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
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
199 changes: 175 additions & 24 deletions app/projects/page.tsx
Original file line number Diff line number Diff line change
@@ -1,30 +1,181 @@
import ProjectGrid from "@/components/project/project-grid";
import { AuroraText } from "@/components/utils/aurora-text";
import { generateMetadata as getMetadata } from "@/config/meta";
import { projectConfig } from "@/config/projects";
"use client";

export const metadata = getMetadata("/projects");
import React from "react";
import {
FileText,
Users,
DollarSign,
Activity,
Plus,
ArrowUpRight,
TrendingUp,
Clock,
} from "lucide-react";
import { motion } from "framer-motion";

export default function Projects() {
export default function DashboardPage() {
return (
<section className="mt-20 relative flex min-h-screen items-center justify-center overflow-hidden px-4 text-center">
<div className="relative z-10 mx-auto max-w-5xl">
<h1 className="text-4xl md:text-7xl font-bold leading-tight">
100+{" "}
<AuroraText
colors={["#22d3ee", "#3b82f6", "#6366f1", "#a855f7", "#ec4899"]}
>
React JS
</AuroraText>{" "}
Projects
</h1>

<p className="mt-4 md:mt-6 text-sm md:text-xl text-foreground/60 max-w-2xl mx-auto">
{projectConfig.description}
</p>

<ProjectGrid />
<div className="p-6 space-y-6">
{/* Header */}
<div className="flex flex-col md:flex-row md:items-center md:justify-between gap-4">
<div>
<h1 className="text-3xl font-semibold tracking-tight">
Dashboard
</h1>
<p className="text-sm text-muted-foreground">
Overview of your platform performance and activity
</p>
</div>

<button className="flex items-center gap-2 bg-primary text-primary-foreground px-4 py-2 rounded-lg shadow hover:opacity-90 transition">
<Plus size={16} />
New Project
</button>
</div>

{/* Stats */}
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
<StatCard
title="Projects"
value="24"
change="+12%"
icon={<FileText size={18} />}
/>
<StatCard
title="Users"
value="1,240"
change="+5%"
icon={<Users size={18} />}
/>
<StatCard
title="Revenue"
value="$12.4K"
change="+18%"
icon={<DollarSign size={18} />}
/>
<StatCard
title="Growth"
value="89%"
change="+3%"
icon={<TrendingUp size={18} />}
/>
</div>

{/* Main Grid */}
<div className="grid grid-cols-1 lg:grid-cols-3 gap-6">
{/* Activity */}
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
className="lg:col-span-2 bg-card p-5 rounded-xl border shadow-sm"
>
<div className="flex items-center justify-between mb-4">
<h2 className="text-lg font-medium">Recent Activity</h2>
<Clock size={16} className="text-muted-foreground" />
</div>

<div className="space-y-3">
{activityData.map((item, i) => (
<div
key={i}
className="flex items-center justify-between p-3 rounded-lg bg-muted hover:bg-accent transition cursor-pointer"
>
<div>
<p className="text-sm">{item.title}</p>
<span className="text-xs text-muted-foreground">
{item.time}
</span>
</div>
<ArrowUpRight size={16} />
</div>
))}
</div>
</motion.div>

{/* Quick Actions */}
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
className="bg-card p-5 rounded-xl border shadow-sm"
>
<h2 className="text-lg font-medium mb-4">Quick Actions</h2>

<div className="space-y-3">
{actions.map((a, i) => (
<button
key={i}
className="w-full text-left p-3 rounded-lg bg-muted hover:bg-accent transition text-sm"
>
{a}
</button>
))}
</div>
</motion.div>
</div>

{/* Projects */}
<div className="bg-card p-5 rounded-xl border shadow-sm">
<div className="flex items-center justify-between mb-4">
<h2 className="text-lg font-medium">Projects</h2>
<button className="text-sm text-primary hover:underline">
View all
</button>
</div>

<div className="grid sm:grid-cols-2 lg:grid-cols-3 gap-4">
{projects.map((p, i) => (
<motion.div
key={i}
whileHover={{ scale: 1.03 }}
className="p-4 rounded-lg border bg-muted hover:bg-accent transition cursor-pointer"
>
<h3 className="font-medium">{p.name}</h3>
<p className="text-xs text-muted-foreground mt-1">
{p.desc}
</p>
</motion.div>
))}
</div>
</div>
</section>
</div>
);
}


function StatCard({ title, value, change, icon }: any) {
return (
<motion.div
whileHover={{ scale: 1.02 }}
className="bg-card p-4 rounded-xl border shadow-sm flex flex-col gap-2"
>
<div className="flex items-center justify-between text-muted-foreground">
{icon}
<span className="text-xs text-green-500">{change}</span>
</div>

<h3 className="text-xl font-semibold">{value}</h3>
<p className="text-sm text-muted-foreground">{title}</p>
</motion.div>
);
}

/* Data */
const activityData = [
{ title: "New user registered", time: "2 min ago" },
{ title: "Payment received", time: "10 min ago" },
{ title: "Project updated", time: "1 hour ago" },
{ title: "New project created", time: "3 hours ago" },
];

const actions = [
"Create Project",
"Invite User",
"Generate Report",
"View Analytics",
];

const projects = [
{ name: "Admin Dashboard", desc: "Internal analytics panel" },
{ name: "E-commerce App", desc: "Shopping platform UI" },
{ name: "Portfolio Website", desc: "Personal branding site" },
];
123 changes: 122 additions & 1 deletion styles/globals.css
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,128 @@

--animate-aurora: aurora 8s ease-in-out infinite alternate;

@keyframes aurora {

{
transition: background-color 0.2s ease, color 0.2s ease, border-color 0.2s ease, transform 0.15s ease;
}

/* Better text rendering */
body {
-webkit-font-smoothing: antialiased;
text-rendering: optimizeLegibility;
}

/* Scrollbar (modern minimal) */
::-webkit-scrollbar {
width: 8px;
height: 8px;
}

::-webkit-scrollbar-track {
background: transparent;
}

::-webkit-scrollbar-thumb {
background: hsl(0 0% 60% / 0.4);
border-radius: 999px;
}

::-webkit-scrollbar-thumb:hover {
background: hsl(0 0% 50% / 0.6);
}

.dark ::-webkit-scrollbar-thumb {
background: hsl(0 0% 40% / 0.5);
}

::selection {
background: var(--color-primary);
color: var(--color-primary-foreground);
}

/* Smooth anchor scrolling */
html {
scroll-behavior: smooth;
}

.card {
@apply bg-card text-card-foreground border rounded-xl shadow-sm;
}


.card-hover {
@apply hover:shadow-md hover:-translate-y-1;
}
.btn {
@apply inline-flex items-center justify-center rounded-lg px-4 py-2 text-sm font-medium transition;
}

.btn-primary {
@apply bg-primary text-primary-foreground hover:opacity-90 active:scale-95;
}

/* Secondary button */
.btn-secondary {
@apply bg-secondary text-secondary-foreground hover:bg-muted;
}

/* Input styling */
.input {
@apply w-full px-3 py-2 rounded-lg border bg-input text-sm outline-none focus:ring-2 focus:ring-ring;
}

/* Glass effect */
.glass {
background: rgba(255, 255, 255, 0.6);
backdrop-filter: blur(12px);
border: 1px solid rgba(255, 255, 255, 0.2);
}

.dark .glass {
background: rgba(20, 20, 20, 0.6);
border: 1px solid rgba(255, 255, 255, 0.05);
}

/* Gradient text */
.gradient-text {
background: linear-gradient(to right, var(--color-primary), #60a5fa);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
}

@keyframes fadeUp {
from {
opacity: 0;
transform: translateY(12px);
}
to {
opacity: 1;
transform: translateY(0);
}
}

@keyframes fadeIn {
from {
opacity: 0;
}
to {
opacity: 1;
}
}

.animate-fadeUp {
animation: fadeUp 0.4s ease forwards;
}

.animate-fadeIn {
animation: fadeIn 0.3s ease forwards;
}

:focus-visible {
outline: 2px solid var(--color-ring);
outline-offset: 2px;
}
@keyframes aurora {
0% {
background-position: 0% 50%;
transform: rotate(-5deg) scale(0.9);
Expand Down