diff --git a/components/common/ErrorBoundary.js b/components/common/ErrorBoundary.js
new file mode 100644
index 00000000..5bb11a9e
--- /dev/null
+++ b/components/common/ErrorBoundary.js
@@ -0,0 +1,33 @@
+/* eslint-disable no-console */
+import { ErrorBoundary as Boundary } from 'react-error-boundary';
+import { Button } from 'react-basics';
+import useMessages from 'hooks/useMessages';
+import styles from './ErrorBoundry.module.css';
+
+const logError = (error, info) => {
+ console.error(error, info.componentStack);
+};
+
+export function ErrorBoundary({ children }) {
+ const { formatMessage, messages } = useMessages();
+
+ const fallbackRender = ({ error, resetErrorBoundary }) => {
+ console.log({ error });
+ return (
+
+
{formatMessage(messages.error)}
+
{error.message}
+
{error.stack}
+
+
+ );
+ };
+
+ return (
+
+ {children}
+
+ );
+}
+
+export default ErrorBoundary;
diff --git a/components/common/ErrorBoundry.module.css b/components/common/ErrorBoundry.module.css
new file mode 100644
index 00000000..915022c4
--- /dev/null
+++ b/components/common/ErrorBoundry.module.css
@@ -0,0 +1,19 @@
+.error {
+ position: fixed;
+ top: 0;
+ left: 0;
+ right: 0;
+ bottom: 0;
+ margin: auto;
+ z-index: var(--z-index-overlay);
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ min-height: 600px;
+ gap: 20px;
+}
+
+.error button {
+ align-self: center;
+}
diff --git a/components/input/DateFilter.js b/components/input/DateFilter.js
index 68dcd417..b6c1ee72 100644
--- a/components/input/DateFilter.js
+++ b/components/input/DateFilter.js
@@ -23,7 +23,7 @@ export function DateFilter({ websiteId, value, className }) {
if (data) {
setDateRange({ value, ...getDateRangeValues(new Date(data.createdAt), Date.now()) });
}
- } else {
+ } else if (value !== 'all') {
setDateRange(value);
}
}
@@ -61,7 +61,7 @@ export function DateFilter({ websiteId, value, className }) {
value: '90day',
},
{ label: formatMessage(labels.thisYear), value: '1year' },
- {
+ websiteId && {
label: formatMessage(labels.allTime),
value: 'all',
divider: true,
@@ -71,7 +71,7 @@ export function DateFilter({ websiteId, value, className }) {
value: 'custom',
divider: true,
},
- ];
+ ].filter(n => n);
const renderValue = value => {
return value === 'custom' ? (
diff --git a/components/metrics/CountriesTable.js b/components/metrics/CountriesTable.js
index 6dfb9195..2d7b5ceb 100644
--- a/components/metrics/CountriesTable.js
+++ b/components/metrics/CountriesTable.js
@@ -17,7 +17,7 @@ export function CountriesTable({ websiteId, ...props }) {
value={countryNames[code] && code}
label={countryNames[code]}
>
-
+
);
}
diff --git a/components/metrics/RegionsTable.js b/components/metrics/RegionsTable.js
index 83296d97..c8e0b768 100644
--- a/components/metrics/RegionsTable.js
+++ b/components/metrics/RegionsTable.js
@@ -18,7 +18,7 @@ export function RegionsTable({ websiteId, ...props }) {
const renderLink = ({ x: code }) => {
return (
-
+
);
};
diff --git a/components/pages/settings/users/UsersList.js b/components/pages/settings/users/UsersList.js
index 3274d7df..1605cb51 100644
--- a/components/pages/settings/users/UsersList.js
+++ b/components/pages/settings/users/UsersList.js
@@ -18,10 +18,15 @@ export function UsersList() {
const { toast, showToast } = useToast();
const hasData = data && data.length !== 0;
- const handleSave = () => refetch();
+ const handleSave = () => {
+ refetch().then(() => showToast({ message: formatMessage(messages.saved), variant: 'success' }));
+ };
- const handleDelete = () =>
- showToast({ message: formatMessage(messages.userDeleted), variant: 'success' });
+ const handleDelete = () => {
+ refetch().then(() =>
+ showToast({ message: formatMessage(messages.userDeleted), variant: 'success' }),
+ );
+ };
return (
diff --git a/lang/ar-SA.json b/lang/ar-SA.json
index b8b53a5b..6bb39439 100644
--- a/lang/ar-SA.json
+++ b/lang/ar-SA.json
@@ -1,6 +1,6 @@
{
- "label.access-code": "Access code",
- "label.actions": "اجراءات",
+ "label.access-code": "كود الدعوة",
+ "label.actions": "الإجراءات",
"label.activity-log": "سجل الأحداث",
"label.add-website": "إضافة موقع",
"label.admin": "مدير",
@@ -59,7 +59,7 @@
"label.more": "المزيد",
"label.name": "الإسم",
"label.new-password": "كلمة مرور جديدة",
- "label.none": "لا شيء",
+ "label.none": "غير معرف",
"label.operating-systems": "نظام التشغيل",
"label.owner": "المالك",
"label.page-views": "مشاهدات الصفحة",
@@ -109,8 +109,8 @@
"label.users": "المستخدمين",
"label.view": "عرض",
"label.view-details": "عرض التفاصيل",
- "label.views": "مشاهدات",
- "label.visitors": "زوار",
+ "label.views": "المشاهدات",
+ "label.visitors": "الزوار",
"label.website-id": "معرف الموقع",
"label.websites": "المواقع",
"label.yesterday": "الأمس",
@@ -136,7 +136,7 @@
"message.saved": "تم الحفظ بنجاح.",
"message.share-url": "هذا الرابط الذي تم مشاركته بشكل عام لـ {target}.",
"message.team-already-member": "أنت عضو في المجموعة",
- "message.team-not-found": "لم يتم العثور على المجموعة found.",
+ "message.team-not-found": "لم يتم العثور على المجموعة",
"message.tracking-code": "كود التتبع",
"message.user-deleted": "تم حذف المستخدم.",
"message.visitor-log": "زائر من {country} يستخدم {browser} على {os} {device}",
diff --git a/lang/es-MX.json b/lang/es-MX.json
index 5e828f7c..999c1d8f 100644
--- a/lang/es-MX.json
+++ b/lang/es-MX.json
@@ -1,39 +1,39 @@
{
- "label.access-code": "Access code",
+ "label.access-code": "Código de acceso",
"label.actions": "Acciones",
- "label.activity-log": "Activity log",
- "label.add-website": "Agregar sitio",
+ "label.activity-log": "Registro de actividad",
+ "label.add-website": "Nuevo sitio web",
"label.admin": "Administrador",
"label.all": "Todos",
"label.all-time": "Todos los tiempos",
- "label.analytics": "Analytics",
+ "label.analytics": "Analíticas",
"label.average-visit-time": "Tiempo promedio de visita",
"label.back": "Atrás",
"label.bounce-rate": "Porcentaje de rebote",
"label.browsers": "Navegadores",
"label.cancel": "Cancelar",
"label.change-password": "Cambiar contraseña",
- "label.cities": "Cities",
- "label.clear-all": "Clear all",
- "label.confirm": "Confirm",
+ "label.cities": "Ciudades",
+ "label.clear-all": "Limpiar todo",
+ "label.confirm": "Confirmar",
"label.confirm-password": "Confirmar contraseña",
- "label.continue": "Continue",
+ "label.continue": "Continuar",
"label.countries": "Países",
- "label.create-team": "Create team",
- "label.create-user": "Create user",
- "label.created": "Created",
+ "label.create-team": "Crear equipo",
+ "label.create-user": "Crear usuario",
+ "label.created": "Creado",
"label.current-password": "Contraseña actual",
"label.custom-range": "Intervalo personalizado",
"label.dashboard": "Panel de control",
- "label.data": "Data",
- "label.date-range": "Fechas",
+ "label.data": "Datos",
+ "label.date-range": "Intervalo de fechas",
"label.default-date-range": "Intervalo por defecto",
"label.delete": "Eliminar",
- "label.delete-team": "Delete team",
- "label.delete-user": "Delete user",
+ "label.delete-team": "Eliminar team",
+ "label.delete-user": "Eliminar usuario",
"label.delete-website": "Eliminar sitio",
"label.desktop": "Escritorio",
- "label.details": "Details",
+ "label.details": "Detalles",
"label.devices": "Dispositivos",
"label.dismiss": "Ignorar",
"label.domain": "Dominio",
@@ -43,18 +43,18 @@
"label.events": "Eventos",
"label.filter-combined": "Combinado",
"label.filter-raw": "Personalizado",
- "label.join": "Join",
- "label.join-team": "Join team",
+ "label.join": "Unir",
+ "label.join-team": "Unir a equipo",
"label.language": "Idioma",
"label.languages": "Idiomas",
"label.laptop": "Portátil",
"label.last-days": "Últimos {x} días",
"label.last-hours": "Últimas {x} horas",
- "label.leave": "Leave",
- "label.leave-team": "Leave team",
+ "label.leave": "Abandonar",
+ "label.leave-team": "Abandonar equipo",
"label.login": "Iniciar sesión",
"label.logout": "Cerrar sesión",
- "label.members": "Members",
+ "label.members": "Miembros",
"label.mobile": "Móvil",
"label.more": "Más",
"label.name": "Nombre",
@@ -67,80 +67,80 @@
"label.password": "Contraseña",
"label.powered-by": "Analíticas de {name}",
"label.profile": "Perfil",
- "label.queries": "Queries",
+ "label.queries": "Consultas",
"label.query-parameters": "Parámetros de petición",
"label.realtime": "Tiempo real",
"label.referrers": "Referido desde",
"label.refresh": "Actualizar",
- "label.regenerate": "Regenerate",
- "label.regions": "Regions",
- "label.remove": "Remove",
+ "label.regenerate": "Regenerar",
+ "label.regions": "Regiones",
+ "label.remove": "Quitar",
"label.required": "Obligatorio",
"label.reset": "Reiniciar",
"label.reset-website": "Reiniciar estadísticas",
- "label.role": "Role",
+ "label.role": "Rol",
"label.save": "Guardar",
"label.screens": "Pantallas",
- "label.select-website": "Select website",
- "label.sessions": "Sessions",
+ "label.select-website": "Seleccionar sitio web",
+ "label.sessions": "Sesiones",
"label.settings": "Configuraciones",
"label.share-url": "Compartir URL",
- "label.single-day": "Dia",
+ "label.single-day": "Día",
"label.tablet": "Tableta",
- "label.team": "Team",
- "label.team-guest": "Team guest",
- "label.team-id": "Team ID",
- "label.team-member": "Team member",
- "label.team-owner": "Team owner",
- "label.teams": "Teams",
+ "label.team": "Equipo",
+ "label.team-guest": "Invitado de equipo",
+ "label.team-id": "ID de equipo",
+ "label.team-member": "Miembro de equipo",
+ "label.team-owner": "Admin. del equipo",
+ "label.teams": "Equipos",
"label.theme": "Tema",
"label.this-month": "Este mes",
"label.this-week": "Esta semana",
"label.this-year": "Este año",
"label.timezone": "Zona horaria",
- "label.title": "Title",
+ "label.title": "Título",
"label.today": "Hoy",
"label.toggle-charts": "Alternar gráficas",
"label.tracking-code": "Código de rastreo",
"label.unique-visitors": "Visitantes únicos",
"label.unknown": "Desconocida",
- "label.user": "User",
+ "label.user": "Usuario",
"label.username": "Nombre de usuario",
- "label.users": "Users",
- "label.view": "View",
+ "label.users": "Usuarios",
+ "label.view": "Visualizar",
"label.view-details": "Ver detalles",
"label.views": "Vistas",
"label.visitors": "Visitantes",
- "label.website-id": "Website ID",
+ "label.website-id": "ID del sitio web",
"label.websites": "Sitios",
"label.yesterday": "Ayer",
"message.active-users": "{x} {x, plural, one {activo} other {activos}}",
- "message.confirm-delete": "¿Estás seguro(a) de querer eliminar {target}?",
- "message.confirm-leave": "Are you sure you want to leave {target}?",
- "message.confirm-reset": "¿Seguro que deseas restablecer las estadísticas de {target}?",
- "message.delete-website": "Eliminar sitio",
+ "message.confirm-delete": "¿Seguro que quieres eliminar {target}?",
+ "message.confirm-leave": "¿Seguro que quieres abandonar {target}?",
+ "message.confirm-reset": "¿Seguro que quieres BORRAR las analíticas de {target}?",
+ "message.delete-website": "Eliminar sitio web",
"message.delete-website-warning": "Toda la información relacionada será eliminada.",
"message.error": "Algo falló.",
- "message.event-log": "{event} on {url}",
+ "message.event-log": "{event} en {url}",
"message.go-to-settings": "Ir a la configuración",
"message.incorrect-username-password": "Nombre de usuario o contraseña incorrectos.",
"message.invalid-domain": "Dominio inválido",
- "message.min-password-length": "Minimum length of {n} characters",
+ "message.min-password-length": "Longitud mínima de {n} caracteres",
"message.no-data-available": "No hay información disponible.",
"message.no-match-password": "Las contraseñas no coinciden",
- "message.no-teams": "You have not created any teams.",
- "message.no-users": "There are no users.",
+ "message.no-teams": "No has creado ningún equipo.",
+ "message.no-users": "No hay usuarios.",
"message.page-not-found": "Página no encontrada",
"message.reset-website": "Reiniciar estadísticas",
"message.reset-website-warning": "Todas las estadísticas de esta página serán eliminadas, pero el código de rastreo permanecerá intacto.",
- "message.saved": "Guardado exitosamente.",
+ "message.saved": "Guardado.",
"message.share-url": "Esta es la URL compartida públicamente para {target}.",
- "message.team-already-member": "You are already a member of the team.",
- "message.team-not-found": "Team not found.",
+ "message.team-already-member": "Ya eres miembro de este equipo.",
+ "message.team-not-found": "Equipo no encontrado.",
"message.tracking-code": "Código de rastreo",
- "message.user-deleted": "User deleted.",
+ "message.user-deleted": "Usuario eliminado.",
"message.visitor-log": "Visitante desde {country} usando {browser} en {os} {device}",
- "messages.no-team-websites": "This team does not have any websites.",
+ "messages.no-team-websites": "Este equipo no tiene ningún sitio web configurado.",
"messages.no-websites-configured": "No tienes ningún sitio configurado.",
- "messages.team-websites-info": "Websites can be viewed by anyone on the team."
+ "messages.team-websites-info": "Las analíticas de tus sitios pueden verse por cualquier miembro del equipo."
}
diff --git a/lang/pl-PL.json b/lang/pl-PL.json
index c04a2830..919fd9b3 100644
--- a/lang/pl-PL.json
+++ b/lang/pl-PL.json
@@ -1,27 +1,27 @@
{
- "label.access-code": "Access code",
+ "label.access-code": "Kod dostępu",
"label.actions": "Działania",
- "label.activity-log": "Activity log",
+ "label.activity-log": "Dziennik aktywności",
"label.add-website": "Dodaj witrynę",
"label.admin": "Administrator",
"label.all": "Wszystkie",
"label.all-time": "Cały czas",
- "label.analytics": "Analytics",
+ "label.analytics": "Analityka",
"label.average-visit-time": "Średni czas wizyty",
"label.back": "Powrót",
"label.bounce-rate": "Współczynnik odrzuceń",
"label.browsers": "Przeglądarki",
"label.cancel": "Anuluj",
"label.change-password": "Zmień hasło",
- "label.cities": "Cities",
- "label.clear-all": "Clear all",
- "label.confirm": "Confirm",
+ "label.cities": "Miasta",
+ "label.clear-all": "Wyczyść wszystko",
+ "label.confirm": "Potwierdź",
"label.confirm-password": "Potwierdź hasło",
- "label.continue": "Continue",
+ "label.continue": "Kontynuuj",
"label.countries": "Kraje",
- "label.create-team": "Create team",
- "label.create-user": "Create user",
- "label.created": "Created",
+ "label.create-team": "Utwórz zespół",
+ "label.create-user": "Utwórz użytkownika",
+ "label.created": "Utworzony",
"label.current-password": "Aktualne hasło",
"label.custom-range": "Zakres niestandardowy",
"label.dashboard": "Panel",
@@ -29,11 +29,11 @@
"label.date-range": "Zakres dat",
"label.default-date-range": "Domyślny zakres dat",
"label.delete": "Usuń",
- "label.delete-team": "Delete team",
- "label.delete-user": "Delete user",
+ "label.delete-team": "Usuń zespół",
+ "label.delete-user": "Usuń użytkownika",
"label.delete-website": "Usuń witrynę",
"label.desktop": "Komputer",
- "label.details": "Details",
+ "label.details": "Szczegóły",
"label.devices": "Urządzenia",
"label.dismiss": "Odrzuć",
"label.domain": "Domena",
@@ -43,18 +43,18 @@
"label.events": "Zdarzenia",
"label.filter-combined": "Połączone",
"label.filter-raw": "Surowe dane",
- "label.join": "Join",
- "label.join-team": "Join team",
+ "label.join": "Dołącz",
+ "label.join-team": "Dołącz do zespołu",
"label.language": "Język",
"label.languages": "Języki",
"label.laptop": "Laptop",
"label.last-days": "Ostatnie {x} dni",
"label.last-hours": "Ostatnie {x} godzin",
- "label.leave": "Leave",
- "label.leave-team": "Leave team",
+ "label.leave": "Opuść",
+ "label.leave-team": "Opuść zespół",
"label.login": "Zaloguj się",
"label.logout": "Wyloguj",
- "label.members": "Members",
+ "label.members": "Członkowie",
"label.mobile": "Smartfon",
"label.more": "Więcej",
"label.name": "Nazwa",
@@ -67,80 +67,80 @@
"label.password": "Hasło",
"label.powered-by": "Obsługiwane przez {name}",
"label.profile": "Profil",
- "label.queries": "Queries",
+ "label.queries": "Zapytania",
"label.query-parameters": "Parametry query",
"label.realtime": "Czas rzeczywisty",
"label.referrers": "Źródła odsyłające",
"label.refresh": "Odśwież",
- "label.regenerate": "Regenerate",
- "label.regions": "Regions",
- "label.remove": "Remove",
+ "label.regenerate": "Wygeneruj ponownie",
+ "label.regions": "Regiony",
+ "label.remove": "Usuń",
"label.required": "Wymagany",
"label.reset": "Zresetuj",
"label.reset-website": "Zresetuj statystyki",
"label.role": "Role",
"label.save": "Zapisz",
"label.screens": "Ekrany",
- "label.select-website": "Select website",
- "label.sessions": "Sessions",
+ "label.select-website": "Wybierz witrynę",
+ "label.sessions": "Sesje",
"label.settings": "Ustawienia",
"label.share-url": "Udostępnij adres URL",
"label.single-day": "W tym dniu",
"label.tablet": "Tablet",
- "label.team": "Team",
- "label.team-guest": "Team guest",
- "label.team-id": "Team ID",
- "label.team-member": "Team member",
- "label.team-owner": "Team owner",
- "label.teams": "Teams",
+ "label.team": "Zespół",
+ "label.team-guest": "Gość zespołu",
+ "label.team-id": "ID zespołu",
+ "label.team-member": "Członek zespołu",
+ "label.team-owner": "Właściciel zespołu",
+ "label.teams": "Zespoły",
"label.theme": "Motyw",
"label.this-month": "W tym miesiącu",
"label.this-week": "W tym tygodniu",
"label.this-year": "W tym roku",
"label.timezone": "Strefa czasowa",
- "label.title": "Title",
+ "label.title": "Tytuł",
"label.today": "Dzisiaj",
"label.toggle-charts": "Przełącz wykresy",
"label.tracking-code": "Kod śledzenia",
"label.unique-visitors": "Unikalni odwiedzający",
"label.unknown": "Nieznany",
- "label.user": "User",
+ "label.user": "Użytkownik",
"label.username": "Nazwa użytkownika",
- "label.users": "Users",
- "label.view": "View",
+ "label.users": "Użytkownicy",
+ "label.view": "Zobacz",
"label.view-details": "Pokaż szczegóły",
"label.views": "Wyświetlenia",
"label.visitors": "Odwiedzający",
- "label.website-id": "Website ID",
+ "label.website-id": "ID witryny",
"label.websites": "Witryny",
"label.yesterday": "Wczoraj",
"message.active-users": "{x} aktualnie {x, plural, one {odwiedzający} other {odwiedzających}}",
"message.confirm-delete": "Czy na pewno chcesz usunąć {target}?",
- "message.confirm-leave": "Are you sure you want to leave {target}?",
+ "message.confirm-leave": "Czy na pewno chcesz opuścić {target}?",
"message.confirm-reset": "Czy na pewno chcesz zresetować statystyki {target}?",
"message.delete-website": "Usuń witrynę",
"message.delete-website-warning": "Wszystkie powiązane dane również zostaną usunięte.",
"message.error": "Coś poszło nie tak.",
- "message.event-log": "{event} on {url}",
+ "message.event-log": "{event} na {url}",
"message.go-to-settings": "Przejdź do ustawień",
"message.incorrect-username-password": "Nieprawidłowa nazwa użytkownika/hasło.",
"message.invalid-domain": "Nieprawidłowa witryna",
- "message.min-password-length": "Minimum length of {n} characters",
+ "message.min-password-length": "Minimalna długość {n} znaków",
"message.no-data-available": "Brak dostępnych danych.",
"message.no-match-password": "Hasła się nie zgadzają",
- "message.no-teams": "You have not created any teams.",
- "message.no-users": "There are no users.",
+ "message.no-teams": "Nie stworzyłeś żadnych zespołów.",
+ "message.no-users": "Nie ma żadnych użytkowników.",
"message.page-not-found": "Strona nie znaleziona.",
"message.reset-website": "Zresetuj statystyki",
"message.reset-website-warning": "Wszystkie statystyki tej witryny zostaną usunięte, ale kod śledzenia pozostanie nienaruszony.",
"message.saved": "Zapisano pomyślnie.",
"message.share-url": "To jest publicznie udostępniany adres URL dla {target}.",
- "message.team-already-member": "You are already a member of the team.",
- "message.team-not-found": "Team not found.",
+ "message.team-already-member": "Jesteś już członkiem zespołu.",
+ "message.team-not-found": "Nie znaleziono zespołu.",
"message.tracking-code": "Kod śledzenia",
- "message.user-deleted": "User deleted.",
+ "message.user-deleted": "Użytkownik usunięty.",
"message.visitor-log": "Odwiedzający z {country} używa {browser} na {os} {device}",
- "messages.no-team-websites": "This team does not have any websites.",
+ "messages.no-team-websites": "Ten zespół nie ma żadnych witryn internetowych.",
"messages.no-websites-configured": "Nie masz skonfigurowanych żadnych witryn internetowych.",
- "messages.team-websites-info": "Websites can be viewed by anyone on the team."
+ "messages.team-websites-info": "Strony internetowe mogą być przeglądane przez każdego członka zespołu."
}
diff --git a/lib/date.js b/lib/date.js
index 41d01304..1cfca75d 100644
--- a/lib/date.js
+++ b/lib/date.js
@@ -53,7 +53,7 @@ export function parseDateRange(value, locale = 'en-US') {
const match = value.match(/^(?[0-9-]+)(?hour|day|week|month|year)$/);
- if (!match) return;
+ if (!match) return {};
const { num, unit } = match.groups;
diff --git a/lib/detect.ts b/lib/detect.ts
index 8b11cd79..868d0a80 100644
--- a/lib/detect.ts
+++ b/lib/detect.ts
@@ -56,12 +56,25 @@ export function getDevice(screen, os) {
}
}
-export async function getLocation(ip) {
+export async function getLocation(ip, req) {
// Ignore local ips
if (await isLocalhost(ip)) {
return;
}
+ if (req.headers['x-vercel-ip-country']) {
+ const country = req.headers['x-vercel-ip-country'];
+ const region = req.headers['x-vercel-ip-country-region'];
+ const city = req.headers['x-vercel-ip-city'];
+
+ return {
+ country,
+ // Vercel documentation says they return only region, but that is not always the case
+ subdivision1: region.includes('-') ? region : `${country}-${region}`,
+ city: decodeURIComponent(city),
+ };
+ }
+
// Database lookup
if (!lookup) {
const dir = path.join(process.cwd(), 'geo');
@@ -70,18 +83,21 @@ export async function getLocation(ip) {
}
const result = lookup.get(ip);
- const country = result?.country?.iso_code ?? result?.registered_country?.iso_code;
- const subdivision1 = result?.subdivisions?.[0]?.iso_code;
- const subdivision2 = result?.subdivisions?.[1]?.names?.en;
- const city = result?.city?.names?.en;
- return { country, subdivision1, subdivision2, city };
+ if (result) {
+ return {
+ country: result.country?.iso_code ?? result?.registered_country?.iso_code,
+ subdivision1: result.subdivisions?.[0]?.iso_code,
+ subdivision2: result.subdivisions?.[1]?.names?.en,
+ city: result.city?.names?.en,
+ };
+ }
}
export async function getClientInfo(req: NextApiRequestCollect, { screen }) {
const userAgent = req.headers['user-agent'];
const ip = getIpAddress(req);
- const location = await getLocation(ip);
+ const location = await getLocation(ip, req);
const country = location?.country;
const subdivision1 = location?.subdivision1;
const subdivision2 = location?.subdivision2;
diff --git a/next.config.js b/next.config.js
index 58e0561f..8efb45bc 100644
--- a/next.config.js
+++ b/next.config.js
@@ -65,10 +65,10 @@ const redirects = [
},
];
-if (process.env.CLOUD_MODE) {
+if (process.env.CLOUD_MODE && process.env.DISABLE_LOGIN && process.env.CLOUD_URL) {
redirects.push({
source: '/login',
- destination: CLOUD_URL,
+ destination: process.env.CLOUD_URL,
permanent: false,
});
}
diff --git a/package.json b/package.json
index a586ebb0..db84659f 100644
--- a/package.json
+++ b/package.json
@@ -97,6 +97,7 @@
"react-basics": "^0.77.0",
"react-beautiful-dnd": "^13.1.0",
"react-dom": "^18.2.0",
+ "react-error-boundary": "^4.0.4",
"react-intl": "^5.24.7",
"react-simple-maps": "^2.3.0",
"react-spring": "^9.4.4",
diff --git a/pages/_app.js b/pages/_app.js
index f1a34521..22458215 100644
--- a/pages/_app.js
+++ b/pages/_app.js
@@ -3,6 +3,7 @@ import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import Head from 'next/head';
import Script from 'next/script';
import { useRouter } from 'next/router';
+import ErrorBoundary from 'components/common/ErrorBoundary';
import useLocale from 'hooks/useLocale';
import useConfig from 'hooks/useConfig';
import '@fontsource/inter/400.css';
@@ -41,21 +42,37 @@ export default function App({ Component, pageProps }) {
textComponent={Wrapper}
onError={() => null}
>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {!pathname.includes('/share/') && }
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {!pathname.includes('/share/') && }
+
);
diff --git a/pages/api/auth/login.ts b/pages/api/auth/login.ts
index 9bdfec22..10c92647 100644
--- a/pages/api/auth/login.ts
+++ b/pages/api/auth/login.ts
@@ -1,3 +1,4 @@
+import debug from 'debug';
import { NextApiResponse } from 'next';
import {
ok,
@@ -13,6 +14,8 @@ import { secret } from 'lib/crypto';
import { NextApiRequestQueryBody, User } from 'lib/types';
import { setAuthKey } from 'lib/auth';
+const log = debug('umami:auth');
+
export interface LoginRequestBody {
username: string;
password: string;
@@ -51,6 +54,8 @@ export default async (
});
}
+ log('Login failed:', { username, user });
+
return unauthorized(res, 'message.incorrect-username-password');
}
diff --git a/pages/login.js b/pages/login.js
index 88c19121..9a1f3c45 100644
--- a/pages/login.js
+++ b/pages/login.js
@@ -16,7 +16,7 @@ export default function LoginPage({ disabled }) {
export async function getServerSideProps() {
return {
props: {
- disabled: !!(process.env.DISABLE_LOGIN || process.env.CLOUD_MODE),
+ disabled: !!process.env.DISABLE_LOGIN,
},
};
}
diff --git a/public/images/flags/xx.png b/public/images/flags/xx.png
new file mode 100644
index 00000000..52058026
Binary files /dev/null and b/public/images/flags/xx.png differ
diff --git a/public/intl/messages/ar-SA.json b/public/intl/messages/ar-SA.json
index dfaa3b53..fc38707d 100644
--- a/public/intl/messages/ar-SA.json
+++ b/public/intl/messages/ar-SA.json
@@ -2,13 +2,13 @@
"label.access-code": [
{
"type": 0,
- "value": "Access code"
+ "value": "كود الدعوة"
}
],
"label.actions": [
{
"type": 0,
- "value": "اجراءات"
+ "value": "الإجراءات"
}
],
"label.activity-log": [
@@ -378,7 +378,7 @@
"label.none": [
{
"type": 0,
- "value": "لا شيء"
+ "value": "غير معرف"
}
],
"label.operating-systems": [
@@ -682,13 +682,13 @@
"label.views": [
{
"type": 0,
- "value": "مشاهدات"
+ "value": "المشاهدات"
}
],
"label.visitors": [
{
"type": 0,
- "value": "زوار"
+ "value": "الزوار"
}
],
"label.website-id": [
@@ -920,7 +920,7 @@
"message.team-not-found": [
{
"type": 0,
- "value": "لم يتم العثور على المجموعة found."
+ "value": "لم يتم العثور على المجموعة"
}
],
"message.tracking-code": [
diff --git a/public/intl/messages/es-MX.json b/public/intl/messages/es-MX.json
index 12ed5739..fdc2483d 100644
--- a/public/intl/messages/es-MX.json
+++ b/public/intl/messages/es-MX.json
@@ -2,7 +2,7 @@
"label.access-code": [
{
"type": 0,
- "value": "Access code"
+ "value": "Código de acceso"
}
],
"label.actions": [
@@ -14,13 +14,13 @@
"label.activity-log": [
{
"type": 0,
- "value": "Activity log"
+ "value": "Registro de actividad"
}
],
"label.add-website": [
{
"type": 0,
- "value": "Agregar sitio"
+ "value": "Nuevo sitio web"
}
],
"label.admin": [
@@ -44,7 +44,7 @@
"label.analytics": [
{
"type": 0,
- "value": "Analytics"
+ "value": "Analíticas"
}
],
"label.average-visit-time": [
@@ -86,19 +86,19 @@
"label.cities": [
{
"type": 0,
- "value": "Cities"
+ "value": "Ciudades"
}
],
"label.clear-all": [
{
"type": 0,
- "value": "Clear all"
+ "value": "Limpiar todo"
}
],
"label.confirm": [
{
"type": 0,
- "value": "Confirm"
+ "value": "Confirmar"
}
],
"label.confirm-password": [
@@ -110,7 +110,7 @@
"label.continue": [
{
"type": 0,
- "value": "Continue"
+ "value": "Continuar"
}
],
"label.countries": [
@@ -122,19 +122,19 @@
"label.create-team": [
{
"type": 0,
- "value": "Create team"
+ "value": "Crear equipo"
}
],
"label.create-user": [
{
"type": 0,
- "value": "Create user"
+ "value": "Crear usuario"
}
],
"label.created": [
{
"type": 0,
- "value": "Created"
+ "value": "Creado"
}
],
"label.current-password": [
@@ -158,13 +158,13 @@
"label.data": [
{
"type": 0,
- "value": "Data"
+ "value": "Datos"
}
],
"label.date-range": [
{
"type": 0,
- "value": "Fechas"
+ "value": "Intervalo de fechas"
}
],
"label.default-date-range": [
@@ -182,13 +182,13 @@
"label.delete-team": [
{
"type": 0,
- "value": "Delete team"
+ "value": "Eliminar team"
}
],
"label.delete-user": [
{
"type": 0,
- "value": "Delete user"
+ "value": "Eliminar usuario"
}
],
"label.delete-website": [
@@ -206,7 +206,7 @@
"label.details": [
{
"type": 0,
- "value": "Details"
+ "value": "Detalles"
}
],
"label.devices": [
@@ -266,13 +266,13 @@
"label.join": [
{
"type": 0,
- "value": "Join"
+ "value": "Unir"
}
],
"label.join-team": [
{
"type": 0,
- "value": "Join team"
+ "value": "Unir a equipo"
}
],
"label.language": [
@@ -324,13 +324,13 @@
"label.leave": [
{
"type": 0,
- "value": "Leave"
+ "value": "Abandonar"
}
],
"label.leave-team": [
{
"type": 0,
- "value": "Leave team"
+ "value": "Abandonar equipo"
}
],
"label.login": [
@@ -348,7 +348,7 @@
"label.members": [
{
"type": 0,
- "value": "Members"
+ "value": "Miembros"
}
],
"label.mobile": [
@@ -430,7 +430,7 @@
"label.queries": [
{
"type": 0,
- "value": "Queries"
+ "value": "Consultas"
}
],
"label.query-parameters": [
@@ -460,19 +460,19 @@
"label.regenerate": [
{
"type": 0,
- "value": "Regenerate"
+ "value": "Regenerar"
}
],
"label.regions": [
{
"type": 0,
- "value": "Regions"
+ "value": "Regiones"
}
],
"label.remove": [
{
"type": 0,
- "value": "Remove"
+ "value": "Quitar"
}
],
"label.required": [
@@ -496,7 +496,7 @@
"label.role": [
{
"type": 0,
- "value": "Role"
+ "value": "Rol"
}
],
"label.save": [
@@ -514,13 +514,13 @@
"label.select-website": [
{
"type": 0,
- "value": "Select website"
+ "value": "Seleccionar sitio web"
}
],
"label.sessions": [
{
"type": 0,
- "value": "Sessions"
+ "value": "Sesiones"
}
],
"label.settings": [
@@ -538,7 +538,7 @@
"label.single-day": [
{
"type": 0,
- "value": "Dia"
+ "value": "Día"
}
],
"label.tablet": [
@@ -550,37 +550,37 @@
"label.team": [
{
"type": 0,
- "value": "Team"
+ "value": "Equipo"
}
],
"label.team-guest": [
{
"type": 0,
- "value": "Team guest"
+ "value": "Invitado de equipo"
}
],
"label.team-id": [
{
"type": 0,
- "value": "Team ID"
+ "value": "ID de equipo"
}
],
"label.team-member": [
{
"type": 0,
- "value": "Team member"
+ "value": "Miembro de equipo"
}
],
"label.team-owner": [
{
"type": 0,
- "value": "Team owner"
+ "value": "Admin. del equipo"
}
],
"label.teams": [
{
"type": 0,
- "value": "Teams"
+ "value": "Equipos"
}
],
"label.theme": [
@@ -616,7 +616,7 @@
"label.title": [
{
"type": 0,
- "value": "Title"
+ "value": "Título"
}
],
"label.today": [
@@ -652,7 +652,7 @@
"label.user": [
{
"type": 0,
- "value": "User"
+ "value": "Usuario"
}
],
"label.username": [
@@ -664,13 +664,13 @@
"label.users": [
{
"type": 0,
- "value": "Users"
+ "value": "Usuarios"
}
],
"label.view": [
{
"type": 0,
- "value": "View"
+ "value": "Visualizar"
}
],
"label.view-details": [
@@ -694,7 +694,7 @@
"label.website-id": [
{
"type": 0,
- "value": "Website ID"
+ "value": "ID del sitio web"
}
],
"label.websites": [
@@ -746,7 +746,7 @@
"message.confirm-delete": [
{
"type": 0,
- "value": "¿Estás seguro(a) de querer eliminar "
+ "value": "¿Seguro que quieres eliminar "
},
{
"type": 1,
@@ -760,7 +760,7 @@
"message.confirm-leave": [
{
"type": 0,
- "value": "Are you sure you want to leave "
+ "value": "¿Seguro que quieres abandonar "
},
{
"type": 1,
@@ -774,7 +774,7 @@
"message.confirm-reset": [
{
"type": 0,
- "value": "¿Seguro que deseas restablecer las estadísticas de "
+ "value": "¿Seguro que quieres BORRAR las analíticas de "
},
{
"type": 1,
@@ -788,7 +788,7 @@
"message.delete-website": [
{
"type": 0,
- "value": "Eliminar sitio"
+ "value": "Eliminar sitio web"
}
],
"message.delete-website-warning": [
@@ -810,7 +810,7 @@
},
{
"type": 0,
- "value": " on "
+ "value": " en "
},
{
"type": 1,
@@ -838,7 +838,7 @@
"message.min-password-length": [
{
"type": 0,
- "value": "Minimum length of "
+ "value": "Longitud mínima de "
},
{
"type": 1,
@@ -846,7 +846,7 @@
},
{
"type": 0,
- "value": " characters"
+ "value": " caracteres"
}
],
"message.no-data-available": [
@@ -864,13 +864,13 @@
"message.no-teams": [
{
"type": 0,
- "value": "You have not created any teams."
+ "value": "No has creado ningún equipo."
}
],
"message.no-users": [
{
"type": 0,
- "value": "There are no users."
+ "value": "No hay usuarios."
}
],
"message.page-not-found": [
@@ -894,7 +894,7 @@
"message.saved": [
{
"type": 0,
- "value": "Guardado exitosamente."
+ "value": "Guardado."
}
],
"message.share-url": [
@@ -914,13 +914,13 @@
"message.team-already-member": [
{
"type": 0,
- "value": "You are already a member of the team."
+ "value": "Ya eres miembro de este equipo."
}
],
"message.team-not-found": [
{
"type": 0,
- "value": "Team not found."
+ "value": "Equipo no encontrado."
}
],
"message.tracking-code": [
@@ -932,7 +932,7 @@
"message.user-deleted": [
{
"type": 0,
- "value": "User deleted."
+ "value": "Usuario eliminado."
}
],
"message.visitor-log": [
@@ -972,7 +972,7 @@
"messages.no-team-websites": [
{
"type": 0,
- "value": "This team does not have any websites."
+ "value": "Este equipo no tiene ningún sitio web configurado."
}
],
"messages.no-websites-configured": [
@@ -984,7 +984,7 @@
"messages.team-websites-info": [
{
"type": 0,
- "value": "Websites can be viewed by anyone on the team."
+ "value": "Las analíticas de tus sitios pueden verse por cualquier miembro del equipo."
}
]
}
diff --git a/public/intl/messages/pl-PL.json b/public/intl/messages/pl-PL.json
index 8c2c7e8c..ba133523 100644
--- a/public/intl/messages/pl-PL.json
+++ b/public/intl/messages/pl-PL.json
@@ -2,7 +2,7 @@
"label.access-code": [
{
"type": 0,
- "value": "Access code"
+ "value": "Kod dostępu"
}
],
"label.actions": [
@@ -14,7 +14,7 @@
"label.activity-log": [
{
"type": 0,
- "value": "Activity log"
+ "value": "Dziennik aktywności"
}
],
"label.add-website": [
@@ -44,7 +44,7 @@
"label.analytics": [
{
"type": 0,
- "value": "Analytics"
+ "value": "Analityka"
}
],
"label.average-visit-time": [
@@ -86,19 +86,19 @@
"label.cities": [
{
"type": 0,
- "value": "Cities"
+ "value": "Miasta"
}
],
"label.clear-all": [
{
"type": 0,
- "value": "Clear all"
+ "value": "Wyczyść wszystko"
}
],
"label.confirm": [
{
"type": 0,
- "value": "Confirm"
+ "value": "Potwierdź"
}
],
"label.confirm-password": [
@@ -110,7 +110,7 @@
"label.continue": [
{
"type": 0,
- "value": "Continue"
+ "value": "Kontynuuj"
}
],
"label.countries": [
@@ -122,19 +122,19 @@
"label.create-team": [
{
"type": 0,
- "value": "Create team"
+ "value": "Utwórz zespół"
}
],
"label.create-user": [
{
"type": 0,
- "value": "Create user"
+ "value": "Utwórz użytkownika"
}
],
"label.created": [
{
"type": 0,
- "value": "Created"
+ "value": "Utworzony"
}
],
"label.current-password": [
@@ -182,13 +182,13 @@
"label.delete-team": [
{
"type": 0,
- "value": "Delete team"
+ "value": "Usuń zespół"
}
],
"label.delete-user": [
{
"type": 0,
- "value": "Delete user"
+ "value": "Usuń użytkownika"
}
],
"label.delete-website": [
@@ -206,7 +206,7 @@
"label.details": [
{
"type": 0,
- "value": "Details"
+ "value": "Szczegóły"
}
],
"label.devices": [
@@ -266,13 +266,13 @@
"label.join": [
{
"type": 0,
- "value": "Join"
+ "value": "Dołącz"
}
],
"label.join-team": [
{
"type": 0,
- "value": "Join team"
+ "value": "Dołącz do zespołu"
}
],
"label.language": [
@@ -324,13 +324,13 @@
"label.leave": [
{
"type": 0,
- "value": "Leave"
+ "value": "Opuść"
}
],
"label.leave-team": [
{
"type": 0,
- "value": "Leave team"
+ "value": "Opuść zespół"
}
],
"label.login": [
@@ -348,7 +348,7 @@
"label.members": [
{
"type": 0,
- "value": "Members"
+ "value": "Członkowie"
}
],
"label.mobile": [
@@ -430,7 +430,7 @@
"label.queries": [
{
"type": 0,
- "value": "Queries"
+ "value": "Zapytania"
}
],
"label.query-parameters": [
@@ -460,19 +460,19 @@
"label.regenerate": [
{
"type": 0,
- "value": "Regenerate"
+ "value": "Wygeneruj ponownie"
}
],
"label.regions": [
{
"type": 0,
- "value": "Regions"
+ "value": "Regiony"
}
],
"label.remove": [
{
"type": 0,
- "value": "Remove"
+ "value": "Usuń"
}
],
"label.required": [
@@ -514,13 +514,13 @@
"label.select-website": [
{
"type": 0,
- "value": "Select website"
+ "value": "Wybierz witrynę"
}
],
"label.sessions": [
{
"type": 0,
- "value": "Sessions"
+ "value": "Sesje"
}
],
"label.settings": [
@@ -550,37 +550,37 @@
"label.team": [
{
"type": 0,
- "value": "Team"
+ "value": "Zespół"
}
],
"label.team-guest": [
{
"type": 0,
- "value": "Team guest"
+ "value": "Gość zespołu"
}
],
"label.team-id": [
{
"type": 0,
- "value": "Team ID"
+ "value": "ID zespołu"
}
],
"label.team-member": [
{
"type": 0,
- "value": "Team member"
+ "value": "Członek zespołu"
}
],
"label.team-owner": [
{
"type": 0,
- "value": "Team owner"
+ "value": "Właściciel zespołu"
}
],
"label.teams": [
{
"type": 0,
- "value": "Teams"
+ "value": "Zespoły"
}
],
"label.theme": [
@@ -616,7 +616,7 @@
"label.title": [
{
"type": 0,
- "value": "Title"
+ "value": "Tytuł"
}
],
"label.today": [
@@ -652,7 +652,7 @@
"label.user": [
{
"type": 0,
- "value": "User"
+ "value": "Użytkownik"
}
],
"label.username": [
@@ -664,13 +664,13 @@
"label.users": [
{
"type": 0,
- "value": "Users"
+ "value": "Użytkownicy"
}
],
"label.view": [
{
"type": 0,
- "value": "View"
+ "value": "Zobacz"
}
],
"label.view-details": [
@@ -694,7 +694,7 @@
"label.website-id": [
{
"type": 0,
- "value": "Website ID"
+ "value": "ID witryny"
}
],
"label.websites": [
@@ -760,7 +760,7 @@
"message.confirm-leave": [
{
"type": 0,
- "value": "Are you sure you want to leave "
+ "value": "Czy na pewno chcesz opuścić "
},
{
"type": 1,
@@ -810,7 +810,7 @@
},
{
"type": 0,
- "value": " on "
+ "value": " na "
},
{
"type": 1,
@@ -838,7 +838,7 @@
"message.min-password-length": [
{
"type": 0,
- "value": "Minimum length of "
+ "value": "Minimalna długość "
},
{
"type": 1,
@@ -846,7 +846,7 @@
},
{
"type": 0,
- "value": " characters"
+ "value": " znaków"
}
],
"message.no-data-available": [
@@ -864,13 +864,13 @@
"message.no-teams": [
{
"type": 0,
- "value": "You have not created any teams."
+ "value": "Nie stworzyłeś żadnych zespołów."
}
],
"message.no-users": [
{
"type": 0,
- "value": "There are no users."
+ "value": "Nie ma żadnych użytkowników."
}
],
"message.page-not-found": [
@@ -914,13 +914,13 @@
"message.team-already-member": [
{
"type": 0,
- "value": "You are already a member of the team."
+ "value": "Jesteś już członkiem zespołu."
}
],
"message.team-not-found": [
{
"type": 0,
- "value": "Team not found."
+ "value": "Nie znaleziono zespołu."
}
],
"message.tracking-code": [
@@ -932,7 +932,7 @@
"message.user-deleted": [
{
"type": 0,
- "value": "User deleted."
+ "value": "Użytkownik usunięty."
}
],
"message.visitor-log": [
@@ -972,7 +972,7 @@
"messages.no-team-websites": [
{
"type": 0,
- "value": "This team does not have any websites."
+ "value": "Ten zespół nie ma żadnych witryn internetowych."
}
],
"messages.no-websites-configured": [
@@ -984,7 +984,7 @@
"messages.team-websites-info": [
{
"type": 0,
- "value": "Websites can be viewed by anyone on the team."
+ "value": "Strony internetowe mogą być przeglądane przez każdego członka zespołu."
}
]
}
diff --git a/scripts/build-geo.js b/scripts/build-geo.js
index 8cb5a971..d0fe04c7 100644
--- a/scripts/build-geo.js
+++ b/scripts/build-geo.js
@@ -7,6 +7,11 @@ const https = require('https');
const zlib = require('zlib');
const tar = require('tar');
+if (process.env.VERCEL) {
+ console.log('Vercel environment detected. Skipping geo setup.');
+ process.exit(0);
+}
+
const db = 'GeoLite2-City';
let url = `https://raw.githubusercontent.com/GitSquared/node-geolite2-redist/master/redist/${db}.tar.gz`;
diff --git a/tracker/index.js b/tracker/index.js
index 2fe6d28c..e5d59273 100644
--- a/tracker/index.js
+++ b/tracker/index.js
@@ -119,6 +119,9 @@
return currentElement;
}
currentElement = currentElement.parentElement;
+ if (currentElement === null) {
+ return null;
+ }
}
return null;
};
@@ -159,11 +162,15 @@
const observer = new MutationObserver(callback);
- observer.observe(document.querySelector('head > title'), {
- subtree: true,
- characterData: true,
- childList: true,
- });
+ const node = document.querySelector('head > title');
+
+ if (node) {
+ observer.observe(node, {
+ subtree: true,
+ characterData: true,
+ childList: true,
+ });
+ }
};
const send = payload => {
diff --git a/yarn.lock b/yarn.lock
index 11227096..84de5a41 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -1497,7 +1497,7 @@
core-js-pure "^3.25.1"
regenerator-runtime "^0.13.11"
-"@babel/runtime@^7.0.0":
+"@babel/runtime@^7.0.0", "@babel/runtime@^7.12.5":
version "7.21.0"
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.0.tgz#5b55c9d394e5fcf304909a8b00c07dc217b56673"
integrity sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==
@@ -3896,25 +3896,10 @@ caniuse-api@^3.0.0:
lodash.memoize "^4.1.2"
lodash.uniq "^4.5.0"
-caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001449:
- version "1.0.30001480"
- resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001480.tgz#9bbd35ee44c2480a1e3a3b9f4496f5066817164a"
- integrity sha512-q7cpoPPvZYgtyC4VaBSN0Bt+PJ4c4EYRf0DrduInOz2SkFpHD5p3LnvEpqBp7UnJn+8x1Ogl1s38saUxe+ihQQ==
-
-caniuse-lite@^1.0.30001400:
- version "1.0.30001427"
- resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001427.tgz#d3a749f74be7ae0671fbec3a4eea18576e8ad646"
- integrity sha512-lfXQ73oB9c8DP5Suxaszm+Ta2sr/4tf8+381GkIm1MLj/YdLf+rEDyDSRCzeltuyTVGm+/s18gdZ0q+Wmp8VsQ==
-
-caniuse-lite@^1.0.30001406:
- version "1.0.30001470"
- resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001470.tgz#09c8e87c711f75ff5d39804db2613dd593feeb10"
- integrity sha512-065uNwY6QtHCBOExzbV6m236DDhYCCtPmQUCoQtwkVqzud8v5QPidoMr6CoMkC2nfp6nksjttqWQRRh75LqUmA==
-
-caniuse-lite@^1.0.30001426:
- version "1.0.30001444"
- resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001444.tgz#c0a530776eb44d933b493de1d05346f2527b30fc"
- integrity sha512-ecER9xgJQVMqcrxThKptsW0pPxSae8R2RB87LNa+ivW9ppNWRHEplXcDzkCOP4LYWGj8hunXLqaiC41iBATNyg==
+caniuse-lite@^1.0.0, caniuse-lite@^1.0.30001400, caniuse-lite@^1.0.30001406, caniuse-lite@^1.0.30001426, caniuse-lite@^1.0.30001449:
+ version "1.0.30001481"
+ resolved "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001481.tgz"
+ integrity sha512-KCqHwRnaa1InZBtqXzP98LPg0ajCVujMKjqKDhZEthIpAsJl/YEIa3YvXjGXPVqzZVguccuu7ga9KOE1J9rKPQ==
caseless@~0.12.0:
version "0.12.0"
@@ -8258,6 +8243,13 @@ react-dom@^18.2.0:
loose-envify "^1.1.0"
scheduler "^0.23.0"
+react-error-boundary@^4.0.4:
+ version "4.0.4"
+ resolved "https://registry.yarnpkg.com/react-error-boundary/-/react-error-boundary-4.0.4.tgz#d2e84505b0a67cec7a6bf33b0146faadfe31597d"
+ integrity sha512-AbqMFx8bCsob8rCHZvJYQ42MQijK0/034RUvan9qrqyJCpazr8d9vKHrysbxcr6odoHLZvQEcYomFPoIqH9fow==
+ dependencies:
+ "@babel/runtime" "^7.12.5"
+
react-fast-compare@^2.0.1:
version "2.0.4"
resolved "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-2.0.4.tgz"