diff --git a/public/data/data.json b/public/data/data.json index 2b6ca87..ac0d99d 100644 --- a/public/data/data.json +++ b/public/data/data.json @@ -49,6 +49,62 @@ "image": "/images/cau-logo.png" } ], + "professorsList": [ + { + "id": 1, + "position": "교수", + "school": "중앙대학교", + "department": "데이터 베이스 시스템", + "email": "jh3095@naver.com", + "url": "https://www.naver.com", + "name": "김정빈" + }, + { + "id": 2, + "position": "교수", + "school": "중앙대학교", + "department": "데이터 베이스 시스템", + "email": "jh3095@naver.com", + "url": "https://www.naver.com", + "name": "최범수" + }, + { + "id": 3, + "position": "조교수", + "school": "고려대학교", + "department": "정보처리", + "email": "jh3095000@naver.com", + "url": "https://www.naver.com", + "name": "유인근" + }, + { + "id": 4, + "position": "교수", + "school": "연세대학교", + "department": "데이터분석", + "email": "jh3095000@gmail.com", + "url": "https://www.naver.com", + "name": "이민수" + }, + { + "id": 5, + "position": "교수", + "school": "상명대학교", + "department": "정보처리", + "email": "jh3095000@naver.com", + "url": "https://www.naver.com", + "name": "김범근" + }, + { + "id": 6, + "position": "교수", + "school": "성공대학교", + "department": "정보분석", + "email": "jh3095000@gmail.com", + "url": "https://www.naver.com", + "name": "최인빈" + } + ], "todoSectionList": [ { "id": 1, diff --git a/public/images/email-plus.svg b/public/images/email-plus.svg new file mode 100644 index 0000000..caddd51 --- /dev/null +++ b/public/images/email-plus.svg @@ -0,0 +1,3 @@ + + + diff --git a/public/images/search.svg b/public/images/search.svg new file mode 100644 index 0000000..1e2d3d4 --- /dev/null +++ b/public/images/search.svg @@ -0,0 +1,9 @@ + + + + + + + + + diff --git a/src/App.tsx b/src/App.tsx index 54be96c..0e44ec9 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,18 +1,37 @@ -import React from 'react' +import React, { useEffect, useState } from 'react' import { Store } from '@/store' import { MainSection } from '@/components/MainSection' import { SideMenuBar } from '@/components/SideMenuBar' import { TodoContainer } from '@/components/TodoContainer' +import { ProfessorCardProps } from '@/components/Professor/ProfessorCard' +import { NavBar } from '@/components/NavBar' import '@/style/fonts.scss' import '@/style/global.scss' +import axios from 'axios' + +const getData = async () => { + const response = await axios.get('/data/data.json') + return response.data.professorsList +} const App: React.FC = () => { + const [professorsList, setProfessorsList] = useState() + + useEffect(() => { + const fetchData = async () => { + const fetchedData = await getData() + setProfessorsList(fetchedData) + } + fetchData() + }, []) + return ( <>
+ {professorsList ? : <>} diff --git a/src/components/NavBar/index.tsx b/src/components/NavBar/index.tsx new file mode 100644 index 0000000..ac38811 --- /dev/null +++ b/src/components/NavBar/index.tsx @@ -0,0 +1,86 @@ +import React, { useEffect, useState } from 'react' +import { Professor } from '@/components/Professor' +// import { Restaurent } from '@/components/Restaurant' +import { ProfessorCardProps } from '@/components/Professor/ProfessorCard' +import { getCurrentDate } from '@/utils/time' +import './style.scss' + +export type ProfessorListProps = { + professorsList: ProfessorCardProps[] +} + +export const NavBar: React.FC = ({ professorsList }) => { + const [currentMenu, setCurrentMenu] = useState('') + const [renderSwitchNum, setRenderSwitchNum] = useState(0) + const [state, setState] = useState('') + const [hour, setHour] = useState(0) + const [minute, setMinute] = useState(0) + const [second, setSecond] = useState(0) + + useEffect(() => { + setTimeout(() => { + const [state, hour, minute, second] = getCurrentDate() + setState(state) + setHour(hour) + setMinute(minute) + setSecond(second) + }, 1000) + }, [second]) + + const clickNavMenu = (e) => { + if (e.target.innerHTML === '맛집 검색') { + setRenderSwitchNum(1) + } else if (e.target.innerHTML === '교수 검색') { + setRenderSwitchNum(2) + } + + if (currentMenu === e.target.innerHTML && renderSwitchNum !== 0) + setRenderSwitchNum(0) + setCurrentMenu(e.target.innerHTML) + } + + const renderSwitch = (num) => { + switch (num) { + case 1: + return <> + case 2: + return + default: + return + } + } + + return ( +
+
+
학사 공지
+
빈 강의실 찾기
+
+
+ {state} {hour}:{minute}:{second} +
+
+
+ 🌤 + -8℃ / + 14℃ +
+
clickNavMenu(e)} + > + 맛집 검색 +
+
clickNavMenu(e)} + > + 교수 검색 +
+
+ {renderSwitch(renderSwitchNum)} +
+ ) +} diff --git a/src/components/NavBar/style.scss b/src/components/NavBar/style.scss new file mode 100644 index 0000000..567f3e2 --- /dev/null +++ b/src/components/NavBar/style.scss @@ -0,0 +1,31 @@ +@use '@/style/package' as *; + +.nav-bar { + position: absolute; + top: 0; + left: 0; + width: 100%; + display: flex; + justify-content: space-between; + font-size: 1.5rem; +} + +.nav-bar-left, +.nav-bar-center, +.nav-bar-right { + display: flex; + justify-content: space-between; + align-items: center; + div { + margin: 1rem; + } +} + +.weather { + .lowest { + color: $color-blue-lighten-0; + } + .best { + color: $color-red-lighten-0; + } +} diff --git a/src/components/Professor/ProfessorCard/index.tsx b/src/components/Professor/ProfessorCard/index.tsx new file mode 100644 index 0000000..78ef3ba --- /dev/null +++ b/src/components/Professor/ProfessorCard/index.tsx @@ -0,0 +1,33 @@ +import React from 'react' +import './style.scss' + +export type ProfessorCardProps = { + id: number + position: string + school: string + department: string + email: string + url: string + name: string +} + +export const ProfessorCard = ({ professor }) => { + return ( +
+
+
+
+ {professor.name} + {professor.position} +
+ + arrowtriangle_right_square + +
+
{professor.school}
+
{professor.department}
+
{professor.email}
+
+
+ ) +} diff --git a/src/components/Professor/ProfessorCard/style.scss b/src/components/Professor/ProfessorCard/style.scss new file mode 100644 index 0000000..17bdb36 --- /dev/null +++ b/src/components/Professor/ProfessorCard/style.scss @@ -0,0 +1,52 @@ +@use '@/style/package' as *; + +.professor { + display: grid; + gap: 1rem 0; + background-color: #ffffff; + border-radius: 0.4rem; + padding: 0.6rem 0.8rem; + font-size: 1.5rem; + font-weight: 500; + letter-spacing: -0.05em; + line-height: 1.2; + color: $color-gray-900; + + .professor-header { + display: flex; + align-items: flex-end; + justify-content: space-between; + } + + .site { + width: 2.7rem; + top: 10rem; + } + + div { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .professor-name { + font-size: 2rem; + } + + .professor-position { + font-size: 1.2rem; + color: $color-gray-600; + } + + .professor-school { + font-size: 1.3rem; + } + + .professor-department { + font-size: 1.3rem; + } + + .professor-email { + font-size: 1.3rem; + } +} diff --git a/src/components/Professor/ProfessorSearch/index.tsx b/src/components/Professor/ProfessorSearch/index.tsx new file mode 100644 index 0000000..981abc9 --- /dev/null +++ b/src/components/Professor/ProfessorSearch/index.tsx @@ -0,0 +1,38 @@ +import React, { useState } from 'react' +import './style.scss' + +export type SearchBarProps = { + filterSelector: (value: string) => void +} + +export const SearchBar: React.FC = ({ filterSelector }) => { + const [professorInput, setProfessorInput] = useState('') + + const handleInput = (e) => { + setProfessorInput(e.target.value) + } + + const enterkey = (e) => { + if (e.keyCode == 13) { + filterSelector(e.target.value) + } + } + + const clickInput = () => { + filterSelector(professorInput) + } + return ( + <> + + + search + + + ) +} diff --git a/src/components/Professor/ProfessorSearch/style.scss b/src/components/Professor/ProfessorSearch/style.scss new file mode 100644 index 0000000..a2b99b9 --- /dev/null +++ b/src/components/Professor/ProfessorSearch/style.scss @@ -0,0 +1,25 @@ +@use '@/style/package' as *; + +.search-bar { + margin-bottom: 0.8rem; + display: flex; + align-items: center; + justify-content: space-between; + + input { + border: none; + width: 15rem; + font-size: 2.5rem; + background: bottom; + color: $color-white; + text-align: left; + &::placeholder { + color: $color-white; + } + } + + .search { + width: 2rem; + fill: $color-white; + } +} diff --git a/src/components/Professor/ProfessorSelector/index.tsx b/src/components/Professor/ProfessorSelector/index.tsx new file mode 100644 index 0000000..0998e1d --- /dev/null +++ b/src/components/Professor/ProfessorSelector/index.tsx @@ -0,0 +1,29 @@ +import React from 'react' +import './style.scss' + +export type SelectorBarProps = { + selector: string[] + filterSelector: (value: string) => void +} + +export const SelectorBar: React.FC = ({ + selector, + filterSelector, +}) => { + const onChangeSelect = (e) => { + filterSelector(e.target.value) + } + + return ( +
+ + chevron_down +
+ ) +} diff --git a/src/components/Professor/ProfessorSelector/style.scss b/src/components/Professor/ProfessorSelector/style.scss new file mode 100644 index 0000000..1e8b16f --- /dev/null +++ b/src/components/Professor/ProfessorSelector/style.scss @@ -0,0 +1,36 @@ +@use '@/style/package' as *; + +.select-bar { + margin-bottom: 1.2rem; + display: flex; + place-content: flex-end; +} + +.search-icon { + width: 1rem; +} + +.custom-select > select { + width: 14rem; + border-color: $color-white; + padding: 0.3rem; + font-size: 1.3rem; + border-radius: 0.4rem; + position: relative; + display: inline-block; + &:first-child { + margin-right: 1rem; + } + + &:ms-expand { + display: none; + } +} +.select-arrow { + position: relative; + font-size: 1.8rem !important; + top: 0.2rem; + right: 3rem; + width: 0; + height: 0; +} diff --git a/src/components/Professor/index.tsx b/src/components/Professor/index.tsx new file mode 100644 index 0000000..a3d95ee --- /dev/null +++ b/src/components/Professor/index.tsx @@ -0,0 +1,66 @@ +import React, { useState } from 'react' +import { ProfessorCard } from '@/components/Professor/ProfessorCard' +import { SearchBar } from '@/components/Professor/ProfessorSearch' +import { SelectorBar } from '@/components/Professor/ProfessorSelector' +import { ProfessorCardProps } from '@/components/Professor/ProfessorCard' +import './style.scss' + +export type ProfessorProps = { + professorsList: ProfessorCardProps[] +} + +export const Professor: React.FC = ({ professorsList }) => { + const [professorCard, setProfessorCard] = useState(professorsList) + const professorSchool = professorsList.map((professor) => professor.school) + const professorDepartment = professorsList.map( + (professor) => professor.department + ) + const changeProfessorSchool = (school) => { + setProfessorCard( + professorsList.filter((professor) => professor.school === school) + ) + } + + const changeProfessorDepartment = (department) => { + setProfessorCard( + professorsList.filter((professor) => professor.department === department) + ) + } + + const searchComment = (search) => { + setProfessorCard( + professorsList.filter( + (professor) => + professor.school.indexOf(search) > -1 || + professor.department.indexOf(search) > -1 || + professor.name.indexOf(search) > -1 + ) + ) + } + + return ( +
+
+ +
+
+ + +
+
+ {professorCard.map((professor) => ( + + ))} +
+
+ ) +} diff --git a/src/components/Professor/style.scss b/src/components/Professor/style.scss new file mode 100644 index 0000000..bf9c8a9 --- /dev/null +++ b/src/components/Professor/style.scss @@ -0,0 +1,23 @@ +@use '@/style/package' as *; + +.search-professor-menu { + position: absolute; + right: 2rem; + top: 5rem; + background-color: rgba($color-black, 0.5); + padding: 1.6rem; + width: 60rem; + height: 30rem; + border-radius: 0.8rem; + overflow-y: scroll; + + &::-webkit-scrollbar { + display: none; + } +} + +.profess-info { + display: grid; + grid-gap: 1rem; + grid-template-columns: repeat(auto-fill, minmax(16rem, 1fr)); +} diff --git a/src/utils/time.ts b/src/utils/time.ts index b4e4dad..55e01c3 100644 --- a/src/utils/time.ts +++ b/src/utils/time.ts @@ -46,3 +46,20 @@ export function getFormattedDate(date: Date, format: string): string { return formattedDate } + +export function getCurrentDate(): [string, number, number, number] { + const date = new Date() + const state = date.toLocaleTimeString().split(' ')[0] === '오전' ? 'AM' : 'PM' + + const dateFormat = (num):number => { + return num< 10 ? `0${num}` : num.toString() + } + + const [hour, minute, second] = [ + state === 'AM' ? dateFormat(date.getHours()) : dateFormat(date.getHours()-12), + dateFormat(date.getMinutes()), + dateFormat(date.getSeconds()) + ] + + return [state, hour, minute, second] +} diff --git a/tsconfig.json b/tsconfig.json index e876f6a..342ceeb 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -21,7 +21,7 @@ "removeComments": true, /* Do not emit comments to output. */ // "noEmit": true, /* Do not emit outputs. */ // "importHelpers": true, /* Import emit helpers from 'tslib'. */ - // "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ + "downlevelIteration": true, /* Provide full support for iterables in 'for-of', spread, and destructuring when targeting 'ES5' or 'ES3'. */ // "isolatedModules": true, /* Transpile each file as a separate module (similar to 'ts.transpileModule'). */ /* Strict Type-Checking Options */