import { v4 as uuidv4 } from "uuid"; export type ILine = { id: string; text: string; }; export type IBlock = { id: string; tag: string; locked: boolean; lines: ILine[]; }; type EditorState = IBlock[]; export type Action = | { type: "add_block" } | { type: "copy" } | { type: "delete_block", blockId: string } | { type: "add_line", blockId: string } | { type: "delete_line", blockId: string } | { type: "update_line_text"; blockId: string; lineId: string; text: string } | { type: "update_tag"; blockId: string; tag: string } | { type: "toggle_lock", blockId: string }; export function editorReducer(state: EditorState, action: Action): EditorState { switch (action.type) { case "add_block": return [ ...state, { id: uuidv4(), tag: "", locked: false, lines: Array.from({ length: 4 }, () => ({ id: uuidv4(), text: "", })), } ]; case "copy": let copyText = ""; state.forEach((block) => { if (block.tag !== "") { copyText += `[${block.tag}]\n`; } block.lines.forEach((line) => copyText += line.text + "\n") copyText += "\n"; }); navigator.clipboard.writeText(copyText); return state; case "delete_block": return state.filter((block) => block.id !== action.blockId); case "add_line": return state.map((block) => { if (block.id === action.blockId) { return { ...block, lines: [...block.lines, { id: uuidv4(), text: "" }], }; } else { return block; } }); case "delete_line": return state.map((block) => { if (block.id === action.blockId && block.lines.length > 0) { return { ...block, lines: block.lines.slice(0, -1), }; } else { return block; } }); case "update_line_text": return state.map((block) => { if (block.id === action.blockId) { return { ...block, lines: block.lines.map((line) => { if (line.id === action.lineId) { return { ...line, text: action.text, }; } else { return line; } }), }; } else { return block; } }); case "update_tag": return state.map((block) => { if (block.id === action.blockId) { return { ...block, tag: action.tag, }; } else { return block; } }); case "toggle_lock": return state.map((block) => { if (block.id === action.blockId) { return { ...block, locked: !block.locked, }; } else { return block; } }); default: return state; } }