-
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.
Add node creation flow and setup for future pages (#3)
* add sidebar nav items, add command implementation for suggestions * add note creation logic and redirects * add all notes table, adjust schema and add helpers to fetch and delete note(s)
- Loading branch information
1 parent
7cd6bde
commit f42deba
Showing
18 changed files
with
1,247 additions
and
23 deletions.
There are no files selected for viewing
File renamed without changes.
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,14 @@ | ||
import SideNav from "./side-nav"; | ||
|
||
export default function RootLayout({ | ||
children, | ||
}: Readonly<{ | ||
children: React.ReactNode; | ||
}>) { | ||
return ( | ||
<div className="flex h-screen divide-x"> | ||
<SideNav /> | ||
<div className="w-full p-4">{children}</div> | ||
</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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
import { | ||
CardStackIcon, | ||
GridIcon, | ||
HomeIcon, | ||
Pencil2Icon, | ||
} from "@radix-ui/react-icons"; | ||
|
||
const navItems = [ | ||
{ | ||
label: "Dashboard", | ||
href: "/dashboard", | ||
icon: HomeIcon, | ||
}, | ||
{ | ||
label: "New note", | ||
href: "/notes/new", | ||
icon: Pencil2Icon, | ||
}, | ||
{ | ||
label: "All notes", | ||
href: "/notes", | ||
icon: CardStackIcon, | ||
}, | ||
{ | ||
label: "Map", | ||
href: "/map", | ||
icon: GridIcon, | ||
}, | ||
]; | ||
|
||
export default navItems; |
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,25 @@ | ||
import { redirect } from "next/navigation"; | ||
|
||
import { getNote } from "@/helpers/notes/getNote"; | ||
|
||
export default async function EditNotePage({ | ||
params, | ||
}: { | ||
params: { noteId: string }; | ||
}) { | ||
const { noteId } = params; | ||
const note = await getNote(noteId); | ||
|
||
if (!note) { | ||
redirect("/notes"); | ||
} | ||
|
||
return ( | ||
<main> | ||
<h1>Edit note</h1> | ||
<pre> | ||
<code>{JSON.stringify(note, null, 2)}</code> | ||
</pre> | ||
</main> | ||
); | ||
} |
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,51 @@ | ||
import { auth } from "@clerk/nextjs"; | ||
import { redirect } from "next/navigation"; | ||
import { NextResponse } from "next/server"; | ||
|
||
import { prisma } from "@/lib/db"; | ||
|
||
// Handles the creation of a new note, fills the note up with placeholder data, then redirects the user | ||
export async function GET() { | ||
const { userId } = auth(); | ||
|
||
if (!userId) { | ||
return new NextResponse("Unauthorized", { status: 401 }); | ||
} | ||
|
||
let newNoteId: string; | ||
|
||
try { | ||
const dbUser = await prisma.user.findUnique({ | ||
where: { clerkId: userId }, | ||
}); | ||
|
||
if (!dbUser) { | ||
return new NextResponse("User in own database not found", { | ||
status: 404, | ||
}); | ||
} | ||
|
||
const newNote = await prisma.note.create({ | ||
data: { | ||
title: "New note", | ||
content: "Start writing here...", | ||
authorId: dbUser.id, | ||
}, | ||
}); | ||
|
||
const { id } = newNote; | ||
|
||
newNoteId = id; | ||
} catch (error) { | ||
return new NextResponse( | ||
`Error creating note: ${(error as Error).message}`, | ||
{ | ||
status: 500, | ||
} | ||
); | ||
} | ||
|
||
// This is necessary to be done here because Next's app directory routing throws an error internally | ||
// that makes it impossible to use it in a try-catch block. Pretty annoying but this is the cleanest solution without a workaround. | ||
redirect(`/notes/${newNoteId}`); | ||
} |
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,57 @@ | ||
import { CrossCircledIcon } from "@radix-ui/react-icons"; | ||
import { Edit2Icon, Edit3Icon } from "lucide-react"; | ||
import Link from "next/link"; | ||
|
||
import { Button } from "@/components/ui/button"; | ||
import { | ||
Table, | ||
TableBody, | ||
TableCaption, | ||
TableCell, | ||
TableHead, | ||
TableHeader, | ||
TableRow, | ||
} from "@/components/ui/table"; | ||
import { getAllNotes } from "@/helpers/notes/getAllNotes"; | ||
|
||
export default async function AllNotesPage() { | ||
const notes = await getAllNotes(); | ||
|
||
return ( | ||
<main> | ||
<Table> | ||
<TableCaption>A list of your recent notes.</TableCaption> | ||
<TableHeader> | ||
<TableRow> | ||
<TableHead className="w-[100px]">Title</TableHead> | ||
<TableHead className="w-[300px]">Snippet</TableHead> | ||
<TableHead className="w-[200px]">Tags</TableHead> | ||
<TableHead className="text-right">Updated</TableHead> | ||
</TableRow> | ||
</TableHeader> | ||
<TableBody> | ||
{notes?.map((note) => ( | ||
<TableRow key={note.id}> | ||
<TableCell> | ||
<Link href={`/notes/${note.id}`}>{note.title}</Link> | ||
</TableCell> | ||
<TableCell> | ||
<Link href={`/notes/${note.id}`}> | ||
{note.content.slice(0, 50)} | ||
</Link> | ||
</TableCell> | ||
<TableCell> | ||
{note.tags.map((tag) => tag.name).join(", ")} | ||
</TableCell> | ||
<TableCell className="text-right"> | ||
<Link href={`/notes/${note.id}`}> | ||
{new Date(note.updatedAt).toLocaleString()} | ||
</Link> | ||
</TableCell> | ||
</TableRow> | ||
))} | ||
</TableBody> | ||
</Table> | ||
</main> | ||
); | ||
} |
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,79 @@ | ||
"use client"; | ||
|
||
import { MagnifyingGlassIcon } from "@radix-ui/react-icons"; | ||
import Link from "next/link"; | ||
import { useRouter } from "next/navigation"; | ||
import { | ||
KeyboardEvent as ReactKeyboardEvent, | ||
useEffect, | ||
useState, | ||
} from "react"; | ||
|
||
import { Button } from "@/components/ui/button"; | ||
import { | ||
CommandDialog, | ||
CommandEmpty, | ||
CommandGroup, | ||
CommandInput, | ||
CommandItem, | ||
CommandList, | ||
} from "@/components/ui/command"; | ||
|
||
import navItems from "./navItems"; | ||
|
||
export default function SearchBar() { | ||
const [showSearchCommand, setShowSearchCommand] = useState(false); | ||
|
||
const router = useRouter(); | ||
|
||
useEffect(() => { | ||
const down = (e: KeyboardEvent) => { | ||
if (e.key === "k" && (e.metaKey || e.ctrlKey)) { | ||
e.preventDefault(); | ||
setShowSearchCommand((open) => !open); | ||
} | ||
}; | ||
document.addEventListener("keydown", down); | ||
return () => document.removeEventListener("keydown", down); | ||
}, []); | ||
|
||
return ( | ||
<> | ||
<Button | ||
className="justify-between text-slate-400 hover:text-slate-800" | ||
variant="outline" | ||
onClick={() => setShowSearchCommand(true)} | ||
> | ||
<div className="flex items-center gap-3"> | ||
<MagnifyingGlassIcon /> | ||
<span>Search</span> | ||
</div> | ||
<span>⌘K</span> | ||
</Button> | ||
<CommandDialog | ||
open={showSearchCommand} | ||
onOpenChange={setShowSearchCommand} | ||
> | ||
<CommandInput placeholder="Type a command or search..." /> | ||
<CommandList> | ||
<CommandEmpty>No results found.</CommandEmpty> | ||
<CommandGroup heading="Suggestions"> | ||
{navItems.map((item) => ( | ||
<Link href={item.href} key={item.href}> | ||
<CommandItem | ||
onSelect={() => { | ||
router.push(item.href); | ||
setShowSearchCommand(false); | ||
}} | ||
> | ||
<item.icon className="mr-2 h-4 w-4" /> | ||
<span>{item.label}</span> | ||
</CommandItem> | ||
</Link> | ||
))} | ||
</CommandGroup> | ||
</CommandList> | ||
</CommandDialog> | ||
</> | ||
); | ||
} |
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,28 @@ | ||
import { UserButton } from "@clerk/nextjs"; | ||
import Link from "next/link"; | ||
|
||
import { Button } from "@/components/ui/button"; | ||
|
||
import navItems from "./navItems"; | ||
import SearchBar from "./search-bar"; | ||
|
||
export default function SideNav() { | ||
return ( | ||
<aside className="flex h-full w-64 flex-col justify-between bg-slate-100/50 p-6"> | ||
<div className="flex flex-col items-stretch gap-4"> | ||
<SearchBar /> | ||
{navItems.map((item) => ( | ||
<Link key={item.href} href={item.href}> | ||
<Button className="w-full justify-start" variant={"secondary"}> | ||
<item.icon className="mr-3" /> | ||
{item.label} | ||
</Button> | ||
</Link> | ||
))} | ||
</div> | ||
<div> | ||
<UserButton afterSignOutUrl="/" /> | ||
</div> | ||
</aside> | ||
); | ||
} |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.