Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

시간표 페이지 퍼블리싱 #36

Merged
merged 47 commits into from
Jul 21, 2023
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
d4f346c
chore(package): moment 라이브러리 추가
Ubinquitous Jul 19, 2023
44b2d2e
refactor(schedule): schedule에서 calender로 라우터명 변경
Ubinquitous Jul 19, 2023
46007be
feat(timetable): 시간표 페이지 퍼블리싱
Ubinquitous Jul 19, 2023
f446ead
feat(atoms): custom select 컴포넌트 생성
Ubinquitous Jul 19, 2023
4aadf8d
feat(hooks): useDate hook 추가 (추후 기능 추가 예정)
Ubinquitous Jul 19, 2023
23ef4c2
chore(assets): down arrow svg 모듈로 추가
Ubinquitous Jul 19, 2023
4072f48
chore(timetable bar): 시간표 막대 움직이는 기능 구현
Ubinquitous Jul 19, 2023
f71079c
chore(timetable box): 시간표 컴포넌트 퍼블리싱, 추후 데이터 파싱 필요
Ubinquitous Jul 19, 2023
aae5572
feat(apis): 예외처리 함수 추가
Ubinquitous Jul 20, 2023
06dd18c
chore(httpClient): postInQuery method 추가
Ubinquitous Jul 20, 2023
bc61526
refactor(constant): constant type 선언, upper 리네이밍
Ubinquitous Jul 20, 2023
0a99f23
feat(oauth): 로그인 처리 페이지 퍼블리싱
Ubinquitous Jul 20, 2023
98514c5
chore(assets): loading gif 추가
Ubinquitous Jul 20, 2023
9b521d4
feat(api): oauth httpClient 세팅
Ubinquitous Jul 20, 2023
2d2b1a4
chore(httpClient): default import 세팅
Ubinquitous Jul 20, 2023
32b2a3f
feat(service): 로그인 관련 로직 세팅
Ubinquitous Jul 20, 2023
5405a85
refactor(httpClient): any 사용 지양
Ubinquitous Jul 20, 2023
5dd73ad
refactor(constant): token constant 사용
Ubinquitous Jul 20, 2023
c5b2ee1
refactor(httpClient): index 파일 이름 변경
Ubinquitous Jul 20, 2023
a8b8870
refactor(imageWithFallback): 기존 Image props도 받게함
Ubinquitous Jul 20, 2023
a2d95a2
chore(aside): user api 연결 및 값 제공, 조건부 렌더링
Ubinquitous Jul 20, 2023
8e098e3
chore(infomation box): 유저 api값 공급
Ubinquitous Jul 20, 2023
b44bcad
chore(assets): icons 하위로 디렉터리 이동
Ubinquitous Jul 20, 2023
46791a1
chore(assets): default profile 이미지 추가
Ubinquitous Jul 20, 2023
19903b3
chore(key): 리애트 쿼리 키 추가
Ubinquitous Jul 20, 2023
a922cb0
chore(router): mypage router 추가
Ubinquitous Jul 20, 2023
7220dca
chore(user): 유저 권한 키 추가
Ubinquitous Jul 20, 2023
ec0ac58
feat(helper): profileMaker 추가
Ubinquitous Jul 20, 2023
0829bd3
chore(modalStore): modal type 선언
Ubinquitous Jul 20, 2023
8dbcc2d
refactor(type): .type.ts로 모듈명 통일
Ubinquitous Jul 20, 2023
88c2759
chore(type): user type 지정
Ubinquitous Jul 20, 2023
7c390c6
feat(hooks): useModal 훅 선언
Ubinquitous Jul 20, 2023
28172ac
feat(hooks): useUser 훅 선언
Ubinquitous Jul 20, 2023
6a31c1b
feat(hooks): useWindow 훅 선언
Ubinquitous Jul 20, 2023
7758ca6
fix(adaptors): 디렉터리 내 adaptors 삭제 ( import 충돌 우려 )
Ubinquitous Jul 20, 2023
b5540cb
refactor(assets): SVG import 경로 수정
Ubinquitous Jul 20, 2023
ee77ac4
refactor(assets): image import 경로 수정
Ubinquitous Jul 20, 2023
1f2c774
fix(httpClient): adaptors 삭제 후 /apis로 직접 import
Ubinquitous Jul 20, 2023
3f9037b
refactor(assets): SVG import 경로 수정
Ubinquitous Jul 20, 2023
8adf374
chore(store): modalStore 선언
Ubinquitous Jul 20, 2023
5084427
chore(store): userStore 선언
Ubinquitous Jul 20, 2023
71ba888
fix(user): Student type으로 useQuery 타입 변경
Ubinquitous Jul 20, 2023
82523e7
feat(assets): 방향 회전 가능한 arrow 컴포넌트 추가
Ubinquitous Jul 21, 2023
9d7fd63
refactor(package): moment.js에서 day.js로 라이브러리 대체
Ubinquitous Jul 21, 2023
bc9b1bf
refactor(assets): svg 컴포넌트화
Ubinquitous Jul 21, 2023
829a152
refactor(assets): svg 컴포넌트화
Ubinquitous Jul 21, 2023
1c2d411
chore(listitem): svg 경로 변경
Ubinquitous Jul 21, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"eslint-config-next": "13.0.0",
"eslint-plugin-prettier": "^4.2.1",
"jest": "^29.3.1",
"moment": "^2.29.4",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moment 대신 요즘 더 많이 쓰이고 최적화도 더 야무진 dayjs 추천합니다
https://blog.hoseung.me/2022-03-13-dayjs-instead-of-momentjs/

"next": "13.4.4",
"prettier": "^2.8.8",
"react": "18.2.0",
Expand Down
9 changes: 9 additions & 0 deletions src/app/calender/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"use client";

import CalenderPage from "@/page/calender";

const Calender = () => {
return <CalenderPage />;
};

export default Calender;
9 changes: 0 additions & 9 deletions src/app/schedule/page.tsx

This file was deleted.

9 changes: 9 additions & 0 deletions src/app/timetable/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
"use client";

import TimeTablePage from "@/page/timetable";

const TimeTable = () => {
return <TimeTablePage />;
};

export default TimeTable;
114 changes: 114 additions & 0 deletions src/components/atoms/Select.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import DownArrow from "@/page/timetable/assets/DownArrow";
import color from "@/styles/color";
import { font } from "@/styles/font";
import React from "react";
import styled, { css } from "styled-components";

interface ISelectProps {
options: string[];
defaultOption: string;
label: string;
size?: string;
handler: React.Dispatch<React.SetStateAction<string>>;
}

const Select = ({
options,
defaultOption,
label,
size = "80px",
handler,
}: ISelectProps) => {
const [hover, setHover] = React.useState(true);

const toggleHandler = (option: string) => {
handler(option);
setHover(true);
};
return (
<StyledSelect
onMouseEnter={() => setHover(false)}
onMouseLeave={() => setHover(true)}
>
<StyledDefaultList size={size}>
<StyledDefaultListText label={label}>
{defaultOption}
</StyledDefaultListText>
<DownArrow width={12} height={8} />
</StyledDefaultList>
<StyledList hover={hover}>
{options.map((option) => (
<StyledListItem
key={option}
size={size}
label={label}
onClick={() => toggleHandler(option)}
>
{option}
</StyledListItem>
))}
</StyledList>
</StyledSelect>
);
};

const StyledSelect = styled.div`
width: fit-content;
cursor: pointer;
`;

const StyledDefaultList = styled.div<{ size: string }>`
display: flex;
align-items: center;
justify-content: center;
gap: 8px;
width: ${({ size }) => size};
padding: 6px 0;
border-radius: 4px;
background-color: ${color.white};
box-shadow: 4px 4px 10px 0 rgba(144, 144, 144, 0.15);

&:hover {
background-color: ${color.on_tertiary};
}
`;

const StyledDefaultListText = styled.div<{ label: string }>`
${font.context};
color: ${color.black};

&:after {
content: "${({ label }) => label}";
}
`;

const StyledList = styled.ul<{ hover: boolean }>`
position: absolute;
border-radius: 4px;
background-color: ${color.white};
padding: 6px 4px;

${({ hover }) =>
hover &&
css`
display: none;
`}
`;

const StyledListItem = styled.li<{ size: string; label: string }>`
width: calc(${({ size }) => size} - 8px);
padding: 6px 0 6px 8px;
border-radius: 4px;
${font.context};
background-color: ${color.white};

&:hover {
background-color: ${color.on_tertiary};
}

&:after {
content: "${({ label }) => label}";
}
`;

export default Select;
14 changes: 14 additions & 0 deletions src/hooks/useDate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import moment from "moment";
import "moment/locale/ko";

const useDate = () => {
const getHMSDate = () => {
const date = moment(new Date());
const HMSDate = moment(date).locale("ko").format("A h:mm:ss");
return HMSDate;
};

return { getHMSDate };
};

export default useDate;
4 changes: 2 additions & 2 deletions src/page/schedule/index.tsx → src/page/calender/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React from "react";
import styled from "styled-components";
import ScheduleBox from "./layouts/ScheduleBox";

const SchedulePage = () => {
const CalenderPage = () => {
return (
<Layout>
<Container>
Expand All @@ -27,4 +27,4 @@ const Container = styled.div`
gap: 8px;
`;

export default SchedulePage;
export default CalenderPage;
21 changes: 21 additions & 0 deletions src/page/timetable/assets/DownArrow.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import SVGAttribute from "@/global/types/SVGAttribute";
import React from "react";

const DownArrow = ({ width, height }: SVGAttribute) => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

개인적으로 얘는 특별히 4방향으로 회전할 수 있는 옵션이 props에 있으면 멋질 것 같습니다!

return (
<svg
width={width ?? 41}
height={height ?? 25}
viewBox="0 0 41 25"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M39.3422 1.86615C38.7783 1.30239 38.0135 0.985684 37.2161 0.985684C36.4187 0.985684 35.654 1.30239 35.09 1.86615L20.2045 16.7517L5.31896 1.86615C4.7518 1.31836 3.99218 1.01526 3.2037 1.02211C2.41523 1.02896 1.66099 1.34522 1.10344 1.90278C0.545881 2.46033 0.229623 3.21457 0.222771 4.00304C0.21592 4.79152 0.519026 5.55114 1.06681 6.1183L18.0784 23.1299C18.6424 23.6937 19.4071 24.0104 20.2045 24.0104C21.0019 24.0104 21.7666 23.6937 22.3306 23.1299L39.3422 6.1183C39.906 5.55437 40.2227 4.78962 40.2227 3.99222C40.2227 3.19482 39.906 2.43008 39.3422 1.86615Z"
fill="#727272"
/>
</svg>
);
};

export default DownArrow;
30 changes: 30 additions & 0 deletions src/page/timetable/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import Aside from "@/components/common/Aside";
import React from "react";
import styled from "styled-components";
import TimteTableBox from "./layouts/TimteTableBox";

const TimeTablePage = () => {
return (
<Layout>
<Container>
<TimteTableBox />
<Aside />
</Container>
</Layout>
);
};

const Layout = styled.div`
width: 100%;
display: flex;
justify-content: center;
`;

const Container = styled.div`
width: 76%;
display: flex;
justify-content: center;
gap: 8px;
`;

export default TimeTablePage;
129 changes: 129 additions & 0 deletions src/page/timetable/layouts/TimeTableBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
import useDate from "@/hooks/useDate";
import color from "@/styles/color";
import { font } from "@/styles/font";
import axios from "axios";
import moment from "moment";
import React from "react";
import styled from "styled-components";

const TimeTableBar = () => {
const [nowDate, setNowDate] = React.useState("");
const scrollRef = React.useRef<HTMLDivElement>(null);
const date = useDate();
const [test, setTest] = React.useState([
{ className: "", startTime: "", endTime: "" },
]);

React.useEffect(() => {
(async () => {
const res = await axios.get("https://bssm.kro.kr/api/timetable/2/2");
setTest(res.data.timetableList.WED);
})();
}, []);

React.useEffect(() => {
setInterval(() => {
const HMSDate = date.getHMSDate();
setNowDate(HMSDate);
}, 1000);
}, [date]);

// test
React.useEffect(() => {
if (scrollRef.current) {
scrollRef.current.scrollLeft = 500;
}
const { endTime } = test[0];
const endMoment = moment(endTime, "HH:mm:ss");
const nowMoment = moment(new Date(), "HH:mm:ss");

const duration = moment.duration(endMoment.diff(nowMoment));
const formattedDuration = moment
.utc(duration.as("milliseconds"))
.format("HH:mm:ss");
}, [test]);

return (
<Box>
<BarBox>
<BarDate>{nowDate}</BarDate>
<Bar />
</BarBox>
<BarList ref={scrollRef}>
{test.map((item, index) => (
<BarItem key={index}>
<BarItemText>test</BarItemText>
</BarItem>
))}
</BarList>
</Box>
);
};

const Box = styled.div`
display: flex;
width: 56vw;
flex-direction: column;
justify-content: center;
align-items: center;
`;

const BarList = styled.div`
display: flex;
width: 100%;
height: 300px;
overflow-x: scroll;
padding: 10px;
padding: 0 28vw;
border-radius: 6px;
position: relative;
gap: 8px;

&::-webkit-scrollbar {
display: none;
}
`;

const BarItem = styled.div`
width: 100px;
padding: 0 120px;
border-radius: 6px;
height: 80px;
display: flex;
overflow-x: scroll;
align-items: center;
justify-content: center;
position: relative;
background-color: ${color.white};
box-shadow: 0 0 10px 0 rgba(0, 0, 0, 0.1);
`;

const BarItemText = styled.span`
position: absolute;
`;

const BarBox = styled.div`
display: flex;
flex-direction: column;
position: absolute;

justify-content: center;
align-items: center;
margin-top: -30vh;
`;

const Bar = styled.div`
width: 5px;
border-radius: 5px;
background-color: ${color.gray};
height: 160px;
z-index: 1;
pointer-events: none;
`;

const BarDate = styled.span`
${font.context};
z-index: 1;
`;

export default TimeTableBar;
Loading