Clean up tabs

This commit is contained in:
1ilit
2024-04-06 04:58:42 +03:00
parent c67f7f512e
commit 40800f8f28
28 changed files with 2345 additions and 2386 deletions

View File

@@ -0,0 +1,101 @@
import { useState } from "react";
import { Row, Col, Button, Input, Popover, Toast } from "@douyinfe/semi-ui";
import { IconDeleteStroked } from "@douyinfe/semi-icons";
import { useAreas, useSaveState, useUndoRedo } from "../../../hooks";
import {
Action,
ObjectType,
State,
defaultBlue,
} from "../../../data/constants";
import ColorPallete from "../../ColorPallete";
export default function AreaInfo({ data, i }) {
const { setSaveState } = useSaveState();
const { deleteArea, updateArea } = useAreas();
const { setUndoStack, setRedoStack } = useUndoRedo();
const [editField, setEditField] = useState({});
return (
<Row
gutter={6}
type="flex"
justify="start"
align="middle"
id={`scroll_area_${data.id}`}
className="my-3"
>
<Col span={18}>
<Input
value={data.name}
placeholder="Name"
onChange={(value) => updateArea(data.id, { name: value })}
onFocus={(e) => setEditField({ name: e.target.value })}
onBlur={(e) => {
if (e.target.value === editField.name) return;
setUndoStack((prev) => [
...prev,
{
action: Action.EDIT,
element: ObjectType.AREA,
aid: i,
undo: editField,
redo: { name: e.target.value },
message: `Edit area name to ${e.target.value}`,
},
]);
setRedoStack([]);
}}
/>
</Col>
<Col span={3}>
<Popover
content={
<div className="popover-theme">
<ColorPallete
currentColor={data.color}
onClearColor={() => {
updateArea(i, { color: defaultBlue });
setSaveState(State.SAVING);
}}
onPickColor={(c) => {
setUndoStack((prev) => [
...prev,
{
action: Action.EDIT,
element: ObjectType.AREA,
aid: i,
undo: { color: data.color },
redo: { color: c },
message: `Edit area color to ${c}`,
},
]);
setRedoStack([]);
updateArea(i, { color: c });
}}
/>
</div>
}
trigger="click"
position="bottomLeft"
showArrow
>
<div
className="h-[32px] w-[32px] rounded"
style={{ backgroundColor: data.color }}
/>
</Popover>
</Col>
<Col span={3}>
<Button
icon={<IconDeleteStroked />}
type="danger"
onClick={() => {
Toast.success(`Area deleted!`);
deleteArea(i, true);
}}
/>
</Col>
</Row>
);
}

View File

@@ -0,0 +1,37 @@
import { Row, Col, Button } from "@douyinfe/semi-ui";
import { IconPlus } from "@douyinfe/semi-icons";
import Empty from "../Empty";
import { useAreas } from "../../../hooks";
import SearchBar from "./SearchBar";
import AreaInfo from "./AreaDetails";
export default function AreasTab() {
const { areas, addArea } = useAreas();
return (
<div>
<Row gutter={6}>
<Col span={16}>
<SearchBar />
</Col>
<Col span={8}>
<Button icon={<IconPlus />} block onClick={addArea}>
Add area
</Button>
</Col>
</Row>
{areas.length <= 0 ? (
<Empty
title="No subject areas"
text="Add subject areas to organize tables!"
/>
) : (
<div className="p-2">
{areas.map((a, i) => (
<AreaInfo data={a} key={"area_" + i} i={i} />
))}
</div>
)}
</div>
);
}

View File

@@ -0,0 +1,39 @@
import { useState } from "react";
import { useAreas } from "../../../hooks";
import { AutoComplete } from "@douyinfe/semi-ui";
import { IconSearch } from "@douyinfe/semi-icons";
export default function SearchBar() {
const { areas } = useAreas();
const [searchText, setSearchText] = useState("");
const [filteredResult, setFilteredResult] = useState(
areas.map((t) => t.name)
);
const handleStringSearch = (value) => {
setFilteredResult(
areas.map((t) => t.name).filter((i) => i.includes(value))
);
};
return (
<AutoComplete
data={filteredResult}
value={searchText}
showClear
prefix={<IconSearch />}
placeholder="Search..."
emptyContent={<div className="p-3 popover-theme">No areas found</div>}
onSearch={(v) => handleStringSearch(v)}
onChange={(v) => setSearchText(v)}
onSelect={(v) => {
const { id } = areas.find((t) => t.name === v);
document
.getElementById(`scroll_area_${id}`)
.scrollIntoView({ behavior: "smooth" });
}}
className="w-full"
/>
);
}