Skip to content

Commit c575890

Browse files
authored
Merge pull request #4 from CodeChefVIT/harshit/users
login page and user ka table
2 parents 248cc2e + 72aa89c commit c575890

32 files changed

Lines changed: 5155 additions & 280 deletions

package.json

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,17 +10,29 @@
1010
"start": "next start"
1111
},
1212
"dependencies": {
13+
"@radix-ui/react-avatar": "^1.1.2",
14+
"@radix-ui/react-checkbox": "^1.1.3",
15+
"@radix-ui/react-dialog": "^1.1.5",
16+
"@radix-ui/react-dropdown-menu": "^2.1.5",
1317
"@radix-ui/react-icons": "^1.3.0",
18+
"@radix-ui/react-label": "^2.1.1",
19+
"@radix-ui/react-popover": "^1.1.5",
20+
"@radix-ui/react-select": "^2.1.5",
21+
"@radix-ui/react-separator": "^1.1.1",
1422
"@radix-ui/react-slot": "^1.1.0",
1523
"@t3-oss/env-nextjs": "^0.10.1",
1624
"@tanstack/react-query": "^5.53.1",
1725
"@tanstack/react-query-devtools": "^5.53.1",
26+
"@tanstack/react-table": "^8.20.6",
1827
"axios": "^1.7.7",
1928
"class-variance-authority": "^0.7.0",
2029
"clsx": "^2.1.1",
30+
"cmdk": "1.0.0",
2131
"geist": "^1.3.0",
2232
"lucide-react": "^0.437.0",
2333
"next": "^14.2.4",
34+
"next-themes": "^0.4.4",
35+
"radix-ui": "^1.1.1",
2436
"react": "^18.3.1",
2537
"react-dom": "^18.3.1",
2638
"react-hot-toast": "^2.4.1",

pnpm-lock.yaml

Lines changed: 2220 additions & 268 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/app/layout.tsx

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import "@/styles/globals.css";
33
import { GeistSans } from "geist/font/sans";
44
import { type Metadata } from "next";
55
import { Toaster } from "react-hot-toast";
6+
import { ThemeProvider } from "@/components/theme-provider"
67

78
export const metadata: Metadata = {
89
title: "CodeChef-VIT",
@@ -31,9 +32,17 @@ export default function RootLayout({
3132
return (
3233
<html lang="en" className={`${GeistSans.variable}`}>
3334
<body>
34-
<div className="bg-[#FFF8D8]">
35+
<div className="bg-black ">
3536
<Toaster position="top-right" toastOptions={{ id: "_toast" }} />
36-
<Providers>{children}</Providers>
37+
<Providers>
38+
<ThemeProvider
39+
attribute="class"
40+
defaultTheme="dark"
41+
enableSystem
42+
disableTransitionOnChange
43+
>
44+
45+
{children}</ThemeProvider></Providers>
3746
</div>
3847
</body>
3948
</html>

src/app/login/page.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { LoginForm } from "@/components/login-form"
2+
3+
export default function Page() {
4+
return (
5+
<div className=" flex min-h-svh w-full items-center justify-center p-6 md:p-10">
6+
<div className="w-full max-w-sm">
7+
<LoginForm />
8+
</div>
9+
</div>
10+
)
11+
}

src/app/users/page.tsx

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
import { DataTable } from "@/components/table/data-table";
2+
import columns from "@/components/columns";
3+
import { tasks } from "@/data/data";
4+
5+
export default function users(){
6+
7+
return (<div className="">
8+
<DataTable data={tasks} columns={columns} />
9+
10+
</div>)
11+
}

src/components/columns.tsx

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
"use client"
2+
3+
import { type ColumnDef } from "@tanstack/react-table"
4+
5+
import { type Task } from "@/data/schema"
6+
import { labels, priorities, statuses } from "@/data/data"
7+
import { Checkbox } from "./ui/checkbox"
8+
import { DataTableColumnHeader } from "./table/data-table-column-header"
9+
import { Badge } from "./ui/badge"
10+
import { DataTableRowActions } from "./table/data-table-row-actions"
11+
12+
const columns: ColumnDef<Task>[] = [
13+
{
14+
id: "select",
15+
header: ({ table }) => (
16+
<Checkbox
17+
checked={
18+
table.getIsAllPageRowsSelected() ||
19+
(table.getIsSomePageRowsSelected() && "indeterminate")
20+
}
21+
onCheckedChange={(value) => table.toggleAllPageRowsSelected(!!value)}
22+
aria-label="Select all"
23+
className="translate-y-[2px]"
24+
/>
25+
),
26+
cell: ({ row }) => (
27+
<Checkbox
28+
checked={row.getIsSelected()}
29+
onCheckedChange={(value) => row.toggleSelected(!!value)}
30+
aria-label="Select row"
31+
className="translate-y-[2px]"
32+
/>
33+
),
34+
enableSorting: false,
35+
enableHiding: false,
36+
},
37+
{
38+
accessorKey: "id",
39+
header: ({ column }) => (
40+
<DataTableColumnHeader column={column} title="Task" />
41+
),
42+
cell: ({ row }) => <div className="w-[80px]">{row.getValue("id")}</div>,
43+
enableSorting: false,
44+
enableHiding: false,
45+
},
46+
{
47+
accessorKey: "title",
48+
header: ({ column }) => (
49+
<DataTableColumnHeader column={column} title="Title" />
50+
),
51+
cell: ({ row }) => {
52+
const label = labels.find((label) => label.value === row.original.label)
53+
54+
return (
55+
<div className="flex space-x-2">
56+
{label && <Badge variant="outline">{label.label}</Badge>}
57+
<span className="max-w-[500px] truncate font-medium">
58+
{row.getValue("title")}
59+
</span>
60+
</div>
61+
)
62+
},
63+
},
64+
{
65+
accessorKey: "status",
66+
header: ({ column }) => (
67+
<DataTableColumnHeader column={column} title="Status" />
68+
),
69+
cell: ({ row }) => {
70+
const status = statuses.find(
71+
(status) => status.value === row.getValue("status")
72+
)
73+
74+
if (!status) {
75+
return null
76+
}
77+
78+
return (
79+
<div className="flex w-[100px] items-center">
80+
{status.icon && (
81+
<status.icon className="mr-2 h-4 w-4 text-muted-foreground" />
82+
)}
83+
<span>{status.label}</span>
84+
</div>
85+
)
86+
},
87+
// filterFn: (row, id, value) => {
88+
// return value.includes(row.getValue(id))
89+
// },
90+
},
91+
{
92+
accessorKey: "priority",
93+
header: ({ column }) => (
94+
<DataTableColumnHeader column={column} title="Priority" />
95+
),
96+
cell: ({ row }) => {
97+
const priority = priorities.find(
98+
(priority) => priority.value === row.getValue("priority")
99+
)
100+
101+
if (!priority) {
102+
return null
103+
}
104+
105+
return (
106+
<div className="flex items-center">
107+
{priority.icon && (
108+
<priority.icon className="mr-2 h-4 w-4 text-muted-foreground" />
109+
)}
110+
<span>{priority.label}</span>
111+
</div>
112+
)
113+
},
114+
// filterFn: (row, id, value) => {
115+
// return value.includes(row.getValue(id))
116+
// },
117+
},
118+
{
119+
id: "actions",
120+
cell: ({ row }) => <DataTableRowActions row={row} />,
121+
},
122+
]
123+
124+
export default columns
125+

src/components/login-form.tsx

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { cn } from "@/lib/utils"
2+
import { Button } from "@/components/ui/button"
3+
import {
4+
Card,
5+
CardContent,
6+
CardDescription,
7+
CardHeader,
8+
CardTitle,
9+
} from "@/components/ui/card"
10+
import { Input } from "@/components/ui/input"
11+
import { Label } from "@/components/ui/label"
12+
13+
export function LoginForm({
14+
className,
15+
...props
16+
}: React.ComponentPropsWithoutRef<"div">) {
17+
return (
18+
<div className={cn("flex flex-col gap-6", className)} {...props}>
19+
<Card>
20+
<CardHeader>
21+
<CardTitle className="text-2xl">Login</CardTitle>
22+
<CardDescription>
23+
Enter your email below to login to your account
24+
</CardDescription>
25+
</CardHeader>
26+
<CardContent>
27+
<form>
28+
<div className="flex flex-col gap-6">
29+
<div className="grid gap-2">
30+
<Label htmlFor="email">Email</Label>
31+
<Input
32+
id="email"
33+
type="email"
34+
placeholder="m@example.com"
35+
required
36+
/>
37+
</div>
38+
<div className="grid gap-2">
39+
<div className="flex items-center">
40+
<Label htmlFor="password">Password</Label>
41+
</div>
42+
<Input id="password" type="password" required />
43+
</div>
44+
<Button type="submit" className="w-full">
45+
Login
46+
</Button>
47+
</div>
48+
</form>
49+
</CardContent>
50+
</Card>
51+
</div>
52+
)
53+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
import { type Column } from "@tanstack/react-table"
2+
import { ArrowDown, ArrowUp, ChevronsUpDown, EyeOff } from "lucide-react"
3+
4+
import { cn } from "@/lib/utils"
5+
import { Button } from "../ui/button"
6+
import {
7+
DropdownMenu,
8+
DropdownMenuContent,
9+
DropdownMenuItem,
10+
DropdownMenuSeparator,
11+
DropdownMenuTrigger,
12+
} from "../ui/dropdown-menu"
13+
14+
interface DataTableColumnHeaderProps<TData, TValue>
15+
extends React.HTMLAttributes<HTMLDivElement> {
16+
column: Column<TData, TValue>
17+
title: string
18+
}
19+
20+
export function DataTableColumnHeader<TData, TValue>({
21+
column,
22+
title,
23+
className,
24+
}: DataTableColumnHeaderProps<TData, TValue>) {
25+
if (!column.getCanSort()) {
26+
return <div className={cn(className)}>{title}</div>
27+
}
28+
29+
return (
30+
<div className={cn("flex items-center space-x-2", className)}>
31+
<DropdownMenu>
32+
<DropdownMenuTrigger asChild>
33+
<Button
34+
variant="ghost"
35+
size="sm"
36+
className="-ml-3 h-8 data-[state=open]:bg-accent"
37+
>
38+
<span>{title}</span>
39+
{column.getIsSorted() === "desc" ? (
40+
<ArrowDown />
41+
) : column.getIsSorted() === "asc" ? (
42+
<ArrowUp />
43+
) : (
44+
<ChevronsUpDown />
45+
)}
46+
</Button>
47+
</DropdownMenuTrigger>
48+
<DropdownMenuContent align="start">
49+
<DropdownMenuItem onClick={() => column.toggleSorting(false)}>
50+
<ArrowUp className="h-3.5 w-3.5 text-muted-foreground/70" />
51+
Asc
52+
</DropdownMenuItem>
53+
<DropdownMenuItem onClick={() => column.toggleSorting(true)}>
54+
<ArrowDown className="h-3.5 w-3.5 text-muted-foreground/70" />
55+
Desc
56+
</DropdownMenuItem>
57+
<DropdownMenuSeparator />
58+
<DropdownMenuItem onClick={() => column.toggleVisibility(false)}>
59+
<EyeOff className="h-3.5 w-3.5 text-muted-foreground/70" />
60+
Hide
61+
</DropdownMenuItem>
62+
</DropdownMenuContent>
63+
</DropdownMenu>
64+
</div>
65+
)
66+
}

0 commit comments

Comments
 (0)