diff options
| author | ivarlovlie <git@ivarlovlie.no> | 2022-09-28 18:28:33 +0200 |
|---|---|---|
| committer | ivarlovlie <git@ivarlovlie.no> | 2022-09-28 18:28:33 +0200 |
| commit | f9337bbe280878c2a2d9d713873c4c06b54325cd (patch) | |
| tree | bbc30d1b0dfb5c3589af609e28db04b12c11b237 | |
| parent | 59a4a340c77aad97e299aac47155bf4bff7a3c30 (diff) | |
| download | greatoffice-f9337bbe280878c2a2d9d713873c4c06b54325cd.tar.xz greatoffice-f9337bbe280878c2a2d9d713873c4c06b54325cd.zip | |
refactor: !WIP Use i18n namespaces
| -rw-r--r-- | apps/kit/src/lib/components/index.ts | 15 | ||||
| -rw-r--r-- | apps/kit/src/lib/i18n/en/app/index.ts | 101 | ||||
| -rw-r--r-- | apps/kit/src/lib/i18n/en/index.ts | 151 | ||||
| -rw-r--r-- | apps/kit/src/lib/i18n/en/reset-password/index.ts | 9 | ||||
| -rw-r--r-- | apps/kit/src/lib/i18n/en/sign-in/index.ts | 10 | ||||
| -rw-r--r-- | apps/kit/src/lib/i18n/en/sign-up/index.ts | 6 | ||||
| -rw-r--r-- | apps/kit/src/lib/i18n/i18n-types.ts | 1011 | ||||
| -rw-r--r-- | apps/kit/src/lib/i18n/i18n-util.async.ts | 18 | ||||
| -rw-r--r-- | apps/kit/src/lib/i18n/i18n-util.sync.ts | 15 | ||||
| -rw-r--r-- | apps/kit/src/lib/i18n/i18n-util.ts | 14 | ||||
| -rw-r--r-- | apps/kit/src/lib/i18n/nb/index.ts | 115 | ||||
| -rw-r--r-- | apps/kit/src/routes/(main)/(public)/reset-password/+page.svelte | 69 | ||||
| -rw-r--r-- | apps/kit/src/routes/(main)/(public)/sign-in/+page.svelte | 18 | ||||
| -rw-r--r-- | apps/kit/src/routes/(main)/+layout.ts | 20 |
14 files changed, 701 insertions, 871 deletions
diff --git a/apps/kit/src/lib/components/index.ts b/apps/kit/src/lib/components/index.ts new file mode 100644 index 0000000..a81e0c3 --- /dev/null +++ b/apps/kit/src/lib/components/index.ts @@ -0,0 +1,15 @@ +import Alert from "./alert.svelte"; +import Button from "./button.svelte"; +import Checkbox from "./checkbox.svelte"; +import Input from "./input.svelte"; +import LocaleSwitcher from "./locale-switcher.svelte"; +import Switch from "./switch.svelte"; + +export { + Alert, + Button, + Checkbox, + Input, + LocaleSwitcher, + Switch +}
\ No newline at end of file diff --git a/apps/kit/src/lib/i18n/en/app/index.ts b/apps/kit/src/lib/i18n/en/app/index.ts new file mode 100644 index 0000000..dd26be2 --- /dev/null +++ b/apps/kit/src/lib/i18n/en/app/index.ts @@ -0,0 +1,101 @@ +import type { BaseTranslation } from '../../i18n-types' + +const en_app: BaseTranslation = { + nav: { + home: "Home", + data: "Data", + settings: "Settings", + usermenu: { + logoutTitle: "Log out of your profile", + profileTitle: "Administrate your profile", + toggleTitle: "Toggle user menu", + } + }, + views: { + dataTablePaginator: { + goToPrevPage: "Go to previous page", + goToNextPage: "Go to next page", + }, + categoryForm: { + defaultLabels: "Default labels", + labelsPlaceholder: "Search or create" + }, + settingsCategoriesTile: { + deleteAllConfirm: "Are you sure you want to delete this category?\nThis will delete all relating entries!", + editEntry: "Edit entry", + deleteEntry: "Delete entry", + noCategories: "No categories", + }, + settingsLabelsTile: { + deleteAllConfirm: "Are you sure you want to delete this label?\nIt will be removed from all related entries!", + editEntry: "Edit label", + deleteEntry: "Delete label", + noLabels: "No labels", + }, + entryForm: { + entryUpdateError: "An error occured while updating the entry, try again soon.", + entryCreateError: "An error occured while creating the entry, try again soon.", + errDescriptionReq: "Description is required", + category: { + placeholder: "Search or create", + noResults: "No categories available (Create a new one by searching for it)", + errisRequired: "Category is required", + _logReset: "Reset category section" + }, + labels: { + placeholder: "Search or create", + noResults: "No labels available (Create a new one by searching for it)", + labels: "Labels", + _logReset: "Reset labels section" + }, + dateTime: { + errDateIsRequired: "Date is required", + errFromIsRequired: "From is required", + errFromAfterTo: "From can not be after To", + errFromEqTo: "From and To can not be equal", + errToIsRequired: "To is required", + errToBeforeFrom: "To can not be before From", + from: "From", + to: "To", + date: "Date", + _logReset: "Reset date time section" + } + } + }, + data: { + durationSummary: "Showing {entryCountString:string}, totalling in {totalHourMin:string}", + hourSingleChar: "h", + minSingleChar: "m", + entry: "entry", + entries: "entries", + confirmDeleteEntry: "Are you sure you want to delete this entry?", + editEntry: "Edit entry", + date: "Date", + from: "From", + duration: "Duration", + category: "Category", + description: "Description", + loading: "Loading", + noEntries: "No entries", + to: "to", + use: "Use", + }, + home: { + confirmDeleteEntry: "Are you sure you want to delete this entry?", + newEntry: "New entry", + editEntry: "Edit entry", + deleteEntry: "Delete entry", + loggedTimeToday: "Logged time today", + loggedTimeTodayString: "{hours}h{minutes}m", + currentTime: "Current time", + loading: "Loading", + stopwatch: "Stopwatch", + todayEntries: "Today's entries", + noEntriesToday: "No entries today", + refreshTodayEntries: "Refresh today's entries", + category: "Category", + timespan: "Timespan", + }, +} + +export default en_app
\ No newline at end of file diff --git a/apps/kit/src/lib/i18n/en/index.ts b/apps/kit/src/lib/i18n/en/index.ts index 6a0c3ac..4c1ad04 100644 --- a/apps/kit/src/lib/i18n/en/index.ts +++ b/apps/kit/src/lib/i18n/en/index.ts @@ -1,145 +1,18 @@ import type { BaseTranslation } from "../i18n-types"; const en: BaseTranslation = { - common: { - or: "Or", - logIn: "Log in", - password: "Password", - active: "Active", - reset: "Reset", - description: "Description", - save: "Save", - create: "Create", - archived: "Archived", - emailAddress: "Email address", - name: "Name", - color: "Color", - profile: "Profile", - logout: "Log out", - labels: "Labels", - categories: "Categories", - of: "{0} of {1}", - category: "Category", - isRequired: "{0} is required", - submit: "Submit", - send: "Send {0}", - request: "Request", - success: "Success", - tryAgainSoon: "Kindly try again soon", - unexpectedError: "An unexpected error occured", - }, - nav: { - home: "Home", - data: "Data", - settings: "Settings", - usermenu: { - logoutTitle: "Log out of your profile", - profileTitle: "Administrate your profile", - toggleTitle: "Toggle user menu", - } - }, - views: { - dataTablePaginator: { - goToPrevPage: "Go to previous page", - goToNextPage: "Go to next page", - }, - categoryForm: { - defaultLabels: "Default labels", - labelsPlaceholder: "Search or create" - }, - settingsCategoriesTile: { - deleteAllConfirm: "Are you sure you want to delete this category?\nThis will delete all relating entries!", - editEntry: "Edit entry", - deleteEntry: "Delete entry", - noCategories: "No categories", - }, - settingsLabelsTile: { - deleteAllConfirm: "Are you sure you want to delete this label?\nIt will be removed from all related entries!", - editEntry: "Edit label", - deleteEntry: "Delete label", - noLabels: "No labels", - }, - entryForm: { - entryUpdateError: "An error occured while updating the entry, try again soon.", - entryCreateError: "An error occured while creating the entry, try again soon.", - errDescriptionReq: "Description is required", - category: { - placeholder: "Search or create", - noResults: "No categories available (Create a new one by searching for it)", - errisRequired: "Category is required", - _logReset: "Reset category section" - }, - labels: { - placeholder: "Search or create", - noResults: "No labels available (Create a new one by searching for it)", - labels: "Labels", - _logReset: "Reset labels section" - }, - dateTime: { - errDateIsRequired: "Date is required", - errFromIsRequired: "From is required", - errFromAfterTo: "From can not be after To", - errFromEqTo: "From and To can not be equal", - errToIsRequired: "To is required", - errToBeforeFrom: "To can not be before From", - from: "From", - to: "To", - date: "Date", - _logReset: "Reset date time section" - } - } - }, - data: { - durationSummary: "Showing {entryCountString:string}, totalling in {totalHourMin:string}", - hourSingleChar: "h", - minSingleChar: "m", - entry: "entry", - entries: "entries", - confirmDeleteEntry: "Are you sure you want to delete this entry?", - editEntry: "Edit entry", - date: "Date", - from: "From", - duration: "Duration", - category: "Category", - description: "Description", - loading: "Loading", - noEntries: "No entries", - to: "to", - use: "Use", - }, - home: { - confirmDeleteEntry: "Are you sure you want to delete this entry?", - newEntry: "New entry", - editEntry: "Edit entry", - deleteEntry: "Delete entry", - loggedTimeToday: "Logged time today", - loggedTimeTodayString: "{hours}h{minutes}m", - currentTime: "Current time", - loading: "Loading", - stopwatch: "Stopwatch", - todayEntries: "Today's entries", - noEntriesToday: "No entries today", - refreshTodayEntries: "Refresh today's entries", - category: "Category", - timespan: "Timespan", - }, - messages: { - pageNotFound: "Page not found", - goToFrontpage: "Go to frontpage", - noInternet: "It seems like your device does not have a internet connection, please check your connection." - }, - login: { - loginToYourAccount: "Log in to your account", - createANewAccount: "create a new account", - password: "Password", - notMyComputer: "This is not my computer", - forgotPassword: "Forgot your password?", - }, - reset: { - resetPassword: "Request a password reset", - gotoLoginPage: "Go to login page", - requestSentMessage: "If we find your email address in our systems, you will receive an email with instructions on how to set a new password for your account." - } + or: "Or", + emailAddress: "Email address", + password: "Password", + pageNotFound: "Page not found", + noInternet: "It seems like your device does not have a internet connection, please check your connection.", + reset: "Reset", + of: "{0} of {1}", + isRequired: "{0} is required", + submit: "Submit", + success: "Success", + tryAgainSoon: "Try again soon", + unexpectedError: "An unexpected error occured", }; export default en; diff --git a/apps/kit/src/lib/i18n/en/reset-password/index.ts b/apps/kit/src/lib/i18n/en/reset-password/index.ts new file mode 100644 index 0000000..00322cf --- /dev/null +++ b/apps/kit/src/lib/i18n/en/reset-password/index.ts @@ -0,0 +1,9 @@ +import type { BaseTranslation } from "../../i18n-types" + +const en_reset_password: BaseTranslation = { + requestAPasswordReset: "Request a password reset", + signIntoYourAccount: "sign into your account", + requestSentMessage: "If we find your email address in our systems, you will receive an email with instructions on how to set a new password for your account." +} + +export default en_reset_password
\ No newline at end of file diff --git a/apps/kit/src/lib/i18n/en/sign-in/index.ts b/apps/kit/src/lib/i18n/en/sign-in/index.ts new file mode 100644 index 0000000..3c9c104 --- /dev/null +++ b/apps/kit/src/lib/i18n/en/sign-in/index.ts @@ -0,0 +1,10 @@ +import type { BaseTranslation } from "../../i18n-types" + +const en_sign_in: BaseTranslation = { + signIn: "Sign In", + createANewAccount: "create a new account", + notMyComputer: "This is not my computer", + resetPassword: "Reset password" +} + +export default en_sign_in
\ No newline at end of file diff --git a/apps/kit/src/lib/i18n/en/sign-up/index.ts b/apps/kit/src/lib/i18n/en/sign-up/index.ts new file mode 100644 index 0000000..fa0c3d5 --- /dev/null +++ b/apps/kit/src/lib/i18n/en/sign-up/index.ts @@ -0,0 +1,6 @@ +import type { BaseTranslation } from "../../i18n-types" + +const en_sign_up: BaseTranslation = { +} + +export default en_sign_up
\ No newline at end of file diff --git a/apps/kit/src/lib/i18n/i18n-types.ts b/apps/kit/src/lib/i18n/i18n-types.ts index 3efe059..5139017 100644 --- a/apps/kit/src/lib/i18n/i18n-types.ts +++ b/apps/kit/src/lib/i18n/i18n-types.ts @@ -2,124 +2,81 @@ /* eslint-disable */ import type { BaseTranslation as BaseTranslationType, LocalizedString, RequiredParams } from 'typesafe-i18n' -export type BaseTranslation = BaseTranslationType +export type BaseTranslation = BaseTranslationType & DisallowNamespaces export type BaseLocale = 'en' export type Locales = | 'en' - | 'nb' -export type Translation = RootTranslation +export type Translation = RootTranslation & DisallowNamespaces -export type Translations = RootTranslation +export type Translations = RootTranslation & +{ + app: NamespaceAppTranslation, + 'reset-password': NamespaceResetPasswordTranslation, + 'sign-in': NamespaceSignInTranslation, + 'sign-up': NamespaceSignUpTranslation +} type RootTranslation = { - common: { - /** - * Or - */ - or: string - /** - * Log in - */ - logIn: string - /** - * Password - */ - password: string - /** - * Active - */ - active: string - /** - * Reset - */ - reset: string - /** - * Description - */ - description: string - /** - * Save - */ - save: string - /** - * Create - */ - create: string - /** - * Archived - */ - archived: string - /** - * Email address - */ - emailAddress: string - /** - * Name - */ - name: string - /** - * Color - */ - color: string - /** - * Profile - */ - profile: string - /** - * Log out - */ - logout: string - /** - * Labels - */ - labels: string - /** - * Categories - */ - categories: string - /** - * {0} of {1} - * @param {unknown} 0 - * @param {unknown} 1 - */ - of: RequiredParams<'0' | '1'> - /** - * Category - */ - category: string - /** - * {0} is required - * @param {unknown} 0 - */ - isRequired: RequiredParams<'0'> - /** - * Submit - */ - submit: string - /** - * Send {0} - * @param {unknown} 0 - */ - send: RequiredParams<'0'> - /** - * Request - */ - request: string - /** - * Success - */ - success: string - /** - * Kindly try again soon - */ - tryAgainSoon: string - /** - * An unexpected error occured - */ - unexpectedError: string - } + /** + * Or + */ + or: string + /** + * Email address + */ + emailAddress: string + /** + * Request + */ + request: string + /** + * Password + */ + password: string + /** + * Page not found + */ + pageNotFound: string + /** + * It seems like your device does not have a internet connection, please check your connection. + */ + noInternet: string + /** + * Reset + */ + reset: string + /** + * {0} of {1} + * @param {unknown} 0 + * @param {unknown} 1 + */ + of: RequiredParams<'0' | '1'> + /** + * {0} is required + * @param {unknown} 0 + */ + isRequired: RequiredParams<'0'> + /** + * Submit + */ + submit: string + /** + * Success + */ + success: string + /** + * Try again soon + */ + tryAgainSoon: string + /** + * An unexpected error occured + */ + unexpectedError: string +} + +export type NamespaceAppTranslation = { nav: { /** * Home @@ -428,514 +385,468 @@ type RootTranslation = { */ timespan: string } - messages: { - /** - * Page not found - */ - pageNotFound: string - /** - * Go to frontpage - */ - goToFrontpage: string - /** - * It seems like your device does not have a internet connection, please check your connection. - */ - noInternet: string - } - login: { - /** - * Log in to your account - */ - loginToYourAccount: string - /** - * create a new account - */ - createANewAccount: string - /** - * Password - */ - password: string - /** - * This is not my computer - */ - notMyComputer: string - /** - * Forgot your password? - */ - forgotPassword: string - } - reset: { - /** - * Request a password reset - */ - resetPassword: string - /** - * Go to login page - */ - gotoLoginPage: string - /** - * If we find your email address in our systems, you will receive an email with instructions on how to set a new password for your account. - */ - requestSentMessage: string - } +} + +export type NamespaceResetPasswordTranslation = { + /** + * Request a password reset + */ + requestAPasswordReset: string + /** + * sign into your account + */ + signIntoYourAccount: string + /** + * If we find your email address in our systems, you will receive an email with instructions on how to set a new password for your account. + */ + requestSentMessage: string +} + +export type NamespaceSignInTranslation = { + /** + * Sign In + */ + signIn: string + /** + * create a new account + */ + createANewAccount: string + /** + * This is not my computer + */ + notMyComputer: string + /** + * Reset password + */ + resetPassword: string +} + +export type NamespaceSignUpTranslation = {} + +export type Namespaces = + | 'app' + | 'reset-password' + | 'sign-in' + | 'sign-up' + +type DisallowNamespaces = { + /** + * reserved for 'app'-namespace\ + * you need to use the `./app/index.ts` file instead + */ + app?: "[typesafe-i18n] reserved for 'app'-namespace. You need to use the `./app/index.ts` file instead." + + /** + * reserved for 'reset-password'-namespace\ + * you need to use the `./reset-password/index.ts` file instead + */ + 'reset-password'?: "[typesafe-i18n] reserved for 'reset-password'-namespace. You need to use the `./reset-password/index.ts` file instead." + + /** + * reserved for 'sign-in'-namespace\ + * you need to use the `./sign-in/index.ts` file instead + */ + 'sign-in'?: "[typesafe-i18n] reserved for 'sign-in'-namespace. You need to use the `./sign-in/index.ts` file instead." + + /** + * reserved for 'sign-up'-namespace\ + * you need to use the `./sign-up/index.ts` file instead + */ + 'sign-up'?: "[typesafe-i18n] reserved for 'sign-up'-namespace. You need to use the `./sign-up/index.ts` file instead." } export type TranslationFunctions = { - common: { - /** - * Or - */ - or: () => LocalizedString - /** - * Log in - */ - logIn: () => LocalizedString - /** - * Password - */ - password: () => LocalizedString - /** - * Active - */ - active: () => LocalizedString - /** - * Reset - */ - reset: () => LocalizedString - /** - * Description - */ - description: () => LocalizedString - /** - * Save - */ - save: () => LocalizedString - /** - * Create - */ - create: () => LocalizedString - /** - * Archived - */ - archived: () => LocalizedString - /** - * Email address - */ - emailAddress: () => LocalizedString - /** - * Name - */ - name: () => LocalizedString - /** - * Color - */ - color: () => LocalizedString - /** - * Profile - */ - profile: () => LocalizedString - /** - * Log out - */ - logout: () => LocalizedString - /** - * Labels - */ - labels: () => LocalizedString - /** - * Categories - */ - categories: () => LocalizedString - /** - * {0} of {1} - */ - of: (arg0: unknown, arg1: unknown) => LocalizedString - /** - * Category - */ - category: () => LocalizedString - /** - * {0} is required - */ - isRequired: (arg0: unknown) => LocalizedString - /** - * Submit - */ - submit: () => LocalizedString - /** - * Send {0} - */ - send: (arg0: unknown) => LocalizedString - /** - * Request - */ - request: () => LocalizedString - /** - * Success - */ - success: () => LocalizedString - /** - * Kindly try again soon - */ - tryAgainSoon: () => LocalizedString - /** - * An unexpected error occured - */ - unexpectedError: () => LocalizedString - } - nav: { - /** - * Home - */ - home: () => LocalizedString - /** - * Data - */ - data: () => LocalizedString - /** - * Settings - */ - settings: () => LocalizedString - usermenu: { - /** - * Log out of your profile - */ - logoutTitle: () => LocalizedString - /** - * Administrate your profile - */ - profileTitle: () => LocalizedString - /** - * Toggle user menu - */ - toggleTitle: () => LocalizedString - } - } - views: { - dataTablePaginator: { - /** - * Go to previous page - */ - goToPrevPage: () => LocalizedString - /** - * Go to next page - */ - goToNextPage: () => LocalizedString - } - categoryForm: { - /** - * Default labels - */ - defaultLabels: () => LocalizedString - /** - * Search or create - */ - labelsPlaceholder: () => LocalizedString - } - settingsCategoriesTile: { - /** - * Are you sure you want to delete this category? - This will delete all relating entries! - */ - deleteAllConfirm: () => LocalizedString - /** - * Edit entry - */ - editEntry: () => LocalizedString - /** - * Delete entry - */ - deleteEntry: () => LocalizedString - /** - * No categories - */ - noCategories: () => LocalizedString - } - settingsLabelsTile: { - /** - * Are you sure you want to delete this label? - It will be removed from all related entries! - */ - deleteAllConfirm: () => LocalizedString - /** - * Edit label - */ - editEntry: () => LocalizedString - /** - * Delete label - */ - deleteEntry: () => LocalizedString - /** - * No labels - */ - noLabels: () => LocalizedString - } - entryForm: { + /** + * Or + */ + or: () => LocalizedString + /** + * Email address + */ + emailAddress: () => LocalizedString + /** + * Request + */ + request: () => LocalizedString + /** + * Password + */ + password: () => LocalizedString + /** + * Page not found + */ + pageNotFound: () => LocalizedString + /** + * It seems like your device does not have a internet connection, please check your connection. + */ + noInternet: () => LocalizedString + /** + * Reset + */ + reset: () => LocalizedString + /** + * {0} of {1} + */ + of: (arg0: unknown, arg1: unknown) => LocalizedString + /** + * {0} is required + */ + isRequired: (arg0: unknown) => LocalizedString + /** + * Submit + */ + submit: () => LocalizedString + /** + * Success + */ + success: () => LocalizedString + /** + * Try again soon + */ + tryAgainSoon: () => LocalizedString + /** + * An unexpected error occured + */ + unexpectedError: () => LocalizedString + app: { + nav: { /** - * An error occured while updating the entry, try again soon. + * Home */ - entryUpdateError: () => LocalizedString + home: () => LocalizedString /** - * An error occured while creating the entry, try again soon. + * Data */ - entryCreateError: () => LocalizedString + data: () => LocalizedString /** - * Description is required + * Settings */ - errDescriptionReq: () => LocalizedString - category: { - /** - * Search or create - */ - placeholder: () => LocalizedString + settings: () => LocalizedString + usermenu: { /** - * No categories available (Create a new one by searching for it) + * Log out of your profile */ - noResults: () => LocalizedString + logoutTitle: () => LocalizedString /** - * Category is required + * Administrate your profile */ - errisRequired: () => LocalizedString + profileTitle: () => LocalizedString /** - * Reset category section + * Toggle user menu */ - _logReset: () => LocalizedString + toggleTitle: () => LocalizedString } - labels: { + } + views: { + dataTablePaginator: { /** - * Search or create + * Go to previous page */ - placeholder: () => LocalizedString + goToPrevPage: () => LocalizedString /** - * No labels available (Create a new one by searching for it) + * Go to next page */ - noResults: () => LocalizedString + goToNextPage: () => LocalizedString + } + categoryForm: { /** - * Labels + * Default labels */ - labels: () => LocalizedString + defaultLabels: () => LocalizedString /** - * Reset labels section + * Search or create */ - _logReset: () => LocalizedString + labelsPlaceholder: () => LocalizedString } - dateTime: { + settingsCategoriesTile: { /** - * Date is required + * Are you sure you want to delete this category? + This will delete all relating entries! */ - errDateIsRequired: () => LocalizedString + deleteAllConfirm: () => LocalizedString /** - * From is required + * Edit entry */ - errFromIsRequired: () => LocalizedString + editEntry: () => LocalizedString /** - * From can not be after To + * Delete entry */ - errFromAfterTo: () => LocalizedString + deleteEntry: () => LocalizedString /** - * From and To can not be equal + * No categories */ - errFromEqTo: () => LocalizedString + noCategories: () => LocalizedString + } + settingsLabelsTile: { /** - * To is required + * Are you sure you want to delete this label? + It will be removed from all related entries! */ - errToIsRequired: () => LocalizedString + deleteAllConfirm: () => LocalizedString /** - * To can not be before From + * Edit label */ - errToBeforeFrom: () => LocalizedString + editEntry: () => LocalizedString /** - * From + * Delete label */ - from: () => LocalizedString + deleteEntry: () => LocalizedString /** - * To + * No labels */ - to: () => LocalizedString + noLabels: () => LocalizedString + } + entryForm: { /** - * Date + * An error occured while updating the entry, try again soon. */ - date: () => LocalizedString + entryUpdateError: () => LocalizedString /** - * Reset date time section + * An error occured while creating the entry, try again soon. */ - _logReset: () => LocalizedString + entryCreateError: () => LocalizedString + /** + * Description is required + */ + errDescriptionReq: () => LocalizedString + category: { + /** + * Search or create + */ + placeholder: () => LocalizedString + /** + * No categories available (Create a new one by searching for it) + */ + noResults: () => LocalizedString + /** + * Category is required + */ + errisRequired: () => LocalizedString + /** + * Reset category section + */ + _logReset: () => LocalizedString + } + labels: { + /** + * Search or create + */ + placeholder: () => LocalizedString + /** + * No labels available (Create a new one by searching for it) + */ + noResults: () => LocalizedString + /** + * Labels + */ + labels: () => LocalizedString + /** + * Reset labels section + */ + _logReset: () => LocalizedString + } + dateTime: { + /** + * Date is required + */ + errDateIsRequired: () => LocalizedString + /** + * From is required + */ + errFromIsRequired: () => LocalizedString + /** + * From can not be after To + */ + errFromAfterTo: () => LocalizedString + /** + * From and To can not be equal + */ + errFromEqTo: () => LocalizedString + /** + * To is required + */ + errToIsRequired: () => LocalizedString + /** + * To can not be before From + */ + errToBeforeFrom: () => LocalizedString + /** + * From + */ + from: () => LocalizedString + /** + * To + */ + to: () => LocalizedString + /** + * Date + */ + date: () => LocalizedString + /** + * Reset date time section + */ + _logReset: () => LocalizedString + } } } + data: { + /** + * Showing {entryCountString}, totalling in {totalHourMin} + */ + durationSummary: (arg: { entryCountString: string, totalHourMin: string }) => LocalizedString + /** + * h + */ + hourSingleChar: () => LocalizedString + /** + * m + */ + minSingleChar: () => LocalizedString + /** + * entry + */ + entry: () => LocalizedString + /** + * entries + */ + entries: () => LocalizedString + /** + * Are you sure you want to delete this entry? + */ + confirmDeleteEntry: () => LocalizedString + /** + * Edit entry + */ + editEntry: () => LocalizedString + /** + * Date + */ + date: () => LocalizedString + /** + * From + */ + from: () => LocalizedString + /** + * Duration + */ + duration: () => LocalizedString + /** + * Category + */ + category: () => LocalizedString + /** + * Description + */ + description: () => LocalizedString + /** + * Loading + */ + loading: () => LocalizedString + /** + * No entries + */ + noEntries: () => LocalizedString + /** + * to + */ + to: () => LocalizedString + /** + * Use + */ + use: () => LocalizedString + } + home: { + /** + * Are you sure you want to delete this entry? + */ + confirmDeleteEntry: () => LocalizedString + /** + * New entry + */ + newEntry: () => LocalizedString + /** + * Edit entry + */ + editEntry: () => LocalizedString + /** + * Delete entry + */ + deleteEntry: () => LocalizedString + /** + * Logged time today + */ + loggedTimeToday: () => LocalizedString + /** + * {hours}h{minutes}m + */ + loggedTimeTodayString: (arg: { hours: unknown, minutes: unknown }) => LocalizedString + /** + * Current time + */ + currentTime: () => LocalizedString + /** + * Loading + */ + loading: () => LocalizedString + /** + * Stopwatch + */ + stopwatch: () => LocalizedString + /** + * Today's entries + */ + todayEntries: () => LocalizedString + /** + * No entries today + */ + noEntriesToday: () => LocalizedString + /** + * Refresh today's entries + */ + refreshTodayEntries: () => LocalizedString + /** + * Category + */ + category: () => LocalizedString + /** + * Timespan + */ + timespan: () => LocalizedString + } } - data: { - /** - * Showing {entryCountString}, totalling in {totalHourMin} - */ - durationSummary: (arg: { entryCountString: string, totalHourMin: string }) => LocalizedString - /** - * h - */ - hourSingleChar: () => LocalizedString - /** - * m - */ - minSingleChar: () => LocalizedString - /** - * entry - */ - entry: () => LocalizedString - /** - * entries - */ - entries: () => LocalizedString - /** - * Are you sure you want to delete this entry? - */ - confirmDeleteEntry: () => LocalizedString - /** - * Edit entry - */ - editEntry: () => LocalizedString - /** - * Date - */ - date: () => LocalizedString - /** - * From - */ - from: () => LocalizedString - /** - * Duration - */ - duration: () => LocalizedString - /** - * Category - */ - category: () => LocalizedString - /** - * Description - */ - description: () => LocalizedString - /** - * Loading - */ - loading: () => LocalizedString - /** - * No entries - */ - noEntries: () => LocalizedString - /** - * to - */ - to: () => LocalizedString - /** - * Use - */ - use: () => LocalizedString - } - home: { - /** - * Are you sure you want to delete this entry? - */ - confirmDeleteEntry: () => LocalizedString - /** - * New entry - */ - newEntry: () => LocalizedString - /** - * Edit entry - */ - editEntry: () => LocalizedString - /** - * Delete entry - */ - deleteEntry: () => LocalizedString - /** - * Logged time today - */ - loggedTimeToday: () => LocalizedString - /** - * {hours}h{minutes}m - */ - loggedTimeTodayString: (arg: { hours: unknown, minutes: unknown }) => LocalizedString - /** - * Current time - */ - currentTime: () => LocalizedString - /** - * Loading - */ - loading: () => LocalizedString - /** - * Stopwatch - */ - stopwatch: () => LocalizedString - /** - * Today's entries - */ - todayEntries: () => LocalizedString - /** - * No entries today - */ - noEntriesToday: () => LocalizedString - /** - * Refresh today's entries - */ - refreshTodayEntries: () => LocalizedString - /** - * Category - */ - category: () => LocalizedString - /** - * Timespan - */ - timespan: () => LocalizedString - } - messages: { + 'reset-password': { /** - * Page not found + * Request a password reset */ - pageNotFound: () => LocalizedString + requestAPasswordReset: () => LocalizedString /** - * Go to frontpage + * sign into your account */ - goToFrontpage: () => LocalizedString + signIntoYourAccount: () => LocalizedString /** - * It seems like your device does not have a internet connection, please check your connection. + * If we find your email address in our systems, you will receive an email with instructions on how to set a new password for your account. */ - noInternet: () => LocalizedString + requestSentMessage: () => LocalizedString } - login: { + 'sign-in': { /** - * Log in to your account + * Sign In */ - loginToYourAccount: () => LocalizedString + signIn: () => LocalizedString /** * create a new account */ createANewAccount: () => LocalizedString /** - * Password - */ - password: () => LocalizedString - /** * This is not my computer */ notMyComputer: () => LocalizedString /** - * Forgot your password? - */ - forgotPassword: () => LocalizedString - } - reset: { - /** - * Request a password reset + * Reset password */ resetPassword: () => LocalizedString - /** - * Go to login page - */ - gotoLoginPage: () => LocalizedString - /** - * If we find your email address in our systems, you will receive an email with instructions on how to set a new password for your account. - */ - requestSentMessage: () => LocalizedString + } + 'sign-up': { } } diff --git a/apps/kit/src/lib/i18n/i18n-util.async.ts b/apps/kit/src/lib/i18n/i18n-util.async.ts index 3ccef5f..a114495 100644 --- a/apps/kit/src/lib/i18n/i18n-util.async.ts +++ b/apps/kit/src/lib/i18n/i18n-util.async.ts @@ -2,12 +2,20 @@ /* eslint-disable */ import { initFormatters } from './formatters' -import type { Locales, Translations } from './i18n-types' +import type { Locales, Namespaces, Translations } from './i18n-types' import { loadedFormatters, loadedLocales, locales } from './i18n-util' const localeTranslationLoaders = { en: () => import('./en'), - nb: () => import('./nb'), +} + +const localeNamespaceLoaders = { + en: { + app: () => import('./en/app'), + 'reset-password': () => import('./en/reset-password'), + 'sign-in': () => import('./en/sign-in'), + 'sign-up': () => import('./en/sign-up') + } } const updateDictionary = (locale: Locales, dictionary: Partial<Translations>) => @@ -25,3 +33,9 @@ export const loadAllLocalesAsync = (): Promise<void[]> => Promise.all(locales.ma export const loadFormatters = (locale: Locales): void => void (loadedFormatters[locale] = initFormatters(locale)) + +export const importNamespaceAsync = async<Namespace extends Namespaces>(locale: Locales, namespace: Namespace) => + (await localeNamespaceLoaders[locale][namespace]()).default as unknown as Translations[Namespace] + +export const loadNamespaceAsync = async <Namespace extends Namespaces>(locale: Locales, namespace: Namespace): Promise<void> => + void updateDictionary(locale, { [namespace]: await importNamespaceAsync(locale, namespace )}) diff --git a/apps/kit/src/lib/i18n/i18n-util.sync.ts b/apps/kit/src/lib/i18n/i18n-util.sync.ts index f1a8e9e..15ae633 100644 --- a/apps/kit/src/lib/i18n/i18n-util.sync.ts +++ b/apps/kit/src/lib/i18n/i18n-util.sync.ts @@ -6,11 +6,20 @@ import type { Locales, Translations } from './i18n-types' import { loadedFormatters, loadedLocales, locales } from './i18n-util' import en from './en' -import nb from './nb' + +import en_app from './en/app' +import en_reset_password from './en/reset-password' +import en_sign_in from './en/sign-in' +import en_sign_up from './en/sign-up' const localeTranslations = { - en, - nb, + en: { + ...en, + app: en_app, + 'reset-password': en_reset_password, + 'sign-in': en_sign_in, + 'sign-up': en_sign_up + }, } export const loadLocale = (locale: Locales): void => { diff --git a/apps/kit/src/lib/i18n/i18n-util.ts b/apps/kit/src/lib/i18n/i18n-util.ts index 11d4b23..c4f5c32 100644 --- a/apps/kit/src/lib/i18n/i18n-util.ts +++ b/apps/kit/src/lib/i18n/i18n-util.ts @@ -4,17 +4,25 @@ import { i18n as initI18n, i18nObject as initI18nObject, i18nString as initI18nString } from 'typesafe-i18n' import type { LocaleDetector } from 'typesafe-i18n/detectors' import { detectLocale as detectLocaleFn } from 'typesafe-i18n/detectors' -import type { Formatters, Locales, Translations, TranslationFunctions } from './i18n-types' +import type { Formatters, Locales, Namespaces, Translations, TranslationFunctions } from './i18n-types' export const baseLocale: Locales = 'en' export const locales: Locales[] = [ - 'en', - 'nb' + 'en' +] + +export const namespaces: Namespaces[] = [ + 'app', + 'reset-password', + 'sign-in', + 'sign-up' ] export const isLocale = (locale: string) => locales.includes(locale as Locales) +export const isNamespace = (namespace: string) => namespaces.includes(namespace as Namespaces) + export const loadedLocales = {} as Record<Locales, Translations> export const loadedFormatters = {} as Record<Locales, Formatters> diff --git a/apps/kit/src/lib/i18n/nb/index.ts b/apps/kit/src/lib/i18n/nb/index.ts deleted file mode 100644 index 4329f14..0000000 --- a/apps/kit/src/lib/i18n/nb/index.ts +++ /dev/null @@ -1,115 +0,0 @@ -import type { Translation } from "../i18n-types"; - -const nb: Translation = { - nav: { - home: "Hjem", - data: "Data", - settings: "Innstillinger", - usermenu: { - logoutTitle: "Logg ut av din profil", - profileTitle: "Administrer din profil", - toggleTitle: "Vis brukermeny" - } - }, - views: { - categoryForm: { - defaultLabels: "Standard merknader", - labelsPlaceholder: "Søk eller opprett" - }, - dataTablePaginator: { - goToPrevPage: "Gå til forrige side", - goToNextPage: "Gå til neste side", - }, - settingsCategoriesTile: { - deleteAllConfirm: "Er du sikker på at du vil slette denne kategorien?\nDette vil slette alle tilhørende rader!", - editEntry: "Rediger kategori", - deleteEntry: "Slett kategori", - noCategories: "Ingen kategorier", - }, - settingsLabelsTile: { - deleteAllConfirm: "Er du sikker på at du vil slette denne merknaden?\nDen vil bli slette fra alle relaterte rader!", - editEntry: "Rediger merknad", - deleteEntry: "Slett merknad", - noLabels: "Ingen merknader", - }, - entryForm: { - entryUpdateError: "En feil oppstod med lagringen av din rad, prøv igjen snart.", - entryCreateError: "En feil oppstod med opprettelsen av din rad, prøv igjen snart.", - errDescriptionReq: "Beskrivelse er påkrevd", - category: { - placeholder: "Søk eller opprett", - noResults: "Ingen kategorier tilgjengelig (Opprett en ny ved å skrive navnet i søkefeltet).", - errisRequired: "Kategori er påkrevd", - _logReset: "Tilbakestilte kategori-seksjonen" - }, - labels: { - placeholder: "Søk eller opprett", - noResults: "Ingen merkander tilgjengelig (Opprett en ny ved å skrive navnet i søkefeltet).", - labels: "Merknader", - _logReset: "Tilbakestilte merknader-seksjonen" - }, - dateTime: { - errDateIsRequired: "Dato er påkrevd", - errFromIsRequired: "Fra er påkrevd", - errFromAfterTo: "Fra kan ikke være etter Til", - errFromEqTo: "Fra og Til kan ikke ha lik verdi", - errToIsRequired: "Til er påkrevd", - errToBeforeFrom: "Til kan ikke være før Fra", - from: "Fra", - to: "Til", - date: "Dato", - _logReset: "Tilbakestilte dato-seksjonen" - } - } - }, - data: { - // durationSummary: "Viser {entryCountString:string}, Tilsammen {totalHourMin:string}", - hourSingleChar: "t", - minSingleChar: "m", - entry: "rad", - entries: "rader", - confirmDeleteEntry: "Er du sikker på at du vil slette denne raden?", - editEntry: "Rediger rad", - date: "Dato", - from: "Fra", - duration: "Tidsrom", - category: "Kategori", - description: "Beskrivelse", - loading: "Laster", - noEntries: "Ingen rader", - to: "til", - use: "Bruk", - }, - home: { - loggedTimeTodayString: "{hours}t{minutes}m", - confirmDeleteEntry: "Er du sikker på at du vil slette denne raden?", - newEntry: "Ny tidsoppføring", - editEntry: "Rediger rad", - deleteEntry: "Slett rad", - loggedTimeToday: "Registrert tid hittil idag", - currentTime: "Klokken", - loading: "Laster", - stopwatch: "Stoppeklokke", - todayEntries: "Dagens tidsoppføringer", - noEntriesToday: "Ingen oppføringer i dag", - refreshTodayEntries: "Last inn dagens tidsoppføringer på nytt", - category: "Kategori", - timespan: "Tidsrom", - }, - messages: { - pageNotFound: "Fant ikke siden", - goToFrontpage: "Gå til forsiden", - noInternet: "Det ser ut som at du er uten internettilgang, vennligst sjekk tilkoblingen din." - }, - login: { - loginToYourAccount: "Logg inn i din konto", - createANewAccount: "lag en ny konto", - password: "Passord", - notMyComputer: "Dette er ikke min datamaskin", - forgotPassword: "Glemt passord?", - }, - reset: { - } -}; - -export default nb; diff --git a/apps/kit/src/routes/(main)/(public)/reset-password/+page.svelte b/apps/kit/src/routes/(main)/(public)/reset-password/+page.svelte index b951153..865be10 100644 --- a/apps/kit/src/routes/(main)/(public)/reset-password/+page.svelte +++ b/apps/kit/src/routes/(main)/(public)/reset-password/+page.svelte @@ -1,9 +1,8 @@ <script lang="ts"> import { create_forgot_password_request } from "$lib/api/user"; - import Alert from "$lib/components/alert.svelte"; + import { Alert, Input, Button } from "$lib/components"; import LL from "$lib/i18n/i18n-svelte"; import type { ErrorResult } from "$lib/models/ErrorResult"; - import { get } from "svelte/store"; const formData = { email: "", @@ -20,14 +19,14 @@ let showSuccessAlert = false; - async function submit() { + async function submitFormAsync() { errorData.text = ""; errorData.title = ""; showSuccessAlert = false; const request = await create_forgot_password_request(formData.email); if (!request.ok) { - errorData.text = request.data.text ?? $LL.common.tryAgainSoon(); - errorData.title = request.data.title ?? $LL.common.unexpectedError(); + errorData.text = request.data.text ?? $LL.tryAgainSoon(); + errorData.title = request.data.title ?? $LL.unexpectedError(); return; } showSuccessAlert = true; @@ -39,25 +38,19 @@ <h2 class="mt-6 text-center text-3xl tracking-tight font-bold text-gray-900" > - {$LL.reset.resetPassword()} + {$LL["reset-password"].requestAPasswordReset()} </h2> <p class="mt-2 text-center text-sm text-gray-600"> - {$LL.common.or()} - <a - href="/sign-in" - class="font-medium text-indigo-600 hover:text-indigo-500" - >{$LL.reset.gotoLoginPage().toLowerCase()}</a - > + {$LL.or()} + <a href="/sign-in" class="link"> + {$LL["reset-password"].signIntoYourAccount()} + </a> </p> </div> <div class="mt-8 sm:mx-auto sm:w-full sm:max-w-md"> <div class="bg-white py-8 px-4 shadow sm:rounded-lg sm:px-10"> - <form - class="space-y-6" - on:submit|preventDefault={submit} - method="POST" - > + <form class="space-y-6" on:submit|preventDefault={submitFormAsync}> <Alert title={errorData.title} message={errorData.text} @@ -67,37 +60,21 @@ <Alert type="success" - title={$LL.common.success()} - message={$LL.reset.requestSentMessage()} + title={$LL.success()} + message={$LL["reset-password"].requestSentMessage()} visible={showSuccessAlert} /> - <div> - <label - for="email" - class="block text-sm font-medium text-gray-700" - > - {$LL.common.emailAddress()}</label - > - <div class="mt-1"> - <input - id="email" - name="email" - type="email" - autocomplete="email" - required - bind:value={formData.email} - class="appearance-none block w-full px-3 py-2 border border-gray-300 rounded-md shadow-sm placeholder-gray-400 focus:outline-none focus:ring-indigo-500 focus:border-indigo-500 sm:text-sm" - /> - </div> - </div> - <div> - <button - type="submit" - class="w-full flex justify-center py-2 px-4 border border-transparent rounded-md shadow-sm text-sm font-medium text-white bg-indigo-600 hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-offset-2 focus:ring-indigo-500" - > - {$LL.common.send($LL.common.request().toLowerCase())} - </button> - </div> + + <Input + id="email" + name="email" + type="email" + autocomplete="email" + required + bind:value={formData.email} + label={$LL.emailAddress()} + /> + <Button text={$LL.submit()} type="submit" fullWidth /> </form> </div> </div> diff --git a/apps/kit/src/routes/(main)/(public)/sign-in/+page.svelte b/apps/kit/src/routes/(main)/(public)/sign-in/+page.svelte index 3802722..d47f924 100644 --- a/apps/kit/src/routes/(main)/(public)/sign-in/+page.svelte +++ b/apps/kit/src/routes/(main)/(public)/sign-in/+page.svelte @@ -39,11 +39,13 @@ <h2 class="mt-6 text-center text-3xl tracking-tight font-bold text-gray-900" > - {$LL.login.loginToYourAccount()} + {$LL["sign-in"].signIn()} </h2> <p class="mt-2 text-center text-sm text-gray-600"> - {$LL.common.or()} - <a href="/sign-up" class="link">{$LL.login.createANewAccount()}</a> + {$LL.or().toLowerCase()} + <a href="/sign-up" class="link" + >{$LL["sign-in"].createANewAccount()}</a + > </p> </div> <div class="mt-8 sm:mx-auto sm:w-full sm:max-w-md"> @@ -67,7 +69,7 @@ id="email" name="email" type="email" - label={$LL.common.emailAddress()} + label={$LL.emailAddress()} required value={data.username} /> @@ -76,7 +78,7 @@ id="password" name="password" type="password" - label={$LL.login.password()} + label={$LL.password()} autocomplete="current-password" required value={data.password} @@ -86,17 +88,17 @@ <Checkbox id="remember-me" name="remember-me" - label={$LL.login.notMyComputer()} + label={$LL["sign-in"].notMyComputer()} /> <div class="text-sm"> <a href="/reset-password" class="link"> - {$LL.login.forgotPassword()} + {$LL["sign-in"].resetPassword()} </a> </div> </div> <Button - text={$LL.common.logIn()} + text={$LL["sign-in"].signIn()} fullWidth type="submit" {loading} diff --git a/apps/kit/src/routes/(main)/+layout.ts b/apps/kit/src/routes/(main)/+layout.ts index de8a5c0..f673067 100644 --- a/apps/kit/src/routes/(main)/+layout.ts +++ b/apps/kit/src/routes/(main)/+layout.ts @@ -1,9 +1,19 @@ -import type {Locales} from "$lib/i18n/i18n-types"; -import {loadLocaleAsync} from "$lib/i18n/i18n-util.async"; -import type {LayoutLoad} from "./$types"; +import type { Locales } from "$lib/i18n/i18n-types"; +import { loadLocaleAsync, loadNamespaceAsync } from "$lib/i18n/i18n-util.async"; +import type { LayoutLoad } from "./$types"; -export const load: LayoutLoad<{ locale: Locales }> = async ({url, params}) => { +export const load: LayoutLoad<{ locale: Locales }> = async ({ url, params }) => { let lang = "en" as Locales; await loadLocaleAsync(lang); - return {locale: lang}; + + if (url.pathname.startsWith("/sign-in")) { + await loadNamespaceAsync(lang, "sign-in"); + } + if (url.pathname.startsWith("/sign-up")) { + await loadNamespaceAsync(lang, "sign-up"); + } + if (url.pathname.startsWith("/reset-password")) { + await loadNamespaceAsync(lang, "reset-password"); + } + return { locale: lang }; };
\ No newline at end of file |
