Skip to content

Commit 90cccf9

Browse files
committed
feat: 리뷰 추가 기능 구현
1 parent 0095688 commit 90cccf9

File tree

7 files changed

+558
-16
lines changed

7 files changed

+558
-16
lines changed

package-lock.json

+58
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+1
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
"react-naver-maps": "^0.1.3",
2626
"react-redux": "^9.1.2",
2727
"react-router-dom": "^6.24.1",
28+
"react-textarea-autosize": "^8.5.4",
2829
"react-typing-effect": "^2.0.5",
2930
"react-virtualized": "^9.22.5",
3031
"react-virtualized-auto-sizer": "^1.0.24",

src/apis/review.jsx

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import axios from 'axios';
2+
3+
export const addReview = (reviewAdd, setWrite, setComplteAdd) => {
4+
console.log('reviewAdd 요청 전', reviewAdd);
5+
axios
6+
.post(`/api/reviews/${reviewAdd.enterpriseId}`, reviewAdd, {
7+
headers: {
8+
'Content-Type': 'application/json', // 명시적으로 Content-Type을 지정
9+
},
10+
withCredentials: true, // 쿠키를 포함하여 요청 보냄
11+
})
12+
.then((response) => {
13+
alert('리뷰 등록완료!');
14+
console.log('리뷰 등록 response:', response);
15+
setWrite(false);
16+
17+
setComplteAdd(true);
18+
})
19+
20+
.catch((error) => {
21+
console.error('리뷰 등록 실패', error);
22+
alert('리뷰 등록 실패');
23+
});
24+
};
25+
26+
export const canAddReview = ({ type, name }) => {
27+
if (type && name) {
28+
if (type === 'labor_user') {
29+
return true;
30+
} else return false;
31+
}
32+
return false;
33+
};

src/components/MainTitle.jsx

+48-4
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,61 @@
11
import React from 'react';
22
import styled from 'styled-components';
33

4-
const MainTitle = ({ text }) => {
5-
return <Title>{text}</Title>;
4+
const MainTitle = ({
5+
text,
6+
isReview = false,
7+
addReview,
8+
isWrite = false,
9+
isLogin = false,
10+
}) => {
11+
const buttonText = isWrite ? '작성 취소' : '리뷰 작성';
12+
return (
13+
<Title>
14+
<TitleText>{text}</TitleText>
15+
{isReview && isLogin && (
16+
<AddReview onClick={addReview} $isWrite={isWrite}>
17+
{buttonText}
18+
</AddReview>
19+
)}
20+
</Title>
21+
);
622
};
723

824
export default MainTitle;
925

1026
const Title = styled.div`
11-
font-size: 26px;
12-
font-weight: bold;
1327
width: 1100px;
1428
border-bottom: 3px solid #379c57;
1529
padding-bottom: 15px;
1630
padding-left: 20px;
31+
display: flex;
32+
position: relative;
33+
`;
34+
const TitleText = styled.div`
35+
font-size: 26px;
36+
font-weight: bold;
37+
`;
38+
const AddReview = styled.button`
39+
background-color: white;
40+
position: absolute;
41+
font-size: 20px;
42+
font-weight: 590;
43+
border: 2px solid
44+
${({ $isWrite }) => ($isWrite ? 'rgb(248, 61, 61)' : '#2c88f8')};
45+
border-radius: 10px;
46+
color: ${({ $isWrite }) => ($isWrite ? 'rgb(248, 61, 61)' : '#2c88f8')};
47+
text-align: center;
48+
padding: 8px 20px;
49+
bottom: 10px;
50+
right: 10px;
51+
transition: all 0.3s ease-in-out;
52+
&:hover {
53+
transform: scale(1.15);
54+
background-color: ${({ $isWrite }) =>
55+
$isWrite ? 'rgb(248, 61, 61)' : '#2c88f8'};
56+
color: white;
57+
}
58+
&:active {
59+
transform: scale(1.35);
60+
}
1761
`;

src/pages/Enterprises/EnterpriseParticular.jsx

+91-12
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,100 @@
1-
import { useContext } from 'react';
2-
import Header from '../../components/Header';
3-
import { BackGroundField } from '../../components/CommonStyled';
4-
import MainTitle from '../../components/MainTitle';
5-
import { CompanyContext, JobContext, ReviewContext } from '../../App';
1+
import { useContext, useEffect, useState } from 'react';
62
import { useParams } from 'react-router-dom';
3+
import { CompanyContext } from '../../App';
4+
import { canAddReview } from '../../apis/review';
5+
import MainTitle from '../../components/MainTitle';
76
import BasicInfo from './components/BasicInfo';
8-
import { Swiper, SwiperSlide } from 'swiper/react';
97
import JobPreview from './components/JobPreview';
108
import ReviewAverage from './components/ReviewAverage';
119
import ReviewList from './components/ReviewList';
10+
import ReviewAddContainer from './components/ReviewAddContainer';
11+
import { BackGroundField } from '../../components/CommonStyled';
12+
1213
const CompanyDetails = () => {
1314
const params = useParams();
1415
const companyContext = useContext(CompanyContext);
15-
16+
const [canAdd, setCanAdd] = useState(false);
17+
const [write, setWrite] = useState(false);
18+
const [reviewAdd, setReviewAdd] = useState({
19+
userId: '',
20+
enterpriseId: '',
21+
title: '',
22+
rating: 0,
23+
promotionRating: 0,
24+
salaryRating: 0,
25+
balanceRating: 0,
26+
cultureRating: 0,
27+
managementRating: 0,
28+
pros: '',
29+
cons: '',
30+
});
31+
const [complteAdd, setComplteAdd] = useState(false);
1632
// 기업 데이터 변수 처리
1733
const EnterpriseData = companyContext.find(
1834
(company) => String(company.enterprise_id) === String(params.enterprise_id)
1935
);
36+
const fetchCanAddReview = async () => {
37+
const sessionType = await window.sessionStorage.getItem('userType');
38+
const sessionName = await window.sessionStorage.getItem('username');
39+
40+
if (EnterpriseData) {
41+
// EnterpriseData가 존재할 때만 setReviewAdd 실행
42+
setReviewAdd((pre) => ({
43+
...pre,
44+
userId: sessionName,
45+
enterpriseId: EnterpriseData.enterprise_id, // enterpriseId 설정
46+
}));
47+
}
2048

21-
// EnterpriseData가 없는 경우에 대비한 조건문 추가
49+
if (sessionType && sessionName) {
50+
const result = await canAddReview({
51+
type: sessionType,
52+
name: sessionName,
53+
});
54+
55+
setCanAdd(result);
56+
}
57+
};
58+
59+
useEffect(() => {
60+
if (EnterpriseData) {
61+
fetchCanAddReview(); // EnterpriseData가 있을 때만 실행
62+
}
63+
}, [EnterpriseData, complteAdd]); // EnterpriseData가 변경될 때만 실행
64+
useEffect(() => {
65+
fetchCanAddReview();
66+
// console.log('변경됐잖아!!!!!!!!!');
67+
}, [complteAdd]); // EnterpriseData가 변경될 때만 실행
68+
69+
const addReview = () => {
70+
setWrite(!write);
71+
if (!write) {
72+
setReviewAdd((pre) => ({
73+
...pre,
74+
enterpriseId: EnterpriseData.enterprise_id, // enterpriseId 다시 설정
75+
title: '',
76+
rating: 0,
77+
promotionRating: 0,
78+
salaryRating: 0,
79+
balanceRating: 0,
80+
cultureRating: 0,
81+
managementRating: 0,
82+
pros: '',
83+
cons: '',
84+
}));
85+
}
86+
};
2287
if (!EnterpriseData) {
2388
return <div>Loading...</div>; // 로딩 상태 표시
2489
}
90+
2591
const EnterpriseImg = EnterpriseData.imageName
2692
? `${import.meta.env.VITE_SERVER_URL}:8080/static/images/` +
2793
EnterpriseData.imageName
2894
: 'https://cdn-icons-png.flaticon.com/512/4091/4091968.png';
2995

3096
const EnterpriseType = EnterpriseData.type || '기업 분류를 작성해주세요!';
31-
32-
const EnterpriseDescripton =
97+
const EnterpriseDescription =
3398
EnterpriseData.description || '기업 설명을 작성해주세요!';
3499

35100
return (
@@ -43,13 +108,27 @@ const CompanyDetails = () => {
43108
address3={EnterpriseData.address3}
44109
phone_number={EnterpriseData.phone_number}
45110
type={EnterpriseType}
46-
description={EnterpriseDescripton}
111+
description={EnterpriseDescription}
47112
/>
48113
<MainTitle text={`${EnterpriseData.name} 채용 공고`} />
49114
<JobPreview />
50115
<MainTitle text={`${EnterpriseData.name} 전체 리뷰 통계`} />
51116
<ReviewAverage />
52-
<MainTitle text={`${EnterpriseData.name} 리뷰`} />
117+
<MainTitle
118+
text={`${EnterpriseData.name} 리뷰`}
119+
isReview={true}
120+
isWrite={write}
121+
addReview={addReview}
122+
isLogin={canAdd} // canAdd 상태를 사용
123+
/>
124+
{write && (
125+
<ReviewAddContainer
126+
reviewAdd={reviewAdd}
127+
setReviewAdd={setReviewAdd}
128+
setWrite={setWrite}
129+
setComplteAdd={setComplteAdd}
130+
/>
131+
)}
53132
<ReviewList />
54133
</BackGroundField>
55134
);

0 commit comments

Comments
 (0)