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
14 changes: 11 additions & 3 deletions src/components/blog/BlogSideBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,13 +44,17 @@ function BlogSideBar({folders, tags, username, profileUrl, selectedFolder, setSe
</div>
<div className="flex flex-col justify-center items-center gap-4 py-8">
<div className="font-bold text-lime-700 text-center">태그</div>
<div className="w-72 flex flex-wrap justify-center gap-x-2 gap-y-4 p-2">
<div className="w-72 flex flex-wrap justify-center gap-x-2 gap-y-4">
{tags.map((tag) => (
<BlogTagCard
key={tag.id}
tag={tag}
username={username || ""}/>
))}
{tags.length === 0 &&
<div className="text-center text-gray-600">
생성된 태그가 없습니다.
</div>}
</div>
</div>
</div>
Expand Down Expand Up @@ -78,7 +82,7 @@ function BlogFolderList({depth = 0, folders, selectedFolder, setSelectedFolder}:

return (
<div className="w-full flex flex-col gap-y-1">
{folders.map(folder =>
{folders.length > 1 && folders.map(folder =>
<div key={folder.id} className={`flex flex-col gap-y-2`}>
{depth === 0 && <div className="h-2"/>}
<button
Expand All @@ -92,13 +96,17 @@ function BlogFolderList({depth = 0, folders, selectedFolder, setSelectedFolder}:
{getFolderTitle(folder.title, depth)}
{folder.id !== "" && <p className="text-xs font-light">({getPostCount(folder)})</p>}
</button>
{depth === 0 && <hr className="text-gray-400"/>}
{folder.subFolders.length > 0 && depth === 0 && <hr className="text-gray-400"/>}
<BlogFolderList
depth={depth + 1}
folders={folder.subFolders}
selectedFolder={selectedFolder}
setSelectedFolder={setSelectedFolder}/>
</div>)}
{depth === 0 && folders.length <= 1 &&
<div className="text-center text-gray-600">
생성된 폴더가 없습니다.
</div>}
</div>
);
}
Expand Down
2 changes: 1 addition & 1 deletion src/components/common/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ function Header() {
</div>
: <div className="flex justify-center items-center mr-4">
<TextLink text={"로그인"} to={"/login"} addStyle={"hover:text-lime-700"}/>
<TextLink text={"회원가입"} to={"/signup/platform"} addStyle={"hover:text-lime-700"}/>
<TextLink text={"회원가입"} to={"/signup/platform"} addStyle={"hover:text-lime-700 hidden sm:block"}/>
</div>}
</div>
</div>
Expand Down
26 changes: 25 additions & 1 deletion src/components/folder/FolderCardList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import {FillButton} from "../common/FillButton.tsx";
import {MdOutlineMenu} from "react-icons/md";
import {TextButton} from "../common/TextButton.tsx";
import {restrictToVerticalAxis} from "@dnd-kit/modifiers";
import {useEffect, useRef} from "react";
import * as React from "react";

function FolderCardList({
folders,
Expand Down Expand Up @@ -87,13 +89,33 @@ function FolderCard({
setSelectedFolder: (selectedFolder: FolderType) => void,
}) {

const folderTitleRef = useRef<HTMLInputElement>(null);

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

const style = {
transform: CSS.Translate.toString(transform),
transition,
};

useEffect(() => {
if (folder.id === editFolderId) {
folderTitleRef.current?.focus();
}
}, [editFolderId]);

const handleEditTitleEnter = (event: React.KeyboardEvent<HTMLInputElement>) => {
if (event.key !== "Enter") {
return;
}

handleEditTitle();
}

const handleEditTitle = () => {
handleEdit({...folder, title: editFolderTitle});
}

return (
<div key={folder.id} ref={setNodeRef} style={style}
className="flex flex-col justify-start items-center">
Expand All @@ -105,13 +127,15 @@ function FolderCard({
className={"flex-1 font-bold border p-2"}
value={editFolderTitle}
onChange={(e) => setEditFolderTitle(e.target.value)}
onKeyDown={handleEditTitleEnter}
ref={folderTitleRef}
placeholder="폴더 이름"/>
<div className="flex items-center gap-x-2">
<FillButton text={"취소"}
onClick={() => setEditFolderId("")}
addStyle={"!bg-gray-400 hover:brightness-110"}/>
<FillButton text={"수정"}
onClick={() => handleEdit({...folder, title: editFolderTitle})}
onClick={handleEditTitle}
addStyle={`${folder.title === editFolderTitle && "opacity-50 hover:!cursor-auto"}`}
disabled={folder.title === editFolderTitle}/>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/components/folder/FolderSelectBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ function FolderSelectCard({folder, depth, selectedFolder, setTargetFolder, setFo
<div className={`flex items-center gap-x-1 ${depth === 0 && "font-bold text-black"}`}>
<div className={`w-${depth * 4}`}/>
{getFolderTitle(folder.title, depth)}
<p className="text-xs font-light">({folder.postCount})</p>
{folder.id !== "empty" && <p className="text-xs font-light">({folder.postCount})</p>}
</div>
</button>
{folder.subFolders &&
Expand Down
8 changes: 6 additions & 2 deletions src/components/member/LoginTextField.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import * as React from "react";
import {Ref} from "react";

function LoginTextField({label, type, placeholder, value, setValue, error, isError, onKeyDown}: {
function LoginTextField({label, type, placeholder, value, setValue, customRef, error, isError, onKeyDown}: {
label?: string,
type: string,
placeholder: string,
value: string,
setValue: (value: string) => void,
customRef?: Ref<HTMLInputElement>,
error?: string,
isError?: boolean,
onKeyDown?: (event: React.KeyboardEvent<HTMLInputElement>) => void,
Expand All @@ -20,7 +22,9 @@ function LoginTextField({label, type, placeholder, value, setValue, error, isErr
className="bg-gray-50 border border-gray-300 text-gray-900 text-md rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5"
value={value}
onChange={(event => setValue(event.target.value))}
onKeyDown={onKeyDown}/>
onKeyDown={onKeyDown}
ref={customRef}
autoComplete={"on"}/>
{(error) && (
isError ?
<p className="h-4 mt-2 text-sm text-red-600">{error}</p>
Expand Down
13 changes: 6 additions & 7 deletions src/components/post/PostCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import DOMPurify from "dompurify";
import {MdImage} from "react-icons/md";
import {dateToKorean} from "../../common/util/date.tsx";
import {Link} from "react-router-dom";
import {FaRegHeart} from "react-icons/fa6";

function PostCard({post}: { post: PostResponse }) {

Expand Down Expand Up @@ -33,12 +32,12 @@ function PostCard({post}: { post: PostResponse }) {
{dateToKorean(post.createdAt)}
</div>
</div>
<div className="flex justify-end items-center gap-x-3 text-sm text-gray-400">
<div className="flex items-center gap-x-1.5">
<FaRegHeart className="size-3"/>
<p className="text-gray-900">20</p>
</div>
</div>
{/*<div className="flex justify-end items-center gap-x-3 text-sm text-gray-400">*/}
{/* <div className="flex items-center gap-x-1.5">*/}
{/* <FaRegHeart className="size-3"/>*/}
{/* <p className="text-gray-900">20</p>*/}
{/* </div>*/}
{/*</div>*/}
</div>
<Link to={`/post/${post.id}`}>
<div className="line-clamp-2 text-lg hover:text-gray-600 font-medium">
Expand Down
2 changes: 1 addition & 1 deletion src/pages/MainPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ function MainPage() {
<BasicLayout>
<div className="w-full flex flex-col justify-center items-start">
<div className="text-2xl font-jalnan mb-8">
인기 있는 게시글
최근 게시글
</div>
<div ref={pageRef}
className="w-full grid sm:grid-cols-1 md:grid-cols-2 lg:grid-cols-3 2xl:grid-cols-4 gap-8">
Expand Down
9 changes: 8 additions & 1 deletion src/pages/member/EmailPage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import BasicLayout from "../../layout/BasicLayout.tsx";
import LoginTextField from "../../components/member/LoginTextField.tsx";
import {useState} from "react";
import {useEffect, useRef, useState} from "react";
import LoginButton from "../../components/member/LoginButton.tsx";
import {useNavigate} from "react-router-dom";
import * as React from "react";
Expand All @@ -15,6 +15,8 @@ function EmailPage() {

const navigate = useNavigate();

const emailRef = useRef<HTMLInputElement>(null);

const handleEmailEnter = (event: React.KeyboardEvent<HTMLInputElement>) => {
if (event.key !== "Enter") {
return;
Expand All @@ -38,6 +40,10 @@ function EmailPage() {
.finally(() => setLoading(false));
}

useEffect(() => {
emailRef.current?.focus();
}, []);

return (
<BasicLayout center={true}>
<div
Expand All @@ -48,6 +54,7 @@ function EmailPage() {
placeholder={"diglog@example.com"}
value={email}
setValue={(value) => setEmail(value)}
customRef={emailRef}
onKeyDown={handleEmailEnter}/>
<LoginButton text={"인증코드 전송"} onClick={handleVerifyEmail} disable={!checkEmail(email)} bgColor={"bg-lime-400"}/>
</div>
Expand Down
30 changes: 24 additions & 6 deletions src/pages/member/LoginPage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import BasicLayout from "../../layout/BasicLayout.tsx";
import {useNavigate} from "react-router-dom";
import {useState} from "react";
import {useEffect, useRef, useState} from "react";
import {useDispatch, useSelector} from "react-redux";
import {getProfile, handleKakaoLogin, loginApi} from "../../common/apis/member.tsx";
import {login, setProfile} from "../../common/slices/loginSlice.tsx";
Expand All @@ -18,6 +18,9 @@ function LoginPage() {
const navigate = useNavigate();
const dispatch = useDispatch();

const emailRef = useRef<HTMLInputElement>(null);
const passwordRef = useRef<HTMLInputElement>(null);

const [loginInfo, setLoginInfo] = useState({email: "", password: ""});

const handleLogin = () => {
Expand Down Expand Up @@ -45,6 +48,14 @@ function LoginPage() {
.catch(error => alert(error.response.data.message));
}

const handleEmailEnter = (event: React.KeyboardEvent<HTMLInputElement>) => {
if (event.key !== "Enter") {
return;
}

passwordRef.current?.focus();
}

const handlePasswordEnter = (event: React.KeyboardEvent<HTMLInputElement>) => {
if (event.key !== "Enter") {
return;
Expand All @@ -57,6 +68,10 @@ function LoginPage() {
handleLogin();
}

useEffect(() => {
emailRef.current?.focus();
}, []);

return (
<BasicLayout center={true}>
<div
Expand All @@ -68,21 +83,24 @@ function LoginPage() {
DIGLOG
</div>
</div>
<div className="flex flex-col justify-center items-center w-full">
<form onSubmit={e => e.preventDefault()} className="flex flex-col justify-center items-center w-full">
<LoginTextField
label={"이메일"}
type={"email"}
placeholder={"diglog@example.com"}
placeholder={"이메일을 입력해주세요."}
value={loginInfo.email}
setValue={(value) => setLoginInfo({...loginInfo, email: value})}/>
setValue={(value) => setLoginInfo({...loginInfo, email: value})}
customRef={emailRef}
onKeyDown={handleEmailEnter}/>
<LoginTextField
label={"비밀번호"}
type={"password"}
placeholder={"영문, 숫자 포함 8-16자"}
placeholder={"비밀번호를 입력해주세요."}
value={loginInfo.password}
setValue={(value) => setLoginInfo({...loginInfo, password: value})}
customRef={passwordRef}
onKeyDown={handlePasswordEnter}/>
</div>
</form>
<div className="flex flex-col justify-center items-center gap-y-4 w-full">
<LoginButton text={"로그인"} onClick={handleLogin} bgColor={"bg-lime-300"}/>
<LoginButton text={"카카오로 시작하기"} onClick={handleKakaoLogin} bgColor={"bg-[#FEE500]"}
Expand Down
28 changes: 23 additions & 5 deletions src/pages/member/SignupPage.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import BasicLayout from "../../layout/BasicLayout.tsx";
import {useLocation, useNavigate} from "react-router-dom";
import {useState} from "react";
import {useEffect, useRef, useState} from "react";
import LoginTextField from "../../components/member/LoginTextField.tsx";
import {checkPassword} from "../../common/util/regex.tsx";
import LoadingLayout from "../../layout/LoadingLayout.tsx";
Expand All @@ -17,11 +17,22 @@ function SignupPage() {
const [loading, setLoading] = useState(false);
const [passwordInfo, setPasswordInfo] = useState({password: "", confirmPassword: ""});

const passwordRef = useRef<HTMLInputElement>(null);
const confirmPasswordRef = useRef<HTMLInputElement>(null);

const handlePasswordEnter = (event: React.KeyboardEvent<HTMLInputElement>) => {
if (event.key !== "Enter") {
return;
}

confirmPasswordRef.current?.focus();
}

const handleConfirmPasswordEnter = (event: React.KeyboardEvent<HTMLInputElement>) => {
if (event.key !== "Enter") {
return;
}

handleSignup();
}

Expand Down Expand Up @@ -51,26 +62,33 @@ function SignupPage() {
return !checkPassword(passwordInfo.password) || (passwordInfo.password !== passwordInfo.confirmPassword);
}

useEffect(() => {
passwordRef.current?.focus();
}, []);

return (
<BasicLayout center={true}>
<div
className="w-full max-w-[calc(420px)] flex flex-col justify-center items-center gap-y-4">
<p className="mb-4">비밀번호 설정을 마치면 회원가입이 완료됩니다.</p>
<div className="w-full">
<form onSubmit={e => e.preventDefault()} className="w-full">
<LoginTextField
label={"비밀번호"}
type={"password"}
placeholder={"영문, 숫자 포함 8-16자"}
value={passwordInfo.password}
setValue={(value) => setPasswordInfo({...passwordInfo, password: value})}/>
setValue={(value) => setPasswordInfo({...passwordInfo, password: value})}
customRef={passwordRef}
onKeyDown={handlePasswordEnter}/>
<LoginTextField
label={"비밀번호 확인"}
type={"password"}
placeholder={"영문, 숫자 포함 8-16자"}
value={passwordInfo.confirmPassword}
setValue={(value) => setPasswordInfo({...passwordInfo, confirmPassword: value})}
onKeyDown={handlePasswordEnter}/>
</div>
customRef={confirmPasswordRef}
onKeyDown={handleConfirmPasswordEnter}/>
</form>
<LoginButton text={"회원가입"} onClick={handleSignup} disable={disableSignupButton()} bgColor={"bg-lime-400"}/>
</div>
<LoadingLayout loading={loading}/>
Expand Down
8 changes: 4 additions & 4 deletions src/pages/post/PostPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,7 @@ function PostPage() {
<div className="w-full flex flex-col">
<div className="flex flex-col gap-y-8">
<div className="flex justify-between items-center">
<div className="flex-1 flex justify-center items-center gap-x-4">
<div className="flex-1 flex flex-wrap justify-center items-center gap-x-4">
<Link to={`/blog/${post.username}`} className="text-xs">
Home
</Link>
Expand All @@ -192,7 +192,7 @@ function PostPage() {
</div>}
</div>
</div>
<div className="flex flex-row w-full justify-center text-center items-center gap-4">
<div className="flex flex-row flex-wrap w-full justify-center text-center items-center gap-4">
<Link to={`/blog/${post.username}`}
className="text-md font-semibold text-lime-700 hover:text-lime-400">
{post.username}
Expand All @@ -211,9 +211,9 @@ function PostPage() {
}}/>)}
</div>
</div>
<div className="w-4xl mx-auto p-8 break-words"
<div className="max-w-4xl mx-auto py-8 break-words"
dangerouslySetInnerHTML={{__html: safeContent}}/>
<div className="w-full max-w-4xl mx-auto p-8 rounded-2xl flex flex-col gap-y-0 my-8">
<div className="w-full max-w-4xl mx-auto py-8 rounded-2xl flex flex-col gap-y-0 my-8">
{loginState.isLogin
? <CommentTextField
value={commentInput}
Expand Down
Loading