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

[1단계 - 지하철 노선도 미션] 미키(권세진) 미션 제출합니다. #21

Merged
merged 121 commits into from
Jun 19, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
121 commits
Select commit Hold shift + click to select a range
6d7ce7a
Update README.md
woowapark May 20, 2021
380f50b
chore: 프로젝트 초기 설정
SunYoungKwon May 20, 2021
d324d63
docs: 구현기능목록 작성
SunYoungKwon May 21, 2021
f1495aa
feat: Header 컴포넌트 추가
SunYoungKwon May 21, 2021
0a76ee9
feat: FlexContainer 컴포넌트 추가
SunYoungKwon May 21, 2021
a330294
feat: Navigation 컴포넌트 추가
SunYoungKwon May 21, 2021
cbaf82c
feat: CardTemplate 컴포넌트 추가
SunYoungKwon May 21, 2021
1db7c17
feat: Button 컴포넌트 추가
SunYoungKwon May 21, 2021
c7bf8e1
feat: Input 컴포넌트 추가
SunYoungKwon May 22, 2021
72e116e
chore: common, shared 폴더명에 @추가
SunYoungKwon May 22, 2021
7012435
feat: ListItem 컴포넌트 추가
SunYoungKwon May 22, 2021
5cd43f3
feat: Modal 컴포넌트 추가
SunYoungKwon May 22, 2021
6a70850
feat: Selectbox 컴포넌트 추가
SunYoungKwon May 22, 2021
0b89937
feat: ColorRadio 컴포넌트 추가
SunYoungKwon May 22, 2021
f9a7558
feat: Icon 컴포넌트들 추가
SunYoungKwon May 22, 2021
801550d
feat: Button 컴포넌트 disabled 스타일 추가
SunYoungKwon May 22, 2021
68ee17c
feat: Icon width 기본 값 설정
SunYoungKwon May 22, 2021
b66719b
fix: Props extends 타입 수정
SunYoungKwon May 22, 2021
9790239
feat: Signup 컴포넌트 추가
SunYoungKwon May 22, 2021
fe93d75
feat: Login 컴포넌트 추가
SunYoungKwon May 22, 2021
31cfed4
feat: Stations 컴포넌트 추가
SunYoungKwon May 22, 2021
032ee4e
feat: Lines 컴포넌트 추가
SunYoungKwon May 22, 2021
aaaab69
feat: ButtonOnLine 컴포넌트 분리
SunYoungKwon May 22, 2021
9ccd215
feat: Sections 컴포넌트 추가
SunYoungKwon May 23, 2021
c8d9722
chore: 앱 타이틀 및 설명 수정
SunYoungKwon May 23, 2021
3e4fadf
feat: SectionModal 컴포넌트 추가
SunYoungKwon May 23, 2021
f1d9f5e
feat: LinesModal 컴포넌트 추가
SunYoungKwon May 23, 2021
9e82783
feat: Lines 수정 버튼 추가
SunYoungKwon May 23, 2021
2f5bbe2
docs: 완료된 기능 목록 체크
SunYoungKwon May 24, 2021
be9ae06
fix: FlexContainer direction 속성이 적용되지 않던 현상
SunYoungKwon May 24, 2021
2b8767e
feat: NotificationInput 컴포넌트 추가
SunYoungKwon May 24, 2021
06c805f
feat: 회원가입 Input -> NotificationInput
SunYoungKwon May 24, 2021
da715e7
feat: 라우터 적용
SunYoungKwon May 24, 2021
e640a26
fix: 잘못된 파일명
SunYoungKwon May 24, 2021
eb2e53e
feat: ColorRadio 컴포넌트의 labelText 표시여부 전달
SunYoungKwon May 24, 2021
8dc98e9
feat: Home 컴포넌트 추가
SunYoungKwon May 24, 2021
fd2a84b
feat: API 상태 추가
SunYoungKwon May 24, 2021
5e8e8dc
feat: 회원가입 api 요청
SunYoungKwon May 25, 2021
15cfd91
docs: 완료된 구현기능 체크
SunYoungKwon May 25, 2021
b78f06b
feat: 로그인
SunYoungKwon May 25, 2021
c066175
feat: 로그인 상태에 따라 nav 메뉴 변경
SunYoungKwon May 25, 2021
6330465
feat: json-server 도입
SunYoungKwon May 25, 2021
47ccdfb
feat: stationSlice 추가
SunYoungKwon May 25, 2021
7664ac9
feat: 새로운 역 추가
SunYoungKwon May 25, 2021
6cd134e
feat: 지하철역 삭제
SunYoungKwon May 25, 2021
fac96d4
chore: json-server의 scripts 설정
SunYoungKwon May 26, 2021
7d60cc0
feat: 노선목록 조회
SunYoungKwon May 26, 2021
595955c
feat: 노선추가 버튼을 선택하면 노선추가모달을 화면에 띄운다
SunYoungKwon May 26, 2021
3899482
feat: 노선 추가
SunYoungKwon May 26, 2021
d7cecbc
feat: 노선 삭제
SunYoungKwon May 26, 2021
874a5c8
feat: 노선 수정
SunYoungKwon May 26, 2021
83bf5c7
feat: 선택된 api 정보를 sessionStorage에 저장
SunYoungKwon May 26, 2021
d12ff16
feat: 선택된 API에 따른 테마색 변경
SunYoungKwon May 26, 2021
5344760
feat: api 변경 및 로그아웃 시 redux 스토어 초기화
SunYoungKwon May 26, 2021
7ee4128
fix: header영역 위로 버튼이 올라오는 문제
SunYoungKwon May 26, 2021
5b196d7
feat: API 변경 시 로그아웃
SunYoungKwon May 26, 2021
a46cf1d
feat: 노선 삭제 시 confirm 추가
SunYoungKwon May 26, 2021
7a0bf08
fix: props 값 오류 수정 및 import 후 사용하지 않는 요소 제거
SunYoungKwon May 27, 2021
d04306a
feat: 회원가입
SunYoungKwon May 27, 2021
8233084
feat: 노선 생성 시 상/하행선을 같은 역으로 선택하면 오류 메시지 출력
SunYoungKwon May 27, 2021
cabd84d
chore: API별 테마 색 변경
SunYoungKwon May 27, 2021
2775974
feat: 노선 추가 시 모든 입력이 완료되었는지 검증
SunYoungKwon May 27, 2021
0a7873b
feat: 노선 수정 시 입력 완료 여부 검증
SunYoungKwon May 27, 2021
e1728e0
feat: 구간관리 페이지에서 노선 조회하기
SunYoungKwon May 27, 2021
3b23979
feat: 구간 추가 시 역 선택 오류 메세지 추가
SunYoungKwon May 27, 2021
a59414c
feat: 구간 추가
SunYoungKwon May 27, 2021
9fd9264
feat: 구간 삭제
SunYoungKwon May 27, 2021
b02c47e
docs: 추가 구현 기능 목록 작성
SunYoungKwon May 27, 2021
e791a66
refactor: axios.defaults의 baseURL, Authorization 설정
SunYoungKwon May 27, 2021
a2e0687
feat: 로그아웃 시 추가, 수정, 삭제 UI 숨김
SunYoungKwon May 27, 2021
3be30c8
feat: API요청 오류시 alert
SunYoungKwon May 27, 2021
bb30f6b
feat: Snackbar 구현
SunYoungKwon May 27, 2021
4071667
chore: _redirects 추가
SunYoungKwon May 27, 2021
180d4e6
fix: Storybook 오류 해결
SunYoungKwon May 28, 2021
3b83fc3
chore: chromatic 추가
SunYoungKwon May 28, 2021
e07619c
chore: dependency, devDependencies 정리
SunYoungKwon May 28, 2021
cfa1db3
test: 로그인 페이지 테스트
SunYoungKwon May 29, 2021
2271905
test: 역 관리 페이지 테스트
0307kwon May 30, 2021
28b9643
test: 회원가입 페이지 테스트
0307kwon May 30, 2021
099a13a
feat: 상,하행선 selectBox 접근성 추가
0307kwon May 30, 2021
0490f32
feat: 접근성을 위한 컴포넌트 추가
0307kwon May 30, 2021
c9f9b5c
refactor: dom element 변수에 '$' prefix 추가
0307kwon May 30, 2021
f3d27b8
test: 노선 관리 페이지 테스트 추가
0307kwon May 30, 2021
26ad27e
chore: msw 의존성 제거
0307kwon May 30, 2021
cb29b5c
refactor: 일관된 이벤트 타이핑
0307kwon May 30, 2021
37b1717
feat: sectionAddModal 취소 버튼을 누르면 modal 창이 닫히도록 수정
0307kwon May 30, 2021
dccb4be
refactor: signup page 커스텀 훅 적용
0307kwon Jun 1, 2021
eb229ad
refactor: useReadyToSubmit 커스텀 훅 구현
0307kwon Jun 1, 2021
d4e58d8
feat: 역 삭제시 confirm 메세지를 띄우도록 수정
0307kwon Jun 1, 2021
d4b31fd
refactor: lineAddModal input 커스텀 훅 적용
0307kwon Jun 1, 2021
79ff1d8
refactor: LineModifyModal Input 커스텀 훅 적용
0307kwon Jun 1, 2021
2ded649
refactor: api 선택 페이지 input 커스텀 훅 적용
0307kwon Jun 1, 2021
c900b55
refactor: SectionAddModal input 커스텀 훅 적용
0307kwon Jun 1, 2021
a3f761b
refactor: section 페이지 input 커스텀 훅 적용
0307kwon Jun 1, 2021
1ff1ad4
refactor: slice 폴더 추가
0307kwon Jun 1, 2021
62a6fd2
refactor: label text 상수화
0307kwon Jun 1, 2021
63dabaf
refactor: hooks/@shared 폴더 삭제
0307kwon Jun 1, 2021
efd30aa
refactor: 기본 api 주소 수정
0307kwon Jun 1, 2021
2c94d88
refactor: 파일의 끝에 개행을 넣음
0307kwon Jun 8, 2021
f075e52
chore: web-vital 라이브러리 삭졔
0307kwon Jun 8, 2021
7f249cf
refactor: axios instance를 만들어 intial 설정을 한 곳에서 관리
0307kwon Jun 8, 2021
a8b0dbe
refactor: VFC 타입을 도입
0307kwon Jun 8, 2021
e893487
refactor: Palette 상수 객체를 enum으로 변경
0307kwon Jun 8, 2021
3731bb0
refactor: 의미없는 propTypes 코드 제거
0307kwon Jun 8, 2021
9adf389
refactor: width -> size 로 prop name을 선언적으로 변경
0307kwon Jun 8, 2021
3cf15ff
fix: 로그인 직후 지하철 관리 권한이 주어지지 않던 현상 수정
0307kwon Jun 8, 2021
58f755d
refactor: CardTemplateTitle의 size를 enum으로 사용
0307kwon Jun 8, 2021
32d5fd2
fix: 구간을 추가하여도 구간 관리 페이지에 바로 적용되지 않던 현상 수정
0307kwon Jun 8, 2021
0155741
refactor: children 체크만을 위한 styled-compoent를 제거
0307kwon Jun 9, 2021
fa817b9
refactor: templateColor를 Palette 타입으로 제한
0307kwon Jun 9, 2021
94be72c
refactor: 공통된 분기문은 하나로 묶기
0307kwon Jun 9, 2021
6709a70
refactor: 의미없는 styled component 삭제
0307kwon Jun 9, 2021
85a236c
refactor: 좀 더 선언적인 prop 네임 사용
0307kwon Jun 9, 2021
207d9aa
refactor: API 정보들을 typescript utility type을 통해 타이핑
0307kwon Jun 9, 2021
5c6bacf
refactor: 배열으로 객체 키값에 접근하는 방식을 선언적으로 변경
0307kwon Jun 9, 2021
f2ce521
refactor: prop 네임을 좀 더 선언적으로 변경
0307kwon Jun 9, 2021
dd6a631
refactor: typescript utility type 적용
0307kwon Jun 9, 2021
bd9e084
refactor: login page 비즈니스 로직 분리
0307kwon Jun 9, 2021
8d21b71
refactor: form을 contextAPI로 활용
0307kwon Jun 11, 2021
0e75416
chore: 배포 설정
0307kwon Jun 11, 2021
648b2f8
refactor: 모달을 context api로 구현하여 외부 의존성을 제거
0307kwon Jun 15, 2021
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
25 changes: 25 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"env": {
"browser": true,
"es2021": true,
"node": true,
"jest/globals": true
},
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:@typescript-eslint/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 12,
"sourceType": "module"
},
"plugins": ["react", "@typescript-eslint", "jest"],
"rules": {
"react/prop-types": 0
}
}
25 changes: 25 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.

build-storybook.log

# dependencies
/node_modules
/.pnp
.pnp.js

# testing
/coverage

# production
/build

# misc
.DS_Store
.env.local
.env.development.local
.env.test.local
.env.production.local

npm-debug.log*
yarn-debug.log*
yarn-error.log*
9 changes: 9 additions & 0 deletions .prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"printWidth": 100,
"singleQuote": true,
"semi": true,
"trailingComma": "es5",
"useTabs": false,
"tabWidth": 2,
"arrowParens": "always"
}
8 changes: 8 additions & 0 deletions .storybook/main.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module.exports = {
stories: ['../src/**/*.stories.mdx', '../src/**/*.stories.@(js|jsx|ts|tsx)'],
addons: [
'@storybook/addon-links',
'@storybook/addon-essentials',
'@storybook/preset-create-react-app',
],
};
2 changes: 2 additions & 0 deletions .storybook/preview-body.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
<div id="modal-root"></div>
<div id="snackbar-root"></div>
25 changes: 25 additions & 0 deletions .storybook/preview.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { Provider } from 'react-redux';
import { BrowserRouter } from 'react-router-dom';
import GlobalStyle from '../src/Global.styles';
import store from '../src/redux/store';

export const parameters = {
actions: { argTypesRegex: '^on[A-Z].*' },
controls: {
matchers: {
color: /(background|color)$/i,
date: /Date$/,
},
},
};

export const decorators = [
(Story) => (
<Provider store={store}>
<GlobalStyle />
<BrowserRouter>
<Story />
</BrowserRouter>
</Provider>
),
];
75 changes: 74 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,75 @@
# react-subway-map
⚛️ React 지하철 노선도 관리 페이지

# 🚇 지하철 노선도 - 레벨2 종합세트 & 테스트

# 미션 목표

- 레벨 2에서 학습한 컴포넌트 기반 개발, 상태 관리 방법에 대한 내용을 전반적으로 복습하며 적용하는 연습을 합니다.
- React에 관한 개념을 전반적으로 복습하며 적용해봅니다.
이번 미션에서 React와 관련한 추가 개념은 다루지 않습니다.
- 테스트를 고려하며 개발하는 연습을 합니다.
- 백엔드 개발자와 협업하기 위한 커뮤니케이션 경험을 쌓습니다.

# 미션 진행 방식

- 프론트엔드 페어 운영 방식 및 프론트엔드 리뷰 프로세스는 동일합니다.
- step1은 페어로 진행, step2는 개별로 진행
- 각 step당 1번씩 리뷰어에게 PR로 리뷰 요청
- 백엔드 개발자와의 협업 경험을 위해 백엔드 크루들이 협업 페어로 매칭됩니다.
- 프론트엔드 1 페어당 백엔드 2 페어가 매칭됩니다. (프론트 크루 2명 + 백엔드 크루 4명)
- 매칭된 백엔드 크루들과 배포 일정, API 설계 논의 일정 등을 자율적으로 논의해 진행해주세요.
- 백엔드 크루들의 API가 배포 완료되기 전까지는 [API명세 문서](https://woowacourse.github.io/atdd-subway-fare/)를 확인하여 개발을 먼저 진행합니다.

---

# 미션 요구사항

각 step의 상세 요구사항은 다음 페이지를 확인해주세요.

## step1) 협업 논의 + 테스트 코드와 함께 지하철 노선도 관리 페이지 기본 구현

```
구현 마감은 5/27(목) 입니다. 원활한 협업이 될 수 있도록 일정을 잘 협의해주세요 :)
```

<br/>

**협업 요구사항**

- 백엔드 페어와 협업을 위해 필요한 사항들을 논의합니다.
- step1에서 사용할 API의 배포 일정, 이후 step2에서의 추가 개발을 위한 설계 논의, 그 외 필요한 사항들 있는 지 확인
- <span class="highlight-cyan">배포한 API 4개 중 하나를 무작위로 연결</span>하더라도 어플리케이션이 정상 동작해야 합니다. - 무작위 연결을 확인해볼 수 있는 방법은 페어와 자율적으로 결정합니다. (단, 코드를 직접 수정해야 하는 방법은 제외)
<br/>

**구현 요구사항**

- [요구사항 명세](./REQUIREMENTS.md)를 작성합니다.
- <span class="highlight-cyan">상태 관리 방법을 스스로 선택</span>합니다. 선택한 상태 관리 방법이 적절하다고 생각한 이유를 명시해주세요.
- 레벨 1에서 구현했던 기능들을 React로 다시 구현해보는 작업입니다. 레벨 1에서 개발했던 어플리케이션을 다시 확인해보세요.
<br/>

**테스트 요구사항**

- 각 기능별로 <span class="highlight-cyan">테스트 코드를 반드시 포함</span>합니다.

---

## step2) 백엔드 개발자와 함께 추가 기능 구현

```
구현 마감은 6/3(목) 입니다. 원활한 협업이 될 수 있도록 일정을 잘 협의해주세요 :)
```

**협업 요구사항**

- 백엔드 개발자와 API 설계 논의부터 함께합니다.
- <span class="highlight-cyan">배포한 API 4개 중 하나를 무작위로 연결</span>하더라도 어플리케이션이 정상 동작해야 합니다.
- 무작위 연결을 확인해볼 수 있는 방법은 페어와 자율적으로 결정합니다. (단, 코드를 직접 수정해야 하는 방법은 제외)
- (기본) 전체보기 기능을 추가로 구현합니다.
- 백엔드 API 신규 개발이 필요합니다. 새로 만들어야 하는 API 명세를 함께 논의하며 개발합니다.
- (선택) 경로 찾기 기능을 추가로 구현합니다.
- 이미 개발되어 있는 백엔드 API가 있습니다. 기존의 API 명세를 확인하고 수정이 필요한 부분이 있는 지 논의하며 개발합니다.

**구현 요구사항**

- 추가 기능을 위한 UI는 직접 설계하고 만듭니다.
95 changes: 95 additions & 0 deletions REQUIREMENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# 구현기능

## UI 구성

- [x] Header
- [x] Navigation
- [x] CardTemplate
- [x] Button
- [x] Input
- [x] NotificationInput
- [x] ListItem
- [x] Modal
- [x] SelectBox
- [x] ColorRadio

## 로그인 & 회원가입

- [x] 회원가입 화면을 구성한다.
- [x] 이메일을 입력받는다.
- 이메일 형식을 검사한다.
- 이메일 중복을 확인한다.
- [x] 나이를 입력 받는다.
- 1 ~ 150 사이의 정수만 입력 가능하다.
- [x] 비밀번호를 입력 받는다.
- 비밀번호는 4~20자 사이여야 한다.
- 비밀번호는 숫자, 영문으로 이루어져야 한다.
- [x] 비밀번호 확인을 입력한다.
- [x] 모든 입력이 올바르게 완료된 경우 회원가입 버튼을 활성화한다.
- [x] 회원가입 할 수 있다.

- 회원가입을 실패하는 경우 alert 메세지를 띄운다.
- 회원가입을 완료하면 로그인 페이지로 이동한다.

- [x] 로그인 화면을 구성한다.
- [x] 사용자는 로그인 할 수 있다.
- 로그인 완료 시 역 관리 페이지로 이동한다.
- 로그인 완료 시 navigation의 로그인 버튼을 로그아웃 버튼으로 변경한다.
- [x] 회원가입 페이지로 이동하는 링크가 존재한다.

## 역 관리

- [x] 역 관리 페이지를 구성한다.
- [x] 지하철 역 목록을 조회한다.
- [x] 새로운 역을 추가할 수 있다.
- 역 이름은 2~20자 사이의 한글 또는 숫자이다.
- 기존에 존재하는 역과 중복된 이름을 사용할 수 없다.
- [x] 역을 삭제할 수 있다.
- 삭제 전 사용자에게 `confirm`을 받는다.
- 노선에 등록된 역은 삭제할 수 없다.

## 노선 관리

- [x] 노선 관리 페이지를 구성한다.
- [x] 지하철 노선 목록을 조회한다.
- [x] 노선 생성 버튼을 선택 시 노선 생성 모달이 나타난다.
- [x] 노선 이름을 입력받는다.
- 노선 이름은 2~10자 사이의 숫자 및 한글이다.
- 노선 이름은 공백을 포함하지 않는다.
- [x] 상행 종점과 하행 종점을 선택할 수 있다.
- 상행 종점과 하행 종점은 같은 역일 수 없다.
- [x] 노선의 거리를 입력받는다.
- 거리는 1 이상의 정수이다.
- [x] 노선 색상을 입력받는다.
- 기존 노선에 사용된 색상은 선택할 수 없다.
- [x] 새로운 노선을 등록할 수 있다.
- [x] 노선을 삭제할 수 있다.
- 삭제 전 사용자에게 `confirm`을 받는다.
- [x] 노선 수정 버튼 선택 시 노선 수정 모달이 나타난다.

## 구간 관리

- [x] 구간 관리 페이지를 구성한다.
- [x] 선택된 노선의 구간을 조회한다.
- [x] 구간 추가 버튼을 선택하는 경우, 구간 추가 모달이 나타난다.
- [x] 상행역과 하행역을 입력받는다.
- 하나의 노선에 중복된 역이 존재할 수 없다.
- 상행역과 하행역 중 하나의 역은 이미 구간에 추가되어있는 역이여야한다.
- 하나의 노선에 갈래길이 생길 수 없다.
- [x] 구간의 거리를 입력받는다.
- 1이상의 정수이다.
- 기존 구간의 거리 미만이어야 한다.
- 모든 입력이 올바르게 완료된 경우 확인 버튼이 활성화된다.
- [x] 구간을 추가할 수 있다.
- [x] 구간을 삭제할 수 있다.
- 노선에 최소 2개의 역이 존재해야한다.
- 삭제 전 사용자에게 `confirm`을 받는다.

## 기타

- [x] 추가, 수정, 삭제 요청에 사용자 인증 토큰 추가하기
- [x] 로그인 하지 않은 사용자에게 추가, 수정, 삭제를 위한 UI 숨기거나 비활성화
- [x] API요청 실패 시 오류 메세지 나타내기
- [x] 스낵바
- [ ] 로딩 UI 구현
- [ ] 에러 UI 구현
44 changes: 44 additions & 0 deletions db.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
{
"login": {
"email": "sun@test.com",
"password": "123445"
},
"stations": [
{
"name": "다음페이지?",
"id": 8
},
{
"name": "성신여대입구역",
"id": 9
},
{
"name": "와아앙",
"id": 10
},
{
"name": "밍키역",
"id": 11
}
],
"lines": [
{
"name": "67호선",
"color": "#10B981",
"id": 6
},
{
"name": "58호선",
"color": "#FB923C",
"id": 7
},
{
"name": "99호선",
"upStationId": 10,
"downStationId": 0,
"distance": 100000,
"color": "#A78BFA",
"id": 8
}
]
}
Loading