feat: note line management
This commit is contained in:
parent
32b33ae4c4
commit
753fb225e1
@ -1,23 +1,27 @@
|
||||
"use server";
|
||||
|
||||
import { revalidatePath } from "next/cache";
|
||||
import { eq } from "drizzle-orm";
|
||||
import { eq, asc } from "drizzle-orm";
|
||||
import { db } from "@/lib/db";
|
||||
import { blocksTable, IBlock } from "@/lib/db/schema";
|
||||
|
||||
export async function createBlock(formData: FormData) {
|
||||
const noteId = formData.get("noteId") as string;
|
||||
const blocks = await getBlocks(noteId);
|
||||
const lastBlock = blocks.pop();
|
||||
const order = lastBlock === undefined ? 1 : lastBlock.order + 1;
|
||||
await db
|
||||
.insert(blocksTable)
|
||||
.values({ noteId });
|
||||
revalidatePath("/notes/[id]");
|
||||
.values({ noteId, order });
|
||||
revalidatePath("/notes/[id]", "page");
|
||||
}
|
||||
|
||||
export async function getBlocks(noteId: string): Promise<IBlock[]> {
|
||||
return db
|
||||
.select()
|
||||
.from(blocksTable)
|
||||
.where(eq(blocksTable.noteId, noteId));
|
||||
.where(eq(blocksTable.noteId, noteId))
|
||||
.orderBy(asc(blocksTable.order));
|
||||
}
|
||||
|
||||
export async function deleteBlock(formData: FormData) {
|
||||
@ -25,7 +29,7 @@ export async function deleteBlock(formData: FormData) {
|
||||
await db
|
||||
.delete(blocksTable)
|
||||
.where(eq(blocksTable.id, blockId));
|
||||
revalidatePath("/notes/[id]");
|
||||
revalidatePath("/notes/[id]", "page");
|
||||
}
|
||||
|
||||
export async function changeLock(formData: FormData) {
|
||||
@ -35,5 +39,39 @@ export async function changeLock(formData: FormData) {
|
||||
.update(blocksTable)
|
||||
.set({ isLocked })
|
||||
.where(eq(blocksTable.id, blockId));
|
||||
revalidatePath("/notes/[id]");
|
||||
revalidatePath("/notes/[id]", "page");
|
||||
}
|
||||
|
||||
export async function addLine(formData: FormData) {
|
||||
const blockId = formData.get("blockId") as string;
|
||||
const blocks = await db
|
||||
.select()
|
||||
.from(blocksTable)
|
||||
.where(eq(blocksTable.id, blockId));
|
||||
if (blocks.length === 0) {
|
||||
return;
|
||||
}
|
||||
const block = blocks[0];
|
||||
await db
|
||||
.update(blocksTable)
|
||||
.set({ lines: [...block.lines, ""] })
|
||||
.where(eq(blocksTable.id, blockId));
|
||||
revalidatePath("/notes/[id]", "page");
|
||||
}
|
||||
|
||||
export async function deleteLine(formData: FormData) {
|
||||
const blockId = formData.get("blockId") as string;
|
||||
const blocks = await db
|
||||
.select()
|
||||
.from(blocksTable)
|
||||
.where(eq(blocksTable.id, blockId));
|
||||
if (blocks.length === 0) {
|
||||
return;
|
||||
}
|
||||
const block = blocks[0];
|
||||
await db
|
||||
.update(blocksTable)
|
||||
.set({ lines: block.lines.slice(0, -1) })
|
||||
.where(eq(blocksTable.id, blockId));
|
||||
revalidatePath("/notes/[id]", "page");
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { ArrowDown, ArrowUp, LockOpen, Lock, Minus, Plus, X } from "lucide-react";
|
||||
import { changeLock, deleteBlock } from "@/app/actions/blocks";
|
||||
import { addLine, changeLock, deleteBlock, deleteLine } from "@/app/actions/blocks";
|
||||
import { IBlock } from "@/lib/db/schema";
|
||||
import IconOnlyButton from "../ui/IconOnlyButton";
|
||||
import LineInput from "./LineInput";
|
||||
@ -20,26 +20,33 @@ export default function Block({ block }: { block: IBlock }) {
|
||||
))}
|
||||
<div className="flex items-center mx-2 mt-2">
|
||||
<div className="flex gap-1 mr-4">
|
||||
<IconOnlyButton icon={<Plus size={18} />} disabled={block.isLocked} />
|
||||
<IconOnlyButton icon={<Minus size={18} />} disabled={block.isLocked} />
|
||||
<form action={addLine}>
|
||||
<input type="hidden" name="blockId" value={block.id} />
|
||||
<IconOnlyButton type="submit" icon={<Plus size={18} />} disabled={block.isLocked} />
|
||||
</form>
|
||||
<form action={deleteLine}>
|
||||
<input type="hidden" name="blockId" value={block.id} />
|
||||
<IconOnlyButton type="submit" icon={<Minus size={18} />} disabled={block.isLocked} />
|
||||
</form>
|
||||
</div>
|
||||
<div className="flex gap-1">
|
||||
<IconOnlyButton icon={<ArrowUp size={18} />} />
|
||||
<IconOnlyButton icon={<ArrowDown size={18} />} />
|
||||
</div>
|
||||
<div className="flex gap-2 ml-auto">
|
||||
<form action={deleteBlock}>
|
||||
<input type="hidden" name="blockId" value={block.id} />
|
||||
<IconOnlyButton icon={<X size={18} />} type="submit" />
|
||||
</form>
|
||||
<form action={changeLock}>
|
||||
<input type="hidden" name="blockId" value={block.id} />
|
||||
{!block.isLocked && <input type="hidden" name="isLocked" />}
|
||||
<IconOnlyButton
|
||||
type="submit"
|
||||
alwaysOn={block.isLocked}
|
||||
icon={block.isLocked ? <Lock size={18} /> : <LockOpen size={18} />}
|
||||
/>
|
||||
</form>
|
||||
<form action={deleteBlock}>
|
||||
<input type="hidden" name="blockId" value={block.id} />
|
||||
<IconOnlyButton type="submit" icon={<X size={18} />} />
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
Loading…
x
Reference in New Issue
Block a user