-
Path {{ $t("library.admin.sources.fsPath") }}
- An absolute path to your game library.
+ {{ $t("library.admin.sources.fsPathDesc") }}
diff --git a/components/UploadFileDialog.vue b/components/UploadFileDialog.vue
index 101f40c..721d8a4 100644
--- a/components/UploadFileDialog.vue
+++ b/components/UploadFileDialog.vue
@@ -49,7 +49,7 @@
/>
Upload file {{ $t("uploadFile") }}
uploadFile_wrapper()"
>
- Upload
+ {{ $t("upload") }}
- Cancel
+ {{ $t("cancel") }}
@@ -129,6 +129,7 @@ const open = defineModel
({
required: true,
});
+const { t } = useI18n();
const file = ref();
const currentFiles = computed(() => file.value);
const currentFileList = computed(() => {
@@ -176,7 +177,7 @@ function uploadFile_wrapper() {
uploadLoading.value = true;
uploadFile()
.catch((error) => {
- uploadError.value = error.statusMessage ?? "An unknown error occurred.";
+ uploadError.value = error.statusMessage ?? t("errors.unknown");
})
.finally(() => {
uploadLoading.value = false;
diff --git a/components/UserFooter.vue b/components/UserFooter.vue
index 46fda6d..1fb1fff 100644
--- a/components/UserFooter.vue
+++ b/components/UserFooter.vue
@@ -1,13 +1,12 @@
-
+
- An open-source game distribution platform built for speed,
- flexibility and beauty.
+ {{ $t("drop.desc") }}
-
Games
+
+ {{ $t("footer.games") }}
+
- Community
+ {{ $t("userHeader.links.community") }}
@@ -54,7 +55,7 @@
- Documentation
+ {{ $t("footer.documentation") }}
-
About
+
+ {{ $t("footer.about") }}
+
import { IconsDiscordLogo, IconsGithubLogo } from "#components";
+const { t } = useI18n();
const navigation = {
games: [
- { name: "Newly Added", href: "#" },
- { name: "New Releases", href: "#" },
- { name: "Top Sellers", href: "#" },
- { name: "Find a Game", href: "#" },
+ { name: t("store.recentlyAdded"), href: "#" },
+ { name: t("store.recentlyReleased"), href: "#" },
+ { name: t("footer.topSellers"), href: "#" },
+ { name: t("footer.findGame"), href: "#" },
],
community: [
- { name: "Friends", href: "#" },
- { name: "Groups", href: "#" },
- { name: "Servers", href: "#" },
+ { name: t("common.friends"), href: "#" },
+ { name: t("common.groups"), href: "#" },
+ { name: t("common.servers"), href: "#" },
],
documentation: [
- { name: "API", href: "https://api.droposs.org/" },
+ { name: t("footer.api"), href: "https://api.droposs.org/" },
{
- name: "Server Docs",
+ name: t("footer.docs.server"),
href: "https://wiki.droposs.org/guides/quickstart.html",
},
{
- name: "Client Docs",
+ name: t("footer.docs.client"),
href: "https://wiki.droposs.org/guides/client.html",
},
],
about: [
- { name: "About Drop", href: "https://droposs.org/" },
- { name: "Features", href: "https://droposs.org/features" },
- { name: "FAQ", href: "https://droposs.org/faq" },
+ { name: t("footer.aboutDrop"), href: "https://droposs.org/" },
+ { name: t("footer.features"), href: "https://droposs.org/features" },
+ { name: t("footer.faq"), href: "https://droposs.org/faq" },
],
social: [
{
- name: "GitHub",
+ name: t("footer.social.github"),
href: "https://github.com/Drop-OSS",
icon: IconsGithubLogo,
},
{
- name: "Discord",
+ name: t("footer.social.discord"),
href: "https://discord.gg/NHx46XKJWA",
icon: IconsDiscordLogo,
},
diff --git a/components/UserHeader.vue b/components/UserHeader.vue
index 8996906..1e13cdd 100644
--- a/components/UserHeader.vue
+++ b/components/UserHeader.vue
@@ -54,6 +54,7 @@
+
@@ -76,7 +77,7 @@
class="-m-2.5 p-2.5 text-zinc-400 lg:hidden"
@click="sidebarOpen = true"
>
-
Open sidebar
+
{{ $t("header.openSidebar") }}
@@ -125,7 +126,9 @@
class="-m-2.5 p-2.5"
@click="sidebarOpen = false"
>
- Close sidebar
+ {{
+ $t("userHeader.closeSidebar")
+ }}
@@ -172,6 +175,11 @@
+
+
+
+
+
@@ -198,28 +206,29 @@ import { Bars3Icon } from "@heroicons/vue/24/outline";
import { XMarkIcon } from "@heroicons/vue/24/solid";
const router = useRouter();
+const { t } = useI18n();
const homepageURL = "/store";
const navigation: Array = [
{
prefix: "/store",
route: "/store",
- label: "Store",
+ label: t("store.title"),
},
{
prefix: "/library",
route: "/library",
- label: "Library",
+ label: t("userHeader.links.library"),
},
{
prefix: "/community",
route: "/community",
- label: "Community",
+ label: t("userHeader.links.community"),
},
{
prefix: "/news",
route: "/news",
- label: "News",
+ label: t("userHeader.links.news"),
},
];
diff --git a/components/UserHeader/NotificationWidgetPanel.vue b/components/UserHeader/NotificationWidgetPanel.vue
index db1a9d2..d399786 100644
--- a/components/UserHeader/NotificationWidgetPanel.vue
+++ b/components/UserHeader/NotificationWidgetPanel.vue
@@ -6,7 +6,7 @@
>
- Unread notifications
+ {{ $t("account.notifications.unread") }}
@@ -15,7 +15,15 @@
type="button"
class="text-sm text-zinc-400"
>
- View all →
+
+
+ {{ $t("chars.arrow") }}
+
+
@@ -32,7 +40,7 @@
v-if="props.notifications.length == 0"
class="text-sm text-zinc-400 p-3 text-center w-full"
>
- No notifications
+ {{ $t("account.notifications.none") }}
diff --git a/components/UserHeader/SelectLang.vue b/components/UserHeader/SelectLang.vue
new file mode 100644
index 0000000..b379341
--- /dev/null
+++ b/components/UserHeader/SelectLang.vue
@@ -0,0 +1,78 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {{ locale.name }}
+
+
+
+
+
+
+
+
+
diff --git a/components/UserHeader/UserWidget.vue b/components/UserHeader/UserWidget.vue
index 067b1df..dc8d517 100644
--- a/components/UserHeader/UserWidget.vue
+++ b/components/UserHeader/UserWidget.vue
@@ -46,29 +46,28 @@
hydrate-on-visible
as="div"
>
-
-
navigateTo(nav.route, close)"
+ @click="close"
>
{{ nav.label }}
-
+
-
-
-
+
- Signout
-
+ {{ $t("auth.signout") }}
+
@@ -84,17 +83,18 @@ import { useObject } from "~/composables/objects";
import type { NavigationItem } from "~/composables/types";
const user = useUser();
+const { t } = useI18n();
const navigation: NavigationItem[] = [
user.value?.admin
? {
- label: "Admin Dashboard",
+ label: t("userHeader.profile.admin"),
route: "/admin",
prefix: "",
}
: undefined,
{
- label: "Account settings",
+ label: t("userHeader.profile.settings"),
route: "/account",
prefix: "",
},
diff --git a/error.vue b/error.vue
index 276eefb..3e2e31a 100644
--- a/error.vue
+++ b/error.vue
@@ -8,13 +8,12 @@ const props = defineProps({
},
});
+const { t } = useI18n();
const route = useRoute();
const user = useUser();
const statusCode = props.error?.statusCode;
const message =
- props.error?.statusMessage ||
- props.error?.message ||
- "An unknown error occurred.";
+ props.error?.message || props.error?.statusMessage || t("errors.unknown");
const showSignIn = statusCode ? statusCode == 403 || statusCode == 401 : false;
async function signIn() {
@@ -24,7 +23,7 @@ async function signIn() {
}
useHead({
- title: `${statusCode ?? message} | Drop`,
+ title: t("errors.pageTitle", [statusCode ?? message]),
});
if (import.meta.client) {
@@ -51,7 +50,7 @@ if (import.meta.client) {
- Oh no!
+ {{ $t("errors.ohNo") }}
- An error occurred while responding to your request. If you believe
- this to be a bug, please report it. Try signing in and see if it
- resolves the issue.
+ {{ $t("errors.occurred") }}
+
← Back to home
+
+
+ {{ $t("chars.arrowBack") }}
+
+
+
- Sign in →
+
+
+ {{ $t("chars.arrow") }}
+
+
@@ -87,7 +94,7 @@ if (import.meta.client) {
- Documentation
+ {{ $t("footer.documentation") }}
- Support Discord
+ {{ $t("errors.support") }}
diff --git a/eslint.config.mjs b/eslint.config.mjs
index 2ab5216..aa553d9 100644
--- a/eslint.config.mjs
+++ b/eslint.config.mjs
@@ -1,5 +1,32 @@
// @ts-check
import withNuxt from "./.nuxt/eslint.config.mjs";
import eslintConfigPrettier from "eslint-config-prettier/flat";
+import vueI18n from "@intlify/eslint-plugin-vue-i18n";
-export default withNuxt([eslintConfigPrettier]);
+export default withNuxt([
+ eslintConfigPrettier,
+
+ // vue-i18n plugin
+ ...vueI18n.configs.recommended,
+ {
+ rules: {
+ // Optional.
+ "@intlify/vue-i18n/no-dynamic-keys": "error",
+ "@intlify/vue-i18n/no-unused-keys": [
+ "error",
+ {
+ extensions: [".js", ".vue", ".ts"],
+ },
+ ],
+ },
+ settings: {
+ "vue-i18n": {
+ localeDir: "./i18n/locales/*.{json,json5,ts,js}", // extension is glob formatting!
+
+ // Specify the version of `vue-i18n` you are using.
+ // If not specified, the message will be parsed twice.
+ messageSyntaxVersion: "^11.0.0",
+ },
+ },
+ },
+]);
diff --git a/i18n/i18n.config.ts b/i18n/i18n.config.ts
new file mode 100644
index 0000000..a960cfd
--- /dev/null
+++ b/i18n/i18n.config.ts
@@ -0,0 +1,27 @@
+export default defineI18nConfig(() => {
+ const defaultDateTimeFormat = {
+ short: {
+ year: "numeric",
+ month: "long",
+ day: "numeric",
+ },
+ long: {
+ year: "numeric",
+ month: "short",
+ day: "numeric",
+ weekday: "short",
+ hour: "numeric",
+ minute: "numeric",
+ },
+ } as const;
+
+ return {
+ // https://i18n.nuxtjs.org/docs/guide/locale-fallback
+ fallbackLocale: "en-us",
+ // https://vue-i18n.intlify.dev/guide/essentials/datetime.html
+ datetimeFormats: {
+ "en-us": defaultDateTimeFormat,
+ "en-pirate": defaultDateTimeFormat,
+ },
+ };
+});
diff --git a/i18n/localeDetector.ts b/i18n/localeDetector.ts
new file mode 100644
index 0000000..d4250b6
--- /dev/null
+++ b/i18n/localeDetector.ts
@@ -0,0 +1,25 @@
+// https://i18n.nuxtjs.org/docs/guide/server-side-translations
+
+// Detect based on query, cookie, header
+export default defineI18nLocaleDetector((event, config) => {
+ // try to get locale from query
+ const query = tryQueryLocale(event, { lang: "" }); // disable locale default value with `lang` option
+ if (query) {
+ return query.toString();
+ }
+
+ // try to get locale from cookie
+ const cookie = tryCookieLocale(event, { lang: "", name: "i18n_redirected" }); // disable locale default value with `lang` option
+ if (cookie) {
+ return cookie.toString();
+ }
+
+ // try to get locale from header (`accept-header`)
+ const header = tryHeaderLocale(event, { lang: "" }); // disable locale default value with `lang` option
+ if (header) {
+ return header.toString();
+ }
+
+ // If the locale cannot be resolved up to this point, it is resolved with the value `defaultLocale` of the locale config passed to the function
+ return config.defaultLocale;
+});
diff --git a/i18n/locales/en_pirate.json b/i18n/locales/en_pirate.json
new file mode 100644
index 0000000..2018cf9
--- /dev/null
+++ b/i18n/locales/en_pirate.json
@@ -0,0 +1,3 @@
+{
+ "welcome": "Arr matey, Welcome!"
+}
diff --git a/i18n/locales/en_us.json b/i18n/locales/en_us.json
new file mode 100644
index 0000000..a7eafc9
--- /dev/null
+++ b/i18n/locales/en_us.json
@@ -0,0 +1,351 @@
+{
+ "account": {
+ "devices": {
+ "capabilities": "Capabilities",
+ "lastConnected": "Last Connected",
+ "noDevices": "No devices connected to your account.",
+ "platform": "Platform",
+ "revoke": "Revoke",
+ "subheader": "Manage the devices authorized to access your Drop account.",
+ "title": "Devices"
+ },
+ "notifications": {
+ "all": "View all {arrow}",
+ "desc": "View and manage your notifications.",
+ "markAllAsRead": "Mark all as read",
+ "markAsRead": "Mark as read",
+ "none": "No notifications",
+ "notifications": "Notifications",
+ "title": "Notifications",
+ "unread": "Unread Notifications"
+ },
+ "settings": "Account Settings",
+ "title": "Account"
+ },
+ "actions": "Actions",
+ "adminTitle": "Admin Dashboard | Drop",
+ "adminTitleTemplate": "{0} | Admin | Drop",
+ "auth": {
+ "callback": {
+ "authClient": "Authorize client?",
+ "authorize": "Authorize",
+ "authorizedClient": "Drop has successfully authorized the client. You may now close this window.",
+ "issues": "Having issues?",
+ "learn": "Learn more {arrow}",
+ "paste": "Paste this code into the client to continue:",
+ "permWarning": "Accepting this request will allow \"{name}\" on \"{platform}\" to:",
+ "requestedAccess": "\"{name}\" has requested access to your Drop account.",
+ "success": "Successful!"
+ },
+ "confirmPassword": "Confirm @:auth.password",
+ "displayName": "Display Name",
+ "email": "Email",
+ "password": "Password",
+ "register": {
+ "confirmPasswordFormat": "Must be the same as above",
+ "emailFormat": "Must be in the format user{'@'}example.com",
+ "passwordFormat": "Must be 14 or more characters",
+ "subheader": "Fill in your details below to create your account.",
+ "title": "Create your Drop account",
+ "usernameFormat": "Must be 5 or more characters, and lowercase"
+ },
+ "signin": {
+ "externalProvider": "Sign in with external provider {arrow}",
+ "forgot": "Forgot password?",
+ "noAccount": "Don't have an account? Ask an admin to create one for you.",
+ "or": "OR",
+ "pageTitle": "Sign in to Drop",
+ "rememberMe": "Remember me",
+ "signin": "Sign in",
+ "title": "Sign in to your account"
+ },
+ "signout": "Signout",
+ "username": "Username"
+ },
+ "cancel": "Cancel",
+ "chars": {
+ "arrow": "β",
+ "arrowBack": "β",
+ "quoted": "\"\"",
+ "srComma": ", {0}"
+ },
+ "close": "Close",
+ "common": {
+ "cannotUndo": "This action cannot be undone.",
+ "date": "Date",
+ "deleteConfirm": "Are you sure you want to delete \"{0}\"?",
+ "friends": "Friends",
+ "groups": "Groups",
+ "noResults": "No results",
+ "servers": "Servers",
+ "tags": "Tags",
+ "today": "Today"
+ },
+ "create": "Create",
+ "delete": "Delete",
+ "drop": {
+ "desc": "An open-source game distribution platform built for speed, flexibility and beauty.",
+ "drop": "Drop"
+ },
+ "edit": "Edit",
+ "editor": {
+ "bold": "Bold",
+ "boldPlaceholder": "bold text",
+ "code": "Code",
+ "codePlaceholder": "code",
+ "heading": "Heading",
+ "headingPlaceholder": "heading",
+ "italic": "Italic",
+ "italicPlaceholder": "italic text",
+ "link": "Link",
+ "linkPlaceholder": "link text",
+ "listItem": "List Item",
+ "listItemPlaceholder": "list item"
+ },
+ "errors": {
+ "backHome": "{arrow} Back to home",
+ "invalidBody": "Invalid request body: {0}",
+ "inviteRequired": "Invitation required to sign up.",
+ "library": {
+ "add": {
+ "desc": "Drop couldn't add this game to your library: {0}",
+ "title": "Failed to add game to library"
+ },
+ "collection": {
+ "create": {
+ "desc": "Drop couldn't create your collection: {0}",
+ "title": "Failed to create collection"
+ }
+ },
+ "source": {
+ "delete": {
+ "desc": "Drop couldn't add delete this source: {0}",
+ "title": "Failed to delete library source"
+ }
+ }
+ },
+ "news": {
+ "article": {
+ "delete": {
+ "desc": "Drop couldn't delete this article: {0}",
+ "title": "Failed to delete article"
+ }
+ }
+ },
+ "occurred": "An error occurred while responding to your request. If you believe this to be a bug, please report it. Try signing in and see if it resolves the issue.",
+ "ohNo": "Oh no!",
+ "pageTitle": "{0} | Drop",
+ "revokeClient": "Failed to revoke client",
+ "revokeClientFull": "Failed to revoke client {0}",
+ "signIn": "Sign in {arrow}",
+ "support": "Support Discord",
+ "unknown": "An unknown error occurred",
+ "version": {
+ "delete": {
+ "desc": "Drop encountered an error while deleting the version: {error}",
+ "title": "There an error while deleting the version"
+ },
+ "order": {
+ "desc": "Drop encountered an error while updating the version: {error}",
+ "title": "There an error while updating the version order"
+ }
+ }
+ },
+ "footer": {
+ "about": "About",
+ "aboutDrop": "About Drop",
+ "api": "API",
+ "docs": {
+ "client": "Client Docs",
+ "server": "Server Docs"
+ },
+ "documentation": "Documentation",
+ "faq": "FAQ",
+ "features": "Features",
+ "findGame": "Find a Game",
+ "footer": "Footer",
+ "games": "Games",
+ "social": {
+ "discord": "Discord",
+ "github": "GitHub"
+ },
+ "topSellers": "Top Sellers"
+ },
+ "header": {
+ "admin": {
+ "admin": "Admin",
+ "meta": "Meta",
+ "tasks": "Tasks",
+ "users": "Users"
+ },
+ "back": "Back",
+ "openSidebar": "Open sidebar"
+ },
+ "highest": "highest",
+ "home": "Home",
+ "library": {
+ "addGames": "All Games",
+ "addToLib": "Add to Library",
+ "admin": {
+ "detectedGame": "Drop has detected you have new games to import.",
+ "detectedVersion": "Drop has detected you have new verions of this game to import.",
+ "gameLibrary": "Game Library",
+ "import": {
+ "import": "Import",
+ "link": "Import {arrow}",
+ "loading": "Loading game results...",
+ "search": "Search",
+ "searchPlaceholder": "Fallout 4",
+ "selectDir": "Please select a directory...",
+ "selectGame": "Select game to import",
+ "selectGamePlaceholder": "Please select a game...",
+ "selectGameSearch": "Select game",
+ "selectPlatform": "Please select a platform...",
+ "version": {
+ "advancedOptions": "Advanced options",
+ "import": "Import version",
+ "installDir": "(install_dir)/",
+ "launchCmd": "Launch executable/command",
+ "launchDesc": "Executable to launch the game",
+ "launchPlaceholder": "game.exe",
+ "loadingVersion": "Loading version metadata...",
+ "noAdv": "No advanced options for this configuration.",
+ "noVersions": "No versions to import",
+ "platform": "Version platform",
+ "setupCmd": "Setup executable/command",
+ "setupDesc": "Ran once when the game is installed",
+ "setupMode": "Setup mode",
+ "setupModeDesc": "When enabled, this version does not have a launch command, and simply runs the executable on the user's computer. Useful for games that only distribute installer and not portable files.",
+ "setupPlaceholder": "setup.exe",
+ "umuLauncherId": "UMU Launcher ID",
+ "umuOverride": "Override UMU Launcher Game ID",
+ "umuOverrideDesc": "By default, Drop uses a non-ID when launching with UMU Launcher. In order to get the right patches for some games, you may have to manually set this field.",
+ "updateMode": "Update mode",
+ "updateModeDesc": "When enabled, these files will be installed on top of (overwriting) the previous version's. If multiple \"update modes\" are chained together, they are applied in order.",
+ "version": "Select version to import"
+ },
+ "withoutMetadata": "Import without metadata"
+ },
+ "metadataProvider": "Metadata provider",
+ "noGames": "No games imported",
+ "noVersions": "You have no versions of this game available.",
+ "noVersionsAdded": "no versions added",
+ "openInMetadata": "Open in Metadata",
+ "openLibrary": "Open with Library {arrow}",
+ "openMetadata": "Open with Metadata {arrow}",
+ "openStore": "Open in Store",
+ "shortDesc": "Short Description",
+ "sources": {
+ "create": "Create source",
+ "createDesc": "Drop will use this source to access your game library, and make them available.",
+ "desc": "Configure your library sources, where Drop will look for new games and versions to import.",
+ "fsDesc": "Imports games from a path on disk. Requires version-based folder structure, and supports archived games.",
+ "fsPath": "Path",
+ "fsPathDesc": "An absolute path to your game library.",
+ "fsPathPlaceholder": "/mnt/games",
+ "link": "Sources {arrow}",
+ "nameDesc": "The name of your source, for reference.",
+ "namePlaceholder": "My New Source",
+ "sources": "Library Sources",
+ "typeDesc": "The type of your source. Changes the required options.",
+ "working": "Working?"
+ },
+ "subheader": "As you add folders to your library sources, Drop will detect it and prompt you to import it. Each game needs to be imported before you can import a version.",
+ "title": "Libraries",
+ "versionPriority": "Version priority"
+ },
+ "back": "Back to Library",
+ "collection": {
+ "addToNew": "Add to new collection",
+ "collections": "Collections",
+ "create": "Create Collection",
+ "createDesc": "Collections can used to organise your games and find them more easily, especially if you have a large library.",
+ "delete": "Delete Collection",
+ "namePlaceholder": "Collection name",
+ "noCollections": "No collections",
+ "notFound": "Collection not found",
+ "subheader": "Add a new collection to organize your games",
+ "title": "Collection"
+ },
+ "gameCount": "{0} games | {0} game | {0} games",
+ "inLib": "In Library",
+ "launcherOpen": "Open in Launcher",
+ "noGames": "No games in library",
+ "notFound": "Game not found",
+ "search": "Search library...",
+ "subheader": "Organize your games into collections for easy access, and access all your games."
+ },
+ "lowest": "lowest",
+ "name": "Name",
+ "news": {
+ "article": {
+ "add": "Add",
+ "content": "Content (Markdown)",
+ "create": "Create New Article",
+ "editor": "Editor",
+ "editorGuide": "Use the shortcuts above or write Markdown directly. Supports **bold**, *italic*, [links](url), and more.",
+ "new": "New article",
+ "preview": "Preview",
+ "shortDesc": "Short description",
+ "submit": "Submit",
+ "tagPlaceholder": "Add a tag...",
+ "titles": "Title",
+ "uploadCover": "Upload cover image"
+ },
+ "back": "Back to News",
+ "checkLater": "Check back later for updates.",
+ "delete": "Delete Article",
+ "filter": {
+ "all": "All time",
+ "month": "This month",
+ "week": "This week",
+ "year": "This year"
+ },
+ "none": "No articles",
+ "notFound": "Article not found",
+ "search": "Search articles",
+ "searchPlaceholder": "Search articles...",
+ "subheader": "Stay up to date with the latest updates and announcements.",
+ "title": "Latest News"
+ },
+ "options": "Options",
+ "save": "Save",
+ "security": "Security",
+ "settings": "Settings",
+ "store": {
+ "commingSoon": "coming soon",
+ "exploreMore": "Explore more {arrow}",
+ "images": "Game Images",
+ "lookAt": "Check it out",
+ "noGame": "no game",
+ "noImages": "No images",
+ "openAdminDashboard": "Open in Admin Dashboard",
+ "platform": "Platform | Platform | Platforms",
+ "rating": "Rating",
+ "readLess": "Click to read less",
+ "readMore": "Click to read more",
+ "recentlyAdded": "Recently Added",
+ "recentlyReleased": "Recently released",
+ "recentlyUpdated": "Recently Updated",
+ "released": "Released",
+ "reviews": "({0} Reviews)",
+ "title": "Store",
+ "view": "View in Store"
+ },
+ "type": "Type",
+ "upload": "Upload",
+ "uploadFile": "Upload file",
+ "userHeader": {
+ "closeSidebar": "Close sidebar",
+ "links": {
+ "community": "Community",
+ "library": "Library",
+ "news": "News"
+ },
+ "profile": {
+ "admin": "Admin Dashboard",
+ "settings": "Account settings"
+ }
+ },
+ "welcome": "American, Welcome!"
+}
diff --git a/layouts/admin.vue b/layouts/admin.vue
index cea7e92..6c7ba76 100644
--- a/layouts/admin.vue
+++ b/layouts/admin.vue
@@ -42,7 +42,9 @@
class="-m-2.5 p-2.5"
@click="sidebarOpen = false"
>
-
Close sidebar
+
{{
+ $t("userHeader.closeSidebar")
+ }}
@@ -96,7 +98,7 @@