Reorganize files

This commit is contained in:
1ilit 2024-04-01 19:44:50 +03:00
parent d4bc5a9669
commit 9df9527950
28 changed files with 280 additions and 253 deletions

View File

@ -12,14 +12,16 @@ import {
tableThemes,
defaultBlue,
State,
} from "../data/constants";
import useLayout from "../hooks/useLayout";
import useSettings from "../hooks/useSettings";
import useUndoRedo from "../hooks/useUndoRedo";
import useSelect from "../hooks/useSelect";
import useAreas from "../hooks/useAreas";
import useSaveState from "../hooks/useSaveState";
import useTransform from "../hooks/useTransform";
} from "../../data/constants";
import {
useLayout,
useSettings,
useUndoRedo,
useSelect,
useAreas,
useSaveState,
useTransform,
} from "../../hooks";
export default function Area({ data, onMouseDown, setResize, setInitCoords }) {
const [hovered, setHovered] = useState(false);

View File

@ -1,17 +1,17 @@
import { useRef, useState, useEffect } from "react";
import { Action, Cardinality, Constraint, ObjectType } from "../data/constants";
import { Action, Cardinality, Constraint, ObjectType } from "../../data/constants";
import { Toast } from "@douyinfe/semi-ui";
import Table from "./Table";
import Area from "./Area";
import Relationship from "./Relationship";
import Note from "./Note";
import useSettings from "../hooks/useSettings";
import useTransform from "../hooks/useTransform";
import useTables from "../hooks/useTables";
import useUndoRedo from "../hooks/useUndoRedo";
import useSelect from "../hooks/useSelect";
import useAreas from "../hooks/useAreas";
import useNotes from "../hooks/useNotes";
import useSettings from "../../hooks/useSettings";
import useTransform from "../../hooks/useTransform";
import useTables from "../../hooks/useTables";
import useUndoRedo from "../../hooks/useUndoRedo";
import useSelect from "../../hooks/useSelect";
import useAreas from "../../hooks/useAreas";
import useNotes from "../../hooks/useNotes";
export default function Canvas() {
const { tables, updateTable, relationships, addRelationship } = useTables();

View File

@ -1,16 +1,16 @@
import { useState } from "react";
import { Action, ObjectType, noteThemes, Tab, State } from "../data/constants";
import { Action, ObjectType, noteThemes, Tab, State } from "../../data/constants";
import { Input, Button, Popover, Toast } from "@douyinfe/semi-ui";
import {
IconEdit,
IconDeleteStroked,
IconCheckboxTick,
} from "@douyinfe/semi-icons";
import useLayout from "../hooks/useLayout";
import useUndoRedo from "../hooks/useUndoRedo";
import useSelect from "../hooks/useSelect";
import useNotes from "../hooks/useNotes";
import useSaveState from "../hooks/useSaveState";
import useLayout from "../../hooks/useLayout";
import useUndoRedo from "../../hooks/useUndoRedo";
import useSelect from "../../hooks/useSelect";
import useNotes from "../../hooks/useNotes";
import useSaveState from "../../hooks/useSaveState";
export default function Note({ data, onMouseDown }) {
const w = 180;

View File

@ -1,7 +1,7 @@
import { useRef } from "react";
import { Cardinality } from "../data/constants";
import useSettings from "../hooks/useSettings";
import { calcPath } from "../utils/calcPath";
import { Cardinality } from "../../data/constants";
import useSettings from "../../hooks/useSettings";
import { calcPath } from "../../utils/calcPath";
export default function Relationship({ data }) {
const { settings } = useSettings();

View File

@ -6,7 +6,7 @@ import {
Tab,
Action,
ObjectType,
} from "../data/constants";
} from "../../data/constants";
import {
IconEdit,
IconMore,
@ -31,13 +31,13 @@ import {
SideSheet,
Toast,
} from "@douyinfe/semi-ui";
import { getSize, hasCheck, hasPrecision, isSized } from "../utils/toSQL";
import useLayout from "../hooks/useLayout";
import useSettings from "../hooks/useSettings";
import useUndoRedo from "../hooks/useUndoRedo";
import useTables from "../hooks/useTables";
import useSelect from "../hooks/useSelect";
import useTypes from "../hooks/useTypes";
import { getSize, hasCheck, hasPrecision, isSized } from "../../utils/toSQL";
import useLayout from "../../hooks/useLayout";
import useSettings from "../../hooks/useSettings";
import useUndoRedo from "../../hooks/useUndoRedo";
import useTables from "../../hooks/useTables";
import useSelect from "../../hooks/useSelect";
import useTypes from "../../hooks/useTypes";
export default function Table(props) {
const [isHovered, setIsHovered] = useState(false);

View File

@ -12,7 +12,7 @@ import {
IconEdit,
} from "@douyinfe/semi-icons";
import { Link, useNavigate } from "react-router-dom";
import icon from "../assets/icon_dark_64.png";
import icon from "../../assets/icon_dark_64.png";
import {
Button,
Divider,
@ -31,9 +31,9 @@ import {
Select,
Checkbox,
} from "@douyinfe/semi-ui";
import timeLine from "../assets/process.png";
import timeLineDark from "../assets/process_dark.png";
import todo from "../assets/calendar.png";
import timeLine from "../../assets/process.png";
import timeLineDark from "../../assets/process_dark.png";
import todo from "../../assets/calendar.png";
import { toPng, toJpeg, toSvg } from "html-to-image";
import { saveAs } from "file-saver";
import {
@ -42,32 +42,32 @@ import {
jsonToSQLite,
jsonToMariaDB,
jsonToSQLServer,
} from "../utils/toSQL";
import { IconAddTable, IconAddArea, IconAddNote } from "./CustomIcons";
import { ObjectType, Action, Tab, State, Cardinality } from "../data/constants";
} from "../../utils/toSQL";
import { IconAddTable, IconAddArea, IconAddNote } from "../CustomIcons";
import { ObjectType, Action, Tab, State, Cardinality } from "../../data/constants";
import jsPDF from "jspdf";
import { useHotkeys } from "react-hotkeys-hook";
import { Validator } from "jsonschema";
import { areaSchema, noteSchema, tableSchema } from "../data/schemas";
import { areaSchema, noteSchema, tableSchema } from "../../data/schemas";
import Editor from "@monaco-editor/react";
import { db } from "../data/db";
import { db } from "../../data/db";
import { useLiveQuery } from "dexie-react-hooks";
import { Parser } from "node-sql-parser";
import Todo from "./Todo";
import { Thumbnail } from "./Thumbnail";
import useLayout from "../hooks/useLayout";
import useSettings from "../hooks/useSettings";
import useTransform from "../hooks/useTransform";
import useTables from "../hooks/useTables";
import useUndoRedo from "../hooks/useUndoRedo";
import useSelect from "../hooks/useSelect";
import { enterFullscreen, exitFullscreen } from "../utils/fullscreen";
import { ddbDiagramIsValid, jsonDiagramIsValid } from "../utils/validateSchema";
import { dataURItoBlob } from "../utils/utils";
import useAreas from "../hooks/useAreas";
import useNotes from "../hooks/useNotes";
import useTypes from "../hooks/useTypes";
import useSaveState from "../hooks/useSaveState";
import useLayout from "../../hooks/useLayout";
import useSettings from "../../hooks/useSettings";
import useTransform from "../../hooks/useTransform";
import useTables from "../../hooks/useTables";
import useUndoRedo from "../../hooks/useUndoRedo";
import useSelect from "../../hooks/useSelect";
import { enterFullscreen, exitFullscreen } from "../../utils/fullscreen";
import { ddbDiagramIsValid, jsonDiagramIsValid } from "../../utils/validateSchema";
import { dataURItoBlob } from "../../utils/utils";
import useAreas from "../../hooks/useAreas";
import useNotes from "../../hooks/useNotes";
import useTypes from "../../hooks/useTypes";
import useSaveState from "../../hooks/useSaveState";
export default function ControlPanel({
diagramId,

View File

@ -1,4 +1,4 @@
import { calcPath } from "../utils/calcPath";
import { calcPath } from "../../utils/calcPath";
export function Thumbnail({ diagram, i, zoom }) {
const translateX = 32 * zoom;

View File

@ -19,9 +19,9 @@ import {
IconDeleteStroked,
IconCaretdown,
} from "@douyinfe/semi-icons";
import { State } from "../data/constants";
import useTasks from "../hooks/useTasks";
import useSaveState from "../hooks/useSaveState";
import { State } from "../../data/constants";
import useTasks from "../../hooks/useTasks";
import useSaveState from "../../hooks/useSaveState";
const Priority = {
NONE: 0,

View File

@ -20,10 +20,10 @@ import {
Action,
ObjectType,
State,
} from "../data/constants";
import useUndoRedo from "../hooks/useUndoRedo";
import useAreas from "../hooks/useAreas";
import useSaveState from "../hooks/useSaveState";
} from "../../data/constants";
import useUndoRedo from "../../hooks/useUndoRedo";
import useAreas from "../../hooks/useAreas";
import useSaveState from "../../hooks/useSaveState";
import Empty from "./Empty";
export default function AreasOverview() {

View File

@ -1,10 +1,10 @@
import { useState, useEffect } from "react";
import { Collapse, Badge } from "@douyinfe/semi-ui";
import { arrayIsEqual } from "../utils/utils";
import { getIssues } from "../utils/issues";
import useSettings from "../hooks/useSettings";
import useTables from "../hooks/useTables";
import useTypes from "../hooks/useTypes";
import { arrayIsEqual } from "../../utils/utils";
import { getIssues } from "../../utils/issues";
import useSettings from "../../hooks/useSettings";
import useTables from "../../hooks/useTables";
import useTypes from "../../hooks/useTypes";
export default function Issues() {
const { settings } = useSettings();

View File

@ -16,9 +16,9 @@ import {
IconSearch,
IconCheckboxTick,
} from "@douyinfe/semi-icons";
import { noteThemes, Action, ObjectType } from "../data/constants";
import useUndoRedo from "../hooks/useUndoRedo";
import useNotes from "../hooks/useNotes";
import { noteThemes, Action, ObjectType } from "../../data/constants";
import useUndoRedo from "../../hooks/useUndoRedo";
import useNotes from "../../hooks/useNotes";
import Empty from "./Empty";
export default function NotesOverview() {

View File

@ -15,9 +15,9 @@ import {
IconMore,
IconSearch,
} from "@douyinfe/semi-icons";
import { Cardinality, Constraint, Action, ObjectType } from "../data/constants";
import useTables from "../hooks/useTables";
import useUndoRedo from "../hooks/useUndoRedo";
import { Cardinality, Constraint, Action, ObjectType } from "../../data/constants";
import useTables from "../../hooks/useTables";
import useUndoRedo from "../../hooks/useUndoRedo";
import Empty from "./Empty";
export default function RelationshipsOverview() {

View File

@ -1,13 +1,13 @@
import { Tabs } from "@douyinfe/semi-ui";
import { Tab } from "../data/constants";
import { Tab } from "../../data/constants";
import TablesOverview from "./TablesOverview";
import RelationshipsOverview from "./RelationshipsOverview";
import AreasOverview from "./AreasOverview";
import NotesOverview from "./NotesOverview";
import TypesOverview from "./TypesOverview";
import Issues from "./Issues";
import useLayout from "../hooks/useLayout";
import useSelect from "../hooks/useSelect";
import useLayout from "../../hooks/useLayout";
import useSelect from "../../hooks/useSelect";
export default function SidePanel({ width, resize, setResize }) {
const { layout } = useLayout();

View File

@ -5,7 +5,7 @@ import {
defaultBlue,
sqlDataTypes,
tableThemes,
} from "../data/constants";
} from "../../data/constants";
import {
Collapse,
Row,
@ -30,11 +30,11 @@ import {
IconPlus,
IconSearch,
} from "@douyinfe/semi-icons";
import { getSize, hasCheck, hasPrecision, isSized } from "../utils/toSQL";
import useTables from "../hooks/useTables";
import useUndoRedo from "../hooks/useUndoRedo";
import useSelect from "../hooks/useSelect";
import useTypes from "../hooks/useTypes";
import { getSize, hasCheck, hasPrecision, isSized } from "../../utils/toSQL";
import useTables from "../../hooks/useTables";
import useUndoRedo from "../../hooks/useUndoRedo";
import useSelect from "../../hooks/useSelect";
import useTypes from "../../hooks/useTypes";
import NoElements from "./Empty";
export default function TablesOverview() {

View File

@ -1,5 +1,5 @@
import { useState } from "react";
import { Action, ObjectType, sqlDataTypes } from "../data/constants";
import { Action, ObjectType, sqlDataTypes } from "../../data/constants";
import {
Collapse,
Row,
@ -22,9 +22,9 @@ import {
IconInfoCircle,
IconMore,
} from "@douyinfe/semi-icons";
import { isSized, hasPrecision, getSize } from "../utils/toSQL";
import useUndoRedo from "../hooks/useUndoRedo";
import useTypes from "../hooks/useTypes";
import { isSized, hasPrecision, getSize } from "../../utils/toSQL";
import useUndoRedo from "../../hooks/useUndoRedo";
import useTypes from "../../hooks/useTypes";
import NoElements from "./Empty";
export default function TypesOverview() {

View File

@ -3,7 +3,7 @@ import useTransform from "../hooks/useTransform";
import useLayout from "../hooks/useLayout";
import { exitFullscreen } from "../utils/fullscreen";
export default function Controls() {
export default function FloatingControls() {
const { transform, setTransform } = useTransform();
const { setLayout } = useLayout();

View File

@ -8,11 +8,11 @@ import { MarkdownShortcutPlugin } from "@lexical/react/LexicalMarkdownShortcutPl
import { ClearEditorPlugin } from "@lexical/react/LexicalClearEditorPlugin";
import { TRANSFORMERS } from "@lexical/markdown";
import LexicalErrorBoundary from "@lexical/react/LexicalErrorBoundary";
import ToolbarPlugin from "../plugins/ToolbarPlugin";
import ListMaxIndentLevelPlugin from "../plugins/ListMaxIndentLevelPlugin";
import CodeHighlightPlugin from "../plugins/CodeHighlightPlugin";
import AutoLinkPlugin from "../plugins/AutoLinkPlugin";
import "../styles/richeditor.css";
import ToolbarPlugin from "./ToolbarPlugin";
import ListMaxIndentLevelPlugin from "./ListMaxIndentLevelPlugin";
import CodeHighlightPlugin from "./CodeHighlightPlugin";
import AutoLinkPlugin from "./AutoLinkPlugin";
import "./styles/index.css";
function Placeholder({ text }) {
return <div className="editor-placeholder">{text || ""}</div>;

View File

@ -40,7 +40,7 @@ import {
getCodeLanguages,
} from "@lexical/code";
import { Dropdown } from "@douyinfe/semi-ui";
import "../styles/richeditor.css";
import "./styles/index.css";
const LowPriority = 1;

View File

@ -1,7 +1,7 @@
import { useState, useEffect, useCallback } from "react";
import ControlPanel from "../components/ControlPanel";
import Canvas from "../components/Canvas";
import SidePanel from "../components/SidePanel";
import ControlPanel from "./EditorHeader/ControlPanel";
import Canvas from "./EditorCanvas/Canvas";
import SidePanel from "./EditorSidePanel/SidePanel";
import { State } from "../data/constants";
import { db } from "../data/db";
import useLayout from "../hooks/useLayout";
@ -9,7 +9,7 @@ import useSettings from "../hooks/useSettings";
import useTransform from "../hooks/useTransform";
import useTables from "../hooks/useTables";
import useUndoRedo from "../hooks/useUndoRedo";
import Controls from "../components/Controls";
import FloatingControls from "./FloatingControls";
import useAreas from "../hooks/useAreas";
import useNotes from "../hooks/useNotes";
import useTypes from "../hooks/useTypes";
@ -302,7 +302,7 @@ export default function WorkSpace() {
<Canvas saveState={saveState} setSaveState={setSaveState} />
{!(layout.sidebar || layout.toolbar || layout.header) && (
<div className="fixed right-5 bottom-4">
<Controls />
<FloatingControls />
</div>
)}
</div>

25
src/hooks/index.js Normal file
View File

@ -0,0 +1,25 @@
import useAreas from "./useAreas";
import useLayout from "./useLayout";
import useNotes from "./useNotes";
import useSaveState from "./useSaveState";
import useSelect from "./useSelect";
import useSettings from "./useSettings";
import useTables from "./useTables";
import useTasks from "./useTasks";
import useTransform from "./useTransform";
import useTypes from "./useTypes";
import useUndoRedo from "./useUndoRedo";
export {
useAreas,
useLayout,
useNotes,
useSaveState,
useSelect,
useSettings,
useTables,
useTasks,
useTransform,
useTypes,
useUndoRedo,
};

View File

@ -8,7 +8,7 @@ import {
IconGithubLogo,
IconPaperclip,
} from "@douyinfe/semi-icons";
import RichEditor from "../components/RichEditor";
import RichEditor from "../components/LexicalEditor/RichEditor";
import { LexicalComposer } from "@lexical/react/LexicalComposer";
import { editorConfig } from "../data/editorConfig";
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";

View File

@ -13,7 +13,7 @@ import {
TextArea,
} from "@douyinfe/semi-ui";
import { IconSun, IconMoon } from "@douyinfe/semi-icons";
import RichEditor from "../components/RichEditor";
import RichEditor from "../components/LexicalEditor/RichEditor";
import { LexicalComposer } from "@lexical/react/LexicalComposer";
import { editorConfig } from "../data/editorConfig";
import { useLexicalComposerContext } from "@lexical/react/LexicalComposerContext";

View File

@ -8,158 +8,6 @@ import { db } from "../data/db";
import { useLiveQuery } from "dexie-react-hooks";
import { calcPath } from "../utils/calcPath";
function Thumbnail({ diagram, i }) {
const zoom = 0.3;
return (
<div className="w-full select-none">
<svg className="bg-white w-full h-full rounded-t-md">
<defs>
<pattern
id={"pattern-circles-" + i}
x="0"
y="0"
width="10"
height="10"
patternUnits="userSpaceOnUse"
patternContentUnits="userSpaceOnUse"
>
<circle
id={"pattern-circle-" + i}
cx="2"
cy="2"
r="0.4"
fill="rgb(99, 152, 191)"
></circle>
</pattern>
</defs>
<rect
x="0"
y="0"
width="100%"
height="100%"
fill={"url(#pattern-circles-" + i + ")"}
></rect>
<g>
{diagram.subjectAreas?.map((a) => (
<foreignObject
key={a.id}
x={a.x * zoom}
y={a.y * zoom}
width={a.width > 0 ? a.width * zoom : 0}
height={a.height > 0 ? a.height * zoom : 0}
>
<div
className={`border border-slate-400 w-full h-full rounded-sm relative`}
>
<div
className="opacity-40 w-fill h-full"
style={{ backgroundColor: a.color }}
/>
</div>
<div className="text-color absolute top-[4px] left-[6px] select-none text-[4px]">
{a.name}
</div>
</foreignObject>
))}
{diagram.tables?.map((table, i) => {
const height = table.fields.length * 36 + 50 + 7;
return (
<foreignObject
x={table.x * zoom}
y={table.y * zoom}
width={200 * zoom}
height={height * zoom}
key={i}
>
<div className="border-[1px] rounded-[3px] border-zinc-300 text-[4px] bg-zinc-100">
<div
className="h-[4px] w-full rounded-t-sm"
style={{ backgroundColor: table.color }}
></div>
<div className="rounded-b-[3px]">
<div className="bg-zinc-200 font-bold py-[2px] px-[4px] border-b border-gray-300">
{table.name}
</div>
{table.fields.map((f, j) => (
<div
className={`flex justify-between items-center py-[2px] px-[3px] ${
j < table.fields.length - 1 ? "border-b" : ""
}`}
key={j}
>
<div className="flex items-center justify-start">
<div
className={`w-[3px] h-[3px] bg-[#2f68ad] opacity-80 z-50 rounded-full me-[2px]`}
></div>
<div>{f.name}</div>
</div>
<div className="text-zinc-500">{f.type}</div>
</div>
))}
</div>
</div>
</foreignObject>
);
})}
{diagram.relationships?.map((e, i) => (
<path
key={i}
d={calcPath(e.startX, e.endX, e.startY, e.endY, zoom)}
fill="none"
strokeWidth={1}
stroke="gray"
/>
))}
{diagram.notes?.map((n) => {
const x = n.x * zoom;
const y = n.y * zoom;
const w = 180 * zoom;
const r = 3 * zoom;
const fold = 24 * zoom;
const h = n.height * zoom;
return (
<g key={n.id}>
<path
d={`M${x + fold} ${y} L${x + w - r} ${y} A${r} ${r} 0 0 1 ${
x + w
} ${y + r} L${x + w} ${y + h - r} A${r} ${r} 0 0 1 ${
x + w - r
} ${y + h} L${x + r} ${y + h} A${r} ${r} 0 0 1 ${x} ${
y + h - r
} L${x} ${y + fold}`}
fill={n.color}
stroke="rgb(168 162 158)"
strokeLinejoin="round"
strokeWidth="0.5"
/>
<path
d={`M${x} ${y + fold} L${x + fold - r} ${
y + fold
} A${r} ${r} 0 0 0 ${x + fold} ${y + fold - r} L${
x + fold
} ${y} L${x} ${y + fold} Z`}
fill={n.color}
stroke={"rgb(168 162 158)"}
strokeLinejoin="round"
strokeWidth="0.5"
/>
<foreignObject x={x} y={y} width={w} height={h}>
<div className="text-gray-900 w-full h-full px-[4px] py-[2px] text-[4px]">
<label htmlFor={`note_${n.id}`} className="ms-[6px]">
{n.title}
</label>
<div className="text-[4px] mt-[2px]">{n.content}</div>
</div>
</foreignObject>
</g>
);
})}
</g>
</svg>
</div>
);
}
export default function Templates() {
const defaultTemplates = useLiveQuery(() =>
db.templates.where({ custom: 0 }).toArray()
@ -339,3 +187,155 @@ export default function Templates() {
</div>
);
}
function Thumbnail({ diagram, i }) {
const zoom = 0.3;
return (
<div className="w-full select-none">
<svg className="bg-white w-full h-full rounded-t-md">
<defs>
<pattern
id={"pattern-circles-" + i}
x="0"
y="0"
width="10"
height="10"
patternUnits="userSpaceOnUse"
patternContentUnits="userSpaceOnUse"
>
<circle
id={"pattern-circle-" + i}
cx="2"
cy="2"
r="0.4"
fill="rgb(99, 152, 191)"
></circle>
</pattern>
</defs>
<rect
x="0"
y="0"
width="100%"
height="100%"
fill={"url(#pattern-circles-" + i + ")"}
></rect>
<g>
{diagram.subjectAreas?.map((a) => (
<foreignObject
key={a.id}
x={a.x * zoom}
y={a.y * zoom}
width={a.width > 0 ? a.width * zoom : 0}
height={a.height > 0 ? a.height * zoom : 0}
>
<div
className={`border border-slate-400 w-full h-full rounded-sm relative`}
>
<div
className="opacity-40 w-fill h-full"
style={{ backgroundColor: a.color }}
/>
</div>
<div className="text-color absolute top-[4px] left-[6px] select-none text-[4px]">
{a.name}
</div>
</foreignObject>
))}
{diagram.tables?.map((table, i) => {
const height = table.fields.length * 36 + 50 + 7;
return (
<foreignObject
x={table.x * zoom}
y={table.y * zoom}
width={200 * zoom}
height={height * zoom}
key={i}
>
<div className="border-[1px] rounded-[3px] border-zinc-300 text-[4px] bg-zinc-100">
<div
className="h-[4px] w-full rounded-t-sm"
style={{ backgroundColor: table.color }}
></div>
<div className="rounded-b-[3px]">
<div className="bg-zinc-200 font-bold py-[2px] px-[4px] border-b border-gray-300">
{table.name}
</div>
{table.fields.map((f, j) => (
<div
className={`flex justify-between items-center py-[2px] px-[3px] ${
j < table.fields.length - 1 ? "border-b" : ""
}`}
key={j}
>
<div className="flex items-center justify-start">
<div
className={`w-[3px] h-[3px] bg-[#2f68ad] opacity-80 z-50 rounded-full me-[2px]`}
></div>
<div>{f.name}</div>
</div>
<div className="text-zinc-500">{f.type}</div>
</div>
))}
</div>
</div>
</foreignObject>
);
})}
{diagram.relationships?.map((e, i) => (
<path
key={i}
d={calcPath(e.startX, e.endX, e.startY, e.endY, zoom)}
fill="none"
strokeWidth={1}
stroke="gray"
/>
))}
{diagram.notes?.map((n) => {
const x = n.x * zoom;
const y = n.y * zoom;
const w = 180 * zoom;
const r = 3 * zoom;
const fold = 24 * zoom;
const h = n.height * zoom;
return (
<g key={n.id}>
<path
d={`M${x + fold} ${y} L${x + w - r} ${y} A${r} ${r} 0 0 1 ${
x + w
} ${y + r} L${x + w} ${y + h - r} A${r} ${r} 0 0 1 ${
x + w - r
} ${y + h} L${x + r} ${y + h} A${r} ${r} 0 0 1 ${x} ${
y + h - r
} L${x} ${y + fold}`}
fill={n.color}
stroke="rgb(168 162 158)"
strokeLinejoin="round"
strokeWidth="0.5"
/>
<path
d={`M${x} ${y + fold} L${x + fold - r} ${
y + fold
} A${r} ${r} 0 0 0 ${x + fold} ${y + fold - r} L${
x + fold
} ${y} L${x} ${y + fold} Z`}
fill={n.color}
stroke={"rgb(168 162 158)"}
strokeLinejoin="round"
strokeWidth="0.5"
/>
<foreignObject x={x} y={y} width={w} height={h}>
<div className="text-gray-900 w-full h-full px-[4px] py-[2px] text-[4px]">
<label htmlFor={`note_${n.id}`} className="ms-[6px]">
{n.title}
</label>
<div className="text-[4px] mt-[2px]">{n.content}</div>
</div>
</foreignObject>
</g>
);
})}
</g>
</svg>
</div>
);
}