Skip to content

Commit 6d45c01

Browse files
committed
feat: init next with shadcn
1 parent 81111cc commit 6d45c01

32 files changed

+1780
-122
lines changed

.vscode/settings.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"typescript.tsdk": "node_modules/typescript/lib",
3+
"editor.formatOnSave": true,
4+
}

app/books/page.tsx

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
import {
2+
Breadcrumb,
3+
BreadcrumbItem,
4+
BreadcrumbLink,
5+
BreadcrumbList,
6+
BreadcrumbPage,
7+
BreadcrumbSeparator,
8+
} from "@/components/ui/breadcrumb";
9+
import {
10+
Pagination,
11+
PaginationContent,
12+
PaginationItem,
13+
PaginationNext,
14+
PaginationPrevious,
15+
} from "@/components/ui/pagination";
16+
import {
17+
Table,
18+
TableBody,
19+
TableCell,
20+
TableHead,
21+
TableHeader,
22+
TableRow,
23+
} from "@/components/ui/table";
24+
import { getListBooks } from "@/lib/api/book";
25+
import Link from "next/link";
26+
27+
export default async function Borrows({
28+
searchParams,
29+
}: {
30+
searchParams: Promise<{
31+
skip?: number;
32+
limit?: number;
33+
library_id?: string;
34+
}>;
35+
}) {
36+
const sp = await searchParams;
37+
const skip = Number(sp?.skip ?? 0);
38+
const limit = Number(sp?.limit ?? 20);
39+
const library_id = sp?.library_id;
40+
const res = await getListBooks({
41+
sort_by: "created_at",
42+
sort_in: "desc",
43+
limit: limit,
44+
skip: skip,
45+
...(library_id ? { library_id } : {}),
46+
});
47+
48+
if ("error" in res) {
49+
console.log(res);
50+
return <div>{JSON.stringify(res.message)}</div>;
51+
}
52+
53+
const prevSkip = skip - limit > 0 ? skip - limit : 0;
54+
55+
const nextURL = `/books?skip=${skip + limit}&limit=${limit}`;
56+
const prevURL = `/books?skip=${prevSkip}&limit=${limit}`;
57+
58+
return (
59+
<div>
60+
<h1 className="text-2xl font-semibold">Books</h1>
61+
<Breadcrumb>
62+
<BreadcrumbList>
63+
<BreadcrumbItem>
64+
<Link href="/" passHref legacyBehavior>
65+
<BreadcrumbLink>Home</BreadcrumbLink>
66+
</Link>
67+
</BreadcrumbItem>
68+
<BreadcrumbSeparator />
69+
70+
<BreadcrumbItem>
71+
<BreadcrumbPage>Borrows</BreadcrumbPage>
72+
</BreadcrumbItem>
73+
</BreadcrumbList>
74+
</Breadcrumb>
75+
76+
<Table>
77+
{/* <TableCaption>List of books available in the library.</TableCaption> */}
78+
<TableHeader>
79+
<TableRow>
80+
<TableHead>Code</TableHead>
81+
<TableHead>Title</TableHead>
82+
<TableHead>Author</TableHead>
83+
<TableHead>Year</TableHead>
84+
</TableRow>
85+
</TableHeader>
86+
<TableBody>
87+
{res.data.map((b) => (
88+
<TableRow key={b.id}>
89+
<TableCell>{b.code}</TableCell>
90+
<TableCell>{b.title}</TableCell>
91+
<TableCell>{b.author}</TableCell>
92+
<TableCell>{b.year}</TableCell>
93+
</TableRow>
94+
))}
95+
</TableBody>
96+
</Table>
97+
98+
<Pagination>
99+
<PaginationContent>
100+
<PaginationItem>
101+
<PaginationPrevious href={prevURL} />
102+
</PaginationItem>
103+
<PaginationItem>
104+
<PaginationNext href={nextURL} />
105+
</PaginationItem>
106+
</PaginationContent>
107+
</Pagination>
108+
</div>
109+
);
110+
}

app/borrows/page.tsx

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
import {
2+
Breadcrumb,
3+
BreadcrumbItem,
4+
BreadcrumbLink,
5+
BreadcrumbList,
6+
BreadcrumbPage,
7+
BreadcrumbSeparator,
8+
} from "@/components/ui/breadcrumb";
9+
import {
10+
Pagination,
11+
PaginationContent,
12+
PaginationItem,
13+
PaginationNext,
14+
PaginationPrevious,
15+
} from "@/components/ui/pagination";
16+
import {
17+
Table,
18+
TableBody,
19+
TableCell,
20+
TableHead,
21+
TableHeader,
22+
TableRow,
23+
} from "@/components/ui/table";
24+
import { getListBorrows } from "@/lib/api/borrow";
25+
import Link from "next/link";
26+
27+
export default async function Borrows({
28+
searchParams,
29+
}: {
30+
searchParams: Promise<{
31+
skip?: number;
32+
limit?: number;
33+
library_id?: string;
34+
}>;
35+
}) {
36+
const sp = await searchParams;
37+
const skip = Number(sp?.skip ?? 0);
38+
const limit = Number(sp?.limit ?? 20);
39+
const library_id = sp?.library_id;
40+
const res = await getListBorrows({
41+
sort_by: "created_at",
42+
sort_in: "desc",
43+
limit: limit,
44+
skip: skip,
45+
...(library_id ? { library_id } : {}),
46+
});
47+
48+
if ("error" in res) {
49+
console.log(res);
50+
return <div>{JSON.stringify(res.message)}</div>;
51+
}
52+
53+
const prevSkip = skip - limit > 0 ? skip - limit : 0;
54+
55+
const nextURL = `/borrows?skip=${skip + limit}&limit=${limit}`;
56+
const prevURL = `/borrows?skip=${prevSkip}&limit=${limit}`;
57+
58+
return (
59+
<div>
60+
<h1 className="text-2xl font-semibold">Borrows</h1>
61+
<Breadcrumb>
62+
<BreadcrumbList>
63+
<BreadcrumbItem>
64+
<Link href="/" passHref legacyBehavior>
65+
<BreadcrumbLink>Home</BreadcrumbLink>
66+
</Link>
67+
</BreadcrumbItem>
68+
<BreadcrumbSeparator />
69+
70+
<BreadcrumbItem>
71+
<BreadcrumbPage>Borrows</BreadcrumbPage>
72+
</BreadcrumbItem>
73+
</BreadcrumbList>
74+
</Breadcrumb>
75+
76+
<Table>
77+
{/* <TableCaption>List of books available in the library.</TableCaption> */}
78+
<TableHeader>
79+
<TableRow>
80+
<TableHead>Book</TableHead>
81+
<TableHead>Date</TableHead>
82+
<TableHead>User</TableHead>
83+
<TableHead>Due</TableHead>
84+
<TableHead>Title</TableHead>
85+
<TableHead>Returned Date</TableHead>
86+
</TableRow>
87+
</TableHeader>
88+
<TableBody>
89+
{res.data.map((b) => (
90+
<TableRow key={b.id}>
91+
<TableCell>{b.book.code}</TableCell>
92+
<TableCell>{b.borrowed_at}</TableCell>
93+
<TableCell>{b.subscription.user.name}</TableCell>
94+
<TableCell>{b.due_at}</TableCell>
95+
<TableCell>{b.book.title}</TableCell>
96+
<TableCell>{b.returned_at}</TableCell>
97+
</TableRow>
98+
))}
99+
</TableBody>
100+
</Table>
101+
102+
<Pagination>
103+
<PaginationContent>
104+
<PaginationItem>
105+
<PaginationPrevious href={prevURL} />
106+
</PaginationItem>
107+
<PaginationItem>
108+
<PaginationNext href={nextURL} />
109+
</PaginationItem>
110+
</PaginationContent>
111+
</Pagination>
112+
</div>
113+
);
114+
}

app/dashboard/page.tsx

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { AppSidebar } from "@/components/app-sidebar"
2+
import {
3+
Breadcrumb,
4+
BreadcrumbItem,
5+
BreadcrumbLink,
6+
BreadcrumbList,
7+
BreadcrumbPage,
8+
BreadcrumbSeparator,
9+
} from "@/components/ui/breadcrumb"
10+
import { Separator } from "@/components/ui/separator"
11+
import {
12+
SidebarInset,
13+
SidebarProvider,
14+
SidebarTrigger,
15+
} from "@/components/ui/sidebar"
16+
17+
export default function Page() {
18+
return (
19+
<SidebarProvider>
20+
<AppSidebar />
21+
<SidebarInset>
22+
<header className="flex h-16 shrink-0 items-center gap-2 border-b px-4">
23+
<SidebarTrigger className="-ml-1" />
24+
<Separator orientation="vertical" className="mr-2 h-4" />
25+
<Breadcrumb>
26+
<BreadcrumbList>
27+
<BreadcrumbItem className="hidden md:block">
28+
<BreadcrumbLink href="#">
29+
Building Your Application
30+
</BreadcrumbLink>
31+
</BreadcrumbItem>
32+
<BreadcrumbSeparator className="hidden md:block" />
33+
<BreadcrumbItem>
34+
<BreadcrumbPage>Data Fetching</BreadcrumbPage>
35+
</BreadcrumbItem>
36+
</BreadcrumbList>
37+
</Breadcrumb>
38+
</header>
39+
<div className="flex flex-1 flex-col gap-4 p-4">
40+
<div className="grid auto-rows-min gap-4 md:grid-cols-3">
41+
<div className="aspect-video rounded-xl bg-muted/50" />
42+
<div className="aspect-video rounded-xl bg-muted/50" />
43+
<div className="aspect-video rounded-xl bg-muted/50" />
44+
</div>
45+
<div className="min-h-[100vh] flex-1 rounded-xl bg-muted/50 md:min-h-min" />
46+
</div>
47+
</SidebarInset>
48+
</SidebarProvider>
49+
)
50+
}

app/globals.css

Lines changed: 61 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,71 @@
22
@tailwind components;
33
@tailwind utilities;
44

5-
:root {
6-
--background: #ffffff;
7-
--foreground: #171717;
5+
body {
6+
font-family: Arial, Helvetica, sans-serif;
87
}
98

10-
@media (prefers-color-scheme: dark) {
9+
@layer base {
1110
:root {
12-
--background: #0a0a0a;
13-
--foreground: #ededed;
11+
--background: 0 0% 100%;
12+
--foreground: 240 10% 3.9%;
13+
--card: 0 0% 100%;
14+
--card-foreground: 240 10% 3.9%;
15+
--popover: 0 0% 100%;
16+
--popover-foreground: 240 10% 3.9%;
17+
--primary: 240 5.9% 10%;
18+
--primary-foreground: 0 0% 98%;
19+
--secondary: 240 4.8% 95.9%;
20+
--secondary-foreground: 240 5.9% 10%;
21+
--muted: 240 4.8% 95.9%;
22+
--muted-foreground: 240 3.8% 46.1%;
23+
--accent: 240 4.8% 95.9%;
24+
--accent-foreground: 240 5.9% 10%;
25+
--destructive: 0 84.2% 60.2%;
26+
--destructive-foreground: 0 0% 98%;
27+
--border: 240 5.9% 90%;
28+
--input: 240 5.9% 90%;
29+
--ring: 240 10% 3.9%;
30+
--chart-1: 12 76% 61%;
31+
--chart-2: 173 58% 39%;
32+
--chart-3: 197 37% 24%;
33+
--chart-4: 43 74% 66%;
34+
--chart-5: 27 87% 67%;
35+
--radius: 0.5rem;
36+
}
37+
.dark {
38+
--background: 240 10% 3.9%;
39+
--foreground: 0 0% 98%;
40+
--card: 240 10% 3.9%;
41+
--card-foreground: 0 0% 98%;
42+
--popover: 240 10% 3.9%;
43+
--popover-foreground: 0 0% 98%;
44+
--primary: 0 0% 98%;
45+
--primary-foreground: 240 5.9% 10%;
46+
--secondary: 240 3.7% 15.9%;
47+
--secondary-foreground: 0 0% 98%;
48+
--muted: 240 3.7% 15.9%;
49+
--muted-foreground: 240 5% 64.9%;
50+
--accent: 240 3.7% 15.9%;
51+
--accent-foreground: 0 0% 98%;
52+
--destructive: 0 62.8% 30.6%;
53+
--destructive-foreground: 0 0% 98%;
54+
--border: 240 3.7% 15.9%;
55+
--input: 240 3.7% 15.9%;
56+
--ring: 240 4.9% 83.9%;
57+
--chart-1: 220 70% 50%;
58+
--chart-2: 160 60% 45%;
59+
--chart-3: 30 80% 55%;
60+
--chart-4: 280 65% 60%;
61+
--chart-5: 340 75% 55%;
1462
}
1563
}
1664

17-
body {
18-
color: var(--foreground);
19-
background: var(--background);
20-
font-family: Arial, Helvetica, sans-serif;
65+
@layer base {
66+
* {
67+
@apply border-border;
68+
}
69+
body {
70+
@apply bg-background text-foreground;
71+
}
2172
}

app/layout.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export default function RootLayout({
2525
return (
2626
<html lang="en">
2727
<body
28-
className={`${geistSans.variable} ${geistMono.variable} antialiased`}
28+
className={`${geistSans.variable} ${geistMono.variable} antialiased container mx-auto px-4`}
2929
>
3030
{children}
3131
</body>

0 commit comments

Comments
 (0)