changed a lot

This commit is contained in:
Harivansh Rathi 2024-11-25 01:24:37 -05:00
parent ef9ccf22d3
commit 28901128ff
20 changed files with 1794 additions and 526 deletions

View file

@ -1,9 +1,14 @@
const DashboardLayout = ({ children }: { children: React.ReactNode }) => {
return (
<main className="max-w-6xl w-full flex items-center justify-center px-6">
{children}
</main>
)
import { Metadata } from "next"
export const metadata: Metadata = {
title: "Dashboard",
description: "Task management and team collaboration dashboard",
}
export default DashboardLayout
export default function DashboardLayout({
children,
}: {
children: React.ReactNode
}) {
return children
}

View file

@ -1,62 +1,151 @@
import { Metadata } from 'next'
"use client"
import {
Calendar,
CheckCircle2,
Clock,
ListTodo,
Plus,
UserRoundCheck
} from 'lucide-react'
import { Button } from '@/components/ui/button'
import { Card } from '@/components/ui/card'
import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs'
import { auth } from '@/auth'
import { redirect } from 'next/navigation'
import { db } from '@/lib/db'
Search,
Bell,
Mail,
Settings,
} from "lucide-react"
import { Button } from "@/components/ui/button"
import { Card } from "@/components/ui/card"
import { Input } from "@/components/ui/input"
import { ProjectSelect } from "@/components/project-select"
import { TaskColumn } from "@/components/task-column"
import { RichTextEditor } from "@/components/rich-text-editor"
import { FileUpload } from "@/components/file-upload"
import {
DndContext,
DragEndEvent,
DragOverlay,
DragStartEvent,
MouseSensor,
TouchSensor,
useSensor,
useSensors,
} from "@dnd-kit/core"
import { useState } from "react"
import { TaskCard } from "@/components/task-card"
export const metadata: Metadata = {
title: 'Dashboard',
description: 'Task management and team collaboration dashboard'
interface Task {
id: string
title: string
status: string
dueDate: string
progress: number
}
export default async function DashboardPage() {
const session = await auth()
export default function DashboardPage() {
const [tasks, setTasks] = useState<Task[]>([
{ id: "1", title: "Design new landing page", status: "In Progress", dueDate: "2023-12-01", progress: 60 },
{ id: "2", title: "Implement authentication", status: "Todo", dueDate: "2023-12-05", progress: 0 },
{ id: "3", title: "Write documentation", status: "Done", dueDate: "2023-11-30", progress: 100 },
])
if (!session) {
redirect('/login')
const [activeTask, setActiveTask] = useState<Task | null>(null)
const sensors = useSensors(
useSensor(MouseSensor, {
activationConstraint: {
distance: 8,
},
}),
useSensor(TouchSensor, {
activationConstraint: {
delay: 300,
tolerance: 8,
},
})
)
const handleDragStart = (event: DragStartEvent) => {
const { active } = event
const task = tasks.find(t => t.id === active.id)
if (task) {
setActiveTask(task)
}
}
// Fetch tasks (placeholder - implement actual DB queries)
const tasks = [
{ id: 1, title: 'Design new landing page', status: 'In Progress', dueDate: '2023-12-01', progress: 60 },
{ id: 2, title: 'Implement authentication', status: 'Todo', dueDate: '2023-12-05', progress: 0 },
{ id: 3, title: 'Write documentation', status: 'Done', dueDate: '2023-11-30', progress: 100 }
]
const handleDragEnd = (event: DragEndEvent) => {
const { active, over } = event
if (over && active.id !== over.id) {
setTasks(tasks => {
const oldIndex = tasks.findIndex(t => t.id === active.id)
const task = tasks[oldIndex]
const newStatus = over.id as string
if (task && (newStatus === "Todo" || newStatus === "In Progress" || newStatus === "Done")) {
const updatedTasks = [...tasks]
updatedTasks[oldIndex] = { ...task, status: newStatus }
return updatedTasks
}
return tasks
})
}
setActiveTask(null)
}
return (
<div className="flex-1 space-y-4 p-4 md:p-8 pt-6">
<div className="flex items-center justify-between space-y-2">
<h2 className="text-3xl font-bold tracking-tight">Dashboard</h2>
<div className="flex items-center space-x-2">
<Button>
<Plus className="mr-2 h-4 w-4" />
Add New Task
</Button>
<div className="flex min-h-screen">
{/* Sidebar */}
<aside className="w-64 border-r bg-card">
<div className="p-6">
<h2 className="text-lg font-semibold">Shadcn UI Kit</h2>
</div>
</div>
<nav className="px-4 space-y-2">
<Button variant="ghost" className="w-full justify-start">
<ListTodo className="mr-2 h-4 w-4" />
Dashboard
</Button>
<Button variant="ghost" className="w-full justify-start">
<Mail className="mr-2 h-4 w-4" />
Messages
</Button>
<Button variant="ghost" className="w-full justify-start">
<Settings className="mr-2 h-4 w-4" />
Settings
</Button>
</nav>
</aside>
<Tabs defaultValue="overview" className="space-y-4">
<TabsList>
<TabsTrigger value="overview">Overview</TabsTrigger>
<TabsTrigger value="tasks">Tasks</TabsTrigger>
<TabsTrigger value="calendar">Calendar</TabsTrigger>
</TabsList>
{/* Main Content */}
<main className="flex-1">
{/* Header */}
<header className="border-b">
<div className="flex h-16 items-center px-6 gap-4">
<ProjectSelect />
<div className="flex-1">
<form>
<div className="relative">
<Search className="absolute left-2.5 top-2.5 h-4 w-4 text-muted-foreground" />
<Input
type="search"
placeholder="Search..."
className="w-full bg-background pl-8 md:w-[300px]"
/>
</div>
</form>
</div>
<Button variant="ghost" size="icon">
<Bell className="h-4 w-4" />
</Button>
</div>
</header>
<TabsContent value="overview" className="space-y-4">
{/* Dashboard Content */}
<div className="p-6 space-y-6">
{/* Stats */}
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-4">
<Card className="p-4">
<div className="space-y-2">
<div className="flex items-center space-x-2">
<div className="flex items-center gap-2">
<ListTodo className="h-4 w-4 text-muted-foreground" />
<span className="text-sm font-medium">Total Tasks</span>
</div>
@ -65,7 +154,7 @@ export default async function DashboardPage() {
</Card>
<Card className="p-4">
<div className="space-y-2">
<div className="flex items-center space-x-2">
<div className="flex items-center gap-2">
<Clock className="h-4 w-4 text-muted-foreground" />
<span className="text-sm font-medium">In Progress</span>
</div>
@ -74,7 +163,7 @@ export default async function DashboardPage() {
</Card>
<Card className="p-4">
<div className="space-y-2">
<div className="flex items-center space-x-2">
<div className="flex items-center gap-2">
<CheckCircle2 className="h-4 w-4 text-muted-foreground" />
<span className="text-sm font-medium">Completed</span>
</div>
@ -83,218 +172,77 @@ export default async function DashboardPage() {
</Card>
<Card className="p-4">
<div className="space-y-2">
<div className="flex items-center space-x-2">
<UserRoundCheck className="h-4 w-4 text-muted-foreground" />
<span className="text-sm font-medium">Team Members</span>
<div className="flex items-center gap-2">
<Calendar className="h-4 w-4 text-muted-foreground" />
<span className="text-sm font-medium">Upcoming</span>
</div>
<div className="text-2xl font-bold">6</div>
<div className="text-2xl font-bold">3</div>
</div>
</Card>
</div>
<div className="grid gap-4 md:grid-cols-2 lg:grid-cols-7">
<Card className="col-span-4">
<div className="p-6">
<h3 className="text-lg font-medium">Recent Tasks</h3>
<div className="mt-4 space-y-4">
{tasks.map(task => (
<div key={task.id} className="flex items-center justify-between border-b pb-4">
<div>
<h4 className="font-medium">{task.title}</h4>
<p className="text-sm text-muted-foreground">Due: {task.dueDate}</p>
</div>
<div className="flex items-center space-x-4">
<span className="text-sm">{task.status}</span>
<div className="h-2 w-24 bg-gray-200 rounded-full">
<div
className="h-full bg-blue-500 rounded-full"
style={{ width: `${task.progress}%` }}
/>
</div>
</div>
</div>
))}
</div>
</div>
</Card>
{/* Task Board */}
<div className="space-y-4">
<div className="flex items-center justify-between">
<h2 className="text-2xl font-bold tracking-tight">Tasks</h2>
<Button>
<Plus className="mr-2 h-4 w-4" />
Add Task
</Button>
</div>
<Card className="col-span-3">
<div className="p-6">
<h3 className="text-lg font-medium">Upcoming Deadlines</h3>
<div className="mt-4 space-y-4">
<div className="flex items-center space-x-4">
<Calendar className="h-4 w-4 text-muted-foreground" />
<div>
<p className="font-medium">Design Review</p>
<p className="text-sm text-muted-foreground">Tomorrow at 2:00 PM</p>
</div>
</div>
<div className="flex items-center space-x-4">
<Calendar className="h-4 w-4 text-muted-foreground" />
<div>
<p className="font-medium">Team Meeting</p>
<p className="text-sm text-muted-foreground">Friday at 10:00 AM</p>
</div>
</div>
</div>
<DndContext
sensors={sensors}
onDragStart={handleDragStart}
onDragEnd={handleDragEnd}
>
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
<TaskColumn
id="Todo"
title="Todo"
icon={ListTodo}
tasks={tasks.filter(t => t.status === "Todo")}
/>
<TaskColumn
id="In Progress"
title="In Progress"
icon={Clock}
tasks={tasks.filter(t => t.status === "In Progress")}
/>
<TaskColumn
id="Done"
title="Done"
icon={CheckCircle2}
tasks={tasks.filter(t => t.status === "Done")}
/>
</div>
</Card>
</div>
</TabsContent>
<TabsContent value="tasks" className="space-y-4">
<div className="flex justify-between items-center">
<h3 className="text-lg font-medium">All Tasks</h3>
<Button>
<Plus className="mr-2 h-4 w-4" />
New Task
</Button>
<DragOverlay>
{activeTask ? <TaskCard {...activeTask} /> : null}
</DragOverlay>
</DndContext>
</div>
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
{/* Todo Column */}
<Card className="p-4">
<h4 className="font-medium mb-4 flex items-center">
<ListTodo className="h-4 w-4 mr-2" />
Todo
</h4>
<div className="space-y-4">
{tasks.filter(t => t.status === 'Todo').map(task => (
<Card key={task.id} className="p-3">
<h5 className="font-medium">{task.title}</h5>
<p className="text-sm text-muted-foreground mt-1">Due: {task.dueDate}</p>
<div className="mt-3 h-1.5 w-full bg-gray-100 rounded-full">
<div
className="h-full bg-blue-500 rounded-full"
style={{ width: `${task.progress}%` }}
/>
</div>
</Card>
))}
</div>
</Card>
{/* In Progress Column */}
<Card className="p-4">
<h4 className="font-medium mb-4 flex items-center">
<Clock className="h-4 w-4 mr-2" />
In Progress
</h4>
<div className="space-y-4">
{tasks.filter(t => t.status === 'In Progress').map(task => (
<Card key={task.id} className="p-3">
<h5 className="font-medium">{task.title}</h5>
<p className="text-sm text-muted-foreground mt-1">Due: {task.dueDate}</p>
<div className="mt-3 h-1.5 w-full bg-gray-100 rounded-full">
<div
className="h-full bg-blue-500 rounded-full"
style={{ width: `${task.progress}%` }}
/>
</div>
</Card>
))}
</div>
</Card>
{/* Done Column */}
<Card className="p-4">
<h4 className="font-medium mb-4 flex items-center">
<CheckCircle2 className="h-4 w-4 mr-2" />
Done
</h4>
<div className="space-y-4">
{tasks.filter(t => t.status === 'Done').map(task => (
<Card key={task.id} className="p-3">
<h5 className="font-medium">{task.title}</h5>
<p className="text-sm text-muted-foreground mt-1">Due: {task.dueDate}</p>
<div className="mt-3 h-1.5 w-full bg-gray-100 rounded-full">
<div
className="h-full bg-blue-500 rounded-full"
style={{ width: `${task.progress}%` }}
/>
</div>
</Card>
))}
</div>
</Card>
</div>
</TabsContent>
<TabsContent value="calendar" className="space-y-4">
<div className="flex justify-between items-center">
<h3 className="text-lg font-medium">Calendar</h3>
<Button variant="outline">
<Calendar className="mr-2 h-4 w-4" />
Select Date
</Button>
</div>
<div className="grid gap-4">
{/* Task Details */}
<div className="grid gap-6 md:grid-cols-2">
<Card className="p-6">
<div className="space-y-6">
{/* Today's Schedule */}
<div>
<h4 className="font-medium mb-4">Today's Schedule</h4>
<div className="space-y-4">
<div className="flex items-center space-x-4">
<div className="w-14 text-sm text-muted-foreground">09:00 AM</div>
<div className="flex-1">
<Card className="p-3">
<h5 className="font-medium">Team Standup</h5>
<p className="text-sm text-muted-foreground">Daily team sync meeting</p>
</Card>
</div>
</div>
<div className="flex items-center space-x-4">
<div className="w-14 text-sm text-muted-foreground">02:00 PM</div>
<div className="flex-1">
<Card className="p-3">
<h5 className="font-medium">Design Review</h5>
<p className="text-sm text-muted-foreground">Review new landing page design</p>
</Card>
</div>
</div>
<div className="flex items-center space-x-4">
<div className="w-14 text-sm text-muted-foreground">04:30 PM</div>
<div className="flex-1">
<Card className="p-3">
<h5 className="font-medium">Sprint Planning</h5>
<p className="text-sm text-muted-foreground">Plan next sprint tasks</p>
</Card>
</div>
</div>
</div>
</div>
<h3 className="text-lg font-medium mb-4">Task Description</h3>
<RichTextEditor
className="min-h-[200px]"
content="<p>Add your task description here...</p>"
onChange={(content) => console.log(content)}
/>
</Card>
{/* Upcoming Events */}
<div>
<h4 className="font-medium mb-4">Upcoming Events</h4>
<div className="space-y-4">
<div className="flex items-center space-x-4">
<div className="w-20 text-sm text-muted-foreground">Tomorrow</div>
<div className="flex-1">
<Card className="p-3">
<h5 className="font-medium">Client Meeting</h5>
<p className="text-sm text-muted-foreground">10:00 AM - Project update discussion</p>
</Card>
</div>
</div>
<div className="flex items-center space-x-4">
<div className="w-20 text-sm text-muted-foreground">Friday</div>
<div className="flex-1">
<Card className="p-3">
<h5 className="font-medium">Team Building</h5>
<p className="text-sm text-muted-foreground">02:00 PM - Virtual team activity</p>
</Card>
</div>
</div>
</div>
</div>
</div>
<Card className="p-6">
<h3 className="text-lg font-medium mb-4">Attachments</h3>
<FileUpload
onUpload={(files) => console.log("Uploaded files:", files)}
/>
</Card>
</div>
</TabsContent>
</Tabs>
</div>
</main>
</div>
)
}