@uniai-fe/uds-templates 0.1.20 → 0.1.21
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/styles.css +2 -2
- package/package.json +7 -3
- package/src/auth/login/jotai/user.ts +13 -0
- package/src/auth/login/types/api.ts +229 -0
- package/src/auth/login/types/form.ts +1 -0
- package/src/auth/login/types/index.ts +4 -0
- package/src/auth/signup/markup/VerificationForm.tsx +3 -2
- package/src/cctv/apis/client.ts +61 -0
- package/src/cctv/apis/index.ts +2 -0
- package/src/cctv/apis/server.ts +188 -0
- package/src/cctv/components/Provider.tsx +47 -0
- package/src/cctv/components/__viewer.tsx +99 -0
- package/src/cctv/components/cam-list/Container.tsx +36 -0
- package/src/cctv/components/cam-list/Item.tsx +71 -0
- package/src/cctv/components/cam-list/index.tsx +7 -0
- package/src/cctv/components/index.tsx +13 -0
- package/src/cctv/components/pagination/Container.tsx +26 -0
- package/src/cctv/components/pagination/Control.tsx +29 -0
- package/src/cctv/components/pagination/Provider.tsx +204 -0
- package/src/cctv/components/pagination/buttons/Base.tsx +56 -0
- package/src/cctv/components/pagination/buttons/Next.tsx +34 -0
- package/src/cctv/components/pagination/buttons/Prev.tsx +34 -0
- package/src/cctv/components/pagination/index.tsx +25 -0
- package/src/cctv/components/pagination/list/Carousel.tsx +26 -0
- package/src/cctv/components/pagination/list/Container.tsx +30 -0
- package/src/cctv/components/pagination/list/Item.tsx +81 -0
- package/src/cctv/components/video/Container.tsx +13 -0
- package/src/cctv/components/video/Video.tsx +34 -0
- package/src/cctv/components/video/index.tsx +9 -0
- package/src/cctv/components/video/overlay/Container.tsx +15 -0
- package/src/cctv/components/video/overlay/Title.tsx +28 -0
- package/src/cctv/components/video/overlay/body/Container.tsx +13 -0
- package/src/cctv/components/video/overlay/body/Error.tsx +16 -0
- package/src/cctv/components/video/overlay/footer/Container.tsx +30 -0
- package/src/cctv/components/video/overlay/footer/OpenButton.tsx +19 -0
- package/src/cctv/components/video/overlay/header/CloseButton.tsx +14 -0
- package/src/cctv/components/video/overlay/header/Container.tsx +50 -0
- package/src/cctv/components/video/overlay/header/LiveState.tsx +21 -0
- package/src/cctv/components/video/overlay/index.tsx +24 -0
- package/src/cctv/components/viewer/Container.tsx +13 -0
- package/src/cctv/components/viewer/desktop/Container.tsx +38 -0
- package/src/cctv/components/viewer/desktop/Pagination.tsx +20 -0
- package/src/cctv/components/viewer/desktop/Placeholder.tsx +18 -0
- package/src/cctv/components/viewer/desktop/Video.tsx +83 -0
- package/src/cctv/components/viewer/index.tsx +12 -0
- package/src/cctv/components/viewer/mobile/Container.tsx +13 -0
- package/src/cctv/data/context.ts +22 -0
- package/src/cctv/data/index.ts +1 -0
- package/src/cctv/hooks/index.tsx +5 -0
- package/src/cctv/hooks/useCompanyData.tsx +39 -0
- package/src/cctv/hooks/useContext.ts +150 -0
- package/src/cctv/hooks/useRtcStream.ts +94 -0
- package/src/cctv/img/chevron-left.svg +3 -0
- package/src/cctv/img/chevron-right.svg +3 -0
- package/src/cctv/img/error.svg +4 -0
- package/src/cctv/img/viewer-close.svg +3 -0
- package/src/cctv/img/viewer-open.svg +6 -0
- package/src/cctv/index.scss +1 -0
- package/src/cctv/index.tsx +9 -0
- package/src/cctv/jotai/context.ts +9 -0
- package/src/cctv/jotai/index.ts +1 -0
- package/src/cctv/styles/cam-list.scss +32 -0
- package/src/cctv/styles/index.scss +5 -0
- package/src/cctv/styles/pagination.scss +77 -0
- package/src/cctv/styles/variables.scss +38 -0
- package/src/cctv/styles/video.scss +142 -0
- package/src/cctv/styles/viewer.scss +7 -0
- package/src/cctv/types/api.ts +166 -0
- package/src/cctv/types/carousel.ts +24 -0
- package/src/cctv/types/context.ts +68 -0
- package/src/cctv/types/index.ts +4 -0
- package/src/cctv/types/list.ts +94 -0
- package/src/cctv/utils/data.ts +40 -0
- package/src/cctv/utils/select.ts +62 -0
- package/src/index.tsx +3 -0
- package/src/modal/styles/base.scss +2 -2
- package/src/types/api.ts +43 -0
- package/src/types/index.ts +1 -0
- package/src/auth/login/types.ts +0 -2
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
import type { UtilQueryBaseParams } from "@uniai-fe/util-functions";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* CCTV; api getCompanyList params
|
|
5
|
+
* @property {string} domain API 요청 도메인(서버)
|
|
6
|
+
* @property {string} routeUrl Next.js app/api 이하 경로 url
|
|
7
|
+
* @property {string} [queryUrl] 백엔드 요청 url
|
|
8
|
+
* @property {URLSearchParams} searchParams api 요청 search params
|
|
9
|
+
*/
|
|
10
|
+
export interface API_Req_GetCompanyListParams extends Omit<
|
|
11
|
+
UtilQueryBaseParams,
|
|
12
|
+
"queryUrl"
|
|
13
|
+
> {
|
|
14
|
+
/**
|
|
15
|
+
* 백엔드 요청 url
|
|
16
|
+
*/
|
|
17
|
+
queryUrl?: string;
|
|
18
|
+
/**
|
|
19
|
+
* api 요청 search params
|
|
20
|
+
*/
|
|
21
|
+
searchParams: URLSearchParams;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* CCTV: 업체에 설치된 카메라 목록
|
|
26
|
+
* @property {string} cam_id 카메라 id코드
|
|
27
|
+
* @property {string} cam_name 카메라 별칭
|
|
28
|
+
* @property {boolean} cam_online 카메라 설치상태
|
|
29
|
+
* @property {string} [cam_rtc] 카메라 스트리밍 WebRTC 경로
|
|
30
|
+
* @property {string} [cam_rtcp] 카메라 RTCP 경로
|
|
31
|
+
*/
|
|
32
|
+
export interface API_Res_CctvCompanyCameraList {
|
|
33
|
+
// API 응답은 데이터-only 구조이므로 UI 전용 콜백은 포함하지 않는다.
|
|
34
|
+
/**
|
|
35
|
+
* 카메라 ID (번호)
|
|
36
|
+
*/
|
|
37
|
+
cam_id: string;
|
|
38
|
+
/**
|
|
39
|
+
* 카메라 이름
|
|
40
|
+
* ex) 1동, 2동, ..., 외부1, 외부2, ...
|
|
41
|
+
*/
|
|
42
|
+
cam_name: string;
|
|
43
|
+
/**
|
|
44
|
+
* 카메라 설치 상태
|
|
45
|
+
*/
|
|
46
|
+
cam_online: boolean;
|
|
47
|
+
/**
|
|
48
|
+
* RTC 경로
|
|
49
|
+
* https://{company_id}.rtc.uniai.com/cam{cam_id}
|
|
50
|
+
*/
|
|
51
|
+
cam_rtc?: string;
|
|
52
|
+
/**
|
|
53
|
+
* RTCP 경로
|
|
54
|
+
*/
|
|
55
|
+
cam_rtcp?: string;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* CCTV; 각 분야그룹의 업체목록
|
|
60
|
+
* @property {string} company_id 업체 id코드 (a.k.a site)
|
|
61
|
+
* @property {string} company_name 업체명
|
|
62
|
+
* @property {API_Res_CctvCompanyCameraList[]} cam_list 설치된 카메라 목록
|
|
63
|
+
*/
|
|
64
|
+
export interface API_Res_CctvCompanyList {
|
|
65
|
+
/**
|
|
66
|
+
* 업체 ID
|
|
67
|
+
*/
|
|
68
|
+
company_id: string;
|
|
69
|
+
/**
|
|
70
|
+
* 업체명
|
|
71
|
+
* - 농장, 부화장, 사료공장 등의 업체명
|
|
72
|
+
*/
|
|
73
|
+
company_name: string;
|
|
74
|
+
/**
|
|
75
|
+
* 업체 내에 설치된 카메라 목록
|
|
76
|
+
*/
|
|
77
|
+
cam_list: API_Res_CctvCompanyCameraList[];
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* CCTV; 각 분야의 그룹 목록
|
|
82
|
+
* @property {string} group_code 사육그룹 코드 (C, PS-Growing, PS-Laying, PS-Hatching, FeedFactory)
|
|
83
|
+
* @property {string} group_name 사육그룹 이름 (사육, 종계(육성), 종계(산란), 부화, 사료공장)
|
|
84
|
+
* @property {API_Res_CctvCompanyList[]} 그룹 하위 업체목록
|
|
85
|
+
*/
|
|
86
|
+
export interface API_Res_CctvCompanyGroup {
|
|
87
|
+
/**
|
|
88
|
+
* 그룹 코드
|
|
89
|
+
* - C: 사육농장
|
|
90
|
+
* - PS-Growing: 종계(육성)농장
|
|
91
|
+
* - PS-Laying: 종계(산란)농장
|
|
92
|
+
* - PS-Hatching: 부화장
|
|
93
|
+
* - FeedFactory: 사료공장
|
|
94
|
+
*/
|
|
95
|
+
group_code: string;
|
|
96
|
+
/**
|
|
97
|
+
* 그룹명
|
|
98
|
+
* - 사육
|
|
99
|
+
* - 종계(육성)
|
|
100
|
+
* - 종계(산란)
|
|
101
|
+
* - 부화
|
|
102
|
+
* - 사료공장
|
|
103
|
+
*/
|
|
104
|
+
group_name: string;
|
|
105
|
+
/**
|
|
106
|
+
* 그룹에 속한 업체 목록
|
|
107
|
+
*/
|
|
108
|
+
list: API_Res_CctvCompanyList[];
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
/**
|
|
112
|
+
* CCTV; 실시간 스트리밍 토큰 요청
|
|
113
|
+
* @property {string} company_id 업체 id코드
|
|
114
|
+
* @property {string} cam_id 카메라 id코드
|
|
115
|
+
* @property {string} username 사용자명
|
|
116
|
+
*/
|
|
117
|
+
export interface API_Req_CctvRtcToken {
|
|
118
|
+
company_id: string;
|
|
119
|
+
cam_id: string;
|
|
120
|
+
username: string;
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
/**
|
|
124
|
+
* CCTV; 실시간 스트리밍 토큰 응답
|
|
125
|
+
* @property {string} token 인증 토큰
|
|
126
|
+
*/
|
|
127
|
+
export interface API_Res_CctvRtcToken {
|
|
128
|
+
token: string;
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
/**
|
|
132
|
+
* CCTV; 스트리밍 토큰 응답
|
|
133
|
+
* @property {string} token JWT Bearer 토큰
|
|
134
|
+
* @property {string} [endpoint] 스트림 WHEP 엔드포인트 (없으면 cam_rtc 사용)
|
|
135
|
+
*/
|
|
136
|
+
export interface API_Res_CctvStreamToken {
|
|
137
|
+
/**
|
|
138
|
+
* JWT Bearer 토큰
|
|
139
|
+
*/
|
|
140
|
+
token: string;
|
|
141
|
+
/**
|
|
142
|
+
* 스트림 엔드포인트 주소 (선택)
|
|
143
|
+
*/
|
|
144
|
+
endpoint?: string;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* CCTV; 스트리밍 토큰 요청 파라미터
|
|
149
|
+
* @property {string} username 사용자 아이디
|
|
150
|
+
* @property {string} company_id 업체 id코드(site)
|
|
151
|
+
* @property {string} cam_id 카메라 id코드
|
|
152
|
+
*/
|
|
153
|
+
export interface API_Req_CctvStreamToken {
|
|
154
|
+
/**
|
|
155
|
+
* 사용자 아이디
|
|
156
|
+
*/
|
|
157
|
+
username: string;
|
|
158
|
+
/**
|
|
159
|
+
* 업체 ID (site)
|
|
160
|
+
*/
|
|
161
|
+
company_id?: string;
|
|
162
|
+
/**
|
|
163
|
+
* 카메라 ID
|
|
164
|
+
*/
|
|
165
|
+
cam_id: string;
|
|
166
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { MutableRefObject, ReactNode } from "react";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* CCTV Pagination Carousel Context 값 모양.
|
|
5
|
+
*/
|
|
6
|
+
export interface CctvPaginationCarouselContextValue {
|
|
7
|
+
viewportRef: MutableRefObject<HTMLDivElement | null>;
|
|
8
|
+
trackRef: MutableRefObject<HTMLUListElement | null>;
|
|
9
|
+
onPrev: () => void;
|
|
10
|
+
onNext: () => void;
|
|
11
|
+
moveTo: (index: number) => void;
|
|
12
|
+
registerItemCount: (count: number) => void;
|
|
13
|
+
currentIndex: number;
|
|
14
|
+
maxIndex: number;
|
|
15
|
+
isReachStart: boolean;
|
|
16
|
+
isReachEnd: boolean;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* CCTV Pagination Carousel Provider props.
|
|
21
|
+
*/
|
|
22
|
+
export interface CctvPaginationCarouselProviderProps {
|
|
23
|
+
children: ReactNode;
|
|
24
|
+
}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
import type { API_Res_CctvCompanyGroup } from "./api";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* CCTV; 컨텍스트 제공자 Props
|
|
5
|
+
* @property {string} [company_id] 업체 id코드 (default: undefined)
|
|
6
|
+
* @property {boolean} [isActiveFinder] 탐색기 활성화 여부 (default: true)
|
|
7
|
+
* @property {boolean} [isPopup] 팝업 모드 여부 (default: undefined | false)
|
|
8
|
+
*/
|
|
9
|
+
export interface CctvContainerProps {
|
|
10
|
+
/**
|
|
11
|
+
* 업체 id코드
|
|
12
|
+
*/
|
|
13
|
+
company_id?: string;
|
|
14
|
+
/**
|
|
15
|
+
* 탐색기 활성화 여부
|
|
16
|
+
*/
|
|
17
|
+
isActiveFinder?: boolean;
|
|
18
|
+
/**
|
|
19
|
+
* 팝업 모드 여부
|
|
20
|
+
*/
|
|
21
|
+
isPopup?: boolean;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* CCTV; 선택된 컨텍스트
|
|
26
|
+
* @property {string} [company_id] 선택된 업체 id코드
|
|
27
|
+
* @property {string} [cam_id] 선택된 카메라 id코드
|
|
28
|
+
*/
|
|
29
|
+
export interface CctvSelectedContext {
|
|
30
|
+
/**
|
|
31
|
+
* 선택된 업체 ID
|
|
32
|
+
* - index 또는 string
|
|
33
|
+
*/
|
|
34
|
+
company_id?: string;
|
|
35
|
+
/**
|
|
36
|
+
* 선택된 카메라 ID
|
|
37
|
+
* - index 또는 string
|
|
38
|
+
*/
|
|
39
|
+
cam_id?: string;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* CCTV; 실시간 영상보기 컨텍스트
|
|
44
|
+
* @property {string} [company_id] 선택된 업체 id코드
|
|
45
|
+
* @property {string} [cam_id] 선택된 카메라 id코드
|
|
46
|
+
* @property {string} [search] 검색 키워드 (입력값)
|
|
47
|
+
* @property {string} [filter] 검색 키워드 (필터값)
|
|
48
|
+
* @property {API_Res_CctvCompanyGroup[]} rawData 원본 데이터 배열
|
|
49
|
+
* @property {boolean} isFetching 데이터 로딩 상태
|
|
50
|
+
* @property {boolean} isError 데이터 에러 상태
|
|
51
|
+
*/
|
|
52
|
+
export interface CctvContext extends CctvSelectedContext {
|
|
53
|
+
username: string;
|
|
54
|
+
/**
|
|
55
|
+
* 검색 키워드 (입력값)
|
|
56
|
+
*/
|
|
57
|
+
search: string;
|
|
58
|
+
/**
|
|
59
|
+
* 검색 키워드 (필터값)
|
|
60
|
+
*/
|
|
61
|
+
filter: string;
|
|
62
|
+
/**
|
|
63
|
+
* 원본 데이터 배열
|
|
64
|
+
*/
|
|
65
|
+
rawData: API_Res_CctvCompanyGroup[];
|
|
66
|
+
isFetching: boolean;
|
|
67
|
+
isError: boolean;
|
|
68
|
+
}
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
API_Res_CctvCompanyCameraList,
|
|
3
|
+
API_Res_CctvCompanyGroup,
|
|
4
|
+
API_Res_CctvCompanyList,
|
|
5
|
+
} from "./api";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* CCTV; 업체 선택 - 카메라 정보
|
|
9
|
+
* @property {string} renderKey 렌더링 unique key
|
|
10
|
+
* @property {boolean} selected 카메라 선택 현황
|
|
11
|
+
* @property {Function} [onSelect] 카메라 선택 콜백 이벤트
|
|
12
|
+
* @property {string} cam_id 카메라 id코드
|
|
13
|
+
* @property {string} cam_name 카메라 별칭
|
|
14
|
+
* @property {boolean} cam_online 카메라 설치상태
|
|
15
|
+
* @property {string} [cam_rtc] 카메라 스트리밍 WebRTC 경로
|
|
16
|
+
* @property {string} [cam_rtcp] 카메라 RTCP 경로
|
|
17
|
+
*/
|
|
18
|
+
export interface CctvCompanyCameraList extends API_Res_CctvCompanyCameraList {
|
|
19
|
+
/**
|
|
20
|
+
* 카메라가 속한 업체 ID
|
|
21
|
+
*/
|
|
22
|
+
company_id?: string;
|
|
23
|
+
/**
|
|
24
|
+
* 카메라가 속한 업체명
|
|
25
|
+
*/
|
|
26
|
+
company_name?: string;
|
|
27
|
+
/**
|
|
28
|
+
* 렌더링 unique key
|
|
29
|
+
*/
|
|
30
|
+
renderKey: string;
|
|
31
|
+
/**
|
|
32
|
+
* 카메라 선택 현황
|
|
33
|
+
*/
|
|
34
|
+
selected: boolean;
|
|
35
|
+
/**
|
|
36
|
+
* 카메라 선택 콜백 이벤트
|
|
37
|
+
* @optional
|
|
38
|
+
*/
|
|
39
|
+
onSelect?: () => void;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* CCTV; 업체 선택 - 그룹 내 업체 UI props
|
|
44
|
+
* @property {string} renderKey 렌더링 unique key
|
|
45
|
+
* @property {boolean} selected 업체 선택 현황
|
|
46
|
+
* @property {Function} [onSelect] 업체 선택 콜백 이벤트
|
|
47
|
+
* @property {string} company_id 업체 id코드 (a.k.a site)
|
|
48
|
+
* @property {string} company_name 업체명
|
|
49
|
+
* @property {API_Res_CctvCompanyCameraList[]} cam_list 설치된 카메라 목록
|
|
50
|
+
* @property {boolean} [disabled] 업체 비활성화
|
|
51
|
+
*/
|
|
52
|
+
export interface CctvCompanyGroupItems extends API_Res_CctvCompanyList {
|
|
53
|
+
/**
|
|
54
|
+
* 렌더링 unique key
|
|
55
|
+
*/
|
|
56
|
+
renderKey: string;
|
|
57
|
+
/**
|
|
58
|
+
* 설치된 카메라 목록
|
|
59
|
+
*/
|
|
60
|
+
cam_list: CctvCompanyCameraList[];
|
|
61
|
+
/**
|
|
62
|
+
* 업체 선택 현황
|
|
63
|
+
*/
|
|
64
|
+
selected: boolean;
|
|
65
|
+
/**
|
|
66
|
+
* 업체 비활성화
|
|
67
|
+
* @optional
|
|
68
|
+
*/
|
|
69
|
+
disabled?: boolean;
|
|
70
|
+
/**
|
|
71
|
+
* 업체 선택 콜백 이벤트
|
|
72
|
+
* @optional
|
|
73
|
+
*/
|
|
74
|
+
onSelect?: () => void;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
/**
|
|
78
|
+
* CCTV; 업체 선택 - 그룹 UI props
|
|
79
|
+
* @property {string} renderKey 렌더링 unique key
|
|
80
|
+
* @property {CctvCompanyGroupItems[]} list 사육그룹 하위업체 목록
|
|
81
|
+
* @property {string} group_code 사육그룹 코드 (C, PS-Growing, PS-Laying, PS-Hatching, FeedFactory)
|
|
82
|
+
* @property {string} group_name 사육그룹 이름 (사육, 종계(육성), 종계(산란), 부화, 사료공장)
|
|
83
|
+
* @property {API_Res_CctvCompanyList[]} 그룹 하위 업체목록
|
|
84
|
+
*/
|
|
85
|
+
export interface CctvCompanyGroup extends API_Res_CctvCompanyGroup {
|
|
86
|
+
/**
|
|
87
|
+
* 렌더링 unique key
|
|
88
|
+
*/
|
|
89
|
+
renderKey: string;
|
|
90
|
+
/**
|
|
91
|
+
* 그룹 하위 업체의 UI props
|
|
92
|
+
*/
|
|
93
|
+
list: CctvCompanyGroupItems[];
|
|
94
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
API_Res_CctvCompanyGroup,
|
|
3
|
+
CctvCompanyCameraList,
|
|
4
|
+
CctvCompanyGroup,
|
|
5
|
+
CctvCompanyGroupItems,
|
|
6
|
+
} from "../types";
|
|
7
|
+
|
|
8
|
+
export function initCompanyList({
|
|
9
|
+
data,
|
|
10
|
+
pageCode,
|
|
11
|
+
}: {
|
|
12
|
+
data: API_Res_CctvCompanyGroup[];
|
|
13
|
+
pageCode?: string;
|
|
14
|
+
}) {
|
|
15
|
+
if (typeof data === "undefined" || !Array.isArray(data)) return [];
|
|
16
|
+
return data.map((group, group_index): CctvCompanyGroup => {
|
|
17
|
+
const RENDER_KEY_PREFIX = `page-${pageCode}/cctv/company-list/group_${group.group_code}`;
|
|
18
|
+
return {
|
|
19
|
+
renderKey: RENDER_KEY_PREFIX,
|
|
20
|
+
...group,
|
|
21
|
+
list: group.list.map((d): CctvCompanyGroupItems => {
|
|
22
|
+
const companyRenderKey = `${RENDER_KEY_PREFIX}/company_${d.company_id}`;
|
|
23
|
+
return {
|
|
24
|
+
...d,
|
|
25
|
+
renderKey: companyRenderKey,
|
|
26
|
+
selected: group_index === 0,
|
|
27
|
+
cam_list: d.cam_list.map(
|
|
28
|
+
(cam): CctvCompanyCameraList => ({
|
|
29
|
+
renderKey: `${companyRenderKey}/camera_${cam.cam_id}`,
|
|
30
|
+
...cam,
|
|
31
|
+
company_id: d.company_id,
|
|
32
|
+
company_name: d.company_name,
|
|
33
|
+
selected: false,
|
|
34
|
+
}),
|
|
35
|
+
),
|
|
36
|
+
};
|
|
37
|
+
}),
|
|
38
|
+
};
|
|
39
|
+
});
|
|
40
|
+
}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type {
|
|
2
|
+
CctvCompanyCameraList,
|
|
3
|
+
CctvCompanyGroup,
|
|
4
|
+
CctvCompanyGroupItems,
|
|
5
|
+
} from "../types";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* CCTV; 그룹 데이터 추출
|
|
9
|
+
* @util
|
|
10
|
+
* @property {CctvCompanyGroup[]} list CCTV 회사 그룹 리스트
|
|
11
|
+
* @property {string} groupCode 그룹 코드
|
|
12
|
+
* @returns {CctvCompanyGroup | undefined} 그룹 정보 객체 반환
|
|
13
|
+
*/
|
|
14
|
+
export const getGroup = (
|
|
15
|
+
list: CctvCompanyGroup[],
|
|
16
|
+
groupCode: string,
|
|
17
|
+
): CctvCompanyGroup | undefined =>
|
|
18
|
+
list.find(({ group_code }) => group_code === groupCode);
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* CCTV; 업체 데이터 추출
|
|
22
|
+
* @util
|
|
23
|
+
* @property {CctvCompanyGroup[]} list CCTV 회사 그룹 리스트
|
|
24
|
+
* @property {string} [companyId] 업체 ID
|
|
25
|
+
* @returns {CctvCompanyGroupItems | undefined} 업체 정보 객체 반환
|
|
26
|
+
*/
|
|
27
|
+
export const getCompany = (
|
|
28
|
+
list: CctvCompanyGroup[],
|
|
29
|
+
companyId?: string,
|
|
30
|
+
): CctvCompanyGroupItems | undefined =>
|
|
31
|
+
typeof companyId === "undefined" || !companyId
|
|
32
|
+
? undefined
|
|
33
|
+
: list
|
|
34
|
+
.flatMap(({ list }) => list)
|
|
35
|
+
.find(({ company_id }) => company_id === companyId);
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* CCTV; 카메라 목록 데이터 추출
|
|
39
|
+
* @util
|
|
40
|
+
* @property {CctvCompanyGroup[]} list CCTV 회사 그룹 리스트
|
|
41
|
+
* @property {string} [companyId] 업체 ID
|
|
42
|
+
* @returns {CctvCompanyCameraList[]} 카메라 목록 배열 반환
|
|
43
|
+
*/
|
|
44
|
+
export const getCamList = (
|
|
45
|
+
list: CctvCompanyGroup[],
|
|
46
|
+
companyId?: string,
|
|
47
|
+
): CctvCompanyCameraList[] => getCompany(list, companyId)?.cam_list || [];
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* CCTV; 카메라 데이터 추출
|
|
51
|
+
* @util
|
|
52
|
+
* @property {CctvCompanyGroup[]} list CCTV 회사 그룹 리스트
|
|
53
|
+
* @property {string} [companyId] 업체 ID
|
|
54
|
+
* @property {string} [camId] 카메라 ID
|
|
55
|
+
* @returns {CctvCompanyCameraList | undefined} 카메라 정보 객체 반환
|
|
56
|
+
*/
|
|
57
|
+
export const getCam = (
|
|
58
|
+
list: CctvCompanyGroup[],
|
|
59
|
+
companyId?: string,
|
|
60
|
+
camId?: string,
|
|
61
|
+
): CctvCompanyCameraList | undefined =>
|
|
62
|
+
getCamList(list, companyId).find(({ cam_id }) => cam_id === camId);
|
package/src/index.tsx
CHANGED
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
--modal-panel-width: 360px;
|
|
5
5
|
--modal-panel-max-width: calc(100vw - var(--spacing-padding-10, 32px) * 2);
|
|
6
6
|
--modal-panel-max-height: calc(100vh - var(--spacing-padding-10, 32px) * 2);
|
|
7
|
-
--modal-panel-bg: var(--color-
|
|
7
|
+
--modal-panel-bg: var(--color-surface-static-white);
|
|
8
8
|
--modal-panel-radius: var(--theme-radius-large-1);
|
|
9
9
|
--modal-panel-shadow: 0px 18px 40px rgba(8, 11, 30, 0.18);
|
|
10
10
|
--modal-border-color: var(--color-border-standard-cool-gray, #e4e5e7);
|
|
@@ -48,7 +48,7 @@
|
|
|
48
48
|
--modal-panel-max-height,
|
|
49
49
|
calc(100vh - var(--spacing-padding-10, 32px) * 2)
|
|
50
50
|
);
|
|
51
|
-
background-color: var(--modal-panel-bg, var(--color-
|
|
51
|
+
background-color: var(--modal-panel-bg, var(--color-surface-static-white));
|
|
52
52
|
border-radius: var(--modal-panel-radius, var(--theme-radius-large-1));
|
|
53
53
|
box-shadow: var(--modal-panel-shadow, 0px 18px 40px rgba(8, 11, 30, 0.18));
|
|
54
54
|
pointer-events: auto;
|
package/src/types/api.ts
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* API 응답; 에러 정보
|
|
3
|
+
* @property {string} field_name - 에러 필드 이름
|
|
4
|
+
* @property {string} message - 에러 메세지
|
|
5
|
+
*/
|
|
6
|
+
export interface API_Res_Error {
|
|
7
|
+
/**
|
|
8
|
+
* 에러 필드 이름
|
|
9
|
+
*/
|
|
10
|
+
field_name: string;
|
|
11
|
+
/**
|
|
12
|
+
* 에러 메세지
|
|
13
|
+
*/
|
|
14
|
+
message: string;
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* API 응답; 기본 구조
|
|
19
|
+
* - GET, POST, PUT, DELETE 등 모든 API 응답에 공통적으로 사용
|
|
20
|
+
* @property {string} status - 통신 상태
|
|
21
|
+
* - "success": 정상 응답
|
|
22
|
+
* - "fail": 비정상 응답
|
|
23
|
+
* - "timeout": 타임아웃 응답
|
|
24
|
+
* @property {ResultDataType} data - 요청 응답 데이터
|
|
25
|
+
* @property {API_Res_Error[]} errors - 에러 정보
|
|
26
|
+
*/
|
|
27
|
+
export interface API_Res_Base<ResultDataType> {
|
|
28
|
+
/**
|
|
29
|
+
* 통신 상태
|
|
30
|
+
* - "success": 정상 응답
|
|
31
|
+
* - "fail": 비정상 응답
|
|
32
|
+
* - "timeout": 타임아웃 응답
|
|
33
|
+
*/
|
|
34
|
+
status: string;
|
|
35
|
+
/**
|
|
36
|
+
* 요청 응답 데이터
|
|
37
|
+
*/
|
|
38
|
+
data: ResultDataType;
|
|
39
|
+
/**
|
|
40
|
+
* 에러 정보
|
|
41
|
+
*/
|
|
42
|
+
errors: API_Res_Error[];
|
|
43
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export type * from "./api";
|
package/src/auth/login/types.ts
DELETED