Skip to content

Commit

Permalink
�Feat : 유저 메인페이지 구현
Browse files Browse the repository at this point in the history
  • Loading branch information
seonwoonam authored Dec 5, 2023
2 parents 15c24f5 + eb1ea5f commit 44d64ea
Show file tree
Hide file tree
Showing 4 changed files with 240 additions and 34 deletions.
21 changes: 21 additions & 0 deletions frontend/dguonoff/src/api/dguonandoff.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import axios from "axios";
import Bookmark from "../types/Bookmark";
import User, { UserRole } from "../types/User";
import { CookieStorageProvider } from "../modules/storage/AppStorageProvider";
import Building from "../types/Building";
Expand Down Expand Up @@ -920,3 +921,23 @@ export async function deleteFixedSchedule(token: string, facilitySchedule: Facil
}
return responseData === "success";
}


export async function getMyBookmark(token: string): Promise<Bookmark[]> {
let result: Bookmark[] = [];
try {
const response = await axios.get(
getApiUrl("/api/user/bookmark"),
{
headers: {
"Authorization": `Bearer ${token}`
}
}
);
console.log(response.data);
result = response.data.map((item: any) => new Bookmark(item.facilityName, item.facilityCode, item.buildingName));
} catch (error) {
console.error(error);
}
return result;
}
21 changes: 21 additions & 0 deletions frontend/dguonoff/src/components/pages/service/Service.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -109,4 +109,25 @@
color: #000000;
}

.modalContent {
background-color: white;
width: 60%; /* 모달 너비를 전체 화면의 60%로 설정 */
padding: 20px;
border-radius: 10px;
box-shadow: 0 4px 8px rgba(0, 0, 0, 0.1);
overflow-y: auto; /* 내용이 넘칠 경우에 스크롤 바 표시 */
}

.noUsingFacility{
display: flex;
flex-direction: column; /* 자식 요소들을 수직으로 정렬 */
align-items: center; /* 수평 중앙 정렬 */
justify-content: center; /* 수직 중앙 정렬 */
height: 100%; /* 부모 요소의 높이를 적절히 설정해야 중앙 정렬이 잘 작동합니다. */
}

.noUsingText{
font-size : 14px;
color : '#646464';
font-weight: bold;
}
196 changes: 162 additions & 34 deletions frontend/dguonoff/src/components/pages/service/home/MainPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,16 @@ import NotificationsIcon from '@mui/icons-material/Notifications';
import styles from "../Service.module.css";
import GrayBorderBox from "../../../../modules/GrayBorderBox";
import GrayCircle from "../../../../modules/GrayCircle";
import { Business, LocalLibrary, FilterHdr } from '@mui/icons-material';
import { Business, LocalLibrary, FilterHdr, BlindsClosedSharp } from '@mui/icons-material';
import { useNavigate } from "react-router-dom";
import useAuth from "../../../../hooks/useAuth";
import Bookmark from "../../../../types/Bookmark";
import { getBuildings, getMyBookmark, getReservations } from "../../../../api/dguonandoff";
import { CookieStorageProvider } from "../../../../modules/storage/AppStorageProvider";
import { useModal } from "../../../../modules/modal/Modal";
import { ModalAnimationType } from "../../../../modules/modal/ModalAnimations";
import Building from "../../../../types/Building";
import Reservation from "../../../../types/Reservation";


interface FacilityMenu {
Expand All @@ -18,14 +25,14 @@ interface FacilityMenu {
export default function MainPage() {
const navigate = useNavigate();
const isUserLoggedIn = useAuth();

useEffect(() => {
console.log('isUserLoggedIn:', isUserLoggedIn)
if (!isUserLoggedIn) {
navigate('/login'); // 로그인 안되어 있으면 로그인 페이지로 이동
}
}, [isUserLoggedIn, navigate]);

const [myBookmarks, setMyBookmarks] = useState<Bookmark[]>([]); // 즐겨찾기 목록
const [myReservations, setMyReservations] = useState<Reservation[]>([]); // 내 예약 목록
const [buildings, setBuildings] = useState<Building[]>([]); // 시설 목록
const [isActive, setIsActive] = useState<boolean>(false);
const [nowUsingReservation, setNowUsingReservation] = useState<Reservation>(); // 현재 이용중인 예약
const [FacilityMenuModal, openFacilityMenuModal, closeFacilityMenuModal] = useModal(ModalAnimationType.ZOOM);

let userToken : string = "";

const appName : string = "동국 ON/OFF";

Expand All @@ -44,10 +51,67 @@ export default function MainPage() {
},
]

useEffect(() => {
console.log('isUserLoggedIn:', isUserLoggedIn)
if (!isUserLoggedIn) {
navigate('/login'); // 로그인 안되어 있으면 로그인 페이지로 이동
}else{
userToken = CookieStorageProvider.get('userAuthToken')!;
handleLoadBookmark();
handleLoadReservation();
handleLoadBuildings();
let { isActiveNow, ActiveReservation } = findActiveReservation(myReservations);
setIsActive(isActiveNow);

if(isActiveNow){
setNowUsingReservation(ActiveReservation!);
}
}
}, [isUserLoggedIn, navigate]);


const handleLoadBookmark = async () => {
const bookmarks : Bookmark[] = await getMyBookmark(userToken);
setMyBookmarks(bookmarks);
}

const handleLoadReservation = async () => {
const reservations : Reservation[] = await getReservations(userToken);
setMyReservations(reservations);
}

const handleBellClick = () => {
console.log("bell clicked");
}

const handleMenuClick = async () => {
openFacilityMenuModal();
}

const handleLoadBuildings = async () => {
const buildings : Building[] = await getBuildings(userToken);
setBuildings(buildings);
}

const handleEndUsing = () => {

}

const findActiveReservation = (reservationList: Reservation[]): { isActiveNow: boolean, ActiveReservation: Reservation | null } => {
const now = new Date();

for (const reservation of reservationList) {
const startDate = new Date(`${reservation.getDate}T${reservation.getStartTime}`);
const endDate = new Date(`${reservation.getDate}T${reservation.getEndTime}`);

if (now >= startDate && now <= endDate) {
return { isActiveNow: true, ActiveReservation :reservation };
}
}

return { isActiveNow: false, ActiveReservation: null };
};

return (
<Container>
<Toolbar>
Expand All @@ -66,50 +130,114 @@ export default function MainPage() {
paddingTop: '32px',
paddingBottom: '32px',
}}>
{/* 상자 안의 내용 */}
<div className={styles.usingFacilityTitle} >
신공학관(기숙사)
</div>
<div className={styles.usingFacilityTitle}>
401-3107(3107 강의실)
</div>
<div style={{ height: '12px' }} />
<div className={styles.usingTime}>
14:00 ~ 15:00 이용중
</div>
<div style={{ height: '12px' }} />
<div style={{ width: '100%', display: 'flex', justifyContent: 'flex-end'}}>
<Button variant="contained"
style={{ backgroundColor: '#EDEBE7', color: '#959494', fontWeight : 'bold', boxShadow: 'none' }}
>이용 종료</Button>
</div>
{
isActive ?
<div>
{/* 상자 안의 내용 */}
<div className={styles.usingFacilityTitle} >
{nowUsingReservation!.getBuildingName()}
</div>
<div className={styles.usingFacilityTitle}>
{nowUsingReservation!.getFacilityName()}
</div>
<div style={{ height: '12px' }} />
<div className={styles.usingTime}>
{nowUsingReservation!.getStartTime()} ~ {nowUsingReservation!.getEndTime()} 이용중
</div>
<div style={{ height: '12px' }} />
<div style={{ width: '100%', display: 'flex', justifyContent: 'flex-end'}}>
<Button
variant="contained"
style={{ backgroundColor: '#EDEBE7', color: '#959494', fontWeight : 'bold', boxShadow: 'none' }}
>이용 종료</Button>
</div>
</div> :
<div className={styles.noUsingFacility}>
<BlindsClosedSharp sx={{ color: '#959494', fontSize: '56px' }}/>
<div className={styles.noUsingText}>
현재 이용중인 시설물이 없어요.
</div>
</div>
}
</GrayBorderBox>

<Box sx={{ display: 'flex', gap: 2 }} >
{
facilityMenu.map((menu, index) => (
<div className={styles.menuContainer}>
<div className={styles.menuContainer} onClick={handleMenuClick}>
<GrayCircle key={index} radius={23} icon = {menu.icon} />
<div className={styles.menuTitle}>{menu.name}</div>
</div>
))
}
</Box>

<GrayBorderBox style={{
height : '180px'
}}>
<GrayBorderBox>
<div className={styles.boxTitle}>
즐겨찾기
</div>
</div>
<Box sx={{ height : '4px' }}/>
{myBookmarks.length > 0 ?
<>
{myBookmarks.map((bookmark, index) => (
<div key={index}>
<div style={{ display: 'flex', flexDirection: 'row', gap: '10px', alignItems: 'center' }}>
<Business sx={{ color: '#959494', paddingTop : '12px' }}/>
<div style={{ paddingTop: '12px' }}>{bookmark.getBuildingName()}</div>
<div style={{ paddingTop: '12px' }}>{bookmark.getFacilityName()}</div>
</div>
</div>
))}
</> :
<div style={{ display: 'flex', justifyContent: 'center', paddingTop: '12px' }}>즐겨찾기가 없어요.</div>}

</GrayBorderBox>
<GrayBorderBox style={{
height : '180px'
}}>
<GrayBorderBox>
<div className={styles.boxTitle}>
내 예약
</div>
<Box sx={{ height : '4px' }}/>
{myReservations.length > 0 ?
<>
{myReservations.map((reservation, index) => (
<div key={index}>
<div style={{ display: 'flex', flexDirection: 'row', gap: '10px', alignItems: 'center' }}>
<Business sx={{ color: '#959494', paddingTop : '12px' }}/>
<div>
<div style={{ paddingTop: '12px', fontSize : '10px' }}>{reservation.getDate()}</div>
<div style={{ display: 'flex', flexDirection: 'row', gap: '8px', alignItems: 'center' }}>
<div style={{ paddingTop: '0px' }}>{reservation.getBuildingName()}</div>
<div style={{ paddingTop: '0px' }}>{reservation.getFacilityName()}</div>
</div>
</div>

</div>
</div>
))}
</> :
<div style={{ display: 'flex', justifyContent: 'center', paddingTop: '12px' }}>예약내역이 없어요.</div>}
</GrayBorderBox>
<FacilityMenuModal>
<table>
<tbody>
<div className={styles.modalContent}>
{buildings.map((building, index) => (
<tr>
<div key={index}>
<div style={{ display: 'flex', flexDirection: 'row', gap: '10px', alignItems: 'center' }}>
<Business sx={{ color: '#959494', paddingTop : '12px' }}/>
<div>
<div style={{ paddingTop: '12px', fontSize : '10px' }}>{building.getName()}</div>
</div>

</div>
</div>
</tr>
))}
</div>x
</tbody>
</table>
</FacilityMenuModal>
</Container>
);
}
36 changes: 36 additions & 0 deletions frontend/dguonoff/src/types/Bookmark.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
export default class Bookmark {
private facilityName: string;
private facilityCode: string;
private buildingName: string;


constructor(facilityName: string = "", facilityCode: string = "", buildingName: string = "") {
this.facilityName = facilityName;
this.facilityCode = facilityCode;
this.buildingName = buildingName;
}

public getFacilityName(): string {
return this.facilityName;
}

public setFacilityName(facilityName: string): void {
this.facilityName = facilityName;
}

public getFacilityCode(): string {
return this.facilityCode;
}

public setFacilityCode(facilityCode: string): void {
this.facilityCode = facilityCode;
}

public getBuildingName(): string {
return this.buildingName;
}

public setBuildingName(buildingName: string): void {
this.buildingName = buildingName;
}
};

0 comments on commit 44d64ea

Please sign in to comment.