@upsnap/strapi 1.0.11 → 1.0.14
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/README.md +3 -0
- package/dist/admin/{App-BIxhBt5_.mjs → App-QKoGSuNi.mjs} +60 -303
- package/dist/admin/{App-CH5fBeNI.js → App-l5dYTPZP.js} +221 -465
- package/dist/admin/index-BWyzuEFm.js +344 -0
- package/dist/admin/index-Ct7siGlB.mjs +343 -0
- package/dist/admin/index.js +2 -63
- package/dist/admin/index.mjs +2 -63
- package/dist/server/index.js +112 -27
- package/dist/server/index.mjs +110 -27
- package/dist/server/src/index.d.ts +2 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -85,6 +85,9 @@ After installing the plugin and restarting Strapi:
|
|
|
85
85
|
4. Save: Save your settings and head to the dashboard to see your site's health in real-time.
|
|
86
86
|
|
|
87
87
|
|
|
88
|
+
## Privacy & Tracking
|
|
89
|
+
This plugin sends limited technical and diagnostic information to enable uptime monitoring and troubleshooting.
|
|
90
|
+
|
|
88
91
|
## Documentation
|
|
89
92
|
[Full Documentation](https://github.com/Appfoster/upsnap-docs/blob/master/strapi/Home.md)
|
|
90
93
|
|
|
@@ -5,61 +5,10 @@ import { SubNav, SubNavHeader, SubNavSection, SubNavLink, Box, Table, Thead, Tr,
|
|
|
5
5
|
import { House, BulletList, Monitor, Cog, Pencil, Trash, Search, Cross, ChevronDown, Plus, EyeStriked, Eye, Graph, MinusCircle, Play, More, CrossCircle, SealCheck, ArrowsCounterClockwise, ArrowRight, ArrowLeft, CheckCircle, Information, ArrowDown, Rocket, Filter, FileCsv, FilePdf, CaretDown, CaretUp } from "@strapi/icons";
|
|
6
6
|
import React, { useState, useRef, useEffect, useMemo, useCallback } from "react";
|
|
7
7
|
import { toast, ToastContainer } from "react-toastify";
|
|
8
|
-
import
|
|
8
|
+
import { f as fetchTags, g as getPrimaryMonitorId, s as setPrimaryMonitorId, a as getUserDetailsCached, b as getUserDetails, r as request, c as getUserData, d as formatTitleToUppercase, e as fetchMonitorSettings, h as settingsToConfig, i as clearAllStoredMonitors, j as handleLogout, k as formatDate, l as formatCheckType, m as getRangeTimestamps, n as formatDateTime, o as fetchRegionsData } from "./index-Ct7siGlB.mjs";
|
|
9
9
|
import styled, { createGlobalStyle } from "styled-components";
|
|
10
10
|
import Chart from "react-apexcharts";
|
|
11
11
|
import "react-toastify/dist/ReactToastify.css";
|
|
12
|
-
const SideNav = () => {
|
|
13
|
-
const CustomSubNavLink = SubNavLink;
|
|
14
|
-
return /* @__PURE__ */ jsxs(SubNav, { "aria-label": "Upsnap navigation", children: [
|
|
15
|
-
/* @__PURE__ */ jsx(SubNavHeader, { label: "Upsnap" }),
|
|
16
|
-
/* @__PURE__ */ jsxs(SubNavSection, { label: "", children: [
|
|
17
|
-
/* @__PURE__ */ jsx(
|
|
18
|
-
CustomSubNavLink,
|
|
19
|
-
{
|
|
20
|
-
as: NavLink,
|
|
21
|
-
to: `dashboard`,
|
|
22
|
-
icon: /* @__PURE__ */ jsx(House, {}),
|
|
23
|
-
padding: 2,
|
|
24
|
-
marginBottom: 1,
|
|
25
|
-
marginLeft: 2,
|
|
26
|
-
style: { marginLeft: "10px", marginBottom: "10px" },
|
|
27
|
-
children: "Dashboard"
|
|
28
|
-
}
|
|
29
|
-
),
|
|
30
|
-
/* @__PURE__ */ jsx(
|
|
31
|
-
CustomSubNavLink,
|
|
32
|
-
{
|
|
33
|
-
as: NavLink,
|
|
34
|
-
to: `incidents`,
|
|
35
|
-
icon: /* @__PURE__ */ jsx(BulletList, {}),
|
|
36
|
-
style: { marginLeft: "10px", marginBottom: "10px" },
|
|
37
|
-
children: "Incidents"
|
|
38
|
-
}
|
|
39
|
-
),
|
|
40
|
-
/* @__PURE__ */ jsx(
|
|
41
|
-
CustomSubNavLink,
|
|
42
|
-
{
|
|
43
|
-
as: NavLink,
|
|
44
|
-
to: `status-pages`,
|
|
45
|
-
icon: /* @__PURE__ */ jsx(Monitor, {}),
|
|
46
|
-
style: { marginLeft: "10px", marginBottom: "10px" },
|
|
47
|
-
children: "Status Pages"
|
|
48
|
-
}
|
|
49
|
-
),
|
|
50
|
-
/* @__PURE__ */ jsx(
|
|
51
|
-
CustomSubNavLink,
|
|
52
|
-
{
|
|
53
|
-
as: NavLink,
|
|
54
|
-
to: `settings`,
|
|
55
|
-
icon: /* @__PURE__ */ jsx(Cog, {}),
|
|
56
|
-
style: { marginLeft: "10px", marginBottom: "10px" },
|
|
57
|
-
children: "Settings"
|
|
58
|
-
}
|
|
59
|
-
)
|
|
60
|
-
] })
|
|
61
|
-
] });
|
|
62
|
-
};
|
|
63
12
|
const PLAN_TYPES = {
|
|
64
13
|
FREE: "free",
|
|
65
14
|
PRO: "pro",
|
|
@@ -195,248 +144,56 @@ const generateRandomColor = () => {
|
|
|
195
144
|
];
|
|
196
145
|
return colors2[Math.floor(Math.random() * colors2.length)];
|
|
197
146
|
};
|
|
198
|
-
const
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
const userDetailsString = localStorage.getItem("userDetails");
|
|
215
|
-
if (!userDetailsString) return null;
|
|
216
|
-
if (!forceFetchFromMicroservice) {
|
|
217
|
-
try {
|
|
218
|
-
const cached2 = JSON.parse(userDetailsString);
|
|
219
|
-
if (cached2.updated_at) {
|
|
220
|
-
const cachedTime = Date.parse(cached2.updated_at);
|
|
221
|
-
if (!isNaN(cachedTime)) {
|
|
222
|
-
const ageMs = Date.now() - cachedTime;
|
|
223
|
-
if (ageMs < 5 * 60 * 1e3) {
|
|
224
|
-
return cached2;
|
|
225
|
-
}
|
|
226
|
-
}
|
|
147
|
+
const SideNav = () => {
|
|
148
|
+
const CustomSubNavLink = SubNavLink;
|
|
149
|
+
return /* @__PURE__ */ jsxs(SubNav, { "aria-label": "Upsnap navigation", children: [
|
|
150
|
+
/* @__PURE__ */ jsx(SubNavHeader, { label: "Upsnap" }),
|
|
151
|
+
/* @__PURE__ */ jsxs(SubNavSection, { label: "", children: [
|
|
152
|
+
/* @__PURE__ */ jsx(
|
|
153
|
+
CustomSubNavLink,
|
|
154
|
+
{
|
|
155
|
+
as: NavLink,
|
|
156
|
+
to: `dashboard`,
|
|
157
|
+
icon: /* @__PURE__ */ jsx(House, {}),
|
|
158
|
+
padding: 2,
|
|
159
|
+
marginBottom: 1,
|
|
160
|
+
marginLeft: 2,
|
|
161
|
+
style: { marginLeft: "10px", marginBottom: "10px" },
|
|
162
|
+
children: "Dashboard"
|
|
227
163
|
}
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
const response = await axios({
|
|
262
|
-
url: `/upsnap${url}`,
|
|
263
|
-
...options
|
|
264
|
-
});
|
|
265
|
-
if (options?.responseType === "blob") {
|
|
266
|
-
return response;
|
|
267
|
-
}
|
|
268
|
-
return response.data;
|
|
269
|
-
};
|
|
270
|
-
const formatDate = (dateString) => {
|
|
271
|
-
const date2 = new Date(dateString);
|
|
272
|
-
if (isNaN(date2.getTime())) {
|
|
273
|
-
return "N/A";
|
|
274
|
-
}
|
|
275
|
-
return date2.toLocaleString(void 0, {
|
|
276
|
-
year: "numeric",
|
|
277
|
-
month: "2-digit",
|
|
278
|
-
day: "2-digit",
|
|
279
|
-
hour: "2-digit",
|
|
280
|
-
minute: "2-digit",
|
|
281
|
-
second: "2-digit",
|
|
282
|
-
hour12: false
|
|
283
|
-
});
|
|
284
|
-
};
|
|
285
|
-
const formatTitleToUppercase = (title) => {
|
|
286
|
-
const words = title.split("_");
|
|
287
|
-
const capitalizedWords = words.map((word) => word.charAt(0).toUpperCase() + word.slice(1));
|
|
288
|
-
return capitalizedWords.join(" ");
|
|
289
|
-
};
|
|
290
|
-
const getRangeTimestamps = (range) => {
|
|
291
|
-
const now = Math.floor(Date.now() / 1e3);
|
|
292
|
-
const ranges = {
|
|
293
|
-
last_hour: 60 * 60,
|
|
294
|
-
last_24_hours: 60 * 60 * 24,
|
|
295
|
-
last_7_days: 60 * 60 * 24 * 7,
|
|
296
|
-
last_30_days: 60 * 60 * 24 * 30,
|
|
297
|
-
last_year: 60 * 60 * 24 * 365
|
|
298
|
-
};
|
|
299
|
-
const duration2 = ranges[range];
|
|
300
|
-
return {
|
|
301
|
-
start: now - duration2,
|
|
302
|
-
end: now
|
|
303
|
-
};
|
|
304
|
-
};
|
|
305
|
-
const formatCheckType = (key) => {
|
|
306
|
-
if (!key) return "";
|
|
307
|
-
const k = String(key).toLowerCase().trim();
|
|
308
|
-
const exceptions = ["ssl"];
|
|
309
|
-
if (exceptions.includes(k)) return k.toUpperCase();
|
|
310
|
-
const parts = k.split("_").filter(Boolean);
|
|
311
|
-
return parts.map((p) => p.charAt(0).toUpperCase() + p.slice(1)).join(" ");
|
|
312
|
-
};
|
|
313
|
-
function formatDateTime(isoTimestamp) {
|
|
314
|
-
if (!isoTimestamp) return "-";
|
|
315
|
-
const date2 = new Date(isoTimestamp);
|
|
316
|
-
return new Intl.DateTimeFormat("en-US", {
|
|
317
|
-
dateStyle: "medium",
|
|
318
|
-
timeStyle: "short"
|
|
319
|
-
}).format(date2);
|
|
320
|
-
}
|
|
321
|
-
const getUserDetails = async () => {
|
|
322
|
-
try {
|
|
323
|
-
const result = await request("/user/details", {
|
|
324
|
-
method: "GET"
|
|
325
|
-
});
|
|
326
|
-
if (!result || result?.userDetailsData?.status !== "success") {
|
|
327
|
-
console.error("Failed to fetch user details");
|
|
328
|
-
} else {
|
|
329
|
-
setUserDetails(result?.userDetailsData.data);
|
|
330
|
-
return result?.userDetailsData.data;
|
|
331
|
-
}
|
|
332
|
-
return null;
|
|
333
|
-
} catch (error) {
|
|
334
|
-
console.error("Error while fetching user details ", error);
|
|
335
|
-
return null;
|
|
336
|
-
}
|
|
337
|
-
};
|
|
338
|
-
async function fetchMonitorSettings(monitorId) {
|
|
339
|
-
try {
|
|
340
|
-
const result = await request(`/monitor/settings/${monitorId}`);
|
|
341
|
-
if (!result) {
|
|
342
|
-
console.error("Failed to fetch monitor settings");
|
|
343
|
-
return null;
|
|
344
|
-
}
|
|
345
|
-
if (result?.monitorSettingsData?.status === "success" && result?.monitorSettingsData?.data) {
|
|
346
|
-
return {
|
|
347
|
-
monitor_id: result.monitorSettingsData.data.monitor_id,
|
|
348
|
-
settings: result.monitorSettingsData.data.settings
|
|
349
|
-
};
|
|
350
|
-
}
|
|
351
|
-
console.error("Invalid response from monitor settings API:", result);
|
|
352
|
-
return null;
|
|
353
|
-
} catch (error) {
|
|
354
|
-
console.error("Error fetching monitor settings:", error);
|
|
355
|
-
return null;
|
|
356
|
-
}
|
|
357
|
-
}
|
|
358
|
-
function settingsToConfig(settings) {
|
|
359
|
-
return {
|
|
360
|
-
meta: settings.meta,
|
|
361
|
-
services: settings.services
|
|
362
|
-
};
|
|
363
|
-
}
|
|
364
|
-
async function setPrimaryMonitorId(monitorId) {
|
|
365
|
-
try {
|
|
366
|
-
const result = await request(`/settings/set-primary-monitor-id`, {
|
|
367
|
-
method: "POST",
|
|
368
|
-
data: { monitorId }
|
|
369
|
-
});
|
|
370
|
-
if (!result) return false;
|
|
371
|
-
if (result?.ok) {
|
|
372
|
-
return true;
|
|
373
|
-
}
|
|
374
|
-
return false;
|
|
375
|
-
} catch (error) {
|
|
376
|
-
console.error("Error setting primary monitor ID:", error);
|
|
377
|
-
return false;
|
|
378
|
-
}
|
|
379
|
-
}
|
|
380
|
-
async function getPrimaryMonitorId() {
|
|
381
|
-
try {
|
|
382
|
-
const result = await request(`/settings/get-primary-monitor-id`, {
|
|
383
|
-
method: "GET"
|
|
384
|
-
});
|
|
385
|
-
if (!result) return null;
|
|
386
|
-
if (result?.primaryMonitorId) {
|
|
387
|
-
return result.primaryMonitorId;
|
|
388
|
-
}
|
|
389
|
-
console.error("Failed to get primary monitor ID:", result);
|
|
390
|
-
return null;
|
|
391
|
-
} catch (error) {
|
|
392
|
-
console.error("Error getting primary monitor ID:", error);
|
|
393
|
-
return null;
|
|
394
|
-
}
|
|
395
|
-
}
|
|
396
|
-
async function handleLogout() {
|
|
397
|
-
try {
|
|
398
|
-
await setPrimaryMonitorId("");
|
|
399
|
-
const res = await request("/settings", {
|
|
400
|
-
method: "POST",
|
|
401
|
-
data: { token: null, logOut: true }
|
|
402
|
-
});
|
|
403
|
-
if (res.ok) {
|
|
404
|
-
return true;
|
|
405
|
-
}
|
|
406
|
-
return false;
|
|
407
|
-
} catch (err) {
|
|
408
|
-
console.log("Error while logging out ", err);
|
|
409
|
-
return;
|
|
410
|
-
}
|
|
411
|
-
}
|
|
412
|
-
const fetchRegionsData = async () => {
|
|
413
|
-
try {
|
|
414
|
-
const result = await request(`/regions`);
|
|
415
|
-
if (!result) return [];
|
|
416
|
-
if (result?.regionsData?.status === "success" && Array.isArray(result?.regionsData?.data)) {
|
|
417
|
-
return result?.regionsData?.data;
|
|
418
|
-
}
|
|
419
|
-
return [];
|
|
420
|
-
} catch (error) {
|
|
421
|
-
console.error("Error fetching regions:", error);
|
|
422
|
-
return [];
|
|
423
|
-
}
|
|
424
|
-
};
|
|
425
|
-
const fetchTags = async (setIsLoading, setTags) => {
|
|
426
|
-
setIsLoading(true);
|
|
427
|
-
try {
|
|
428
|
-
const result = await request("/tags", {
|
|
429
|
-
method: "GET"
|
|
430
|
-
});
|
|
431
|
-
if (!result?.tagsData) {
|
|
432
|
-
throw new Error("Failed to fetch tags");
|
|
433
|
-
}
|
|
434
|
-
setTags(result?.tagsData?.data);
|
|
435
|
-
} catch (error) {
|
|
436
|
-
console.error("Error fetching tags:", error);
|
|
437
|
-
} finally {
|
|
438
|
-
setIsLoading(false);
|
|
439
|
-
}
|
|
164
|
+
),
|
|
165
|
+
/* @__PURE__ */ jsx(
|
|
166
|
+
CustomSubNavLink,
|
|
167
|
+
{
|
|
168
|
+
as: NavLink,
|
|
169
|
+
to: `incidents`,
|
|
170
|
+
icon: /* @__PURE__ */ jsx(BulletList, {}),
|
|
171
|
+
style: { marginLeft: "10px", marginBottom: "10px" },
|
|
172
|
+
children: "Incidents"
|
|
173
|
+
}
|
|
174
|
+
),
|
|
175
|
+
/* @__PURE__ */ jsx(
|
|
176
|
+
CustomSubNavLink,
|
|
177
|
+
{
|
|
178
|
+
as: NavLink,
|
|
179
|
+
to: `status-pages`,
|
|
180
|
+
icon: /* @__PURE__ */ jsx(Monitor, {}),
|
|
181
|
+
style: { marginLeft: "10px", marginBottom: "10px" },
|
|
182
|
+
children: "Status Pages"
|
|
183
|
+
}
|
|
184
|
+
),
|
|
185
|
+
/* @__PURE__ */ jsx(
|
|
186
|
+
CustomSubNavLink,
|
|
187
|
+
{
|
|
188
|
+
as: NavLink,
|
|
189
|
+
to: `settings`,
|
|
190
|
+
icon: /* @__PURE__ */ jsx(Cog, {}),
|
|
191
|
+
style: { marginLeft: "10px", marginBottom: "10px" },
|
|
192
|
+
children: "Settings"
|
|
193
|
+
}
|
|
194
|
+
)
|
|
195
|
+
] })
|
|
196
|
+
] });
|
|
440
197
|
};
|
|
441
198
|
function MonitorsTable({
|
|
442
199
|
monitors = [],
|
|
@@ -545,7 +302,7 @@ function MonitorsTable({
|
|
|
545
302
|
),
|
|
546
303
|
/* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral500", children: monitor.config.meta.url }),
|
|
547
304
|
monitor.tag_ids && monitor.tag_ids.length > 0 && /* @__PURE__ */ jsx(Flex, { wrap: "wrap", gap: 1, width: "300px", children: monitor.tag_ids.map((tagId) => {
|
|
548
|
-
const tag = availableTags
|
|
305
|
+
const tag = availableTags?.find((tag2) => tag2.id === tagId);
|
|
549
306
|
if (!tag) return null;
|
|
550
307
|
return /* @__PURE__ */ jsx(
|
|
551
308
|
Badge,
|
|
@@ -7697,14 +7454,14 @@ function IntegrationFormModal({
|
|
|
7697
7454
|
name: ""
|
|
7698
7455
|
});
|
|
7699
7456
|
const [errors, setErrors] = useState({});
|
|
7700
|
-
const [userDetails,
|
|
7457
|
+
const [userDetails, setUserDetails] = useState(null);
|
|
7701
7458
|
const [userDataEmail, setUserDataEmail] = useState("");
|
|
7702
7459
|
const [showPassword, setShowPassword] = useState({});
|
|
7703
7460
|
useEffect(() => {
|
|
7704
7461
|
const userData = getUserData();
|
|
7705
7462
|
setUserDataEmail(userData?.user?.email || "");
|
|
7706
7463
|
(async () => {
|
|
7707
|
-
|
|
7464
|
+
setUserDetails(await getUserDetailsCached());
|
|
7708
7465
|
})();
|
|
7709
7466
|
}, []);
|
|
7710
7467
|
const buildInitialFormData = useCallback(() => {
|
|
@@ -8679,7 +8436,7 @@ function LogInForm({
|
|
|
8679
8436
|
Field.Root,
|
|
8680
8437
|
{
|
|
8681
8438
|
width: "100%",
|
|
8682
|
-
error: errors?.issues
|
|
8439
|
+
error: errors?.issues?.find((issue2) => issue2.path[0] === "email")?.message || forgotPasswordError,
|
|
8683
8440
|
required: true,
|
|
8684
8441
|
children: [
|
|
8685
8442
|
/* @__PURE__ */ jsx(Field.Label, { children: "Email" }),
|
|
@@ -8700,7 +8457,7 @@ function LogInForm({
|
|
|
8700
8457
|
Field.Root,
|
|
8701
8458
|
{
|
|
8702
8459
|
width: "100%",
|
|
8703
|
-
error: errors?.issues
|
|
8460
|
+
error: errors?.issues?.find((issue2) => issue2.path[0] === "password")?.message,
|
|
8704
8461
|
required: true,
|
|
8705
8462
|
children: [
|
|
8706
8463
|
/* @__PURE__ */ jsx(Field.Label, { children: "Password" }),
|
|
@@ -8813,7 +8570,7 @@ function RegisterForm({
|
|
|
8813
8570
|
Field.Root,
|
|
8814
8571
|
{
|
|
8815
8572
|
width: "100%",
|
|
8816
|
-
error: errors?.issues
|
|
8573
|
+
error: errors?.issues?.find((issue2) => issue2.path[0] === "fullName")?.message,
|
|
8817
8574
|
required: true,
|
|
8818
8575
|
children: [
|
|
8819
8576
|
/* @__PURE__ */ jsx(Field.Label, { children: "Full Name" }),
|
|
@@ -8834,7 +8591,7 @@ function RegisterForm({
|
|
|
8834
8591
|
Field.Root,
|
|
8835
8592
|
{
|
|
8836
8593
|
width: "100%",
|
|
8837
|
-
error: errors?.issues
|
|
8594
|
+
error: errors?.issues?.find((issue2) => issue2.path[0] === "email")?.message,
|
|
8838
8595
|
required: true,
|
|
8839
8596
|
children: [
|
|
8840
8597
|
/* @__PURE__ */ jsx(Field.Label, { children: "Email" }),
|
|
@@ -8855,7 +8612,7 @@ function RegisterForm({
|
|
|
8855
8612
|
Field.Root,
|
|
8856
8613
|
{
|
|
8857
8614
|
width: "100%",
|
|
8858
|
-
error: errors?.issues
|
|
8615
|
+
error: errors?.issues?.find((issue2) => issue2.path[0] === "password")?.message,
|
|
8859
8616
|
required: true,
|
|
8860
8617
|
children: [
|
|
8861
8618
|
/* @__PURE__ */ jsx(Field.Label, { children: "Password" }),
|
|
@@ -8879,7 +8636,7 @@ function RegisterForm({
|
|
|
8879
8636
|
Field.Root,
|
|
8880
8637
|
{
|
|
8881
8638
|
width: "100%",
|
|
8882
|
-
error: errors?.issues
|
|
8639
|
+
error: errors?.issues?.find((issue2) => issue2.path[0] === "confirmPassword")?.message || confirmPasswordError,
|
|
8883
8640
|
required: true,
|
|
8884
8641
|
children: [
|
|
8885
8642
|
/* @__PURE__ */ jsx(Field.Label, { children: "Confirm Password" }),
|
|
@@ -12414,7 +12171,7 @@ function IncidentsList({ defaultMonitorId }) {
|
|
|
12414
12171
|
return { backgroundColor: "neutral100", textColor: "neutral600" };
|
|
12415
12172
|
};
|
|
12416
12173
|
const getRegionName = (regionId) => {
|
|
12417
|
-
const region = regions
|
|
12174
|
+
const region = regions?.find((item) => item?.id === regionId);
|
|
12418
12175
|
return region?.name || regionId || "N/A";
|
|
12419
12176
|
};
|
|
12420
12177
|
const [searchParams] = useSearchParams();
|