feat: add line saves
This commit is contained in:
parent
5da589c331
commit
ed28943b54
@ -89,7 +89,6 @@ export async function moveUp(formData: FormData) {
|
|||||||
const block = await getBlock(blockId);
|
const block = await getBlock(blockId);
|
||||||
if (!block) return;
|
if (!block) return;
|
||||||
|
|
||||||
// Найти блок, который перед текущим
|
|
||||||
const siblings = await getBlocks(block.noteId);
|
const siblings = await getBlocks(block.noteId);
|
||||||
const currentIndex = siblings.findIndex((b) => b.id === block.id);
|
const currentIndex = siblings.findIndex((b) => b.id === block.id);
|
||||||
if (currentIndex <= 0) return;
|
if (currentIndex <= 0) return;
|
||||||
@ -136,3 +135,18 @@ export async function moveDown(formData: FormData) {
|
|||||||
|
|
||||||
revalidatePath("/notes/[id]", "page");
|
revalidatePath("/notes/[id]", "page");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function setLines(blockId: string, lines: string[]) {
|
||||||
|
console.log(lines)
|
||||||
|
await db
|
||||||
|
.update(blocksTable)
|
||||||
|
.set({ lines })
|
||||||
|
.where(eq(blocksTable.id, blockId));
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function setTag(blockId: string, tag: string) {
|
||||||
|
await db
|
||||||
|
.update(blocksTable)
|
||||||
|
.set({ tag })
|
||||||
|
.where(eq(blocksTable.id, blockId));
|
||||||
|
}
|
||||||
|
@ -4,8 +4,8 @@ import { revalidatePath } from "next/cache";
|
|||||||
import { redirect } from "next/navigation";
|
import { redirect } from "next/navigation";
|
||||||
import { desc, eq, and } from "drizzle-orm";
|
import { desc, eq, and } from "drizzle-orm";
|
||||||
import { blocksTable, INote, notesTable, usersTable } from "@/lib/db/schema";
|
import { blocksTable, INote, notesTable, usersTable } from "@/lib/db/schema";
|
||||||
import { db } from "@/lib/db";
|
|
||||||
import { requireAuth } from "./auth";
|
import { requireAuth } from "./auth";
|
||||||
|
import { db } from "@/lib/db";
|
||||||
|
|
||||||
export async function createNote() {
|
export async function createNote() {
|
||||||
const user = await requireAuth();
|
const user = await requireAuth();
|
||||||
@ -45,3 +45,11 @@ export async function deleteNote(formData: FormData) {
|
|||||||
.where(and(eq(notesTable.id, noteId), eq(notesTable.authorId, user.id)));
|
.where(and(eq(notesTable.id, noteId), eq(notesTable.authorId, user.id)));
|
||||||
revalidatePath("/notes");
|
revalidatePath("/notes");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function setTitle(noteId: string, title: string) {
|
||||||
|
await db
|
||||||
|
.update(notesTable)
|
||||||
|
.set({ title })
|
||||||
|
.where(eq(notesTable.id, noteId));
|
||||||
|
revalidatePath("/notes/[id]", "page");
|
||||||
|
}
|
||||||
|
@ -1,10 +1,24 @@
|
|||||||
|
import { ChangeEvent, useState } from "react";
|
||||||
import { ArrowDown, ArrowUp, LockOpen, Lock, Minus, Plus, X } from "lucide-react";
|
import { ArrowDown, ArrowUp, LockOpen, Lock, Minus, Plus, X } from "lucide-react";
|
||||||
import { addLine, changeLock, deleteBlock, deleteLine, moveDown, moveUp } from "@/app/actions/blocks";
|
import { addLine, changeLock, deleteBlock, deleteLine, moveDown, moveUp, setLines } from "@/app/actions/blocks";
|
||||||
|
import { useDebounce } from "@/lib/hooks/useDebounce";
|
||||||
import { IBlock } from "@/lib/db/schema";
|
import { IBlock } from "@/lib/db/schema";
|
||||||
import IconOnlyButton from "../ui/IconOnlyButton";
|
import IconOnlyButton from "../ui/IconOnlyButton";
|
||||||
import LineInput from "./LineInput";
|
import LineInput from "./LineInput";
|
||||||
|
|
||||||
export default function Block({ block }: { block: IBlock }) {
|
export default function Block({ block }: { block: IBlock }) {
|
||||||
|
const [lines, setLinesState] = useState(block.lines);
|
||||||
|
|
||||||
|
useDebounce(() => {
|
||||||
|
setLines(block.id, lines);
|
||||||
|
}, [lines]);
|
||||||
|
|
||||||
|
const lineChangeHandler = (i: number, e: ChangeEvent<HTMLInputElement>) => {
|
||||||
|
const newLines = [...lines];
|
||||||
|
newLines[i] = e.target.value;
|
||||||
|
setLinesState(newLines);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col gap-2 w-full">
|
<div className="flex flex-col gap-2 w-full">
|
||||||
<div className="border-2 border-neutral-800 rounded-lg p-3 w-full">
|
<div className="border-2 border-neutral-800 rounded-lg p-3 w-full">
|
||||||
@ -16,7 +30,7 @@ export default function Block({ block }: { block: IBlock }) {
|
|||||||
disabled={block.isLocked}
|
disabled={block.isLocked}
|
||||||
/>
|
/>
|
||||||
{block.lines.map((line, i) => (
|
{block.lines.map((line, i) => (
|
||||||
<LineInput key={i} defaultValue={line} disabled={block.isLocked} />
|
<LineInput key={i} defaultValue={line} disabled={block.isLocked} onChange={(e) => lineChangeHandler(i, e)} />
|
||||||
))}
|
))}
|
||||||
<div className="flex items-center mx-2 mt-2">
|
<div className="flex items-center mx-2 mt-2">
|
||||||
<div className="flex gap-1 mr-4">
|
<div className="flex gap-1 mr-4">
|
||||||
|
@ -1,11 +1,14 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
|
import { useState } from "react";
|
||||||
import { Copy, Plus } from "lucide-react";
|
import { Copy, Plus } from "lucide-react";
|
||||||
import { v4 as uuidv4 } from "uuid";
|
import { v4 as uuidv4 } from "uuid";
|
||||||
import { IBlock, INote } from "@/lib/db/schema";
|
import { IBlock, INote } from "@/lib/db/schema";
|
||||||
import { createBlock } from "@/app/actions/blocks";
|
import { createBlock } from "@/app/actions/blocks";
|
||||||
import IconOnlyButton from "../ui/IconOnlyButton";
|
import IconOnlyButton from "../ui/IconOnlyButton";
|
||||||
import Block from "./Block";
|
import Block from "./Block";
|
||||||
|
import { useDebounce } from "@/lib/hooks/useDebounce";
|
||||||
|
import { setTitle } from "@/app/actions/notes";
|
||||||
|
|
||||||
const defaultNoteId = uuidv4();
|
const defaultNoteId = uuidv4();
|
||||||
|
|
||||||
@ -35,6 +38,8 @@ export default function Editor({
|
|||||||
note?: INote;
|
note?: INote;
|
||||||
blocks?: IBlock[];
|
blocks?: IBlock[];
|
||||||
}) {
|
}) {
|
||||||
|
const [title, setTitleState] = useState(note.title);
|
||||||
|
|
||||||
const copyHandler = () => {
|
const copyHandler = () => {
|
||||||
let copyText = "";
|
let copyText = "";
|
||||||
blocks.forEach((block) => {
|
blocks.forEach((block) => {
|
||||||
@ -46,11 +51,16 @@ export default function Editor({
|
|||||||
navigator.clipboard.writeText(copyText);
|
navigator.clipboard.writeText(copyText);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
useDebounce(() => {
|
||||||
|
setTitle(note.id, title);
|
||||||
|
}, [title]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col items-center max-w-2xl w-full gap-4">
|
<div className="flex flex-col items-center max-w-2xl w-full gap-4">
|
||||||
<input
|
<input
|
||||||
className="font-bold text-xl w-full text-center focus:outline-none"
|
className="font-bold text-xl w-full text-center focus:outline-none"
|
||||||
defaultValue={note.title}
|
onChange={(e) => setTitleState(e.target.value)}
|
||||||
|
value={title}
|
||||||
/>
|
/>
|
||||||
{blocks.map((block) => <Block key={block.id} block={block} /> )}
|
{blocks.map((block) => <Block key={block.id} block={block} /> )}
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
|
@ -1,10 +1,15 @@
|
|||||||
/* eslint-disable react-hooks/exhaustive-deps */
|
/* eslint-disable react-hooks/exhaustive-deps */
|
||||||
import { useEffect } from "react";
|
import { DependencyList, useEffect, useState } from "react";
|
||||||
|
|
||||||
|
export function useDebounce(callback: () => void, deps: DependencyList) {
|
||||||
|
const [isFirstTime, setIsFirstTime] = useState(true);
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
export function useDebounce(callback: () => void, deps: any[]) {
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const timeout = setTimeout(callback, 1000);
|
if (isFirstTime) {
|
||||||
return () => clearTimeout(timeout);
|
setIsFirstTime(false);
|
||||||
|
} else {
|
||||||
|
const timeout = setTimeout(callback, 1000);
|
||||||
|
return () => clearTimeout(timeout);
|
||||||
|
}
|
||||||
}, deps);
|
}, deps);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user