Skip to content

Commit

Permalink
feat: 작성된 섹션 클릭 기능 및 새로운 섹션 추가 기능
Browse files Browse the repository at this point in the history
  • Loading branch information
JaeHyup0504 committed May 9, 2024
1 parent 2a9b390 commit 317e1a7
Show file tree
Hide file tree
Showing 12 changed files with 2,449 additions and 2,322 deletions.
4,472 changes: 2,236 additions & 2,236 deletions .pnp.cjs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/components/Editor/Components/Auto.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const Auto = () => {
{create ? (
<>
<div className="w-full h-auto">
<EditSections type="auto" />
<EditSections />
</div>
<div className="w-full h-auto">
<SelectSections />
Expand Down
2 changes: 1 addition & 1 deletion src/components/Editor/Components/Builder.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const Builder = () => {
return (
<div className="w-full h-full flex flex-col gap-[20px]">
<div className="w-full h-auto">
<EditSections type="builder" />
<EditSections />
</div>
<div className="w-full h-auto">
<SelectSections />
Expand Down
45 changes: 10 additions & 35 deletions src/components/Editor/Components/EditSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,27 +7,12 @@ import { useSection } from "context/SectionContext";
import { SectionsType } from "../types";

interface Props extends SectionsType {
focusSection: number;
setFocusSection: React.Dispatch<React.SetStateAction<number | null>>;
onDeleteSection: (e: React.MouseEvent<HTMLElement, MouseEvent>, targetId: number) => void;
onResetSection: (e: React.MouseEvent<HTMLElement, MouseEvent>, targetId: number) => void;
onDeleteSection: (e: React.MouseEvent<HTMLElement, MouseEvent>, section: SectionsType) => void;
onResetSection: (e: React.MouseEvent<HTMLElement, MouseEvent>, section: SectionsType) => void;
}

const EditSection = ({
id,
title,
markdown,
focusSection,
setFocusSection,
onDeleteSection,
onResetSection,
}: Props) => {
const EditSection = ({ id, title, markdown, onDeleteSection, onResetSection }: Props) => {
const { state, actions } = useSection();

const [hover, setHover] = useState<boolean>(false);
const onMouseEnter = () => setHover(true);
const onMouseLeave = () => setHover(false);

const { attributes, listeners, setNodeRef, transform, transition } = useSortable({ id });

const style = {
Expand All @@ -37,47 +22,37 @@ const EditSection = ({

const onClickSection = () => {
actions.setEditorMarkDown(prev => ({ ...prev, id, title, markdown }));
setFocusSection(id);
actions.setFocusSection(id);
};

useEffect(() => {
localStorage.setItem("select-section", JSON.stringify(state.editorMarkDown));
}, [onClickSection]);
localStorage.setItem("current-section", JSON.stringify(state.editorMarkDown));
}, [state.editorMarkDown]);

return (
<div
ref={setNodeRef}
{...attributes}
style={style}
onClick={onClickSection}
onMouseEnter={onMouseEnter}
onMouseLeave={onMouseLeave}
className={clsx(
"w-full h-[45px] py-[8px] px-[12px]",
"flex flex-row gap-[10px] items-center",
"rounded-[8px] border-solid border bg-white border-[#F1F3F5] drop-shadow-[0_1px_1px_rgba(173,181,189,0.25)]",
"cursor-pointer",
{
"ring-2 ring-textBlue": focusSection === id,
"ring-2 ring-textBlue": state.focusSection === id,
},
)}
>
<List {...listeners} size={25} className="fill-textSecondary min-w-[25px]" />
<p className="text-textPrimary mb-0 truncate">{title}</p>
{focusSection === id && (
{state.focusSection === id && (
<div className="flex flex-row gap-[10px] ml-auto">
<button
onClick={e => {
onResetSection(e, id);
}}
>
<button onClick={e => onResetSection(e, { id, title, markdown })}>
<Reset size={20} className="fill-[#ADB5BD]" />
</button>
<button
onClick={e => {
onDeleteSection(e, id);
}}
>
<button onClick={e => onDeleteSection(e, { id, title, markdown })}>
<TrashCan size={20} className="fill-textPrimary" />
</button>
</div>
Expand Down
56 changes: 34 additions & 22 deletions src/components/Editor/Components/EditSections.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@ import {
} from "@dnd-kit/sortable";
import { restrictToVerticalAxis } from "@dnd-kit/modifiers";
import { useSection } from "context/SectionContext";
import { KeyType, SectionsType } from "../types";
import { SectionsType } from "../types";

const EditSections = ({ type }: KeyType) => {
const { actions } = useSection();
const [sections, setSections] = useState<SectionsType[]>([]);
const [focusSection, setFocusSection] = useState<number | null>(null);
const EditSections = () => {
const { state, actions } = useSection();
const [sections, setSections] = useState<SectionsType[]>(() => {
const localData = JSON.parse(localStorage.getItem("edit-sections-list") || "[]");
return localData.length > 0 ? localData : state.editSections;
});

const getIndex = (id: number) => sections.findIndex(el => el.id === id);

Expand All @@ -33,8 +35,9 @@ const EditSections = ({ type }: KeyType) => {
setSections(sections => {
const oldIndex = getIndex(active.id as number);
const newIndex = getIndex(over?.id as number);

return arrayMove(sections, oldIndex, newIndex);
const newSections = arrayMove(sections, oldIndex, newIndex);
actions.setEditSections(newSections);
return newSections;
});
};

Expand All @@ -46,41 +49,52 @@ const EditSections = ({ type }: KeyType) => {
}),
);

const onDeleteSection = (e: React.MouseEvent<HTMLElement, MouseEvent>, targetId: number) => {
const onDeleteSection = (e: React.MouseEvent<HTMLElement, MouseEvent>, section: SectionsType) => {
e.stopPropagation();
setSections(prev => prev.filter(el => el.id !== targetId));
setSections(prev => prev.filter(el => el.id !== section.id));
actions.setSelectSections(prev => [...prev, section].sort((a, b) => a.id - b.id));
actions.setEditSections(prev => prev.filter(el => el.id !== section.id));
if (sections.length > 1) {
let index;
const deleteSection = sections.findIndex(el => el.id === targetId);
const deleteSection = sections.findIndex(el => el.id === section.id);
if (deleteSection === 0) {
index = 1;
} else {
index = deleteSection - 1;
}
actions.setEditorMarkDown(sections[index]);
setFocusSection(sections[index].id);
actions.setFocusSection(sections[index].id);
} else {
actions.setFocusSection(undefined);
localStorage.removeItem("current-section");
}
};

const onResetSection = (e: React.MouseEvent<HTMLElement, MouseEvent>, targetId: number) => {
const onResetSection = (e: React.MouseEvent<HTMLElement, MouseEvent>, section: SectionsType) => {
e.stopPropagation();
console.log(state.editorMarkDown);
console.log(section.markdown);
// actions.setEditorMarkDown(prev => ({ ...prev, markdown: "" }));
};

useEffect(() => {
const sectionsList = JSON.parse(localStorage.getItem(`${type}-sections-list`) || "[]");
if (sectionsList.length > 0) {
setSections(sectionsList);
actions.setEditorMarkDown(sectionsList[0]);
setFocusSection(sectionsList[0]?.id);
if (sections.length > 0) {
actions.setEditorMarkDown(sections[0]);
actions.setFocusSection(sections[0]?.id);
}
actions.setEditSections(sections);
}, []);

useEffect(() => {
localStorage.setItem(`${type}-sections-list`, JSON.stringify(sections));
const sectionsList = JSON.parse(localStorage.getItem(`${type}-sections-list`) || "[]");
actions.setMarkDowns(sectionsList);
localStorage.setItem("edit-sections-list", JSON.stringify(sections));
}, [sections]);

useEffect(() => {
if (state.editSections.length > 0) {
setSections(state.editSections);
}
}, [state.editSections]);

return (
<div className="flex flex-col gap-[10px] px-[10px]">
<div className="flex-Center flex-row justify-between min-h-[30px]">
Expand All @@ -100,8 +114,6 @@ const EditSections = ({ type }: KeyType) => {
title={section.title}
id={section.id}
markdown={section.markdown}
focusSection={focusSection!}
setFocusSection={setFocusSection}
onDeleteSection={onDeleteSection}
onResetSection={onResetSection}
/>
Expand Down
9 changes: 4 additions & 5 deletions src/components/Editor/Components/Editor.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import React, { useEffect, useState } from "react";
import { useSection } from "context/SectionContext";
import MDEditor, { commands } from "@uiw/react-md-editor";
import { KeyType } from "../types";

const Editor = () => {
const { state, actions } = useSection();
Expand All @@ -11,7 +10,7 @@ const Editor = () => {

const onEditEditor = (value: string) => {
setMarkdownValue(value);
actions.setMarkDowns(prev =>
actions.setEditSections(prev =>
prev.map(markdown => {
if (markdown.id === state.editorMarkDown.id) {
return { ...markdown, markdown: value };
Expand All @@ -20,7 +19,7 @@ const Editor = () => {
}
}),
);
localStorage.setItem("builder-sections-list", JSON.stringify(state.markDowns));
localStorage.setItem("edit-sections-list", JSON.stringify(state.editSections));
};

useEffect(() => {
Expand All @@ -35,7 +34,7 @@ const Editor = () => {
className="w-full h-full rounded-[8px] border-solid border border-textTertiary overflow-y-auto"
data-color-mode="dark"
>
{state.markDowns.length > 0 ? (
{state.editSections.length > 0 ? (
<MDEditor
className="editor"
value={markdownValue}
Expand Down Expand Up @@ -64,7 +63,7 @@ export default Editor;

const EmptySections = () => {
return (
<div className="w-full h-full flex-Center">
<div className="w-full h-full flex-Center p-[20px]">
<p className="text-textBlue">Select a section from the left sidebar to edit the contents</p>
</div>
);
Expand Down
20 changes: 15 additions & 5 deletions src/components/Editor/Components/SelectSection.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
import clsx from "clsx";
import { useSection } from "context/SectionContext";
import React from "react";
import { SectionsType } from "../types";

const SelectSection = () => {
interface Props extends SectionsType {
onClickSection: (e: React.MouseEvent<HTMLElement, MouseEvent>, section: SectionsType) => void;
}

const SelectSection = ({ id, title, markdown, onClickSection }: Props) => {
return (
<div
onClick={e => onClickSection(e, { id, title, markdown })}
className="
w-full h-[45px] py-[8px] px-[12px]
flex items-center
rounded-[8px] border-solid border bg-white border-[#F1F3F5] drop-shadow-[0_1px_1px_rgba(173,181,189,0.25)]
cursor-pointer"
flex items-center
rounded-[8px] border-solid border bg-white border-[#F1F3F5] drop-shadow-[0_1px_1px_rgba(173,181,189,0.25)]
cursor-pointer
hover:ring-2 hover:ring-textBlue
"
>
<p className="text-textPrimary mb-0 truncate"></p>
<p className="text-textPrimary mb-0 truncate">{title}</p>
</div>
);
};
Expand Down
42 changes: 40 additions & 2 deletions src/components/Editor/Components/SelectSections.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,18 @@
import React, { useRef, useState } from "react";
import React, { useEffect, useRef, useState } from "react";
import { Add } from "@carbon/icons-react";
import SearchSection from "./SearchSection";
import SelectSection from "./SelectSection";
import AddSectionModal from "../Modal/AddSectionModal";
import { SectionsType } from "../types";
import { useSection } from "context/SectionContext";

const SelectSections = () => {
const { state, actions } = useSection();
const [sections, setSections] = useState<SectionsType[]>(() => {
const localData = JSON.parse(localStorage.getItem("select-sections-list") || "[]");
return localData.length > 0 ? localData : state.selectSections;
});

const [openModal, setOpenModal] = useState(false);
const modalRef = useRef<HTMLDivElement | null>(null);

Expand All @@ -18,6 +26,28 @@ const SelectSections = () => {
setOpenModal(!openModal);
};

const onClickSection = (e: React.MouseEvent<HTMLElement, MouseEvent>, section: SectionsType) => {
setSections(prev => prev.filter(el => el.id !== section.id));
actions.setSelectSections(prev => prev.filter(el => el.id !== section.id));
actions.setEditSections(prev => [...prev, section]);
actions.setEditorMarkDown(prev => ({ ...prev, ...section }));
actions.setFocusSection(section.id);
};

useEffect(() => {
if (sections.length > 0) {
actions.setSelectSections(sections);
}
}, []);

useEffect(() => {
setSections(state.selectSections);
}, [state.selectSections]);

useEffect(() => {
localStorage.setItem("select-sections-list", JSON.stringify(sections));
}, [sections]);

return (
<div className="h-full flex flex-col gap-[10px] px-[10px]">
<div className="flex-Center flex-row justify-between min-h-[40px]">
Expand All @@ -26,7 +56,15 @@ const SelectSections = () => {
</div>
<div className="h-full max-h-auto flex flex-col gap-[10px]">
<SearchSection />
<SelectSection />
{sections.map(section => (
<SelectSection
key={section.id}
id={section.id}
title={section.title}
markdown={section.markdown}
onClickSection={onClickSection}
/>
))}
</div>
{openModal && (
<AddSectionModal
Expand Down
13 changes: 6 additions & 7 deletions src/components/Editor/EditorPreviewContainer.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
import React, { useEffect, useState } from "react";
import React, { useState } from "react";
import Preview from "./Components/Preview";
import Raw from "./Components/Raw";
import { Tab, Tabs } from "../Common/Tabs";
import { useSection } from "../../context/SectionContext";
import Editor from "./Components/Editor";
import { Download } from "@carbon/icons-react";
import clsx from "clsx";
import { SectionsType } from "./types";

const EditorPreviewContainer = () => {
const { state } = useSection();
const markDownsData = state.markDowns.map(el => el.markdown).join("");
const markDownsData = state.editSections.map(el => el.markdown).join("");
const [selectedTab, setSelectedTab] = useState<string | undefined>("Preview");

const handleTabClick = (value?: string | undefined) => {
Expand Down Expand Up @@ -60,14 +59,14 @@ const EditorPreviewContainer = () => {
"bg-textBlue text-white ",
"rounded-[8px]",
{
"hover:bg-[#6E9EFF]": state.markDowns.length > 0,
"cursor-pointer": state.markDowns.length > 0,
"hover:bg-[#6E9EFF]": state.editSections.length > 0,
"cursor-pointer": state.editSections.length > 0,
},
{
"bg-textTertiary": state.markDowns.length === 0,
"bg-textTertiary": state.editSections.length === 0,
},
)}
disabled={state.markDowns.length > 0 ? false : true}
disabled={state.editSections.length > 0 ? false : true}
>
<Download size={16} />
<p className="mb-0 text-sm">Download</p>
Expand Down
Loading

0 comments on commit 317e1a7

Please sign in to comment.