diff --git a/FE/error/public/Profile.png b/FE/error/public/Profile.png
new file mode 100644
index 00000000..ab8a9297
Binary files /dev/null and b/FE/error/public/Profile.png differ
diff --git a/FE/error/public/seed0838.png b/FE/error/public/seed0838.png
new file mode 100644
index 00000000..a3194054
Binary files /dev/null and b/FE/error/public/seed0838.png differ
diff --git a/FE/error/src/axiosConfig.js b/FE/error/src/axiosConfig.js
index f70e5442..907b9aef 100644
--- a/FE/error/src/axiosConfig.js
+++ b/FE/error/src/axiosConfig.js
@@ -1,80 +1,6 @@
import axios from "axios";
-import { useNavigate } from "react-router-dom";
// Axios 기본 설정
axios.defaults.baseURL = import.meta.env.VITE_ERROR_API;
axios.defaults.headers.common["Content-Type"] = "application/json";
axios.defaults.withCredentials = true;
-
-let isRefreshing = false;
-let refreshSubscribers = [];
-
-const onRefreshed = (token) => {
- refreshSubscribers.map((cb) => cb(token));
-};
-
-const addRefreshSubscriber = (cb) => {
- refreshSubscribers.push(cb);
-};
-
-axios.interceptors.request.use(
- (config) => {
- const token = localStorage.getItem("slackToken");
- if (token) {
- config.headers["Authorization"] = `Bearer ${token}`;
- }
- return config;
- },
- (error) => {
- return Promise.reject(error);
- }
-);
-
-axios.interceptors.response.use(
- (response) => {
- return response;
- },
- async (error) => {
- const originalRequest = error.config;
- if (error.response.status === 401 && !originalRequest._retry) {
- if (isRefreshing) {
- return new Promise((resolve) => {
- addRefreshSubscriber((token) => {
- originalRequest.headers["Authorization"] = "Bearer " + token;
- resolve(axios(originalRequest));
- });
- });
- }
-
- originalRequest._retry = true;
- isRefreshing = true;
-
- const refreshToken = localStorage.getItem("refreshToken");
-
- return new Promise((resolve, reject) => {
- axios
- .post("/auth/reissue", { refreshToken: refreshToken })
- .then(({ data }) => {
- const newToken = data.data.accessToken;
- localStorage.setItem("slackToken", newToken);
- axios.defaults.headers.common["Authorization"] =
- "Bearer " + newToken;
- originalRequest.headers["Authorization"] = "Bearer " + newToken;
- onRefreshed(newToken);
- resolve(axios(originalRequest));
- })
- .catch((err) => {
- reject(err);
- useNavigate().push("/login");
- })
- .finally(() => {
- isRefreshing = false;
- refreshSubscribers = [];
- });
- });
- }
- return Promise.reject(error);
- }
-);
-
-export default axios;
diff --git a/FE/error/src/components/DeleteEvent.jsx b/FE/error/src/components/DeleteEvent.jsx
index b69a7826..3a6e16c4 100644
--- a/FE/error/src/components/DeleteEvent.jsx
+++ b/FE/error/src/components/DeleteEvent.jsx
@@ -7,9 +7,15 @@ const DeleteEvent = ({
onRequestClose,
handleUpdateDeleteData,
}) => {
+ const storedToken = localStorage.getItem("slackToken");
+
const calendarDelete = () => {
axios
- .delete("/api/calendar/" + selectID)
+ .delete(`/api/calendar/${selectID}`, {
+ headers: {
+ Authorization: `Bearer ${storedToken}`,
+ },
+ })
.then(() => {
handleUpdateDeleteData(selectID);
handleDelete();
diff --git a/FE/error/src/components/EconoCalendar.jsx b/FE/error/src/components/EconoCalendar.jsx
index 814eae47..8e52858e 100644
--- a/FE/error/src/components/EconoCalendar.jsx
+++ b/FE/error/src/components/EconoCalendar.jsx
@@ -25,13 +25,10 @@ const EconoCalendar = ({ isLoggedIn, setIsLoggedIn }) => {
const uri = isUserLoggedIn
? "/api/calendar/all"
- : "/api/calendar/public/all";
- const config = isUserLoggedIn
- ? { headers: { Authorization: `Bearer ${storedToken}` } }
- : {};
+ : "/api/calendar/all/public";
axios
- .get(uri, config)
+ .get(uri, { headers: { Authorization: `Bearer ${storedToken}` } })
.then((res) => {
const fetchedEvents = res.data.data.map((event) => ({
title: event.eventName,
@@ -292,7 +289,7 @@ const CalendarContainer = styled.div`
background-color: #fff;
border-color: #cbcbcb;
color: #595959;
- margin-right: 0.7rem;
+ margin-right: 1rem;
}
.fc-event-title-container {
height: 1.3rem;
@@ -301,4 +298,7 @@ const CalendarContainer = styled.div`
font-size: 0.95rem;
margin-left: 0.3rem;
}
+ .fc-direction-ltr .fc-toolbar > * > :not(:first-child) {
+ margin-left: 0.5rem;
+ }
`;
diff --git a/FE/error/src/components/SideBar/ProfileBar.jsx b/FE/error/src/components/SideBar/ProfileBar.jsx
index 2f72a1aa..c6d11be2 100644
--- a/FE/error/src/components/SideBar/ProfileBar.jsx
+++ b/FE/error/src/components/SideBar/ProfileBar.jsx
@@ -1,12 +1,66 @@
import styled from "styled-components";
+import { useState } from "react";
+import { HiPencil } from "react-icons/hi2";
+import { useNavigate } from "react-router-dom";
const ProfileBar = () => {
- return ;
+ const [isHovered, setIsHovered] = useState(false);
+ const navigate = useNavigate();
+
+ const handleProfileClick = () => {
+ navigate("/profile");
+ };
+
+ return (
+
+ setIsHovered(true)}
+ onMouseLeave={() => setIsHovered(false)}
+ onClick={handleProfileClick}
+ >
+
+ {isHovered && (
+
+
+
+ )}
+
+
+ );
};
export default ProfileBar;
const StyledProfileFrame = styled.div`
- width: 20rem;
- height: 18.4375rem;
+ width: 15.625rem;
+ height: 15rem;
+ align-items: center;
+ display: flex;
+ flex-direction: column;
+ margin-bottom: 0.6rem;
+`;
+
+const ProfileImageContainer = styled.div`
+ position: relative;
+ cursor: pointer;
+`;
+
+const ProfileImage = styled.img`
+ margin-top: 1.25rem;
+ width: 13rem;
+`;
+
+const EditIconOverlay = styled.div`
+ position: absolute;
+ top: 1rem;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ border-radius: 50%;
+ background-color: rgba(0, 0, 0, 0.5);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ color: white;
+ font-size: 2rem;
`;
diff --git a/FE/error/src/components/SideBar/individualFilter/IndividualFilter.jsx b/FE/error/src/components/SideBar/individualFilter/IndividualFilter.jsx
index eda403f9..c31c60b8 100644
--- a/FE/error/src/components/SideBar/individualFilter/IndividualFilter.jsx
+++ b/FE/error/src/components/SideBar/individualFilter/IndividualFilter.jsx
@@ -6,7 +6,11 @@ import styled from "styled-components";
import FilterCreateModal from "../../../utils/filterUtils/FilterCreateModal";
import FilterList from "../../../utils/filterUtils/FilterList";
-const IndividualFilter = ({ filterLists, addNewFilter }) => {
+const IndividualFilter = ({
+ filterLists,
+ addNewFilter,
+ updateDeleteFilter,
+}) => {
const [individualFilterIsOpen, setindividualFilterIsOpen] = useState(false);
const [filterListsIsOpen, setFilterListsIsOpen] = useState(true);
const createIndividualFilter = () => {
@@ -16,6 +20,7 @@ const IndividualFilter = ({ filterLists, addNewFilter }) => {
const handleArrowDown = () => {
setFilterListsIsOpen(!filterListsIsOpen);
};
+
return (
<>
@@ -60,7 +65,12 @@ const IndividualFilter = ({ filterLists, addNewFilter }) => {
/>
- {filterListsIsOpen && }
+ {filterListsIsOpen && (
+
+ )}
>
);
};
diff --git a/FE/error/src/components/scheduleCheck/CheckCalendar.jsx b/FE/error/src/components/scheduleCheck/CheckCalendar.jsx
index 8fe3df22..2424f0b8 100644
--- a/FE/error/src/components/scheduleCheck/CheckCalendar.jsx
+++ b/FE/error/src/components/scheduleCheck/CheckCalendar.jsx
@@ -21,6 +21,7 @@ const CheckCalendar = ({
handleUpdateDeleteData,
}) => {
const [event, setEvent] = useState({});
+ const storedToken = localStorage.getItem("slackToken");
function createDate(title, startDate, endDate, place, info, type, color) {
const specificEvent = {
@@ -42,17 +43,21 @@ const CheckCalendar = ({
return;
}
- axios.get("/api/calendar/" + selectID).then((res) => {
- createDate(
- res.data.data.eventName,
- res.data.data.eventStartDate,
- res.data.data.eventEndDate,
- res.data.data.eventPlace,
- res.data.data.eventInfo,
- res.data.data.eventType,
- res.data.data.filterColor
- );
- });
+ axios
+ .get("/api/calendar/" + selectID, {
+ headers: { Authorization: `Bearer ${storedToken}` },
+ })
+ .then((res) => {
+ createDate(
+ res.data.data.eventName,
+ res.data.data.eventStartDate,
+ res.data.data.eventEndDate,
+ res.data.data.eventPlace,
+ res.data.data.eventInfo,
+ res.data.data.eventType,
+ res.data.data.filterColor
+ );
+ });
}, [selectID]);
function date(startDate, endDate) {
diff --git a/FE/error/src/components/scheduleCreate/CreateModal.jsx b/FE/error/src/components/scheduleCreate/CreateModal.jsx
index ae74644c..cfa40859 100644
--- a/FE/error/src/components/scheduleCreate/CreateModal.jsx
+++ b/FE/error/src/components/scheduleCreate/CreateModal.jsx
@@ -29,6 +29,7 @@ const CreateModal = ({
const [eventEndTime, setEventEndTime] = useState("00:00");
const [selectedFilter, setSelectedFilter] = useState(null);
const [activeDropdown, setActiveDropdown] = useState(null);
+ const [privateFilters, setPrivateFilters] = useState([]);
useEffect(() => {
if (isOpen && selectedDate) {
@@ -38,16 +39,32 @@ const CreateModal = ({
setEventInfo("");
setEventPlace("");
setEventMemo("");
- setEventStartTime("00:00"); // 초기화 추가
- setEventEndTime("00:00"); // 초기화 추가
- setNewStartDate(selectedDate + "T00:00"); // 수정
- setNewEndDate(selectedDate + "T00:00"); // 수정
-
+ setEventStartTime("00:00");
+ setEventEndTime("00:00");
+ setNewStartDate(selectedDate + "T00:00");
+ setNewEndDate(selectedDate + "T00:00");
setSelectedFilter(null);
setActiveDropdown(null);
+
+ fetchFilters();
}
}, [isOpen, selectedDate]);
+ const storedToken = localStorage.getItem("slackToken");
+
+ const fetchFilters = async () => {
+ try {
+ const response = await axios.get("/api/filter", {
+ headers: { Authorization: `Bearer ${storedToken}` },
+ });
+ if (response.data && response.data.data) {
+ setPrivateFilters(response.data.data);
+ }
+ } catch (error) {
+ console.error("필터 정보를 가져오는 데 실패했습니다:", error);
+ }
+ };
+
const isFilterSelected = () => {
return selectedFilter && selectedFilter.category && selectedFilter.filter;
};
@@ -82,7 +99,6 @@ const CreateModal = ({
setEventStartTime(time);
setNewStartDate(`${StartDate}T${time}`);
- // 시작 시간이 종료 시간보다 늦을 경우, 종료 시간을 시작 시간과 같게 설정
if (StartDate === EndDate && time > eventEndTime) {
setEventEndTime(time);
setNewEndDate(`${EndDate}T${time}`);
@@ -91,7 +107,6 @@ const CreateModal = ({
const handleEndTimeSelect = (time) => {
if (StartDate === EndDate && time < eventStartTime) {
- // 종료 시간이 시작 시간보다 이를 경우, 시작 시간을 종료 시간과 같게 설정
setEventStartTime(time);
setNewStartDate(`${StartDate}T${time}`);
}
@@ -122,11 +137,11 @@ const CreateModal = ({
return selectedFilter.filter;
}
switch (category) {
- case "econo":
+ case "public":
return "에코노";
case "group":
return "그룹";
- case "personal":
+ case "private":
return "개인";
default:
return "";
@@ -146,7 +161,7 @@ const CreateModal = ({
const saveData = () => {
if (!eventName || !isFilterSelected()) {
- return; // 추가적인 안전장치
+ return;
}
const data = {
@@ -155,20 +170,27 @@ const CreateModal = ({
eventEndDate: eventEndDate,
eventPlace: eventPlace,
eventInfo: eventMemo,
- eventCategory: {
- [selectedFilter.category]: selectedFilter.filter,
- },
+ scheduleType: selectedFilter.category,
+ filterName: selectedFilter.filter,
};
- axios.post("/api/calendar", data).then((res) => {
- createDate(
- eventName,
- res.data.data.eventId,
- eventStartDate,
- eventEndDate
- );
- onRequestClose();
- });
+ axios
+ .post(
+ "/api/calendar",
+ {
+ headers: { Authorization: `Bearer ${storedToken}` },
+ },
+ data
+ )
+ .then((res) => {
+ createDate(
+ eventName,
+ res.data.data.eventId,
+ eventStartDate,
+ eventEndDate
+ );
+ onRequestClose();
+ });
};
return (
@@ -191,7 +213,7 @@ const CreateModal = ({
- {["econo", "group", "personal"].map((category) => (
+ {["public", "group", "private"].map((category) => (
{activeDropdown === category && (
- {category === "econo" && (
+ {category === "public" && (
<>
handleFilterSelect(category, "공식행사")}
@@ -220,38 +242,29 @@ const CreateModal = ({
<>
- handleFilterSelect(category, "그룹필터1")
+ handleFilterSelect(category, "28기 신입모집 TF")
}
>
- 그룹필터1
+ 28기 신입모집 TF
- handleFilterSelect(category, "그룹필터2")
- }
+ onClick={() => handleFilterSelect(category, "행사부")}
>
- 그룹필터2
+ 행사부
>
)}
- {category === "personal" && (
- <>
+ {category === "private" &&
+ privateFilters.map((filter) => (
- handleFilterSelect(category, "개인필터1")
+ handleFilterSelect(category, filter.filterName)
}
>
- 개인필터1
+ {filter.filterName}
-
- handleFilterSelect(category, "개인필터2")
- }
- >
- 개인필터2
-
- >
- )}
+ ))}
)}
diff --git a/FE/error/src/pages/CalendarModify.jsx b/FE/error/src/pages/CalendarModify.jsx
index 614361f6..58c92628 100644
--- a/FE/error/src/pages/CalendarModify.jsx
+++ b/FE/error/src/pages/CalendarModify.jsx
@@ -10,6 +10,7 @@ const CalendarModify = () => {
const navigate = useNavigate();
const location = useLocation();
const selectID = location.state.selectID;
+ const storedToken = localStorage.getItem("slackToken");
const [modifyName, setModifyName] = useState("");
const [modifyStartDate, setModifyStartDate] = useState("");
@@ -75,7 +76,13 @@ const CalendarModify = () => {
eventPlace: modifyPlace,
};
axios
- .put("/api/calendar/" + selectID, eventData)
+ .put(
+ "/api/calendar/" + selectID,
+ {
+ headers: { Authorization: `Bearer ${storedToken}` },
+ },
+ eventData
+ )
.then((res) => {
goBack();
})
diff --git a/FE/error/src/pages/LoginPage.jsx b/FE/error/src/pages/LoginPage.jsx
index e1cae153..e9e0cf0b 100644
--- a/FE/error/src/pages/LoginPage.jsx
+++ b/FE/error/src/pages/LoginPage.jsx
@@ -1,7 +1,7 @@
import { useEffect, useState } from "react";
import styled from "styled-components";
import { useNavigate, useSearchParams } from "react-router-dom";
-import axios from "../utils/axiosConfig"; // 수정된 부분
+import axios from "axios";
const LoginPage = () => {
const navigate = useNavigate();
@@ -23,12 +23,11 @@ const LoginPage = () => {
setError(null);
try {
const response = await axios.post(
- `/auth/login/slack?type=slack&code=${authCode}&redirect_uri=${redirectUri}`
+ `https://error.econo-calendar.com:8080/api/auth/login/slack?type=slack&code=${authCode}&redirect_uri=https://econo-calendar.com/login`
);
if (response.data.code === "201") {
localStorage.setItem("slackToken", response.data.data.accessToken);
- localStorage.setItem("refreshToken", response.data.data.refreshToken); // 수정된 부분
navigate("/");
} else {
setError(response.data.message || "로그인 실패");
diff --git a/FE/error/src/pages/MainPage.jsx b/FE/error/src/pages/MainPage.jsx
index c0d9dd7a..69da177e 100644
--- a/FE/error/src/pages/MainPage.jsx
+++ b/FE/error/src/pages/MainPage.jsx
@@ -5,12 +5,12 @@ import ProfileBar from "../components/SideBar/ProfileBar";
import PublicFilter from "../components/SideBar/publicFilter/PublicFilter";
import IndividualFilter from "../components/SideBar/individualFilter/IndividualFilter";
import GroupFilter from "../components/SideBar/groupFilter/GroupFilter";
+import axios from "axios";
const MainPage = () => {
const [filterIndividualLists, setFilterIndividualLists] = useState([]);
const [filterGroupLists, setFilterGroupLists] = useState([]);
const [isLoggedIn, setIsLoggedIn] = useState(false);
-
useEffect(() => {
const token = localStorage.getItem("slackToken");
setIsLoggedIn(!!token);
@@ -23,6 +23,31 @@ const MainPage = () => {
const addNewGroupFilter = (newGroupFilter) => {
setFilterGroupLists([...filterGroupLists, newGroupFilter]);
};
+ const updateDeleteFilter = (newFilter) => {
+ setFilterIndividualLists(
+ filterIndividualLists.filter((filter) => filter.filterId !== newFilter)
+ );
+ };
+ const storedToken = localStorage.getItem("slackToken");
+
+ useEffect(() => {
+ axios
+ .get("/api/filter", {
+ headers: { Authorization: `Bearer ${storedToken}` },
+ })
+ .then((res) => {
+ console.log(res);
+ const fetchedFilter = res.data.data.map((filter) => ({
+ filterId: filter.filterId,
+ filterName: filter.filterName,
+ filterColor: filter.filterColor,
+ }));
+ setFilterIndividualLists(fetchedFilter);
+ })
+ .catch((err) => {
+ console.log("Error fetching events:", err);
+ });
+ }, []);
return (
@@ -30,22 +55,24 @@ const MainPage = () => {
ERROR
-
-
-
- {isLoggedIn && (
- <>
-
-
- >
- )}
-
+
+
+
+
+ {isLoggedIn && (
+ <>
+
+
+ >
+ )}
+
+
@@ -56,9 +83,11 @@ const MainPage = () => {
export default MainPage;
const SideBar = styled.div`
- width: 250px;
+ width: 15.625rem;
height: 98.1vh;
margin-top: 1rem;
+ display: flex;
+ flex-direction: column;
`;
const CalendarPage = styled.div`
@@ -71,7 +100,7 @@ const LineBox = styled.div`
height: 1.25rem;
border: 1px solid #ddd;
border-right: none;
- margin-top: 1.63em;
+ margin-top: 0.65rem;
`;
const Logo = styled.div`
@@ -83,6 +112,36 @@ const Logo = styled.div`
margin-bottom: 1rem;
`;
+const ScrollableContent = styled.div`
+ flex-grow: 1;
+ overflow-y: auto;
+ overflow-x: hidden;
+
+ /* 기본적으로 스크롤바를 숨김 */
+ scrollbar-width: thin;
+ scrollbar-color: transparent transparent;
+
+ /* 호버 시 스크롤바 표시 */
+ &:hover {
+ scrollbar-color: #c6c6c6 transparent;
+ }
+
+ /* Webkit 브라우저 (Chrome, Safari 등)를 위한 스타일 */
+ &::-webkit-scrollbar {
+ width: 8px;
+ }
+
+ &::-webkit-scrollbar-track {
+ background: transparent;
+ }
+
+ &::-webkit-scrollbar-thumb {
+ background-color: transparent;
+ border-radius: 20px;
+ border: 3px solid transparent;
+ }
+`;
+
const FilterFrame = styled.div`
display: flex;
flex-direction: column;
diff --git a/FE/error/src/pages/ProfilePage.jsx b/FE/error/src/pages/ProfilePage.jsx
index 9513a7ef..d1f72533 100644
--- a/FE/error/src/pages/ProfilePage.jsx
+++ b/FE/error/src/pages/ProfilePage.jsx
@@ -1,17 +1,51 @@
-import { useState } from "react";
+import { useState, useEffect } from "react";
import styled from "styled-components";
import { FaRandom } from "react-icons/fa";
+import axios from "axios"; // axios를 import 합니다.
const ProfilePage = () => {
const [selectedImage, setSelectedImage] = useState(null);
- const [images, setImages] = useState(
- Array(16).fill("https://via.placeholder.com/200")
- );
+ const [images, setImages] = useState([]);
+ const [isLoading, setIsLoading] = useState(true);
+ const storedToken = localStorage.getItem("slackToken");
+
+ useEffect(() => {
+ const fetchImages = async () => {
+ try {
+ const response = await axios.get("http://localhost:8080/api/images", {
+ headers: { Authorization: `Bearer ${storedToken}` },
+ });
+ setImages(response.data);
+ setIsLoading(false);
+ } catch (error) {
+ console.error("Failed to fetch images:", error);
+ if (error.response) {
+ // 서버 응답이 2xx 범위를 벗어난 상태 코드를 반환한 경우
+ console.error(error.response.data);
+ console.error(error.response.status);
+ console.error(error.response.headers);
+ } else if (error.request) {
+ // 요청이 이루어졌으나 응답을 받지 못한 경우
+ console.error(error.request);
+ } else {
+ // 요청을 설정하는 중에 오류가 발생한 경우
+ console.error("Error", error.message);
+ }
+ setIsLoading(false);
+ }
+ };
+
+ fetchImages();
+ }, []);
const selectImage = (index) => {
setSelectedImage(index);
};
+ if (isLoading) {
+ return
Loading...
;
+ }
+
return (
<>
diff --git a/FE/error/src/utils/filterUtils/FilterCreateModal.jsx b/FE/error/src/utils/filterUtils/FilterCreateModal.jsx
index 226e818f..e7f21efe 100644
--- a/FE/error/src/utils/filterUtils/FilterCreateModal.jsx
+++ b/FE/error/src/utils/filterUtils/FilterCreateModal.jsx
@@ -5,6 +5,7 @@ import Modal from "react-modal";
import "./CreateFilterModal.css";
import GroupFilterCreateModal from "../../components/SideBar/groupFilter/GroupFilterCreateModal";
import FilterColorSelect from "./FilterColorSelect";
+import axios from "axios";
const FilterCreateModal = ({
isOpen,
@@ -14,20 +15,28 @@ const FilterCreateModal = ({
}) => {
const [filterTitle, setFilterTitle] = useState("");
const [filterColor, setFilterColor] = useState("");
-
+ const storedToken = localStorage.getItem("slackToken");
const handleTitleChange = (event) => {
setFilterTitle(event.target.value);
};
const handleCreateFilter = () => {
const newFilter = {
- title: filterTitle,
- color: filterColor,
+ filterName: filterTitle,
+ filterColor: filterColor,
};
- addNewFilter(newFilter);
- setFilterTitle("");
- setFilterColor("");
- onRequestClose();
+ axios
+ .post("/api/filter", newFilter, {
+ headers: { Authorization: `Bearer ${storedToken}` },
+ })
+ .then((res) => {
+ console.log(res);
+ addNewFilter(newFilter);
+ setFilterTitle("");
+ setFilterColor("");
+ onRequestClose();
+ });
};
+
return (
<>
{
+ const storedToken = localStorage.getItem("slackToken");
+
+ const handleDelete = () => {
+ axios
+ .delete("/api/filter/" + filterID, {
+ headers: { Authorization: `Bearer ${storedToken}` },
+ })
+ .then(() => {
+ updateDeleteFilter(filterID);
+ });
+ };
+ return (
+ <>
+ (e.currentTarget.style.color = "#000")}
+ onMouseLeave={(e) => (e.currentTarget.style.color = "#B8B6B6")}
+ >
+
+
+ >
+ );
+};
+
+export default FilterDelete;
+
+const StyledDetailIcon = styled.button`
+ background-color: #fff;
+ border: none;
+ display: none;
+ margin-left: 0.5rem;
+`;
diff --git a/FE/error/src/utils/filterUtils/FilterList.jsx b/FE/error/src/utils/filterUtils/FilterList.jsx
index 07d8851a..33b72f4a 100644
--- a/FE/error/src/utils/filterUtils/FilterList.jsx
+++ b/FE/error/src/utils/filterUtils/FilterList.jsx
@@ -1,36 +1,28 @@
-import { AiOutlineClose, AiOutlineMore } from "react-icons/ai";
import styled from "styled-components";
import ScheduleToggle from "./ScheduleToggle";
+import FilterModify from "./FilterModify";
+import FilterDelete from "./FilterDelete";
-const FilterList = ({ filterLists }) => {
- const filterDelete = () => {};
-
+const FilterList = ({ filterLists, updateDeleteFilter }) => {
return (
{filterLists.map((filterList, index) => (
-
+
-
- {filterList.title}
+
+ {filterList.filterName}
- (e.currentTarget.style.color = "#000")}
- onMouseLeave={(e) => (e.currentTarget.style.color = "#B8B6B6")}
- >
-
-
- (e.currentTarget.style.color = "#000")}
- onMouseLeave={(e) => (e.currentTarget.style.color = "#B8B6B6")}
- >
-
-
+
+
-
+
))}
);
@@ -44,7 +36,7 @@ const StyledFilterListFrame = styled.div`
margin-left: 1.3rem;
margin-bottom: 0.3rem;
`;
-const StyledSceduleType = styled.div`
+const StyledScheduleType = styled.div`
height: 1.8rem;
display: flex;
align-items: center;
@@ -63,9 +55,3 @@ const StyledTitle = styled.div`
display: flex;
align-items: center;
`;
-const StyledDetailIcon = styled.button`
- background-color: #fff;
- border: none;
- display: none;
- margin-left: 0.5rem;
-`;
diff --git a/FE/error/src/utils/filterUtils/FilterModify.jsx b/FE/error/src/utils/filterUtils/FilterModify.jsx
new file mode 100644
index 00000000..df6a961b
--- /dev/null
+++ b/FE/error/src/utils/filterUtils/FilterModify.jsx
@@ -0,0 +1,141 @@
+import { AiOutlineMore } from "react-icons/ai";
+import styled from "styled-components";
+import Modal from "react-modal";
+import { useState } from "react";
+import FilterColorSelect from "./FilterColorSelect";
+import axios from "axios";
+
+const FilterModify = ({ filterName, filterID }) => {
+ const [showModal, setShowModal] = useState(false);
+ const [clickPosition, setClickPosition] = useState({ x: 0, y: 0 });
+ const [filterTitle, setFilterTitle] = useState(filterName);
+ const [filterColor, setFilterColor] = useState("");
+
+ const handleModify = (e) => {
+ const rect = e.currentTarget.getBoundingClientRect();
+ setClickPosition({ x: rect.left, y: rect.top });
+ setShowModal(true);
+ };
+ const storedToken = localStorage.getItem("slackToken");
+
+ const handleTitleChange = (event) => {
+ setFilterTitle(event.target.value);
+ };
+
+ const handleModifyFilter = () => {
+ const modifyFilter = {
+ filterName: filterTitle,
+ filterColor: filterColor,
+ };
+ axios
+ .post(
+ "/api/calendar/filter/" + filterID,
+ {
+ headers: { Authorization: `Bearer ${storedToken}` },
+ },
+ modifyFilter
+ )
+ .then((res) => {
+ setShowModal(false);
+ window.location.reload();
+ });
+ };
+
+ const customStyles = {
+ content: {
+ position: "absolute",
+ top: "auto",
+ left: `${clickPosition.x}px`,
+ right: "auto",
+ bottom: `calc(100% - ${clickPosition.y}px)`,
+ transform: "translateY(-10px)",
+ marginRight: "-50%",
+ borderRadius: "0.5rem",
+ width: "19rem",
+ height: "auto",
+ backgroundColor: "white",
+ boxShadow: "0 0 10px 8px rgba(0, 0, 0, 0.1)",
+ },
+ overlay: {
+ backgroundColor: "rgba(0, 0, 0, 0)",
+ },
+ };
+
+ return (
+ <>
+ (e.currentTarget.style.color = "#000")}
+ onMouseLeave={(e) => (e.currentTarget.style.color = "#B8B6B6")}
+ >
+
+
+ setShowModal(false)}
+ style={customStyles}
+ contentLabel="Modify Filter Modal"
+ className="FilterModal"
+ overlayClassName="overlay"
+ >
+
+
+
+
+
+
+ 필터수정
+
+
+
+ >
+ );
+};
+
+export default FilterModify;
+
+const StyledDetailIcon = styled.button`
+ background-color: #fff;
+ border: none;
+ display: none;
+ margin-left: 0.5rem;
+`;
+
+const StyledDetail = styled.div`
+ margin: 2rem;
+`;
+
+const StyledTitleInput = styled.input`
+ width: 95%;
+ height: 2rem;
+ margin-bottom: 2rem;
+ font-size: 1.5rem;
+ border: none;
+ border-bottom: 1px solid #495057;
+ outline: none;
+`;
+
+const StyledModalFooter = styled.div`
+ margin-right: 1.5rem;
+ margin-bottom: 1rem;
+ display: flex;
+ flex-direction: row-reverse;
+`;
+
+const StyledCreateFilterBtn = styled.button`
+ width: 4.5rem;
+ height: 2rem;
+ background-color: #ff9999;
+ border-radius: 0.5rem;
+ border: none;
+
+ span {
+ font-size: 0.88rem;
+ color: #fff;
+ }
+`;