@uniai-fe/uds-templates 0.1.16 → 0.1.17

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.
Files changed (92) hide show
  1. package/dist/styles.css +139 -10
  2. package/package.json +18 -11
  3. package/src/auth/common/complete/Template.tsx +3 -0
  4. package/src/auth/common/complete/types.ts +4 -1
  5. package/src/auth/common/find/markup/CodeStep.tsx +2 -1
  6. package/src/auth/common/find/markup/InfoStep.tsx +2 -1
  7. package/src/auth/common/find/styles/result.scss +1 -1
  8. package/src/auth/find-password/markup/StepResetPassword.tsx +2 -1
  9. package/src/auth/login/markup/FormField.tsx +2 -1
  10. package/src/auth/signup/markup/AccountForm.tsx +2 -1
  11. package/src/auth/signup/markup/Complete.tsx +2 -1
  12. package/src/auth/signup/markup/UserInfoForm.tsx +2 -1
  13. package/src/auth/signup/markup/VerificationForm.tsx +4 -2
  14. package/src/index.scss +1 -0
  15. package/src/index.tsx +1 -0
  16. package/src/modal/core/components/FooterButtons.tsx +4 -1
  17. package/src/modal/templates/Dialog.tsx +4 -2
  18. package/src/modal/types/footer.ts +4 -2
  19. package/src/page-frame/container/index.scss +14 -8
  20. package/src/page-frame/desktop/components/header/Container.tsx +22 -0
  21. package/src/page-frame/desktop/components/header/Section.tsx +20 -0
  22. package/src/page-frame/desktop/components/header/index.tsx +19 -0
  23. package/src/page-frame/desktop/components/header/util/Button.tsx +23 -0
  24. package/src/page-frame/desktop/components/header/util/Container.tsx +18 -0
  25. package/src/page-frame/desktop/components/header/util/Item.tsx +13 -0
  26. package/src/page-frame/desktop/components/header/util/Logout.tsx +26 -0
  27. package/src/page-frame/desktop/components/header/util/setting/Button.tsx +39 -0
  28. package/src/page-frame/desktop/components/index.tsx +15 -0
  29. package/src/page-frame/desktop/components/nav/Button.tsx +24 -0
  30. package/src/page-frame/desktop/components/nav/Container.tsx +70 -0
  31. package/src/page-frame/desktop/components/nav/Logo.tsx +46 -0
  32. package/src/page-frame/desktop/components/nav/index.tsx +5 -0
  33. package/src/page-frame/desktop/components/page/Container.tsx +13 -0
  34. package/src/page-frame/desktop/components/page/ServiceFrame.tsx +15 -0
  35. package/src/page-frame/desktop/components/page/ServiceMain.tsx +13 -0
  36. package/src/page-frame/desktop/components/page/ServiceMainWrapper.tsx +24 -0
  37. package/src/page-frame/desktop/components/page/index.tsx +14 -0
  38. package/src/page-frame/desktop/components/popup/Container.tsx +18 -0
  39. package/src/page-frame/desktop/components/popup/frame/Body.tsx +14 -0
  40. package/src/page-frame/desktop/components/popup/frame/Container.tsx +16 -0
  41. package/src/page-frame/desktop/components/popup/frame/Header.tsx +26 -0
  42. package/src/page-frame/desktop/components/popup/frame/index.tsx +11 -0
  43. package/src/page-frame/desktop/components/popup/index.tsx +9 -0
  44. package/src/page-frame/desktop/index.scss +5 -0
  45. package/src/page-frame/desktop/index.tsx +5 -0
  46. package/src/page-frame/desktop/styles/page/common.scss +40 -0
  47. package/src/page-frame/desktop/styles/page/header.scss +49 -0
  48. package/src/page-frame/desktop/styles/page/nav.scss +128 -0
  49. package/src/page-frame/desktop/styles/popup/popup.scss +45 -0
  50. package/src/page-frame/desktop/styles/variables.scss +28 -0
  51. package/src/page-frame/desktop/types/nav.ts +77 -0
  52. package/src/page-frame/index.tsx +2 -0
  53. package/src/page-frame/mobile/index.scss +1 -1
  54. package/src/page-frame/types/index.ts +69 -0
  55. package/src/weather/apis/index.ts +4 -0
  56. package/src/weather/apis/korea/client.ts +93 -0
  57. package/src/weather/apis/korea/server.ts +253 -0
  58. package/src/weather/apis/open-weather-map/client.ts +69 -0
  59. package/src/weather/apis/open-weather-map/server.ts +134 -0
  60. package/src/weather/components/icon/Address.tsx +13 -0
  61. package/src/weather/components/icon/Weather.tsx +32 -0
  62. package/src/weather/components/index.tsx +7 -0
  63. package/src/weather/components/page-header/Address.tsx +21 -0
  64. package/src/weather/components/page-header/Alert.tsx +42 -0
  65. package/src/weather/components/page-header/Container.tsx +14 -0
  66. package/src/weather/components/page-header/Forecast.tsx +26 -0
  67. package/src/weather/components/page-header/NextDays.tsx +32 -0
  68. package/src/weather/components/page-header/Today.tsx +135 -0
  69. package/src/weather/context/mock.tsx +45 -0
  70. package/src/weather/data/alert-regions-meta.json +1286 -0
  71. package/src/weather/data/response.ts +36 -0
  72. package/src/weather/data/weather-regions-meta.json +9833 -0
  73. package/src/weather/hooks/index.ts +4 -0
  74. package/src/weather/hooks/useOpenWeatherMap.ts +42 -0
  75. package/src/weather/hooks/useWeatherKorea.ts +78 -0
  76. package/src/weather/hooks/useWeatherKoreaAlert.ts +36 -0
  77. package/src/weather/index.tsx +11 -0
  78. package/src/weather/jotai/coordinate.ts +16 -0
  79. package/src/weather/jotai/farm-idx.ts +5 -0
  80. package/src/weather/jotai/index.ts +2 -0
  81. package/src/weather/styles/weather.scss +151 -0
  82. package/src/weather/types/api.ts +215 -0
  83. package/src/weather/types/base.ts +50 -0
  84. package/src/weather/types/index.ts +4 -0
  85. package/src/weather/types/korea.ts +228 -0
  86. package/src/weather/types/open-weather-map.ts +164 -0
  87. package/src/weather/utils/alert.ts +30 -0
  88. package/src/weather/utils/date-time.ts +65 -0
  89. package/src/weather/utils/index.ts +4 -0
  90. package/src/weather/utils/location.ts +161 -0
  91. package/src/weather/utils/validate.ts +9 -0
  92. package/src/weather/utils/weather.ts +304 -0
@@ -0,0 +1,304 @@
1
+ import type {
2
+ API_Res_WeatherKoreaBase,
3
+ API_Res_WeatherKoreaForecast,
4
+ API_Res_WeatherKoreaNow,
5
+ KMA_Res_WeatherItem,
6
+ KMA_Res_WeatherForecast,
7
+ KMA_Res_WeatherNow,
8
+ } from "../types";
9
+ import { getMoments } from "./date-time";
10
+
11
+ /**
12
+ * 날씨 도구; 현재 날씨/예보 값 추출
13
+ * @param {KMA_Res_WeatherItem[]} items - 현재 날씨 아이템
14
+ * @param {string} category - 카테고리
15
+ * @return {string | null} 현재 날씨 값
16
+ */
17
+ const getValueNow = (
18
+ items: KMA_Res_WeatherItem[],
19
+ category: string,
20
+ ): string | null => items.find(i => i.category === category)?.fcstValue || null;
21
+
22
+ /**
23
+ * 날씨 도구; 예보 값 추출
24
+ * @param {KMA_Res_WeatherItem[]} items - 예보 아이템
25
+ * @param {string} date - 날짜
26
+ * @param {string} category - 카테고리
27
+ * @return {string | null} 예보 값
28
+ */
29
+ const getValueForecast = (
30
+ items: KMA_Res_WeatherItem[],
31
+ date: string,
32
+ category: string,
33
+ ): string | null =>
34
+ items.find(i => i.fcstDate === date && i.category === category)?.fcstValue ||
35
+ null;
36
+
37
+ /**
38
+ * 강수량 코드
39
+ * @desc
40
+ * - 1(약한 비); 3mm/h 미만
41
+ * - 2(보통 비); 3mm/h 이상 15mm/h 미만
42
+ * - 3(강한 비); 15mm/h 이상
43
+ * @param {string} props.pty - 강수형태 코드
44
+ * @param {string} props.pcp - 1시간 강수량
45
+ * @return {string | null} 강수량 코드; 1(약한비), 2(보통비), 3(강한비)
46
+ */
47
+ const getRainAmount = ({
48
+ pty,
49
+ pcp,
50
+ }: {
51
+ pty: string | null;
52
+ pcp: string | null;
53
+ }): string | null => {
54
+ if (!pty || !pcp) return null;
55
+
56
+ if (Number(pcp) < 3) return "1";
57
+ else if (3 <= Number(pcp) && Number(pcp) < 15) return "2";
58
+ else return "3";
59
+ };
60
+
61
+ /**
62
+ * 강설량 코드
63
+ * @desc
64
+ * - 1(보통 눈); 1cm/h 미만
65
+ * - 2(많은 눈); 1cm/h 이상
66
+ * @param {string} props.pty - 강수형태 코드
67
+ * @param {string} props.snow - 1시간 신적설
68
+ * @return {string | null} 강설량 코드; 1(보통눈), 2(많은눈)
69
+ */
70
+ const getSnowAmount = ({
71
+ pty,
72
+ snow,
73
+ }: {
74
+ pty: string | null;
75
+ snow: string | null;
76
+ }): string | null => {
77
+ if (!pty || !snow) return null;
78
+
79
+ if (Number(snow) < 1) return "1";
80
+ else return "2";
81
+ };
82
+
83
+ /**
84
+ * 풍속 코드
85
+ * @desc
86
+ * - 1(약한 바람); 4m/s 미만
87
+ * - 2(약간 강한 바람); 4m/s 이상 9m/s 미만
88
+ * - 3(강한 바람); 9m/s 이상
89
+ * @param {string} props.wind - 풍속
90
+ * @return {string | null} 풍속 코드; 1(약한바람), 2(약간강한바람), 3(강한바람)
91
+ */
92
+ const getWindSpeed = ({ wind }: { wind: string | null }): string | null => {
93
+ if (!wind) return null;
94
+ if (Number(wind) < 4) return "1";
95
+ else if (4 <= Number(wind) && Number(wind) < 9) return "2";
96
+ else return "3";
97
+ };
98
+
99
+ /**
100
+ * 날씨 상태 코드
101
+ * @desc
102
+ * - sky-1(맑음)
103
+ * - sky-2(구름조금)
104
+ * - sky-3(구름많음)
105
+ * - sky-4(흐림)
106
+ * - drop-rain-shower(소나기)
107
+ * - drop-rain(비)
108
+ * - drop-rain-1(약한 비)
109
+ * - drop-rain-2(보통 비)
110
+ * - drop-rain-3(강한 비)
111
+ * - drop-rain-snow(비/눈)
112
+ * - drop-rain-snow-1(약한 비/눈)
113
+ * - drop-rain-snow-2(보통 비/눈)
114
+ * - drop-rain-snow-3(강한 비/눈)
115
+ * - drop-snow(눈)
116
+ * - drop-snow-1(보통 눈)
117
+ * - drop-snow-2(많은 눈)
118
+ * @param {string} props.sky - 하늘상태 코드; 1(맑음), 2(구름조금), 3(구름많음), 4(흐림)
119
+ * @param {string} props.pty - 강수형태 코드; 0(없음), 1(비), 2(비/눈), 3(눈), 4(소나기)
120
+ * @param {string} props.pcp - 1시간 강수량
121
+ * @param {string} props.snow - 1시간 신적설
122
+ */
123
+ const getWeatherCondition = ({
124
+ sky,
125
+ pty,
126
+ pcp,
127
+ snow,
128
+ }: {
129
+ sky: string | null;
130
+ pty: string | null;
131
+ pcp: string | null;
132
+ snow: string | null;
133
+ }): { code: string | null; name: string | null } => {
134
+ const dropType = () => {
135
+ if (!pty || isNaN(Number(pty)) || pty === "0") return null;
136
+ switch (Number(pty)) {
137
+ case 1:
138
+ return "rain";
139
+ case 2:
140
+ return "rain-snow";
141
+ case 3:
142
+ return "snow";
143
+ case 4:
144
+ return "shower";
145
+ default:
146
+ return null;
147
+ }
148
+ };
149
+
150
+ if (!dropType()) {
151
+ const skyCode = sky === null ? null : sky;
152
+ const skyName = () => {
153
+ switch (Number(skyCode)) {
154
+ case 1:
155
+ return "맑음";
156
+ case 2:
157
+ return "구름조금";
158
+ case 3:
159
+ return "구름많음";
160
+ case 4:
161
+ return "흐림";
162
+ default:
163
+ return null;
164
+ }
165
+ };
166
+
167
+ return {
168
+ code: `sky-${skyCode}`,
169
+ name: skyName(),
170
+ };
171
+ }
172
+
173
+ const rainAmount = getRainAmount({ pty, pcp });
174
+ const snowAmount = getSnowAmount({ pty, snow });
175
+
176
+ const dropStrength = (): string | null => {
177
+ const type = dropType();
178
+ if (type === "rain") return rainAmount;
179
+ else if (type === "snow") return snowAmount;
180
+ else if (type === "rain-snow") {
181
+ if (rainAmount === null) return snowAmount;
182
+ if (snowAmount === null) return rainAmount;
183
+ // rainAmount와 snowAmount 중 큰 값을 선택
184
+ return Math.max(Number(rainAmount), Number(snowAmount)).toString();
185
+ }
186
+ // 소나기
187
+ else if (type === "shower") return type;
188
+ return null;
189
+ };
190
+
191
+ const dropCode = `drop-${dropType()}${dropStrength() ? `-${dropStrength()}` : ""}`;
192
+ const dropName = () => {
193
+ const type = dropType();
194
+ if (type === "rain") {
195
+ if (dropStrength() === null) return "비";
196
+ if (rainAmount === "1") return "약한 비";
197
+ else if (rainAmount === "2") return "보통 비";
198
+ else if (rainAmount === "3") return "강한 비";
199
+ } else if (type === "snow") {
200
+ if (dropStrength() === null) return "눈";
201
+ if (snowAmount === "1") return "보통 눈";
202
+ else if (snowAmount === "2") return "많은 눈";
203
+ } else if (type === "rain-snow") {
204
+ if (dropStrength() === null) return "비/눈";
205
+ if (dropStrength() === "1") return "약한 비/눈";
206
+ else if (dropStrength() === "2") return "보통 비/눈";
207
+ else if (dropStrength() === "3") return "강한 비/눈";
208
+ } else if (type === "shower") {
209
+ return "소나기";
210
+ }
211
+ return null;
212
+ };
213
+
214
+ return {
215
+ code: dropCode,
216
+ name: dropName(),
217
+ };
218
+ };
219
+
220
+ export function now(
221
+ outputResponse: API_Res_WeatherKoreaNow,
222
+ apiResponse: KMA_Res_WeatherNow,
223
+ ): API_Res_WeatherKoreaNow {
224
+ const res: API_Res_WeatherKoreaNow = { ...outputResponse };
225
+
226
+ const items = apiResponse?.response?.body?.items?.item;
227
+ if (!items || !Array.isArray(items) || items.length === 0) return res;
228
+
229
+ const sky = getValueNow(items, "SKY"); // 없음
230
+ const pty = getValueNow(items, "PTY"); // 강수형태
231
+ const pcp = getValueNow(items, "RN1"); // 1시간 강수량 PCP없음
232
+ const snow = getValueNow(items, "SNO"); // 없음
233
+ const wind = getValueNow(items, "WSD");
234
+
235
+ const condition = getWeatherCondition({ sky, pty, pcp, snow });
236
+
237
+ const getDailyState: API_Res_WeatherKoreaBase = {
238
+ sky,
239
+ drop: pty,
240
+ rainAmount: getRainAmount({ pty, pcp }),
241
+ snowAmount: getSnowAmount({ pty, snow }),
242
+ windSpeed: getWindSpeed({ wind }),
243
+ condition: condition.code,
244
+ conditionName: condition.name,
245
+ };
246
+
247
+ res.today.temperature = getValueNow(items, "T1H");
248
+ res.today.humidity = getValueNow(items, "REH");
249
+
250
+ Object.assign(res.today, getDailyState);
251
+
252
+ return res;
253
+ }
254
+
255
+ export function forecast(
256
+ outputResponse: API_Res_WeatherKoreaForecast,
257
+ apiResponse: KMA_Res_WeatherForecast,
258
+ ): API_Res_WeatherKoreaForecast {
259
+ const res: API_Res_WeatherKoreaForecast = { ...outputResponse };
260
+
261
+ const items = apiResponse?.response?.body?.items?.item;
262
+ if (!items || !Array.isArray(items) || items.length === 0) return res;
263
+
264
+ const { today, tomorrow, dayAfterTomorrow } = getMoments();
265
+
266
+ const getDailyState = (date: string): API_Res_WeatherKoreaBase => {
267
+ const sky = getValueForecast(items, date, "SKY");
268
+ const pty = getValueForecast(items, date, "PTY");
269
+ const pcp = getValueForecast(items, date, "PCP");
270
+ const snow = getValueForecast(items, date, "SNO");
271
+ const wind = getValueForecast(items, date, "WSD");
272
+
273
+ const condition = getWeatherCondition({ sky, pty, pcp, snow });
274
+
275
+ return {
276
+ sky,
277
+ drop: pty,
278
+ rainAmount: getRainAmount({ pty, pcp }),
279
+ snowAmount: getSnowAmount({ pty, snow }),
280
+ windSpeed: getWindSpeed({ wind }),
281
+ condition: condition.code,
282
+ conditionName: condition.name,
283
+ };
284
+ };
285
+
286
+ res.today.temperature = getValueForecast(items, today, "TMP");
287
+ res.today.humidity = getValueForecast(items, today, "REH");
288
+ Object.assign(res.today, getDailyState(today));
289
+
290
+ res.day_1.max_temperature = getValueForecast(items, tomorrow, "TMX");
291
+ res.day_1.min_temperature = getValueForecast(items, tomorrow, "TMN");
292
+ Object.assign(res.day_1, getDailyState(tomorrow));
293
+
294
+ res.day_2.max_temperature = getValueForecast(items, dayAfterTomorrow, "TMX");
295
+ res.day_2.min_temperature = getValueForecast(items, dayAfterTomorrow, "TMN");
296
+ Object.assign(res.day_2, getDailyState(dayAfterTomorrow));
297
+
298
+ return res;
299
+ }
300
+
301
+ export const extractWeatherSummary = {
302
+ forecast,
303
+ now,
304
+ };