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

[2단계 - 음식점 목록] 가브리엘(윤주현) 미션 제출합니다. #58

Merged
merged 182 commits into from
Mar 12, 2023
Merged
Show file tree
Hide file tree
Changes from 158 commits
Commits
Show all changes
182 commits
Select commit Hold shift + click to select a range
3ed37ec
docs: 기능 목록 문서 초안 작성
kangyeongmin Feb 28, 2023
bdb0d7a
chore: 아이콘 파일 폴더 정리
kangyeongmin Feb 28, 2023
0461b55
feat(css): style 파일 선언
kangyeongmin Feb 28, 2023
8d5315e
feat(Component): NavBar 구현
kangyeongmin Feb 28, 2023
82ad0fc
feat(index.js): NavBar 구현
kangyeongmin Feb 28, 2023
a1003f8
feat(Component): BottomSheet 구현
kangyeongmin Feb 28, 2023
1fb402c
feat(Component): AddRestaurant 구현
kangyeongmin Feb 28, 2023
cabae0e
feat(html): header 구현
kangyeongmin Feb 28, 2023
f0ae2a3
fix(css): 스크롤되게 수정
kangyeongmin Feb 28, 2023
656cd0b
refactor(components): Bottomsheet CustomElement로 수정
kangyeongmin Mar 2, 2023
7bcf414
refactor(components): NavBar CustomElement로 수정
kangyeongmin Mar 2, 2023
e6c2362
refactor(index.js): CustomElement로 수정
kangyeongmin Mar 2, 2023
aad5bbb
docs: 기능목록 요구사항 업데이트
kangyeongmin Mar 2, 2023
54e14f7
feat: AddRestaurant component 구현
kangyeongmin Mar 2, 2023
e665a08
feat: Restaurant type 정의
kangyeongmin Mar 2, 2023
df19090
feat: Restaurant model 정의
kangyeongmin Mar 2, 2023
593cad3
feat: Restaurant type 정의
kangyeongmin Mar 2, 2023
e7d3a30
feat(controller): 새로운 restaurant 객체를 추가한다
kangyeongmin Mar 2, 2023
1647117
feat(components): bottomsheet children을 인자로 받아 렌더링
kangyeongmin Mar 2, 2023
e4163c2
refactor: 변수명 수정
kangyeongmin Mar 2, 2023
98cf052
feat(controller): restaurant 객체들을 관리하고 localStorage에 저장한다
kangyeongmin Mar 2, 2023
aa590a4
feat(components): AddRestaurant 추가하기 클릭 이벤트 구현
kangyeongmin Mar 2, 2023
fc9fc20
feat(index.js): controller 호출 로직 구현
kangyeongmin Mar 2, 2023
80d20b3
feat(components): RestaurantList component 구현
kangyeongmin Mar 2, 2023
394586e
fix(components): bottomsheet 중복 생성 에러 수정 Co-authored-by: Gabriel Ju H…
kangyeongmin Mar 2, 2023
2e3721a
feat(components): RestaurantItem component 구현
kangyeongmin Mar 2, 2023
b59b412
feat(controller): localstorage에 있는 데이터를 복구한다
kangyeongmin Mar 2, 2023
45a8508
feat(index.js): RestaurantList 구현
kangyeongmin Mar 2, 2023
a0c8cc6
docs: 요구사항 문서 업데이트
kangyeongmin Mar 2, 2023
3856fdf
feat(controller): 이름순, 거리순으로 정렬하고 카테고리별로 필터링한다
kangyeongmin Mar 2, 2023
e496eeb
feat(components): SortingSelectBox 구현
kangyeongmin Mar 2, 2023
39439bc
feat(components): CategorySelectBox 구현
kangyeongmin Mar 2, 2023
4eabead
refactor: 탭 간격 조정
kangyeongmin Mar 2, 2023
155f2a3
feat(index.js): SelectingBox들 구현
kangyeongmin Mar 2, 2023
965c108
docs: 요구사항 문서 업데이트
kangyeongmin Mar 2, 2023
29e3c2d
fix: 닫힌 태그 에러 수정
kangyeongmin Mar 2, 2023
022c559
fix: 배열 에러 수정
kangyeongmin Mar 2, 2023
9aa353e
fix: css 에러 수정
kangyeongmin Mar 2, 2023
d73eb64
fix: 태그 에러 수정
kangyeongmin Mar 2, 2023
e4b71ee
fix: png파일 import 에러 수정
kangyeongmin Mar 3, 2023
3b3f57b
refactor: 파일 이름 수정
kangyeongmin Mar 3, 2023
022cab8
refactor: open할때 children 요소를 받도록 수정
kangyeongmin Mar 3, 2023
7ce6c68
refactor: 함수명 수정
kangyeongmin Mar 3, 2023
d7168de
refactor: 함수 역할 분리
kangyeongmin Mar 3, 2023
cdb78fc
refactor: sort 함수 리펙토링
kangyeongmin Mar 3, 2023
23e7fca
refactor: push 안쓰도록 함수 리펙토링
kangyeongmin Mar 3, 2023
bbfb993
refactor: 함수 분리
kangyeongmin Mar 3, 2023
44a8312
refactor: 탭 리펙토링
kangyeongmin Mar 3, 2023
2cfea7b
refactor: 함수명 수정
kangyeongmin Mar 3, 2023
c723169
refactor: 상태 변경 감지해서 자동으로 렌더링되게 수정
kangyeongmin Mar 3, 2023
915edf1
refactor: 함수 리펙토링
kangyeongmin Mar 3, 2023
3b9bb24
refactor: 함수 리펙토링
kangyeongmin Mar 3, 2023
0aa1de1
refactor: instance 확인하도록 함수 리펙토링
kangyeongmin Mar 3, 2023
f4ee89a
refactor: any 안쓰도록 함수 리펙토링
kangyeongmin Mar 3, 2023
c851dd7
chore: 안쓰는 파일 삭제
kangyeongmin Mar 3, 2023
0e710cf
test: component 렌더 테스트
kangyeongmin Mar 3, 2023
ac867a1
chore: test에 필요한 파일 정의
kangyeongmin Mar 3, 2023
c3e4dbf
refactor: Controller 제거 및 리스트 렌더링을 RestaurantList에 이전
gabrielyoon7 Mar 4, 2023
980834a
refactor: Controller 제거 및 카테고리와 필터링 키를 RestaurantList에 전달하는 기능 구현
gabrielyoon7 Mar 4, 2023
5614ae4
fix: 필터링과 정렬이 제대로 중첩되지 않던 문제 수정
gabrielyoon7 Mar 4, 2023
900423a
refactor: LocalStorage 관련 함수 모듈화
gabrielyoon7 Mar 4, 2023
52d4adc
refactor: html 주석 제거
gabrielyoon7 Mar 4, 2023
07efc8a
refactor: 불필요한 부정연산자 제거
gabrielyoon7 Mar 4, 2023
bdf5592
refactor: 기본 음식점 데이터 입력
gabrielyoon7 Mar 4, 2023
fe17f26
refactor: 불필요한 클래스 제거
gabrielyoon7 Mar 4, 2023
4b55356
refactor: 로컬스토리지 초기화용 버튼 추가 (테스트 후 제거 예정)
gabrielyoon7 Mar 4, 2023
09c1c9a
refactor: RestaurantItem 구조 개선
gabrielyoon7 Mar 4, 2023
211007d
refactor: 정렬 요청 메서드 분리
gabrielyoon7 Mar 4, 2023
0054c07
refactor: 카테고리 정렬 메서드 분리
gabrielyoon7 Mar 4, 2023
79f8890
refactor: 인터페이스 파일명 수정
gabrielyoon7 Mar 5, 2023
052bff0
refactor: 키 값을 계산된 프로퍼티 값으로 처리
gabrielyoon7 Mar 5, 2023
fdccfc7
refactor: closeBottomSheet 함수 분리
gabrielyoon7 Mar 5, 2023
5f2662f
refactor: 음식점 추가 함수 분리
gabrielyoon7 Mar 5, 2023
c9608c0
refactor: RestaurantType.ts를 Restaurant.ts로 변경
gabrielyoon7 Mar 5, 2023
9b1887d
refactor: state에 type-guard 적용
gabrielyoon7 Mar 5, 2023
6c847b9
refactor: any 제거
gabrielyoon7 Mar 5, 2023
f2f40e1
refactor: 렌더링 함수 분리
gabrielyoon7 Mar 5, 2023
51d9e33
refactor: 객체의 키를 한글로 사용하는 것을 switch로 대체함
gabrielyoon7 Mar 5, 2023
cc932e5
refactor: LocalStorage 폴더 이전
gabrielyoon7 Mar 5, 2023
5a8df6d
refactor: 기본 데이터 값 ts로 이전
gabrielyoon7 Mar 5, 2023
a1d5e26
refactor: LocalStorage를 js에서 ts 파일로 수정
gabrielyoon7 Mar 5, 2023
9a1c6ca
refactor: I접두사 추가
gabrielyoon7 Mar 5, 2023
4b17561
refactor: Proxy의 set함수 타입 지정 수정
gabrielyoon7 Mar 5, 2023
bac4952
refactor: LocalStorage 테스트 추가
gabrielyoon7 Mar 6, 2023
6522005
fix: 문자열이 공백으로만 이루어진 경우를 검사하는 로직 추가
gabrielyoon7 Mar 6, 2023
cacf940
fix: 링크 주소의 유효성을 검사하지 않던 문제 수정
gabrielyoon7 Mar 6, 2023
ab3367a
refactor: 불필요한 주석 제거
gabrielyoon7 Mar 6, 2023
5ca0ed3
refactor: error의 any 제거
gabrielyoon7 Mar 6, 2023
5d807f0
refactor: 새로운 형식에 맞는 테스트 구조로 개선
gabrielyoon7 Mar 6, 2023
290b677
test: 식당 추가 여부 확인 테스트 추가
gabrielyoon7 Mar 6, 2023
87e073f
refactor: 원할한 테스트를 위한 로컬 스토리지 비우기 버튼 제거
gabrielyoon7 Mar 6, 2023
f6c2666
refactor: RestaurantList의 state명 변경
gabrielyoon7 Mar 6, 2023
8d36ebc
refactor: AddRestaurant.ts의 비즈니스 로직 분리
gabrielyoon7 Mar 6, 2023
2a68f1f
refactor: 카테고리 키 값을 영어로 관리하도록 수정
gabrielyoon7 Mar 6, 2023
28cc47d
refactor: TCategory 추가
gabrielyoon7 Mar 6, 2023
f673de3
refactor: LocalStorage.ts 메서드 모듈화
gabrielyoon7 Mar 6, 2023
e238922
refactor: Storage 역할 및 메서드 이름 변경
gabrielyoon7 Mar 6, 2023
c371414
refactor: 기본 데이터의 link를 undefined로 변경
gabrielyoon7 Mar 6, 2023
43e929c
refactor: 불필요한 타입 명시 제거
gabrielyoon7 Mar 6, 2023
e726a2f
refactor: 필터 로직 개선
gabrielyoon7 Mar 6, 2023
2ebc2ae
refactor: 컴포넌트 조작 메서드를 분리
gabrielyoon7 Mar 7, 2023
1dab34c
refactor: 컴포넌트 조작 메서드를 분리
gabrielyoon7 Mar 7, 2023
1cedb76
refactor: RestaurantList 폴더 위치 이동
gabrielyoon7 Mar 7, 2023
f827af7
refactor: restaurant list의 render를 외부에서 지시하는 메서드 제작
gabrielyoon7 Mar 7, 2023
21b518c
refactor: Proxy 관리 객체를 모듈화
gabrielyoon7 Mar 7, 2023
22eeabe
refactor: addNewRestaurant 제거 및 addRestaurant으로 통합
gabrielyoon7 Mar 7, 2023
2a938d3
refactor: selectRestaurants 모듈화
gabrielyoon7 Mar 7, 2023
e973d04
refactor: 정렬, 필터링 관련 메서드 분리
gabrielyoon7 Mar 7, 2023
a91bff4
refactor: 로컬 스토리지 복구하는 메서드 모듈화
gabrielyoon7 Mar 7, 2023
ab2cfee
refactor: CATEGORY_NAME을 활용하여 출력 로직 개선
gabrielyoon7 Mar 7, 2023
a31f552
refactor: DISTANCE 모듈화
gabrielyoon7 Mar 7, 2023
a2d1a55
refactor: 일부 로직 모듈화
gabrielyoon7 Mar 7, 2023
bc9090a
refactor: 새로운 코드에 맞게 테스트 파일 수정
gabrielyoon7 Mar 7, 2023
c367915
feat: 즐겨찾기용 이미지 추가
gabrielyoon7 Mar 7, 2023
af1a9d9
docs: 리드미 규격 변경
gabrielyoon7 Mar 7, 2023
f4a8cd2
feat: 메뉴 탭 html 추가
gabrielyoon7 Mar 8, 2023
c647406
refactor: IListState 구현
gabrielyoon7 Mar 8, 2023
c0be794
refactor: 뷰와 프록시를 완벽하게 분리
gabrielyoon7 Mar 8, 2023
25fb9d4
refactor: 불필요한 함수 제거
gabrielyoon7 Mar 8, 2023
5737888
refactor: 불필요한 import 제거
gabrielyoon7 Mar 8, 2023
6d9fd25
feat: radio inputs를 클릭했을 때 이벤트 반응이 가능하도록 구현
gabrielyoon7 Mar 8, 2023
eacee08
refactor: 불필요한 바인딩 제거
gabrielyoon7 Mar 8, 2023
d568fe5
feat: 페이지 전환 기능 구현
gabrielyoon7 Mar 8, 2023
ce3a8a7
feat: 텍스트를 클릭해도 탭 전환이 되는 기능 구현
gabrielyoon7 Mar 8, 2023
2d060b4
feat: 즐겨찾기 등록 된 음식점은 별 마크의 색상이 채워지도록 개선
gabrielyoon7 Mar 8, 2023
f6817cf
chore: 랜덤 아이디 발급을 위한 uuid 패키지 설치
gabrielyoon7 Mar 8, 2023
dfae17a
chore: type-uuid로 교체
gabrielyoon7 Mar 8, 2023
70ada35
feat: uuid로 고유한 아이디 부여
gabrielyoon7 Mar 8, 2023
e6ccb03
refactor: 음식점 리스트 정렬 및 필터링 명령 함수 위치 변경
gabrielyoon7 Mar 8, 2023
0725292
refactor: RestaurantItem을 customeElement로 이전
gabrielyoon7 Mar 9, 2023
8c0b83c
feat: 즐겨찾기 등록/제거 기능 구현
gabrielyoon7 Mar 9, 2023
b92f610
feat: 리스트를 눌렀을 때, bottomSheet가 열리는 기능 구현
gabrielyoon7 Mar 9, 2023
870682e
refactor: 잘못된 엘리먼트 태그 수정
gabrielyoon7 Mar 9, 2023
0f6d8aa
fix: 즐겨찾기와 모달 여는 것이 동시에 되던 버그 수정
gabrielyoon7 Mar 9, 2023
ec13a7e
refactor: bottomSheet를 컴포넌트화
gabrielyoon7 Mar 9, 2023
91d40eb
refactor: 음식점 조회 함수 모듈화
gabrielyoon7 Mar 9, 2023
7e212f5
feat: BottomSheet에서 음식점 정보를 출력하도록 기능 구현
gabrielyoon7 Mar 9, 2023
97e9e02
refactor: CategoryImage 모듈화
gabrielyoon7 Mar 9, 2023
77ffd5a
refactor: 즐겨찾기 버튼 컴포넌트화
gabrielyoon7 Mar 9, 2023
f169db8
refactor: 불필요한 import 제거
gabrielyoon7 Mar 9, 2023
9089404
refactor: 즐겨 찾기 업데이트 하는 함수 모듈화
gabrielyoon7 Mar 9, 2023
411c1db
feat: 어트리뷰트 조작을 활용한 즐겨 찾기 렌더링 최신화 기능 구현
gabrielyoon7 Mar 9, 2023
de52f56
refactor: bottomSheet 내부 디자인 개선
gabrielyoon7 Mar 9, 2023
a04c950
feat: RestaurantView 디자인 구현
gabrielyoon7 Mar 9, 2023
2ef7d73
feat: RestauranView 닫기 버튼 구현
gabrielyoon7 Mar 9, 2023
a8a15b7
refactor: 어떤 음식점 버튼을 삭제해야 하는지 인자로 넘겨서 관리하는 기능 구현
gabrielyoon7 Mar 9, 2023
63eac7d
refactor: 음식점 객체를 관리하는 함수 위치를 변경
gabrielyoon7 Mar 9, 2023
c28becf
feat: 음식점 삭제 기능 구현
gabrielyoon7 Mar 9, 2023
34655f5
fix: 즐겨찾기 목록이 바로 반영이 되지 않는 버그 수정
gabrielyoon7 Mar 9, 2023
c5f7b28
feat: 탭 디자인 구현
gabrielyoon7 Mar 10, 2023
09337d0
refactor: 초기 상태 값을 변수로 분리함
gabrielyoon7 Mar 10, 2023
bee332f
refactor: bottomSheet 조작 메서드 리팩터링
gabrielyoon7 Mar 10, 2023
b279ca1
refactor: 일부 로직 개선
gabrielyoon7 Mar 10, 2023
6593966
refactor: 음식점 상태 업데이트 로직을 획일화 하는 작업
gabrielyoon7 Mar 10, 2023
ee53ead
docs: 요구사항 목록 최신화
gabrielyoon7 Mar 10, 2023
61b6d94
Merge branch 'gabrielyoon7' into step2
gabrielyoon7 Mar 10, 2023
59c114f
fix: 잘못된 merge 복구
gabrielyoon7 Mar 10, 2023
0883f22
fix: 잘못된 merge 복구
gabrielyoon7 Mar 10, 2023
5b8ffaf
fix: bottomSheet 스크롤 버그 수정
gabrielyoon7 Mar 10, 2023
9e3f3bf
feat: 메뉴 탭 간격 조정
gabrielyoon7 Mar 10, 2023
380eb14
feat: 탭 색상 전환하는 기능 구현
gabrielyoon7 Mar 11, 2023
604a2c4
feat: 즐겨찾기 음식점이 비어있는 경우 알림 구현
gabrielyoon7 Mar 11, 2023
fd1c57c
feat: 삭제하기 전 질문하는 기능 구현
gabrielyoon7 Mar 11, 2023
ea9d5ce
refactor: 메뉴탭 업데이트 하는 로직 개선
gabrielyoon7 Mar 11, 2023
1df668e
refactor: 레스토랑 상태에 인터페이스 적용
gabrielyoon7 Mar 11, 2023
63641f0
feat: 리스트가 비어있는 경우를 좀 더 상세히 알리는 기능 구현
gabrielyoon7 Mar 11, 2023
0944818
refactor: 개행 처리 및 미사용 메서드 제거
gabrielyoon7 Mar 11, 2023
b64d2f8
refactor: 개행 처리 및 미사용 메서드 제거
gabrielyoon7 Mar 11, 2023
c46a902
style: 코드 포맷팅
gabrielyoon7 Mar 11, 2023
0bd3a91
refactor: 불필요한 코드 제거
gabrielyoon7 Mar 11, 2023
5718c64
refactor: 객체 축약형 표시 사용
gabrielyoon7 Mar 11, 2023
b294d8a
refactor: 불필요한 타입 정의 개선
gabrielyoon7 Mar 11, 2023
12bd126
refactor: 즐겨찾기 속성 설정 시 검사하는 기능 추가
gabrielyoon7 Mar 11, 2023
2e61eb8
refactor: 데이터 속성 사용하기 적용
gabrielyoon7 Mar 11, 2023
e91ff3a
refactor: 불필요한 주석 제거
gabrielyoon7 Mar 11, 2023
b91ec37
feat: 음식점 정보 디자인 개선
gabrielyoon7 Mar 11, 2023
8a1ceaa
fix: 글자가 화면 바깥으로 나가는 문제를 수정
gabrielyoon7 Mar 11, 2023
92ae053
refactor: css파일 분리
gabrielyoon7 Mar 11, 2023
a6b7aaf
test: 음식점 추가 cypress 테스트
gabrielyoon7 Mar 11, 2023
b5c9d80
refactor: css클래스 값을 상수 처리
gabrielyoon7 Mar 11, 2023
a4b0cd3
refactor: 스타일 클래스 상수화
gabrielyoon7 Mar 11, 2023
a485a6d
refactor: 스타일 클래스를 상수화 처리
gabrielyoon7 Mar 11, 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
134 changes: 48 additions & 86 deletions docs/REQUIREMENTS.md
Original file line number Diff line number Diff line change
@@ -1,91 +1,53 @@
## 점심 뭐먹지 기능 요구 사항

- [ ] 음식점 목록을 확인할 수 있다.
- [ ] 카테고리별로 필터링해서 확인할 수 있다.
- [ ] 이름순으로 정렬해서 확인할 수 있다.
- [ ] 거리순으로 정렬해서 확인할 수 있다.
- [ ] 음식점 목록에 새로운 음식점을 추가할 수 있다.
- [ ] 음식점의 카테고리, 이름, 거리(도보 이동 시간), 설명, 참고 링크를 입력해서 추가할 수 있다.
- [ ] 카테고리, 거리는 셀렉트 박스, 이름/설명/참고 링크는 텍스트 인풋을 사용한다.
- [ ] 카테고리, 이름, 거리는 입력 필수.
- [ ] 카테고리는 "한식", "중식", "일식", "아시안", "양식", "기타" 중 하나를 선택한다.
- [ ] 거리는 캠퍼스로부터 도보로 걸리는 시간(분). 5, 10, 15, 20, 30 중 하나를 선택한다.
- [ ] 설명, 참고 링크는 옵션. 입력하지 않아도 음식점을 추가할 수 있어야 한다.
- [ ] 입력값이 잘못되었을 때 사용자에게 알려주는 방식은 자유롭게 구현한다.
- [ ] 새로고침해도 추가한 음식점 정보들이 유지되어야 한다.
- [x] 음식점 목록을 확인할 수 있다.
- [x] 카테고리별로 필터링해서 확인할 수 있다.
- [x] 이름순으로 정렬해서 확인할 수 있다.
- [x] 거리순으로 정렬해서 확인할 수 있다.
- [x] 음식점 목록에 새로운 음식점을 추가할 수 있다.
- [x] 음식점의 카테고리, 이름, 거리(도보 이동 시간), 설명, 참고 링크를 입력해서 추가할 수 있다.
- [x] 카테고리, 거리는 셀렉트 박스, 이름/설명/참고 링크는 텍스트 인풋을 사용한다.
- [x] 카테고리, 이름, 거리는 입력 필수.
- [x] 카테고리는 "한식", "중식", "일식", "아시안", "양식", "기타" 중 하나를 선택한다.
- [x] 거리는 캠퍼스로부터 도보로 걸리는 시간(분). 5, 10, 15, 20, 30 중 하나를 선택한다.
- [x] 설명, 참고 링크는 옵션. 입력하지 않아도 음식점을 추가할 수 있어야 한다.
- [x] 입력값이 잘못되었을 때 사용자에게 알려주는 방식은 자유롭게 구현한다.
- [x] 새로고침해도 추가한 음식점 정보들이 유지되어야 한다.
- [x] 음식점 상세 정보를 확인할 수 있다.
- [x] 카테고리, 이름, 거리, 설명, 참고 링크를 확인할 수 있다.
- [x] 음식점을 삭제할 수 있다.
- [x] 자주 가는 음식점을 추가하고 목록으로 확인할 수 있다.
- [x] 음식점 목록에서 자주 가는 음식점을 추가할 수 있다.
- [x] 음식점 상세 정보에서 자주 가는 음식점으로 추가할 수 있다.
- [x] 자주 가는 음식점 탭에서 추가한 음식점 목록을 확인할 수 있다.
- [x] 새로고침해도 추가한 정보들이 유지되어야 한다.

---

## 점심 뭐먹지 src 폴더 구조 및 역할 목록

# components

: 독립적이고 재사용가능한 ui요소들을 분리하고 정의한다.

1. NavBar

2. AddRestaurant

- 레스토랑 추가를 위한 ui와 인풋 태그들을 가진다.

3. BottomSheet

- 위로 올라갔다가 내려가는 애니메이션 효과를 가진다.

4. RestaurantItem

- 레스토랑 이름, 거리, 설명, 카테고리 정보를 담는다.

5. RestaurantList

- RestaurantItem을 리스트로 나열한다.

6. CategorySelectBox

- 카테고리를 선택한다.

7. SortingSelectBox

- 정렬순서를 선택한다.

# domain

## Controller.ts

- restaurant 객체들을 반환한다.
- 새로운 restaurant 객체를 추가한다.
- restaurant 객체들을 localStorage에 저장한다.
- localSorage에 있는 정보를 불러온다.
- restaurant 객체들을 이름순 및 거리순으로 정렬한다.
- restaurant 객체들을 카테고리별로 필터링한다.

## model

1. Restaurant

- restaurant 객체를 올바르게 생성한다.(inputValidator를 호출하며)

## inputValidator

- 카테고리, 이름, 거리(도보 이동 시간), 설명, 참고 링크에 대한 유효성을 검사한다.

# index.js

- customElement들을 정의한다.

## 구현 순서

[1]
NavBar => BottomSheet => form => 음식점 추가하는 기능 완성

[2]
음식점 리스트를 영구저장 기능 + 복구하는 기능

# 리팩토링 리스트

// any 없애기
// 은닉화
// util함수
// bottomSheet 열고 닫을 때, 위에 겹겹이 쌓이는 버그 존재
// map 안의 new 없애기
// sortRestaurnat 함수
## 점심 뭐먹지 폴더 구조 및 역할 목록

```
.
├─src
│ ├─assets
│ ├─components
│ │ ├─AddRestaurant // 식당 정보를 추가하는 폼
│ │ ├─BottomSheet // 모달
│ │ ├─FavoriteButton // 즐겨찾기 버튼
│ │ ├─MenuTab // 즐겨찾기 모아보기 버튼
│ │ ├─RestaurantItem // 식당 리스트에 표기될 카드
│ │ ├─RestaurantList // 식당 리스트
│ │ ├─RestaurantView // 식당의 상세 정보를 표시
│ │ ├─CategoryImage // 카테고리에 맞는 이미지를 태그로 제작해주는 기능
│ │ ├─CategorySelectBox // 카테고리를 선택하는 박스
│ │ ├─NavBar // 헤더
│ │ └─SortingSelectBox // 정렬 기준을 선택하는 박스
│ ├─constants
│ ├─css
│ ├─domain
│ │ ├─restaurant // 레스토랑 관련 도메인 로직 모음
│ │ └─restaurants // 레스토랑 데이터를 Proxy로 관리해주는 객체
│ ├─tools
│ └─type
└─index.html
```
27 changes: 18 additions & 9 deletions index.html
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,22 @@
<title>점심 뭐 먹지</title>
</head>

<body>
<nav-bar></nav-bar>
<section class="restaurant-filter-container">
<category-select-box></category-select-box>
<sorting-select-box></sorting-select-box>
</section>
<restaurant-list id="restaurantList"></restaurant-list>
<bottom-sheet id="bottomSheet" class="modal"></bottom-sheet>
</body>
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>점심 뭐 먹지</title>
</head>

<body>
<nav-bar></nav-bar>
<menu-tab></menu-tab>
<section class="restaurant-filter-container">
<category-select-box></category-select-box>
<sorting-select-box></sorting-select-box>
Comment on lines +21 to +22

Choose a reason for hiding this comment

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

여닫는 태그 사이에 아무것도 존재하지 않으면 <tagName />과 같이 간결하게 사용할 수도 있답니다!

Copy link
Member Author

Choose a reason for hiding this comment

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

step1에서 <tagName />을 사용하는 경우 오류가 발생하는 경우가 있어서 <tagName></tagName >으로 표기했습니다. insertAdjacentHtml으로 모달 내부를 그려주는 과정에서 잘못 된 위치에서 태그가 닫히는 등 여러 문제가 있었습니다 ㅠㅠ 지금은 insertAdjacentHtml을 제거하여 해당 문제가 없긴 하지만 당시에 그 원인이 <tagName />표기법 때문인지를 확신하기 어려워서 <tagName></tagName >로 교체하고 innerHtml을 쓰는 것으로 문제를 해결하였습니다.

gabrielyoon7@394586e

gabrielyoon7@d73eb64

</section>
<restaurant-list id="restaurantList"></restaurant-list>
<bottom-sheet id="bottomSheet" class="modal"></bottom-sheet>
</body>

</html>
5 changes: 4 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -51,5 +51,8 @@
"\\.(jpg|ico|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$": "<rootDir>/mocks/fileMock.js",
"\\.(css|less)$": "<rootDir>/mocks/fileMock.js"
}
},
"dependencies": {
"@types/uuid": "^9.0.1"
}
}
}
4 changes: 4 additions & 0 deletions src/assets/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ import categoryKorean from "../assets/category-korean.png";
import categoryWestern from "../assets/category-western.png";
import categoryEtc from "../assets/category-etc.png";
import addButton from "../assets/add-button.png";
import favoriteFilled from "../assets/favorite-icon-filled.png";
import favoriteLined from "../assets/favorite-icon-lined.png";

export {
categoryAsian,
Expand All @@ -14,4 +16,6 @@ export {
categoryWestern,
categoryEtc,
addButton,
favoriteFilled,
favoriteLined,
};
18 changes: 17 additions & 1 deletion src/components/BottomSheet/handleBottomSheet.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,24 @@
import BottomSheet from ".";

export const onClickBackdrop = () => {
const modalBackdrop = document.getElementById("modalBackdrop");
modalBackdrop?.addEventListener("click", () => {
closeBottomSheet();
});
};

export const openBottomSheet = (children: string) => {
const bottomSheet = document.getElementById("bottomSheet");
if (bottomSheet instanceof BottomSheet) {
bottomSheet.classList.add("modal--open");
bottomSheet.render(children);
}
};

export const closeBottomSheet = () => {
const bottomSheet = document.getElementById("bottomSheet");
if (bottomSheet instanceof BottomSheet) {
bottomSheet.close();
bottomSheet.classList.remove("modal--open");
bottomSheet.render("");
}
};
23 changes: 3 additions & 20 deletions src/components/BottomSheet/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import { onClickBackdrop } from "./handleBottomSheet";

class BottomSheet extends HTMLElement {
constructor() {
super();
Expand All @@ -10,26 +12,7 @@ class BottomSheet extends HTMLElement {
${children}
</div>
`;
this.onClickBackdrop();
}

onClickBackdrop() {
const modalBackdrop = document.getElementById("modalBackdrop");
modalBackdrop?.addEventListener("click", () => {
this.close();
});
}

open(children: string) {
const bottomSheet = document.getElementById("bottomSheet");
bottomSheet?.classList.add("modal--open");
this.render(children);
}

close() {
const bottomSheet = document.getElementById("bottomSheet");
bottomSheet?.classList.remove("modal--open");
this.render("");
onClickBackdrop();
}
}

Expand Down
9 changes: 9 additions & 0 deletions src/components/CategoryImage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import findImage from "../tools/findImage";

export const CategoryImage = (category: string) => `
<img
src="${findImage(category)}"
alt="${category}"
class="category-icon"
>
`;
7 changes: 2 additions & 5 deletions src/components/CategorySelectBox.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { categoryOptions } from "../domain/restaurant";
import { restaurants } from "../domain/restaurants";
import { TCategory } from "../type/TCategory";
import RestaurantList from "./RestaurantList";

class CategorySelectBox extends HTMLElement {
constructor() {
Expand Down Expand Up @@ -28,10 +28,7 @@ class CategorySelectBox extends HTMLElement {
}

filterCategory(key: TCategory) {
const restaurantList = document.getElementById("restaurantList");
if (restaurantList instanceof RestaurantList) {
restaurantList.filterBy(key);
}
restaurants.state.filter = key;
}
}

Expand Down
Empty file.
49 changes: 49 additions & 0 deletions src/components/FavoriteButton/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { updateFavorite } from "../../domain/restaurant";
import { restaurants } from "../../domain/restaurants";
import findImage from "../../tools/findImage";
import Storage from "../../tools/Storage";
import { renderRestaurantList } from "../RestaurantList/handleRestaurantList";

class FavoriteButton extends HTMLElement {
restaurantId: string | null;
favorite: string | null;
constructor() {
woowahan-cron marked this conversation as resolved.
Show resolved Hide resolved
super();
this.restaurantId = this.getAttribute("restaurant-id");
this.favorite = JSON.parse(this.getAttribute("favorite") as string);
this.render();
this.onClickFavoriteButton(this.restaurantId as string);
}
render() {
this.innerHTML = `
<img
src="${findImage(this.favorite ? "favoriteFilled" : "favoriteLined")}"
alt="즐겨찾기 버튼"
class="category-icon"
>
`;
}

static get observedAttributes() {
return ["favorite"];
}

attributeChangedCallback(name: string, oldValue: string, newValue: string) {
this.favorite = JSON.parse(newValue);

Choose a reason for hiding this comment

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

newValue는 오류가 나지 않을 것이란 보장을 받을 수 있나요?

Copy link
Member Author

Choose a reason for hiding this comment

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

보장 받기 어렵습니다. 반영하겠습니다.

this.render();
}

onClickFavoriteButton(id: string) {
this.addEventListener("click", (event) => {
event.stopPropagation();
updateFavorite(id);
const buttons = document.querySelectorAll(

Choose a reason for hiding this comment

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

✨ 깜짝 퀴즈

querySelectorquerySelectorAll의 차이점이 무엇인가요?

Copy link
Member Author

Choose a reason for hiding this comment

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

🙋‍♂️ 깜짝 대답

querySelector은 조건에 따라 탐색한 엘리먼트 중 가장 먼저 등장한 엘리먼트 1개를 반환합니다.
반면에 querySelectorAll은 조건에 따라 탐색한 엘리먼트 모두를 배열로 반환합니다.

`.favorite-button-${this.restaurantId}`
);
buttons.forEach((button) => {
button.setAttribute("favorite", `${!this.favorite}`);

Choose a reason for hiding this comment

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

웹 컴포넌트로 작성되는 부분이기는 하지만 favorite는 버튼이 가지는 기본 속성은 아닐 텐데요!
데이터 속성을 사용해 보는 것은 어떤가요? (사용하지 않아도 무방합니다. 취향 차이..)

Copy link
Member Author

Choose a reason for hiding this comment

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

보내주신 자료를 토대로 버튼의 favorite 속성을 데이터 속성으로 표기해봤는데, 엘리먼트의 dataset을 통해 접근을 할 수 있다는 것이 유용한 것 같습니다. 예를 들면 제가 임의로 어트리뷰트 명을 짓게되면, 해당 네이밍이 표준인지 비표준인지 헷갈릴 수 있게 되는 문제가 있는데, 데이터 속성은 이런 문제들을 일부 방지해주는 장점이 있는 것 같습니다.

다만 이번 미션에서는 기존에 적용해놨던 어트리뷰트들이 어디서 쓰이는지 파악하기 어려워진 것 같아서 즐겨찾기 기능에만 적용해보겠습니다.

});
});
}
}
export default FavoriteButton;
11 changes: 11 additions & 0 deletions src/components/MenuTab/handleMenuTab.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import { restaurants } from "../../domain/restaurants";

export const onChangeMenuTabs = () => {
const form = document.getElementById("menuTabForm");
form?.addEventListener("change", (event) => {
if (event.target instanceof HTMLInputElement) {
const newMenu = event.target.value;
restaurants.state.menuTab = newMenu;

Choose a reason for hiding this comment

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

newMenu 값은 8번째 줄 이후로 참조되지 않는다면 굳이 선언하여 사용할 필요가 있을까요?

Suggested change
const newMenu = event.target.value;
restaurants.state.menuTab = newMenu;
restaurants.state.menuTab = event.target.value;

Copy link
Member Author

Choose a reason for hiding this comment

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

새로 선택된 탭이라는 것을 명시하기 위해 newMenu를 선언했었는데, menuTab에 들어가는 것이 당연히 새로운 탭이라고 생각해보면 불필요한 조치였던 것 같습니다.

}
});
};
24 changes: 24 additions & 0 deletions src/components/MenuTab/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { onChangeMenuTabs } from "./handleMenuTab";

class MenuTab extends HTMLElement {
constructor() {
super();
this.render();
onChangeMenuTabs();
}
render() {
this.innerHTML = `
<form id="menuTabForm" class="d-flex justify-content-between mx-2">
<label class="tab-menu w-100 text-center py-1">
<input type="radio" name="tab-menu" value="tab-all" checked>
모든 음식점
</label>
<label class="tab-menu w-100 text-center py-1">
<input type="radio" name="tab-menu" value="tab-favorites">
자주 가는 음식점
</label>
</form>
`;
}
}
export default MenuTab;
6 changes: 2 additions & 4 deletions src/components/NavBar.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { addButton } from "../assets";
import BottomSheet from "./BottomSheet";
import { openBottomSheet } from "./BottomSheet/handleBottomSheet";

class NavBar extends HTMLElement {
constructor() {
Expand All @@ -22,10 +23,7 @@ class NavBar extends HTMLElement {
onClickAddIcon() {
const addIcon = document.getElementById("addIcon");
addIcon?.addEventListener("click", () => {
const bottomSheet = document.getElementById("bottomSheet");
if (bottomSheet instanceof BottomSheet) {
bottomSheet.open("<add-restaurant />");
}
openBottomSheet("<add-restaurant></add-restaurant>");
});
}
}
Expand Down
Loading