Skip to content

Commit f0df9fe

Browse files
authored
Merge pull request #260 from YAPP-Github/feat/YS-556
[YS-556] 공고 등록 / 수정 form 교내 실험 여부 필드 추가 및 공고 상세 조회 시 해당 필드에 따른 수정사항 반영
2 parents ae3cbfe + 32f7796 commit f0df9fe

26 files changed

Lines changed: 225 additions & 81 deletions

File tree

src/app/edit/[postId]/components/EditExperimentPost.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
import { usePathname, useRouter } from 'next/navigation';
44
import { useEffect, useState } from 'react';
5-
import { FormProvider } from 'react-hook-form';
5+
import { FormProvider, useWatch } from 'react-hook-form';
66

77
import { emptySubTitle } from '@/app/my-posts/components/MyPostsTable/MyPostsTable.css';
88
import { emptyViewLayout } from '@/app/post/[postId]/desktop/components/ExperimentPostContainer/ExperimentPostContainer.css';
@@ -31,12 +31,12 @@ const EditExperimentPost = ({ params }: { params: { postId: string } }) => {
3131

3232
const [addLink, setAddLink] = useState<boolean>(false);
3333
const [addContact, setAddContact] = useState<boolean>(false);
34+
const [isOnCampus, setIsOnCampus] = useState<boolean>(true);
3435

3536
const [openSubmitAlertDialog, setOpenSubmitAlertDialog] = useState<boolean>(false);
3637
const [openUpdateAlertModal, setOpenUpdateAlertModal] = useState<boolean>(false);
3738

3839
const [images, setImages] = useState<(File | string)[]>([]);
39-
4040
const [errorMessage, setErrorMessage] = useState<string>('');
4141

4242
const { form, handleSubmit, isLoading, applyMethodData, isRecruitStatus, originExperimentError } =
@@ -45,17 +45,23 @@ const EditExperimentPost = ({ params }: { params: { postId: string } }) => {
4545
postId: params.postId,
4646
addLink,
4747
addContact,
48+
isOnCampus,
4849
setOpenAlertModal: setOpenSubmitAlertDialog,
4950
images,
5051
setImages,
5152
setErrorMessage,
5253
});
5354

5455
const isUserInputDirty = form.formState.isDirty;
56+
const isOnCampusValue = useWatch({ name: 'isOnCampus', control: form.control });
5557

5658
const { isLeaveConfirmModalOpen, handleBackClick, handleCancelLeave, handleConfirmLeave } =
5759
useLeaveConfirmModal({ isUserInputDirty });
5860

61+
useEffect(() => {
62+
setIsOnCampus(isOnCampusValue);
63+
}, [isOnCampusValue, isUserInputDirty]);
64+
5965
useEffect(() => {
6066
if (originExperimentError) {
6167
setOpenUpdateAlertModal(true);
@@ -101,6 +107,7 @@ const EditExperimentPost = ({ params }: { params: { postId: string } }) => {
101107
experimentDateChecked={experimentDateChecked}
102108
durationChecked={durationChecked}
103109
isRecruitStatus={isRecruitStatus}
110+
setIsOnCampus={setIsOnCampus}
104111
/>
105112
<ApplyMethodSection
106113
addLink={addLink}

src/app/post/[postId]/ExperimentPostPage.utils.ts

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { format } from 'date-fns';
22

3-
import { GENDER_TYPE, GenderType } from './ExperimentPostPage.types';
3+
import { GENDER_TYPE, GenderType, MATCH_TYPE } from './ExperimentPostPage.types';
44

55
import { durationMinutesOptions } from '@/app/upload/upload.constants';
66
import { convertToWebpUrl } from '@/app/upload/upload.utils';
@@ -97,6 +97,40 @@ const replaceImageListWithWebp = async (originalImages: string[]): Promise<strin
9797
);
9898
};
9999

100+
// 조건별 실험 장소 렌더링
101+
const getAddressDisplay = (
102+
matchType: string,
103+
address: {
104+
region: string | null;
105+
area: string | null;
106+
isOnCampus: boolean;
107+
place: string | null;
108+
detailedAddress: string | null;
109+
},
110+
) => {
111+
// 1. 비대면 실험일 때
112+
if (matchType === MATCH_TYPE.ONLINE) return '본문 참고';
113+
114+
// 2. 지역 정보 없을 때
115+
if (!address.region || !address.area) return '본문 참고';
116+
117+
// 지역 + 지역구 조합
118+
const baseAddress = `${getRegionLabel(address.region)} ${getAreaLabel(
119+
address.region,
120+
address.area,
121+
)}`;
122+
123+
// 3. 교내 실험 (place 필수, detailedAddress는 옵셔널)
124+
if (address.isOnCampus) {
125+
const parts = [baseAddress, address.place, address.detailedAddress].filter(Boolean);
126+
return parts.join(' ');
127+
}
128+
129+
// 4. 교외 실험 (detailedAddress 필수, place 필드 없음)
130+
const parts = [baseAddress, address.detailedAddress].filter(Boolean);
131+
return parts.join(' ');
132+
};
133+
100134
export {
101135
formattedContentText,
102136
getGenderLabel,
@@ -108,4 +142,5 @@ export {
108142
formatDate,
109143
checkImageExists,
110144
replaceImageListWithWebp,
145+
getAddressDisplay,
111146
};

src/app/post/[postId]/desktop/components/ExperimentPostInfo/ExperimentPostInfo.css.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,4 +65,8 @@ export const buttonStyles = style({
6565

6666
export const postTitle = style({
6767
flex: 1,
68+
overflow: 'hidden',
69+
wordBreak: 'break-word',
70+
whiteSpace: 'normal',
71+
marginRight: '1rem',
6872
});

src/app/post/[postId]/desktop/components/ExperimentPostOutline/ExperimentPostOutline.tsx

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,13 @@ import {
1414
dynamicSpacing,
1515
divider,
1616
} from './ExperimentPostOutline.css';
17-
import { GENDER_TYPE, MATCH_TYPE } from '../../../ExperimentPostPage.types';
17+
import { GENDER_TYPE } from '../../../ExperimentPostPage.types';
1818
import {
1919
getGenderLabel,
2020
getDurationLabel,
21-
getRegionLabel,
22-
getAreaLabel,
2321
getMatchTypeText,
2422
formatDate,
23+
getAddressDisplay,
2524
} from '../../../ExperimentPostPage.utils';
2625
import { UseApplyMethodQueryResponse } from '../../../hooks/useApplyMethodQuery';
2726
import { UseQueryExperimentDetailsAPIResponse } from '../../../hooks/useExperimentDetailsQuery';
@@ -105,16 +104,7 @@ const ExperimentPostOutline = ({ postDetailData, applyMethodData }: ExperimentPo
105104
<tr>
106105
<th>실험 장소</th>
107106
<td>
108-
<p>
109-
{summary.matchType === MATCH_TYPE.ONLINE
110-
? '비대면'
111-
: address.place && address.region && address.area
112-
? `${getRegionLabel(address.region)} ${getAreaLabel(
113-
address.region,
114-
address.area,
115-
)} ${address.place} ${address.detailedAddress}`
116-
: '본문 참고'}
117-
</p>
107+
<p>{getAddressDisplay(summary.matchType, address)}</p>
118108
</td>
119109
</tr>
120110

src/app/post/[postId]/desktop/components/ParticipationGuideModal/ParticipationGuideModal.css.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,8 @@ export const participationModalTitle = style({
4040
color: colors.text06,
4141
marginTop: '1.2rem',
4242
marginRight: '1.2rem',
43+
44+
overflowWrap: 'break-word',
4345
});
4446

4547
export const contactInfoRowContainer = style({

src/app/post/[postId]/hooks/useExperimentDetailsQuery.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ interface Address {
3030
region: string | null;
3131
area: string | null;
3232
detailedAddress: string;
33+
isOnCampus: boolean;
3334
}
3435

3536
export interface UseQueryExperimentDetailsAPIResponse {

src/app/post/[postId]/mobile/components/ExperimentPostSummary/ExperimentPostSummary.tsx

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,13 @@ import {
55
postSummaryContent,
66
postSummaryLayout,
77
} from './ExperimentPostSummary.css';
8-
import { GENDER_TYPE, MATCH_TYPE } from '../../../ExperimentPostPage.types';
8+
import { GENDER_TYPE } from '../../../ExperimentPostPage.types';
99
import {
1010
getGenderLabel,
1111
getMatchTypeText,
1212
getDurationLabel,
13-
getRegionLabel,
14-
getAreaLabel,
1513
formatDate,
14+
getAddressDisplay,
1615
} from '../../../ExperimentPostPage.utils';
1716
import { UseQueryExperimentDetailsAPIResponse } from '../../../hooks/useExperimentDetailsQuery';
1817

@@ -80,16 +79,7 @@ const ExperimentPostSummary = ({
8079
<tr>
8180
<th>실험 장소</th>
8281
<td>
83-
<p>
84-
{summary.matchType === MATCH_TYPE.ONLINE
85-
? '비대면'
86-
: address.place && address.region && address.area
87-
? `${getRegionLabel(address.region)} ${getAreaLabel(
88-
address.region,
89-
address.area,
90-
)} ${address.place} ${address.detailedAddress}`
91-
: '본문 참고'}
92-
</p>
82+
<p>{getAddressDisplay(summary.matchType, address)}</p>
9383
</td>
9484
</tr>
9585

src/app/post/[postId]/mobile/components/ParticipationGuideBottomSheet/ParticipationGuideBottomSheet.css.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ export const bottomSheetTitle = style({
1414
color: colors.text06,
1515

1616
marginBottom: '1.2rem',
17+
18+
width: '100%',
19+
overflowWrap: 'break-word',
1720
});
1821

1922
export const contactInfoRowContainer = style({

src/app/upload/components/AgeForm/AgeForm.css.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,4 +22,11 @@ export const ageInput = style({
2222
'::placeholder': {
2323
color: colors.text02,
2424
},
25+
26+
'@media': {
27+
'screen and (max-width: 767px)': {
28+
maxWidth: '17.2rem',
29+
width: '100%',
30+
},
31+
},
2532
});

src/app/upload/components/ApplyMethodSection/ApplyMethodSection.css.ts

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,13 +28,24 @@ export const targetConditionLayout = style({
2828

2929
export const targetGroupContainer = style({
3030
display: 'flex',
31-
flexFlow: 'row nowrap',
31+
3232
justifyContent: 'space-between',
33+
alignItems: 'flex-start',
34+
35+
flexDirection: 'row',
36+
37+
'@media': {
38+
'screen and (max-width: 767px)': {
39+
flexDirection: 'column',
40+
gap: '1.2rem',
41+
},
42+
},
3343
});
3444

3545
export const ageInputContainer = recipe({
3646
base: {
37-
width: '45.2rem',
47+
maxWidth: '45.2rem',
48+
width: '100%',
3849
height: '4.8rem',
3950
display: 'flex',
4051
alignItems: 'center',
@@ -63,8 +74,8 @@ export const textStyle = style({
6374

6475
export const alarmAgreeContainer = style({
6576
width: 'fit-content',
66-
height: '3.4rem',
67-
padding: '0 1rem',
77+
minHeight: '3.4rem',
78+
padding: '0.2rem 1rem',
6879
backgroundColor: colors.field02,
6980
borderRadius: '0.8rem',
7081
display: 'flex',

0 commit comments

Comments
 (0)