Skip to content

Commit aefd78d

Browse files
authored
Merge pull request Next-Room#82 from Next-Room/fix/outside-click
feat: 버튼 클릭 시 모달 노출 유무 수정
2 parents 0a9eb28 + 6b40511 commit aefd78d

File tree

7 files changed

+140
-23
lines changed

7 files changed

+140
-23
lines changed

app/admin-new/(components)/Sidebar.tsx

Lines changed: 43 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,22 @@ import Image from "next/image";
33
import classNames from "classnames";
44
import { useRouter, useSearchParams } from "next/navigation";
55

6+
import HintDialog from "@/components/common/Hint-Dialog-new/Dialog";
67
import {
78
logoProps,
89
plusDisableProps,
910
plusProps,
1011
subscribeLinkURL,
1112
} from "@/admin-new/(consts)/sidebar";
12-
import { getSelectedThemeId, getStatus } from "@/utils/localStorage";
13+
import {
14+
getSelectedThemeId,
15+
getStatus,
16+
removeAccessToken,
17+
} from "@/utils/localStorage";
1318
import { useSelectedThemeReset } from "@/components/atoms/selectedTheme.atom";
19+
import { useIsLoggedInWrite } from "@/components/atoms/account.atom";
20+
import { useDrawerState } from "@/components/atoms/drawer.atom";
21+
import useModal from "@/hooks/useModal";
1422

1523
interface Theme {
1624
id: number;
@@ -30,6 +38,10 @@ interface Props {
3038
export default function Sidebar(props: Props) {
3139
const router = useRouter();
3240
const resetSelectedTheme = useSelectedThemeReset();
41+
// const setIsLoggedIn = useIsLoggedInWrite();
42+
const [drawer, setDrawer] = useDrawerState();
43+
const { open } = useModal();
44+
3345
const status = getStatus();
3446
const searchParams = useSearchParams();
3547
const selectedThemeId = getSelectedThemeId();
@@ -40,6 +52,34 @@ export default function Sidebar(props: Props) {
4052
categories,
4153
handleClickSelected,
4254
} = props;
55+
56+
// const handleLogout = () => {
57+
// removeAccessToken();
58+
// setIsLoggedIn(false);
59+
// };
60+
61+
const navigateToNewTheme = () => {
62+
resetSelectedTheme();
63+
router.push("/admin-new");
64+
};
65+
const handleSelectTheme = (theme: Theme) => {
66+
if (drawer.isOpen && !drawer.isSameHint) {
67+
open(HintDialog, { type: "put", fn: () => handleClickSelected(theme) });
68+
} else {
69+
setDrawer({ ...drawer, isOpen: false });
70+
handleClickSelected(theme);
71+
}
72+
};
73+
74+
const handleCreateTheme = () => {
75+
if (drawer.isOpen && !drawer.isSameHint) {
76+
open(HintDialog, { type: "put", fn: navigateToNewTheme });
77+
} else {
78+
setDrawer({ ...drawer, isOpen: false });
79+
navigateToNewTheme();
80+
}
81+
};
82+
4383
return (
4484
<div className="sidebar">
4585
<div className="sidebar__top">
@@ -51,7 +91,6 @@ export default function Sidebar(props: Props) {
5191
</div>
5292
<div className="sidebar__theme-title">우리 지점 테마</div>
5393
</div>
54-
5594
<div className="sidebar__scroll">
5695
<ul className="sidebar__theme-list">
5796
{[...categories].reverse().map((theme) => (
@@ -65,7 +104,7 @@ export default function Sidebar(props: Props) {
65104
className={classNames("sidebar__theme-button", {
66105
selected: selectedThemeId === theme.id?.toString() && params,
67106
})}
68-
onClick={() => handleClickSelected(theme)}
107+
onClick={() => handleSelectTheme(theme)}
69108
>
70109
{theme.title}
71110
</button>
@@ -80,11 +119,7 @@ export default function Sidebar(props: Props) {
80119
selected: !params,
81120
}
82121
)}
83-
onClick={() => {
84-
resetSelectedTheme();
85-
86-
router.push("/admin-new");
87-
}}
122+
onClick={handleCreateTheme}
88123
>
89124
<Image {...(params ? plusDisableProps : plusProps)} />새 테마
90125
추가하기

app/admin-new/(components)/ThemeDrawer/hooks/useEditHint.ts

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import useHintUpload from "@/queries/getPreSignedUrl";
1313
import useModal from "@/hooks/useModal";
1414
import extractFilename from "@/utils/helper";
1515
import { getHintList } from "@/queries/getHintList";
16+
import { useDrawerState } from "@/components/atoms/drawer.atom";
1617

1718
import { DrawerType } from "../types/themeDrawerTypes";
1819

@@ -34,6 +35,8 @@ const useEditHint = ({
3435

3536
const drawerRef = useRef<HTMLFormElement>(null);
3637

38+
const [drawer, setDrawer] = useDrawerState();
39+
3740
useEffect(() => {
3841
setCreateHint((prev) => ({
3942
...prev,
@@ -63,9 +66,29 @@ const useEditHint = ({
6366
Boolean(!answerImages.length);
6467

6568
useEffect(() => {
66-
if (hintType === "Add") {
69+
const isSameHint =
70+
String(createHint.hintCode) === String(selectedHint.hintCode) &&
71+
Number(createHint.progress) === Number(selectedHint.progress) &&
72+
String(createHint.contents) === String(selectedHint.contents) &&
73+
String(createHint.answer) === String(selectedHint.answer) &&
74+
// 서버에 올라간 사진 삭제 여부를 비교
75+
createHint.hintImageUrlList === selectedHint.hintImageUrlList &&
76+
createHint.answerImageUrlList === selectedHint.answerImageUrlList &&
77+
// 로컬 업로드 사진 하나라도 있으면 변경된 것
78+
Boolean(!hintImages.length) &&
79+
Boolean(!answerImages.length);
80+
81+
setDrawer((prevDrawer) => ({
82+
...prevDrawer,
83+
isSameHint,
84+
}));
85+
}, [createHint, selectedHint]);
86+
87+
useEffect(() => {
88+
if (drawer.hintType === "Add") {
6789
return;
6890
}
91+
6992
if (isSameHint || isImcomplete) {
7093
setIsDisabled(true);
7194
} else {
@@ -89,8 +112,10 @@ const useEditHint = ({
89112
...prev,
90113
contents: selectedHint.contents,
91114
answer: selectedHint.answer,
115+
answerImageUrlList: selectedHint.answerImageUrlList,
116+
hintImageUrlList: selectedHint.hintImageUrlList,
92117
}));
93-
}, [hintType, selectedHint, setCreateHint]);
118+
}, [hintType, selectedHint]);
94119

95120
const { handleProcess } = useHintUpload();
96121
const handleSubmit = async (e: FormEvent) => {

app/admin-new/(components)/ThemeInfo/Container.tsx

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import "../../(style)/themeInfo.modules.sass";
66
import useModal from "@/hooks/useModal";
77
import Dialog from "@/components/common/Dialog-new/Dialog";
88
import { useSelectedHintReset } from "@/components/atoms/selectedHint.atom";
9+
import { useDrawerState } from "@/components/atoms/drawer.atom";
910

1011
import ThemeDrawer from "../ThemeDrawer/Container";
1112

@@ -17,21 +18,19 @@ export default function ThemeInfo() {
1718
const { open } = useModal();
1819
const resetSelectedHint = useSelectedHintReset();
1920

20-
const [openHintDrawer, setOpenHintDrawer] = useState(false);
21-
const [hintType, setHintType] = useState<string>("Add");
21+
const [drawer, setDrawerState] = useDrawerState();
2222

2323
const handleOpenModal = () => {
2424
open(Dialog, { type: "put" });
2525
};
2626

2727
const handleCloseDrawer = () => {
2828
resetSelectedHint();
29-
setOpenHintDrawer(false);
29+
setDrawerState({ ...drawer, isOpen: false, hintType: "" });
3030
};
3131

3232
const handleHintCreate = (type: string) => {
33-
setOpenHintDrawer(true);
34-
setHintType(type);
33+
setDrawerState({ ...drawer, isOpen: true, hintType: type });
3534
};
3635

3736
useEffect(() => {
@@ -50,17 +49,17 @@ export default function ThemeInfo() {
5049
return (
5150
<div
5251
className={classNames("theme-infomation", {
53-
"drawer-open": openHintDrawer,
52+
"drawer-open": drawer.isOpen,
5453
})}
5554
>
5655
<ThemeInfoTitle handleOpenModal={handleOpenModal} />
5756
<ThemeInfoBody handleOpenModal={handleOpenModal} />
5857
<ThemeInfoHint handleHintCreate={handleHintCreate} />
59-
{openHintDrawer && (
58+
{drawer.isOpen && (
6059
<ThemeDrawer
6160
handleHintCreate={handleHintCreate}
6261
onCloseDrawer={handleCloseDrawer}
63-
hintType={hintType}
62+
hintType={drawer.hintType}
6463
/>
6564
)}
6665
</div>

app/admin-new/(components)/ThemeInfo/ThemeInfoHint.tsx

Lines changed: 33 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import classNames from "classnames";
33

44
import { useGetHintList } from "@/queries/getHintList";
55
import { useSelectedThemeValue } from "@/components/atoms/selectedTheme.atom";
6+
import HintDialog from "@/components/common/Hint-Dialog-new/Dialog";
67
import {
78
SelectedHintType,
89
useSelectedHint,
@@ -12,6 +13,8 @@ import {
1213
useCreateHint,
1314
useCreateHintReset,
1415
} from "@/components/atoms/createHint.atom";
16+
import { useDrawerState } from "@/components/atoms/drawer.atom";
17+
import useModal from "@/hooks/useModal";
1518

1619
interface ThemeDrawerProps {
1720
handleHintCreate: (type: string) => void;
@@ -25,23 +28,48 @@ const ThemeInfoHint: React.FC<ThemeDrawerProps> = ({ handleHintCreate }) => {
2528
const [_, setCreateHint] = useCreateHint();
2629
const resetSelectedHint = useSelectedHintReset();
2730
const resetCreateHint = useCreateHintReset();
31+
const [drawer, setDrawer] = useDrawerState();
32+
const { open } = useModal();
2833

29-
const handleAddHintBtn = () => {
34+
const handleResetCreateHint = () => {
3035
resetSelectedHint();
3136
resetCreateHint();
3237
handleHintCreate("Add");
38+
setDrawer({ ...drawer, isOpen: true, hintType: "add" });
39+
};
40+
41+
const handleAddHintBtn = () => {
42+
if (drawer.isOpen && !drawer.isSameHint) {
43+
open(HintDialog, {
44+
type: "put",
45+
fn: handleResetCreateHint,
46+
});
47+
} else handleResetCreateHint();
3348
};
49+
3450
const handleEditHintBtn = (
3551
e: React.MouseEvent<HTMLLIElement, globalThis.MouseEvent>,
3652
hintElement: SelectedHintType
3753
) => {
54+
if (drawer.isOpen && !drawer.isSameHint) {
55+
open(HintDialog, {
56+
type: "put",
57+
fn: () => {
58+
setSelectedHint(hintElement);
59+
setCreateHint(hintElement);
60+
handleHintCreate("Edit");
61+
setDrawer({ ...drawer, isOpen: true, hintType: "put" });
62+
},
63+
});
64+
} else {
65+
setSelectedHint(hintElement);
66+
setCreateHint(hintElement);
67+
68+
handleHintCreate("Edit");
69+
}
3870
if (hintElement.id === selectedHint.id) {
3971
return;
4072
}
41-
42-
setCreateHint(hintElement);
43-
setSelectedHint(hintElement);
44-
handleHintCreate("Edit");
4573
};
4674

4775
return (
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import {
2+
atom,
3+
useRecoilValue,
4+
useRecoilState,
5+
useSetRecoilState,
6+
} from "recoil";
7+
8+
interface DrawerType {
9+
isOpen: boolean;
10+
hintType: string;
11+
isSameHint: boolean;
12+
}
13+
14+
const drawerState = atom<DrawerType>({
15+
key: "drawer",
16+
default: { isOpen: false, hintType: "", isSameHint: false },
17+
});
18+
19+
export const useDrawerState = () => useRecoilState(drawerState);
20+
export const useDrawerStateValue = () => useRecoilValue(drawerState);
21+
export const useDrawerStateWrite = () => useSetRecoilState(drawerState);

app/components/common/Hint-Dialog-new/Dialog.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ import DialogBody from "@/components/common/Hint-Dialog-new/DialogBody";
99
import "@/components/common/Dialog-new/dialog.sass";
1010
import { useDeleteHint } from "@/mutations/deleteHint";
1111
import { useSelectedHint } from "@/components/atoms/selectedHint.atom";
12+
import {
13+
useDrawerState,
14+
} from "@/components/atoms/drawer.atom";
1215

1316
import ModalPortal from "./ModalPortal";
1417

@@ -38,13 +41,15 @@ const Dialog = forwardRef<HTMLFormElement, DialogProps>((props) => {
3841
const [selectedHint] = useSelectedHint();
3942

4043
const { mutateAsync: deleteHint } = useDeleteHint();
44+
const [drawer, setDrawer] = useDrawerState();
4145

4246
const onSubmit: SubmitHandler<FormValues> = () => {
4347
const { id } = selectedHint;
4448

4549
if (type === "put") {
4650
fn();
4751
close();
52+
setDrawer({ ...drawer, isOpen: false });
4853
} else if (type === "delete") {
4954
deleteHint({ id });
5055
close();

app/utils/localStorage.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,3 +96,7 @@ export const getSelectedThemeId = () => getLocalStorage(THEME_ID);
9696
export const removeAccessToken = () => {
9797
removeLocalStorageItem(ACCESS_TOKEN);
9898
};
99+
100+
export const removeLocalStorageAll = () => {
101+
localStorage.clear();
102+
};

0 commit comments

Comments
 (0)