diff --git a/src/components/NotePage/NoteList/NoteItem.tsx b/src/components/NotePage/NoteList/NoteItem.tsx index c7d14fd03d..7748820a3c 100644 --- a/src/components/NotePage/NoteList/NoteItem.tsx +++ b/src/components/NotePage/NoteList/NoteItem.tsx @@ -15,6 +15,7 @@ import { scaleAndTransformFromLeft } from '../../../lib/styled' import { PopulatedNoteDoc } from '../../../lib/db/types' import { useContextMenu, MenuTypes } from '../../../lib/contextMenu' import { useDb } from '../../../lib/db' +import { useTranslation } from 'react-i18next' export const StyledNoteListItem = styled.div` margin: 0; @@ -109,6 +110,8 @@ export default ({ const { popup } = useContextMenu() const { createNote, trashNote, updateNote } = useDb() + const { t } = useTranslation() + const contextMenuCallback = useCallback( (event: React.MouseEvent) => { event.stopPropagation() @@ -116,7 +119,7 @@ export default ({ popup(event, [ { type: MenuTypes.Normal, - label: 'Duplicate', + label: t('note.duplicate'), onClick: async () => { createNote(note.storageId, { title: note.title, @@ -130,14 +133,14 @@ export default ({ }, { type: MenuTypes.Normal, - label: 'Delete', + label: t('note.delete'), onClick: async () => { trashNote(note.storageId, note._id) } }, { type: MenuTypes.Normal, - label: note.bookmarked ? 'Remove Bookmark' : 'Bookmark', + label: note.bookmarked ? t('bookmark.remove') : t('bookmark.add'), onClick: async () => { note.bookmarked = !note.bookmarked updateNote(note.storageId, note._id, note) @@ -161,13 +164,13 @@ export default ({ .shift() return contentToHighlight == null ? ( - 'Empty note' + t('note.empty') ) : ( ) } - return trimmedContent.split('\n').shift() || 'Empty note' + return trimmedContent.split('\n').shift() || t('note.empty') }, [note.content, search]) const handleDragStart = useCallback( @@ -189,9 +192,11 @@ export default ({
- {note.title.length === 0 &&
No title
} + {note.title.length === 0 && ( +
{t('note.noTitle')}
+ )}
- {formatDistanceToNow(new Date(note.updatedAt))} ago + {formatDistanceToNow(new Date(note.updatedAt))} {t('note.date')}
{contentPreview}
{note.tags.length > 0 && ( diff --git a/src/components/NotePage/NoteList/NoteList.tsx b/src/components/NotePage/NoteList/NoteList.tsx index 15bacb07ec..0f313274c2 100644 --- a/src/components/NotePage/NoteList/NoteList.tsx +++ b/src/components/NotePage/NoteList/NoteList.tsx @@ -13,6 +13,7 @@ import { iconColor } from '../../../lib/styled/styleFunctions' import { IconEdit, IconLoupe } from '../../icons' +import { useTranslation } from 'react-i18next' export const StyledNoteListContainer = styled.div` display: flex; @@ -81,6 +82,8 @@ type NoteListProps = { lastCreatedNoteId: string } +const { t } = useTranslation() + const NoteList = ({ notes, createNote, @@ -127,7 +130,7 @@ const NoteList = ({ className='input' value={search} onChange={updateSearchInput} - placeholder='Search Notes' + placeholder={t('note.search')} /> @@ -156,9 +159,9 @@ const NoteList = ({ })} {notes.length === 0 ? ( search.trim() === '' ? ( -
  • No notes
  • +
  • {t('note.nothing')}
  • ) : ( -
  • No notes could be found.
  • +
  • {t('note.nothingMessage')}
  • ) ) : null} diff --git a/src/components/NotePage/NotePage.tsx b/src/components/NotePage/NotePage.tsx index 62a62bea39..3a701bbac9 100644 --- a/src/components/NotePage/NotePage.tsx +++ b/src/components/NotePage/NotePage.tsx @@ -23,6 +23,7 @@ import { import { useGeneralStatus, ViewModeType } from '../../lib/generalStatus' import { useDialog, DialogIconTypes } from '../../lib/dialog' import { escapeRegExp } from '../../lib/regex' +import { useTranslation } from 'react-i18next' export const StyledNoteDetailNoNote = styled.div` text-align: center; @@ -59,6 +60,8 @@ export default () => { const { push } = useRouter() const [lastCreatedNoteId, setLastCreatedNoteId] = useState('') + const { t } = useTranslation() + useEffect(() => { setLastCreatedNoteId('') }, [currentPathnameWithoutNoteId]) @@ -216,10 +219,10 @@ export default () => { const purgeNote = useCallback( (storageId: string, noteId: string) => { messageBox({ - title: 'Delete a Note', - message: 'The note will be deleted permanently', + title: t('note.delete2'), + message: t('note.deleteMessage'), iconType: DialogIconTypes.Warning, - buttons: ['Delete Note', 'Cancel'], + buttons: [t('note.delete2'), t('general.cancel')], defaultButtonIndex: 0, cancelButtonIndex: 1, onClose: (value: number | null) => { @@ -273,13 +276,14 @@ export default () => { {storageId != null ? (
    -

    Command(⌘) + N

    -

    to create a new note

    +

    {t('note.createKeyMac')}

    +

    {t('note.createKeyWinLin')}

    +

    {t('note.createkeymessage1')}

    ) : (
    -

    Select a storage

    -

    to create a new note

    +

    {t('note.createkeymessage2')}

    +

    {t('note.createkeymessage3')}

    )}
    diff --git a/src/components/PreferencesModal/AboutTab.tsx b/src/components/PreferencesModal/AboutTab.tsx index febd9df152..2f0da538b8 100644 --- a/src/components/PreferencesModal/AboutTab.tsx +++ b/src/components/PreferencesModal/AboutTab.tsx @@ -9,6 +9,7 @@ import { import { openNew } from '../../lib/utils/platform' import Image from '../atoms/Image' import AppLink from '../atoms/AppLink' +import { useTranslation } from 'react-i18next' const AboutContents = styled.div` max-width: 360px; @@ -79,6 +80,7 @@ interface PrimaryLinkProps { href: string children: string } +const { t } = useTranslation() const PrimaryLink = ({ href, children }: PrimaryLinkProps) => { const handleClick = useCallback( @@ -102,23 +104,20 @@ const AboutTab = () => {
    - About + {t('about.about')}

    Boost Note {process.env.VERSION}

    -

    - An open source note-taking app made for programmers just like - you. -

    +

    {t('about.boostnoteDescription')}

    - Official Website + {t('about.website')} - Boost Note for Team + {t('about.boostWiki')}

    @@ -130,48 +129,48 @@ const AboutTab = () => {
    - Cross-platform + {t('about.platform')}
    - Community + {t('about.community')}
    • - GitHub Repository + {t('about.github')}
    • - Bounty on IssueHunt + {t('about.bounty')}
    • - Blog + {t('about.blog')}
    • - Slack Group + {t('about.slack')}
    • - Twitter Account + {t('about.twitter')}
    • - Facebook Group + {t('about.facebook')}
    • - Reddit + {t('about.reddit')}
    diff --git a/src/components/PreferencesModal/BillingTab.tsx b/src/components/PreferencesModal/BillingTab.tsx index fa56541509..475ca031e0 100644 --- a/src/components/PreferencesModal/BillingTab.tsx +++ b/src/components/PreferencesModal/BillingTab.tsx @@ -11,6 +11,7 @@ import { usePreferences } from '../../lib/preferences' import { getSubscription, Subscription } from '../../lib/accounts' import LoginButton from '../atoms/LoginButton' import { openNew } from '../../lib/utils/platform' +import { useTranslation } from 'react-i18next' const BillingContent = styled.div` .billing-lead { @@ -66,37 +67,43 @@ const BillingTab = () => { const loggedIn = user != null const hasSubscription = subscription != null + const { t } = useTranslation() + return (
    - Billing + {t('billing.billing')} {!loggedIn && (
    -

    Please sign in to upgrade your plan.

    +

    {t('billing.message')}

    )} - Basic + {t('billing.basic')} $0 {!hasSubscription && ( - Current + {t('billing.current')} )} - Premium - $3/Month (USD) * + {t('billing.premium')} + {t('billing.price')} {!loggedIn && ( - Sign In + {t('general.signin')} )} {loggedIn && ( - openNew('https://note.boostio.co/subscription')}> + + openNew('https://note.boostio.co/subscription') + } + > {hasSubscription ? 'Manage' : 'Upgrade'} )} @@ -104,37 +111,37 @@ const BillingTab = () => { - Web App + {t('billing.browser')} 〇 〇 - Desktop App (Mac/Windows/Linux) + {t('billing.desktop')} 〇 〇 - Mobile App (Will be launched at Jan, 2020) + {t('billing.mobile')} 〇 〇 - Syncing Multiple Devices + {t('billing.sync')} 〇 〇 - Local Storage + {t('billing.local')} 〇 〇 - Cloud Storage + {t('billing.cloud')} 〇 〇 - Cloud Storage Size + {t('billing.storageSize')} 100MB 2GB @@ -142,12 +149,12 @@ const BillingTab = () => { {loggedIn && (
    -

    - * If you need more cloud storage, you can add it at any time by - paying $5 (USD) for every 5GB. Click the "Add Extra Storage" - button below. -

    - openNew('https://note.boostio.co/subscription')}>Add Extra Storage +

    {t('billing.addStorageDescription')}

    + openNew('https://note.boostio.co/subscription')} + > + {t('billing.addStorage')} +
    )}
    diff --git a/src/components/PreferencesModal/ImportTab.tsx b/src/components/PreferencesModal/ImportTab.tsx index 3a54c90364..dd45f664ba 100644 --- a/src/components/PreferencesModal/ImportTab.tsx +++ b/src/components/PreferencesModal/ImportTab.tsx @@ -22,6 +22,7 @@ import { textColor } from '../../lib/styled/styleFunctions' import { useToast } from '../../lib/toast' +import { useTranslation } from 'react-i18next' interface Success { err: false @@ -54,6 +55,8 @@ const StyledRemove = styled.span` color: ${({ theme }) => theme.primaryColor}; ` +const { t } = useTranslation() + export default () => { const { pushMessage } = useToast() const { storageMap, createNote } = useDb() @@ -168,14 +171,12 @@ export default () => { return (
    - Import -

    Import .cson files from old Boostnote.

    -

    1. Open old Boostnote folder in your PC.

    -

    2. Drag and drop .cson files to the form below.

    -

    - 3. Choose the Storage and Folder that you want to move your old data. -

    -

    4. Upload!

    + {t('preferences.import')} +

    {t('preferences.description')}

    +

    {t('preferences.importFlow1')}

    +

    {t('preferences.importFlow2')}

    +

    {t('preferences.importFlow3')}

    +

    {t('preferences.importFlow4')}

    { ? `Invalid File: ${entry.filename}` : `Ready to import: ${entry.note.title}`} importRemoveCallback(id)}> - remove + {t('preferences.importRemove')} ) @@ -226,7 +227,7 @@ export default () => { - Upload + {t('preferences.importUpload')}
    ) diff --git a/src/components/PreferencesModal/MarkdownTab.tsx b/src/components/PreferencesModal/MarkdownTab.tsx index 6175fff482..922a5cae42 100644 --- a/src/components/PreferencesModal/MarkdownTab.tsx +++ b/src/components/PreferencesModal/MarkdownTab.tsx @@ -88,10 +88,10 @@ const MarkdownTab = () => { {t('preferences.previewStyle')} - Save + {t('general.save')} - Use default style + {t('preferences.defaultTheme')} @@ -109,7 +109,7 @@ const MarkdownTab = () => { value={preferences['markdown.codeBlockTheme']} onChange={selectCodeFenceTheme} > - + {themes.map(theme => (
    - Markdown Preview + {t('preferences.markdownPreview')}
    { return null } + const { t } = useTranslation() + return ( -
    Preferences
    +
    {t('preferences.general')}
    (

    {user.name}

    signout(user)}> - Sign Out + {t('general.signOut')}
    ) diff --git a/src/components/SideNavigator/FolderListFragment.tsx b/src/components/SideNavigator/FolderListFragment.tsx index 7f4b573c70..306467754c 100644 --- a/src/components/SideNavigator/FolderListFragment.tsx +++ b/src/components/SideNavigator/FolderListFragment.tsx @@ -10,6 +10,7 @@ import ControlButton from './ControlButton' import { getFolderItemId } from '../../lib/nav' import { getTransferrableNoteData } from '../../lib/dnd' import { IconAddRound, IconBook, IconFile, IconFileOpen } from '../icons' +import { useTranslation } from 'react-i18next' interface FolderListFragmentProps { storage: NoteStorage @@ -17,6 +18,8 @@ interface FolderListFragmentProps { showPromptToRenameFolder: (folderPathname: string) => void } +const { t } = useTranslation() + const FolderListFragment = ({ storage, showPromptToCreateFolder, @@ -63,14 +66,14 @@ const FolderListFragment = ({ popup(event, [ { type: MenuTypes.Normal, - label: 'New Folder', + label: t('folder.create'), onClick: async () => { showPromptToCreateFolder(folderPathname) } }, { type: MenuTypes.Normal, - label: 'Rename Folder', + label: t('folder.rename'), enabled: folderPathname !== '/', onClick: async () => { showPromptToRenameFolder(folderPathname) @@ -78,14 +81,14 @@ const FolderListFragment = ({ }, { type: MenuTypes.Normal, - label: 'Remove Folder', + label: t('folder.remove'), enabled: folderPathname !== '/', onClick: () => { messageBox({ title: `Remove "${folderPathname}" folder`, - message: 'All notes and subfolders will be deleted.', + message: t('folder.removeMessage'), iconType: DialogIconTypes.Warning, - buttons: ['Remove Folder', 'Cancel'], + buttons: [t('folder.remove'), t('general.cancel')], defaultButtonIndex: 0, cancelButtonIndex: 1, onClose: (value: number | null) => { @@ -143,10 +146,10 @@ const FolderListFragment = ({ }) } else { messageBox({ - title: 'Move Note to Other storage', - message: 'You are trying to move a note to different storage.', + title: t('storage.moveTitle'), + message: t('storage.moveMessage'), iconType: DialogIconTypes.Info, - buttons: ['Move Note', 'Copy Note', 'Cancel'], + buttons: [t('storage.move'), t('storage.copy'), t('general.cancel')], defaultButtonIndex: 0, cancelButtonIndex: 2, onClose: async (value: number | null) => { @@ -174,12 +177,13 @@ const FolderListFragment = ({ } } } + return ( <> diff --git a/src/components/SideNavigator/SideNavigator.tsx b/src/components/SideNavigator/SideNavigator.tsx index fb517fd684..f945ca9f03 100644 --- a/src/components/SideNavigator/SideNavigator.tsx +++ b/src/components/SideNavigator/SideNavigator.tsx @@ -20,6 +20,7 @@ import TagListFragment from './TagListFragment' import TutorialsNavigator from '../Tutorials/TutorialsNavigator' import { useUsers } from '../../lib/accounts' import { useToast } from '../../lib/toast' +import { useTranslation } from 'react-i18next' import { IconAddRound, IconAdjustVertical, @@ -172,6 +173,8 @@ export default () => { const currentPathname = usePathnameWithoutNoteId() + const { t } = useTranslation() + return (
    @@ -235,12 +238,11 @@ export default () => { } const showPromptToRenameFolder = (folderPathname: string) => { prompt({ - title: 'Rename the Folder', - message: - 'Enter the new folder name, every note and subfolder paths will also be updated.', + title: t('folder.rename'), + message: t('folder.renameMessage'), iconType: DialogIconTypes.Question, defaultValue: folderPathname.split('/').pop(), - submitButtonLabel: 'Rename Folder', + submitButtonLabel: t('folder.rename'), onClose: async (value: string | null) => { const folderPathSplit = folderPathname.split('/') if ( @@ -257,8 +259,8 @@ export default () => { openSideNavFolderItemRecursively(storage.id, newPathname) } catch (error) { pushMessage({ - title: 'Error', - description: 'You could not rename the folder' + title: t('general.error'), + description: t('folder.renameErrorMessage') }) } } @@ -323,14 +325,14 @@ export default () => { popup(event, [ { type: MenuTypes.Normal, - label: 'Rename Storage', + label: t('storage.rename'), onClick: async () => { prompt({ title: `Rename "${storage.name}" storage`, - message: 'Enter new storage name', + message: t('storage.renameMessage'), iconType: DialogIconTypes.Question, defaultValue: storage.name, - submitButtonLabel: 'Rename Storage', + submitButtonLabel: t('storage.rename'), onClose: async (value: string | null) => { if (value == null) return await renameStorage(storage.id, value) @@ -340,14 +342,13 @@ export default () => { }, { type: MenuTypes.Normal, - label: 'Remove Storage', + label: t('storage.remove'), onClick: async () => { messageBox({ title: `Remove "${storage.name}" storage`, - message: - 'The storage will be unlinked from this app.', + message: t('storage.removeMessage'), iconType: DialogIconTypes.Warning, - buttons: ['Remove Storage', 'Cancel'], + buttons: [t('storage.remove'), t('general.cancel')], defaultButtonIndex: 0, cancelButtonIndex: 1, onClose: (value: number | null) => { @@ -372,7 +373,7 @@ export default () => { @@ -388,7 +389,7 @@ export default () => { /> : } active={trashcanPageIsActive} onClick={() => push(trashcanPagePathname)} @@ -403,7 +404,7 @@ export default () => { ) })} {storageEntries.length === 0 && ( -
    No storages
    +
    {t('storage.noStorage')}
    )} {preferences['general.tutorials'] === 'display' && ( diff --git a/src/components/SideNavigator/TagListFragment.tsx b/src/components/SideNavigator/TagListFragment.tsx index f9fe0a1793..39a2938278 100644 --- a/src/components/SideNavigator/TagListFragment.tsx +++ b/src/components/SideNavigator/TagListFragment.tsx @@ -8,11 +8,14 @@ import { useContextMenu, MenuTypes } from '../../lib/contextMenu' import { useDialog, DialogIconTypes } from '../../lib/dialog' import { useDb } from '../../lib/db' import { IconTag, IconTags, IconTagFill } from '../icons' +import { useTranslation } from 'react-i18next' interface TagListFragmentProps { storage: NoteStorage } +const { t } = useTranslation() + const TagListFragment = ({ storage }: TagListFragmentProps) => { const { toggleSideNavOpenedItem, sideNavOpenedItemSet } = useGeneralStatus() const { id: storageId, tagMap } = storage @@ -44,13 +47,13 @@ const TagListFragment = ({ storage }: TagListFragmentProps) => { popup(event, [ { type: MenuTypes.Normal, - label: 'Remove Tag', + label: t('tag.remove'), onClick: () => { messageBox({ title: `Remove "${tagName}" tag`, - message: 'The tag will be untagged from all notes.', + message: t('tag.removeMessage'), iconType: DialogIconTypes.Warning, - buttons: ['Remove Folder', 'Cancel'], + buttons: [t('tag.removeMessage'), t('general.cancel')], defaultButtonIndex: 0, cancelButtonIndex: 1, onClose: (value: number | null) => { @@ -73,7 +76,7 @@ const TagListFragment = ({ storage }: TagListFragmentProps) => { } - label='Tags' + label={t('tag.tag')} folded={tagList.length > 0 ? tagListIsFolded : undefined} onFoldButtonClick={() => { toggleSideNavOpenedItem(tagListNavItemId) diff --git a/src/components/Storage/StorageCreate.tsx b/src/components/Storage/StorageCreate.tsx index bfb8a9883d..d2745728a5 100644 --- a/src/components/Storage/StorageCreate.tsx +++ b/src/components/Storage/StorageCreate.tsx @@ -46,7 +46,7 @@ export default () => { {t('Create new storage')} - + { checked={storageType === 'cloud'} onChange={() => setStorageType('cloud')} /> - Cloud + {t('storage.typeCloud')} {(storageType === 'local' || isLoggedIn) && ( <> createStorageCallback()}> - Create Storage + {t('storage.create')} @@ -86,7 +86,7 @@ export default () => { {!isLoggedIn && storageType === 'cloud' && ( <> -

    You need to sign in to create a cloud storage.

    +

    {t('storage.needSignIn')}

    { const db = useDb() const router = useRouter() + const { t } = useTranslation() const [name, setName] = useState(storage.name) const { messageBox } = useDialog() const { pushMessage } = useToast() @@ -31,9 +33,9 @@ export default ({ storage }: StorageEditProps) => { const removeCallback = useCallback(() => { messageBox({ title: `Remove "${storage.name}" storage`, - message: 'The storage will be unlinked from this app.', + message: t('storage.removeMessage'), iconType: DialogIconTypes.Warning, - buttons: ['Remove Storage', 'Cancel'], + buttons: [t('storage.remove'), t('general.cancel')], defaultButtonIndex: 0, cancelButtonIndex: 1, onClose: async (value: number | null) => { @@ -43,7 +45,7 @@ export default ({ storage }: StorageEditProps) => { router.push('/app') } catch { pushMessage({ - title: 'Network Error', + title: t('general.networkError'), description: `An error occurred while deleting storage (id: ${storage.id})` }) } @@ -56,7 +58,7 @@ export default ({ storage }: StorageEditProps) => { () => { db.renameStorage(storage.id, name).catch(() => { pushMessage({ - title: 'Network Error', + title: t('general.networkError'), description: `An error occured while updating storage (id:${storage.id}}` }) }) @@ -68,11 +70,11 @@ export default ({ storage }: StorageEditProps) => { return (
    - Edit Storage + {t('storage.edit')}
    - Delete Storage + {t('storage.delete')}
    {isCloudStorageData(storage) && (

    - Last synced at + {t('storage.syncDate')} {new Date(storage.cloudStorage.updatedAt).toLocaleString()}

    diff --git a/src/components/Tutorials/TutorialsNoteDetail.tsx b/src/components/Tutorials/TutorialsNoteDetail.tsx index 0d7f39d41e..24093fb146 100644 --- a/src/components/Tutorials/TutorialsNoteDetail.tsx +++ b/src/components/Tutorials/TutorialsNoteDetail.tsx @@ -8,6 +8,7 @@ import { TutorialsNavigatorTreeItem } from '../../lib/tutorials' import { StyledNoteDetailContainer } from '../NotePage/NoteDetail/NoteDetail' import { ViewModeType } from '../../lib/generalStatus' import { IconEye, IconSplit, IconEdit } from '../icons' +import { useTranslation } from 'react-i18next' type TutorialsNoteDetailProps = { note: TutorialsNavigatorTreeItem @@ -79,10 +80,12 @@ export default class TutorialsNoteDetail extends React.Component< ) + const { t } = useTranslation() + return ( {note == null ? ( -

    No note is selected

    +

    {t('note.unselect')}

    ) : ( <>
    diff --git a/src/components/Tutorials/TutorialsNoteList.tsx b/src/components/Tutorials/TutorialsNoteList.tsx index 623398cf57..b552f0a632 100644 --- a/src/components/Tutorials/TutorialsNoteList.tsx +++ b/src/components/Tutorials/TutorialsNoteList.tsx @@ -2,6 +2,7 @@ import React, { useCallback, KeyboardEvent, useRef } from 'react' import { TutorialsNavigatorTreeItem } from '../../lib/tutorials' import TutorialsNoteItem from './TutorialsNoteItem' import { StyledNoteListContainer } from '../NotePage/NoteList/NoteList' +import { useTranslation } from 'react-i18next' type TutorialsNoteListProps = { currentTree: TutorialsNavigatorTreeItem @@ -47,6 +48,8 @@ const TutorialsNoteList = ({ ? [] : parentTree.children.filter(child => child.type === 'note') + const { t } = useTranslation() + return (
      @@ -65,7 +68,7 @@ const TutorialsNoteList = ({ ) })} - {notes.length === 0 &&
    • No notes
    • } + {notes.length === 0 &&
    • {t('note.nothing')}
    • }
    ) diff --git a/src/components/Tutorials/TutorialsPage.tsx b/src/components/Tutorials/TutorialsPage.tsx index acec69903d..d30ce87997 100644 --- a/src/components/Tutorials/TutorialsPage.tsx +++ b/src/components/Tutorials/TutorialsPage.tsx @@ -5,6 +5,7 @@ import { useGeneralStatus, ViewModeType } from '../../lib/generalStatus' import { useRouter } from '../../lib/router' import TutorialsNoteList from './TutorialsNoteList' import TutorialsNoteDetail from './TutorialsNoteDetail' +import { useTranslation } from 'react-i18next' interface TutorialsPageProps { pathname: string @@ -18,7 +19,7 @@ type TutoriasPagePicker = { export default ({ pathname }: TutorialsPageProps) => { const { generalStatus, setGeneralStatus } = useGeneralStatus() const router = useRouter() - + const { t } = useTranslation() const searchThroughTreeForIdenticalNode = useCallback( ( pathToSearch: string, @@ -241,7 +242,7 @@ export default ({ pathname }: TutorialsPageProps) => { } right={ selectedNote == null ? ( -
    No note selected
    +
    {t('note.unselect')}
    ) : (