Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions src/common/apis/post.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,9 @@ export const getPost = async (id: string) =>

export const getPosts = async (postListRequest: PostListRequest) =>
await axiosApi.get(`/post${postListRequestToParameter(postListRequest)}`);

export interface FolderRequest {
id: string;
name: string;
subFolders: FolderRequest[];
}
74 changes: 74 additions & 0 deletions src/common/types/blog.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
export interface FolderRequest {
id: string | null,
title: string,
depth: number,
orderIndex: number,
parentOrderIndex: number,
}

export interface FolderType {
id: string,
title: string,
subFolders: FolderType[],
}

export interface FolderResponse {
folderId: string,
title: string,
depth: number,
orderIndex: number,
parentFolderId: string | null,
}

export const toFolderTypeList = (folderResponseList: FolderResponse[]) => {
const result: FolderType[] = [];

folderResponseList.sort((a, b) => a.orderIndex - b.orderIndex)
.forEach(folderResponse => {
const folderType = toFolderType(folderResponse);

if (folderResponse.depth === 0) {
result.push(folderType);
} else if (folderResponse.depth === 1) {
result[result.length - 1].subFolders.push(folderType);
} else if (folderResponse.depth === 2) {
const subFoldersLength = result[result.length - 1].subFolders.length;
result[result.length - 1].subFolders[subFoldersLength - 1].subFolders.push(folderType);
}
});

return result;
}

const toFolderType = (folderResponse: FolderResponse) => {
return {
id: folderResponse.folderId,
title: folderResponse.title,
subFolders: [],
};
}

export const toFolderRequestList = (folderTypeList: FolderType[]) => {
const result: FolderRequest[] = [];

const getFolderRequestList = (folderTypeList: FolderType[], depth: number = 0, parentIndex: number = -1) => {
folderTypeList.forEach(folder => {
const id = (!folder.id.startsWith("temp") ? folder.id : null);
result.push({
id: id,
title: folder.title,
depth: depth,
orderIndex: result.length,
parentOrderIndex: parentIndex,
});

if (folder.subFolders.length > 0) {
getFolderRequestList(folder.subFolders, depth + 1, result.length - 1);
}
});
}

getFolderRequestList(folderTypeList);

return result;
}
87 changes: 87 additions & 0 deletions src/components/blog/CategorySelectBox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import {FolderType} from "../../common/types/blog.tsx";
import {MdOutlineArrowDropDown} from "react-icons/md";
import {useEffect, useRef, useState} from "react";

function CategorySelectBox({folders, depth, selectedFolder, targetFolder, setTargetFolder, center}: {
folders: FolderType[],
depth: number,
selectedFolder: FolderType,
targetFolder: FolderType,
setTargetFolder: (folder: FolderType) => void,
center?: boolean,
}) {

const [folderOpen, setFolderOpen] = useState(false);
const handleFolderOpen = () => {
setFolderOpen(prev => !prev);
}

const folderRef = useRef<HTMLDivElement | null>(null);
const handleClickOutside = (event: MouseEvent) => {
if (folderRef.current && !folderRef.current.contains(event.target as Node)) {
setFolderOpen(false);
}
};
useEffect(() => {
document.addEventListener('mousedown', handleClickOutside);
return () => {
document.removeEventListener('mousedown', handleClickOutside);
};
}, []);

return (
<div ref={folderRef}
className={`w-full relative flex ${center ? "justify-center" : "justify-start"} text-gray-700 items-center my-2 text-sm font-normal`}>
<button
className="w-full flex justify-between items-center gap-x-2 px-4 py-2 border border-gray-200 hover:bg-gray-50 hover:cursor-pointer"
onClick={handleFolderOpen}>
{targetFolder.title}
<MdOutlineArrowDropDown/>
</button>
<div
className={`${folderOpen ? "" : "hidden"} absolute z-50 w-full top-12 left-0 bg-white divide-y divide-gray-300 rounded-lg shadow-sm`}>
{folders.map((folder) =>
<CategorySelectCard
key={folder.id}
folder={folder}
depth={depth}
selectedFolder={selectedFolder}
setTargetFolder={setTargetFolder}
setFolderOpen={setFolderOpen}/>
)}
</div>
</div>
);
}

function CategorySelectCard({folder, depth, selectedFolder, setTargetFolder, setFolderOpen}: {
folder: FolderType,
depth: number,
selectedFolder: FolderType,
setTargetFolder: (folder: FolderType) => void,
setFolderOpen: (open: boolean) => void,
}) {
return folder.id !== selectedFolder.id ? (
<div key={folder.title} className={`text-sm`}>
<button
className={`px-4 py-2 text-gray-700 w-full text-start hover:bg-gray-100 hover:cursor-pointer`}
onClick={() => {
setTargetFolder(folder);
setFolderOpen(false);
}}>
<p className={`ml-${depth * 4}`}>{folder.title}</p>
</button>
{folder.subFolders.length > 0 &&
folder.subFolders.map((subFolder =>
<CategorySelectCard
key={subFolder.id}
folder={subFolder}
selectedFolder={selectedFolder}
depth={depth + 1}
setTargetFolder={setTargetFolder}
setFolderOpen={setFolderOpen}/>))}
</div>
) : <></>;
}

export default CategorySelectBox;
20 changes: 10 additions & 10 deletions src/components/setting/FolderAddModal.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import ModalLayout from "../../layout/ModalLayout.tsx";
import {useState} from "react";
import {FillButton} from "../common/FillButton.tsx";
import {FolderType} from "../../pages/setting/SettingPage.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[],
Expand Down Expand Up @@ -38,36 +38,36 @@ function FolderAddModal({folders, setShowFolderAddModal}: {
</div>
{folders.map((folder) => {
if (!folder.subFolders) {
return <div key={folder.name} className="py-2 w-auto text-sm">
return <div key={folder.title} className="py-2 w-auto text-sm">
<button
className="px-4 py-2 text-gray-700 text-start hover:bg-gray-100 w-full hover:cursor-pointer"
onClick={() => {
setSelectedFolder(folder.name);
setSelectedFolder(folder.title);
setFolderOpen(false);
}}>
{folder.name}
{folder.title}
</button>
</div>
} else {
return <div key={folder.name}
return <div key={folder.title}
className="flex flex-col items-start py-2 w-auto text-sm">
<button
className="px-4 py-2 text-gray-700 text-start border-gray-200 hover:bg-gray-100 w-full hover:cursor-pointer"
onClick={() => {
setSelectedFolder(folder.name);
setSelectedFolder(folder.title);
setFolderOpen(false);
}}>
{folder.name}
{folder.title}
</button>
{folder.subFolders.map((subFolder: FolderType) =>
<button
key={subFolder.name}
key={subFolder.title}
className="px-4 py-2 text-gray-700 text-start hover:bg-gray-100 w-full hover:cursor-pointer"
onClick={() => {
setSelectedFolder(`${folder.name} > ${subFolder.name}`);
setSelectedFolder(`${folder.title} > ${subFolder.title}`);
setFolderOpen(false);
}}>
{`${folder.name} > ${subFolder.name}`}
{`${folder.title} > ${subFolder.title}`}
</button>
)}
</div>;
Expand Down
102 changes: 0 additions & 102 deletions src/components/setting/FolderCard.tsx

This file was deleted.

Loading