diff --git a/src/app/actions/notes.ts b/src/app/actions/notes.ts new file mode 100644 index 0000000..2401749 --- /dev/null +++ b/src/app/actions/notes.ts @@ -0,0 +1,31 @@ +"use server"; + +import { revalidatePath } from "next/cache"; +import { redirect } from "next/navigation"; +import { desc, eq } from "drizzle-orm"; +import { db } from "@/lib/db"; +import { INote, IUser, notesTable, usersTable } from "@/lib/db/schema"; + +export async function createNote(user: IUser) { + const result = await db + .insert(notesTable) + .values({ authorId: user.id }) + .returning({ id: usersTable.id }); + const id = result[0].id; + redirect(`/notes/${id}`); +} + +export async function getNotes(user: IUser): Promise { + return db + .select() + .from(notesTable) + .where(eq(notesTable.authorId, user.id)) + .orderBy(desc(notesTable.lastEdited)); +} + +export async function deleteNote(note: INote) { + await db + .delete(notesTable) + .where(eq(notesTable.id, note.id)); + revalidatePath("/notes"); +} diff --git a/src/app/auth/page.tsx b/src/app/auth/page.tsx index ab3766f..d59522e 100644 --- a/src/app/auth/page.tsx +++ b/src/app/auth/page.tsx @@ -2,11 +2,11 @@ import { Metadata } from "next"; import AuthForm from "@/components/forms/AuthForm"; export const metadata: Metadata = { - title: "Authenticate - Rhyme", + title: "Authentication - Rhyme", description: "Register or log into Rhyme account to save, show and load notes", }; -export default function About() { +export default function Auth() { return ( <>

Authenticate

diff --git a/src/app/layout.tsx b/src/app/layout.tsx index 11099cd..7ce4435 100644 --- a/src/app/layout.tsx +++ b/src/app/layout.tsx @@ -1,5 +1,6 @@ import { Metadata } from "next"; import { Noto_Sans_Mono } from "next/font/google"; +import { getAuth } from "./actions/auth"; import Header from "@/components/Header"; import "./globals.css"; @@ -10,18 +11,20 @@ const notoSansMono = Noto_Sans_Mono({ export const metadata: Metadata = { title: "Rhyme", - description: "Line notes writing and sharing", + description: "Free service for writing and saving notes, lyrics, poetry and more", }; -export default function RootLayout({ +export default async function RootLayout({ children, }: Readonly<{ children: React.ReactNode; }>) { + const user = await getAuth(); + return ( -
+
{children}
diff --git a/src/app/notes/page.tsx b/src/app/notes/page.tsx index e8f75fb..401ed85 100644 --- a/src/app/notes/page.tsx +++ b/src/app/notes/page.tsx @@ -1,4 +1,8 @@ +import { getAuth } from "@/app/actions/auth"; +import { getNotes } from "@/app/actions/notes"; +import NoteCard from "@/components/ui/NoteCard"; import { Metadata } from "next"; +import { redirect } from "next/navigation"; export const metadata: Metadata = { title: "Notes - Rhyme", @@ -6,10 +10,16 @@ export const metadata: Metadata = { }; export default async function Notes() { + const user = await getAuth(); + if (!user) { + redirect("/auth"); + } + const notes = await getNotes(user); + return ( <> -

Notes of (username):

- {/* notes */} +

Notes of {user.username}:

+ {notes.map((note) => )} ); } diff --git a/src/components/Header.tsx b/src/components/Header.tsx index 56cfc3e..e0a20cd 100644 --- a/src/components/Header.tsx +++ b/src/components/Header.tsx @@ -1,20 +1,22 @@ +"use client"; + import Link from "next/link"; import { CircleQuestionMark, List, Plus, UserRound, UserRoundMinus } from "lucide-react"; -import { getAuth } from "@/app/actions/auth"; +import { logOut } from "@/app/actions/auth"; +import { createNote } from "@/app/actions/notes"; +import { IUser } from "@/lib/db/schema"; import HeaderButton from "./ui/HeaderButton"; -export default async function Header() { - const auth = await getAuth(); - +export default function Header({ user }: { user: IUser | null }) { return (
- + - {auth && ( + {user && (
- } /> + } onClick={() => createNote(user)} /> } /> @@ -25,8 +27,8 @@ export default async function Header() { } /> - {auth ? ( - } /> + {user ? ( + } /> ) : ( } /> diff --git a/src/components/ui/NoteCard.tsx b/src/components/ui/NoteCard.tsx index 17e0ae9..ec11649 100644 --- a/src/components/ui/NoteCard.tsx +++ b/src/components/ui/NoteCard.tsx @@ -1,18 +1,24 @@ import Link from "next/link"; import { X } from "lucide-react"; import { INote } from "@/lib/db/schema"; +import { deleteNote } from "@/app/actions/notes"; import IconOnlyButton from "./IconOnlyButton"; function makeTimestamp(date: Date) { const day = date.getDate(); const month = date.getMonth() + 1; const year = date.getFullYear(); - const hours = date.getHours(); - const minutes = date.getMinutes(); + const hours = date.getHours().toString().length === 1 ? `0${date.getHours()}` : date.getHours(); + const minutes = date.getMinutes().toString().length === 1 ? `0${date.getMinutes()}` : date.getMinutes(); return `${day}.${month}.${year} ${hours}:${minutes}`; } export default function NoteCard({ note }: { note: INote }) { + const deleteNoteAction = async () => { + "use server"; + await deleteNote(note); + }; + return (
@@ -20,7 +26,7 @@ export default function NoteCard({ note }: { note: INote }) { Last time edited: {makeTimestamp(note.lastEdited)} Creation date: {makeTimestamp(note.creationTime)} - } /> + } onClick={deleteNoteAction} />
); }