feat: add title to the editor state
This commit is contained in:
parent
8b1de14f79
commit
2ad220e525
23
src/app/actions/blocks.ts
Normal file
23
src/app/actions/blocks.ts
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
"use server";
|
||||||
|
|
||||||
|
import { eq } from "drizzle-orm";
|
||||||
|
import { blocksTable } from "@/lib/db/schema";
|
||||||
|
import { db } from "@/lib/db";
|
||||||
|
|
||||||
|
export async function updateBlock({
|
||||||
|
id,
|
||||||
|
tag,
|
||||||
|
lines,
|
||||||
|
}: {
|
||||||
|
id: string;
|
||||||
|
tag?: string;
|
||||||
|
lines?: string[];
|
||||||
|
}) {
|
||||||
|
await db
|
||||||
|
.update(blocksTable)
|
||||||
|
.set({
|
||||||
|
...(tag !== undefined ? { tag } : {}),
|
||||||
|
...(lines !== undefined ? { lines } : {}),
|
||||||
|
})
|
||||||
|
.where(eq(blocksTable.id, id));
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
import Link from "next/link";
|
import Link from "next/link";
|
||||||
import { CircleQuestionMark, List, Plus, UserRound, UserRoundMinus } from "lucide-react";
|
import { CircleQuestionMark, List, Plus, UserRound, UserRoundMinus } from "lucide-react";
|
||||||
import { logOut } from "@/app/actions";
|
import { logOut } from "@/app/actions/auth";
|
||||||
import { getAuth } from "@/lib/auth";
|
import { getAuth } from "@/lib/auth";
|
||||||
import HeaderButton from "./ui/HeaderButton";
|
import HeaderButton from "./ui/HeaderButton";
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useReducer } from "react";
|
import { ChangeEvent, useReducer } 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 { editorReducer, IBlock } from "@/lib/editorReducer";
|
import { editorReducer, IBlock } from "@/lib/editorReducer";
|
||||||
@ -25,7 +25,14 @@ const defaultBlocks = [
|
|||||||
];
|
];
|
||||||
|
|
||||||
export default function Editor(props: EditorProps) {
|
export default function Editor(props: EditorProps) {
|
||||||
const [state, dispatch] = useReducer(editorReducer, props.defaultBlocks || defaultBlocks);
|
const [state, dispatch] = useReducer(editorReducer, {
|
||||||
|
title: props.defaultTitle || "Untitled",
|
||||||
|
blocks: props.defaultBlocks || defaultBlocks,
|
||||||
|
});
|
||||||
|
|
||||||
|
const handleUpdateTitle = (e: ChangeEvent<HTMLInputElement>) => {
|
||||||
|
dispatch({ type: "update_title", title: e.target.value });
|
||||||
|
}
|
||||||
|
|
||||||
const handleAddBlock = () => {
|
const handleAddBlock = () => {
|
||||||
dispatch({ type: "add_block" });
|
dispatch({ type: "add_block" });
|
||||||
@ -37,8 +44,8 @@ export default function Editor(props: EditorProps) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex flex-col items-center px-4 max-w-2xl w-full gap-4">
|
<div className="flex flex-col items-center px-4 max-w-2xl w-full gap-4">
|
||||||
<input className="font-bold text-xl w-full text-center focus:outline-none" defaultValue={props.defaultTitle || "Untitled"} />
|
<input className="font-bold text-xl w-full text-center focus:outline-none" defaultValue={state.title} onChange={handleUpdateTitle} />
|
||||||
{state.map((block) => <Block key={block.id} block={block} dispatch={dispatch} /> )}
|
{state.blocks.map((block) => <Block key={block.id} block={block} dispatch={dispatch} /> )}
|
||||||
<div className="flex gap-2">
|
<div className="flex gap-2">
|
||||||
<IconOnlyButton onClick={handleAddBlock} icon={<Plus size={24} />} />
|
<IconOnlyButton onClick={handleAddBlock} icon={<Plus size={24} />} />
|
||||||
<IconOnlyButton onClick={handleCopy} icon={<Copy size={24} />} title="Copy note to clipboard" />
|
<IconOnlyButton onClick={handleCopy} icon={<Copy size={24} />} title="Copy note to clipboard" />
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
"use client";
|
"use client";
|
||||||
|
|
||||||
import { useActionState } from "react";
|
import { useActionState } from "react";
|
||||||
import { login, register } from "@/app/actions";
|
import { login, register } from "@/app/actions/auth";
|
||||||
|
|
||||||
export default function AuthForm({ isRegister = false }: { isRegister?: boolean }) {
|
export default function AuthForm({ isRegister = false }: { isRegister?: boolean }) {
|
||||||
const [state, formAction] = useActionState(isRegister ? register : login, null);
|
const [state, formAction] = useActionState(isRegister ? register : login, null);
|
||||||
|
@ -12,7 +12,10 @@ export type IBlock = {
|
|||||||
lines: ILine[];
|
lines: ILine[];
|
||||||
};
|
};
|
||||||
|
|
||||||
type EditorState = IBlock[];
|
type EditorState = {
|
||||||
|
title: string;
|
||||||
|
blocks: IBlock[];
|
||||||
|
};
|
||||||
|
|
||||||
export type Action =
|
export type Action =
|
||||||
| { type: "add_block" }
|
| { type: "add_block" }
|
||||||
@ -20,6 +23,7 @@ export type Action =
|
|||||||
| { type: "delete_block", blockId: string }
|
| { type: "delete_block", blockId: string }
|
||||||
| { type: "add_line", blockId: string }
|
| { type: "add_line", blockId: string }
|
||||||
| { type: "delete_line", blockId: string }
|
| { type: "delete_line", blockId: string }
|
||||||
|
| { type: "update_title", title: string }
|
||||||
| { type: "update_line_text"; blockId: string; lineId: string; text: string }
|
| { type: "update_line_text"; blockId: string; lineId: string; text: string }
|
||||||
| { type: "update_tag"; blockId: string; tag: string }
|
| { type: "update_tag"; blockId: string; tag: string }
|
||||||
| { type: "move_block_up", blockId: string }
|
| { type: "move_block_up", blockId: string }
|
||||||
@ -28,9 +32,17 @@ export type Action =
|
|||||||
|
|
||||||
export function editorReducer(state: EditorState, action: Action): EditorState {
|
export function editorReducer(state: EditorState, action: Action): EditorState {
|
||||||
switch (action.type) {
|
switch (action.type) {
|
||||||
case "add_block":
|
case "update_title":
|
||||||
return [
|
return {
|
||||||
...state,
|
...state,
|
||||||
|
title: action.title,
|
||||||
|
};
|
||||||
|
|
||||||
|
case "add_block":
|
||||||
|
return {
|
||||||
|
...state,
|
||||||
|
blocks: [
|
||||||
|
...state.blocks,
|
||||||
{
|
{
|
||||||
id: uuidv4(),
|
id: uuidv4(),
|
||||||
tag: "",
|
tag: "",
|
||||||
@ -40,12 +52,13 @@ export function editorReducer(state: EditorState, action: Action): EditorState {
|
|||||||
text: "",
|
text: "",
|
||||||
})),
|
})),
|
||||||
}
|
}
|
||||||
];
|
]
|
||||||
|
};
|
||||||
|
|
||||||
case "copy":
|
case "copy":
|
||||||
let copyText = "";
|
let copyText = "";
|
||||||
|
|
||||||
state.forEach((block) => {
|
state.blocks.forEach((block) => {
|
||||||
if (block.tag !== "") {
|
if (block.tag !== "") {
|
||||||
copyText += `[${block.tag}]\n`;
|
copyText += `[${block.tag}]\n`;
|
||||||
}
|
}
|
||||||
@ -62,10 +75,15 @@ export function editorReducer(state: EditorState, action: Action): EditorState {
|
|||||||
return state;
|
return state;
|
||||||
|
|
||||||
case "delete_block":
|
case "delete_block":
|
||||||
return state.filter((block) => block.id !== action.blockId);
|
return {
|
||||||
|
...state,
|
||||||
|
blocks: state.blocks.filter((block) => block.id !== action.blockId),
|
||||||
|
};
|
||||||
|
|
||||||
case "add_line":
|
case "add_line":
|
||||||
return state.map((block) => {
|
return {
|
||||||
|
...state,
|
||||||
|
blocks: state.blocks.map((block) => {
|
||||||
if (block.id === action.blockId) {
|
if (block.id === action.blockId) {
|
||||||
return {
|
return {
|
||||||
...block,
|
...block,
|
||||||
@ -74,10 +92,13 @@ export function editorReducer(state: EditorState, action: Action): EditorState {
|
|||||||
} else {
|
} else {
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
});
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
case "delete_line":
|
case "delete_line":
|
||||||
return state.map((block) => {
|
return {
|
||||||
|
...state,
|
||||||
|
blocks: state.blocks.map((block) => {
|
||||||
if (block.id === action.blockId && block.lines.length > 0) {
|
if (block.id === action.blockId && block.lines.length > 0) {
|
||||||
return {
|
return {
|
||||||
...block,
|
...block,
|
||||||
@ -86,10 +107,13 @@ export function editorReducer(state: EditorState, action: Action): EditorState {
|
|||||||
} else {
|
} else {
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
});
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
case "update_line_text":
|
case "update_line_text":
|
||||||
return state.map((block) => {
|
return {
|
||||||
|
...state,
|
||||||
|
blocks: state.blocks.map((block) => {
|
||||||
if (block.id === action.blockId) {
|
if (block.id === action.blockId) {
|
||||||
return {
|
return {
|
||||||
...block,
|
...block,
|
||||||
@ -107,10 +131,13 @@ export function editorReducer(state: EditorState, action: Action): EditorState {
|
|||||||
} else {
|
} else {
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
});
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
case "update_tag":
|
case "update_tag":
|
||||||
return state.map((block) => {
|
return {
|
||||||
|
...state,
|
||||||
|
blocks: state.blocks.map((block) => {
|
||||||
if (block.id === action.blockId) {
|
if (block.id === action.blockId) {
|
||||||
return {
|
return {
|
||||||
...block,
|
...block,
|
||||||
@ -119,26 +146,35 @@ export function editorReducer(state: EditorState, action: Action): EditorState {
|
|||||||
} else {
|
} else {
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
});
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
case "move_block_up": {
|
case "move_block_up": {
|
||||||
const index = state.findIndex((b) => b.id === action.blockId);
|
const index = state.blocks.findIndex((b) => b.id === action.blockId);
|
||||||
if (index <= 0) return state;
|
if (index <= 0) return state;
|
||||||
const newState = [...state];
|
const newBlocks = [...state.blocks];
|
||||||
[newState[index - 1], newState[index]] = [newState[index], newState[index - 1]];
|
[newBlocks[index - 1], newBlocks[index]] = [newBlocks[index], newBlocks[index - 1]];
|
||||||
return newState;
|
return {
|
||||||
|
...state,
|
||||||
|
blocks: newBlocks,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
case "move_block_down": {
|
case "move_block_down": {
|
||||||
const index = state.findIndex((b) => b.id === action.blockId);
|
const index = state.blocks.findIndex((b) => b.id === action.blockId);
|
||||||
if (index === state.length - 1) return state;
|
if (index === state.blocks.length - 1) return state;
|
||||||
const newState = [...state];
|
const newBlocks = [...state.blocks];
|
||||||
[newState[index], newState[index + 1]] = [newState[index + 1], newState[index]];
|
[newBlocks[index], newBlocks[index + 1]] = [newBlocks[index + 1], newBlocks[index]];
|
||||||
return newState;
|
return {
|
||||||
|
...state,
|
||||||
|
blocks: newBlocks,
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
case "toggle_lock":
|
case "toggle_lock":
|
||||||
return state.map((block) => {
|
return {
|
||||||
|
...state,
|
||||||
|
blocks: state.blocks.map((block) => {
|
||||||
if (block.id === action.blockId) {
|
if (block.id === action.blockId) {
|
||||||
return {
|
return {
|
||||||
...block,
|
...block,
|
||||||
@ -147,7 +183,8 @@ export function editorReducer(state: EditorState, action: Action): EditorState {
|
|||||||
} else {
|
} else {
|
||||||
return block;
|
return block;
|
||||||
}
|
}
|
||||||
});
|
}),
|
||||||
|
};
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return state;
|
return state;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user