diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000000000000000000000000000000000000..0eedc676d727f5fe2edcf17d6838708385acf620 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,13 @@ +{ + "name": "whenmeet", + "version": "1.0.0", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "name": "whenmeet", + "version": "1.0.0", + "license": "ISC" + } + } +} diff --git a/react-whenMeet/src/App.js b/react-whenMeet/src/App.js index 76f67d41a3cf73c6d601f7ec47a18e1166712f42..c2230460ec9f578c458891c332fca4ea439f0c02 100644 --- a/react-whenMeet/src/App.js +++ b/react-whenMeet/src/App.js @@ -1,28 +1,35 @@ -import {useState,useEffect} from "react"; -import HomeMake from "./routes/HomeMake" -import MeetingInfo from "./routes/MeetingInfo" -import LinkPage from "./routes/LinkPage" -import HomeParticipate from "./routes/HomeParticipate" -import UserTimeInfo from "./routes/HomeMake" -import{ - BrowserRouter as Router, - Routes, - Route, -} from "react-router-dom"; +import { useState, useEffect } from "react"; +import HomeMake from "./routes/HomeMake"; +import MeetingInfo from "./routes/MeetingInfo"; +import LinkPage from "./routes/LinkPage"; +import HomeParticipate from "./routes/HomeParticipate"; +import UserTimeInfo from "./routes/HomeMake"; +import ResultMake from "./routes/ResultMake"; +import ResultEnd from "./routes/ResultEnd"; +import { BrowserRouter as Router, Routes, Route } from "react-router-dom"; function App() { return ( <Router> <Routes> - <Route path="/" element={<HomeMake/>}> </Route> + <Route path="/" element={<HomeMake />}> + {" "} + </Route> <Route path="/homeparticipate" element={<HomeParticipate />}></Route> - <Route path="/meetinginfo" element={<MeetingInfo />}> </Route> + <Route path="/meetinginfo" element={<MeetingInfo />}> + {" "} + </Route> <Route path="/meetinginfo/linkpage" element={<LinkPage />}></Route> - <Route path="/homeparticipate/usertimeinfo" element={<UserTimeInfo />}></Route> + <Route + path="/homeparticipate/usertimeinfo" + element={<UserTimeInfo />} + ></Route> + <Route path="/result" element={<ResultMake />}></Route>//결과확인페이지 + <Route path="/resultend" element={<ResultEnd />}></Route>// 투표 종료 + 페이지 </Routes> </Router> ); } - -export default App; \ No newline at end of file +export default App; diff --git a/react-whenMeet/src/components/Calendar.js b/react-whenMeet/src/components/Calendar.js index 634214cbacfd5a022eda4f71fc493637f78055d0..6989702ea3f2308e0228a27e8aecd970762ccd39 100644 --- a/react-whenMeet/src/components/Calendar.js +++ b/react-whenMeet/src/components/Calendar.js @@ -1,16 +1,16 @@ -import React from 'react'; -import { useState } from 'react'; -import Input from './Input'; -import CalendarMonth from './CalendarMonth'; -import CalendarWeek from './CalendarWeek'; +import React from "react"; +import { useState } from "react"; +import Input from "./Input"; +import CalendarMonth from "./CalendarMonth"; +//import CalendarWeek from './CalendarWeek'; -function Calendar({onChange}){ - return( - <div> - <h2>달력</h2> - <CalendarMonth/> - </div> - ); +function Calendar({ onChange }) { + return ( + <div> + <h2>달력</h2> + <CalendarMonth /> + </div> + ); } -export default Calendar; \ No newline at end of file +export default Calendar; diff --git a/react-whenMeet/src/components/CalendarWeek.jsx b/react-whenMeet/src/components/CalendarWeek.jsx new file mode 100644 index 0000000000000000000000000000000000000000..9262d2ec45310c1d02fa17c4350f8adb77b5c764 --- /dev/null +++ b/react-whenMeet/src/components/CalendarWeek.jsx @@ -0,0 +1,51 @@ +import React, { useState } from "react"; +import "../styles/CalendarWeek.css"; +const hours = [...Array(24).keys()].map((i) => `${i}:00`); // 0:00 to 23:00 +const days = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]; + +const CalendarWeek = () => { + const [schedule, setSchedule] = useState({}); + + const toggleHour = (day, hour) => { + const daySchedule = schedule[day] || []; + if (daySchedule.includes(hour)) { + setSchedule({ + ...schedule, + [day]: daySchedule.filter((h) => h !== hour), + }); + } else { + setSchedule({ + ...schedule, + [day]: [...daySchedule, hour], + }); + } + }; + + return ( + <table className="calendar-container"> + <thead> + <tr> + {["", ...days].map((day) => ( + <th key={day}>{day}</th> + ))} + </tr> + </thead> + <tbody> + {hours.map((hour) => ( + <tr key={hour}> + <td>{hour}</td> + {days.map((day) => ( + <td + key={day} + className={schedule[day]?.includes(hour) ? "selected" : ""} + onClick={() => toggleHour(day, hour)} + /> + ))} + </tr> + ))} + </tbody> + </table> + ); +}; + +export default CalendarWeek; diff --git a/react-whenMeet/src/components/ResultEndForm.jsx b/react-whenMeet/src/components/ResultEndForm.jsx new file mode 100644 index 0000000000000000000000000000000000000000..a46f3ababc37010e6a704790e08f0cd6264dc771 --- /dev/null +++ b/react-whenMeet/src/components/ResultEndForm.jsx @@ -0,0 +1,64 @@ +import CalendarWeek from "./CalendarWeek"; +import React, { useState } from "react"; +import "../styles/ResultEnd.css"; +import "../styles/CalendarWeek.css"; +export default function ResultEndForm() { + const [title, setTitle] = useState("Title 예시"); + const [resultTime, setresultTIme] = useState("00:37:30"); + const [completedPeopleNum, setcompletedPeopleNum] = useState(3); + const [selectedDate, setSelectedDate] = useState(""); + //const [possibleDates, setpossibleDate] = useState(""); + const possibleDates = ["23.07.01 ~~~", "23.07.02 ~~~", "23.07.03 ~~~"]; + const [completedTasks, setCompletedTasks] = useState(3); + const [totalTasks, setTotalTasks] = useState(7); + const [timeLeft, setTimeLeft] = useState("00:37:30"); + const handleDateChange = (event) => { + setSelectedDate(event.target.value); + }; + + return ( + <div style={{ textAlign: "center", width: "50%" }}> + <h1 className="title-box">{title}</h1> + <p>투표가 종료되었습니다.</p> + <p style={{ color: "blue" }}>약속 시간은 {resultTime}입니다.</p> + <div> + <h2>총 참여한 인원수</h2> + <p>{completedPeopleNum}</p> + <form className="form-container"> + {possibleDates.map((date, index) => ( + <label key={index}> + <input + type="radio" + name="date" + value={date} + checked={selectedDate === date} + onChange={handleDateChange} + /> + {date} + </label> + ))} + </form> + <button + style={{ marginTop: "20px", padding: "10px 20px" }} + onClick={() => console.log(selectedDate)} + > + 이 시간으로 정했어요 + </button> + <button style={{ marginTop: "10px", padding: "10px 20px" }}> + 랜덤으로 약속 시간 확정하기 + </button> + </div> + <CalendarWeek className="calander" /> + <span + className="possibleMan" + style={{ + position: "absolute", + marginTop: "100px", + marginLeft: "100px", + }} + > + <div style={{ textAlign: "center" }}>가능한 사람</div> + </span> + </div> + ); +} diff --git a/react-whenMeet/src/components/ResultMakeForm.js b/react-whenMeet/src/components/ResultMakeForm.js new file mode 100644 index 0000000000000000000000000000000000000000..7f34f58fdb5becbd86b39e8f351b8aae8182ebcb --- /dev/null +++ b/react-whenMeet/src/components/ResultMakeForm.js @@ -0,0 +1,47 @@ +//결과 확인 페이지 +import React, { useState } from "react"; +import CalendarWeek from "./CalendarWeek"; +import { useNavigate } from "react-router-dom"; + +function ResultMakeForm() { + const [title, setTitle] = useState("Title 예시"); + const [completedTasks, setCompletedTasks] = useState(3); + const [totalTasks, setTotalTasks] = useState(7); + const [timeLeft, setTimeLeft] = useState("00:37:30"); + const navigate = useNavigate(); + // 타이머를 시작하고 관리하는 로직 + + const handleEdit = () => { + navigate("/meetinginfo/linkpage"); + }; + + return ( + <div> + <h1 className="title-box">{title}</h1> + <div> + 현재 완료한 일업수 {completedTasks} / {totalTasks} + </div> + <div>종료까지 남은 시간 {timeLeft}</div> + <button onClick={handleEdit}>수정하기</button> + <button + onClick={() => { + navigate("/resultend"); + }} + > + 투표 종료하기 + </button> + <CalendarWeek /> + <span className="mostTime"> + <div style={{ textAlign: "center" }}> + 가장 많은 사람들이 가능한 일정 + </div> + <ol>//일정 5개 나열</ol> + </span> + <span className="possibleMan"> + <div style={{ textAlign: "center" }}>가능한 사람</div> + </span> + </div> + ); +} + +export default ResultMakeForm; diff --git a/react-whenMeet/src/routes/ResultEnd.jsx b/react-whenMeet/src/routes/ResultEnd.jsx new file mode 100644 index 0000000000000000000000000000000000000000..6a9caacb875013647f346280425893b71eea4c4d --- /dev/null +++ b/react-whenMeet/src/routes/ResultEnd.jsx @@ -0,0 +1,12 @@ +import ResultEndForm from "../components/ResultEndForm"; +import "../styles/HomeMake.css"; + +function ResultEnd() { + return ( + <div className="center-container"> + <ResultEndForm /> + </div> + ); +} + +export default ResultEnd; diff --git a/react-whenMeet/src/routes/ResultMake.js b/react-whenMeet/src/routes/ResultMake.js new file mode 100644 index 0000000000000000000000000000000000000000..d9c30bf09abc4ac2ab216212d30b46d7dbf73496 --- /dev/null +++ b/react-whenMeet/src/routes/ResultMake.js @@ -0,0 +1,12 @@ +import ResultMakeForm from "../components/ResultMakeForm"; +import "../styles/HomeMake.css"; + +function ResultMake() { + return ( + <div className="center-container"> + <ResultMakeForm /> + </div> + ); +} + +export default ResultMake; diff --git a/react-whenMeet/src/styles/CalendarWeek.css b/react-whenMeet/src/styles/CalendarWeek.css new file mode 100644 index 0000000000000000000000000000000000000000..b9371efdb40771653bdd7ed696489dd673189f7e --- /dev/null +++ b/react-whenMeet/src/styles/CalendarWeek.css @@ -0,0 +1,34 @@ +.calendar-container { + position: absolute; + left: 100px; + margin-top: 100px; + width: auto; +} + +table { + width: 100%; + border-collapse: collapse; + text-align: center; +} + +th, +td { + border: 1px solid #ddd; + padding: 10px; +} + +th { + background-color: #f4f4f4; +} + +td { + background-color: #f4f4f4; + cursor: pointer; +} +td:hover { + background-color: aqua; +} + +.selected { + background-color: #e0ffe0; /* 선택된 셀의 배경색 */ +} diff --git a/react-whenMeet/src/styles/HomeMake.css b/react-whenMeet/src/styles/HomeMake.css index 64c92f44c3162fc26a1208ce0d75d1e9dc91f907..60d78746a0a72e7e23f0a97f0977285f7bc29d6a 100644 --- a/react-whenMeet/src/styles/HomeMake.css +++ b/react-whenMeet/src/styles/HomeMake.css @@ -1,77 +1,106 @@ body { - background-color: #3CB371; /* Set the background color of the entire page */ - margin: 0; - padding: 0; + background-color: #3cb371; /* Set the background color of the entire page */ + margin: 0; + padding: 0; } .center-container { - display: flex; - justify-content: center; - align-items: center; - height: 100vh; + display: flex; + justify-content: center; + align-items: center; + height: 100vh; } form { - width: 30%; - padding: 20px; - background-color: #f4f4f4; - border-radius: 8px; - box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); - text-align: center; + width: 30%; + padding: 20px; + background-color: #f4f4f4; + border-radius: 8px; + box-shadow: 0 0 10px rgba(0, 0, 0, 0.2); + text-align: center; } h1 { - margin-bottom: 20px; - color: #333333; - font-size: 24px; - font-family: 'Lato'; + margin-bottom: 20px; + color: #333333; + font-size: 24px; + font-family: "Lato"; } input { - width: 100%; - padding: 10px; - margin: 8px 0; - box-sizing: border-box; - border: 1px solid #ccc; - border-radius: 4px; + width: 100%; + padding: 10px; + margin: 8px 0; + box-sizing: border-box; + border: 1px solid #ccc; + border-radius: 4px; } button { - width: 100%; - padding: 10px; - margin-top: 16px; - background-color: #3498db; - color: white; - border: none; - border-radius: 4px; - cursor: pointer; + width: 100%; + padding: 10px; + margin-top: 16px; + background-color: #3498db; + color: white; + border: none; + border-radius: 4px; + cursor: pointer; } button:hover { - background-color: #2980b9; + background-color: #2980b9; } .calendarTable { - margin: 0 auto; /* 가운데 정렬을 위해 margin을 auto로 설정합니다. */ + margin: 0 auto; /* 가운데 정렬을 위해 margin을 auto로 설정합니다. */ } .calendarTable .cellb { - color: gray; /* 회색으로 글자색 지정 */ + color: gray; /* 회색으로 글자색 지정 */ } /* cella 클래스에 대한 스타일 */ .calendarTable .cella { - color: black; /* 검정색으로 글자색 지정 */ + color: black; /* 검정색으로 글자색 지정 */ } +.mostTime { + position: absolute; + margin-top: 200px; + margin-left: 20px; + width: 20em; + border-width: 1px; + border-color: black; + border-style: solid; + padding: 20px; +} +.possibleMan { + position: absolute; + margin-left: 20px; + margin-top: 800px; + width: 20em; + border-width: 1px; + border-color: black; + border-style: solid; + padding: 20px; +} + +.title-box { + text-align: center; + border-width: 1px; + border-color: black; + border-style: solid; + margin: 10px; + padding: 2px 10px; +} /* Media queries for responsiveness */ @media (max-width: 768px) { - form { - width: 80%; - } + form { + width: 80%; + } } @media (max-width: 576px) { - form { - width: 90%; - } + form { + width: 90%; + } } diff --git a/react-whenMeet/src/styles/ResultEnd.css b/react-whenMeet/src/styles/ResultEnd.css new file mode 100644 index 0000000000000000000000000000000000000000..77afcb70d7fc824c77b53623730900f755f03801 --- /dev/null +++ b/react-whenMeet/src/styles/ResultEnd.css @@ -0,0 +1,8 @@ +.form-container { + width: 100%; + margin-bottom: 20px; + padding: 0; +} +.calendar { + margin-top: 100px; +}