Skip to content

Commit 8455e92

Browse files
authored
Merge pull request depromeet#763 from depromeet/762-데스크탑-커스텀-템플릿-제목-변경
[데스크탑] 커스텀 템플릿 제목 변경 기능 추가
2 parents a2ae3f6 + 6bd4162 commit 8455e92

10 files changed

Lines changed: 101 additions & 33 deletions

File tree

apps/web/package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
"jotai": "^2.8.4",
4040
"jotai-devtools": "^0.10.0",
4141
"js-cookie": "^3.0.5",
42+
"lodash-es": "^4.17.22",
4243
"lottie-react": "^2.4.0",
4344
"mixpanel-browser": "^2.55.1",
4445
"prettier": "^3.2.5",
@@ -65,6 +66,7 @@
6566
"@tanstack/eslint-plugin-query": "^5.49.1",
6667
"@types/date-fns": "^2.6.0",
6768
"@types/js-cookie": "^3.0.6",
69+
"@types/lodash-es": "^4.17.12",
6870
"@types/node": "^20.12.12",
6971
"@types/react": "^18.2.66",
7072
"@types/react-beforeunload": "^2.1.5",

apps/web/src/app/desktop/component/retrospect/template/list/CustomTemplateListDetailItem/index.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,13 @@ import { useSetAtom } from "jotai";
55
import { retrospectInitialState } from "@/store/retrospect/retrospectInitial";
66
import { TemplateQuestion } from "../TemplateListDetailItem/TemplateQuestion";
77
import { RetrospectCreate } from "@/app/desktop/component/retrospectCreate";
8+
import { useSearchParams } from "react-router-dom";
89

910
function CustomTemplateListDetailItem({ templateId }: { templateId: number }) {
1011
const { data } = useGetCustomTemplate(templateId);
12+
const [searchParams, _] = useSearchParams();
13+
const templateMode = searchParams.get("template_mode");
14+
1115
const transformedData = {
1216
...data,
1317
questions: data.questions.map((q, index) => ({
@@ -37,9 +41,11 @@ function CustomTemplateListDetailItem({ templateId }: { templateId: number }) {
3741
<>
3842
<TemplateQuestion templateId={templateId} templateDetailQuestionList={transformedData.questions} />
3943

40-
<ButtonProvider sort={"horizontal"}>
41-
<ButtonProvider.Primary onClick={handleSelectTemplate}>선택하기</ButtonProvider.Primary>
42-
</ButtonProvider>
44+
{templateMode !== "readonly" && (
45+
<ButtonProvider sort={"horizontal"}>
46+
<ButtonProvider.Primary onClick={handleSelectTemplate}>선택하기</ButtonProvider.Primary>
47+
</ButtonProvider>
48+
)}
4349
</>
4450
);
4551
}

apps/web/src/app/desktop/component/retrospect/template/list/TemplateListConform.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import { Spacing } from "@/component/common/Spacing";
44
import { useGetSimpleTemplateInfo } from "@/hooks/api/template/useGetSimpleTemplateInfo";
55
import { retrospectInitialState } from "@/store/retrospect/retrospectInitial";
66
import { css } from "@emotion/react";
7-
import { useAtomValue, useSetAtom } from "jotai";
7+
import { useAtom, useSetAtom } from "jotai";
88
import { Tooltip } from "@/component/common/tip";
99
import { ButtonProvider } from "@/component/common/button";
1010
import { useFunnelModal } from "@/hooks/useFunnelModal";
@@ -15,11 +15,10 @@ import { RetrospectCreate } from "@/app/desktop/component/retrospectCreate";
1515
import { retrospectCreateAtom } from "@/store/retrospect/retrospectCreate";
1616

1717
export function TemplateListConform() {
18-
const setRetrospectValue = useSetAtom(retrospectInitialState);
19-
const { tempTemplateId } = useAtomValue(retrospectInitialState);
18+
const [retrospectValue, setRetrospectValue] = useAtom(retrospectInitialState);
2019
const setRetroCreateData = useSetAtom(retrospectCreateAtom);
2120

22-
const { data: templateData, isLoading } = useGetSimpleTemplateInfo(tempTemplateId);
21+
const { data: templateData, isLoading } = useGetSimpleTemplateInfo(retrospectValue.tempTemplateId);
2322
const { openFunnelModal } = useFunnelModal();
2423
const { openActionModal } = useActionModal();
2524

apps/web/src/app/desktop/component/retrospectCreate/QuestionEditSection/AddQuestionView.tsx

Lines changed: 0 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,6 @@ import { useCheckBox } from "@/hooks/useCheckBox";
1212
import { QuestionItemCheckbox } from "@/component/retrospectCreate";
1313
import { useToast } from "@/hooks/useToast";
1414
import { DESIGN_TOKEN_COLOR } from "@/style/designTokens";
15-
import { useSetAtom } from "jotai";
16-
import { retrospectCreateAtom } from "@/store/retrospect/retrospectCreate";
1715

1816
type AddQuestionViewProps = {
1917
onAddQuestion: (content: string) => void;
@@ -27,28 +25,17 @@ export default function AddQuestionView({ onAddQuestion, onAddMultipleQuestions,
2725
const { value: customQuestion, handleInputChange: handleCustomChange, resetInput } = useInput();
2826
const { tabs: categoryTabs, curTab: curCategoryTab, selectTab: selectCategoryTab } = useTabs(QUESTION_TYPES);
2927
const { selectedValues, isChecked, toggle } = useCheckBox();
30-
const setRetroCreateData = useSetAtom(retrospectCreateAtom);
31-
32-
const updateRetrospectData = () => {
33-
setRetroCreateData((prev) => ({
34-
...prev,
35-
isNewForm: true,
36-
formName: `커스텀 템플릿`,
37-
}));
38-
};
3928

4029
const handleDirectAdd = () => {
4130
if (customQuestion.trim()) {
4231
onAddQuestion(customQuestion);
4332
resetInput();
44-
updateRetrospectData();
4533
}
4634
};
4735

4836
const handleRecommendedAdd = () => {
4937
if (selectedValues.length > 0) {
5038
onAddMultipleQuestions(selectedValues);
51-
updateRetrospectData();
5239
}
5340
};
5441

apps/web/src/app/desktop/component/retrospectCreate/QuestionEditSection/MainQuestionsContents.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export default function MainQuestionsContents({ questions, isDeleteMode, handleD
2929
*/
3030
const handleContentChange = (index: number, newContent: string) => {
3131
const updatedQuestions = questions.map((item, i) => (i === index ? { ...item, questionContent: newContent } : item));
32-
setRetroCreateData((prev) => ({ ...prev, questions: updatedQuestions, isNewForm: true, formName: `커스텀 템플릿` }));
32+
setRetroCreateData((prev) => ({ ...prev, questions: updatedQuestions, isNewForm: true }));
3333
};
3434

3535
/**

apps/web/src/app/desktop/component/retrospectCreate/QuestionEditSection/index.tsx

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ import MainQuestionsHeader from "./MainQuestionsHeader";
1717
import MainQuestionsContents from "./MainQuestionsContents";
1818
import AddQuestionView from "./AddQuestionView";
1919
import { useModal } from "@/hooks/useModal";
20+
import { isEqual } from "lodash-es";
2021

2122
type QuestionEditSectionProps = {
2223
onClose: () => void;
@@ -86,6 +87,7 @@ export default function QuestionEditSection({ onClose }: QuestionEditSectionProp
8687
} else {
8788
setRetrospectQuestions(updatedQuestions);
8889
}
90+
8991
toast.success("삭제가 완료되었어요!");
9092
};
9193

@@ -117,7 +119,7 @@ export default function QuestionEditSection({ onClose }: QuestionEditSectionProp
117119
const handleAddQuestionComplete = (content: string) => {
118120
const newQuestions = [...questions, { questionType: "plain_text" as const, questionContent: content }];
119121
if (isInitializedCreateSpace) {
120-
setRetroCreateData((prev) => ({ ...prev, questions: newQuestions, hasChangedOriginal: true, isNewForm: true, formName: `커스텀 템플릿` }));
122+
setRetroCreateData((prev) => ({ ...prev, questions: newQuestions }));
121123
} else {
122124
setRetrospectQuestions(newQuestions);
123125
}
@@ -228,6 +230,21 @@ export default function QuestionEditSection({ onClose }: QuestionEditSectionProp
228230
setBackupQuestions([]);
229231
};
230232

233+
// 제출 완료 핸들러
234+
const handleComplete = () => {
235+
const hasChanged = !isEqual(backupQuestions, questions);
236+
237+
if (hasChanged || retroCreateData.hasChangedOriginal) {
238+
setRetroCreateData((prev) => ({
239+
...prev,
240+
hasChangedOriginal: true,
241+
isNewForm: true,
242+
}));
243+
}
244+
245+
onClose();
246+
};
247+
231248
return (
232249
<>
233250
{isAddMode ? (
@@ -293,7 +310,7 @@ export default function QuestionEditSection({ onClose }: QuestionEditSectionProp
293310
padding-top: 0.8rem;
294311
`}
295312
>
296-
<Button colorSchema={"primary"} onClick={onClose} isProgress={false}>
313+
<Button colorSchema={"primary"} onClick={handleComplete} isProgress={false}>
297314
완료
298315
</Button>
299316
</ButtonProvider>

apps/web/src/app/desktop/component/retrospectCreate/index.tsx

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,11 @@ export function RetrospectCreate() {
6464
closeFunnelModal();
6565
toast.success("회고가 생성되었어요!");
6666

67-
setRetrospectValue({
68-
spaceId: "",
69-
templateId: "",
67+
setRetrospectValue((prev) => ({
68+
...prev,
7069
tempTemplateId: "",
7170
saveTemplateId: false,
72-
});
71+
}));
7372
},
7473
},
7574
);

apps/web/src/app/desktop/component/retrospectCreate/steps/ConfirmDefaultTemplate.tsx

Lines changed: 44 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import { Tag } from "@/component/common/tag";
77
import { Spacing } from "@/component/common/Spacing";
88
import { ButtonProvider } from "@/component/common/button";
99
import QuestionEditButton from "@/app/desktop/component/retrospectCreate/QuestionEditButton";
10-
import { useContext, useEffect, useRef } from "react";
10+
import { useContext, useEffect, useRef, useState } from "react";
1111

1212
import { useAtom, useAtomValue } from "jotai";
1313
import { retrospectCreateAtom } from "@/store/retrospect/retrospectCreate";
@@ -16,23 +16,33 @@ import { TemplateChoice } from "@/app/desktop/component/retrospect/choice";
1616
import { retrospectInitialState } from "@/store/retrospect/retrospectInitial";
1717
import { RetrospectCreateContext } from "..";
1818
import { Tooltip } from "@/component/common/tip";
19+
import { useToast } from "@/hooks/useToast";
1920

2021
export function ConfirmDefaultTemplate() {
2122
const { templateId, saveTemplateId } = useAtomValue(retrospectInitialState);
2223
const { goNext } = useContext(RetrospectCreateContext);
2324
const [retroCreateData, setRetroCreateData] = useAtom(retrospectCreateAtom);
2425
const { openActionModal } = useActionModal();
26+
const { toast } = useToast();
27+
const [customTemplateTitle, setCustomTemplateTitle] = useState("");
2528

2629
const titleRef = useRef<HTMLDivElement>(null);
2730

2831
const {
2932
data: { title, tag, questions },
3033
} = useGetCustomTemplate(Number(templateId));
3134

32-
// 질문이 수정되었는지 여부에 따라 보여줄 텍스트 결정
33-
const displayTitle = retroCreateData.hasChangedOriginal ? "커스텀 템플릿" : title;
35+
const displayTitle = retroCreateData.hasChangedOriginal ? retroCreateData.formName || customTemplateTitle || "커스텀 템플릿" : title;
3436
const displayTag = retroCreateData.hasChangedOriginal ? "CUSTOM" : tag;
3537

38+
useEffect(() => {
39+
if (retroCreateData.hasChangedOriginal && retroCreateData.formName) {
40+
setCustomTemplateTitle(retroCreateData.formName);
41+
} else {
42+
setCustomTemplateTitle(title);
43+
}
44+
}, [title, retroCreateData.hasChangedOriginal, retroCreateData.formName]);
45+
3646
useEffect(() => {
3747
setRetroCreateData((prev) => ({
3848
...prev,
@@ -48,6 +58,14 @@ export function ConfirmDefaultTemplate() {
4858
});
4959
};
5060

61+
const handleTitleChange = (newTitle: string) => {
62+
setCustomTemplateTitle(newTitle);
63+
setRetroCreateData((prev) => ({
64+
...prev,
65+
formName: newTitle,
66+
}));
67+
};
68+
5169
return (
5270
<>
5371
<Header
@@ -79,7 +97,29 @@ export function ConfirmDefaultTemplate() {
7997
padding-top: 0.2rem;
8098
`}
8199
>
82-
<Typography variant={"S1"}>{displayTitle}</Typography>
100+
{!retroCreateData.hasChangedOriginal ? (
101+
<Typography variant={"S1"}>{displayTitle}</Typography>
102+
) : (
103+
<input
104+
type="text"
105+
value={customTemplateTitle}
106+
onChange={(e) => {
107+
handleTitleChange(e.target.value);
108+
}}
109+
css={css`
110+
font-size: 2rem;
111+
font-weight: bold;
112+
width: 100%;
113+
margin-right: 1rem;
114+
`}
115+
onBlur={() => {
116+
if (displayTitle !== retroCreateData.formName) {
117+
toast.success("이름 수정이 완료되었어요!");
118+
}
119+
}}
120+
/>
121+
)}
122+
83123
<Tag styles="margin-top: 0.8rem">{displayTag}</Tag>
84124
</div>
85125
{retroCreateData.hasChangedOriginal ? (

apps/web/src/component/retrospectCreate/customTemplate/EditQuestions.tsx

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,6 @@ export function EditQuestions({ goNext, goPrev }: EditQuestionsProps) {
7373
isNewForm: isEdited,
7474
hasChangedOriginal: !isDefaultExtended,
7575
questions: newQuestions,
76-
formName: `커스텀 템플릿`,
7776
}));
7877
};
7978

pnpm-lock.yaml

Lines changed: 20 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)