Skip to content
Snippets Groups Projects
Commit 3f1f32be authored by Min Dong Hyeun's avatar Min Dong Hyeun
Browse files

[ADD]CSS

parents 6cc28ba6 a9faac79
Branches
No related tags found
No related merge requests found
......@@ -3,5 +3,5 @@ WORKDIR /app
COPY package.json ./
RUN npm install
COPY . .
EXPOSE 80
EXPOSE 3001
CMD ["npm", "start"]
\ No newline at end of file
......@@ -19,7 +19,7 @@
"web-vitals": "^2.1.4"
},
"scripts": {
"start": "react-scripts start",
"start": "export PORT=3001 && react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
......
......@@ -115,7 +115,7 @@ const CalendarWeek = ({
const weekDates = weeks[currentWeekIndex] || [];
return (
<div className="wrap">
<div className="calendarWeekContainer wrap">
<div className="button-container">
<button onClick={handlePrevWeek} disabled={currentWeekIndex === 0}>
Prev Week
......
......@@ -13,7 +13,70 @@ function ResultMakeForm() {
const [hoveredInfo, setHoveredInfo] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const [isModalOpen, setIsModalOpen] = useState(false);
const [mostAvailableDates, setMostAvailableDates] = useState([]);
const [topAvailableDates, setTopAvailableDates] = useState([]);
useEffect(() => {
if (meetingData && meetingData.participants) {
calculateTopAvailableDates();
}
}, [meetingData]);
const calculateTopAvailableDates = () => {
let dateAvailability = {};
meetingData.participants.forEach((participant) => {
participant.availableSchedules.forEach((schedule) => {
if (!dateAvailability[schedule.availableDate]) {
dateAvailability[schedule.availableDate] = {};
}
schedule.availableTimes.forEach((time) => {
if (!dateAvailability[schedule.availableDate][time]) {
dateAvailability[schedule.availableDate][time] = 0;
}
dateAvailability[schedule.availableDate][time]++;
});
});
});
let dateCounts = Object.entries(dateAvailability).map(([date, times]) => {
let maxCount = Math.max(...Object.values(times));
let count = Object.values(times).filter((val) => val === maxCount).length;
return { date, count, maxCount };
});
dateCounts.sort((a, b) => b.maxCount - a.maxCount || b.count - a.count);
setTopAvailableDates(dateCounts.slice(0, 5));
};
useEffect(() => {
if (meetingData && meetingData.participants) {
calculateMostAvailableDates();
}
}, [meetingData]);
const calculateMostAvailableDates = () => {
let dateAvailabilityCount = {};
meetingData.participants.forEach((participant) => {
participant.availableSchedules.forEach((schedule) => {
if (!dateAvailabilityCount[schedule.availableDate]) {
dateAvailabilityCount[schedule.availableDate] = new Set();
}
schedule.availableTimes.forEach((time) => {
dateAvailabilityCount[schedule.availableDate].add(time);
});
});
});
const sortedDates = Object.entries(dateAvailabilityCount)
.map(([date, times]) => ({ date, count: times.size }))
.sort((a, b) => b.count - a.count)
.slice(0, 5);
setMostAvailableDates(sortedDates);
};
useEffect(() => {
const fetchMeetingData = async () => {
setIsLoading(true);
......@@ -141,15 +204,15 @@ function ResultMakeForm() {
<h1 className="title-box">{meetingData?.title}</h1>
{meetingData.maxParticipants && (
<div>
현재 완료한 인원수 {meetingData?.currentParticipants} /{" "}
현재 완료한 인원수 : {meetingData?.currentParticipants} /{" "}
{meetingData?.maxParticipants}
</div>
)}
{!meetingData.maxParticipants && (
<div>현재 완료한 인원수 {meetingData?.currentParticipants}</div>
<div>현재 완료한 인원수 : {meetingData?.currentParticipants}</div>
)}
<div>종료까지 남은 시간 {timeLeft}</div>
<div>종료까지 남은 시간 : {timeLeft}</div>
<button onClick={handleEdit}>수정하기</button>
<button onClick={closeMeeting}>투표 종료하기</button>
</div>
......@@ -174,33 +237,42 @@ function ResultMakeForm() {
onRequestClose={handleModalClose}
onSubmit={handlePasswordSubmit}
/>
<span className="mostTime">
<div style={{ textAlign: "center" }}>
가장 많은 사람들이 가능한 일정
</div>
<ol>//일정 5개 나열</ol>
</span>
<span className="possible">
{!hoveredInfo && (
<div>
<strong>가능한 사람들이 표시됩니다.</strong>
<p>마우스를 달력 위에 올려보세요!</p>
</div>
)}
{hoveredInfo && (
<div style={{ textAlign: "center" }}>
<strong>
{hoveredInfo.date} {hoveredInfo.time} 가능한 사람:
</strong>
<ul>
{hoveredInfo.participants.map((name) => (
<li key={name}>{name}</li>
))}
</ul>
</div>
)}
</span>
<div className="flex-bottom-container">
<span className="mostTime">
<strong style={{ textAlign: "center" }}>
가장 많은 사람들이 가능한 일정
</strong>
<ol>
{topAvailableDates.map((dateInfo, index) => (
<li key={index}>
{dateInfo.date} ({dateInfo.maxCount}명이 가능한 시간대:{" "}
{dateInfo.count} )
</li>
))}
</ol>
</span>
<span className="possible">
{!hoveredInfo && (
<div>
<strong>가능한 사람들이 표시됩니다.</strong>
<p>마우스를 달력 위에 올려보세요!</p>
</div>
)}
{hoveredInfo && (
<div style={{ textAlign: "center" }}>
<strong>
{hoveredInfo.date} {hoveredInfo.time} 가능한 사람:
</strong>
<ul>
{hoveredInfo.participants.map((name) => (
<li key={name}>{name}</li>
))}
</ul>
</div>
)}
</span>
</div>
</>
);
}
......
.calendar-container {
.calendarWeekContainer .calendar-container {
margin-top: 20px;
width: 100%;
background-color: #5fbdff;
}
.button-container {
.calendarWeekContainer .button-container {
display: flex;
justify-content: space-between;
}
.button-container button:first-child {
margin-right: 20px;
.calendarWeekContainer .button-container button:first-child {
margin-right: 10%;
margin-left: 10%;
}
.button-container button:last-child {
margin-left: 20px;
.calendarWeekContainer .button-container button:last-child {
margin-right: 10%;
margin-left: 10%;
}
.wrap {
.calendarWeekContainer .wrap {
width: 80%;
}
table {
.calendarWeekContainer table {
width: 100%;
border-collapse: collapse;
text-align: center;
margin-bottom: 4%;
}
th,
td {
.calendarWeekContainer th,
.calendarWeekContainer td {
border: 1px solid #ddd;
padding: 10px;
}
th {
.calendarWeekContainer th {
background-color: #f4f4f4;
}
td {
.calendarWeekContainer td {
background-color: #f4f4f4;
cursor: pointer;
transition: background-color 0.3s ease, transform 0.3s ease,
box-shadow 0.3s ease; /* 부드러운 애니메이션 효과 */
box-shadow 0.3s ease;
}
td:hover {
.calendarWeekContainer td:hover {
background-color: aqua;
transform: scale(1.05); /* 셀을 약간 확대 */
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); /* 셀에 그림자 추가 */
border: 1px solid #5fbdff; /* 셀 주위에 테두리 추가 */
transform: scale(1.05);
box-shadow: 0 0 10px rgba(0, 0, 0, 0.2);
border: 1px solid #5fbdff;
}
.calendarWeekContainer .selected {
background-color: #e0ffe0;
}
.selected {
background-color: #e0ffe0; /* 선택된 셀의 배경색 */
@media screen and (max-width: 768px) {
.calendarWeekContainer .wrap {
display: flex;
width: 100%;
}
}
......@@ -9,11 +9,11 @@
}
.form-container label {
display: flex;
align-items: center; /* 라디오 버튼과 텍스트를 세로 중앙에 맞춤 */
margin: 20px 0; /* 라벨 간에 여백을 추가 */
align-items: center;
margin: 20px 0;
}
.form-container input[type="radio"] {
margin-right: 10px; /* 라디오 버튼과 텍스트 사이의 공간 조정 */
margin-right: 10px;
width: 20%;
}
......@@ -24,11 +24,9 @@
.possible {
position: fixed;
right: 0; /* 화면의 오른쪽 끝에 고정 */
top: 60%; /* 화면의 상단으로부터 50%의 위치에 고정 */
transform: translateY(
-50%
); /* 상단 50% 위치에서 자기 자신의 높이의 절반을 위로 이동 */
right: 0;
top: 60%;
transform: translateY(-50%);
width: 20%;
border: 1px solid black;
padding: 20px;
......@@ -45,3 +43,15 @@
flex-direction: column;
align-items: center;
}
@media screen and (max-width: 768px) {
.possible {
position: static;
width: 40%;
margin: 200px 20px;
}
.flex-row {
flex-direction: column;
width: 100%;
}
}
......@@ -18,15 +18,60 @@
box-shadow: 0px 1px 5px rgba(95, 189, 255, 0.5); /* 구분선에 그림자 효과 추가 */
padding-top: 20px;
margin-top: 30px;
width: 50%;
overflow-x: auto;
}
.mostTime,
.possible {
border: 1px solid #ddd;
padding: 20px;
margin: 10px; /* 각 요소 주변의 공간을 더욱 명확히 */
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1); /* 세련된 그림자 효과 */
border-radius: 8px; /* 모서리를 둥글게 */
background-color: #ffffff; /* 배경색 설정 */
box-sizing: border-box; /* 패딩과 보더를 너비에 포함 */
}
.mostTime {
position: fixed;
right: 0;
top: 30%;
transform: translateY(-50%);
transform: translateY(-60%);
width: 20%;
border: 1px solid black;
padding: 20px;
margin-right: 2%;
}
.possible {
position: fixed;
right: 0;
top: 60%;
transform: translateY(-40%);
width: 20%;
border: 1px solid black;
padding: 20px;
margin-right: 2%;
}
@media screen and (max-width: 768px) {
.flex-bottom-container {
display: flex;
justify-content: space-between;
width: 100%;
bottom: 0;
left: 0;
}
.mostTime,
.possible {
position: static;
width: 40%;
margin: 200px 20px;
}
.flex-row {
flex-direction: column;
width: 100%;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment