-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat(dashboard-&-landingPage): completed project
- Loading branch information
Showing
24 changed files
with
1,282 additions
and
77 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
import db from "@/db/db"; | ||
import { NextRequest, NextResponse } from "next/server"; | ||
|
||
export async function GET( | ||
req: NextRequest, | ||
{ params }: { params: { id: string } } | ||
) { | ||
const id = parseInt(params.id, 10); | ||
await db.read(); | ||
const burger = db.data?.burgers.find((b) => b.id === id); | ||
|
||
if (!burger) { | ||
return NextResponse.json({ error: "Burger not found" }, { status: 404 }); | ||
} | ||
|
||
return NextResponse.json(burger, { status: 200 }); | ||
} | ||
|
||
export async function PUT( | ||
request: NextRequest, | ||
{ params }: { params: { id: string } } | ||
) { | ||
const id = parseInt(params.id, 10); | ||
const updatedData = await request.json(); | ||
await db.read(); | ||
const index = db.data?.burgers.findIndex((b) => b.id === id); | ||
|
||
if (index === undefined || index === -1) { | ||
return NextResponse.json({ error: "Burger not found" }, { status: 404 }); | ||
} | ||
|
||
db.data!.burgers[index] = { ...db.data!.burgers[index], ...updatedData }; | ||
await db.write(); | ||
|
||
return NextResponse.json(db.data!.burgers[index], { status: 200 }); | ||
} | ||
|
||
export async function DELETE( | ||
_: Request, | ||
{ params }: { params: { id: string } } | ||
) { | ||
const id = parseInt(params.id, 10); | ||
await db.read(); | ||
const index = db.data?.burgers.findIndex((b) => b.id === id); | ||
|
||
if (index === undefined || index === -1) { | ||
return NextResponse.json({ error: "Burger not found" }, { status: 404 }); | ||
} | ||
|
||
const [deletedBurger] = db.data!.burgers.splice(index, 1); | ||
await db.write(); | ||
|
||
return NextResponse.json(deletedBurger, { status: 200 }); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import db from "@/db/db"; | ||
import { Burger } from "@/types/Burger"; | ||
import { NextRequest, NextResponse } from "next/server"; | ||
|
||
export async function GET() { | ||
await db.read(); | ||
return NextResponse.json(db.data?.burgers || [], { status: 200 }); | ||
} | ||
|
||
export async function POST(request: NextRequest) { | ||
const newBurger: Omit<Burger, "id"> = await request.json(); | ||
await db.read(); | ||
const id = Date.now(); | ||
const burger: Burger = { id, ...newBurger }; | ||
db.data?.burgers.push(burger); | ||
await db.write(); | ||
|
||
return NextResponse.json(burger, { status: 201 }); | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
import { createUploadthing, type FileRouter } from "uploadthing/next"; | ||
import { UploadThingError } from "uploadthing/server"; | ||
|
||
const f = createUploadthing(); | ||
|
||
const auth = (req: Request) => ({ id: "fakeId" }); // Fake auth function | ||
|
||
// FileRouter for your app, can contain multiple FileRoutes | ||
export const ourFileRouter = { | ||
// Define as many FileRoutes as you like, each with a unique routeSlug | ||
imageUploader: f({ | ||
image: { maxFileSize: "4MB", maxFileCount: 1 }, | ||
}).onUploadComplete(async ({ file }) => { | ||
// This code RUNS ON YOUR SERVER after upload | ||
|
||
console.log("file url", file.url); | ||
|
||
// !!! Whatever is returned here is sent to the clientside `onClientUploadComplete` callback | ||
return { success: true }; | ||
}), | ||
} satisfies FileRouter; | ||
|
||
export type OurFileRouter = typeof ourFileRouter; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
import { createRouteHandler } from "uploadthing/next"; | ||
|
||
import { ourFileRouter } from "./core"; | ||
|
||
// Export routes for Next App Router | ||
export const { GET, POST } = createRouteHandler({ | ||
router: ourFileRouter, | ||
|
||
// Apply an (optional) custom config: | ||
// config: { ... }, | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
"use client"; | ||
|
||
import { Burger } from "@/types/Burger"; | ||
import { useQuery } from "@tanstack/react-query"; | ||
import Image from "next/image"; | ||
import React from "react"; | ||
|
||
export default function page({ params }: { params: { id: string } }) { | ||
async function fetchBurger(): Promise<Burger> { | ||
const response = await fetch( | ||
`${window.location.origin}/api/burgers/${params.id}`, | ||
{ | ||
method: "GET", | ||
headers: { | ||
"Content-Type": "application/json", | ||
}, | ||
cache: "no-store", | ||
} | ||
); | ||
|
||
if (!response.ok) throw new Error("Failed to fetch burgers"); | ||
return response.json(); | ||
} | ||
|
||
const { | ||
data: burger, | ||
isLoading, | ||
error, | ||
} = useQuery({ queryKey: ["burger"], queryFn: fetchBurger }); | ||
|
||
if (isLoading) return <p>Loading...</p>; | ||
return ( | ||
<div className="flex justify-center h-[89vw] items-center mx-auto mt-6 flex-col w-1/2"> | ||
<Image | ||
src={burger?.imageURL || ""} | ||
width={512} | ||
height={512} | ||
className="rounded-full" | ||
alt="burger" | ||
></Image> | ||
<h1 className="font-bold text-5xl text-left my-8">{burger?.name}</h1> | ||
<p className="text-3xl text-left my-6">{burger?.description}</p> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,18 +1,129 @@ | ||
"use client"; | ||
|
||
import { useSession } from "next-auth/react"; | ||
// import { useRouter } from "next/navigation"; | ||
// import { useEffect } from "react"; | ||
import { Button } from "@/components/ui/button"; | ||
import { useQuery } from "@tanstack/react-query"; | ||
import { Burger } from "@/types/Burger"; | ||
import { | ||
Table, | ||
TableBody, | ||
TableCell, | ||
TableHead, | ||
TableHeader, | ||
TableRow, | ||
} from "@/components/ui/table"; | ||
import Image from "next/image"; | ||
import { Pencil, Trash } from "lucide-react"; | ||
import { useState } from "react"; | ||
import { AddOrEditItem } from "@/components/AddItemDialog"; | ||
import { DeleteDialog } from "@/components/DeleteDialog"; | ||
|
||
export default function DashboardPage() { | ||
const { data: session } = useSession(); | ||
|
||
if (session) { | ||
return ( | ||
<div> | ||
<h1>Welcome to the Dashboard, {session!.user?.name}</h1> | ||
<p>Your token : ${session?.accessToken}</p> | ||
</div> | ||
); | ||
const [isAddOpen, setIsAddOpen] = useState(false); | ||
const [editingBurger, setEditingBurger] = useState<Burger | null>(null); | ||
const [isDeleteOpen, setIsDeleteOpen] = useState(false); | ||
const [burgerIdToDelete, setBurgerIdToDelete] = useState<string | null>(null); | ||
|
||
async function fetchBurgers(): Promise<Burger[]> { | ||
const response = await fetch(`${window.location.origin}/api/burgers`, { | ||
method: "GET", | ||
headers: { | ||
"Content-Type": "application/json", | ||
}, | ||
cache: "no-store", | ||
}); | ||
|
||
if (!response.ok) throw new Error("Failed to fetch burgers"); | ||
return response.json(); | ||
} | ||
|
||
const { | ||
data: burgers, | ||
isLoading, | ||
error, | ||
} = useQuery({ queryKey: ["burgers"], queryFn: fetchBurgers }); | ||
|
||
if (isLoading) return <p>Loading burgers...</p>; | ||
if (error) return <p>Error loading burgers</p>; | ||
|
||
// Open dialog for adding new item | ||
const handleAddClick = () => { | ||
setEditingBurger(null); | ||
setIsAddOpen(true); | ||
}; | ||
|
||
// Open dialog for editing an existing item | ||
const handleEditClick = (burger: Burger) => { | ||
setEditingBurger(burger); | ||
setIsAddOpen(true); | ||
}; | ||
|
||
// Open delete dialog and set burger to be deleted | ||
const handleDeleteClick = (burgerId: string) => { | ||
setBurgerIdToDelete(burgerId); | ||
setIsDeleteOpen(true); | ||
}; | ||
|
||
return ( | ||
<div className="container mx-auto p-4"> | ||
<h1 className="text-2xl font-semibold mb-4">Burgers Menu</h1> | ||
<Button className="mb-4" onClick={handleAddClick}> | ||
Add Item | ||
</Button> | ||
<Table> | ||
<TableHeader> | ||
<TableRow> | ||
<TableHead>ID</TableHead> | ||
<TableHead>Name</TableHead> | ||
<TableHead>Description</TableHead> | ||
<TableHead>Image</TableHead> | ||
<TableHead>Actions</TableHead> | ||
</TableRow> | ||
</TableHeader> | ||
<TableBody> | ||
{burgers?.map((burger: Burger) => ( | ||
<TableRow key={burger.id}> | ||
<TableCell>{burger.id}</TableCell> | ||
<TableCell>{burger.name}</TableCell> | ||
<TableCell>{burger.description}</TableCell> | ||
<TableCell> | ||
<Image | ||
src={burger.imageURL || ""} | ||
alt={burger.name} | ||
className="w-16 h-16 object-cover rounded-full" | ||
width={64} | ||
height={64} | ||
/> | ||
</TableCell> | ||
<TableCell className="flex items-center justify-center h-16 w-16 gap-2"> | ||
<Pencil | ||
size={16} | ||
className="cursor-pointer" | ||
onClick={() => handleEditClick(burger)} | ||
/> | ||
<Trash | ||
size={16} | ||
className="cursor-pointer" | ||
onClick={() => handleDeleteClick(String(burger.id))} | ||
/> | ||
</TableCell> | ||
</TableRow> | ||
))} | ||
</TableBody> | ||
</Table> | ||
|
||
{/* Dialog for Add or Edit */} | ||
<AddOrEditItem | ||
open={isAddOpen} | ||
setOpen={setIsAddOpen} | ||
burgerData={editingBurger} | ||
/> | ||
|
||
{/* Delete confirmation dialog */} | ||
<DeleteDialog | ||
open={isDeleteOpen} | ||
setOpen={setIsDeleteOpen} | ||
burgerId={burgerIdToDelete} | ||
/> | ||
</div> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.