Simplify i18n: remove old react-intl artifacts, rename formatMessage to t, replace FormattedMessage with t.rich().

- Rewrite messages.ts to plain string key maps (remove MessageDescriptor)
- Rewrite useMessages hook to expose t from useTranslations() directly
- Rename formatMessage → t across 193 consumer files
- Replace custom FormattedMessage component with next-intl t.rich()
- Update 52 language files to use rich text tags (<b>, <a>)
- Remove all direct imports from @/components/messages in favor of useMessages()

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Mike Cao 2026-02-07 10:10:21 -08:00
parent 80cad6ea65
commit 50edb71687
247 changed files with 1660 additions and 2194 deletions

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "البيانات المجمعة", "collected-data": "البيانات المجمعة",
"confirm-delete": "هل أنت متأكد من حذف {target}?", "confirm-delete": "هل أنت متأكد من حذف {target}?",
"confirm-leave": "هل أنت متأكد من مغادرة {target}?", "confirm-leave": "هل أنت متأكد من مغادرة <b>{target}</b>?",
"confirm-remove": "هل انت متأكد من حذف {target}?", "confirm-remove": "هل انت متأكد من حذف <b>{target}</b>?",
"confirm-reset": "هل أنت متأكد من اعادة تعيين الإحصائيات لـ {target}؟", "confirm-reset": "هل أنت متأكد من اعادة تعيين الإحصائيات لـ {target}؟",
"delete-team-warning": "سيؤدي حذف الفريق أيضًا إلى حذف كافة مواقع الفريق", "delete-team-warning": "سيؤدي حذف الفريق أيضًا إلى حذف كافة مواقع الفريق",
"delete-website-warning": "سيتم حذف كافة بيانات الموقع.", "delete-website-warning": "سيتم حذف كافة بيانات الموقع.",
"error": "حدث خطأ ما.", "error": "حدث خطأ ما.",
"event-log": "{event} في {url}", "event-log": "<b>{event}</b> في <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "الذهاب إلى الإعدادات", "go-to-settings": "الذهاب إلى الإعدادات",
"incorrect-username-password": "اسم المستخدم او كلمة المرور غير صحيحة.", "incorrect-username-password": "اسم المستخدم او كلمة المرور غير صحيحة.",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "تم حذف المستخدم.", "user-deleted": "تم حذف المستخدم.",
"viewed-page": "شوهدت الصفحة", "viewed-page": "شوهدت الصفحة",
"visitor-log": "زائر من {country} يستخدم {browser} على {os} {device}" "visitor-log": "زائر من <b>{country}</b> يستخدم <b>{browser}</b> على <b>{os}</b> <b>{device}</b>"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Сабраныя дадзеныя", "collected-data": "Сабраныя дадзеныя",
"confirm-delete": "Вы дакладна хочаце выдаліць {target}?", "confirm-delete": "Вы дакладна хочаце выдаліць {target}?",
"confirm-leave": "Вы дакладна хочаце пакінуць {target}?", "confirm-leave": "Вы дакладна хочаце пакінуць <b>{target}</b>?",
"confirm-remove": "Вы дакладна хочаце выдаліць {target}?", "confirm-remove": "Вы дакладна хочаце выдаліць <b>{target}</b>?",
"confirm-reset": "Вы дакладна хочаце скінуць {target} статыстыку?", "confirm-reset": "Вы дакладна хочаце скінуць {target} статыстыку?",
"delete-team-warning": "Выдаленне каманды таксама выдаліць усе сайты каманды.", "delete-team-warning": "Выдаленне каманды таксама выдаліць усе сайты каманды.",
"delete-website-warning": "Усе асацыяваныя дадзеныя будуць таксама выдалены.", "delete-website-warning": "Усе асацыяваныя дадзеныя будуць таксама выдалены.",
"error": "Нешта пайшло не так.", "error": "Нешта пайшло не так.",
"event-log": "{event} на {url}", "event-log": "<b>{event}</b> на <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "Да налад", "go-to-settings": "Да налад",
"incorrect-username-password": "Некарэктнае імя карыстальніка/пароль.", "incorrect-username-password": "Некарэктнае імя карыстальніка/пароль.",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "Карыстальнік выдалены.", "user-deleted": "Карыстальнік выдалены.",
"viewed-page": "Праглядзеў старонку", "viewed-page": "Праглядзеў старонку",
"visitor-log": "Наведвальнік з {country} праз {browser} на {os} {device}" "visitor-log": "Наведвальнік з <b>{country}</b> праз <b>{browser}</b> на <b>{os}</b> <b>{device}</b>"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Невалидна заявка", "bad-request": "Невалидна заявка",
"collected-data": "Събрани данни", "collected-data": "Събрани данни",
"confirm-delete": "Сигурни ли сте, че искате да изтриете {target}?", "confirm-delete": "Сигурни ли сте, че искате да изтриете {target}?",
"confirm-leave": "Сигурни ли сте, че искате да напуснете {target}?", "confirm-leave": "Сигурни ли сте, че искате да напуснете <b>{target}</b>?",
"confirm-remove": "Сигурни ли сте, че искате да премахнете {target}?", "confirm-remove": "Сигурни ли сте, че искате да премахнете <b>{target}</b>?",
"confirm-reset": "Сигурни ли сте, че искате да нулирате {target}?", "confirm-reset": "Сигурни ли сте, че искате да нулирате {target}?",
"delete-team-warning": "Изтриването на екип ще изтрие и всички уебсайтове създадени от екипа.", "delete-team-warning": "Изтриването на екип ще изтрие и всички уебсайтове създадени от екипа.",
"delete-website-warning": "Всички данни за уебсайта ще бъдат изтрити.", "delete-website-warning": "Всички данни за уебсайта ще бъдат изтрити.",
"error": "Възникна грешка.", "error": "Възникна грешка.",
"event-log": "{event} на {url}", "event-log": "<b>{event}</b> на <a>{url}</a>",
"forbidden": "Забранено", "forbidden": "Забранено",
"go-to-settings": "Отидете в настройките", "go-to-settings": "Отидете в настройките",
"incorrect-username-password": "Неправилно потребителско име и/или парола.", "incorrect-username-password": "Неправилно потребителско име и/или парола.",
@ -338,6 +338,6 @@
"unauthorized": "Неоторизиран достъп", "unauthorized": "Неоторизиран достъп",
"user-deleted": "Потребителят е изтрит.", "user-deleted": "Потребителят е изтрит.",
"viewed-page": "Страницата е видяна", "viewed-page": "Страницата е видяна",
"visitor-log": "Посетител от {country}, използващ {browser} на {os} {device}" "visitor-log": "Посетител от <b>{country}</b>, използващ <b>{browser}</b> на <b>{os}</b> <b>{device}</b>"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Collected data", "collected-data": "Collected data",
"confirm-delete": "আপনি কি নিশ্চিত যে আপনি {target} মুছতে চান?", "confirm-delete": "আপনি কি নিশ্চিত যে আপনি {target} মুছতে চান?",
"confirm-leave": "Are you sure you want to leave {target}?", "confirm-leave": "Are you sure you want to leave <b>{target}</b>?",
"confirm-remove": "Are you sure you want to remove {target}?", "confirm-remove": "Are you sure you want to remove <b>{target}</b>?",
"confirm-reset": "আপনি কি নিশ্চিত যে আপনি {target} এর পরিসংখ্যান পুনরায় সেট করতে চান?", "confirm-reset": "আপনি কি নিশ্চিত যে আপনি {target} এর পরিসংখ্যান পুনরায় সেট করতে চান?",
"delete-team-warning": "Deleting a team will also delete all team websites.", "delete-team-warning": "Deleting a team will also delete all team websites.",
"delete-website-warning": "সমস্ত সম্পর্কিত ডেটা পাশাপাশি মুছে ফেলা হবে।", "delete-website-warning": "সমস্ত সম্পর্কিত ডেটা পাশাপাশি মুছে ফেলা হবে।",
"error": "কিছু ভুল হয়েছে।", "error": "কিছু ভুল হয়েছে।",
"event-log": "{event} on {url}", "event-log": "<b>{event}</b> on <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "সেটিংস এ যান", "go-to-settings": "সেটিংস এ যান",
"incorrect-username-password": "ভুল ব্যবহারকারীর নাম/পাসওয়ার্ড।", "incorrect-username-password": "ভুল ব্যবহারকারীর নাম/পাসওয়ার্ড।",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "User deleted.", "user-deleted": "User deleted.",
"viewed-page": "Viewed page", "viewed-page": "Viewed page",
"visitor-log": "{country} থেকে একজন ভিসিটর {ব্রাউজার}, ব্যবহার করছেন {os} {device} এর মধ্যে।" "visitor-log": "<b>{country}</b> থেকে একজন ভিসিটর {ব্রাউজার}, ব্যবহার করছেন <b>{os}</b> <b>{device}</b> এর মধ্যে।"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Collected data", "collected-data": "Collected data",
"confirm-delete": "Jeste li sigurni da želite obrisati {target}?", "confirm-delete": "Jeste li sigurni da želite obrisati {target}?",
"confirm-leave": "Jeste li sigurni da želite napustiti {target}?", "confirm-leave": "Jeste li sigurni da želite napustiti <b>{target}</b>?",
"confirm-remove": "Jeste li sigurni da želite ukloniti {target}?", "confirm-remove": "Jeste li sigurni da želite ukloniti <b>{target}</b>?",
"confirm-reset": "Jeste li sigurni da želite resetovati {target}?", "confirm-reset": "Jeste li sigurni da želite resetovati {target}?",
"delete-team-warning": "Brisanje tima će također obrisati sve web stranice tima.", "delete-team-warning": "Brisanje tima će također obrisati sve web stranice tima.",
"delete-website-warning": "Svi podaci web stranice biće obrisani.", "delete-website-warning": "Svi podaci web stranice biće obrisani.",
"error": "Nešto je pošlo po zlu.", "error": "Nešto je pošlo po zlu.",
"event-log": "{event} na {url}", "event-log": "<b>{event}</b> na <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "Idi na postavke", "go-to-settings": "Idi na postavke",
"incorrect-username-password": "Pogrešno korisničko ime i/ili šifra.", "incorrect-username-password": "Pogrešno korisničko ime i/ili šifra.",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "Korisnik obrisan.", "user-deleted": "Korisnik obrisan.",
"viewed-page": "Pogledana stranica", "viewed-page": "Pogledana stranica",
"visitor-log": "Posjetitelj iz {country} koristi {browser} na {os} {device}" "visitor-log": "Posjetitelj iz <b>{country}</b> koristi <b>{browser}</b> na <b>{os}</b> <b>{device}</b>"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Dades recol·lectades", "collected-data": "Dades recol·lectades",
"confirm-delete": "Segur que vol esborrar {target}?", "confirm-delete": "Segur que vol esborrar {target}?",
"confirm-leave": "Segur que vol abandonar {target}?", "confirm-leave": "Segur que vol abandonar <b>{target}</b>?",
"confirm-remove": "Segur que vol eliminar {target}?", "confirm-remove": "Segur que vol eliminar <b>{target}</b>?",
"confirm-reset": "Segur que vol restablir les estadístiques de {target}?", "confirm-reset": "Segur que vol restablir les estadístiques de {target}?",
"delete-team-warning": "Al eliminar un equip també s'eliminaran tots els llocs web de l'equip.", "delete-team-warning": "Al eliminar un equip també s'eliminaran tots els llocs web de l'equip.",
"delete-website-warning": "També s'esborraran totes les dades relacionades.", "delete-website-warning": "També s'esborraran totes les dades relacionades.",
"error": "S'ha produït un error.", "error": "S'ha produït un error.",
"event-log": "{event} a {url}", "event-log": "<b>{event}</b> a <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "Vés a la configuració", "go-to-settings": "Vés a la configuració",
"incorrect-username-password": "Nom d'usuari o contrasenya incorrectes.", "incorrect-username-password": "Nom d'usuari o contrasenya incorrectes.",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "Usuari eliminat.", "user-deleted": "Usuari eliminat.",
"viewed-page": "Pàgina vista", "viewed-page": "Pàgina vista",
"visitor-log": "Visitant de {country} usant {browser} a {os} {device}" "visitor-log": "Visitant de <b>{country}</b> usant <b>{browser}</b> a <b>{os}</b> <b>{device}</b>"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Collected data", "collected-data": "Collected data",
"confirm-delete": "Opravdu smazat {target}?", "confirm-delete": "Opravdu smazat {target}?",
"confirm-leave": "Are you sure you want to leave {target}?", "confirm-leave": "Are you sure you want to leave <b>{target}</b>?",
"confirm-remove": "Are you sure you want to remove {target}?", "confirm-remove": "Are you sure you want to remove <b>{target}</b>?",
"confirm-reset": "Are your sure you want to reset {target}'s statistics?", "confirm-reset": "Are your sure you want to reset {target}'s statistics?",
"delete-team-warning": "Deleting a team will also delete all team websites.", "delete-team-warning": "Deleting a team will also delete all team websites.",
"delete-website-warning": "Všechna související data budou také smazána.", "delete-website-warning": "Všechna související data budou také smazána.",
"error": "Něco se pokazilo.", "error": "Něco se pokazilo.",
"event-log": "{event} on {url}", "event-log": "<b>{event}</b> on <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "Jít do nastavení", "go-to-settings": "Jít do nastavení",
"incorrect-username-password": "Nesprávné jméno/heslo.", "incorrect-username-password": "Nesprávné jméno/heslo.",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "User deleted.", "user-deleted": "User deleted.",
"viewed-page": "Viewed page", "viewed-page": "Viewed page",
"visitor-log": "Návštěvník z {country} s prohlížečem {browser} na {os} {device}" "visitor-log": "Návštěvník z <b>{country}</b> s prohlížečem <b>{browser}</b> na <b>{os}</b> <b>{device}</b>"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Collected data", "collected-data": "Collected data",
"confirm-delete": "Er du sikker på at du vil slette {target}?", "confirm-delete": "Er du sikker på at du vil slette {target}?",
"confirm-leave": "Are you sure you want to leave {target}?", "confirm-leave": "Are you sure you want to leave <b>{target}</b>?",
"confirm-remove": "Are you sure you want to remove {target}?", "confirm-remove": "Are you sure you want to remove <b>{target}</b>?",
"confirm-reset": "Er du sikker på at du ville nulstille {target}'s statistikker?", "confirm-reset": "Er du sikker på at du ville nulstille {target}'s statistikker?",
"delete-team-warning": "Deleting a team will also delete all team websites.", "delete-team-warning": "Deleting a team will also delete all team websites.",
"delete-website-warning": "Alle tilknyttede data slettes også.", "delete-website-warning": "Alle tilknyttede data slettes også.",
"error": "Noget gik galt.", "error": "Noget gik galt.",
"event-log": "{event} on {url}", "event-log": "<b>{event}</b> on <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "Gå til betjeningspanel", "go-to-settings": "Gå til betjeningspanel",
"incorrect-username-password": "Ugyldigt brugernavn/adgangskode.", "incorrect-username-password": "Ugyldigt brugernavn/adgangskode.",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "User deleted.", "user-deleted": "User deleted.",
"viewed-page": "Viewed page", "viewed-page": "Viewed page",
"visitor-log": "Besøgende fra {country} bruger {browser} på {os} {device}" "visitor-log": "Besøgende fra <b>{country}</b> bruger <b>{browser}</b> på <b>{os}</b> <b>{device}</b>"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Gsammleti Date", "collected-data": "Gsammleti Date",
"confirm-delete": "Sind Sie sich sicher, {target} zlösche?", "confirm-delete": "Sind Sie sich sicher, {target} zlösche?",
"confirm-leave": "Sind Sie sich sicher, {target} zverlah?", "confirm-leave": "Sind Sie sich sicher, <b>{target}</b> zverlah?",
"confirm-remove": "Sind Sie sich sicher, dass Sie {target} wänd entferne?", "confirm-remove": "Sind Sie sich sicher, dass Sie <b>{target}</b> wänd entferne?",
"confirm-reset": "Sind Sie sicher, dass Sie d Statistike vo {target} zruggsetze wänd?", "confirm-reset": "Sind Sie sicher, dass Sie d Statistike vo {target} zruggsetze wänd?",
"delete-team-warning": "Es Team lösche dued ebefalls alli team Websiite lösche.", "delete-team-warning": "Es Team lösche dued ebefalls alli team Websiite lösche.",
"delete-website-warning": "Alli dezueghörige Date werded ebefalls glöscht.", "delete-website-warning": "Alli dezueghörige Date werded ebefalls glöscht.",
"error": "Es isch en Fehler ufträte.", "error": "Es isch en Fehler ufträte.",
"event-log": "{event} uf {url}", "event-log": "<b>{event}</b> uf <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "Zu de Istellige", "go-to-settings": "Zu de Istellige",
"incorrect-username-password": "Falsches Passwort oder Benutzername.", "incorrect-username-password": "Falsches Passwort oder Benutzername.",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "Bnutzer glöscht.", "user-deleted": "Bnutzer glöscht.",
"viewed-page": "Siite agluegt", "viewed-page": "Siite agluegt",
"visitor-log": "Bsuecher us {country} nutzt {browser} uf {os} {device}" "visitor-log": "Bsuecher us <b>{country}</b> nutzt <b>{browser}</b> uf <b>{os}</b> <b>{device}</b>"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Gesammelte Daten", "collected-data": "Gesammelte Daten",
"confirm-delete": "Sind Sie sich sicher, {target} zu löschen?", "confirm-delete": "Sind Sie sich sicher, {target} zu löschen?",
"confirm-leave": "Sind Sie sicher, dass die {target} verlassen möchten?", "confirm-leave": "Sind Sie sicher, dass die <b>{target}</b> verlassen möchten?",
"confirm-remove": "Sind Sie sicher, {target} zu entfernen?", "confirm-remove": "Sind Sie sicher, <b>{target}</b> zu entfernen?",
"confirm-reset": "Sind Sie sicher, dass Sie die Statistiken von {target} zurücksetzen wollen?", "confirm-reset": "Sind Sie sicher, dass Sie die Statistiken von {target} zurücksetzen wollen?",
"delete-team-warning": "Ein Team zu löschen, wird auch alle Team-Websites löschen.", "delete-team-warning": "Ein Team zu löschen, wird auch alle Team-Websites löschen.",
"delete-website-warning": "Alle zugehörigen Daten werden ebenfalls gelöscht.", "delete-website-warning": "Alle zugehörigen Daten werden ebenfalls gelöscht.",
"error": "Es ist ein Fehler aufgetreten.", "error": "Es ist ein Fehler aufgetreten.",
"event-log": "{event} auf {url}", "event-log": "<b>{event}</b> auf <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "Zu den Einstellungen", "go-to-settings": "Zu den Einstellungen",
"incorrect-username-password": "Falsches Passwort oder Benutzername.", "incorrect-username-password": "Falsches Passwort oder Benutzername.",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "Benutzer gelöscht.", "user-deleted": "Benutzer gelöscht.",
"viewed-page": "Seite besucht", "viewed-page": "Seite besucht",
"visitor-log": "Besucher aus {country} benutzt {browser} auf {os} {device}" "visitor-log": "Besucher aus <b>{country}</b> benutzt <b>{browser}</b> auf <b>{os}</b> <b>{device}</b>"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Collected data", "collected-data": "Collected data",
"confirm-delete": "Είστε βέβαιοι ότι θέλετε να διαγράψετε το {target};", "confirm-delete": "Είστε βέβαιοι ότι θέλετε να διαγράψετε το {target};",
"confirm-leave": "Are you sure you want to leave {target}?", "confirm-leave": "Are you sure you want to leave <b>{target}</b>?",
"confirm-remove": "Are you sure you want to remove {target}?", "confirm-remove": "Are you sure you want to remove <b>{target}</b>?",
"confirm-reset": "Are your sure you want to reset {target}'s statistics?", "confirm-reset": "Are your sure you want to reset {target}'s statistics?",
"delete-team-warning": "Deleting a team will also delete all team websites.", "delete-team-warning": "Deleting a team will also delete all team websites.",
"delete-website-warning": "Όλα τα σχετικά δεδομένα θα διαγραφούν επίσης.", "delete-website-warning": "Όλα τα σχετικά δεδομένα θα διαγραφούν επίσης.",
"error": "Κάτι πήγε στραβά.", "error": "Κάτι πήγε στραβά.",
"event-log": "{event} on {url}", "event-log": "<b>{event}</b> on <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "Μεταβείτε στις ρυθμίσεις", "go-to-settings": "Μεταβείτε στις ρυθμίσεις",
"incorrect-username-password": "Εσφαλμένο όνομα χρήστη / κωδικός πρόσβασης.", "incorrect-username-password": "Εσφαλμένο όνομα χρήστη / κωδικός πρόσβασης.",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "User deleted.", "user-deleted": "User deleted.",
"viewed-page": "Viewed page", "viewed-page": "Viewed page",
"visitor-log": "Visitor from {country} using {browser} on {os} {device}" "visitor-log": "Visitor from <b>{country}</b> using <b>{browser}</b> on <b>{os}</b> <b>{device}</b>"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Collected data", "collected-data": "Collected data",
"confirm-delete": "Are you sure you want to delete {target}?", "confirm-delete": "Are you sure you want to delete {target}?",
"confirm-leave": "Are you sure you want to leave {target}?", "confirm-leave": "Are you sure you want to leave <b>{target}</b>?",
"confirm-remove": "Are you sure you want to remove {target}?", "confirm-remove": "Are you sure you want to remove <b>{target}</b>?",
"confirm-reset": "Are you sure you want to reset {target}'s statistics?", "confirm-reset": "Are you sure you want to reset {target}'s statistics?",
"delete-team-warning": "Deleting a team will also delete all team websites.", "delete-team-warning": "Deleting a team will also delete all team websites.",
"delete-website-warning": "All associated data will be deleted as well.", "delete-website-warning": "All associated data will be deleted as well.",
"error": "Something went wrong.", "error": "Something went wrong.",
"event-log": "{event} on {url}", "event-log": "<b>{event}</b> on <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "Go to settings", "go-to-settings": "Go to settings",
"incorrect-username-password": "Incorrect username/password.", "incorrect-username-password": "Incorrect username/password.",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "User deleted.", "user-deleted": "User deleted.",
"viewed-page": "Viewed page", "viewed-page": "Viewed page",
"visitor-log": "Visitor from {country} using {browser} on {os} {device}" "visitor-log": "Visitor from <b>{country}</b> using <b>{browser}</b> on <b>{os}</b> <b>{device}</b>"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Collected data", "collected-data": "Collected data",
"confirm-delete": "Are you sure you want to delete {target}?", "confirm-delete": "Are you sure you want to delete {target}?",
"confirm-leave": "Are you sure you want to leave {target}?", "confirm-leave": "Are you sure you want to leave <b>{target}</b>?",
"confirm-remove": "Are you sure you want to remove {target}?", "confirm-remove": "Are you sure you want to remove <b>{target}</b>?",
"confirm-reset": "Are you sure you want to reset {target}?", "confirm-reset": "Are you sure you want to reset {target}?",
"delete-team-warning": "Deleting a team will also delete all team websites.", "delete-team-warning": "Deleting a team will also delete all team websites.",
"delete-website-warning": "All website data will be deleted.", "delete-website-warning": "All website data will be deleted.",
"error": "Something went wrong.", "error": "Something went wrong.",
"event-log": "{event} on {url}", "event-log": "<b>{event}</b> on <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "Go to settings", "go-to-settings": "Go to settings",
"incorrect-username-password": "Incorrect username and/or password.", "incorrect-username-password": "Incorrect username and/or password.",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "User deleted.", "user-deleted": "User deleted.",
"viewed-page": "Viewed page", "viewed-page": "Viewed page",
"visitor-log": "Visitor from {country} using {browser} on {os} {device}" "visitor-log": "Visitor from <b>{country}</b> using <b>{browser}</b> on <b>{os}</b> <b>{device}</b>"
} }
} }

View file

@ -299,13 +299,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Datos obtenidos", "collected-data": "Datos obtenidos",
"confirm-delete": "¿Seguro que quieres eliminar {target}?", "confirm-delete": "¿Seguro que quieres eliminar {target}?",
"confirm-leave": "¿Seguro que quieres abandonar {target}?", "confirm-leave": "¿Seguro que quieres abandonar <b>{target}</b>?",
"confirm-remove": "¿Estás seguro de que desea eliminar {target}?", "confirm-remove": "¿Estás seguro de que desea eliminar <b>{target}</b>?",
"confirm-reset": "¿Seguro que quieres BORRAR las analíticas de {target}?", "confirm-reset": "¿Seguro que quieres BORRAR las analíticas de {target}?",
"delete-team-warning": "Al eliminar un equipo, también se eliminarán todos los sitios web del equipo.", "delete-team-warning": "Al eliminar un equipo, también se eliminarán todos los sitios web del equipo.",
"delete-website-warning": "Toda la información relacionada será eliminada.", "delete-website-warning": "Toda la información relacionada será eliminada.",
"error": "Algo falló.", "error": "Algo falló.",
"event-log": "{event} en {url}", "event-log": "<b>{event}</b> en <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "Ir a la configuración", "go-to-settings": "Ir a la configuración",
"incorrect-username-password": "Nombre de usuario o contraseña incorrectos.", "incorrect-username-password": "Nombre de usuario o contraseña incorrectos.",
@ -339,6 +339,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "Usuario eliminado.", "user-deleted": "Usuario eliminado.",
"viewed-page": "Página vista", "viewed-page": "Página vista",
"visitor-log": "Visitante desde {country} usando {browser} en {os} {device}" "visitor-log": "Visitante desde <b>{country}</b> usando <b>{browser}</b> en <b>{os}</b> <b>{device}</b>"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "داده‌های جمع‌آوری شده", "collected-data": "داده‌های جمع‌آوری شده",
"confirm-delete": "آیا مطمئن هستید می‌خواهید {target} را حذف کنید؟", "confirm-delete": "آیا مطمئن هستید می‌خواهید {target} را حذف کنید؟",
"confirm-leave": "آیا مطمئن هستید می‌خواهید از {target} خارج شوید؟", "confirm-leave": "آیا مطمئن هستید می‌خواهید از <b>{target}</b> خارج شوید؟",
"confirm-remove": "آیا مطمئن هستید می‌خواهید {target} را حذف کنید؟", "confirm-remove": "آیا مطمئن هستید می‌خواهید <b>{target}</b> را حذف کنید؟",
"confirm-reset": "آیا مطمئن هستید می‌خواهید {target} را بازنشانی کنید؟", "confirm-reset": "آیا مطمئن هستید می‌خواهید {target} را بازنشانی کنید؟",
"delete-team-warning": "با حذف تیم، تمامی وب‌سایت‌های تیم هم حذف خواهند شد.", "delete-team-warning": "با حذف تیم، تمامی وب‌سایت‌های تیم هم حذف خواهند شد.",
"delete-website-warning": "همه‌ی داده‌های وب‌سایت هم حذف خواهد شد.", "delete-website-warning": "همه‌ی داده‌های وب‌سایت هم حذف خواهد شد.",
"error": "مشکلی پیش آمده است.", "error": "مشکلی پیش آمده است.",
"event-log": "{event} در {url}", "event-log": "<b>{event}</b> در <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "رفتن به تنظیمات", "go-to-settings": "رفتن به تنظیمات",
"incorrect-username-password": "نام کاربری / رمز نادرست است.", "incorrect-username-password": "نام کاربری / رمز نادرست است.",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "کاربر حذف شد.", "user-deleted": "کاربر حذف شد.",
"viewed-page": "صفحه مشاهده شد", "viewed-page": "صفحه مشاهده شد",
"visitor-log": "بازدیدکننده از کشور {country} با مروگر {browser} در {os} {device}" "visitor-log": "بازدیدکننده از کشور <b>{country}</b> با مروگر <b>{browser}</b> در <b>{os}</b> <b>{device}</b>"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Virheellinen pyyntö", "bad-request": "Virheellinen pyyntö",
"collected-data": "Kerätty data", "collected-data": "Kerätty data",
"confirm-delete": "Haluatko varmasti poistaa sivuston {target}?", "confirm-delete": "Haluatko varmasti poistaa sivuston {target}?",
"confirm-leave": "Haluatko varmasti poistua {target}?", "confirm-leave": "Haluatko varmasti poistua <b>{target}</b>?",
"confirm-remove": "Haluatko varmasti poistaa {target}?", "confirm-remove": "Haluatko varmasti poistaa <b>{target}</b>?",
"confirm-reset": "Haluatko varmasti poistaa sivuston {target} tilastot?", "confirm-reset": "Haluatko varmasti poistaa sivuston {target} tilastot?",
"delete-team-warning": "Tiimin poistaminen poistaa myös kaikki tiimin sivustot.", "delete-team-warning": "Tiimin poistaminen poistaa myös kaikki tiimin sivustot.",
"delete-website-warning": "Kaikki siihen liittyvät tiedot poistetaan.", "delete-website-warning": "Kaikki siihen liittyvät tiedot poistetaan.",
"error": "Jotain meni pieleen.", "error": "Jotain meni pieleen.",
"event-log": "{event} on {url}", "event-log": "<b>{event}</b> on <a>{url}</a>",
"forbidden": "Kielletty", "forbidden": "Kielletty",
"go-to-settings": "Mene asetuksiin", "go-to-settings": "Mene asetuksiin",
"incorrect-username-password": "Väärä käyttäjänimi/salasana.", "incorrect-username-password": "Väärä käyttäjänimi/salasana.",
@ -338,6 +338,6 @@
"unauthorized": "Ei oikeuksia", "unauthorized": "Ei oikeuksia",
"user-deleted": "Käyttäjä poistettu.", "user-deleted": "Käyttäjä poistettu.",
"viewed-page": "Katsottu sivu", "viewed-page": "Katsottu sivu",
"visitor-log": "Vierailija maasta {country} selaimella {browser} laitteella {os} {device}" "visitor-log": "Vierailija maasta <b>{country}</b> selaimella <b>{browser}</b> laitteella <b>{os}</b> <b>{device}</b>"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Collected data", "collected-data": "Collected data",
"confirm-delete": "Ert tú sikkur at tú ynskir at strika {target}?", "confirm-delete": "Ert tú sikkur at tú ynskir at strika {target}?",
"confirm-leave": "Are you sure you want to leave {target}?", "confirm-leave": "Are you sure you want to leave <b>{target}</b>?",
"confirm-remove": "Are you sure you want to remove {target}?", "confirm-remove": "Are you sure you want to remove <b>{target}</b>?",
"confirm-reset": "Are your sure you want to reset {target}'s statistics?", "confirm-reset": "Are your sure you want to reset {target}'s statistics?",
"delete-team-warning": "Deleting a team will also delete all team websites.", "delete-team-warning": "Deleting a team will also delete all team websites.",
"delete-website-warning": "Øll data ið er knýtt at verður eisini strika.", "delete-website-warning": "Øll data ið er knýtt at verður eisini strika.",
"error": "Okkurt bleiv gali.", "error": "Okkurt bleiv gali.",
"event-log": "{event} on {url}", "event-log": "<b>{event}</b> on <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "Far til stillingar", "go-to-settings": "Far til stillingar",
"incorrect-username-password": "Skeivt brúkaranavn/loyniorð.", "incorrect-username-password": "Skeivt brúkaranavn/loyniorð.",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "User deleted.", "user-deleted": "User deleted.",
"viewed-page": "Viewed page", "viewed-page": "Viewed page",
"visitor-log": "Vitjandi frá {country} brúkar {browser} á {os} {device}" "visitor-log": "Vitjandi frá <b>{country}</b> brúkar <b>{browser}</b> á <b>{os}</b> <b>{device}</b>"
} }
} }

View file

@ -300,13 +300,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Donnée collectée", "collected-data": "Donnée collectée",
"confirm-delete": "Êtes-vous sûr de vouloir supprimer {target} ?", "confirm-delete": "Êtes-vous sûr de vouloir supprimer {target} ?",
"confirm-leave": "Êtes-vous sûr de vouloir quitter {target} ?", "confirm-leave": "Êtes-vous sûr de vouloir quitter <b>{target}</b> ?",
"confirm-remove": "Êtes-vous sûr de vouloir retirer {target} ?", "confirm-remove": "Êtes-vous sûr de vouloir retirer <b>{target}</b> ?",
"confirm-reset": "Êtes-vous sûr de vouloir réinitialiser les statistiques de {target} ?", "confirm-reset": "Êtes-vous sûr de vouloir réinitialiser les statistiques de {target} ?",
"delete-team-warning": "Supprimer une équipe supprimera aussi tous les sites de cette équipe.", "delete-team-warning": "Supprimer une équipe supprimera aussi tous les sites de cette équipe.",
"delete-website-warning": "Toutes les données associées seront supprimées.", "delete-website-warning": "Toutes les données associées seront supprimées.",
"error": "Un problème est survenu.", "error": "Un problème est survenu.",
"event-log": "{event} sur {url}", "event-log": "<b>{event}</b> sur <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "Aller aux paramètres", "go-to-settings": "Aller aux paramètres",
"incorrect-username-password": "Nom d'utilisateur/Mot de passe incorrect.", "incorrect-username-password": "Nom d'utilisateur/Mot de passe incorrect.",
@ -340,6 +340,6 @@
"unauthorized": "Non authorisé!", "unauthorized": "Non authorisé!",
"user-deleted": "Utilisateur supprimé.", "user-deleted": "Utilisateur supprimé.",
"viewed-page": "Page vue", "viewed-page": "Page vue",
"visitor-log": "Visiteur de {country} utilisant {browser} sur {os} {device}" "visitor-log": "Visiteur de <b>{country}</b> utilisant <b>{browser}</b> sur <b>{os}</b> <b>{device}</b>"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Datos recopilados", "collected-data": "Datos recopilados",
"confirm-delete": "Estás seguro/a de que queres eliminar {target}?", "confirm-delete": "Estás seguro/a de que queres eliminar {target}?",
"confirm-leave": "Estás seguro/a de que queres deixar {target}?", "confirm-leave": "Estás seguro/a de que queres deixar <b>{target}</b>?",
"confirm-remove": "Estás seguro/a de que queres eliminar {target}?", "confirm-remove": "Estás seguro/a de que queres eliminar <b>{target}</b>?",
"confirm-reset": "Estás seguro/a de querer restablecer as estatísticas de {target}?", "confirm-reset": "Estás seguro/a de querer restablecer as estatísticas de {target}?",
"delete-team-warning": "Eliminar un equipo tamén eliminará tódolos sitios web do equipo.", "delete-team-warning": "Eliminar un equipo tamén eliminará tódolos sitios web do equipo.",
"delete-website-warning": "Tamén serán borrados tódolos datos asociados.", "delete-website-warning": "Tamén serán borrados tódolos datos asociados.",
"error": "Houbo un fallo.", "error": "Houbo un fallo.",
"event-log": "{event} en {url}", "event-log": "<b>{event}</b> en <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "Ir aos axustes", "go-to-settings": "Ir aos axustes",
"incorrect-username-password": "Credenciais incorrectas.", "incorrect-username-password": "Credenciais incorrectas.",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "Usuario eliminado.", "user-deleted": "Usuario eliminado.",
"viewed-page": "Páxina vista", "viewed-page": "Páxina vista",
"visitor-log": "Visitante desde {country} usando {browser} en {os} {device}" "visitor-log": "Visitante desde <b>{country}</b> usando <b>{browser}</b> en <b>{os}</b> <b>{device}</b>"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Collected data", "collected-data": "Collected data",
"confirm-delete": "האם באמת למחוק את {target}?", "confirm-delete": "האם באמת למחוק את {target}?",
"confirm-leave": "Are you sure you want to leave {target}?", "confirm-leave": "Are you sure you want to leave <b>{target}</b>?",
"confirm-remove": "Are you sure you want to remove {target}?", "confirm-remove": "Are you sure you want to remove <b>{target}</b>?",
"confirm-reset": "Are your sure you want to reset {target}'s statistics?", "confirm-reset": "Are your sure you want to reset {target}'s statistics?",
"delete-team-warning": "Deleting a team will also delete all team websites.", "delete-team-warning": "Deleting a team will also delete all team websites.",
"delete-website-warning": "כל המידע המקושר יימחק", "delete-website-warning": "כל המידע המקושר יימחק",
"error": "משהו השתבש", "error": "משהו השתבש",
"event-log": "{event} on {url}", "event-log": "<b>{event}</b> on <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "להדרותג", "go-to-settings": "להדרותג",
"incorrect-username-password": "שם משתמש או סיסמה לא נכונים", "incorrect-username-password": "שם משתמש או סיסמה לא נכונים",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "User deleted.", "user-deleted": "User deleted.",
"viewed-page": "Viewed page", "viewed-page": "Viewed page",
"visitor-log": "מבקר ממדינת {country} משתמבש בדפדפן {browser} ב-{os} {device}" "visitor-log": "מבקר ממדינת <b>{country}</b> משתמבש בדפדפן <b>{browser}</b> ב-<b>{os}</b> <b>{device}</b>"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Collected data", "collected-data": "Collected data",
"confirm-delete": "क्या आप वाकई में {target} हटाना चाहते हैं?", "confirm-delete": "क्या आप वाकई में {target} हटाना चाहते हैं?",
"confirm-leave": "Are you sure you want to leave {target}?", "confirm-leave": "Are you sure you want to leave <b>{target}</b>?",
"confirm-remove": "Are you sure you want to remove {target}?", "confirm-remove": "Are you sure you want to remove <b>{target}</b>?",
"confirm-reset": "Are your sure you want to reset {target}'s statistics?", "confirm-reset": "Are your sure you want to reset {target}'s statistics?",
"delete-team-warning": "Deleting a team will also delete all team websites.", "delete-team-warning": "Deleting a team will also delete all team websites.",
"delete-website-warning": "सभी संबद्ध डेटा को भी हटा दिया जाएगा।", "delete-website-warning": "सभी संबद्ध डेटा को भी हटा दिया जाएगा।",
"error": "कुछ गलत हो गया।", "error": "कुछ गलत हो गया।",
"event-log": "{event} on {url}", "event-log": "<b>{event}</b> on <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "समायोजन में जाइए", "go-to-settings": "समायोजन में जाइए",
"incorrect-username-password": "ग़लत उपयोगकर्ता नाम / पासवर्ड।", "incorrect-username-password": "ग़लत उपयोगकर्ता नाम / पासवर्ड।",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "User deleted.", "user-deleted": "User deleted.",
"viewed-page": "Viewed page", "viewed-page": "Viewed page",
"visitor-log": "{country} का आगंतुक, जो {browser} का उपयोग करता है, {os} यन्त्र पर" "visitor-log": "<b>{country}</b> का आगंतुक, जो <b>{browser}</b> का उपयोग करता है, <b>{os}</b> यन्त्र पर"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Collected data", "collected-data": "Collected data",
"confirm-delete": "Jeste li sigurni da želite obrisati {target}?", "confirm-delete": "Jeste li sigurni da želite obrisati {target}?",
"confirm-leave": "Are you sure you want to leave {target}?", "confirm-leave": "Are you sure you want to leave <b>{target}</b>?",
"confirm-remove": "Are you sure you want to remove {target}?", "confirm-remove": "Are you sure you want to remove <b>{target}</b>?",
"confirm-reset": "Jeste li sigurni da želite resetirati {target}'s statistiku?", "confirm-reset": "Jeste li sigurni da želite resetirati {target}'s statistiku?",
"delete-team-warning": "Deleting a team will also delete all team websites.", "delete-team-warning": "Deleting a team will also delete all team websites.",
"delete-website-warning": "All website data will be deleted.", "delete-website-warning": "All website data will be deleted.",
"error": "Something went wrong.", "error": "Something went wrong.",
"event-log": "{event} on {url}", "event-log": "<b>{event}</b> on <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "Idi u postavke", "go-to-settings": "Idi u postavke",
"incorrect-username-password": "Neispravno korisničke ime/lozinka.", "incorrect-username-password": "Neispravno korisničke ime/lozinka.",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "User deleted.", "user-deleted": "User deleted.",
"viewed-page": "Viewed page", "viewed-page": "Viewed page",
"visitor-log": "Visitor from {country} using {browser} on {os} {device}" "visitor-log": "Visitor from <b>{country}</b> using <b>{browser}</b> on <b>{os}</b> <b>{device}</b>"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Collected data", "collected-data": "Collected data",
"confirm-delete": "Biztos, hogy törölni szeretnéd {target} elemet?", "confirm-delete": "Biztos, hogy törölni szeretnéd {target} elemet?",
"confirm-leave": "Are you sure you want to leave {target}?", "confirm-leave": "Are you sure you want to leave <b>{target}</b>?",
"confirm-remove": "Are you sure you want to remove {target}?", "confirm-remove": "Are you sure you want to remove <b>{target}</b>?",
"confirm-reset": "Are your sure you want to reset {target}'s statistics?", "confirm-reset": "Are your sure you want to reset {target}'s statistics?",
"delete-team-warning": "Deleting a team will also delete all team websites.", "delete-team-warning": "Deleting a team will also delete all team websites.",
"delete-website-warning": "Minden társított adat törlésre kerül.", "delete-website-warning": "Minden társított adat törlésre kerül.",
"error": "Valami baj történt.", "error": "Valami baj történt.",
"event-log": "{event} on {url}", "event-log": "<b>{event}</b> on <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "Tovább a beállításokhoz", "go-to-settings": "Tovább a beállításokhoz",
"incorrect-username-password": "Érvénytelen felhasználónév/jelszó.", "incorrect-username-password": "Érvénytelen felhasználónév/jelszó.",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "User deleted.", "user-deleted": "User deleted.",
"viewed-page": "Viewed page", "viewed-page": "Viewed page",
"visitor-log": "Látógató {country} területéről, {os} {device} eszközön, {browser} böngészőből." "visitor-log": "Látógató <b>{country}</b> területéről, <b>{os}</b> <b>{device}</b> eszközön, <b>{browser}</b> böngészőből."
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Data dikumpulkan", "collected-data": "Data dikumpulkan",
"confirm-delete": "Apakah kamu yakin ingin menghapus {target}?", "confirm-delete": "Apakah kamu yakin ingin menghapus {target}?",
"confirm-leave": "Apakah Anda yakin ingin meninggalkan {target}?", "confirm-leave": "Apakah Anda yakin ingin meninggalkan <b>{target}</b>?",
"confirm-remove": "Apakah Anda yakin ingin menghapus {target}?", "confirm-remove": "Apakah Anda yakin ingin menghapus <b>{target}</b>?",
"confirm-reset": "Anda yakin ingin mengatur ulang statistik {target}?", "confirm-reset": "Anda yakin ingin mengatur ulang statistik {target}?",
"delete-team-warning": "Menghapus tim juga akan menghapus semua situs web yang terkait.", "delete-team-warning": "Menghapus tim juga akan menghapus semua situs web yang terkait.",
"delete-website-warning": "Semua data terkait juga akan dihapus.", "delete-website-warning": "Semua data terkait juga akan dihapus.",
"error": "Ada yang salah.", "error": "Ada yang salah.",
"event-log": "{event} on {url}", "event-log": "<b>{event}</b> on <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "Pergi ke pengaturan", "go-to-settings": "Pergi ke pengaturan",
"incorrect-username-password": "Nama pengguna/kata sandi salah.", "incorrect-username-password": "Nama pengguna/kata sandi salah.",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "Pengguna telah dihapus.", "user-deleted": "Pengguna telah dihapus.",
"viewed-page": "Halaman dilihat", "viewed-page": "Halaman dilihat",
"visitor-log": "Pengunjung dari {country} dengan {browser} di {device} {os}" "visitor-log": "Pengunjung dari <b>{country}</b> dengan <b>{browser}</b> di <b>{device}</b> <b>{os}</b>"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Collected data", "collected-data": "Collected data",
"confirm-delete": "Sei sicuro di voler eliminare {target}?", "confirm-delete": "Sei sicuro di voler eliminare {target}?",
"confirm-leave": "Are you sure you want to leave {target}?", "confirm-leave": "Are you sure you want to leave <b>{target}</b>?",
"confirm-remove": "Are you sure you want to remove {target}?", "confirm-remove": "Are you sure you want to remove <b>{target}</b>?",
"confirm-reset": "Sei sicuro di voler azzerare le statistiche di {target}?", "confirm-reset": "Sei sicuro di voler azzerare le statistiche di {target}?",
"delete-team-warning": "Deleting a team will also delete all team websites.", "delete-team-warning": "Deleting a team will also delete all team websites.",
"delete-website-warning": "Saranno eliminati anche tutti i dati associati.", "delete-website-warning": "Saranno eliminati anche tutti i dati associati.",
"error": "Si è verificato un errore.", "error": "Si è verificato un errore.",
"event-log": "{event} on {url}", "event-log": "<b>{event}</b> on <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "Vai alle impostazioni", "go-to-settings": "Vai alle impostazioni",
"incorrect-username-password": "Username o password non corretti.", "incorrect-username-password": "Username o password non corretti.",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "User deleted.", "user-deleted": "User deleted.",
"viewed-page": "Viewed page", "viewed-page": "Viewed page",
"visitor-log": "Utenti da {country} tramite {browser} su {os} {device}" "visitor-log": "Utenti da <b>{country}</b> tramite <b>{browser}</b> su <b>{os}</b> <b>{device}</b>"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "収集されたデータ", "collected-data": "収集されたデータ",
"confirm-delete": "{target}を削除してもよろしいですか?", "confirm-delete": "{target}を削除してもよろしいですか?",
"confirm-leave": "{target}から離脱してもよろしいですか?", "confirm-leave": "<b>{target}</b>から離脱してもよろしいですか?",
"confirm-remove": "{target}を削除してもよろしいですか?", "confirm-remove": "<b>{target}</b>を削除してもよろしいですか?",
"confirm-reset": "{target}をリセットしてもよろしいですか?", "confirm-reset": "{target}をリセットしてもよろしいですか?",
"delete-team-warning": "チームを削除すると、そのチームが管理しているWebサイトもすべて削除されます。", "delete-team-warning": "チームを削除すると、そのチームが管理しているWebサイトもすべて削除されます。",
"delete-website-warning": "Webサイトのデータがすべて削除されます。", "delete-website-warning": "Webサイトのデータがすべて削除されます。",
"error": "未知のエラーが発生しました。", "error": "未知のエラーが発生しました。",
"event-log": "{url}の{event}", "event-log": "<a>{url}</a>の<b>{event}</b>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "設定に移動する", "go-to-settings": "設定に移動する",
"incorrect-username-password": "ユーザー名またはパスワードが間違っています。", "incorrect-username-password": "ユーザー名またはパスワードが間違っています。",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "ユーザーが削除されました。", "user-deleted": "ユーザーが削除されました。",
"viewed-page": "閲覧されたページ", "viewed-page": "閲覧されたページ",
"visitor-log": "{os}({device})で{browser}を使用している{country}からの訪問者" "visitor-log": "<b>{os}</b>(<b>{device}</b>)で<b>{browser}</b>を使用している<b>{country}</b>からの訪問者"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "ទិន្នន័យដែលបានប្រមូលទុក", "collected-data": "ទិន្នន័យដែលបានប្រមូលទុក",
"confirm-delete": "តើអ្នកប្រាកដថាចង់លុប {target} ទេ?", "confirm-delete": "តើអ្នកប្រាកដថាចង់លុប {target} ទេ?",
"confirm-leave": "តើអ្នកប្រាកដថាចង់ចាកចេញ {target} ទេ?", "confirm-leave": "តើអ្នកប្រាកដថាចង់ចាកចេញ <b>{target}</b> ទេ?",
"confirm-remove": "តើអ្នកប្រាកដថាចង់លុប {target} ទេ?", "confirm-remove": "តើអ្នកប្រាកដថាចង់លុប <b>{target}</b> ទេ?",
"confirm-reset": "តើអ្នកប្រាកដថាចង់កំណត់ស្ថិតិរបស់ {target} ឡើងវិញទេ?", "confirm-reset": "តើអ្នកប្រាកដថាចង់កំណត់ស្ថិតិរបស់ {target} ឡើងវិញទេ?",
"delete-team-warning": "ពេលលុបក្រុម គេហទំព័ររបស់ក្រុមក៏នឹងត្រូវលប់ចោលទាំងអស់ផងដែរ។", "delete-team-warning": "ពេលលុបក្រុម គេហទំព័ររបស់ក្រុមក៏នឹងត្រូវលប់ចោលទាំងអស់ផងដែរ។",
"delete-website-warning": "ទិន្នន័យរបស់គេហទំព័រទាំងអស់នឹងត្រូវលុបចោល។", "delete-website-warning": "ទិន្នន័យរបស់គេហទំព័រទាំងអស់នឹងត្រូវលុបចោល។",
"error": "មាន​អ្វីមួយ​មិន​ប្រក្រតី។", "error": "មាន​អ្វីមួយ​មិន​ប្រក្រតី។",
"event-log": "{event} on {url}", "event-log": "<b>{event}</b> on <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "ការកំណត់", "go-to-settings": "ការកំណត់",
"incorrect-username-password": "ឈ្មោះអ្នកប្រើឬពាក្យសម្ងាត់មិនត្រឹមត្រូវ។", "incorrect-username-password": "ឈ្មោះអ្នកប្រើឬពាក្យសម្ងាត់មិនត្រឹមត្រូវ។",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "អ្នកប្រើប្រាស់ត្រូវបានលុបចោល។", "user-deleted": "អ្នកប្រើប្រាស់ត្រូវបានលុបចោល។",
"viewed-page": "ទំព័រដែលបានមើល", "viewed-page": "ទំព័រដែលបានមើល",
"visitor-log": "អ្នកមើលពីប្រទេស {country} ប្រើប្រាស់កម្មវិធី {browser} លើឧបករណ៍ {os} {device}" "visitor-log": "អ្នកមើលពីប្រទេស <b>{country}</b> ប្រើប្រាស់កម្មវិធី <b>{browser}</b> លើឧបករណ៍ <b>{os}</b> <b>{device}</b>"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "수집된 데이터", "collected-data": "수집된 데이터",
"confirm-delete": "{target}을(를) 삭제하시겠습니까?", "confirm-delete": "{target}을(를) 삭제하시겠습니까?",
"confirm-leave": "{target}을(를) 떠나시겠습니까?", "confirm-leave": "<b>{target}</b>을(를) 떠나시겠습니까?",
"confirm-remove": "{target}을(를) 제거하시겠습니까?", "confirm-remove": "<b>{target}</b>을(를) 제거하시겠습니까?",
"confirm-reset": "{target}을(를) 초기화하시겠습니까?", "confirm-reset": "{target}을(를) 초기화하시겠습니까?",
"delete-team-warning": "팀을 삭제하면 팀에 등록된 모든 웹사이트도 삭제됩니다.", "delete-team-warning": "팀을 삭제하면 팀에 등록된 모든 웹사이트도 삭제됩니다.",
"delete-website-warning": "관련된 모든 데이터가 삭제됩니다.", "delete-website-warning": "관련된 모든 데이터가 삭제됩니다.",
"error": "문제가 발생했습니다.", "error": "문제가 발생했습니다.",
"event-log": "{event} - {url}", "event-log": "<b>{event}</b> - <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "설정으로 이동", "go-to-settings": "설정으로 이동",
"incorrect-username-password": "사용자 이름 또는 비밀번호를 잘못 입력했습니다.", "incorrect-username-password": "사용자 이름 또는 비밀번호를 잘못 입력했습니다.",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "사용자를 삭제했습니다.", "user-deleted": "사용자를 삭제했습니다.",
"viewed-page": "조회한 페이지", "viewed-page": "조회한 페이지",
"visitor-log": "{os} {device}에서 {browser}을(를) 사용하는 {country}의 방문자" "visitor-log": "<b>{os}</b> <b>{device}</b>에서 <b>{browser}</b>을(를) 사용하는 <b>{country}</b>의 방문자"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Collected data", "collected-data": "Collected data",
"confirm-delete": "Ar esate tikri, jog norite ištrinti svetainę {target}?", "confirm-delete": "Ar esate tikri, jog norite ištrinti svetainę {target}?",
"confirm-leave": "Ar esate tikri, jog norite palikti {target}?", "confirm-leave": "Ar esate tikri, jog norite palikti <b>{target}</b>?",
"confirm-remove": "Ar esate tikri, jog norite ištrinti {target}?", "confirm-remove": "Ar esate tikri, jog norite ištrinti <b>{target}</b>?",
"confirm-reset": "Are esate tikri, jog norite atstatyti svetainės {target} statistikos duomenis?", "confirm-reset": "Are esate tikri, jog norite atstatyti svetainės {target} statistikos duomenis?",
"delete-team-warning": "Ištrinant komandą bus ištrintos ir visos komandos svetainės.", "delete-team-warning": "Ištrinant komandą bus ištrintos ir visos komandos svetainės.",
"delete-website-warning": "Visi susiję duomenys taip pat bus ištrinti.", "delete-website-warning": "Visi susiję duomenys taip pat bus ištrinti.",
"error": "Kažkas įvyko ne taip.", "error": "Kažkas įvyko ne taip.",
"event-log": "{event} on {url}", "event-log": "<b>{event}</b> on <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "Eiti į nustatymus", "go-to-settings": "Eiti į nustatymus",
"incorrect-username-password": "Neteisingas vartotojo vardas/slaptažodis.", "incorrect-username-password": "Neteisingas vartotojo vardas/slaptažodis.",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "Vartotojas ištrintas.", "user-deleted": "Vartotojas ištrintas.",
"viewed-page": "Viewed page", "viewed-page": "Viewed page",
"visitor-log": "Lankytojas iš {country}, naudojantis {browser} sistemoje {os} {device}" "visitor-log": "Lankytojas iš <b>{country}</b>, naudojantis <b>{browser}</b> sistemoje <b>{os}</b> <b>{device}</b>"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Цуглуулсан өгөгдөл", "collected-data": "Цуглуулсан өгөгдөл",
"confirm-delete": "Та {target}-г устгахдаа итгэлтэй байна уу?", "confirm-delete": "Та {target}-г устгахдаа итгэлтэй байна уу?",
"confirm-leave": "Та {target}-с гарахдаа итгэлтэй байна уу?", "confirm-leave": "Та <b>{target}</b>-с гарахдаа итгэлтэй байна уу?",
"confirm-remove": "Та {target}-г устгахдаа итгэлтэй байна уу?", "confirm-remove": "Та <b>{target}</b>-г устгахдаа итгэлтэй байна уу?",
"confirm-reset": "Та {target}-н тоон үзүүлэлтүүдийг устгахдаа итгэлтэй байна уу?", "confirm-reset": "Та {target}-н тоон үзүүлэлтүүдийг устгахдаа итгэлтэй байна уу?",
"delete-team-warning": "Баг устгах нь мөн түүнд харъяалагдах вебүүдийг устгах болно.", "delete-team-warning": "Баг устгах нь мөн түүнд харъяалагдах вебүүдийг устгах болно.",
"delete-website-warning": "Энэ вебтэй холбоотой бүх өгөгдөл устах болно.", "delete-website-warning": "Энэ вебтэй холбоотой бүх өгөгдөл устах болно.",
"error": "Ямар нэг зүйл буруу боллоо.", "error": "Ямар нэг зүйл буруу боллоо.",
"event-log": "{url}-д {event}", "event-log": "<a>{url}</a>-д <b>{event}</b>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "Тохиргоо руу очих", "go-to-settings": "Тохиргоо руу очих",
"incorrect-username-password": "Буруу хэрэглэгчийн нэр/нууц үг.", "incorrect-username-password": "Буруу хэрэглэгчийн нэр/нууц үг.",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "Хэрэглэгч устсан.", "user-deleted": "Хэрэглэгч устсан.",
"viewed-page": "Үзсэн хуудас", "viewed-page": "Үзсэн хуудас",
"visitor-log": "{country} улсаас {os} {device} дээр {browser} хөтөч ашиглан орсон" "visitor-log": "<b>{country}</b> улсаас <b>{os}</b> <b>{device}</b> дээр <b>{browser}</b> хөтөч ашиглан орсон"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Collected data", "collected-data": "Collected data",
"confirm-delete": "Pastikah anda ingin memadam {target}?", "confirm-delete": "Pastikah anda ingin memadam {target}?",
"confirm-leave": "Are you sure you want to leave {target}?", "confirm-leave": "Are you sure you want to leave <b>{target}</b>?",
"confirm-remove": "Are you sure you want to remove {target}?", "confirm-remove": "Are you sure you want to remove <b>{target}</b>?",
"confirm-reset": "Are your sure you want to reset {target}'s statistics?", "confirm-reset": "Are your sure you want to reset {target}'s statistics?",
"delete-team-warning": "Deleting a team will also delete all team websites.", "delete-team-warning": "Deleting a team will also delete all team websites.",
"delete-website-warning": "Semua data yang berkaitan juga akan dihapuskan.", "delete-website-warning": "Semua data yang berkaitan juga akan dihapuskan.",
"error": "Ada yang tidak kena.", "error": "Ada yang tidak kena.",
"event-log": "{event} on {url}", "event-log": "<b>{event}</b> on <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "Pergi ke tetapan", "go-to-settings": "Pergi ke tetapan",
"incorrect-username-password": "Pengguna/kata laluan tidak betul.", "incorrect-username-password": "Pengguna/kata laluan tidak betul.",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "User deleted.", "user-deleted": "User deleted.",
"viewed-page": "Viewed page", "viewed-page": "Viewed page",
"visitor-log": "Pelawat dari {country} mengguna {browser} pada {os} {device}" "visitor-log": "Pelawat dari <b>{country}</b> mengguna <b>{browser}</b> pada <b>{os}</b> <b>{device}</b>"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Collected data", "collected-data": "Collected data",
"confirm-delete": "{target} ကို ဖျက်ရန် သေချာပါသလား?", "confirm-delete": "{target} ကို ဖျက်ရန် သေချာပါသလား?",
"confirm-leave": "{target} ကို ထွက်ရန် သေချာပါသလား?", "confirm-leave": "<b>{target}</b> ကို ထွက်ရန် သေချာပါသလား?",
"confirm-remove": "Are you sure you want to remove {target}?", "confirm-remove": "Are you sure you want to remove <b>{target}</b>?",
"confirm-reset": "{target} ကို ဖျက်၍ပြန်စလုပ်ရန် သေချာပါသလား?", "confirm-reset": "{target} ကို ဖျက်၍ပြန်စလုပ်ရန် သေချာပါသလား?",
"delete-team-warning": "Deleting a team will also delete all team websites.", "delete-team-warning": "Deleting a team will also delete all team websites.",
"delete-website-warning": "ဝက်ဘ်ဆိုဒ် ဒေတာအကုန် ဖျက်မည်", "delete-website-warning": "ဝက်ဘ်ဆိုဒ် ဒေတာအကုန် ဖျက်မည်",
"error": "မှားယွင်းမှုတစ်ခု ရှိသွားပါသည်", "error": "မှားယွင်းမှုတစ်ခု ရှိသွားပါသည်",
"event-log": "{url} တွင် {event}", "event-log": "<a>{url}</a> တွင် <b>{event}</b>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "ဆက်တင်သို့ သွားရန်", "go-to-settings": "ဆက်တင်သို့ သွားရန်",
"incorrect-username-password": "အသုံးပြုသူအမည် သို့မဟုတ် စကားဝှက် မှားနေသည်", "incorrect-username-password": "အသုံးပြုသူအမည် သို့မဟုတ် စကားဝှက် မှားနေသည်",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "အသုံးပြုသူ ဖျက်ပြီးပါပြီ", "user-deleted": "အသုံးပြုသူ ဖျက်ပြီးပါပြီ",
"viewed-page": "Viewed page", "viewed-page": "Viewed page",
"visitor-log": "{country} မှ {browser} ဖြင့် {os} {device} တွင် ဝင်ရောက်ကြည့်ရှုသူ" "visitor-log": "<b>{country}</b> မှ <b>{browser}</b> ဖြင့် <b>{os}</b> <b>{device}</b> တွင် ဝင်ရောက်ကြည့်ရှုသူ"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Innsamlede data", "collected-data": "Innsamlede data",
"confirm-delete": "Er du sikker på at du vil slette {target}?", "confirm-delete": "Er du sikker på at du vil slette {target}?",
"confirm-leave": "Er du sikker på at du vil forlate {target}?", "confirm-leave": "Er du sikker på at du vil forlate <b>{target}</b>?",
"confirm-remove": "Er du sikker på at du vil fjerne {target}?", "confirm-remove": "Er du sikker på at du vil fjerne <b>{target}</b>?",
"confirm-reset": "Er du sikker på at du vil nullstille statistikken til {target}?", "confirm-reset": "Er du sikker på at du vil nullstille statistikken til {target}?",
"delete-team-warning": "Å slette et team vil også slette alle teamets nettsteder.", "delete-team-warning": "Å slette et team vil også slette alle teamets nettsteder.",
"delete-website-warning": "Alle tilknyttede data vil også bli slettet.", "delete-website-warning": "Alle tilknyttede data vil også bli slettet.",
"error": "Noe gikk galt.", "error": "Noe gikk galt.",
"event-log": "{event} på {url}", "event-log": "<b>{event}</b><a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "Gå til innstillinger", "go-to-settings": "Gå til innstillinger",
"incorrect-username-password": "Ugyldig brukernavn/passord.", "incorrect-username-password": "Ugyldig brukernavn/passord.",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "Bruker slettet.", "user-deleted": "Bruker slettet.",
"viewed-page": "Vist side", "viewed-page": "Vist side",
"visitor-log": "Besøkende fra {country} med {browser} på {os} {device}" "visitor-log": "Besøkende fra <b>{country}</b> med <b>{browser}</b> på <b>{os}</b> <b>{device}</b>"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Collected data", "collected-data": "Collected data",
"confirm-delete": "Weet je zeker dat je {target} wilt verwijderen?", "confirm-delete": "Weet je zeker dat je {target} wilt verwijderen?",
"confirm-leave": "Weet je zeker dat je {target} wilt verlaten?", "confirm-leave": "Weet je zeker dat je <b>{target}</b> wilt verlaten?",
"confirm-remove": "Weet je zeker dat je {target} wilt verwijderen?", "confirm-remove": "Weet je zeker dat je <b>{target}</b> wilt verwijderen?",
"confirm-reset": "Weet je zeker dat je de statistieken van {target} opnieuw wilt instellen?", "confirm-reset": "Weet je zeker dat je de statistieken van {target} opnieuw wilt instellen?",
"delete-team-warning": "Als een team wordt verwijderd, worden ook alle websites van dat team verwijderd.", "delete-team-warning": "Als een team wordt verwijderd, worden ook alle websites van dat team verwijderd.",
"delete-website-warning": "Alle verwante gegevens zullen ook verwijderd worden.", "delete-website-warning": "Alle verwante gegevens zullen ook verwijderd worden.",
"error": "Er is iets misgegaan.", "error": "Er is iets misgegaan.",
"event-log": "{event} op {url}", "event-log": "<b>{event}</b> op <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "Naar instellingen", "go-to-settings": "Naar instellingen",
"incorrect-username-password": "Incorrecte gebruikersnaam/wachtwoord.", "incorrect-username-password": "Incorrecte gebruikersnaam/wachtwoord.",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "Gebruiker verwijderd", "user-deleted": "Gebruiker verwijderd",
"viewed-page": "Bekeken pagina", "viewed-page": "Bekeken pagina",
"visitor-log": "Bezoeker uit {country} met {browser} op een {os} {device}" "visitor-log": "Bezoeker uit <b>{country}</b> met <b>{browser}</b> op een <b>{os}</b> <b>{device}</b>"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Zebrane dane", "collected-data": "Zebrane dane",
"confirm-delete": "Czy na pewno chcesz usunąć {target}?", "confirm-delete": "Czy na pewno chcesz usunąć {target}?",
"confirm-leave": "Czy na pewno chcesz opuścić {target}?", "confirm-leave": "Czy na pewno chcesz opuścić <b>{target}</b>?",
"confirm-remove": "Czy na pewno chcesz usunąć {target}?", "confirm-remove": "Czy na pewno chcesz usunąć <b>{target}</b>?",
"confirm-reset": "Czy na pewno chcesz zresetować statystyki {target}?", "confirm-reset": "Czy na pewno chcesz zresetować statystyki {target}?",
"delete-team-warning": "Usunięcie zespołu usunie wszystkie jego witryny.", "delete-team-warning": "Usunięcie zespołu usunie wszystkie jego witryny.",
"delete-website-warning": "Wszystkie powiązane dane również zostaną usunięte.", "delete-website-warning": "Wszystkie powiązane dane również zostaną usunięte.",
"error": "Coś poszło nie tak.", "error": "Coś poszło nie tak.",
"event-log": "{event} na {url}", "event-log": "<b>{event}</b> na <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "Przejdź do ustawień", "go-to-settings": "Przejdź do ustawień",
"incorrect-username-password": "Nieprawidłowa nazwa użytkownika lub hasło.", "incorrect-username-password": "Nieprawidłowa nazwa użytkownika lub hasło.",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "Użytkownik usunięty.", "user-deleted": "Użytkownik usunięty.",
"viewed-page": "Obejrzana strona", "viewed-page": "Obejrzana strona",
"visitor-log": "Odwiedzający z {country} używa {browser} na {os} {device}" "visitor-log": "Odwiedzający z <b>{country}</b> używa <b>{browser}</b> na <b>{os}</b> <b>{device}</b>"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Collected data", "collected-data": "Collected data",
"confirm-delete": "Tem certeza de que deseja excluir {target}?", "confirm-delete": "Tem certeza de que deseja excluir {target}?",
"confirm-leave": "Tem certeza de que deseja sair de {target}?", "confirm-leave": "Tem certeza de que deseja sair de <b>{target}</b>?",
"confirm-remove": "Tem certeza que deseja remover {target}?", "confirm-remove": "Tem certeza que deseja remover <b>{target}</b>?",
"confirm-reset": "Tem certeza que deseja redefinir os dados de {target}?", "confirm-reset": "Tem certeza que deseja redefinir os dados de {target}?",
"delete-team-warning": "Excluir a equipe também excluirá todos os sites da equipe.", "delete-team-warning": "Excluir a equipe também excluirá todos os sites da equipe.",
"delete-website-warning": "Todos os dados relacionados serão excluídos.", "delete-website-warning": "Todos os dados relacionados serão excluídos.",
"error": "Ocorreu um erro.", "error": "Ocorreu um erro.",
"event-log": "{event} em {url}", "event-log": "<b>{event}</b> em <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "Ir para as configurações", "go-to-settings": "Ir para as configurações",
"incorrect-username-password": "Nome de usuário ou senha incorretos.", "incorrect-username-password": "Nome de usuário ou senha incorretos.",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "Usuário excluído.", "user-deleted": "Usuário excluído.",
"viewed-page": "Página visualizada", "viewed-page": "Página visualizada",
"visitor-log": "Visitante de {country} usando o navegador {browser} em um {device} com sistema operacional {os}." "visitor-log": "Visitante de <b>{country}</b> usando o navegador <b>{browser}</b> em um <b>{device}</b> com sistema operacional <b>{os}</b>."
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Collected data", "collected-data": "Collected data",
"confirm-delete": "Tem a certeza que pretende eliminar {target}?", "confirm-delete": "Tem a certeza que pretende eliminar {target}?",
"confirm-leave": "Are you sure you want to leave {target}?", "confirm-leave": "Are you sure you want to leave <b>{target}</b>?",
"confirm-remove": "Are you sure you want to remove {target}?", "confirm-remove": "Are you sure you want to remove <b>{target}</b>?",
"confirm-reset": "Tem a certeza que pretende restaurar as estatísticas de {target}?", "confirm-reset": "Tem a certeza que pretende restaurar as estatísticas de {target}?",
"delete-team-warning": "Deleting a team will also delete all team websites.", "delete-team-warning": "Deleting a team will also delete all team websites.",
"delete-website-warning": "Todos os dados associados também serão eliminados.", "delete-website-warning": "Todos os dados associados também serão eliminados.",
"error": "Ocorreu um erro.", "error": "Ocorreu um erro.",
"event-log": "{event} on {url}", "event-log": "<b>{event}</b> on <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "Ir para as definições", "go-to-settings": "Ir para as definições",
"incorrect-username-password": "Nome de utilizador/senha incorretos.", "incorrect-username-password": "Nome de utilizador/senha incorretos.",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "User deleted.", "user-deleted": "User deleted.",
"viewed-page": "Viewed page", "viewed-page": "Viewed page",
"visitor-log": "Visitante de {country} a usar {browser} no {device} {os}" "visitor-log": "Visitante de <b>{country}</b> a usar <b>{browser}</b> no <b>{device}</b> <b>{os}</b>"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Date colectate", "collected-data": "Date colectate",
"confirm-delete": "Ești sigur că vrei să ștergi {target}?", "confirm-delete": "Ești sigur că vrei să ștergi {target}?",
"confirm-leave": "Ești sigur că vrei să părăsești {target}?", "confirm-leave": "Ești sigur că vrei să părăsești <b>{target}</b>?",
"confirm-remove": "Ești sigur că vrei să ștergi {target}?", "confirm-remove": "Ești sigur că vrei să ștergi <b>{target}</b>?",
"confirm-reset": "Ești sigur că vrei să resetezi statisticile pentru {target}?", "confirm-reset": "Ești sigur că vrei să resetezi statisticile pentru {target}?",
"delete-team-warning": "Ștergerea unei echipe va șterge și toate website-urile echipei.", "delete-team-warning": "Ștergerea unei echipe va șterge și toate website-urile echipei.",
"delete-website-warning": "Toate datele asociate vor fi șterse, de asemenea.", "delete-website-warning": "Toate datele asociate vor fi șterse, de asemenea.",
"error": "Ceva n-a mers bine.", "error": "Ceva n-a mers bine.",
"event-log": "{event} la {url}", "event-log": "<b>{event}</b> la <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "Mergi la Setări", "go-to-settings": "Mergi la Setări",
"incorrect-username-password": "Nume utilizator / parolă incorecte.", "incorrect-username-password": "Nume utilizator / parolă incorecte.",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "Utilizator șters.", "user-deleted": "Utilizator șters.",
"viewed-page": "Pagină vizualizată", "viewed-page": "Pagină vizualizată",
"visitor-log": "Vizitator din {country} folosind {browser} pe {os} {device}" "visitor-log": "Vizitator din <b>{country}</b> folosind <b>{browser}</b> pe <b>{os}</b> <b>{device}</b>"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Собранные данные", "collected-data": "Собранные данные",
"confirm-delete": "Вы уверены, что хотите удалить {target}?", "confirm-delete": "Вы уверены, что хотите удалить {target}?",
"confirm-leave": "Вы уверены, что хотите уйти {target}?", "confirm-leave": "Вы уверены, что хотите уйти <b>{target}</b>?",
"confirm-remove": "Вы уверены, что хотите удалить {target}?", "confirm-remove": "Вы уверены, что хотите удалить <b>{target}</b>?",
"confirm-reset": "Вы уверены, что хотите сбросить статистику {target}?", "confirm-reset": "Вы уверены, что хотите сбросить статистику {target}?",
"delete-team-warning": "При удалении команды будут удалены и все ее веб-сайты.", "delete-team-warning": "При удалении команды будут удалены и все ее веб-сайты.",
"delete-website-warning": "Все связанные данные будут также удалены.", "delete-website-warning": "Все связанные данные будут также удалены.",
"error": "Что-то пошло не так.", "error": "Что-то пошло не так.",
"event-log": "{event} на {url}", "event-log": "<b>{event}</b> на <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "Перейти к настройкам", "go-to-settings": "Перейти к настройкам",
"incorrect-username-password": "Неверное имя пользователя/пароль.", "incorrect-username-password": "Неверное имя пользователя/пароль.",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "Пользователь удален.", "user-deleted": "Пользователь удален.",
"viewed-page": "Просмотренная страница", "viewed-page": "Просмотренная страница",
"visitor-log": "Посетитель из {country} используя {browser} на {os} {device}" "visitor-log": "Посетитель из <b>{country}</b> используя <b>{browser}</b> на <b>{os}</b> <b>{device}</b>"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Collected data", "collected-data": "Collected data",
"confirm-delete": "{target} මකා දැමීම ගැන විශ්වාසද?", "confirm-delete": "{target} මකා දැමීම ගැන විශ්වාසද?",
"confirm-leave": "Are you sure you want to leave {target}?", "confirm-leave": "Are you sure you want to leave <b>{target}</b>?",
"confirm-remove": "Are you sure you want to remove {target}?", "confirm-remove": "Are you sure you want to remove <b>{target}</b>?",
"confirm-reset": "{target} ට අදාල සංඛ්‍යාලේඛන නැවත පිහිටුවීමට අවශ්‍යද?", "confirm-reset": "{target} ට අදාල සංඛ්‍යාලේඛන නැවත පිහිටුවීමට අවශ්‍යද?",
"delete-team-warning": "Deleting a team will also delete all team websites.", "delete-team-warning": "Deleting a team will also delete all team websites.",
"delete-website-warning": "All website data will be deleted.", "delete-website-warning": "All website data will be deleted.",
"error": "Something went wrong.", "error": "Something went wrong.",
"event-log": "{event} on {url}", "event-log": "<b>{event}</b> on <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "සැකසීම් වෙත යන්න", "go-to-settings": "සැකසීම් වෙත යන්න",
"incorrect-username-password": "වැරදි පරිශීලක නාමය/මුරපදය.", "incorrect-username-password": "වැරදි පරිශීලක නාමය/මුරපදය.",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "User deleted.", "user-deleted": "User deleted.",
"viewed-page": "Viewed page", "viewed-page": "Viewed page",
"visitor-log": "Visitor from {country} using {browser} on {os} {device}" "visitor-log": "Visitor from <b>{country}</b> using <b>{browser}</b> on <b>{os}</b> <b>{device}</b>"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Collected data", "collected-data": "Collected data",
"confirm-delete": "Naozaj zmazať {target}?", "confirm-delete": "Naozaj zmazať {target}?",
"confirm-leave": "Are you sure you want to leave {target}?", "confirm-leave": "Are you sure you want to leave <b>{target}</b>?",
"confirm-remove": "Are you sure you want to remove {target}?", "confirm-remove": "Are you sure you want to remove <b>{target}</b>?",
"confirm-reset": "Are your sure you want to reset {target}'s statistics?", "confirm-reset": "Are your sure you want to reset {target}'s statistics?",
"delete-team-warning": "Deleting a team will also delete all team websites.", "delete-team-warning": "Deleting a team will also delete all team websites.",
"delete-website-warning": "Všetky príbuzné data budu tiež zmazané.", "delete-website-warning": "Všetky príbuzné data budu tiež zmazané.",
"error": "Niečo sa pokazilo.", "error": "Niečo sa pokazilo.",
"event-log": "{event} on {url}", "event-log": "<b>{event}</b> on <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "Ísť do nastavení", "go-to-settings": "Ísť do nastavení",
"incorrect-username-password": "Nesprávné meno/heslo.", "incorrect-username-password": "Nesprávné meno/heslo.",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "User deleted.", "user-deleted": "User deleted.",
"viewed-page": "Viewed page", "viewed-page": "Viewed page",
"visitor-log": "Návštevník z {country} s prehliadačom {browser} na {os} {device}" "visitor-log": "Návštevník z <b>{country}</b> s prehliadačom <b>{browser}</b> na <b>{os}</b> <b>{device}</b>"
} }
} }

View file

@ -277,13 +277,13 @@
"active-users": "{x} trenutni {x, plural, one {obiskovalec} other {obiskovalcev}}", "active-users": "{x} trenutni {x, plural, one {obiskovalec} other {obiskovalcev}}",
"collected-data": "Zbrani podatki", "collected-data": "Zbrani podatki",
"confirm-delete": "Ste prepričani, da želite izbrisati {target}?", "confirm-delete": "Ste prepričani, da želite izbrisati {target}?",
"confirm-leave": "Ste prepričani, da želite zapustiti {target}?", "confirm-leave": "Ste prepričani, da želite zapustiti <b>{target}</b>?",
"confirm-remove": "Ali ste prepričani, da želite odstraniti {target}?", "confirm-remove": "Ali ste prepričani, da želite odstraniti <b>{target}</b>?",
"confirm-reset": "Ste prepričani, da želite ponastaviti statistiko {target}?", "confirm-reset": "Ste prepričani, da želite ponastaviti statistiko {target}?",
"delete-team-warning": "Brisanje ekipe bo izbrisalo tudi vsa spletna mesta ekipe.", "delete-team-warning": "Brisanje ekipe bo izbrisalo tudi vsa spletna mesta ekipe.",
"delete-website-warning": "Izbrisani bodo tudi vsi pripadajoči podatki.", "delete-website-warning": "Izbrisani bodo tudi vsi pripadajoči podatki.",
"error": "Nekaj je šlo narobe.", "error": "Nekaj je šlo narobe.",
"event-log": "{event} na {url}", "event-log": "<b>{event}</b> na <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "Pojdi v nastavitve", "go-to-settings": "Pojdi v nastavitve",
"incorrect-username-password": "Nepravilno uporabniško ime/geslo.", "incorrect-username-password": "Nepravilno uporabniško ime/geslo.",
@ -316,7 +316,7 @@
"triggered-event": "Sprožen dogodek", "triggered-event": "Sprožen dogodek",
"user-deleted": "Uporabnik je izbrisan.", "user-deleted": "Uporabnik je izbrisan.",
"viewed-page": "Ogledana stran", "viewed-page": "Ogledana stran",
"visitor-log": "Obiskovalec iz {country} uporablja {browser} na {os} {device}", "visitor-log": "Obiskovalec iz <b>{country}</b> uporablja <b>{browser}</b> na <b>{os}</b> <b>{device}</b>",
"visitors-dropped-off": "Osip obiskovalcev" "visitors-dropped-off": "Osip obiskovalcev"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Collected data", "collected-data": "Collected data",
"confirm-delete": "Är du säker på att du vill radera {target}?", "confirm-delete": "Är du säker på att du vill radera {target}?",
"confirm-leave": "Är du säker på att du vill lämna {target}?", "confirm-leave": "Är du säker på att du vill lämna <b>{target}</b>?",
"confirm-remove": "Are you sure you want to remove {target}?", "confirm-remove": "Are you sure you want to remove <b>{target}</b>?",
"confirm-reset": "Är du säker på att du vill återställa statistiken för {target}?", "confirm-reset": "Är du säker på att du vill återställa statistiken för {target}?",
"delete-team-warning": "Deleting a team will also delete all team websites.", "delete-team-warning": "Deleting a team will also delete all team websites.",
"delete-website-warning": "All tillhörande data kommer också att raderas.", "delete-website-warning": "All tillhörande data kommer också att raderas.",
"error": "Något gick fel.", "error": "Något gick fel.",
"event-log": "{event} på {url}", "event-log": "<b>{event}</b><a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "Gå till inställningar", "go-to-settings": "Gå till inställningar",
"incorrect-username-password": "Felaktigt användarnamn/lösenord.", "incorrect-username-password": "Felaktigt användarnamn/lösenord.",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "Användaren har raderats.", "user-deleted": "Användaren har raderats.",
"viewed-page": "Viewed page", "viewed-page": "Viewed page",
"visitor-log": "Besökare från {country} med {browser} på {os} {device}" "visitor-log": "Besökare från <b>{country}</b> med <b>{browser}</b> på <b>{os}</b> <b>{device}</b>"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Collected data", "collected-data": "Collected data",
"confirm-delete": "நீங்கள் நிச்சயமாக {target} நீக்க விரும்புகிறீர்களா?", "confirm-delete": "நீங்கள் நிச்சயமாக {target} நீக்க விரும்புகிறீர்களா?",
"confirm-leave": "Are you sure you want to leave {target}?", "confirm-leave": "Are you sure you want to leave <b>{target}</b>?",
"confirm-remove": "Are you sure you want to remove {target}?", "confirm-remove": "Are you sure you want to remove <b>{target}</b>?",
"confirm-reset": "Are your sure you want to reset {target}'s statistics?", "confirm-reset": "Are your sure you want to reset {target}'s statistics?",
"delete-team-warning": "Deleting a team will also delete all team websites.", "delete-team-warning": "Deleting a team will also delete all team websites.",
"delete-website-warning": "தொடர்புடைய எல்லா தரவும் நீக்கப்படும்.", "delete-website-warning": "தொடர்புடைய எல்லா தரவும் நீக்கப்படும்.",
"error": "ஏதோ தவறு நடந்துவிட்டது.", "error": "ஏதோ தவறு நடந்துவிட்டது.",
"event-log": "{event} on {url}", "event-log": "<b>{event}</b> on <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "அமைப்புகளுக்குச் செல்லவும்", "go-to-settings": "அமைப்புகளுக்குச் செல்லவும்",
"incorrect-username-password": "தவறான பயனர்பெயர் / கடவுச்சொல்.", "incorrect-username-password": "தவறான பயனர்பெயர் / கடவுச்சொல்.",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "User deleted.", "user-deleted": "User deleted.",
"viewed-page": "Viewed page", "viewed-page": "Viewed page",
"visitor-log": "{country}வில் இருந்து பார்வையாளர் {browser} ஐ {os} {device}லில் பயன்படுத்துகிறார்" "visitor-log": "<b>{country}</b>வில் இருந்து பார்வையாளர் <b>{browser}</b> ஐ <b>{os}</b> <b>{device}</b>லில் பயன்படுத்துகிறார்"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Collected data", "collected-data": "Collected data",
"confirm-delete": "คุณแน่ใจหรือไม่ว่าต้องการลบ {target} ?", "confirm-delete": "คุณแน่ใจหรือไม่ว่าต้องการลบ {target} ?",
"confirm-leave": "Are you sure you want to leave {target}?", "confirm-leave": "Are you sure you want to leave <b>{target}</b>?",
"confirm-remove": "Are you sure you want to remove {target}?", "confirm-remove": "Are you sure you want to remove <b>{target}</b>?",
"confirm-reset": "คุณแน่ใจหรือไม่ว่าต้องการรีเซตข้อมูลสถิติของ {target} ?", "confirm-reset": "คุณแน่ใจหรือไม่ว่าต้องการรีเซตข้อมูลสถิติของ {target} ?",
"delete-team-warning": "Deleting a team will also delete all team websites.", "delete-team-warning": "Deleting a team will also delete all team websites.",
"delete-website-warning": "ข้อมูลที่เกี่ยวข้องทั้งหมดจะถูกลบ.", "delete-website-warning": "ข้อมูลที่เกี่ยวข้องทั้งหมดจะถูกลบ.",
"error": "เกิดข้อผิดพลาด.", "error": "เกิดข้อผิดพลาด.",
"event-log": "{event} on {url}", "event-log": "<b>{event}</b> on <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "ไปที่การตั้งค่า", "go-to-settings": "ไปที่การตั้งค่า",
"incorrect-username-password": "ชื่อผู้ใช้หรือรหัสผ่านไม่ถูกต้อง.", "incorrect-username-password": "ชื่อผู้ใช้หรือรหัสผ่านไม่ถูกต้อง.",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "User deleted.", "user-deleted": "User deleted.",
"viewed-page": "Viewed page", "viewed-page": "Viewed page",
"visitor-log": "ผู้เข้าชมจาก {country} กำลังใช้งานผ่าน {browser} บน {os} {device}" "visitor-log": "ผู้เข้าชมจาก <b>{country}</b> กำลังใช้งานผ่าน <b>{browser}</b> บน <b>{os}</b> <b>{device}</b>"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Collected data", "collected-data": "Collected data",
"confirm-delete": "{target} kaydını silmek istediğinizden emin misiniz?", "confirm-delete": "{target} kaydını silmek istediğinizden emin misiniz?",
"confirm-leave": "{target} kaydından ayrılmak istediğinizden emin misiniz?", "confirm-leave": "<b>{target}</b> kaydından ayrılmak istediğinizden emin misiniz?",
"confirm-remove": "{target} kaydını kaldırmak istediğinizden emin misiniz?", "confirm-remove": "<b>{target}</b> kaydını kaldırmak istediğinizden emin misiniz?",
"confirm-reset": "{target} istatistiklerini sıfırlamak istediğinizden emin misiniz?", "confirm-reset": "{target} istatistiklerini sıfırlamak istediğinizden emin misiniz?",
"delete-team-warning": "Bir takımı silmek tüm takım web sitelerini de silecektir.", "delete-team-warning": "Bir takımı silmek tüm takım web sitelerini de silecektir.",
"delete-website-warning": "İlişkili tüm veriler de silinecektir.", "delete-website-warning": "İlişkili tüm veriler de silinecektir.",
"error": "Bir şeyler ters gitti!", "error": "Bir şeyler ters gitti!",
"event-log": "{event} on {url}", "event-log": "<b>{event}</b> on <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "Ayarlara git", "go-to-settings": "Ayarlara git",
"incorrect-username-password": "Hatalı kullanıcı adı ya da parola.", "incorrect-username-password": "Hatalı kullanıcı adı ya da parola.",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "Kullanıcı silindi.", "user-deleted": "Kullanıcı silindi.",
"viewed-page": "Görüntülenen sayfa", "viewed-page": "Görüntülenen sayfa",
"visitor-log": "Yeni ziyaretçi: {country}, {os}, {device}, {browser}" "visitor-log": "Yeni ziyaretçi: <b>{country}</b>, <b>{os}</b>, <b>{device}</b>, <b>{browser}</b>"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Collected data", "collected-data": "Collected data",
"confirm-delete": "Ви впевнені, що бажаєте видалити {target}?", "confirm-delete": "Ви впевнені, що бажаєте видалити {target}?",
"confirm-leave": "Ви впевнені, що бажаєте покинути {target}?", "confirm-leave": "Ви впевнені, що бажаєте покинути <b>{target}</b>?",
"confirm-remove": "Ви впевнені, що бажаєте видалити {target}?", "confirm-remove": "Ви впевнені, що бажаєте видалити <b>{target}</b>?",
"confirm-reset": "Ви впевнені, що бажаєте скинути статистику для {target}?", "confirm-reset": "Ви впевнені, що бажаєте скинути статистику для {target}?",
"delete-team-warning": "Видалення команди також призведе до видалення всіх її веб-сайтів.", "delete-team-warning": "Видалення команди також призведе до видалення всіх її веб-сайтів.",
"delete-website-warning": "Усі пов'язані дані будуть видалені також.", "delete-website-warning": "Усі пов'язані дані будуть видалені також.",
"error": "Щось пішло не так.", "error": "Щось пішло не так.",
"event-log": "{event} на {url}", "event-log": "<b>{event}</b> на <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "Перейти до налаштувань", "go-to-settings": "Перейти до налаштувань",
"incorrect-username-password": "Невірне ім'я користувача або пароль.", "incorrect-username-password": "Невірне ім'я користувача або пароль.",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "Користувача видалено.", "user-deleted": "Користувача видалено.",
"viewed-page": "Переглянута сторінка", "viewed-page": "Переглянута сторінка",
"visitor-log": "Відвідувач з {country} використовуючи {browser} на {os} {device}" "visitor-log": "Відвідувач з <b>{country}</b> використовуючи <b>{browser}</b> на <b>{os}</b> <b>{device}</b>"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "Collected data", "collected-data": "Collected data",
"confirm-delete": "کیا آپ واقعی {target} کو حذف کرنا چاہتے ہیں؟", "confirm-delete": "کیا آپ واقعی {target} کو حذف کرنا چاہتے ہیں؟",
"confirm-leave": "Are you sure you want to leave {target}?", "confirm-leave": "Are you sure you want to leave <b>{target}</b>?",
"confirm-remove": "Are you sure you want to remove {target}?", "confirm-remove": "Are you sure you want to remove <b>{target}</b>?",
"confirm-reset": "کیا آپ واقعی {target} کے اعدادوشمار کو دوبارہ ترتیب دینا چاہتے ہیں؟", "confirm-reset": "کیا آپ واقعی {target} کے اعدادوشمار کو دوبارہ ترتیب دینا چاہتے ہیں؟",
"delete-team-warning": "Deleting a team will also delete all team websites.", "delete-team-warning": "Deleting a team will also delete all team websites.",
"delete-website-warning": "تمام متعلقہ ڈیٹا بھی حذف کر دیا جائے گا۔", "delete-website-warning": "تمام متعلقہ ڈیٹا بھی حذف کر دیا جائے گا۔",
"error": "کچھ غلط ہو گیا.", "error": "کچھ غلط ہو گیا.",
"event-log": "{event} on {url}", "event-log": "<b>{event}</b> on <a>{url}</a>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "ترتیبات پر جائیں", "go-to-settings": "ترتیبات پر جائیں",
"incorrect-username-password": "غلط صارف نام/پاس ورڈ۔", "incorrect-username-password": "غلط صارف نام/پاس ورڈ۔",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "User deleted.", "user-deleted": "User deleted.",
"viewed-page": "Viewed page", "viewed-page": "Viewed page",
"visitor-log": "{os} {device} پر {browser} کا استعمال کرتے ہوئے {country} سے آنے والا" "visitor-log": "<b>{os}</b> <b>{device}</b> پر <b>{browser}</b> کا استعمال کرتے ہوئے <b>{country}</b> سے آنے والا"
} }
} }

View file

@ -243,13 +243,13 @@
"active-users": "{x} joriy {x, plural, one {tashrif buyuruvchi} other {tashrif buyuruvchilar}}", "active-users": "{x} joriy {x, plural, one {tashrif buyuruvchi} other {tashrif buyuruvchilar}}",
"collected-data": "Yigʻilgan ma'lumotlar", "collected-data": "Yigʻilgan ma'lumotlar",
"confirm-delete": "**{target}** ni oʻchirmoqchi ekanligingizga ishonchingiz komilmi?", "confirm-delete": "**{target}** ni oʻchirmoqchi ekanligingizga ishonchingiz komilmi?",
"confirm-leave": "**{target}** ni tark etmoqchi ekanligingizga ishonchingiz komilmi?", "confirm-leave": "**<b>{target}</b>** ni tark etmoqchi ekanligingizga ishonchingiz komilmi?",
"confirm-remove": "**{target}** ni olib tashlamoqchi ekanligingizga ishonchingiz komilmi?", "confirm-remove": "**<b>{target}</b>** ni olib tashlamoqchi ekanligingizga ishonchingiz komilmi?",
"confirm-reset": "**{target}** ni qayta tiklamoqchi ekanligingizga ishonchingiz komilmi?", "confirm-reset": "**{target}** ni qayta tiklamoqchi ekanligingizga ishonchingiz komilmi?",
"delete-team-warning": "Jamoani oʻchirish, shuningdek, barcha jamoa veb-saytlarini ham oʻchiradi.", "delete-team-warning": "Jamoani oʻchirish, shuningdek, barcha jamoa veb-saytlarini ham oʻchiradi.",
"delete-website-warning": "Barcha veb-sayt ma'lumotlari oʻchiriladi.", "delete-website-warning": "Barcha veb-sayt ma'lumotlari oʻchiriladi.",
"error": "Nimadir xato ketdi.", "error": "Nimadir xato ketdi.",
"event-log": "**{url}** da **{event}** hodisasi", "event-log": "**<a>{url}</a>** da **<b>{event}</b>** hodisasi",
"go-to-settings": "Sozlamalarga oʻtish", "go-to-settings": "Sozlamalarga oʻtish",
"incorrect-username-password": "Notoʻgʻri foydalanuvchi nomi va/yoki parol.", "incorrect-username-password": "Notoʻgʻri foydalanuvchi nomi va/yoki parol.",
"invalid-domain": "Notoʻgʻri domen. http/https qoʻshmang.", "invalid-domain": "Notoʻgʻri domen. http/https qoʻshmang.",
@ -278,7 +278,7 @@
"triggered-event": "Hodisa ishga tushirildi", "triggered-event": "Hodisa ishga tushirildi",
"user-deleted": "Foydalanuvchi oʻchirildi.", "user-deleted": "Foydalanuvchi oʻchirildi.",
"viewed-page": "Sahifa koʻrildi", "viewed-page": "Sahifa koʻrildi",
"visitor-log": "{os} {device} da {browser} dan foydalanayotgan {country} dan tashrif buyuruvchi", "visitor-log": "<b>{os}</b> <b>{device}</b> da <b>{browser}</b> dan foydalanayotgan <b>{country}</b> dan tashrif buyuruvchi",
"visitors-dropped-off": "Tashrif buyuruvchilar tashlab ketishdi" "visitors-dropped-off": "Tashrif buyuruvchilar tashlab ketishdi"
} }
} }

View file

@ -243,13 +243,13 @@
"active-users": "{x} {x, plural, one {người dùng} other {người dùng}} đang hoạt động", "active-users": "{x} {x, plural, one {người dùng} other {người dùng}} đang hoạt động",
"collected-data": "Dữ liệu đã thu thập", "collected-data": "Dữ liệu đã thu thập",
"confirm-delete": "Bạn có chắc chắn muốn xóa {target}?", "confirm-delete": "Bạn có chắc chắn muốn xóa {target}?",
"confirm-leave": "Bạn có chắc chắn muốn rời {target}?", "confirm-leave": "Bạn có chắc chắn muốn rời <b>{target}</b>?",
"confirm-remove": "Bạn có chắc chắn muốn xóa {target}?", "confirm-remove": "Bạn có chắc chắn muốn xóa <b>{target}</b>?",
"confirm-reset": "Bạn có chắc chắn muốn đặt lại thống kê {target}?", "confirm-reset": "Bạn có chắc chắn muốn đặt lại thống kê {target}?",
"delete-team-warning": "Việc xóa một nhóm cũng sẽ xóa tất cả các website của nhóm.", "delete-team-warning": "Việc xóa một nhóm cũng sẽ xóa tất cả các website của nhóm.",
"delete-website-warning": "Tất cả dữ liệu liên quan cũng sẽ bị xóa.", "delete-website-warning": "Tất cả dữ liệu liên quan cũng sẽ bị xóa.",
"error": "Đã xảy ra lỗi.", "error": "Đã xảy ra lỗi.",
"event-log": "{event} trên {url}", "event-log": "<b>{event}</b> trên <a>{url}</a>",
"go-to-settings": "Chuyển đến cài đặt", "go-to-settings": "Chuyển đến cài đặt",
"incorrect-username-password": "Sai tên đăng nhập/mật khẩu.", "incorrect-username-password": "Sai tên đăng nhập/mật khẩu.",
"invalid-domain": "Tên miền không hợp lệ", "invalid-domain": "Tên miền không hợp lệ",
@ -278,7 +278,7 @@
"triggered-event": "Sự kiện được kích hoạt", "triggered-event": "Sự kiện được kích hoạt",
"user-deleted": "Người dùng đã bị xóa.", "user-deleted": "Người dùng đã bị xóa.",
"viewed-page": "Đã xem trang", "viewed-page": "Đã xem trang",
"visitor-log": "Khách từ {country} đang sử dụng {browser} trên {os} {device}", "visitor-log": "Khách từ <b>{country}</b> đang sử dụng <b>{browser}</b> trên <b>{os}</b> <b>{device}</b>",
"visitors-dropped-off": "Khách truy cập đã rời đi" "visitors-dropped-off": "Khách truy cập đã rời đi"
} }
} }

View file

@ -329,13 +329,13 @@
"bad-request": "请求错误", "bad-request": "请求错误",
"collected-data": "已收集的数据", "collected-data": "已收集的数据",
"confirm-delete": "你确定要删除 {target} 吗?", "confirm-delete": "你确定要删除 {target} 吗?",
"confirm-leave": "你确定要离开 {target} 吗?", "confirm-leave": "你确定要离开 <b>{target}</b> 吗?",
"confirm-remove": "您确定要移除 {target} ", "confirm-remove": "您确定要移除 <b>{target}</b> ",
"confirm-reset": "您确定要重置 {target} 的数据吗?", "confirm-reset": "您确定要重置 {target} 的数据吗?",
"delete-team-warning": "删除团队也会删除所有团队网站。", "delete-team-warning": "删除团队也会删除所有团队网站。",
"delete-website-warning": "所有相关数据将会被删除。", "delete-website-warning": "所有相关数据将会被删除。",
"error": "发生错误。", "error": "发生错误。",
"event-log": "{url} 上的 {event}", "event-log": "<a>{url}</a> 上的 <b>{event}</b>",
"forbidden": "禁止访问", "forbidden": "禁止访问",
"go-to-settings": "去设置", "go-to-settings": "去设置",
"incorrect-username-password": "用户名或密码不正确。", "incorrect-username-password": "用户名或密码不正确。",
@ -369,6 +369,6 @@
"unauthorized": "未授权", "unauthorized": "未授权",
"user-deleted": "用户已删除。", "user-deleted": "用户已删除。",
"viewed-page": "已浏览页面", "viewed-page": "已浏览页面",
"visitor-log": "来自 {country} 的访客在搭载 {os} 的 {device} 上使用 {browser} 浏览器进行访问。" "visitor-log": "来自 <b>{country}</b> 的访客在搭载 <b>{os}</b> 的 <b>{device}</b> 上使用 <b>{browser}</b> 浏览器进行访问。"
} }
} }

View file

@ -298,13 +298,13 @@
"bad-request": "Bad request", "bad-request": "Bad request",
"collected-data": "已蒐集的資料", "collected-data": "已蒐集的資料",
"confirm-delete": "您確定要刪除 {target} 嗎?", "confirm-delete": "您確定要刪除 {target} 嗎?",
"confirm-leave": "您確定要離開 {target} 嗎?", "confirm-leave": "您確定要離開 <b>{target}</b> 嗎?",
"confirm-remove": "您確定要移除 {target} 嗎?", "confirm-remove": "您確定要移除 <b>{target}</b> 嗎?",
"confirm-reset": "您確定要重設 {target} 的統計資料嗎?", "confirm-reset": "您確定要重設 {target} 的統計資料嗎?",
"delete-team-warning": "刪除團隊的同時也會刪除所有團隊的網站。", "delete-team-warning": "刪除團隊的同時也會刪除所有團隊的網站。",
"delete-website-warning": "所有網站資料都將被刪除。", "delete-website-warning": "所有網站資料都將被刪除。",
"error": "發生錯誤。", "error": "發生錯誤。",
"event-log": "在 {url} 上的 {event}", "event-log": "在 <a>{url}</a> 上的 <b>{event}</b>",
"forbidden": "Forbidden", "forbidden": "Forbidden",
"go-to-settings": "前往設定", "go-to-settings": "前往設定",
"incorrect-username-password": "使用者名稱或密碼不正確。", "incorrect-username-password": "使用者名稱或密碼不正確。",
@ -338,6 +338,6 @@
"unauthorized": "Unauthorized", "unauthorized": "Unauthorized",
"user-deleted": "使用者已刪除。", "user-deleted": "使用者已刪除。",
"viewed-page": "已瀏覽的網頁", "viewed-page": "已瀏覽的網頁",
"visitor-log": "來自 {country} 的訪客在 {device} 上的 {os} 使用 {browser} 瀏覽。" "visitor-log": "來自 <b>{country}</b> 的訪客在 <b>{device}</b> 上的 <b>{os}</b> 使用 <b>{browser}</b> 瀏覽。"
} }
} }

View file

@ -11,7 +11,7 @@ import { AdminNav } from './admin/AdminNav';
import { SettingsNav } from './settings/SettingsNav'; import { SettingsNav } from './settings/SettingsNav';
export function MobileNav() { export function MobileNav() {
const { formatMessage, labels } = useMessages(); const { t, labels } = useMessages();
const { pathname, websiteId, renderUrl } = useNavigation(); const { pathname, websiteId, renderUrl } = useNavigation();
const isAdmin = pathname.includes('/admin'); const isAdmin = pathname.includes('/admin');
const isSettings = pathname.includes('/settings'); const isSettings = pathname.includes('/settings');
@ -19,19 +19,19 @@ export function MobileNav() {
const links = [ const links = [
{ {
id: 'websites', id: 'websites',
label: formatMessage(labels.websites), label: t(labels.websites),
path: '/websites', path: '/websites',
icon: <Globe />, icon: <Globe />,
}, },
{ {
id: 'links', id: 'links',
label: formatMessage(labels.links), label: t(labels.links),
path: '/links', path: '/links',
icon: <LinkIcon />, icon: <LinkIcon />,
}, },
{ {
id: 'pixels', id: 'pixels',
label: formatMessage(labels.pixels), label: t(labels.pixels),
path: '/pixels', path: '/pixels',
icon: <Grid2x2 />, icon: <Grid2x2 />,
}, },

View file

@ -21,7 +21,7 @@ import { NavButton } from '@/components/input/NavButton';
import { Logo } from '@/components/svg'; import { Logo } from '@/components/svg';
export function SideNav(props: any) { export function SideNav(props: any) {
const { formatMessage, labels } = useMessages(); const { t, labels } = useMessages();
const { pathname, renderUrl, websiteId, router } = useNavigation(); const { pathname, renderUrl, websiteId, router } = useNavigation();
const [isCollapsed, setIsCollapsed] = useGlobalState('sidenav-collapsed', false); const [isCollapsed, setIsCollapsed] = useGlobalState('sidenav-collapsed', false);
@ -30,25 +30,25 @@ export function SideNav(props: any) {
const links = [ const links = [
{ {
id: 'boards', id: 'boards',
label: formatMessage(labels.boards), label: t(labels.boards),
path: '/boards', path: '/boards',
icon: <LayoutDashboard />, icon: <LayoutDashboard />,
}, },
{ {
id: 'websites', id: 'websites',
label: formatMessage(labels.websites), label: t(labels.websites),
path: '/websites', path: '/websites',
icon: <Globe />, icon: <Globe />,
}, },
{ {
id: 'links', id: 'links',
label: formatMessage(labels.links), label: t(labels.links),
path: '/links', path: '/links',
icon: <LinkIcon />, icon: <LinkIcon />,
}, },
{ {
id: 'pixels', id: 'pixels',
label: formatMessage(labels.pixels), label: t(labels.pixels),
path: '/pixels', path: '/pixels',
icon: <Grid2x2 />, icon: <Grid2x2 />,
}, },

View file

@ -7,7 +7,7 @@ import { setItem } from '@/lib/storage';
import { checkVersion, useVersion } from '@/store/version'; import { checkVersion, useVersion } from '@/store/version';
export function UpdateNotice({ user, config }) { export function UpdateNotice({ user, config }) {
const { formatMessage, labels, messages } = useMessages(); const { t, labels, messages } = useMessages();
const { latest, checked, hasUpdate, releaseUrl } = useVersion(); const { latest, checked, hasUpdate, releaseUrl } = useVersion();
const pathname = usePathname(); const pathname = usePathname();
const [dismissed, setDismissed] = useState(checked); const [dismissed, setDismissed] = useState(checked);
@ -49,11 +49,11 @@ export function UpdateNotice({ user, config }) {
return ( return (
<Column justifyContent="center" alignItems="center" position="fixed" top="10px" width="100%"> <Column justifyContent="center" alignItems="center" position="fixed" top="10px" width="100%">
<Row width="600px"> <Row width="600px">
<AlertBanner title={formatMessage(messages.newVersionAvailable, { version: `v${latest}` })}> <AlertBanner title={t(messages.newVersionAvailable, { version: `v${latest}` })}>
<Button variant="primary" onPress={handleViewClick}> <Button variant="primary" onPress={handleViewClick}>
{formatMessage(labels.viewDetails)} {t(labels.viewDetails)}
</Button> </Button>
<Button onPress={handleDismissClick}>{formatMessage(labels.dismiss)}</Button> <Button onPress={handleDismissClick}>{t(labels.dismiss)}</Button>
</AlertBanner> </AlertBanner>
</Row> </Row>
</Column> </Column>

View file

@ -3,28 +3,28 @@ import { useMessages, useNavigation } from '@/components/hooks';
import { Globe, User, Users } from '@/components/icons'; import { Globe, User, Users } from '@/components/icons';
export function AdminNav({ onItemClick }: { onItemClick?: () => void }) { export function AdminNav({ onItemClick }: { onItemClick?: () => void }) {
const { formatMessage, labels } = useMessages(); const { t, labels } = useMessages();
const { pathname } = useNavigation(); const { pathname } = useNavigation();
const items = [ const items = [
{ {
label: formatMessage(labels.manage), label: t(labels.manage),
items: [ items: [
{ {
id: 'users', id: 'users',
label: formatMessage(labels.users), label: t(labels.users),
path: '/admin/users', path: '/admin/users',
icon: <User />, icon: <User />,
}, },
{ {
id: 'websites', id: 'websites',
label: formatMessage(labels.websites), label: t(labels.websites),
path: '/admin/websites', path: '/admin/websites',
icon: <Globe />, icon: <Globe />,
}, },
{ {
id: 'teams', id: 'teams',
label: formatMessage(labels.teams), label: t(labels.teams),
path: '/admin/teams', path: '/admin/teams',
icon: <Users />, icon: <Users />,
}, },
@ -39,7 +39,7 @@ export function AdminNav({ onItemClick }: { onItemClick?: () => void }) {
return ( return (
<NavMenu <NavMenu
items={items} items={items}
title={formatMessage(labels.admin)} title={t(labels.admin)}
selectedKey={selectedKey} selectedKey={selectedKey}
allowMinimize={false} allowMinimize={false}
onItemClick={onItemClick} onItemClick={onItemClick}

View file

@ -7,13 +7,13 @@ import { TeamsAddButton } from '../../teams/TeamsAddButton';
import { AdminTeamsDataTable } from './AdminTeamsDataTable'; import { AdminTeamsDataTable } from './AdminTeamsDataTable';
export function AdminTeamsPage() { export function AdminTeamsPage() {
const { formatMessage, labels } = useMessages(); const { t, labels } = useMessages();
const handleSave = () => {}; const handleSave = () => {};
return ( return (
<Column gap="6" margin="2"> <Column gap="6" margin="2">
<PageHeader title={formatMessage(labels.teams)}> <PageHeader title={t(labels.teams)}>
<TeamsAddButton onSave={handleSave} isAdmin={true} /> <TeamsAddButton onSave={handleSave} isAdmin={true} />
</PageHeader> </PageHeader>
<Panel> <Panel>

View file

@ -14,22 +14,22 @@ export function AdminTeamsTable({
data: any[]; data: any[];
showActions?: boolean; showActions?: boolean;
}) { }) {
const { formatMessage, labels } = useMessages(); const { t, labels } = useMessages();
const [deleteTeam, setDeleteTeam] = useState(null); const [deleteTeam, setDeleteTeam] = useState(null);
return ( return (
<> <>
<DataTable data={data}> <DataTable data={data}>
<DataColumn id="name" label={formatMessage(labels.name)} width="1fr"> <DataColumn id="name" label={t(labels.name)} width="1fr">
{(row: any) => <Link href={`/admin/teams/${row.id}`}>{row.name}</Link>} {(row: any) => <Link href={`/admin/teams/${row.id}`}>{row.name}</Link>}
</DataColumn> </DataColumn>
<DataColumn id="websites" label={formatMessage(labels.members)} width="140px"> <DataColumn id="websites" label={t(labels.members)} width="140px">
{(row: any) => row?._count?.members} {(row: any) => row?._count?.members}
</DataColumn> </DataColumn>
<DataColumn id="members" label={formatMessage(labels.websites)} width="140px"> <DataColumn id="members" label={t(labels.websites)} width="140px">
{(row: any) => row?._count?.websites} {(row: any) => row?._count?.websites}
</DataColumn> </DataColumn>
<DataColumn id="owner" label={formatMessage(labels.owner)}> <DataColumn id="owner" label={t(labels.owner)}>
{(row: any) => { {(row: any) => {
const name = row?.members?.[0]?.user?.username; const name = row?.members?.[0]?.user?.username;
@ -40,7 +40,7 @@ export function AdminTeamsTable({
); );
}} }}
</DataColumn> </DataColumn>
<DataColumn id="created" label={formatMessage(labels.created)} width="160px"> <DataColumn id="created" label={t(labels.created)} width="160px">
{(row: any) => <DateDistance date={new Date(row.createdAt)} />} {(row: any) => <DateDistance date={new Date(row.createdAt)} />}
</DataColumn> </DataColumn>
{showActions && ( {showActions && (
@ -55,7 +55,7 @@ export function AdminTeamsTable({
<Icon> <Icon>
<Edit /> <Edit />
</Icon> </Icon>
<Text>{formatMessage(labels.edit)}</Text> <Text>{t(labels.edit)}</Text>
</Row> </Row>
</MenuItem> </MenuItem>
<MenuItem <MenuItem
@ -67,7 +67,7 @@ export function AdminTeamsTable({
<Icon> <Icon>
<Trash /> <Trash />
</Icon> </Icon>
<Text>{formatMessage(labels.delete)}</Text> <Text>{t(labels.delete)}</Text>
</Row> </Row>
</MenuItem> </MenuItem>
</MenuButton> </MenuButton>

View file

@ -4,12 +4,12 @@ import { Plus } from '@/components/icons';
import { UserAddForm } from './UserAddForm'; import { UserAddForm } from './UserAddForm';
export function UserAddButton({ onSave }: { onSave?: () => void }) { export function UserAddButton({ onSave }: { onSave?: () => void }) {
const { formatMessage, labels, messages } = useMessages(); const { t, labels, messages } = useMessages();
const { toast } = useToast(); const { toast } = useToast();
const { touch } = useModified(); const { touch } = useModified();
const handleSave = () => { const handleSave = () => {
toast(formatMessage(messages.saved)); toast(t(messages.saved));
touch('users'); touch('users');
onSave?.(); onSave?.();
}; };
@ -20,10 +20,10 @@ export function UserAddButton({ onSave }: { onSave?: () => void }) {
<Icon> <Icon>
<Plus /> <Plus />
</Icon> </Icon>
<Text>{formatMessage(labels.createUser)}</Text> <Text>{t(labels.createUser)}</Text>
</Button> </Button>
<Modal> <Modal>
<Dialog title={formatMessage(labels.createUser)} style={{ width: 400 }}> <Dialog title={t(labels.createUser)} style={{ width: 400 }}>
{({ close }) => <UserAddForm onSave={handleSave} onClose={close} />} {({ close }) => <UserAddForm onSave={handleSave} onClose={close} />}
</Dialog> </Dialog>
</Modal> </Modal>

View file

@ -10,12 +10,11 @@ import {
TextField, TextField,
} from '@umami/react-zen'; } from '@umami/react-zen';
import { useMessages, useUpdateQuery } from '@/components/hooks'; import { useMessages, useUpdateQuery } from '@/components/hooks';
import { messages } from '@/components/messages';
import { ROLES } from '@/lib/constants'; import { ROLES } from '@/lib/constants';
export function UserAddForm({ onSave, onClose }) { export function UserAddForm({ onSave, onClose }) {
const { mutateAsync, error, isPending } = useUpdateQuery(`/users`); const { mutateAsync, error, isPending } = useUpdateQuery(`/users`);
const { formatMessage, labels, getErrorMessage } = useMessages(); const { t, labels, messages, getErrorMessage } = useMessages();
const handleSubmit = async (data: any) => { const handleSubmit = async (data: any) => {
await mutateAsync(data, { await mutateAsync(data, {
@ -29,45 +28,41 @@ export function UserAddForm({ onSave, onClose }) {
return ( return (
<Form onSubmit={handleSubmit} error={getErrorMessage(error)}> <Form onSubmit={handleSubmit} error={getErrorMessage(error)}>
<FormField <FormField
label={formatMessage(labels.username)} label={t(labels.username)}
name="username" name="username"
rules={{ required: formatMessage(labels.required) }} rules={{ required: t(labels.required) }}
> >
<TextField autoComplete="new-username" data-test="input-username" /> <TextField autoComplete="new-username" data-test="input-username" />
</FormField> </FormField>
<FormField <FormField
label={formatMessage(labels.password)} label={t(labels.password)}
name="password" name="password"
rules={{ rules={{
required: formatMessage(labels.required), required: t(labels.required),
minLength: { value: 8, message: formatMessage(messages.minPasswordLength, { n: '8' }) }, minLength: { value: 8, message: t(messages.minPasswordLength, { n: '8' }) },
}} }}
> >
<PasswordField autoComplete="new-password" data-test="input-password" /> <PasswordField autoComplete="new-password" data-test="input-password" />
</FormField> </FormField>
<FormField <FormField label={t(labels.role)} name="role" rules={{ required: t(labels.required) }}>
label={formatMessage(labels.role)}
name="role"
rules={{ required: formatMessage(labels.required) }}
>
<Select> <Select>
<ListItem id={ROLES.viewOnly} data-test="dropdown-item-viewOnly"> <ListItem id={ROLES.viewOnly} data-test="dropdown-item-viewOnly">
{formatMessage(labels.viewOnly)} {t(labels.viewOnly)}
</ListItem> </ListItem>
<ListItem id={ROLES.user} data-test="dropdown-item-user"> <ListItem id={ROLES.user} data-test="dropdown-item-user">
{formatMessage(labels.user)} {t(labels.user)}
</ListItem> </ListItem>
<ListItem id={ROLES.admin} data-test="dropdown-item-admin"> <ListItem id={ROLES.admin} data-test="dropdown-item-admin">
{formatMessage(labels.admin)} {t(labels.admin)}
</ListItem> </ListItem>
</Select> </Select>
</FormField> </FormField>
<FormButtons> <FormButtons>
<Button isDisabled={isPending} onPress={onClose}> <Button isDisabled={isPending} onPress={onClose}>
{formatMessage(labels.cancel)} {t(labels.cancel)}
</Button> </Button>
<FormSubmitButton variant="primary" data-test="button-submit" isDisabled={false}> <FormSubmitButton variant="primary" data-test="button-submit" isDisabled={false}>
{formatMessage(labels.save)} {t(labels.save)}
</FormSubmitButton> </FormSubmitButton>
</FormButtons> </FormButtons>
</Form> </Form>

View file

@ -12,7 +12,7 @@ export function UserDeleteButton({
username: string; username: string;
onDelete?: () => void; onDelete?: () => void;
}) { }) {
const { formatMessage, labels } = useMessages(); const { t, labels } = useMessages();
const { user } = useLoginQuery(); const { user } = useLoginQuery();
return ( return (
@ -21,10 +21,10 @@ export function UserDeleteButton({
<Icon size="sm"> <Icon size="sm">
<Trash /> <Trash />
</Icon> </Icon>
<Text>{formatMessage(labels.delete)}</Text> <Text>{t(labels.delete)}</Text>
</Button> </Button>
<Modal> <Modal>
<Dialog title={formatMessage(labels.deleteUser)} style={{ width: 400 }}> <Dialog title={t(labels.deleteUser)} style={{ width: 400 }}>
{({ close }) => ( {({ close }) => (
<UserDeleteForm userId={userId} username={username} onSave={onDelete} onClose={close} /> <UserDeleteForm userId={userId} username={username} onSave={onDelete} onClose={close} />
)} )}

View file

@ -12,7 +12,7 @@ export function UserDeleteForm({
onSave?: () => void; onSave?: () => void;
onClose?: () => void; onClose?: () => void;
}) { }) {
const { messages, labels, formatMessage } = useMessages(); const { messages, labels, t } = useMessages();
const { mutateAsync } = useDeleteQuery(`/users/${userId}`); const { mutateAsync } = useDeleteQuery(`/users/${userId}`);
const { touch } = useModified(); const { touch } = useModified();
@ -29,13 +29,13 @@ export function UserDeleteForm({
return ( return (
<AlertDialog <AlertDialog
title={formatMessage(labels.delete)} title={t(labels.delete)}
onConfirm={handleConfirm} onConfirm={handleConfirm}
onCancel={onClose} onCancel={onClose}
confirmLabel={formatMessage(labels.delete)} confirmLabel={t(labels.delete)}
isDanger isDanger
> >
<Row gap="1">{formatMessage(messages.confirmDelete, { target: username })}</Row> <Row gap="1">{t(messages.confirmDelete, { target: username })}</Row>
</AlertDialog> </AlertDialog>
); );
} }

View file

@ -7,13 +7,13 @@ import { UserAddButton } from './UserAddButton';
import { UsersDataTable } from './UsersDataTable'; import { UsersDataTable } from './UsersDataTable';
export function UsersPage() { export function UsersPage() {
const { formatMessage, labels } = useMessages(); const { t, labels } = useMessages();
const handleSave = () => {}; const handleSave = () => {};
return ( return (
<Column gap="6" margin="2"> <Column gap="6" margin="2">
<PageHeader title={formatMessage(labels.users)}> <PageHeader title={t(labels.users)}>
<UserAddButton onSave={handleSave} /> <UserAddButton onSave={handleSave} />
</PageHeader> </PageHeader>
<Panel> <Panel>

View file

@ -15,26 +15,24 @@ export function UsersTable({
data: any[]; data: any[];
showActions?: boolean; showActions?: boolean;
}) { }) {
const { formatMessage, labels } = useMessages(); const { t, labels } = useMessages();
const [deleteUser, setDeleteUser] = useState(null); const [deleteUser, setDeleteUser] = useState(null);
return ( return (
<> <>
<DataTable data={data}> <DataTable data={data}>
<DataColumn id="username" label={formatMessage(labels.username)} width="2fr"> <DataColumn id="username" label={t(labels.username)} width="2fr">
{(row: any) => <Link href={`/admin/users/${row.id}`}>{row.username}</Link>} {(row: any) => <Link href={`/admin/users/${row.id}`}>{row.username}</Link>}
</DataColumn> </DataColumn>
<DataColumn id="role" label={formatMessage(labels.role)}> <DataColumn id="role" label={t(labels.role)}>
{(row: any) => {(row: any) =>
formatMessage( t(labels[Object.keys(ROLES).find(key => ROLES[key] === row.role)] || labels.unknown)
labels[Object.keys(ROLES).find(key => ROLES[key] === row.role)] || labels.unknown,
)
} }
</DataColumn> </DataColumn>
<DataColumn id="websites" label={formatMessage(labels.websites)}> <DataColumn id="websites" label={t(labels.websites)}>
{(row: any) => row._count.websites} {(row: any) => row._count.websites}
</DataColumn> </DataColumn>
<DataColumn id="created" label={formatMessage(labels.created)}> <DataColumn id="created" label={t(labels.created)}>
{(row: any) => <DateDistance date={new Date(row.createdAt)} />} {(row: any) => <DateDistance date={new Date(row.createdAt)} />}
</DataColumn> </DataColumn>
{showActions && ( {showActions && (
@ -49,7 +47,7 @@ export function UsersTable({
<Icon> <Icon>
<Edit /> <Edit />
</Icon> </Icon>
<Text>{formatMessage(labels.edit)}</Text> <Text>{t(labels.edit)}</Text>
</Row> </Row>
</MenuItem> </MenuItem>
<MenuItem <MenuItem
@ -61,7 +59,7 @@ export function UsersTable({
<Icon> <Icon>
<Trash /> <Trash />
</Icon> </Icon>
<Text>{formatMessage(labels.delete)}</Text> <Text>{t(labels.delete)}</Text>
</Row> </Row>
</MenuItem> </MenuItem>
</MenuButton> </MenuButton>

View file

@ -12,7 +12,7 @@ import { useLoginQuery, useMessages, useUpdateQuery, useUser } from '@/component
import { ROLES } from '@/lib/constants'; import { ROLES } from '@/lib/constants';
export function UserEditForm({ userId, onSave }: { userId: string; onSave?: () => void }) { export function UserEditForm({ userId, onSave }: { userId: string; onSave?: () => void }) {
const { formatMessage, labels, messages, getMessage } = useMessages(); const { t, labels, messages, getMessage } = useMessages();
const user = useUser(); const user = useUser();
const { user: login } = useLoginQuery(); const { user: login } = useLoginQuery();
@ -21,7 +21,7 @@ export function UserEditForm({ userId, onSave }: { userId: string; onSave?: () =
const handleSubmit = async (data: any) => { const handleSubmit = async (data: any) => {
await mutateAsync(data, { await mutateAsync(data, {
onSuccess: async () => { onSuccess: async () => {
toast(formatMessage(messages.saved)); toast(t(messages.saved));
touch('users'); touch('users');
touch(`user:${user.id}`); touch(`user:${user.id}`);
onSave?.(); onSave?.();
@ -31,41 +31,37 @@ export function UserEditForm({ userId, onSave }: { userId: string; onSave?: () =
return ( return (
<Form onSubmit={handleSubmit} error={getMessage(error?.code)} values={user}> <Form onSubmit={handleSubmit} error={getMessage(error?.code)} values={user}>
<FormField name="username" label={formatMessage(labels.username)}> <FormField name="username" label={t(labels.username)}>
<TextField data-test="input-username" /> <TextField data-test="input-username" />
</FormField> </FormField>
<FormField <FormField
name="password" name="password"
label={formatMessage(labels.password)} label={t(labels.password)}
rules={{ rules={{
minLength: { value: 8, message: formatMessage(messages.minPasswordLength, { n: '8' }) }, minLength: { value: 8, message: t(messages.minPasswordLength, { n: '8' }) },
}} }}
> >
<PasswordField autoComplete="new-password" data-test="input-password" /> <PasswordField autoComplete="new-password" data-test="input-password" />
</FormField> </FormField>
{user.id !== login.id && ( {user.id !== login.id && (
<FormField <FormField name="role" label={t(labels.role)} rules={{ required: t(labels.required) }}>
name="role"
label={formatMessage(labels.role)}
rules={{ required: formatMessage(labels.required) }}
>
<Select defaultValue={user.role}> <Select defaultValue={user.role}>
<ListItem id={ROLES.viewOnly} data-test="dropdown-item-viewOnly"> <ListItem id={ROLES.viewOnly} data-test="dropdown-item-viewOnly">
{formatMessage(labels.viewOnly)} {t(labels.viewOnly)}
</ListItem> </ListItem>
<ListItem id={ROLES.user} data-test="dropdown-item-user"> <ListItem id={ROLES.user} data-test="dropdown-item-user">
{formatMessage(labels.user)} {t(labels.user)}
</ListItem> </ListItem>
<ListItem id={ROLES.admin} data-test="dropdown-item-admin"> <ListItem id={ROLES.admin} data-test="dropdown-item-admin">
{formatMessage(labels.admin)} {t(labels.admin)}
</ListItem> </ListItem>
</Select> </Select>
</FormField> </FormField>
)} )}
<FormButtons> <FormButtons>
<FormSubmitButton data-test="button-submit" variant="primary"> <FormSubmitButton data-test="button-submit" variant="primary">
{formatMessage(labels.save)} {t(labels.save)}
</FormSubmitButton> </FormSubmitButton>
</FormButtons> </FormButtons>
</Form> </Form>

View file

@ -4,14 +4,14 @@ import { UserEditForm } from './UserEditForm';
import { UserWebsites } from './UserWebsites'; import { UserWebsites } from './UserWebsites';
export function UserSettings({ userId }: { userId: string }) { export function UserSettings({ userId }: { userId: string }) {
const { formatMessage, labels } = useMessages(); const { t, labels } = useMessages();
return ( return (
<Column gap="6"> <Column gap="6">
<Tabs> <Tabs>
<TabList> <TabList>
<Tab id="details">{formatMessage(labels.details)}</Tab> <Tab id="details">{t(labels.details)}</Tab>
<Tab id="websites">{formatMessage(labels.websites)}</Tab> <Tab id="websites">{t(labels.websites)}</Tab>
</TabList> </TabList>
<TabPanel id="details" style={{ width: 500 }}> <TabPanel id="details" style={{ width: 500 }}>
<UserEditForm userId={userId} /> <UserEditForm userId={userId} />

View file

@ -6,11 +6,11 @@ import { useMessages } from '@/components/hooks';
import { AdminWebsitesDataTable } from './AdminWebsitesDataTable'; import { AdminWebsitesDataTable } from './AdminWebsitesDataTable';
export function AdminWebsitesPage() { export function AdminWebsitesPage() {
const { formatMessage, labels } = useMessages(); const { t, labels } = useMessages();
return ( return (
<Column gap="6" margin="2"> <Column gap="6" margin="2">
<PageHeader title={formatMessage(labels.websites)} /> <PageHeader title={t(labels.websites)} />
<Panel> <Panel>
<AdminWebsitesDataTable /> <AdminWebsitesDataTable />
</Panel> </Panel>

View file

@ -8,23 +8,23 @@ import { Edit, Trash, Users } from '@/components/icons';
import { MenuButton } from '@/components/input/MenuButton'; import { MenuButton } from '@/components/input/MenuButton';
export function AdminWebsitesTable({ data = [] }: { data: any[] }) { export function AdminWebsitesTable({ data = [] }: { data: any[] }) {
const { formatMessage, labels } = useMessages(); const { t, labels } = useMessages();
const [deleteWebsite, setDeleteWebsite] = useState(null); const [deleteWebsite, setDeleteWebsite] = useState(null);
return ( return (
<> <>
<DataTable data={data}> <DataTable data={data}>
<DataColumn id="name" label={formatMessage(labels.name)}> <DataColumn id="name" label={t(labels.name)}>
{(row: any) => ( {(row: any) => (
<Text truncate> <Text truncate>
<Link href={`/admin/websites/${row.id}`}>{row.name}</Link> <Link href={`/admin/websites/${row.id}`}>{row.name}</Link>
</Text> </Text>
)} )}
</DataColumn> </DataColumn>
<DataColumn id="domain" label={formatMessage(labels.domain)}> <DataColumn id="domain" label={t(labels.domain)}>
{(row: any) => <Text truncate>{row.domain}</Text>} {(row: any) => <Text truncate>{row.domain}</Text>}
</DataColumn> </DataColumn>
<DataColumn id="owner" label={formatMessage(labels.owner)}> <DataColumn id="owner" label={t(labels.owner)}>
{(row: any) => { {(row: any) => {
if (row?.team) { if (row?.team) {
return ( return (
@ -45,7 +45,7 @@ export function AdminWebsitesTable({ data = [] }: { data: any[] }) {
); );
}} }}
</DataColumn> </DataColumn>
<DataColumn id="created" label={formatMessage(labels.created)} width="180px"> <DataColumn id="created" label={t(labels.created)} width="180px">
{(row: any) => <DateDistance date={new Date(row.createdAt)} />} {(row: any) => <DateDistance date={new Date(row.createdAt)} />}
</DataColumn> </DataColumn>
<DataColumn id="action" align="end" width="50px"> <DataColumn id="action" align="end" width="50px">
@ -59,7 +59,7 @@ export function AdminWebsitesTable({ data = [] }: { data: any[] }) {
<Icon> <Icon>
<Edit /> <Edit />
</Icon> </Icon>
<Text>{formatMessage(labels.edit)}</Text> <Text>{t(labels.edit)}</Text>
</Row> </Row>
</MenuItem> </MenuItem>
<MenuItem <MenuItem
@ -71,7 +71,7 @@ export function AdminWebsitesTable({ data = [] }: { data: any[] }) {
<Icon> <Icon>
<Trash /> <Trash />
</Icon> </Icon>
<Text>{formatMessage(labels.delete)}</Text> <Text>{t(labels.delete)}</Text>
</Row> </Row>
</MenuItem> </MenuItem>
</MenuButton> </MenuButton>

View file

@ -4,13 +4,13 @@ import { Plus } from '@/components/icons';
import { BoardAddForm } from './BoardAddForm'; import { BoardAddForm } from './BoardAddForm';
export function BoardAddButton() { export function BoardAddButton() {
const { formatMessage, labels, messages } = useMessages(); const { t, labels, messages } = useMessages();
const { toast } = useToast(); const { toast } = useToast();
const { touch } = useModified(); const { touch } = useModified();
const { teamId } = useNavigation(); const { teamId } = useNavigation();
const handleSave = async () => { const handleSave = async () => {
toast(formatMessage(messages.saved)); toast(t(messages.saved));
touch('boards'); touch('boards');
}; };
@ -20,10 +20,10 @@ export function BoardAddButton() {
<Icon> <Icon>
<Plus /> <Plus />
</Icon> </Icon>
<Text>{formatMessage(labels.addBoard)}</Text> <Text>{t(labels.addBoard)}</Text>
</Button> </Button>
<Modal> <Modal>
<Dialog title={formatMessage(labels.addBoard)} style={{ width: 400 }}> <Dialog title={t(labels.addBoard)} style={{ width: 400 }}>
{({ close }) => <BoardAddForm teamId={teamId} onSave={handleSave} onClose={close} />} {({ close }) => <BoardAddForm teamId={teamId} onSave={handleSave} onClose={close} />}
</Dialog> </Dialog>
</Modal> </Modal>

View file

@ -12,7 +12,7 @@ export function BoardAddForm({
onSave?: () => void; onSave?: () => void;
onClose?: () => void; onClose?: () => void;
}) { }) {
const { formatMessage, labels } = useMessages(); const { t, labels } = useMessages();
const { mutateAsync, error, isPending } = useUpdateQuery('/boards', { teamId }); const { mutateAsync, error, isPending } = useUpdateQuery('/boards', { teamId });
const [websiteId, setWebsiteId] = useState<string>(); const [websiteId, setWebsiteId] = useState<string>();
@ -30,34 +30,30 @@ export function BoardAddForm({
return ( return (
<Form onSubmit={handleSubmit} error={error?.message}> <Form onSubmit={handleSubmit} error={error?.message}>
<FormField <FormField label={t(labels.name)} name="name" rules={{ required: t(labels.required) }}>
label={formatMessage(labels.name)}
name="name"
rules={{ required: formatMessage(labels.required) }}
>
<TextField autoComplete="off" /> <TextField autoComplete="off" />
</FormField> </FormField>
<FormField <FormField
label={formatMessage(labels.description)} label={t(labels.description)}
name="description" name="description"
rules={{ rules={{
required: formatMessage(labels.required), required: t(labels.required),
}} }}
> >
<TextField asTextArea autoComplete="off" /> <TextField asTextArea autoComplete="off" />
</FormField> </FormField>
<Row alignItems="center" gap="3" paddingTop="3"> <Row alignItems="center" gap="3" paddingTop="3">
<Text>{formatMessage(labels.website)}</Text> <Text>{t(labels.website)}</Text>
<WebsiteSelect websiteId={websiteId} teamId={teamId} onChange={setWebsiteId} /> <WebsiteSelect websiteId={websiteId} teamId={teamId} onChange={setWebsiteId} />
</Row> </Row>
<Row justifyContent="flex-end" paddingTop="3" gap="3"> <Row justifyContent="flex-end" paddingTop="3" gap="3">
{onClose && ( {onClose && (
<Button isDisabled={isPending} onPress={onClose}> <Button isDisabled={isPending} onPress={onClose}>
{formatMessage(labels.cancel)} {t(labels.cancel)}
</Button> </Button>
)} )}
<FormSubmitButton data-test="button-submit" isDisabled={false}> <FormSubmitButton data-test="button-submit" isDisabled={false}>
{formatMessage(labels.save)} {t(labels.save)}
</FormSubmitButton> </FormSubmitButton>
</Row> </Row>
</Form> </Form>

View file

@ -40,7 +40,7 @@ export function BoardProvider({
const { post, useMutation } = useApi(); const { post, useMutation } = useApi();
const { touch } = useModified(); const { touch } = useModified();
const { toast } = useToast(); const { toast } = useToast();
const { formatMessage, labels, messages } = useMessages(); const { t, labels, messages } = useMessages();
const { router, renderUrl } = useNavigation(); const { router, renderUrl } = useNavigation();
const [board, setBoard] = useState<Partial<Board>>(data ?? createDefaultBoard()); const [board, setBoard] = useState<Partial<Board>>(data ?? createDefaultBoard());
@ -70,7 +70,7 @@ export function BoardProvider({
}, []); }, []);
const saveBoard = useCallback(async () => { const saveBoard = useCallback(async () => {
const defaultName = formatMessage(labels.untitled); const defaultName = t(labels.untitled);
// Get current layout sizes from BoardBody if registered // Get current layout sizes from BoardBody if registered
const layoutData = layoutGetterRef.current?.(); const layoutData = layoutGetterRef.current?.();
@ -82,7 +82,7 @@ export function BoardProvider({
parameters, parameters,
}); });
toast(formatMessage(messages.saved)); toast(t(messages.saved));
touch('boards'); touch('boards');
if (board.id) { if (board.id) {
@ -92,17 +92,7 @@ export function BoardProvider({
} }
return result; return result;
}, [ }, [board, mutateAsync, toast, t, labels.untitled, messages.saved, touch, router, renderUrl]);
board,
mutateAsync,
toast,
formatMessage,
labels.untitled,
messages.saved,
touch,
router,
renderUrl,
]);
if (boardId && isFetching && isLoading) { if (boardId && isFetching && isLoading) {
return <Loading placement="absolute" />; return <Loading placement="absolute" />;

View file

@ -10,14 +10,14 @@ import { Plus } from '@/components/icons';
import { BoardsDataTable } from './BoardsDataTable'; import { BoardsDataTable } from './BoardsDataTable';
export function BoardsPage() { export function BoardsPage() {
const { formatMessage, labels } = useMessages(); const { t, labels } = useMessages();
return ( return (
<PageBody> <PageBody>
<Column margin="2"> <Column margin="2">
<PageHeader title={formatMessage(labels.boards)}> <PageHeader title={t(labels.boards)}>
<LinkButton href="/boards/create" variant="primary"> <LinkButton href="/boards/create" variant="primary">
<IconLabel icon={<Plus />} label={formatMessage(labels.addBoard)} /> <IconLabel icon={<Plus />} label={t(labels.addBoard)} />
</LinkButton> </LinkButton>
</PageHeader> </PageHeader>
<Panel> <Panel>

View file

@ -4,19 +4,19 @@ import { DateDistance } from '@/components/common/DateDistance';
import { useMessages, useNavigation, useSlug } from '@/components/hooks'; import { useMessages, useNavigation, useSlug } from '@/components/hooks';
export function BoardsTable(props: DataTableProps) { export function BoardsTable(props: DataTableProps) {
const { formatMessage, labels } = useMessages(); const { t, labels } = useMessages();
const { websiteId, renderUrl } = useNavigation(); const { websiteId, renderUrl } = useNavigation();
const { getSlugUrl } = useSlug('link'); const { getSlugUrl } = useSlug('link');
return ( return (
<DataTable {...props}> <DataTable {...props}>
<DataColumn id="name" label={formatMessage(labels.name)}> <DataColumn id="name" label={t(labels.name)}>
{({ id, name }: any) => { {({ id, name }: any) => {
return <Board href={renderUrl(`/boards/${id}`)}>{name}</Board>; return <Board href={renderUrl(`/boards/${id}`)}>{name}</Board>;
}} }}
</DataColumn> </DataColumn>
<DataColumn id="description" label={formatMessage(labels.description)} /> <DataColumn id="description" label={t(labels.description)} />
<DataColumn id="created" label={formatMessage(labels.created)} width="200px"> <DataColumn id="created" label={t(labels.created)} width="200px">
{(row: any) => <DateDistance date={new Date(row.createdAt)} />} {(row: any) => <DateDistance date={new Date(row.createdAt)} />}
</DataColumn> </DataColumn>
<DataColumn id="action" align="end" width="100px"> <DataColumn id="action" align="end" width="100px">

View file

@ -13,9 +13,9 @@ import { WebsiteSelect } from '@/components/input/WebsiteSelect';
export function BoardEditHeader() { export function BoardEditHeader() {
const { board, updateBoard, saveBoard, isPending } = useBoard(); const { board, updateBoard, saveBoard, isPending } = useBoard();
const { formatMessage, labels } = useMessages(); const { t, labels } = useMessages();
const { teamId, router, renderUrl } = useNavigation(); const { router, renderUrl } = useNavigation();
const defaultName = formatMessage(labels.untitled); const defaultName = t(labels.untitled);
const handleNameChange = (value: string) => { const handleNameChange = (value: string) => {
updateBoard({ name: value }); updateBoard({ name: value });
@ -71,7 +71,7 @@ export function BoardEditHeader() {
variant="quiet" variant="quiet"
name="description" name="description"
value={board?.description ?? ''} value={board?.description ?? ''}
placeholder={`+ ${formatMessage(labels.addDescription)}`} placeholder={`+ ${t(labels.addDescription)}`}
autoComplete="off" autoComplete="off"
onChange={handleDescriptionChange} onChange={handleDescriptionChange}
style={{ width: '100%' }} style={{ width: '100%' }}
@ -80,21 +80,17 @@ export function BoardEditHeader() {
</TextField> </TextField>
</Row> </Row>
<Row alignItems="center" gap="3"> <Row alignItems="center" gap="3">
<Text>{formatMessage(labels.website)}</Text> <Text>{t(labels.website)}</Text>
<WebsiteSelect <WebsiteSelect websiteId={board?.parameters?.websiteId} onChange={handleWebsiteChange} />
websiteId={board?.parameters?.websiteId}
teamId={teamId}
onChange={handleWebsiteChange}
/>
</Row> </Row>
</Column> </Column>
<Column justifyContent="center" alignItems="flex-end"> <Column justifyContent="center" alignItems="flex-end">
<Row gap="3"> <Row gap="3">
<Button variant="quiet" onPress={handleCancel}> <Button variant="quiet" onPress={handleCancel}>
{formatMessage(labels.cancel)} {t(labels.cancel)}
</Button> </Button>
<LoadingButton variant="primary" onPress={handleSave} isLoading={isPending}> <LoadingButton variant="primary" onPress={handleSave} isLoading={isPending}>
{formatMessage(labels.save)} {t(labels.save)}
</LoadingButton> </LoadingButton>
</Row> </Row>
</Column> </Column>

View file

@ -8,14 +8,14 @@ import { Edit } from '@/components/icons';
export function BoardViewHeader() { export function BoardViewHeader() {
const { board } = useBoard(); const { board } = useBoard();
const { renderUrl } = useNavigation(); const { renderUrl } = useNavigation();
const { formatMessage, labels } = useMessages(); const { t, labels } = useMessages();
const { data: website } = useWebsiteQuery(board?.parameters?.websiteId); const { data: website } = useWebsiteQuery(board?.parameters?.websiteId);
return ( return (
<PageHeader title={board?.name} description={board?.description}> <PageHeader title={board?.name} description={board?.description}>
{website?.name && <Text>{website.name}</Text>} {website?.name && <Text>{website.name}</Text>}
<LinkButton href={renderUrl(`/boards/${board?.id}/edit`, false)}> <LinkButton href={renderUrl(`/boards/${board?.id}/edit`, false)}>
<IconLabel icon={<Edit />}>{formatMessage(labels.edit)}</IconLabel> <IconLabel icon={<Edit />}>{t(labels.edit)}</IconLabel>
</LinkButton> </LinkButton>
</PageHeader> </PageHeader>
); );

View file

@ -5,12 +5,12 @@ import { PageHeader } from '@/components/common/PageHeader';
import { useMessages } from '@/components/hooks'; import { useMessages } from '@/components/hooks';
export function DashboardPage() { export function DashboardPage() {
const { formatMessage, labels } = useMessages(); const { t, labels } = useMessages();
return ( return (
<PageBody> <PageBody>
<Column margin="2"> <Column margin="2">
<PageHeader title={formatMessage(labels.dashboard)}></PageHeader> <PageHeader title={t(labels.dashboard)}></PageHeader>
</Column> </Column>
</PageBody> </PageBody>
); );

View file

@ -4,15 +4,10 @@ import { DialogButton } from '@/components/input/DialogButton';
import { LinkEditForm } from './LinkEditForm'; import { LinkEditForm } from './LinkEditForm';
export function LinkAddButton({ teamId }: { teamId?: string }) { export function LinkAddButton({ teamId }: { teamId?: string }) {
const { formatMessage, labels } = useMessages(); const { t, labels } = useMessages();
return ( return (
<DialogButton <DialogButton icon={<Plus />} label={t(labels.addLink)} variant="primary" width="600px">
icon={<Plus />}
label={formatMessage(labels.addLink)}
variant="primary"
width="600px"
>
{({ close }) => <LinkEditForm teamId={teamId} onClose={close} />} {({ close }) => <LinkEditForm teamId={teamId} onClose={close} />}
</DialogButton> </DialogButton>
); );

View file

@ -2,7 +2,6 @@ import { ConfirmationForm } from '@/components/common/ConfirmationForm';
import { useDeleteQuery, useMessages, useModified } from '@/components/hooks'; import { useDeleteQuery, useMessages, useModified } from '@/components/hooks';
import { Trash } from '@/components/icons'; import { Trash } from '@/components/icons';
import { DialogButton } from '@/components/input/DialogButton'; import { DialogButton } from '@/components/input/DialogButton';
import { messages } from '@/components/messages';
export function LinkDeleteButton({ export function LinkDeleteButton({
linkId, linkId,
@ -14,7 +13,7 @@ export function LinkDeleteButton({
name: string; name: string;
onSave?: () => void; onSave?: () => void;
}) { }) {
const { formatMessage, labels, getErrorMessage, FormattedMessage } = useMessages(); const { t, labels, messages, getErrorMessage } = useMessages();
const { mutateAsync, isPending, error } = useDeleteQuery(`/links/${linkId}`); const { mutateAsync, isPending, error } = useDeleteQuery(`/links/${linkId}`);
const { touch } = useModified(); const { touch } = useModified();
@ -29,27 +28,18 @@ export function LinkDeleteButton({
}; };
return ( return (
<DialogButton <DialogButton icon={<Trash />} title={t(labels.confirm)} variant="quiet" width="400px">
icon={<Trash />}
title={formatMessage(labels.confirm)}
variant="quiet"
width="400px"
>
{({ close }) => ( {({ close }) => (
<ConfirmationForm <ConfirmationForm
message={ message={t.rich(messages.confirmRemove, {
<FormattedMessage target: name,
{...messages.confirmRemove} b: chunks => <b>{chunks}</b>,
values={{ })}
target: <b>{name}</b>,
}}
/>
}
isLoading={isPending} isLoading={isPending}
error={getErrorMessage(error)} error={getErrorMessage(error)}
onConfirm={handleConfirm.bind(null, close)} onConfirm={handleConfirm.bind(null, close)}
onClose={close} onClose={close}
buttonLabel={formatMessage(labels.delete)} buttonLabel={t(labels.delete)}
buttonVariant="danger" buttonVariant="danger"
/> />
)} )}

View file

@ -4,10 +4,10 @@ import { DialogButton } from '@/components/input/DialogButton';
import { LinkEditForm } from './LinkEditForm'; import { LinkEditForm } from './LinkEditForm';
export function LinkEditButton({ linkId }: { linkId: string }) { export function LinkEditButton({ linkId }: { linkId: string }) {
const { formatMessage, labels } = useMessages(); const { t, labels } = useMessages();
return ( return (
<DialogButton icon={<Edit />} title={formatMessage(labels.link)} variant="quiet" width="800px"> <DialogButton icon={<Edit />} title={t(labels.link)} variant="quiet" width="800px">
{({ close }) => { {({ close }) => {
return <LinkEditForm linkId={linkId} onClose={close} />; return <LinkEditForm linkId={linkId} onClose={close} />;
}} }}

View file

@ -32,7 +32,7 @@ export function LinkEditForm({
onSave?: () => void; onSave?: () => void;
onClose?: () => void; onClose?: () => void;
}) { }) {
const { formatMessage, labels, messages, getErrorMessage } = useMessages(); const { t, labels, messages, getErrorMessage } = useMessages();
const { mutateAsync, error, isPending, touch, toast } = useUpdateQuery( const { mutateAsync, error, isPending, touch, toast } = useUpdateQuery(
linkId ? `/links/${linkId}` : '/links', linkId ? `/links/${linkId}` : '/links',
{ {
@ -48,7 +48,7 @@ export function LinkEditForm({
const handleSubmit = async (data: any) => { const handleSubmit = async (data: any) => {
await mutateAsync(data, { await mutateAsync(data, {
onSuccess: async () => { onSuccess: async () => {
toast(formatMessage(messages.saved)); toast(t(messages.saved));
touch('links'); touch('links');
touch(`link:${linkId}`); touch(`link:${linkId}`);
onSave?.(); onSave?.();
@ -59,7 +59,7 @@ export function LinkEditForm({
const checkUrl = (url: string) => { const checkUrl = (url: string) => {
if (!isValidUrl(url)) { if (!isValidUrl(url)) {
return formatMessage(labels.invalidUrl); return t(labels.invalidUrl);
} }
return true; return true;
}; };
@ -79,18 +79,14 @@ export function LinkEditForm({
return ( return (
<> <>
<FormField <FormField label={t(labels.name)} name="name" rules={{ required: t(labels.required) }}>
label={formatMessage(labels.name)}
name="name"
rules={{ required: formatMessage(labels.required) }}
>
<TextField autoComplete="off" autoFocus /> <TextField autoComplete="off" autoFocus />
</FormField> </FormField>
<FormField <FormField
label={formatMessage(labels.destinationUrl)} label={t(labels.destinationUrl)}
name="url" name="url"
rules={{ required: formatMessage(labels.required), validate: checkUrl }} rules={{ required: t(labels.required), validate: checkUrl }}
> >
<TextField placeholder="https://example.com" autoComplete="off" /> <TextField placeholder="https://example.com" autoComplete="off" />
</FormField> </FormField>
@ -98,9 +94,9 @@ export function LinkEditForm({
<Grid columns="1fr auto" alignItems="end" gap> <Grid columns="1fr auto" alignItems="end" gap>
<FormField <FormField
name="slug" name="slug"
label={formatMessage({ id: 'label.slug', defaultMessage: 'Slug' })} label={t({ id: 'label.slug', defaultMessage: 'Slug' })}
rules={{ rules={{
required: formatMessage(labels.required), required: t(labels.required),
}} }}
> >
<TextField autoComplete="off" /> <TextField autoComplete="off" />
@ -116,7 +112,7 @@ export function LinkEditForm({
</Grid> </Grid>
<Column> <Column>
<Label>{formatMessage(labels.link)}</Label> <Label>{t(labels.link)}</Label>
<Row alignItems="center" gap> <Row alignItems="center" gap>
<TextField <TextField
value={`${hostUrl}/${slug}`} value={`${hostUrl}/${slug}`}
@ -131,10 +127,10 @@ export function LinkEditForm({
<Row justifyContent="flex-end" paddingTop="3" gap="3"> <Row justifyContent="flex-end" paddingTop="3" gap="3">
{onClose && ( {onClose && (
<Button isDisabled={isPending} onPress={onClose}> <Button isDisabled={isPending} onPress={onClose}>
{formatMessage(labels.cancel)} {t(labels.cancel)}
</Button> </Button>
)} )}
<FormSubmitButton>{formatMessage(labels.save)}</FormSubmitButton> <FormSubmitButton>{t(labels.save)}</FormSubmitButton>
</Row> </Row>
</> </>
); );

View file

@ -10,7 +10,7 @@ import { LinkAddButton } from './LinkAddButton';
export function LinksPage() { export function LinksPage() {
const { user } = useLoginQuery(); const { user } = useLoginQuery();
const { formatMessage, labels } = useMessages(); const { t, labels } = useMessages();
const { teamId } = useNavigation(); const { teamId } = useNavigation();
const { data } = useTeamMembersQuery(teamId); const { data } = useTeamMembersQuery(teamId);
@ -23,7 +23,7 @@ export function LinksPage() {
return ( return (
<PageBody> <PageBody>
<Column gap="6" margin="2"> <Column gap="6" margin="2">
<PageHeader title={formatMessage(labels.links)}> <PageHeader title={t(labels.links)}>
{showActions && <LinkAddButton teamId={teamId} />} {showActions && <LinkAddButton teamId={teamId} />}
</PageHeader> </PageHeader>
<Panel> <Panel>

View file

@ -11,18 +11,18 @@ export interface LinksTableProps extends DataTableProps {
} }
export function LinksTable({ showActions, ...props }: LinksTableProps) { export function LinksTable({ showActions, ...props }: LinksTableProps) {
const { formatMessage, labels } = useMessages(); const { t, labels } = useMessages();
const { websiteId, renderUrl } = useNavigation(); const { websiteId, renderUrl } = useNavigation();
const { getSlugUrl } = useSlug('link'); const { getSlugUrl } = useSlug('link');
return ( return (
<DataTable {...props}> <DataTable {...props}>
<DataColumn id="name" label={formatMessage(labels.name)}> <DataColumn id="name" label={t(labels.name)}>
{({ id, name }: any) => { {({ id, name }: any) => {
return <Link href={renderUrl(`/links/${id}`)}>{name}</Link>; return <Link href={renderUrl(`/links/${id}`)}>{name}</Link>;
}} }}
</DataColumn> </DataColumn>
<DataColumn id="slug" label={formatMessage(labels.link)}> <DataColumn id="slug" label={t(labels.link)}>
{({ slug }: any) => { {({ slug }: any) => {
const url = getSlugUrl(slug); const url = getSlugUrl(slug);
return ( return (
@ -32,12 +32,12 @@ export function LinksTable({ showActions, ...props }: LinksTableProps) {
); );
}} }}
</DataColumn> </DataColumn>
<DataColumn id="url" label={formatMessage(labels.destinationUrl)}> <DataColumn id="url" label={t(labels.destinationUrl)}>
{({ url }: any) => { {({ url }: any) => {
return <ExternalLink href={url}>{url}</ExternalLink>; return <ExternalLink href={url}>{url}</ExternalLink>;
}} }}
</DataColumn> </DataColumn>
<DataColumn id="created" label={formatMessage(labels.created)} width="200px"> <DataColumn id="created" label={t(labels.created)} width="200px">
{(row: any) => <DateDistance date={new Date(row.createdAt)} />} {(row: any) => <DateDistance date={new Date(row.createdAt)} />}
</DataColumn> </DataColumn>
{showActions && ( {showActions && (

View file

@ -5,14 +5,14 @@ import { useLink, useMessages, useSlug } from '@/components/hooks';
import { ExternalLink, Link } from '@/components/icons'; import { ExternalLink, Link } from '@/components/icons';
export function LinkHeader() { export function LinkHeader() {
const { formatMessage, labels } = useMessages(); const { t, labels } = useMessages();
const { getSlugUrl } = useSlug('link'); const { getSlugUrl } = useSlug('link');
const link = useLink(); const link = useLink();
return ( return (
<PageHeader title={link.name} description={link.url} icon={<Link />}> <PageHeader title={link.name} description={link.url} icon={<Link />}>
<LinkButton href={getSlugUrl(link.slug)} target="_blank" prefetch={false} asAnchor> <LinkButton href={getSlugUrl(link.slug)} target="_blank" prefetch={false} asAnchor>
<IconLabel icon={<ExternalLink />} label={formatMessage(labels.view)} /> <IconLabel icon={<ExternalLink />} label={t(labels.view)} />
</LinkButton> </LinkButton>
</PageHeader> </PageHeader>
); );

View file

@ -13,7 +13,7 @@ export function LinkMetricsBar({
compareMode?: boolean; compareMode?: boolean;
}) { }) {
const { isAllTime } = useDateRange(); const { isAllTime } = useDateRange();
const { formatMessage, labels } = useMessages(); const { t, labels } = useMessages();
const { data, isLoading, isFetching, error } = useWebsiteStatsQuery(linkId); const { data, isLoading, isFetching, error } = useWebsiteStatsQuery(linkId);
const { pageviews, visitors, visits, comparison } = data || {}; const { pageviews, visitors, visits, comparison } = data || {};
@ -22,19 +22,19 @@ export function LinkMetricsBar({
? [ ? [
{ {
value: visitors, value: visitors,
label: formatMessage(labels.visitors), label: t(labels.visitors),
change: visitors - comparison.visitors, change: visitors - comparison.visitors,
formatValue: formatLongNumber, formatValue: formatLongNumber,
}, },
{ {
value: visits, value: visits,
label: formatMessage(labels.visits), label: t(labels.visits),
change: visits - comparison.visits, change: visits - comparison.visits,
formatValue: formatLongNumber, formatValue: formatLongNumber,
}, },
{ {
value: pageviews, value: pageviews,
label: formatMessage(labels.views), label: t(labels.views),
change: pageviews - comparison.pageviews, change: pageviews - comparison.pageviews,
formatValue: formatLongNumber, formatValue: formatLongNumber,
}, },

View file

@ -6,13 +6,13 @@ import { MetricsTable } from '@/components/metrics/MetricsTable';
import { WorldMap } from '@/components/metrics/WorldMap'; import { WorldMap } from '@/components/metrics/WorldMap';
export function LinkPanels({ linkId }: { linkId: string }) { export function LinkPanels({ linkId }: { linkId: string }) {
const { formatMessage, labels } = useMessages(); const { t, labels } = useMessages();
const tableProps = { const tableProps = {
websiteId: linkId, websiteId: linkId,
limit: 10, limit: 10,
allowDownload: false, allowDownload: false,
showMore: true, showMore: true,
metric: formatMessage(labels.visitors), metric: t(labels.visitors),
}; };
const rowProps = { minHeight: 570 }; const rowProps = { minHeight: 570 };
@ -20,36 +20,36 @@ export function LinkPanels({ linkId }: { linkId: string }) {
<Grid gap="3"> <Grid gap="3">
<GridRow layout="two" {...rowProps}> <GridRow layout="two" {...rowProps}>
<Panel> <Panel>
<Heading size="2xl">{formatMessage(labels.sources)}</Heading> <Heading size="2xl">{t(labels.sources)}</Heading>
<Tabs> <Tabs>
<TabList> <TabList>
<Tab id="referrer">{formatMessage(labels.referrers)}</Tab> <Tab id="referrer">{t(labels.referrers)}</Tab>
<Tab id="channel">{formatMessage(labels.channels)}</Tab> <Tab id="channel">{t(labels.channels)}</Tab>
</TabList> </TabList>
<TabPanel id="referrer"> <TabPanel id="referrer">
<MetricsTable type="referrer" title={formatMessage(labels.domain)} {...tableProps} /> <MetricsTable type="referrer" title={t(labels.domain)} {...tableProps} />
</TabPanel> </TabPanel>
<TabPanel id="channel"> <TabPanel id="channel">
<MetricsTable type="channel" title={formatMessage(labels.type)} {...tableProps} /> <MetricsTable type="channel" title={t(labels.type)} {...tableProps} />
</TabPanel> </TabPanel>
</Tabs> </Tabs>
</Panel> </Panel>
<Panel> <Panel>
<Heading size="2xl">{formatMessage(labels.environment)}</Heading> <Heading size="2xl">{t(labels.environment)}</Heading>
<Tabs> <Tabs>
<TabList> <TabList>
<Tab id="browser">{formatMessage(labels.browsers)}</Tab> <Tab id="browser">{t(labels.browsers)}</Tab>
<Tab id="os">{formatMessage(labels.os)}</Tab> <Tab id="os">{t(labels.os)}</Tab>
<Tab id="device">{formatMessage(labels.devices)}</Tab> <Tab id="device">{t(labels.devices)}</Tab>
</TabList> </TabList>
<TabPanel id="browser"> <TabPanel id="browser">
<MetricsTable type="browser" title={formatMessage(labels.browser)} {...tableProps} /> <MetricsTable type="browser" title={t(labels.browser)} {...tableProps} />
</TabPanel> </TabPanel>
<TabPanel id="os"> <TabPanel id="os">
<MetricsTable type="os" title={formatMessage(labels.os)} {...tableProps} /> <MetricsTable type="os" title={t(labels.os)} {...tableProps} />
</TabPanel> </TabPanel>
<TabPanel id="device"> <TabPanel id="device">
<MetricsTable type="device" title={formatMessage(labels.device)} {...tableProps} /> <MetricsTable type="device" title={t(labels.device)} {...tableProps} />
</TabPanel> </TabPanel>
</Tabs> </Tabs>
</Panel> </Panel>
@ -59,21 +59,21 @@ export function LinkPanels({ linkId }: { linkId: string }) {
<WorldMap websiteId={linkId} /> <WorldMap websiteId={linkId} />
</Panel> </Panel>
<Panel> <Panel>
<Heading size="2xl">{formatMessage(labels.location)}</Heading> <Heading size="2xl">{t(labels.location)}</Heading>
<Tabs> <Tabs>
<TabList> <TabList>
<Tab id="country">{formatMessage(labels.countries)}</Tab> <Tab id="country">{t(labels.countries)}</Tab>
<Tab id="region">{formatMessage(labels.regions)}</Tab> <Tab id="region">{t(labels.regions)}</Tab>
<Tab id="city">{formatMessage(labels.cities)}</Tab> <Tab id="city">{t(labels.cities)}</Tab>
</TabList> </TabList>
<TabPanel id="country"> <TabPanel id="country">
<MetricsTable type="country" title={formatMessage(labels.country)} {...tableProps} /> <MetricsTable type="country" title={t(labels.country)} {...tableProps} />
</TabPanel> </TabPanel>
<TabPanel id="region"> <TabPanel id="region">
<MetricsTable type="region" title={formatMessage(labels.region)} {...tableProps} /> <MetricsTable type="region" title={t(labels.region)} {...tableProps} />
</TabPanel> </TabPanel>
<TabPanel id="city"> <TabPanel id="city">
<MetricsTable type="city" title={formatMessage(labels.city)} {...tableProps} /> <MetricsTable type="city" title={t(labels.city)} {...tableProps} />
</TabPanel> </TabPanel>
</Tabs> </Tabs>
</Panel> </Panel>

View file

@ -4,15 +4,10 @@ import { DialogButton } from '@/components/input/DialogButton';
import { PixelEditForm } from './PixelEditForm'; import { PixelEditForm } from './PixelEditForm';
export function PixelAddButton({ teamId }: { teamId?: string }) { export function PixelAddButton({ teamId }: { teamId?: string }) {
const { formatMessage, labels } = useMessages(); const { t, labels } = useMessages();
return ( return (
<DialogButton <DialogButton icon={<Plus />} label={t(labels.addPixel)} variant="primary" width="600px">
icon={<Plus />}
label={formatMessage(labels.addPixel)}
variant="primary"
width="600px"
>
{({ close }) => <PixelEditForm teamId={teamId} onClose={close} />} {({ close }) => <PixelEditForm teamId={teamId} onClose={close} />}
</DialogButton> </DialogButton>
); );

View file

@ -2,7 +2,6 @@ import { ConfirmationForm } from '@/components/common/ConfirmationForm';
import { useDeleteQuery, useMessages, useModified } from '@/components/hooks'; import { useDeleteQuery, useMessages, useModified } from '@/components/hooks';
import { Trash } from '@/components/icons'; import { Trash } from '@/components/icons';
import { DialogButton } from '@/components/input/DialogButton'; import { DialogButton } from '@/components/input/DialogButton';
import { messages } from '@/components/messages';
export function PixelDeleteButton({ export function PixelDeleteButton({
pixelId, pixelId,
@ -13,7 +12,7 @@ export function PixelDeleteButton({
name: string; name: string;
onSave?: () => void; onSave?: () => void;
}) { }) {
const { formatMessage, labels, getErrorMessage, FormattedMessage } = useMessages(); const { t, labels, messages, getErrorMessage } = useMessages();
const { mutateAsync, isPending, error } = useDeleteQuery(`/pixels/${pixelId}`); const { mutateAsync, isPending, error } = useDeleteQuery(`/pixels/${pixelId}`);
const { touch } = useModified(); const { touch } = useModified();
@ -28,27 +27,18 @@ export function PixelDeleteButton({
}; };
return ( return (
<DialogButton <DialogButton icon={<Trash />} variant="quiet" title={t(labels.confirm)} width="400px">
icon={<Trash />}
variant="quiet"
title={formatMessage(labels.confirm)}
width="400px"
>
{({ close }) => ( {({ close }) => (
<ConfirmationForm <ConfirmationForm
message={ message={t.rich(messages.confirmRemove, {
<FormattedMessage target: name,
{...messages.confirmRemove} b: chunks => <b>{chunks}</b>,
values={{ })}
target: <b>{name}</b>,
}}
/>
}
isLoading={isPending} isLoading={isPending}
error={getErrorMessage(error)} error={getErrorMessage(error)}
onConfirm={handleConfirm.bind(null, close)} onConfirm={handleConfirm.bind(null, close)}
onClose={close} onClose={close}
buttonLabel={formatMessage(labels.delete)} buttonLabel={t(labels.delete)}
buttonVariant="danger" buttonVariant="danger"
/> />
)} )}

View file

@ -4,15 +4,10 @@ import { DialogButton } from '@/components/input/DialogButton';
import { PixelEditForm } from './PixelEditForm'; import { PixelEditForm } from './PixelEditForm';
export function PixelEditButton({ pixelId }: { pixelId: string }) { export function PixelEditButton({ pixelId }: { pixelId: string }) {
const { formatMessage, labels } = useMessages(); const { t, labels } = useMessages();
return ( return (
<DialogButton <DialogButton icon={<Edit />} title={t(labels.addPixel)} variant="quiet" width="600px">
icon={<Edit />}
title={formatMessage(labels.addPixel)}
variant="quiet"
width="600px"
>
{({ close }) => { {({ close }) => {
return <PixelEditForm pixelId={pixelId} onClose={close} />; return <PixelEditForm pixelId={pixelId} onClose={close} />;
}} }}

View file

@ -30,7 +30,7 @@ export function PixelEditForm({
onSave?: () => void; onSave?: () => void;
onClose?: () => void; onClose?: () => void;
}) { }) {
const { formatMessage, labels, messages, getErrorMessage } = useMessages(); const { t, labels, messages, getErrorMessage } = useMessages();
const { mutateAsync, error, isPending, touch, toast } = useUpdateQuery( const { mutateAsync, error, isPending, touch, toast } = useUpdateQuery(
pixelId ? `/pixels/${pixelId}` : '/pixels', pixelId ? `/pixels/${pixelId}` : '/pixels',
{ {
@ -46,7 +46,7 @@ export function PixelEditForm({
const handleSubmit = async (data: any) => { const handleSubmit = async (data: any) => {
await mutateAsync(data, { await mutateAsync(data, {
onSuccess: async () => { onSuccess: async () => {
toast(formatMessage(messages.saved)); toast(t(messages.saved));
touch('pixels'); touch('pixels');
touch(`pixel:${pixelId}`); touch(`pixel:${pixelId}`);
onSave?.(); onSave?.();
@ -78,18 +78,14 @@ export function PixelEditForm({
{({ setValue }) => { {({ setValue }) => {
return ( return (
<> <>
<FormField <FormField label={t(labels.name)} name="name" rules={{ required: t(labels.required) }}>
label={formatMessage(labels.name)}
name="name"
rules={{ required: formatMessage(labels.required) }}
>
<TextField autoComplete="off" /> <TextField autoComplete="off" />
</FormField> </FormField>
<FormField <FormField
name="slug" name="slug"
rules={{ rules={{
required: formatMessage(labels.required), required: t(labels.required),
}} }}
style={{ display: 'none' }} style={{ display: 'none' }}
> >
@ -97,7 +93,7 @@ export function PixelEditForm({
</FormField> </FormField>
<Column> <Column>
<Label>{formatMessage(labels.link)}</Label> <Label>{t(labels.link)}</Label>
<Row alignItems="center" gap> <Row alignItems="center" gap>
<TextField <TextField
value={`${hostUrl}/${slug}`} value={`${hostUrl}/${slug}`}
@ -117,10 +113,10 @@ export function PixelEditForm({
<Row justifyContent="flex-end" paddingTop="3" gap="3"> <Row justifyContent="flex-end" paddingTop="3" gap="3">
{onClose && ( {onClose && (
<Button isDisabled={isPending} onPress={onClose}> <Button isDisabled={isPending} onPress={onClose}>
{formatMessage(labels.cancel)} {t(labels.cancel)}
</Button> </Button>
)} )}
<FormSubmitButton isDisabled={false}>{formatMessage(labels.save)}</FormSubmitButton> <FormSubmitButton isDisabled={false}>{t(labels.save)}</FormSubmitButton>
</Row> </Row>
</> </>
); );

View file

@ -10,7 +10,7 @@ import { PixelsDataTable } from './PixelsDataTable';
export function PixelsPage() { export function PixelsPage() {
const { user } = useLoginQuery(); const { user } = useLoginQuery();
const { formatMessage, labels } = useMessages(); const { t, labels } = useMessages();
const { teamId } = useNavigation(); const { teamId } = useNavigation();
const { data } = useTeamMembersQuery(teamId); const { data } = useTeamMembersQuery(teamId);
@ -23,7 +23,7 @@ export function PixelsPage() {
return ( return (
<PageBody> <PageBody>
<Column gap="6" margin="2"> <Column gap="6" margin="2">
<PageHeader title={formatMessage(labels.pixels)}> <PageHeader title={t(labels.pixels)}>
{showActions && <PixelAddButton teamId={teamId} />} {showActions && <PixelAddButton teamId={teamId} />}
</PageHeader> </PageHeader>
<Panel> <Panel>

View file

@ -11,13 +11,13 @@ export interface PixelsTableProps extends DataTableProps {
} }
export function PixelsTable({ showActions, ...props }: PixelsTableProps) { export function PixelsTable({ showActions, ...props }: PixelsTableProps) {
const { formatMessage, labels } = useMessages(); const { t, labels } = useMessages();
const { renderUrl } = useNavigation(); const { renderUrl } = useNavigation();
const { getSlugUrl } = useSlug('pixel'); const { getSlugUrl } = useSlug('pixel');
return ( return (
<DataTable {...props}> <DataTable {...props}>
<DataColumn id="name" label={formatMessage(labels.name)}> <DataColumn id="name" label={t(labels.name)}>
{({ id, name }: any) => { {({ id, name }: any) => {
return <Link href={renderUrl(`/pixels/${id}`)}>{name}</Link>; return <Link href={renderUrl(`/pixels/${id}`)}>{name}</Link>;
}} }}
@ -32,7 +32,7 @@ export function PixelsTable({ showActions, ...props }: PixelsTableProps) {
); );
}} }}
</DataColumn> </DataColumn>
<DataColumn id="created" label={formatMessage(labels.created)}> <DataColumn id="created" label={t(labels.created)}>
{(row: any) => <DateDistance date={new Date(row.createdAt)} />} {(row: any) => <DateDistance date={new Date(row.createdAt)} />}
</DataColumn> </DataColumn>
{showActions && ( {showActions && (

View file

@ -5,14 +5,14 @@ import { useMessages, usePixel, useSlug } from '@/components/hooks';
import { ExternalLink, Grid2x2 } from '@/components/icons'; import { ExternalLink, Grid2x2 } from '@/components/icons';
export function PixelHeader() { export function PixelHeader() {
const { formatMessage, labels } = useMessages(); const { t, labels } = useMessages();
const { getSlugUrl } = useSlug('pixel'); const { getSlugUrl } = useSlug('pixel');
const pixel = usePixel(); const pixel = usePixel();
return ( return (
<PageHeader title={pixel.name} icon={<Grid2x2 />}> <PageHeader title={pixel.name} icon={<Grid2x2 />}>
<LinkButton href={getSlugUrl(pixel.slug)} target="_blank" prefetch={false} asAnchor> <LinkButton href={getSlugUrl(pixel.slug)} target="_blank" prefetch={false} asAnchor>
<IconLabel icon={<ExternalLink />} label={formatMessage(labels.view)} /> <IconLabel icon={<ExternalLink />} label={t(labels.view)} />
</LinkButton> </LinkButton>
</PageHeader> </PageHeader>
); );

View file

@ -13,7 +13,7 @@ export function PixelMetricsBar({
compareMode?: boolean; compareMode?: boolean;
}) { }) {
const { isAllTime } = useDateRange(); const { isAllTime } = useDateRange();
const { formatMessage, labels } = useMessages(); const { t, labels } = useMessages();
const { data, isLoading, isFetching, error } = useWebsiteStatsQuery(pixelId); const { data, isLoading, isFetching, error } = useWebsiteStatsQuery(pixelId);
const { pageviews, visitors, visits, comparison } = data || {}; const { pageviews, visitors, visits, comparison } = data || {};
@ -22,19 +22,19 @@ export function PixelMetricsBar({
? [ ? [
{ {
value: visitors, value: visitors,
label: formatMessage(labels.visitors), label: t(labels.visitors),
change: visitors - comparison.visitors, change: visitors - comparison.visitors,
formatValue: formatLongNumber, formatValue: formatLongNumber,
}, },
{ {
value: visits, value: visits,
label: formatMessage(labels.visits), label: t(labels.visits),
change: visits - comparison.visits, change: visits - comparison.visits,
formatValue: formatLongNumber, formatValue: formatLongNumber,
}, },
{ {
value: pageviews, value: pageviews,
label: formatMessage(labels.views), label: t(labels.views),
change: pageviews - comparison.pageviews, change: pageviews - comparison.pageviews,
formatValue: formatLongNumber, formatValue: formatLongNumber,
}, },

View file

@ -6,13 +6,13 @@ import { MetricsTable } from '@/components/metrics/MetricsTable';
import { WorldMap } from '@/components/metrics/WorldMap'; import { WorldMap } from '@/components/metrics/WorldMap';
export function PixelPanels({ pixelId }: { pixelId: string }) { export function PixelPanels({ pixelId }: { pixelId: string }) {
const { formatMessage, labels } = useMessages(); const { t, labels } = useMessages();
const tableProps = { const tableProps = {
websiteId: pixelId, websiteId: pixelId,
limit: 10, limit: 10,
allowDownload: false, allowDownload: false,
showMore: true, showMore: true,
metric: formatMessage(labels.visitors), metric: t(labels.visitors),
}; };
const rowProps = { minHeight: 570 }; const rowProps = { minHeight: 570 };
@ -20,36 +20,36 @@ export function PixelPanels({ pixelId }: { pixelId: string }) {
<Grid gap="3"> <Grid gap="3">
<GridRow layout="two" {...rowProps}> <GridRow layout="two" {...rowProps}>
<Panel> <Panel>
<Heading size="2xl">{formatMessage(labels.sources)}</Heading> <Heading size="2xl">{t(labels.sources)}</Heading>
<Tabs> <Tabs>
<TabList> <TabList>
<Tab id="referrer">{formatMessage(labels.referrers)}</Tab> <Tab id="referrer">{t(labels.referrers)}</Tab>
<Tab id="channel">{formatMessage(labels.channels)}</Tab> <Tab id="channel">{t(labels.channels)}</Tab>
</TabList> </TabList>
<TabPanel id="referrer"> <TabPanel id="referrer">
<MetricsTable type="referrer" title={formatMessage(labels.domain)} {...tableProps} /> <MetricsTable type="referrer" title={t(labels.domain)} {...tableProps} />
</TabPanel> </TabPanel>
<TabPanel id="channel"> <TabPanel id="channel">
<MetricsTable type="channel" title={formatMessage(labels.type)} {...tableProps} /> <MetricsTable type="channel" title={t(labels.type)} {...tableProps} />
</TabPanel> </TabPanel>
</Tabs> </Tabs>
</Panel> </Panel>
<Panel> <Panel>
<Heading size="2xl">{formatMessage(labels.environment)}</Heading> <Heading size="2xl">{t(labels.environment)}</Heading>
<Tabs> <Tabs>
<TabList> <TabList>
<Tab id="browser">{formatMessage(labels.browsers)}</Tab> <Tab id="browser">{t(labels.browsers)}</Tab>
<Tab id="os">{formatMessage(labels.os)}</Tab> <Tab id="os">{t(labels.os)}</Tab>
<Tab id="device">{formatMessage(labels.devices)}</Tab> <Tab id="device">{t(labels.devices)}</Tab>
</TabList> </TabList>
<TabPanel id="browser"> <TabPanel id="browser">
<MetricsTable type="browser" title={formatMessage(labels.browser)} {...tableProps} /> <MetricsTable type="browser" title={t(labels.browser)} {...tableProps} />
</TabPanel> </TabPanel>
<TabPanel id="os"> <TabPanel id="os">
<MetricsTable type="os" title={formatMessage(labels.os)} {...tableProps} /> <MetricsTable type="os" title={t(labels.os)} {...tableProps} />
</TabPanel> </TabPanel>
<TabPanel id="device"> <TabPanel id="device">
<MetricsTable type="device" title={formatMessage(labels.device)} {...tableProps} /> <MetricsTable type="device" title={t(labels.device)} {...tableProps} />
</TabPanel> </TabPanel>
</Tabs> </Tabs>
</Panel> </Panel>
@ -59,21 +59,21 @@ export function PixelPanels({ pixelId }: { pixelId: string }) {
<WorldMap websiteId={pixelId} /> <WorldMap websiteId={pixelId} />
</Panel> </Panel>
<Panel> <Panel>
<Heading size="2xl">{formatMessage(labels.location)}</Heading> <Heading size="2xl">{t(labels.location)}</Heading>
<Tabs> <Tabs>
<TabList> <TabList>
<Tab id="country">{formatMessage(labels.countries)}</Tab> <Tab id="country">{t(labels.countries)}</Tab>
<Tab id="region">{formatMessage(labels.regions)}</Tab> <Tab id="region">{t(labels.regions)}</Tab>
<Tab id="city">{formatMessage(labels.cities)}</Tab> <Tab id="city">{t(labels.cities)}</Tab>
</TabList> </TabList>
<TabPanel id="country"> <TabPanel id="country">
<MetricsTable type="country" title={formatMessage(labels.country)} {...tableProps} /> <MetricsTable type="country" title={t(labels.country)} {...tableProps} />
</TabPanel> </TabPanel>
<TabPanel id="region"> <TabPanel id="region">
<MetricsTable type="region" title={formatMessage(labels.region)} {...tableProps} /> <MetricsTable type="region" title={t(labels.region)} {...tableProps} />
</TabPanel> </TabPanel>
<TabPanel id="city"> <TabPanel id="city">
<MetricsTable type="city" title={formatMessage(labels.city)} {...tableProps} /> <MetricsTable type="city" title={t(labels.city)} {...tableProps} />
</TabPanel> </TabPanel>
</Tabs> </Tabs>
</Panel> </Panel>

View file

@ -3,33 +3,33 @@ import { useMessages, useNavigation } from '@/components/hooks';
import { Settings2, UserCircle, Users } from '@/components/icons'; import { Settings2, UserCircle, Users } from '@/components/icons';
export function SettingsNav({ onItemClick }: { onItemClick?: () => void }) { export function SettingsNav({ onItemClick }: { onItemClick?: () => void }) {
const { formatMessage, labels } = useMessages(); const { t, labels } = useMessages();
const { renderUrl, pathname } = useNavigation(); const { renderUrl, pathname } = useNavigation();
const items = [ const items = [
{ {
label: formatMessage(labels.application), label: t(labels.application),
items: [ items: [
{ {
id: 'preferences', id: 'preferences',
label: formatMessage(labels.preferences), label: t(labels.preferences),
path: renderUrl('/settings/preferences'), path: renderUrl('/settings/preferences'),
icon: <Settings2 />, icon: <Settings2 />,
}, },
], ],
}, },
{ {
label: formatMessage(labels.account), label: t(labels.account),
items: [ items: [
{ {
id: 'profile', id: 'profile',
label: formatMessage(labels.profile), label: t(labels.profile),
path: renderUrl('/settings/profile'), path: renderUrl('/settings/profile'),
icon: <UserCircle />, icon: <UserCircle />,
}, },
{ {
id: 'teams', id: 'teams',
label: formatMessage(labels.teams), label: t(labels.teams),
path: renderUrl('/settings/teams'), path: renderUrl('/settings/teams'),
icon: <Users />, icon: <Users />,
}, },
@ -44,7 +44,7 @@ export function SettingsNav({ onItemClick }: { onItemClick?: () => void }) {
return ( return (
<NavMenu <NavMenu
items={items} items={items}
title={formatMessage(labels.settings)} title={t(labels.settings)}
selectedKey={selectedKey} selectedKey={selectedKey}
allowMinimize={false} allowMinimize={false}
onItemClick={onItemClick} onItemClick={onItemClick}

View file

@ -6,7 +6,7 @@ import { DATE_RANGE_CONFIG, DEFAULT_DATE_RANGE_VALUE } from '@/lib/constants';
import { getItem, setItem } from '@/lib/storage'; import { getItem, setItem } from '@/lib/storage';
export function DateRangeSetting() { export function DateRangeSetting() {
const { formatMessage, labels } = useMessages(); const { t, labels } = useMessages();
const [date, setDate] = useState(getItem(DATE_RANGE_CONFIG) || DEFAULT_DATE_RANGE_VALUE); const [date, setDate] = useState(getItem(DATE_RANGE_CONFIG) || DEFAULT_DATE_RANGE_VALUE);
const handleChange = (value: string) => { const handleChange = (value: string) => {
@ -27,7 +27,7 @@ export function DateRangeSetting() {
placement="bottom start" placement="bottom start"
style={{ minWidth: '250px' }} style={{ minWidth: '250px' }}
/> />
<Button onPress={handleReset}>{formatMessage(labels.reset)}</Button> <Button onPress={handleReset}>{t(labels.reset)}</Button>
</Row> </Row>
); );
} }

View file

@ -6,7 +6,7 @@ import { languages } from '@/lib/lang';
export function LanguageSetting() { export function LanguageSetting() {
const [search, setSearch] = useState(''); const [search, setSearch] = useState('');
const { formatMessage, labels } = useMessages(); const { t, labels } = useMessages();
const { locale, saveLocale } = useLocale(); const { locale, saveLocale } = useLocale();
const items = search const items = search
? Object.keys(languages).filter(n => { ? Object.keys(languages).filter(n => {
@ -43,7 +43,7 @@ export function LanguageSetting() {
))} ))}
{!items.length && <ListItem></ListItem>} {!items.length && <ListItem></ListItem>}
</Select> </Select>
<Button onPress={handleReset}>{formatMessage(labels.reset)}</Button> <Button onPress={handleReset}>{t(labels.reset)}</Button>
</Row> </Row>
); );
} }

View file

@ -8,7 +8,7 @@ import { VersionSetting } from './VersionSetting';
export function PreferenceSettings() { export function PreferenceSettings() {
const { user } = useLoginQuery(); const { user } = useLoginQuery();
const { formatMessage, labels } = useMessages(); const { t, labels } = useMessages();
if (!user) { if (!user) {
return null; return null;
@ -17,23 +17,23 @@ export function PreferenceSettings() {
return ( return (
<Column gap="6"> <Column gap="6">
<Column> <Column>
<Label>{formatMessage(labels.defaultDateRange)}</Label> <Label>{t(labels.defaultDateRange)}</Label>
<DateRangeSetting /> <DateRangeSetting />
</Column> </Column>
<Column> <Column>
<Label>{formatMessage(labels.timezone)}</Label> <Label>{t(labels.timezone)}</Label>
<TimezoneSetting /> <TimezoneSetting />
</Column> </Column>
<Column> <Column>
<Label>{formatMessage(labels.language)}</Label> <Label>{t(labels.language)}</Label>
<LanguageSetting /> <LanguageSetting />
</Column> </Column>
<Column> <Column>
<Label>{formatMessage(labels.theme)}</Label> <Label>{t(labels.theme)}</Label>
<ThemeSetting /> <ThemeSetting />
</Column> </Column>
<Column> <Column>
<Label>{formatMessage(labels.version)}</Label> <Label>{t(labels.version)}</Label>
<VersionSetting /> <VersionSetting />
</Column> </Column>
</Column> </Column>

View file

@ -7,12 +7,12 @@ import { useMessages } from '@/components/hooks';
import { PreferenceSettings } from './PreferenceSettings'; import { PreferenceSettings } from './PreferenceSettings';
export function PreferencesPage() { export function PreferencesPage() {
const { formatMessage, labels } = useMessages(); const { t, labels } = useMessages();
return ( return (
<PageBody> <PageBody>
<Column gap="6"> <Column gap="6">
<PageHeader title={formatMessage(labels.preferences)} /> <PageHeader title={t(labels.preferences)} />
<Panel> <Panel>
<PreferenceSettings /> <PreferenceSettings />
</Panel> </Panel>

View file

@ -7,7 +7,7 @@ const timezones = Intl.supportedValuesOf('timeZone');
export function TimezoneSetting() { export function TimezoneSetting() {
const [search, setSearch] = useState(''); const [search, setSearch] = useState('');
const { formatMessage, labels } = useMessages(); const { t, labels } = useMessages();
const { timezone, saveTimezone } = useTimezone(); const { timezone, saveTimezone } = useTimezone();
const items = search const items = search
? timezones.filter(n => n.toLowerCase().includes(search.toLowerCase())) ? timezones.filter(n => n.toLowerCase().includes(search.toLowerCase()))
@ -39,7 +39,7 @@ export function TimezoneSetting() {
))} ))}
{!items.length && <ListItem></ListItem>} {!items.length && <ListItem></ListItem>}
</Select> </Select>
<Button onPress={handleReset}>{formatMessage(labels.reset)}</Button> <Button onPress={handleReset}>{t(labels.reset)}</Button>
</Row> </Row>
); );
} }

Some files were not shown because too many files have changed in this diff Show more