Added Bootstrap and Vue I18N; added header and footer components; added language switcher
This commit is contained in:
@@ -2,5 +2,7 @@
|
|||||||
"$schema": "https://json.schemastore.org/prettierrc",
|
"$schema": "https://json.schemastore.org/prettierrc",
|
||||||
"semi": false,
|
"semi": false,
|
||||||
"singleQuote": true,
|
"singleQuote": true,
|
||||||
"printWidth": 100
|
"printWidth": 100,
|
||||||
|
"useTabs": true,
|
||||||
|
"tabWidth": 4
|
||||||
}
|
}
|
||||||
|
|||||||
66
README.md
66
README.md
@@ -1,6 +1,22 @@
|
|||||||
# glossary_admin_client
|
# NATO Glossary, Admin Client
|
||||||
|
|
||||||
This template should help get you started developing with Vue 3 in Vite.
|
This is the repo for the admin client of the NATO Glossary project. This README will explain all basic commands for running, developing, testing, and building the app.
|
||||||
|
|
||||||
|
## Stack
|
||||||
|
|
||||||
|
- [Vue 3](https://vuejs.org/) + [Vite](https://vite.dev/)
|
||||||
|
- [TypeScript](https://www.typescriptlang.org/)
|
||||||
|
- [Bootstrap](https://getbootstrap.com/) for UI and styling
|
||||||
|
- [Vue I18N](https://vue-i18n.intlify.dev/) for multi-language options
|
||||||
|
- [Pinia](https://pinia.vuejs.org/) for state management
|
||||||
|
- [Vitest](https://vitest.dev/) for unit testing
|
||||||
|
- [Playwright](https://playwright.dev/) for end-to-end (e2e) testing
|
||||||
|
- [ESLint](https://eslint.org/) for code linting
|
||||||
|
- [Prettier](https://prettier.io/) for code formatting
|
||||||
|
|
||||||
|
## File Structure
|
||||||
|
|
||||||
|
Given the small scope of this project, we're beginning with a [Flat Structure](https://alexop.dev/posts/how-to-structure-vue-projects/#1-flat-structure-perfect-for-small-projects) to organize the files.
|
||||||
|
|
||||||
## Recommended IDE Setup
|
## Recommended IDE Setup
|
||||||
|
|
||||||
@@ -17,30 +33,36 @@ This template should help get you started developing with Vue 3 in Vite.
|
|||||||
|
|
||||||
## Type Support for `.vue` Imports in TS
|
## Type Support for `.vue` Imports in TS
|
||||||
|
|
||||||
TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) to make the TypeScript language service aware of `.vue` types.
|
TypeScript cannot handle type information for `.vue` imports by default, so we replace the `tsc` CLI with `vue-tsc` for type checking. In editors, we need [Vue (Official)](https://marketplace.visualstudio.com/items?itemName=Vue.volar) to make the TypeScript language service aware of `.vue` types.
|
||||||
|
|
||||||
## Customize configuration
|
## Customize configuration
|
||||||
|
|
||||||
See [Vite Configuration Reference](https://vite.dev/config/).
|
See [Vite Configuration Reference](https://vite.dev/config/).
|
||||||
|
|
||||||
## Project Setup
|
## First-Time Setup
|
||||||
|
|
||||||
```sh
|
Install dependencies:
|
||||||
|
|
||||||
|
```bash
|
||||||
npm install
|
npm install
|
||||||
```
|
```
|
||||||
|
|
||||||
### Compile and Hot-Reload for Development
|
## Development Environment
|
||||||
|
|
||||||
```sh
|
To properly run on and test this application, you'll need the following pieces to be running:
|
||||||
|
|
||||||
|
- Development Server (the web app)
|
||||||
|
- Local Database (a dev database that provides dummy data to testing)
|
||||||
|
- Development API (the API that serves the dummy data from the database to the web app)
|
||||||
|
|
||||||
|
### Development Server
|
||||||
|
|
||||||
|
Start the development server on `http://localhost:3000`:
|
||||||
|
|
||||||
|
```bash
|
||||||
npm run dev
|
npm run dev
|
||||||
```
|
```
|
||||||
|
|
||||||
### Type-Check, Compile and Minify for Production
|
|
||||||
|
|
||||||
```sh
|
|
||||||
npm run build
|
|
||||||
```
|
|
||||||
|
|
||||||
### Run Unit Tests with [Vitest](https://vitest.dev/)
|
### Run Unit Tests with [Vitest](https://vitest.dev/)
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
@@ -71,3 +93,21 @@ npm run test:e2e -- --debug
|
|||||||
```sh
|
```sh
|
||||||
npm run lint
|
npm run lint
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Production
|
||||||
|
|
||||||
|
Build the application for production:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# npm
|
||||||
|
npm run build
|
||||||
|
```
|
||||||
|
|
||||||
|
Locally preview production build:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# npm
|
||||||
|
npm run preview
|
||||||
|
```
|
||||||
|
|
||||||
|
Check out the [deployment documentation](https://nuxt.com/docs/getting-started/deployment) for more information.
|
||||||
130
package-lock.json
generated
130
package-lock.json
generated
@@ -8,8 +8,11 @@
|
|||||||
"name": "glossary_admin_client",
|
"name": "glossary_admin_client",
|
||||||
"version": "0.0.0",
|
"version": "0.0.0",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"bootstrap": "^5.3.8",
|
||||||
|
"bootstrap-vue-next": "^0.42.0",
|
||||||
"pinia": "^3.0.4",
|
"pinia": "^3.0.4",
|
||||||
"vue": "^3.5.26",
|
"vue": "^3.5.26",
|
||||||
|
"vue-i18n": "^11.2.8",
|
||||||
"vue-router": "^4.6.4"
|
"vue-router": "^4.6.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
@@ -1403,6 +1406,50 @@
|
|||||||
"url": "https://github.com/sponsors/nzakas"
|
"url": "https://github.com/sponsors/nzakas"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@intlify/core-base": {
|
||||||
|
"version": "11.2.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/@intlify/core-base/-/core-base-11.2.8.tgz",
|
||||||
|
"integrity": "sha512-nBq6Y1tVkjIUsLsdOjDSJj4AsjvD0UG3zsg9Fyc+OivwlA/oMHSKooUy9tpKj0HqZ+NWFifweHavdljlBLTwdA==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@intlify/message-compiler": "11.2.8",
|
||||||
|
"@intlify/shared": "11.2.8"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 16"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/kazupon"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@intlify/message-compiler": {
|
||||||
|
"version": "11.2.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/@intlify/message-compiler/-/message-compiler-11.2.8.tgz",
|
||||||
|
"integrity": "sha512-A5n33doOjmHsBtCN421386cG1tWp5rpOjOYPNsnpjIJbQ4POF0QY2ezhZR9kr0boKwaHjbOifvyQvHj2UTrDFQ==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@intlify/shared": "11.2.8",
|
||||||
|
"source-map-js": "^1.0.2"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 16"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/kazupon"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/@intlify/shared": {
|
||||||
|
"version": "11.2.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/@intlify/shared/-/shared-11.2.8.tgz",
|
||||||
|
"integrity": "sha512-l6e4NZyUgv8VyXXH4DbuucFOBmxLF56C/mqh2tvApbzl2Hrhi1aTDcuv5TKdxzfHYmpO3UB0Cz04fgDT9vszfw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 16"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/kazupon"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@isaacs/cliui": {
|
"node_modules/@isaacs/cliui": {
|
||||||
"version": "8.0.2",
|
"version": "8.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
|
||||||
@@ -1562,6 +1609,17 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/@popperjs/core": {
|
||||||
|
"version": "2.11.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/@popperjs/core/-/core-2.11.8.tgz",
|
||||||
|
"integrity": "sha512-P1st0aksCrn9sGZhp8GMYwBnQsbvAWsZAX44oXNNvLHGqAOcoVxmjZiohstwQ7SqKnbR47akdNi+uleWD8+g6A==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peer": true,
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/popperjs"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@rolldown/pluginutils": {
|
"node_modules/@rolldown/pluginutils": {
|
||||||
"version": "1.0.0-beta.53",
|
"version": "1.0.0-beta.53",
|
||||||
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.53.tgz",
|
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.53.tgz",
|
||||||
@@ -2965,6 +3023,52 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "ISC"
|
"license": "ISC"
|
||||||
},
|
},
|
||||||
|
"node_modules/bootstrap": {
|
||||||
|
"version": "5.3.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/bootstrap/-/bootstrap-5.3.8.tgz",
|
||||||
|
"integrity": "sha512-HP1SZDqaLDPwsNiqRqi5NcP0SSXciX2s9E+RyqJIIqGo+vJeN5AJVM98CXmW/Wux0nQ5L7jeWUdplCEf0Ee+tg==",
|
||||||
|
"funding": [
|
||||||
|
{
|
||||||
|
"type": "github",
|
||||||
|
"url": "https://github.com/sponsors/twbs"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/bootstrap"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"@popperjs/core": "^2.11.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/bootstrap-vue-next": {
|
||||||
|
"version": "0.42.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/bootstrap-vue-next/-/bootstrap-vue-next-0.42.0.tgz",
|
||||||
|
"integrity": "sha512-CSkk2jL8Y2U9zgdutxjbBx4DRhKFmxTmaTQhhMYXVvczkVksw2mzRu1MU//950z0lvUwSqJo3R7y0opoyEA8zg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/bootstrap-vue-next"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@floating-ui/vue": "*",
|
||||||
|
"@vueuse/core": "*",
|
||||||
|
"vue": "^3.5.13",
|
||||||
|
"vue-router": "*"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@floating-ui/vue": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"@vueuse/core": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"vue-router": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/brace-expansion": {
|
"node_modules/brace-expansion": {
|
||||||
"version": "2.0.2",
|
"version": "2.0.2",
|
||||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
|
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.2.tgz",
|
||||||
@@ -6293,6 +6397,32 @@
|
|||||||
"url": "https://opencollective.com/eslint"
|
"url": "https://opencollective.com/eslint"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/vue-i18n": {
|
||||||
|
"version": "11.2.8",
|
||||||
|
"resolved": "https://registry.npmjs.org/vue-i18n/-/vue-i18n-11.2.8.tgz",
|
||||||
|
"integrity": "sha512-vJ123v/PXCZntd6Qj5Jumy7UBmIuE92VrtdX+AXr+1WzdBHojiBxnAxdfctUFL+/JIN+VQH4BhsfTtiGsvVObg==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@intlify/core-base": "11.2.8",
|
||||||
|
"@intlify/shared": "11.2.8",
|
||||||
|
"@vue/devtools-api": "^6.5.0"
|
||||||
|
},
|
||||||
|
"engines": {
|
||||||
|
"node": ">= 16"
|
||||||
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://github.com/sponsors/kazupon"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"vue": "^3.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"node_modules/vue-i18n/node_modules/@vue/devtools-api": {
|
||||||
|
"version": "6.6.4",
|
||||||
|
"resolved": "https://registry.npmjs.org/@vue/devtools-api/-/devtools-api-6.6.4.tgz",
|
||||||
|
"integrity": "sha512-sGhTPMuXqZ1rVOk32RylztWkfXTRhuS7vgAKv0zjqk8gbsHkJ7xfFf+jbySxt7tWObEJwyKaHMikV/WGDiQm8g==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/vue-router": {
|
"node_modules/vue-router": {
|
||||||
"version": "4.6.4",
|
"version": "4.6.4",
|
||||||
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.6.4.tgz",
|
"resolved": "https://registry.npmjs.org/vue-router/-/vue-router-4.6.4.tgz",
|
||||||
|
|||||||
@@ -18,8 +18,11 @@
|
|||||||
"format": "prettier --write --experimental-cli src/"
|
"format": "prettier --write --experimental-cli src/"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
|
"bootstrap": "^5.3.8",
|
||||||
|
"bootstrap-vue-next": "^0.42.0",
|
||||||
"pinia": "^3.0.4",
|
"pinia": "^3.0.4",
|
||||||
"vue": "^3.5.26",
|
"vue": "^3.5.26",
|
||||||
|
"vue-i18n": "^11.2.8",
|
||||||
"vue-router": "^4.6.4"
|
"vue-router": "^4.6.4"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
|||||||
12
src/App.vue
12
src/App.vue
@@ -1,11 +1,11 @@
|
|||||||
<script setup lang="ts"></script>
|
<script setup lang="ts">
|
||||||
|
import { BApp } from 'bootstrap-vue-next'
|
||||||
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<h1>You did it!</h1>
|
<BApp>
|
||||||
<p>
|
<RouterView />
|
||||||
Visit <a href="https://vuejs.org/" target="_blank" rel="noopener">vuejs.org</a> to read the
|
</BApp>
|
||||||
documentation
|
|
||||||
</p>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped></style>
|
<style scoped></style>
|
||||||
|
|||||||
11
src/components/AppFooter.vue
Normal file
11
src/components/AppFooter.vue
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import { BContainer } from 'bootstrap-vue-next';
|
||||||
|
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<!-- <div class="bg-dark text-white text-center py-3 fixed-bottom">Footer</div> -->
|
||||||
|
<BContainer fluid class="bg-dark text-white fixed-bottom py-3">
|
||||||
|
Footer
|
||||||
|
</BContainer>
|
||||||
|
</template>
|
||||||
64
src/components/AppHeader.vue
Normal file
64
src/components/AppHeader.vue
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import {
|
||||||
|
BButton,
|
||||||
|
BCollapse,
|
||||||
|
BDropdownItem,
|
||||||
|
BNavbar,
|
||||||
|
BNavbarBrand,
|
||||||
|
BNavbarNav,
|
||||||
|
BNavbarToggle,
|
||||||
|
BNavItem,
|
||||||
|
BNavItemDropdown,
|
||||||
|
vBColorMode
|
||||||
|
} from 'bootstrap-vue-next'
|
||||||
|
import { useI18n } from 'vue-i18n'
|
||||||
|
|
||||||
|
// use global scope
|
||||||
|
const { t } = useI18n({
|
||||||
|
useScope: 'global',
|
||||||
|
inheritLocale: true,
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<b-navbar v-b-color-mode="'dark'" toggleable="lg" variant="primary">
|
||||||
|
<b-navbar-brand>{{ t('navbar.natoGlossary') }}</b-navbar-brand>
|
||||||
|
<b-navbar-toggle target="nav-collapse" />
|
||||||
|
<b-collapse id="nav-collapse" is-nav>
|
||||||
|
<b-navbar-nav>
|
||||||
|
<b-nav-item href="#">
|
||||||
|
<RouterLink
|
||||||
|
:to="{ name: 'Home' }"
|
||||||
|
class="nav-link active"
|
||||||
|
aria-current="page"
|
||||||
|
href="#"
|
||||||
|
>{{ t('navbar.home') }}</RouterLink
|
||||||
|
>
|
||||||
|
</b-nav-item>
|
||||||
|
<b-nav-item href="#">
|
||||||
|
<RouterLink
|
||||||
|
:to="{ name: 'List' }"
|
||||||
|
class="nav-link active"
|
||||||
|
aria-current="page"
|
||||||
|
href="#"
|
||||||
|
>{{ t('navbar.list') }}</RouterLink
|
||||||
|
>
|
||||||
|
</b-nav-item>
|
||||||
|
</b-navbar-nav>
|
||||||
|
<!-- Right aligned nav items -->
|
||||||
|
<b-navbar-nav class="ms-auto mb-2 mb-lg-0">
|
||||||
|
<b-nav-item-dropdown text="Lang" right>
|
||||||
|
<b-dropdown-item
|
||||||
|
v-for="locale in $i18n.availableLocales"
|
||||||
|
:key="`locale-${locale}`"
|
||||||
|
v-on:click="$i18n.locale = locale"
|
||||||
|
>{{ locale }}</b-dropdown-item
|
||||||
|
>
|
||||||
|
</b-nav-item-dropdown>
|
||||||
|
</b-navbar-nav>
|
||||||
|
<b-button type="button">{{ t('navbar.login') }}</b-button>
|
||||||
|
</b-collapse>
|
||||||
|
</b-navbar>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="css" scoped></style>
|
||||||
14
src/layout/DefaultLayout.vue
Normal file
14
src/layout/DefaultLayout.vue
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
import AppHeader from '../components/AppHeader.vue'
|
||||||
|
import AppFooter from '../components/AppFooter.vue'
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<AppHeader />
|
||||||
|
<RouterView />
|
||||||
|
<AppFooter />
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="css" scoped></style>
|
||||||
12
src/locales/en.json
Normal file
12
src/locales/en.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"hello": "hello world!",
|
||||||
|
"errors": ["Error!"],
|
||||||
|
"navbar": {
|
||||||
|
"natoGlossary": "NATO GLossary",
|
||||||
|
"home": "Home",
|
||||||
|
"list": "List",
|
||||||
|
"language": "Language",
|
||||||
|
"logout": "logout",
|
||||||
|
"login": "login"
|
||||||
|
}
|
||||||
|
}
|
||||||
12
src/locales/fr.json
Normal file
12
src/locales/fr.json
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"hello": "bonjour monde !",
|
||||||
|
"errors": ["Erreur !"],
|
||||||
|
"navbar": {
|
||||||
|
"natoGlossary": "NATO GLossary",
|
||||||
|
"home": "Home",
|
||||||
|
"list": "Liste",
|
||||||
|
"language": "Language",
|
||||||
|
"logout": "se déconnecter",
|
||||||
|
"login": "se connecter"
|
||||||
|
}
|
||||||
|
}
|
||||||
44
src/main.ts
44
src/main.ts
@@ -1,12 +1,56 @@
|
|||||||
import { createApp } from 'vue'
|
import { createApp } from 'vue'
|
||||||
import { createPinia } from 'pinia'
|
import { createPinia } from 'pinia'
|
||||||
|
import { createI18n } from 'vue-i18n'
|
||||||
|
|
||||||
import App from './App.vue'
|
import App from './App.vue'
|
||||||
|
import 'bootstrap/dist/css/bootstrap.css'
|
||||||
|
import 'bootstrap-vue-next/dist/bootstrap-vue-next.css'
|
||||||
import router from './router'
|
import router from './router'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* import locale messages resource from json for global scope
|
||||||
|
*/
|
||||||
|
import en from './locales/en.json'
|
||||||
|
import fr from './locales/fr.json'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* setup vue-i18n with i18n resources with global type definition.
|
||||||
|
* The defined i18n resource schema in the `*.d.ts` file is checked with typeScript.
|
||||||
|
* You can check global type definition at `./vue-i18n.d.ts`.
|
||||||
|
*/
|
||||||
|
const i18n = createI18n({
|
||||||
|
locale: 'en',
|
||||||
|
fallbackLocale: 'fr',
|
||||||
|
messages: {
|
||||||
|
en: en,
|
||||||
|
fr: fr,
|
||||||
|
},
|
||||||
|
// datetimeFormats: {
|
||||||
|
// 'en': {
|
||||||
|
// short: {
|
||||||
|
// hour: 'numeric',
|
||||||
|
// minute: 'numeric',
|
||||||
|
// second: 'numeric',
|
||||||
|
// timeZoneName: 'short',
|
||||||
|
// timezone: 'America/Montreal'
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// },
|
||||||
|
// numberFormats: {
|
||||||
|
// 'en': {
|
||||||
|
// currency: {
|
||||||
|
// style: 'currency',
|
||||||
|
// currencyDisplay: 'symbol',
|
||||||
|
// currency: 'CAD'
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
})
|
||||||
|
|
||||||
const app = createApp(App)
|
const app = createApp(App)
|
||||||
|
|
||||||
app.use(createPinia())
|
app.use(createPinia())
|
||||||
app.use(router)
|
app.use(router)
|
||||||
|
app.use(i18n)
|
||||||
|
|
||||||
app.mount('#app')
|
app.mount('#app')
|
||||||
|
|||||||
@@ -1,8 +1,30 @@
|
|||||||
import { createRouter, createWebHistory } from 'vue-router'
|
import { createRouter, createWebHistory } from 'vue-router'
|
||||||
|
import Home from '@/views/Home.vue'
|
||||||
|
import List from '@/views/List.vue'
|
||||||
|
|
||||||
|
import DefaultLayout from '@/layout/DefaultLayout.vue'
|
||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
history: createWebHistory(import.meta.env.BASE_URL),
|
history: createWebHistory(import.meta.env.BASE_URL),
|
||||||
routes: [],
|
routes: [
|
||||||
|
{
|
||||||
|
path: '/',
|
||||||
|
name: 'Public',
|
||||||
|
component: DefaultLayout,
|
||||||
|
children: [
|
||||||
|
{
|
||||||
|
path: '/',
|
||||||
|
name: 'Home',
|
||||||
|
component: Home,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
path: '/list',
|
||||||
|
name: 'List',
|
||||||
|
component: List,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
})
|
})
|
||||||
|
|
||||||
export default router
|
export default router
|
||||||
|
|||||||
7
src/views/Home.vue
Normal file
7
src/views/Home.vue
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<script setup lang="ts"></script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>This is Home</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="css" scoped></style>
|
||||||
8
src/views/List.vue
Normal file
8
src/views/List.vue
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
<script setup lang="ts">
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<template>
|
||||||
|
<div>This is List</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<style lang="css" scoped></style>
|
||||||
45
src/vue-i18n.d.ts
vendored
Normal file
45
src/vue-i18n.d.ts
vendored
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
/**
|
||||||
|
* global type definitions
|
||||||
|
* using the typescript interface, you can define the i18n resources that is type-safed!
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* you need to import the some interfaces
|
||||||
|
*/
|
||||||
|
import { DefineLocaleMessage, DefineDateTimeFormat, DefineNumberFormat } from 'vue-i18n'
|
||||||
|
|
||||||
|
declare module 'vue-i18n' {
|
||||||
|
// define the locale messages schema
|
||||||
|
export interface DefineLocaleMessage {
|
||||||
|
hello: string
|
||||||
|
errors: string[]
|
||||||
|
navbar: {
|
||||||
|
natoGlossary: string
|
||||||
|
home: string
|
||||||
|
list: string
|
||||||
|
language: string
|
||||||
|
logout: string
|
||||||
|
login: string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// // define the datetime format schema
|
||||||
|
// export interface DefineDateTimeFormat {
|
||||||
|
// short: {
|
||||||
|
// hour: 'numeric'
|
||||||
|
// minute: 'numeric'
|
||||||
|
// second: 'numeric'
|
||||||
|
// timeZoneName: 'short'
|
||||||
|
// timezone: string
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // define the number format schema
|
||||||
|
// export interface DefineNumberFormat {
|
||||||
|
// currency: {
|
||||||
|
// style: 'currency'
|
||||||
|
// currencyDisplay: 'symbol'
|
||||||
|
// currency: string
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user