- {post.username}
-
-
- {dateToKorean(post.createdAt)}
+
+
+
+ {post.username}
+
+
+ {dateToKorean(post.createdAt)}
+
+
+
diff --git a/src/components/setting/FolderAddModal.tsx b/src/components/setting/FolderAddModal.tsx
deleted file mode 100644
index ee9d235..0000000
--- a/src/components/setting/FolderAddModal.tsx
+++ /dev/null
@@ -1,94 +0,0 @@
-import ModalLayout from "../../layout/ModalLayout.tsx";
-import {useState} from "react";
-import {FillButton} from "../common/FillButton.tsx";
-import {TextButton} from "../common/TextButton.tsx";
-import {MdOutlineArrowDropDown} from "react-icons/md";
-import {FolderType} from "../../common/types/blog.tsx";
-
-function FolderAddModal({folders, setShowFolderAddModal}: {
- folders: FolderType[],
- setShowFolderAddModal: (modal: boolean) => void
-}) {
-
- const [inputFolder, setInputFolder] = useState("");
- const [folderOpen, setFolderOpen] = useState(false);
- const [selectedFolder, setSelectedFolder] = useState("블로그");
-
- return (
-
-
-
폴더 추가
-
-
-
-
-
- {folders.map((folder) => {
- if (!folder.subFolders) {
- return
-
-
- } else {
- return
-
- {folder.subFolders.map((subFolder: FolderType) =>
-
- )}
-
;
- }
- })}
-
-
setInputFolder(e.target.value)}
- placeholder="폴더 이름을 입력해주세요."
- className="border border-gray-400 p-4 font-bold"/>
-
- setShowFolderAddModal(false)}/>
- {
- alert("폴더가 추가되었습니다.");
- setShowFolderAddModal(false);
- }}/>
-
-
-
- );
-}
-
-export default FolderAddModal;
\ No newline at end of file
diff --git a/src/components/setting/SettingSideBar.tsx b/src/components/setting/SettingSideBar.tsx
new file mode 100644
index 0000000..fcebca3
--- /dev/null
+++ b/src/components/setting/SettingSideBar.tsx
@@ -0,0 +1,41 @@
+interface TabType {
+ section: string;
+ title: string;
+}
+
+function SettingSideBar({setSelectedSection}: {
+ setSelectedSection: (section: string) => void,
+ side?: boolean,
+}) {
+
+ const tabList: TabType[] = [
+ {section: "profile", title: "프로필"},
+ {section: "folder", title: "폴더"},
+ {section: "post", title: "게시글"},
+ ];
+
+ const handleSelectedTab = (tabSection: string) => {
+ const tab = tabList.find(tab => tab.section === tabSection);
+ if (tab) {
+ setSelectedSection(tab.section);
+ }
+ }
+
+ return (
+
+
+ {tabList.map((tab) =>
+ -
+
+
)}
+
+
+ );
+}
+
+export default SettingSideBar;
\ No newline at end of file
diff --git a/src/pages/blog/BlogPage.tsx b/src/pages/blog/BlogPage.tsx
index 113b51a..a2972f7 100644
--- a/src/pages/blog/BlogPage.tsx
+++ b/src/pages/blog/BlogPage.tsx
@@ -1,27 +1,93 @@
import BasicLayout from "../../layout/BasicLayout.tsx";
-import {useParams, useSearchParams} from "react-router-dom";
+import {useNavigate, useParams} from "react-router-dom";
import {faker} from "@faker-js/faker/locale/ko";
import PostCard from "../../components/post/PostCard.tsx";
-import TagCard from "../../components/post/TagCard.tsx";
import {useEffect, useRef, useState} from "react";
import {MdMenu, MdOutlineExitToApp} from "react-icons/md";
import PaginationButton from "../../components/common/PaginationButton.tsx";
-import TagChip from "../../components/post/TagChip.tsx";
-import {OutlineLink} from "../../components/common/OutlineButton.tsx";
-import {useSelector} from "react-redux";
-import {RootState} from "../../store.tsx";
+import {FolderType} from "../../common/types/blog.tsx";
+import BlogSideBar from "../../components/blog/BlogSideBar.tsx";
+import IconButton from "../../components/common/IconButton.tsx";
+import {PageResponse} from "../../common/types/common.tsx";
function BlogPage() {
const {username} = useParams();
- const [searchParams, setSearchParams] = useSearchParams({"folder": ""});
+ const [page, setPage] = useState(0);
+ const [pageInfo, setPageInfo] = useState
({number: 0, size: 5, totalElements: 53, totalPages: 11});
+ const folderData: FolderType[] = [
+ {
+ id: crypto.randomUUID(),
+ title: faker.lorem.words(),
+ subFolders: [
+ {
+ id: crypto.randomUUID(),
+ title: faker.lorem.words(),
+ subFolders: [
+ {
+ id: crypto.randomUUID(),
+ title: faker.lorem.words(),
+ subFolders: [],
+ },
+ ],
+ },
+ {
+ id: crypto.randomUUID(),
+ title: faker.lorem.words(),
+ subFolders: [],
+ },
+ {
+ id: crypto.randomUUID(),
+ title: faker.lorem.words(),
+ subFolders: [],
+ },
+ {
+ id: crypto.randomUUID(),
+ title: faker.lorem.words(),
+ subFolders: [],
+ },
+ ]
+ },
+ {
+ id: crypto.randomUUID(),
+ title: faker.lorem.words(),
+ subFolders: [
+ {
+ id: crypto.randomUUID(),
+ title: faker.lorem.words(),
+ subFolders: [],
+ },
+ ],
+ },
+ {
+ id: crypto.randomUUID(),
+ title: faker.lorem.words(),
+ subFolders: [
+ {
+ id: crypto.randomUUID(),
+ title: faker.lorem.words(),
+ subFolders: [],
+ },
+ {
+ id: crypto.randomUUID(),
+ title: faker.lorem.words(),
+ subFolders: [],
+ },
+ {
+ id: crypto.randomUUID(),
+ title: faker.lorem.words(),
+ subFolders: [],
+ },
+ ]
+ },
+ ];
+ const [folders, setFolders] = useState([]);
const [isOpen, setIsOpen] = useState(false);
- const [selectedFolder, setSelectedFolder] = useState(searchParams.get("folder") || "");
+ const [selectedFolder, setSelectedFolder] = useState(null);
const [selectedTagList, setSelectedTagList] = useState([]);
- const mainRef = useRef(null);
const sideBarRef = useRef(null);
const handleMenuOpen = () => {
@@ -37,22 +103,12 @@ function BlogPage() {
setSelectedTagList([...selectedTagList, selectTag]);
}
- const removeTag = (selectTag: string) => {
- setSelectedTagList(prevState => prevState.filter(tag => tag !== selectTag));
- }
-
- const removeFolder = (selectFolder: string) => {
- console.log(selectFolder);
- setSelectedFolder("");
- }
-
useEffect(() => {
- if (sideBarRef.current && mainRef.current) {
- sideBarRef.current.style.height = `${mainRef.current.offsetHeight + 220}px`;
- }
+ // todo: 내 게시글 불러오기 api
+ console.log(page, setPageInfo.toString());
+ setFolders(folderData);
}, []);
-
useEffect(() => {
document.addEventListener('mousedown', handleClickOutside);
document.title = username || "DIGLOG";
@@ -63,44 +119,36 @@ function BlogPage() {
};
}, []);
+ const navigate = useNavigate();
useEffect(() => {
- setSearchParams({
- "folder": selectedFolder
- })
+ navigate(`/blog/${username}?folder=${selectedFolder?.id || ""}`);
}, [selectedFolder]);
useEffect(() => {
if (isOpen) {
- document.body.classList.remove('overflow-x-hidden');
+ document.body.style.overflow = 'hidden';
} else {
- document.body.classList.add('overflow-x-hidden');
+ document.body.style.overflow = 'auto';
}
return () => {
- document.body.classList.remove('overflow-x-hidden');
+ document.body.style.overflow = 'auto';
};
}, [isOpen]);
return (
-
-
+
+
-
-
- 폴더 {selectedFolder !== "" && }
-
-
- 태그 {selectedTagList.map((tag) => )}
-
+
}
+ onClick={handleMenuOpen}
+ addStyle="lg:hidden"/>
-
+
{[Array.from({length: 3}).map(() => (
`}
username={username || faker.animal.cat()}
tags={[{
- id: faker.number.int().toString(),
+ id: crypto.randomUUID(),
name: faker.word.sample()
- }, {id: faker.number.int().toString(), name: faker.word.sample()}]}
+ }, {id: crypto.randomUUID(), name: faker.word.sample()}]}
createdAt={new Date()}/>
))]}
{
- }}/>
+ pageInfo={pageInfo} setPage={setPage}/>
-
@@ -136,78 +184,16 @@ function BlogPage() {
onClick={() => setIsOpen(false)}>
-
+ bgColor={"bg-gray-50"}
+ side={true}/>
);
}
-function SideBar({username, addTag, setSelectedFolder, bgColor}: {
- username: string | undefined,
- addTag: (tagName: string) => void,
- setSelectedFolder: (folder: string) => void,
- bgColor?: string
-}) {
-
- const loginState = useSelector((state: RootState) => state.loginSlice);
-
- return (
-
-
-
})
-
- {username}
-
- {username === loginState.username && (
-
-
-
-
- )}
-
-
-
폴더
-
- {[Array.from({length: 10}).map((_, i) => (
-
-
-
- {Array.from({length: 3}).map((_, i) => (
-
- ))}
-
-
- ))]}
-
-
-
-
태그
-
- {[Array.from({length: 24}).map(() => (
-
- ))]}
-
-
-
- );
-}
-
export default BlogPage;
\ No newline at end of file
diff --git a/src/pages/member/CodePage.tsx b/src/pages/member/CodePage.tsx
index b0ecab0..f64804a 100644
--- a/src/pages/member/CodePage.tsx
+++ b/src/pages/member/CodePage.tsx
@@ -14,27 +14,30 @@ function CodePage() {
const [loading, setLoading] = useState(false);
const inputRefs = useRef
([]);
- const [code, setCode] = useState(Array(6).fill(""));
+ const [code, setCode] = useState("");
const [timer, setTimer] = useState(600);
const handleChange = (index: number, value: string) => {
- if (/[^0-9]/g.test(value)) {
- return;
- }
+ let newCode = code;
+ for (const digit of value.split("")) {
+ if (/[^0-9]/g.test(digit)) {
+ return;
+ }
- const newCode = [...code];
+ newCode += digit;
+ }
- newCode[index] = value.replace(/[^0-9]/g, "");
- setCode(newCode);
+ setCode(newCode.substring(0, 6));
if (value && index < inputRefs.current.length - 1) {
- inputRefs.current[index + 1].focus();
+ inputRefs.current[index + Math.min(value.length, 5)].focus();
}
};
const handleBackspace = (event: React.KeyboardEvent, index: number) => {
- if (event.key === "Backspace" && !event.currentTarget.value && index > 0) {
+ if (event.key === "Backspace" && index > 0) {
+ setCode(code.substring(0, index - 1));
inputRefs.current[index - 1].focus();
}
};
@@ -61,14 +64,19 @@ function CodePage() {
}, [timer]);
useEffect(() => {
- if (code[5] !== "") {
+ if (code.length >= 6) {
setLoading(true);
- checkCode(email, code.join(""))
+ checkCode(email, code)
.then(() => {
- navigate("/signup", {state: {email: email, code: code.join("")}});
+ navigate("/signup", {state: {email: email, code: code}});
+ })
+ .catch((error) => {
+ alert(error.response.data.message);
+ if (inputRefs.current) {
+ inputRefs.current[5].focus();
+ }
})
- .catch((error) => alert(error.response.data.message))
.finally(() => setLoading(false));
}
}, [code]);
@@ -82,7 +90,7 @@ function CodePage() {
인증코드 6자리를 입력해주세요.
- {code.map((digit, index) => (
+ {Array.from({length: 6}).map((_, index) => (
{
@@ -90,10 +98,10 @@ function CodePage() {
inputRefs.current[index] = el;
}
}}
- type=" text"
- maxLength={1}
+ type="text"
+ maxLength={6}
className="w-12 h-16 rounded-lg font-bold text-lg appearance-none border border-gray-200 text-center focus:outline-1"
- value={digit}
+ value={code[index] ?? ""}
onChange={(e) => handleChange(index, e.target.value)}
onKeyDown={(e) => {
handleBackspace(e, index)
diff --git a/src/pages/post/PostPage.tsx b/src/pages/post/PostPage.tsx
index 42dab10..5ad2f13 100644
--- a/src/pages/post/PostPage.tsx
+++ b/src/pages/post/PostPage.tsx
@@ -8,15 +8,11 @@ import {useEffect, useState} from "react";
import {PostResponse} from "../../common/types/post.tsx";
import {checkUUID} from "../../common/util/regex.tsx";
import {sortTagByName} from "../../common/util/sort.tsx";
-import {useSelector} from "react-redux";
-import {RootState} from "../../store.tsx";
-import {FillLink} from "../../components/common/FillButton.tsx";
function PostPage() {
const {id} = useParams();
const navigate = useNavigate();
- const loginState = useSelector((state: RootState) => state.loginSlice);
const [post, setPost] = useState({
id: "",
@@ -53,8 +49,6 @@ function PostPage() {
- {(loginState.username === post.username)
- &&
}
Home
{` > `}
@@ -62,8 +56,6 @@ function PostPage() {
{` > `}
{post.title}
- {(loginState.username === post.username)
- &&
}
state.loginSlice);
const navigate = useNavigate();
- const folderRef = useRef
(null);
const path = useLocation().pathname.substring(0, location.pathname.lastIndexOf("/"));
const {id} = useParams();
@@ -43,13 +43,9 @@ function WritePage() {
});
const [showTag, setShowTag] = useState(false);
- const [folderOpen, setFolderOpen] = useState(false);
- const [selectedFolder, setSelectedFolder] = useState("폴더 선택");
+ const [targetFolder, setTargetFolder] = useState({id: crypto.randomUUID(), title: "", subFolders: []});
const [uploadCount, setUploadCount] = useState(0);
const [exitPage, setExitPage] = useState(false);
- const handleFolderOpen = () => {
- setFolderOpen(prev => !prev);
- }
const removeTag = (tag: string | null) => {
setPost({...post, tags: post.tags.filter(prevTag => prevTag !== tag)});
@@ -131,12 +127,6 @@ function WritePage() {
.catch((error) => alert(error.response.data.message));
}
- const handleClickOutside = (event: MouseEvent) => {
- if (folderRef.current && !folderRef.current.contains(event.target as Node)) {
- setFolderOpen(false);
- }
- };
-
// 뒤로가기 방지
useBlocker(() => {
return (!!post.title || !!post.content) &&
@@ -151,12 +141,10 @@ function WritePage() {
event.preventDefault();
};
- document.addEventListener('mousedown', handleClickOutside);
window.addEventListener('beforeunload', handleBeforeUnload);
return () => {
window.removeEventListener('beforeunload', handleBeforeUnload);
- document.removeEventListener('mousedown', handleClickOutside);
};
}, []);
@@ -168,7 +156,13 @@ function WritePage() {
{
id: crypto.randomUUID(),
title: faker.lorem.words(),
- subFolders: [],
+ subFolders: [
+ {
+ id: crypto.randomUUID(),
+ title: faker.lorem.words(),
+ subFolders: [],
+ },
+ ],
},
{
id: crypto.randomUUID(),
@@ -180,7 +174,13 @@ function WritePage() {
{
id: crypto.randomUUID(),
title: faker.lorem.words(),
- subFolders: [],
+ subFolders: [
+ {
+ id: crypto.randomUUID(),
+ title: faker.lorem.words(),
+ subFolders: [],
+ },
+ ],
},
{
id: crypto.randomUUID(),
@@ -245,54 +245,10 @@ function WritePage() {
-
-
-
- {folderData.map((folder) => {
- if (!folder.subFolders) {
- return
-
-
- } else {
- return
-
- {folder.subFolders.map((subFolder: FolderType) =>
-
- )}
-
;
- }
- })}
-
+
+
diff --git a/src/pages/setting/FolderSettingPage.tsx b/src/pages/setting/FolderSettingPage.tsx
index b34bb39..623b7f5 100644
--- a/src/pages/setting/FolderSettingPage.tsx
+++ b/src/pages/setting/FolderSettingPage.tsx
@@ -3,10 +3,10 @@ import {useEffect, useRef, useState} from "react";
import {FolderResponse, FolderType, toFolderRequestList, toFolderTypeList} from "../../common/types/blog.tsx";
import {FillButton} from "../../components/common/FillButton.tsx";
import ModalLayout from "../../layout/ModalLayout.tsx";
-import CategorySelectBox from "../../components/blog/CategorySelectBox.tsx";
import {DragEndEvent} from "@dnd-kit/core";
-import FolderCardList from "../../components/setting/FolderCardList.tsx";
+import FolderCardList from "../../components/folder/FolderCardList.tsx";
import {arrayMove} from "@dnd-kit/sortable";
+import FolderSelectBox from "../../components/folder/FolderSelectBox.tsx";
function FolderSettingPage() {
@@ -361,7 +361,6 @@ function FolderSettingPage() {
폴더 관리
{selectedFolder.title} 폴더를
-
([]);
+ const [page, setPage] = useState(0);
+ const [pageInfo, setPageInfo] = useState({number: 0, size: 5, totalElements: 0, totalPages: 0});
+
+ useEffect(() => {
+ // todo: 본인 게시글 api로 변경
+ getPosts({
+ sorts: ["createdAt"],
+ page: page,
+ size: pageInfo.size,
+ isDescending: true,
+ })
+ .then((res) => {
+ setPosts([...res.data.content]);
+ setPageInfo(res.data.page);
+ })
+ .catch((error) => alert(error.response.data.message));
+ }, [page]);
+
return (
-
게시글 관리
+
+
+ {posts.map((post: PostResponse) => (
+
+
+
{post.title}
+
{fullDateToKorean(post.createdAt)}
+
+
+
+
+
+ ))}
+
+
);
}
diff --git a/src/pages/setting/SettingPage.tsx b/src/pages/setting/SettingPage.tsx
index c422191..099c9a2 100644
--- a/src/pages/setting/SettingPage.tsx
+++ b/src/pages/setting/SettingPage.tsx
@@ -1,40 +1,34 @@
import BasicLayout from "../../layout/BasicLayout.tsx";
-import {useState} from "react";
+import {useEffect, useState} from "react";
import PostSettingPage from "./PostSettingPage.tsx";
import ProfileSettingPage from "./ProfileSettingPage.tsx";
import FolderSettingPage from "./FolderSettingPage.tsx";
+import {useNavigate, useParams} from "react-router-dom";
+import SettingSideBar from "../../components/setting/SettingSideBar.tsx";
function SettingPage() {
- const tabList = ["프로필", "폴더", "게시글"];
+ const {section} = useParams();
+ const navigate = useNavigate();
+ const [selectedSection, setSelectedSection] = useState(section || "profile");
- const [selectedTab, setSelectedTab] = useState("프로필");
+ useEffect(() => {
+ navigate(`/setting/${selectedSection}`);
+ }, [selectedSection]);
return (
-
-
- {tabList.map((tab) =>
- -
-
-
)}
-
-
- {(selectedTab === "프로필") &&
+
+ {(selectedSection === "profile") &&
}
- {(selectedTab === "폴더") &&
+ {(selectedSection === "folder") &&
}
- {(selectedTab === "게시글") &&
+ {(selectedSection === "post") &&
}