Client - upgrade Vue to 3.3 and move to Vite

This commit is contained in:
Sam 2023-11-11 15:23:04 +01:00
parent 91455251e1
commit 1befae927d
309 changed files with 6291 additions and 12719 deletions

View File

@ -194,7 +194,7 @@ lint-client:
cd fittrackee_client && $(NPM) lint cd fittrackee_client && $(NPM) lint
lint-client-fix: lint-client-fix:
cd fittrackee_client && $(NPM) lint-fix cd fittrackee_client && $(NPM) format
lint-python: lint-python:
$(PYTEST) --isort --black -m "isort or black" fittrackee e2e --ignore=fittrackee/migrations $(PYTEST) --isort --black -m "isort or black" fittrackee e2e --ignore=fittrackee/migrations
@ -233,7 +233,7 @@ serve-dev:
serve-client: serve-client:
# for dev environments # for dev environments
cd fittrackee_client && PORT=3000 $(NPM) serve cd fittrackee_client && PORT=3000 $(NPM) dev
serve-python: serve-python:
# for dev environments # for dev environments
@ -269,6 +269,9 @@ type-check:
echo 'Running mypy...' echo 'Running mypy...'
$(MYPY) fittrackee $(MYPY) fittrackee
type-check-client:
cd fittrackee_client && $(NPM) type-check
upgrade-db: upgrade-db:
$(FTCLI) db upgrade $(FTCLI) db upgrade

View File

@ -1,2 +1,2 @@
VUE_APP_API_URL=http://localhost:5000 VITE_APP_API_URL=http://localhost:5000
PORT=3000 PORT=3000

View File

@ -0,0 +1,18 @@
/* eslint-env node */
require('@rushstack/eslint-patch/modern-module-resolution')
module.exports = {
root: true,
'extends': [
'plugin:vue/vue3-essential',
'eslint:recommended',
'@vue/eslint-config-typescript',
'@vue/eslint-config-prettier/skip-formatting'
],
parserOptions: {
ecmaVersion: 'latest'
},
"rules": {
"vue/multi-word-component-names": "off"
}
}

28
fittrackee_client/.gitignore vendored Normal file
View File

@ -0,0 +1,28 @@
# Logs
logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
pnpm-debug.log*
lerna-debug.log*
node_modules
.DS_Store
dist
dist-ssr
coverage
*.local
/cypress/videos/
/cypress/screenshots/
# Editor directories and files
.vscode/*
!.vscode/extensions.json
.idea
*.suo
*.ntvs*
*.njsproj
*.sln
*.sw?

View File

@ -1,4 +1,5 @@
{ {
"$schema": "https://json.schemastore.org/prettierrc",
"tabWidth": 2, "tabWidth": 2,
"semi": false, "semi": false,
"singleQuote": true, "singleQuote": true,

View File

@ -1,29 +1,46 @@
# fittrackee_client # fittrackee_client
## Project setup This template should help get you started developing with Vue 3 in Vite.
```
yarn install ## Recommended IDE Setup
[VSCode](https://code.visualstudio.com/) + [Volar](https://marketplace.visualstudio.com/items?itemName=Vue.volar) (and disable Vetur) + [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin).
## 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 [TypeScript Vue Plugin (Volar)](https://marketplace.visualstudio.com/items?itemName=Vue.vscode-typescript-vue-plugin) to make the TypeScript language service aware of `.vue` types.
If the standalone TypeScript plugin doesn't feel fast enough to you, Volar has also implemented a [Take Over Mode](https://github.com/johnsoncodehk/volar/discussions/471#discussioncomment-1361669) that is more performant. You can enable it by the following steps:
1. Disable the built-in TypeScript Extension
1) Run `Extensions: Show Built-in Extensions` from VSCode's command palette
2) Find `TypeScript and JavaScript Language Features`, right click and select `Disable (Workspace)`
2. Reload the VSCode window by running `Developer: Reload Window` from the command palette.
## Customize configuration
See [Vite Configuration Reference](https://vitejs.dev/config/).
## Project Setup
```sh
yarn
``` ```
### Compiles and hot-reloads for development ### Compile and Hot-Reload for Development
```
yarn serve ```sh
yarn dev
``` ```
### Compiles and minifies for production ### Type-Check, Compile and Minify for Production
```
```sh
yarn build yarn build
``` ```
### Run your unit tests ### Lint with [ESLint](https://eslint.org/)
```
yarn test:unit
```
### Lints and fixes files ```sh
```
yarn lint yarn lint
``` ```
### Customize configuration
See [Configuration Reference](https://cli.vuejs.org/config/).

View File

@ -1,3 +0,0 @@
module.exports = {
presets: ['@vue/cli-plugin-babel/preset'],
}

1
fittrackee_client/env.d.ts vendored Normal file
View File

@ -0,0 +1 @@
/// <reference types="vite/client" />

View File

@ -0,0 +1,15 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<link rel="icon" href="/favicon.ico">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="static/css/fork-awesome.min.css"/>
<link rel="stylesheet" href="static/css/leaflet.css"/>
<title>Vite App</title>
</head>
<body>
<div id="app"></div>
<script type="module" src="/src/main.ts"></script>
</body>
</html>

View File

@ -3,127 +3,63 @@
"version": "0.7.25", "version": "0.7.25",
"private": true, "private": true,
"scripts": { "scripts": {
"serve": "vue-cli-service serve", "dev": "vite",
"build": "vue-cli-service build", "build": "run-p type-check \"build-only {@}\" --",
"test:unit": "vue-cli-service test:unit", "preview": "vite preview",
"lint": "vue-cli-service lint", "build-only": "vite build",
"lint-fix": "vue-cli-service lint --fix", "type-check": "vue-tsc --noEmit -p tsconfig.app.json --composite false",
"i18n:report": "vue-cli-service i18n:report --src \"./src/**/*.?(js|vue)\" --locales \"./src/locales/**/*.json\"" "lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
"format": "prettier --write src/"
}, },
"dependencies": { "dependencies": {
"@tmcw/togeojson": "^5.8.1", "@tmcw/togeojson": "^5.8.1",
"@vue-leaflet/vue-leaflet": "0.9.0", "@vue-leaflet/vue-leaflet": "^0.10.1",
"@zxcvbn-ts/core": "^3.0.4", "@zxcvbn-ts/core": "^3.0.4",
"@zxcvbn-ts/language-common": "^3.0.3", "@zxcvbn-ts/language-common": "^3.0.4",
"@zxcvbn-ts/language-de": "^3.0.2", "@zxcvbn-ts/language-de": "^3.0.2",
"@zxcvbn-ts/language-en": "^3.0.2", "@zxcvbn-ts/language-en": "^3.0.2",
"@zxcvbn-ts/language-es-es": "^3.0.2", "@zxcvbn-ts/language-es-es": "^3.0.2",
"@zxcvbn-ts/language-fr": "^3.0.2", "@zxcvbn-ts/language-fr": "^3.0.2",
"@zxcvbn-ts/language-it": "^3.0.2", "@zxcvbn-ts/language-it": "^3.0.2",
"@zxcvbn-ts/language-pl": "^3.0.2", "@zxcvbn-ts/language-pl": "^3.0.2",
"axios": "^1.5.1", "axios": "^1.6.1",
"chart.js": "^4.4.0", "chart.js": "^4.4.0",
"chartjs-plugin-datalabels": "^2.2.0", "chartjs-plugin-datalabels": "^2.2.0",
"core-js": "^3.33.0", "core-js": "^3.33.2",
"date-fns": "2.29.3", "date-fns": "2.30.0",
"date-fns-tz": "^2.0.0", "date-fns-tz": "^2.0.0",
"leaflet": "^1.9.4", "leaflet": "^1.9.4",
"linkify-html": "^4.1.1", "linkify-html": "^4.1.2",
"linkifyjs": "^4.1.1", "linkifyjs": "^4.1.2",
"register-service-worker": "^1.7.1",
"sanitize-html": "^2.11.0", "sanitize-html": "^2.11.0",
"snarkdown": "^2.0.0", "snarkdown": "^2.0.0",
"vue": "3.2.47", "vue": "^3.3.8",
"vue-chart-3": "3.1.1", "vue-chart-3": "^3.1.8",
"vue-fullscreen": "^3.1.1", "vue-fullscreen": "^3.1.1",
"vue-i18n": "^9.5.0", "vue-i18n": "^9.6.5",
"vue-router": "^4.2.5", "vue-router": "^4.2.5",
"vuex": "^4.1.0" "vuex": "^4.1.0"
}, },
"devDependencies": { "devDependencies": {
"@intlify/vue-i18n-loader": "^4.2.0", "@intlify/vue-i18n-loader": "^4.2.0",
"@types/chai": "^4.3.6", "@rushstack/eslint-patch": "^1.3.3",
"@types/mocha": "^10.0.2", "@tsconfig/node18": "^18.2.2",
"@types/sanitize-html": "^2.9.1", "@types/chai": "^4.3.10",
"@typescript-eslint/eslint-plugin": "^5.60.0", "@types/mocha": "^10.0.4",
"@typescript-eslint/parser": "^5.60.0", "@types/node": "^20.9.0",
"@vue/cli-plugin-babel": "~5.0.8", "@types/sanitize-html": "^2.9.4",
"@vue/cli-plugin-eslint": "~5.0.8", "@vitejs/plugin-vue": "^4.4.0",
"@vue/cli-plugin-pwa": "~5.0.8", "@vue/eslint-config-prettier": "^8.0.0",
"@vue/cli-plugin-router": "~5.0.8", "@vue/eslint-config-typescript": "^12.0.0",
"@vue/cli-plugin-typescript": "~5.0.8", "@vue/tsconfig": "^0.4.0",
"@vue/cli-plugin-unit-mocha": "~5.0.8",
"@vue/cli-plugin-vuex": "~5.0.8",
"@vue/cli-service": "~5.0.8",
"@vue/eslint-config-typescript": "^11.0.3",
"@vue/test-utils": "^2.4.1",
"chai": "^4.3.10", "chai": "^4.3.10",
"eslint": "8.42.0", "eslint": "^8.49.0",
"eslint-config-prettier": "^8.10.0",
"eslint-import-resolver-typescript": "^3.6.1",
"eslint-plugin-import": "^2.28.1",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-vue": "^9.17.0", "eslint-plugin-vue": "^9.17.0",
"prettier": "^2.8.8", "npm-run-all2": "^6.1.1",
"sass": "^1.68.0", "prettier": "^3.0.3",
"sass-loader": "^13.3.2", "sass": "^1.69.5",
"typescript": "5.0.4", "typescript": "~5.2.0",
"vue-cli-plugin-i18n": "~2.3.2" "vite": "^4.4.11",
}, "vue-tsc": "^1.8.19"
"eslintConfig": {
"root": true,
"env": {
"node": true
},
"extends": [
"plugin:vue/vue3-essential",
"eslint:recommended",
"@vue/typescript/recommended",
"plugin:import/recommended",
"plugin:import/typescript"
],
"globals": {
"defineProps": "readonly",
"defineEmits": "readonly",
"defineExpose": "readonly",
"withDefaults": "readonly"
},
"settings": {
"import/resolver": "typescript"
},
"parserOptions": {
"ecmaVersion": 2020,
"parser": "@typescript-eslint/parser"
},
"rules": {
"import/order": [
"error",
{
"newlines-between": "always",
"alphabetize": {
"order": "asc",
"caseInsensitive": true
} }
} }
],
"vue/multi-word-component-names": "off"
},
"overrides": [
{
"files": [
"**/__tests__/*.{j,t}s?(x)",
"**/tests/unit/**/*.spec.{j,t}s?(x)"
],
"env": {
"mocha": true
}
}
]
},
"browserslist": [
"> 1%",
"last 2 versions",
"not dead",
"not ie 11"
]
}

View File

@ -1,19 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width,initial-scale=1.0">
<link rel="icon" href="<%= BASE_URL %>favicon.ico">
<link rel="stylesheet" href="<%= BASE_URL %>static/css/fork-awesome.min.css"/>
<link rel="stylesheet" href="<%= BASE_URL %>static/css/leaflet.css"/>
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<noscript>
<strong>We're sorry but <%= htmlWebpackPlugin.options.title %> doesn't work properly without JavaScript enabled. Please enable it to continue.</strong>
</noscript>
<div id="app"></div>
<!-- built files will be auto injected -->
</body>
</html>

View File

@ -29,13 +29,14 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ComputedRef, computed, ref, onBeforeMount, onMounted } from 'vue' import { computed, ref, onBeforeMount, onMounted } from 'vue'
import type { ComputedRef } from 'vue'
import Footer from '@/components/Footer.vue' import Footer from '@/components/Footer.vue'
import NavBar from '@/components/NavBar.vue' import NavBar from '@/components/NavBar.vue'
import NoConfig from '@/components/NoConfig.vue' import NoConfig from '@/components/NoConfig.vue'
import { ROOT_STORE } from '@/store/constants' import { ROOT_STORE } from '@/store/constants'
import { TAppConfig } from '@/types/application' import type { TAppConfig } from '@/types/application'
import { useStore } from '@/use/useStore' import { useStore } from '@/use/useStore'
import { localeFromLanguage } from '@/utils/locales' import { localeFromLanguage } from '@/utils/locales'

View File

@ -1,4 +1,4 @@
import { AxiosRequestConfig } from 'axios' import type { AxiosRequestConfig } from 'axios'
export const pendingRequests = new Map() export const pendingRequests = new Map()

View File

@ -49,9 +49,7 @@
</div> </div>
<template v-if="appConfig.about"> <template v-if="appConfig.about">
<p class="about-instance">{{ $t('about.ABOUT_THIS_INSTANCE') }}</p> <p class="about-instance">{{ $t('about.ABOUT_THIS_INSTANCE') }}</p>
<div <div v-html="snarkdown(linkifyAndClean(appConfig.about))" />
v-html="snarkdown(linkifyAndClean(appConfig.about))"
/>
</template> </template>
</div> </div>
</div> </div>
@ -59,10 +57,11 @@
<script lang="ts" setup> <script lang="ts" setup>
import snarkdown from 'snarkdown' import snarkdown from 'snarkdown'
import { ComputedRef, computed, capitalize } from 'vue' import { computed, capitalize } from 'vue'
import type { ComputedRef } from 'vue'
import { ROOT_STORE } from '@/store/constants' import { ROOT_STORE } from '@/store/constants'
import { TAppConfig } from '@/types/application' import type { TAppConfig } from '@/types/application'
import { useStore } from '@/use/useStore' import { useStore } from '@/use/useStore'
import { linkifyAndClean } from '@/utils/inputs' import { linkifyAndClean } from '@/utils/inputs'

View File

@ -88,7 +88,13 @@
/> />
<div <div
v-else v-else
v-html="snarkdown(linkifyAndClean(appData.about ? appData.about : $t('admin.NO_TEXT_ENTERED')))" v-html="
snarkdown(
linkifyAndClean(
appData.about ? appData.about : $t('admin.NO_TEXT_ENTERED')
)
)
"
class="textarea-content" class="textarea-content"
/> />
<label class="privacy-policy-label" for="privacy_policy"> <label class="privacy-policy-label" for="privacy_policy">
@ -106,7 +112,15 @@
/> />
<div <div
v-else v-else
v-html="snarkdown(linkifyAndClean(appData.privacy_policy ? appData.privacy_policy : $t('admin.NO_TEXT_ENTERED')))" v-html="
snarkdown(
linkifyAndClean(
appData.privacy_policy
? appData.privacy_policy
: $t('admin.NO_TEXT_ENTERED')
)
)
"
class="textarea-content" class="textarea-content"
/> />
<ErrorMessage :message="errorMessages" v-if="errorMessages" /> <ErrorMessage :message="errorMessages" v-if="errorMessages" />
@ -137,19 +151,12 @@
<script setup lang="ts"> <script setup lang="ts">
import snarkdown from 'snarkdown' import snarkdown from 'snarkdown'
import { import { capitalize, computed, reactive, onBeforeMount, toRefs } from 'vue'
ComputedRef, import type { ComputedRef } from 'vue'
capitalize,
computed,
reactive,
withDefaults,
onBeforeMount,
toRefs,
} from 'vue'
import { useRouter } from 'vue-router' import { useRouter } from 'vue-router'
import { ROOT_STORE } from '@/store/constants' import { ROOT_STORE } from '@/store/constants'
import { TAppConfig, TAppConfigForm } from '@/types/application' import type { TAppConfig, TAppConfigForm } from '@/types/application'
import { useStore } from '@/use/useStore' import { useStore } from '@/use/useStore'
import { getFileSizeInMB } from '@/utils/files' import { getFileSizeInMB } from '@/utils/files'
import { linkifyAndClean } from '@/utils/inputs' import { linkifyAndClean } from '@/utils/inputs'
@ -187,19 +194,17 @@
function updateForm(appConfig: TAppConfig) { function updateForm(appConfig: TAppConfig) {
Object.keys(appData).map((key) => { Object.keys(appData).map((key) => {
['max_single_file_size', 'max_zip_file_size'].includes(key) ;['max_single_file_size', 'max_zip_file_size'].includes(key)
? // eslint-disable-next-line @typescript-eslint/ban-ts-comment ? // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore // @ts-ignore
(appData[key] = getFileSizeInMB(appConfig[key])) (appData[key] = getFileSizeInMB(appConfig[key]))
: ['about', 'privacy_policy'].includes(key) : ['about', 'privacy_policy'].includes(key)
// eslint-disable-next-line @typescript-eslint/ban-ts-comment ? // eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore // @ts-ignore
? appData[key] = appConfig[key]!== null (appData[key] = appConfig[key] !== null ? appConfig[key] : '')
? appConfig[key] : // eslint-disable-next-line @typescript-eslint/ban-ts-comment
: ''
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore // @ts-ignore
: (appData[key] = appConfig[key]) (appData[key] = appConfig[key])
}) })
} }
function onCancel() { function onCancel() {
@ -242,6 +247,5 @@
margin-bottom: $default-margin; margin-bottom: $default-margin;
padding: $default-padding; padding: $default-padding;
} }
} }
</style> </style>

View File

@ -54,18 +54,18 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { capitalize, onMounted, toRefs, withDefaults } from 'vue' import { capitalize, onMounted, toRefs } from 'vue'
import AppStatsCards from '@/components/Administration/AppStatsCards.vue' import AppStatsCards from '@/components/Administration/AppStatsCards.vue'
import Card from '@/components/Common/Card.vue' import Card from '@/components/Common/Card.vue'
import { IAppStatistics, TAppConfig } from '@/types/application' import type { IAppStatistics, TAppConfig } from '@/types/application'
interface Props { interface Props {
appConfig: TAppConfig appConfig: TAppConfig
appStatistics?: IAppStatistics appStatistics?: IAppStatistics
} }
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
appStatistics: () => ({} as IAppStatistics), appStatistics: () => ({}) as IAppStatistics,
}) })
const { appConfig, appStatistics } = toRefs(props) const { appConfig, appStatistics } = toRefs(props)

View File

@ -84,11 +84,12 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ComputedRef, computed } from 'vue' import { computed } from 'vue'
import type { ComputedRef } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { ROOT_STORE, SPORTS_STORE } from '@/store/constants' import { ROOT_STORE, SPORTS_STORE } from '@/store/constants'
import { ITranslatedSport } from '@/types/sports' import type { ITranslatedSport } from '@/types/sports'
import { useStore } from '@/use/useStore' import { useStore } from '@/use/useStore'
import { translateSports } from '@/utils/sports' import { translateSports } from '@/utils/sports'

View File

@ -134,8 +134,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { import {
ComputedRef,
Ref,
computed, computed,
reactive, reactive,
watch, watch,
@ -143,15 +141,17 @@
onBeforeMount, onBeforeMount,
onUnmounted, onUnmounted,
} from 'vue' } from 'vue'
import { LocationQuery, useRoute, useRouter } from 'vue-router' import type { ComputedRef, Ref } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import type { LocationQuery } from 'vue-router'
import FilterSelects from '@/components/Common/FilterSelects.vue' import FilterSelects from '@/components/Common/FilterSelects.vue'
import Pagination from '@/components/Common/Pagination.vue' import Pagination from '@/components/Common/Pagination.vue'
import UserPicture from '@/components/User/UserPicture.vue' import UserPicture from '@/components/User/UserPicture.vue'
import UsersNameFilter from '@/components/Users/UsersNameFilter.vue' import UsersNameFilter from '@/components/Users/UsersNameFilter.vue'
import { AUTH_USER_STORE, ROOT_STORE, USERS_STORE } from '@/store/constants' import { AUTH_USER_STORE, ROOT_STORE, USERS_STORE } from '@/store/constants'
import { IPagination, TPaginationPayload } from '@/types/api' import type { IPagination, TPaginationPayload } from '@/types/api'
import { IAuthUserProfile, IUserProfile } from '@/types/user' import type { IAuthUserProfile, IUserProfile } from '@/types/user'
import { useStore } from '@/use/useStore' import { useStore } from '@/use/useStore'
import { getQuery, sortList } from '@/utils/api' import { getQuery, sortList } from '@/utils/api'
import { formatDate } from '@/utils/dates' import { formatDate } from '@/utils/dates'

View File

@ -27,7 +27,7 @@
import { computed, toRefs } from 'vue' import { computed, toRefs } from 'vue'
import StatCard from '@/components/Common/StatCard.vue' import StatCard from '@/components/Common/StatCard.vue'
import { IAppStatistics } from '@/types/application' import type { IAppStatistics } from '@/types/application'
import { getReadableFileSize } from '@/utils/files' import { getReadableFileSize } from '@/utils/files'
interface Props { interface Props {

View File

@ -15,7 +15,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ref, watch, withDefaults } from 'vue' import { ref, watch } from 'vue'
interface Props { interface Props {
name: string name: string

View File

@ -7,9 +7,10 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ComputedRef, computed, toRefs, withDefaults } from 'vue' import { computed, toRefs } from 'vue'
import type { ComputedRef } from 'vue'
import { TUnit } from '@/types/units' import type { TUnit } from '@/types/units'
import { units, convertDistance } from '@/utils/units' import { units, convertDistance } from '@/utils/units'
interface Props { interface Props {

View File

@ -29,7 +29,7 @@
import { ref, toRefs, watch } from 'vue' import { ref, toRefs, watch } from 'vue'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import { IDropdownOption, TDropdownOptions } from '@/types/forms' import type { IDropdownOption, TDropdownOptions } from '@/types/forms'
interface Props { interface Props {
options: TDropdownOptions options: TDropdownOptions
selected: string selected: string

View File

@ -11,7 +11,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { toRefs, withDefaults } from 'vue' import { toRefs } from 'vue'
interface Props { interface Props {
title: string title: string

View File

@ -45,7 +45,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { toRefs } from 'vue' import { toRefs } from 'vue'
import { TPaginationPayload } from '@/types/api' import type { TPaginationPayload } from '@/types/api'
interface Props { interface Props {
order_by: string[] order_by: string[]

View File

@ -56,7 +56,7 @@
</svg> </svg>
</template> </template>
<script> <script lang="ts">
export default { export default {
name: 'EmailSent', name: 'EmailSent',
} }

View File

@ -21,7 +21,7 @@
</svg> </svg>
</template> </template>
<script> <script lang="ts">
export default { export default {
name: 'ErrorImg', name: 'ErrorImg',
} }

View File

@ -87,7 +87,7 @@
</svg> </svg>
</template> </template>
<script> <script lang="ts">
export default { export default {
name: 'Password', name: 'Password',
} }

View File

@ -44,7 +44,7 @@
</svg> </svg>
</template> </template>
<script> <script lang="ts">
export default { export default {
name: 'CyclingSport', name: 'CyclingSport',
} }

View File

@ -26,7 +26,7 @@
</svg> </svg>
</template> </template>
<script> <script lang="ts">
export default { export default {
name: 'CyclingTransport', name: 'CyclingTransport',
} }

View File

@ -8,31 +8,40 @@
style="enable-background: new 0 0 491.737 491.737" style="enable-background: new 0 0 491.737 491.737"
xml:space="preserve" xml:space="preserve"
xmlns="http://www.w3.org/2000/svg" xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"> xmlns:svg="http://www.w3.org/2000/svg"
<desc >
id="cyclingVirtualDescription"> <desc id="cyclingVirtualDescription">
silhouette of a person riding a bicycle with virtual indicator silhouette of a person riding a bicycle with virtual indicator
</desc> </desc>
<path <path
d="m 321.097,112.359 c 20.973,12.338 47.985,5.315 60.293,-15.652 12.34,-20.973 5.35,-47.974 -15.623,-60.304 -21.009,-12.332 -47.99,-5.317 -60.314,15.65 -12.324,20.983 -5.35,47.974 15.644,60.306 z" d="m 321.097,112.359 c 20.973,12.338 47.985,5.315 60.293,-15.652 12.34,-20.973 5.35,-47.974 -15.623,-60.304 -21.009,-12.332 -47.99,-5.317 -60.314,15.65 -12.324,20.983 -5.35,47.974 15.644,60.306 z"
id="path3" /><path id="path3"
/>
<path
d="m 393.081,264.102 c -2.414,0 -4.8,0.194 -7.169,0.362 l -14.431,-71.605 4.702,-1.757 c 10.666,-3.987 16.093,-15.868 12.098,-26.54 -3.994,-10.681 -15.946,-16.084 -26.531,-12.09 l -51.823,19.38 -2.321,-18.864 c 6.3,-13.193 5.541,-29.78 -4.767,-41.482 -21.224,-24.092 -47.12,-12.508 -55.191,-5.976 l -106.884,86.555 0.016,0.024 c -3.319,2.893 -6.089,6.485 -7.86,10.842 -2.191,5.396 -2.596,11.067 -1.564,16.384 -8.503,0.669 -15.255,7.571 -15.255,16.246 0,9.085 7.346,16.44 16.432,16.48 l -6.797,15.906 c -8.62,-2.465 -17.674,-3.866 -27.066,-3.866 C 44.27,264.102 0,308.354 0,362.754 c 0,54.403 44.27,98.663 98.668,98.663 54.403,0 98.652,-44.26 98.652,-98.663 0,-36.228 -19.683,-67.867 -48.858,-85.024 l 10.957,-25.652 h 17.767 l 60.281,24.462 -32.201,52.773 c -8.297,13.612 -3.994,31.382 9.615,39.685 4.691,2.86 9.878,4.229 15,4.229 9.729,0 19.234,-4.929 24.677,-13.838 l 29.339,-48.095 19.072,11.511 c -5.447,12.227 -8.54,25.726 -8.54,39.95 0,54.403 44.254,98.663 98.652,98.663 54.402,0 98.656,-44.26 98.656,-98.663 0,-54.401 -44.254,-98.653 -98.656,-98.653 z M 98.668,436.671 c -40.756,0 -73.923,-33.161 -73.923,-73.917 0,-40.756 33.167,-73.909 73.923,-73.909 5.944,0 11.649,0.896 17.188,2.224 L 95.38,338.962 c -11.758,1.619 -20.843,11.598 -20.843,23.792 0,13.323 10.808,24.132 24.13,24.132 8.767,0 16.367,-4.745 20.589,-11.76 h 52.065 c -5.926,34.862 -36.133,61.545 -72.653,61.545 z m 72.654,-86.288 h -52.065 c -0.355,-0.588 -0.708,-1.176 -1.112,-1.732 l 20.476,-47.901 c 17.058,11.026 29.172,28.845 32.701,49.633 z m 125.459,-60.208 7.666,-12.564 c 4.416,-7.233 5.431,-16.038 2.774,-24.084 -2.661,-8.046 -8.718,-14.515 -16.562,-17.704 l -52.725,-21.395 32.443,-26.281 1.804,14.691 c 0.756,6.267 4.366,11.841 9.761,15.12 3.271,1.981 6.979,2.988 10.698,2.988 2.435,0 4.88,-0.435 7.218,-1.306 l 48.15,-18.001 13.627,67.691 c -18.268,6.162 -34.117,17.51 -45.848,32.314 z m 78.615,47.458 -38.003,-22.94 c 7.877,-9.118 17.787,-16.319 29.205,-20.734 z m 17.685,99.038 c -40.757,0 -73.907,-33.161 -73.907,-73.917 0,-9.544 1.965,-18.597 5.268,-26.983 l 44.541,26.888 c 0,0.032 -0.016,0.064 -0.016,0.095 0,13.323 10.808,24.132 24.114,24.132 13.322,0 24.118,-10.81 24.118,-24.132 0,-10.478 -6.721,-19.307 -16.06,-22.64 l -10.277,-51.043 c 0.756,-0.024 1.463,-0.226 2.22,-0.226 40.757,0 73.911,33.153 73.911,73.909 -10e-4,40.756 -33.155,73.917 -73.912,73.917 z" d="m 393.081,264.102 c -2.414,0 -4.8,0.194 -7.169,0.362 l -14.431,-71.605 4.702,-1.757 c 10.666,-3.987 16.093,-15.868 12.098,-26.54 -3.994,-10.681 -15.946,-16.084 -26.531,-12.09 l -51.823,19.38 -2.321,-18.864 c 6.3,-13.193 5.541,-29.78 -4.767,-41.482 -21.224,-24.092 -47.12,-12.508 -55.191,-5.976 l -106.884,86.555 0.016,0.024 c -3.319,2.893 -6.089,6.485 -7.86,10.842 -2.191,5.396 -2.596,11.067 -1.564,16.384 -8.503,0.669 -15.255,7.571 -15.255,16.246 0,9.085 7.346,16.44 16.432,16.48 l -6.797,15.906 c -8.62,-2.465 -17.674,-3.866 -27.066,-3.866 C 44.27,264.102 0,308.354 0,362.754 c 0,54.403 44.27,98.663 98.668,98.663 54.403,0 98.652,-44.26 98.652,-98.663 0,-36.228 -19.683,-67.867 -48.858,-85.024 l 10.957,-25.652 h 17.767 l 60.281,24.462 -32.201,52.773 c -8.297,13.612 -3.994,31.382 9.615,39.685 4.691,2.86 9.878,4.229 15,4.229 9.729,0 19.234,-4.929 24.677,-13.838 l 29.339,-48.095 19.072,11.511 c -5.447,12.227 -8.54,25.726 -8.54,39.95 0,54.403 44.254,98.663 98.652,98.663 54.402,0 98.656,-44.26 98.656,-98.663 0,-54.401 -44.254,-98.653 -98.656,-98.653 z M 98.668,436.671 c -40.756,0 -73.923,-33.161 -73.923,-73.917 0,-40.756 33.167,-73.909 73.923,-73.909 5.944,0 11.649,0.896 17.188,2.224 L 95.38,338.962 c -11.758,1.619 -20.843,11.598 -20.843,23.792 0,13.323 10.808,24.132 24.13,24.132 8.767,0 16.367,-4.745 20.589,-11.76 h 52.065 c -5.926,34.862 -36.133,61.545 -72.653,61.545 z m 72.654,-86.288 h -52.065 c -0.355,-0.588 -0.708,-1.176 -1.112,-1.732 l 20.476,-47.901 c 17.058,11.026 29.172,28.845 32.701,49.633 z m 125.459,-60.208 7.666,-12.564 c 4.416,-7.233 5.431,-16.038 2.774,-24.084 -2.661,-8.046 -8.718,-14.515 -16.562,-17.704 l -52.725,-21.395 32.443,-26.281 1.804,14.691 c 0.756,6.267 4.366,11.841 9.761,15.12 3.271,1.981 6.979,2.988 10.698,2.988 2.435,0 4.88,-0.435 7.218,-1.306 l 48.15,-18.001 13.627,67.691 c -18.268,6.162 -34.117,17.51 -45.848,32.314 z m 78.615,47.458 -38.003,-22.94 c 7.877,-9.118 17.787,-16.319 29.205,-20.734 z m 17.685,99.038 c -40.757,0 -73.907,-33.161 -73.907,-73.917 0,-9.544 1.965,-18.597 5.268,-26.983 l 44.541,26.888 c 0,0.032 -0.016,0.064 -0.016,0.095 0,13.323 10.808,24.132 24.114,24.132 13.322,0 24.118,-10.81 24.118,-24.132 0,-10.478 -6.721,-19.307 -16.06,-22.64 l -10.277,-51.043 c 0.756,-0.024 1.463,-0.226 2.22,-0.226 40.757,0 73.911,33.153 73.911,73.909 -10e-4,40.756 -33.155,73.917 -73.912,73.917 z"
id="path5" /> id="path5"
<g />
id="g10174" <g id="g10174" transform="rotate(-45,60.058765,120.50397)">
transform="rotate(-45,60.058765,120.50397)"><path <path
d="m 100.16593,30.670651 c -5.521751,5.521749 -5.521751,14.11256 0,19.638597 17.79324,17.793301 28.22948,42.342094 28.22948,67.502302 0,25.77277 -9.81917,49.70354 -27.61257,67.50231 -5.521761,5.52175 -5.521761,14.11256 0,19.63859 2.45267,2.45269 6.13811,4.29754 9.81916,4.29754 3.68106,0 7.36234,-1.22848 9.81921,-4.29754 23.31927,-23.31932 36.20348,-54.00119 36.20348,-87.1365 0,-33.134258 -12.88856,-63.816092 -36.20348,-87.136525 -6.14243,-5.530298 -14.73279,-5.530298 -20.25443,-0.0085 z" d="m 100.16593,30.670651 c -5.521751,5.521749 -5.521751,14.11256 0,19.638597 17.79324,17.793301 28.22948,42.342094 28.22948,67.502302 0,25.77277 -9.81917,49.70354 -27.61257,67.50231 -5.521761,5.52175 -5.521761,14.11256 0,19.63859 2.45267,2.45269 6.13811,4.29754 9.81916,4.29754 3.68106,0 7.36234,-1.22848 9.81921,-4.29754 23.31927,-23.31932 36.20348,-54.00119 36.20348,-87.1365 0,-33.134258 -12.88856,-63.816092 -36.20348,-87.136525 -6.14243,-5.530298 -14.73279,-5.530298 -20.25443,-0.0085 z"
id="path3370" id="path3370"
style="stroke-width:1.09578" /><path style="stroke-width: 1.09578"
/>
<path
d="m 83.597679,66.875252 c -5.52175,-5.521722 -14.11255,-5.521722 -19.63857,0 -5.52175,5.521756 -5.52175,14.11259 0,19.6386 8.59071,8.5907 12.88856,19.638598 12.88856,31.294418 0,11.66021 -4.90967,23.31931 -12.88856,31.29441 -5.52175,5.52175 -5.52175,14.11256 0,19.63859 2.45267,2.45269 6.13812,4.29754 9.81917,4.29754 3.68105,0 7.36233,-1.22847 9.81917,-4.29754 13.50002,-13.50004 21.479501,-31.91025 20.862591,-50.93191 0.61209,-19.026028 -6.750211,-37.431868 -20.862591,-50.93189 z" d="m 83.597679,66.875252 c -5.52175,-5.521722 -14.11255,-5.521722 -19.63857,0 -5.52175,5.521756 -5.52175,14.11259 0,19.6386 8.59071,8.5907 12.88856,19.638598 12.88856,31.294418 0,11.66021 -4.90967,23.31931 -12.88856,31.29441 -5.52175,5.52175 -5.52175,14.11256 0,19.63859 2.45267,2.45269 6.13812,4.29754 9.81917,4.29754 3.68105,0 7.36233,-1.22847 9.81917,-4.29754 13.50002,-13.50004 21.479501,-31.91025 20.862591,-50.93191 0.61209,-19.026028 -6.750211,-37.431868 -20.862591,-50.93189 z"
id="path3372" id="path3372"
style="stroke-width:1.09578" /><path style="stroke-width: 1.09578"
/>
<path
d="m 54.143079,118.42081 c 0,11.86074 -9.61798,21.47512 -21.4795,21.47512 -11.861488,0 -21.4795,-9.61372 -21.4795,-21.47512 0,-11.86141 9.618012,-21.479498 21.4795,-21.479498 11.86152,0 21.4795,9.618008 21.4795,21.479498" d="m 54.143079,118.42081 c 0,11.86074 -9.61798,21.47512 -21.4795,21.47512 -11.861488,0 -21.4795,-9.61372 -21.4795,-21.47512 0,-11.86141 9.618012,-21.479498 21.4795,-21.479498 11.86152,0 21.4795,9.618008 21.4795,21.479498"
id="path3378" id="path3378"
style="stroke-width:1.09578" /></g></svg> style="stroke-width: 1.09578"
/>
</g>
</svg>
</template> </template>
<script> <script lang="ts">
export default { export default {
name: 'CyclingVirtual', name: 'CyclingVirtual',
} }

View File

@ -31,7 +31,7 @@
</svg> </svg>
</template> </template>
<script> <script lang="ts">
export default { export default {
name: 'Hiking', name: 'Hiking',
} }

View File

@ -44,7 +44,7 @@
</svg> </svg>
</template> </template>
<script> <script lang="ts">
export default { export default {
name: 'MountainBiking', name: 'MountainBiking',
} }

View File

@ -64,7 +64,7 @@
</svg> </svg>
</template> </template>
<script> <script lang="ts">
export default { export default {
name: 'MountainBikingElectric', name: 'MountainBikingElectric',
} }

View File

@ -50,7 +50,7 @@
</svg> </svg>
</template> </template>
<script> <script lang="ts">
export default { export default {
name: 'Mountaineering', name: 'Mountaineering',
} }

View File

@ -138,7 +138,7 @@
</svg> </svg>
</template> </template>
<script> <script lang="ts">
export default { export default {
name: 'OpenWaterSwimming', name: 'OpenWaterSwimming',
} }

View File

@ -33,7 +33,7 @@
</svg> </svg>
</template> </template>
<script> <script lang="ts">
export default { export default {
name: 'Paragliding', name: 'Paragliding',
} }

View File

@ -31,7 +31,7 @@
</svg> </svg>
</template> </template>
<script> <script lang="ts">
export default { export default {
name: 'Rowing', name: 'Rowing',
} }

View File

@ -31,7 +31,7 @@
</svg> </svg>
</template> </template>
<script> <script lang="ts">
export default { export default {
name: 'Running', name: 'Running',
} }

View File

@ -35,7 +35,7 @@
</svg> </svg>
</template> </template>
<script> <script lang="ts">
export default { export default {
name: 'SkiingAlpine', name: 'SkiingAlpine',
} }

View File

@ -31,7 +31,7 @@
</svg> </svg>
</template> </template>
<script> <script lang="ts">
export default { export default {
name: 'SkiingCrossCountry', name: 'SkiingCrossCountry',
} }

View File

@ -55,7 +55,7 @@
</svg> </svg>
</template> </template>
<script> <script lang="ts">
export default { export default {
name: 'Snowshoes', name: 'Snowshoes',
} }

View File

@ -37,7 +37,7 @@
</svg> </svg>
</template> </template>
<script> <script lang="ts">
export default { export default {
name: 'Trail', name: 'Trail',
} }

View File

@ -25,7 +25,7 @@
</svg> </svg>
</template> </template>
<script> <script lang="ts">
export default { export default {
name: 'Walking', name: 'Walking',
} }

View File

@ -38,14 +38,8 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { import { computed, onUnmounted, onMounted, toRefs } from 'vue'
ComputedRef, import type { ComputedRef } from 'vue'
computed,
onUnmounted,
onMounted,
toRefs,
withDefaults,
} from 'vue'
import { ROOT_STORE } from '@/store/constants' import { ROOT_STORE } from '@/store/constants'
import { useStore } from '@/use/useStore' import { useStore } from '@/use/useStore'

View File

@ -8,7 +8,8 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { Ref, onMounted, ref, toRefs, withDefaults, onUnmounted } from 'vue' import { onMounted, ref, toRefs, onUnmounted } from 'vue'
import type { Ref } from 'vue'
import Error from '@/components/Common/Error.vue' import Error from '@/components/Common/Error.vue'
interface Props { interface Props {

View File

@ -51,9 +51,9 @@
<script setup lang="ts"> <script setup lang="ts">
import { toRefs } from 'vue' import { toRefs } from 'vue'
import { IPagination, TPaginationPayload } from '@/types/api' import type { IPagination, TPaginationPayload } from '@/types/api'
import { IOauth2ClientsPayload } from '@/types/oauth' import type { IOauth2ClientsPayload } from '@/types/oauth'
import { TWorkoutsPayload } from '@/types/workouts' import type { TWorkoutsPayload } from '@/types/workouts'
import { rangePagination } from '@/utils/api' import { rangePagination } from '@/utils/api'
interface Props { interface Props {

View File

@ -30,7 +30,8 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { Ref, ref, toRefs, watch, withDefaults } from 'vue' import { ref, toRefs, watch } from 'vue'
import type { Ref } from 'vue'
import PasswordStrength from '@/components/Common/PasswordStength.vue' import PasswordStrength from '@/components/Common/PasswordStength.vue'

View File

@ -29,15 +29,8 @@
<script setup lang="ts"> <script setup lang="ts">
import { zxcvbn } from '@zxcvbn-ts/core' import { zxcvbn } from '@zxcvbn-ts/core'
import { import { computed, ref, onBeforeMount, toRefs, watch } from 'vue'
ComputedRef, import type { ComputedRef, Ref } from 'vue'
Ref,
computed,
ref,
onBeforeMount,
toRefs,
watch,
} from 'vue'
import { AUTH_USER_STORE, ROOT_STORE } from '@/store/constants' import { AUTH_USER_STORE, ROOT_STORE } from '@/store/constants'
import { useStore } from '@/use/useStore' import { useStore } from '@/use/useStore'

View File

@ -23,9 +23,9 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { toRefs, withDefaults } from 'vue' import { toRefs } from 'vue'
import { IWorkout } from '@/types/workouts' import type { IWorkout } from '@/types/workouts'
import { getApiUrl } from '@/utils' import { getApiUrl } from '@/utils'
interface Props { interface Props {

View File

@ -5,13 +5,14 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { ChartOptions, LayoutItem } from 'chart.js' import type { ChartOptions, LayoutItem } from 'chart.js'
import { PropType, computed, defineComponent } from 'vue' import { computed, defineComponent } from 'vue'
import type { PropType } from 'vue'
import { BarChart, useBarChart } from 'vue-chart-3' import { BarChart, useBarChart } from 'vue-chart-3'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { IChartDataset } from '@/types/chart' import type { IChartDataset } from '@/types/chart'
import { TStatisticsDatasetKeys } from '@/types/statistics' import type { TStatisticsDatasetKeys } from '@/types/statistics'
import { formatTooltipValue } from '@/utils/tooltip' import { formatTooltipValue } from '@/utils/tooltip'
export default defineComponent({ export default defineComponent({

View File

@ -81,28 +81,20 @@
<script lang="ts"> <script lang="ts">
import { format } from 'date-fns' import { format } from 'date-fns'
import { import { computed, defineComponent, ref, watch, onBeforeMount } from 'vue'
ComputedRef, import type { ComputedRef, PropType, Ref } from 'vue'
PropType,
Ref,
computed,
defineComponent,
ref,
watch,
onBeforeMount,
} from 'vue'
import Chart from '@/components/Common/StatsChart/Chart.vue' import Chart from '@/components/Common/StatsChart/Chart.vue'
import { STATS_STORE } from '@/store/constants' import { STATS_STORE } from '@/store/constants'
import { ISport } from '@/types/sports' import type { ISport } from '@/types/sports'
import { import type {
IStatisticsChartData, IStatisticsChartData,
TStatisticsDatasetKeys, TStatisticsDatasetKeys,
IStatisticsDateParams, IStatisticsDateParams,
TStatisticsFromApi, TStatisticsFromApi,
IStatisticsParams, IStatisticsParams,
} from '@/types/statistics' } from '@/types/statistics'
import { IAuthUserProfile } from '@/types/user' import type { IAuthUserProfile } from '@/types/user'
import { useStore } from '@/use/useStore' import { useStore } from '@/use/useStore'
import { formatStats } from '@/utils/statistics' import { formatStats } from '@/utils/statistics'

View File

@ -33,14 +33,15 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ComputedRef, computed, ref, onBeforeMount, toRefs } from 'vue' import { computed, ref, onBeforeMount, toRefs } from 'vue'
import type { ComputedRef } from 'vue'
import WorkoutCard from '@/components/Workout/WorkoutCard.vue' import WorkoutCard from '@/components/Workout/WorkoutCard.vue'
import NoWorkouts from '@/components/Workouts/NoWorkouts.vue' import NoWorkouts from '@/components/Workouts/NoWorkouts.vue'
import { WORKOUTS_STORE } from '@/store/constants' import { WORKOUTS_STORE } from '@/store/constants'
import { ISport } from '@/types/sports' import type { ISport } from '@/types/sports'
import { IUserProfile } from '@/types/user' import type { IUserProfile } from '@/types/user'
import { IWorkout } from '@/types/workouts' import type { IWorkout } from '@/types/workouts'
import { useStore } from '@/use/useStore' import { useStore } from '@/use/useStore'
import { defaultOrder } from '@/utils/workouts' import { defaultOrder } from '@/utils/workouts'

View File

@ -26,11 +26,12 @@
<script setup lang="ts"> <script setup lang="ts">
import { addDays, format, isSameDay, isSameMonth, isToday } from 'date-fns' import { addDays, format, isSameDay, isSameMonth, isToday } from 'date-fns'
import { Ref, ref, toRefs, watch, onMounted } from 'vue' import { ref, toRefs, watch, onMounted } from 'vue'
import type { Ref } from 'vue'
import CalendarWorkouts from '@/components/Dashboard/UserCalendar/CalendarWorkouts.vue' import CalendarWorkouts from '@/components/Dashboard/UserCalendar/CalendarWorkouts.vue'
import { ISport } from '@/types/sports' import type { ISport } from '@/types/sports'
import { IWorkout } from '@/types/workouts' import type { IWorkout } from '@/types/workouts'
import { getDateWithTZ } from '@/utils/dates' import { getDateWithTZ } from '@/utils/dates'
interface Props { interface Props {

View File

@ -7,7 +7,8 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { Locale, format, addDays } from 'date-fns' import { format, addDays } from 'date-fns'
import type { Locale } from 'date-fns'
interface Props { interface Props {
startDate: Date startDate: Date

View File

@ -21,7 +21,8 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { Locale, format } from 'date-fns' import { format } from 'date-fns'
import type { Locale } from 'date-fns'
import { toRefs } from 'vue' import { toRefs } from 'vue'
interface Props { interface Props {

View File

@ -30,7 +30,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { toRefs } from 'vue' import { toRefs } from 'vue'
import { IWorkout } from '@/types/workouts' import type { IWorkout } from '@/types/workouts'
interface Props { interface Props {
displayHARecord: boolean displayHARecord: boolean
workout: IWorkout workout: IWorkout

View File

@ -41,8 +41,8 @@
import CalendarWorkout from '@/components/Dashboard/UserCalendar/CalendarWorkout.vue' import CalendarWorkout from '@/components/Dashboard/UserCalendar/CalendarWorkout.vue'
import CalendarWorkoutsChart from '@/components/Dashboard/UserCalendar/CalendarWorkoutsChart.vue' import CalendarWorkoutsChart from '@/components/Dashboard/UserCalendar/CalendarWorkoutsChart.vue'
import { ISport } from '@/types/sports' import type { ISport } from '@/types/sports'
import { IWorkout } from '@/types/workouts' import type { IWorkout } from '@/types/workouts'
import { getSportColor, getSportLabel, sportIdColors } from '@/utils/sports' import { getSportColor, getSportLabel, sportIdColors } from '@/utils/sports'
import { getDonutDatasets } from '@/utils/workouts' import { getDonutDatasets } from '@/utils/workouts'

View File

@ -28,8 +28,8 @@
import CalendarWorkout from '@/components/Dashboard/UserCalendar/CalendarWorkout.vue' import CalendarWorkout from '@/components/Dashboard/UserCalendar/CalendarWorkout.vue'
import DonutChart from '@/components/Dashboard/UserCalendar/DonutChart.vue' import DonutChart from '@/components/Dashboard/UserCalendar/DonutChart.vue'
import { ISport } from '@/types/sports' import type { ISport } from '@/types/sports'
import { IWorkout } from '@/types/workouts' import type { IWorkout } from '@/types/workouts'
import { getSportColor, getSportLabel } from '@/utils/sports' import { getSportColor, getSportLabel } from '@/utils/sports'
interface Props { interface Props {
@ -88,7 +88,8 @@
.more-workouts { .more-workouts {
background: whitesmoke; background: whitesmoke;
border-radius: 4px; border-radius: 4px;
box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.2), box-shadow:
0 4px 8px 0 rgba(0, 0, 0, 0.2),
0 6px 20px 0 rgba(0, 0, 0, 0.19); 0 6px 20px 0 rgba(0, 0, 0, 0.19);
position: absolute; position: absolute;
top: 52px; top: 52px;

View File

@ -26,16 +26,18 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { Locale, addMonths, format, subMonths } from 'date-fns' import { addMonths, format, subMonths } from 'date-fns'
import { ComputedRef, computed, ref, toRefs, onBeforeMount } from 'vue' import type { Locale } from 'date-fns'
import { computed, ref, toRefs, onBeforeMount } from 'vue'
import type { ComputedRef } from 'vue'
import CalendarCells from '@/components/Dashboard/UserCalendar/CalendarCells.vue' import CalendarCells from '@/components/Dashboard/UserCalendar/CalendarCells.vue'
import CalendarDays from '@/components/Dashboard/UserCalendar/CalendarDays.vue' import CalendarDays from '@/components/Dashboard/UserCalendar/CalendarDays.vue'
import CalendarHeader from '@/components/Dashboard/UserCalendar/CalendarHeader.vue' import CalendarHeader from '@/components/Dashboard/UserCalendar/CalendarHeader.vue'
import { ROOT_STORE, WORKOUTS_STORE } from '@/store/constants' import { ROOT_STORE, WORKOUTS_STORE } from '@/store/constants'
import { ISport } from '@/types/sports' import type { ISport } from '@/types/sports'
import { IAuthUserProfile } from '@/types/user' import type { IAuthUserProfile } from '@/types/user'
import { IWorkout, TWorkoutsPayload } from '@/types/workouts' import type { IWorkout, TWorkoutsPayload } from '@/types/workouts'
import { useStore } from '@/use/useStore' import { useStore } from '@/use/useStore'
import { getCalendarStartAndEnd } from '@/utils/dates' import { getCalendarStartAndEnd } from '@/utils/dates'
import { defaultOrder } from '@/utils/workouts' import { defaultOrder } from '@/utils/workouts'

View File

@ -20,8 +20,8 @@
import { toRefs } from 'vue' import { toRefs } from 'vue'
import StatChart from '@/components/Common/StatsChart/index.vue' import StatChart from '@/components/Common/StatsChart/index.vue'
import { ISport } from '@/types/sports' import type { ISport } from '@/types/sports'
import { IUserProfile } from '@/types/user' import type { IUserProfile } from '@/types/user'
interface Props { interface Props {
sports: ISport[] sports: ISport[]

View File

@ -35,7 +35,7 @@
import { toRefs } from 'vue' import { toRefs } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { ICardRecord, IRecord, IRecordsBySports } from '@/types/workouts' import type { ICardRecord, IRecord, IRecordsBySports } from '@/types/workouts'
import { sortRecords } from '@/utils/records' import { sortRecords } from '@/utils/records'
interface Props { interface Props {

View File

@ -24,8 +24,8 @@
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import RecordsCard from '@/components/Dashboard/UserRecords/RecordsCard.vue' import RecordsCard from '@/components/Dashboard/UserRecords/RecordsCard.vue'
import { ISport } from '@/types/sports' import type { ISport } from '@/types/sports'
import { IAuthUserProfile } from '@/types/user' import type { IAuthUserProfile } from '@/types/user'
import { getRecordsBySports } from '@/utils/records' import { getRecordsBySports } from '@/utils/records'
import { translateSports } from '@/utils/sports' import { translateSports } from '@/utils/sports'

View File

@ -31,12 +31,13 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ComputedRef, computed, toRefs } from 'vue' import { computed, toRefs } from 'vue'
import type { ComputedRef } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import StatCard from '@/components/Common/StatCard.vue' import StatCard from '@/components/Common/StatCard.vue'
import { TUnit } from '@/types/units' import type { TUnit } from '@/types/units'
import { IAuthUserProfile } from '@/types/user' import type { IAuthUserProfile } from '@/types/user'
import { convertDistance, units } from '@/utils/units' import { convertDistance, units } from '@/utils/units'
interface Props { interface Props {
user: IAuthUserProfile user: IAuthUserProfile
@ -56,17 +57,28 @@
: distanceUnitFrom : distanceUnitFrom
const totalDistance: ComputedRef<number> = computed(() => const totalDistance: ComputedRef<number> = computed(() =>
user.value.imperial_units user.value.imperial_units
? convertDistance(user.value.total_distance, distanceUnitFrom, distanceUnitTo, 2) ? convertDistance(
: parseFloat(user.value.total_distance.toFixed(2))) user.value.total_distance,
distanceUnitFrom,
distanceUnitTo,
2
)
: parseFloat(user.value.total_distance.toFixed(2))
)
const ascentUnitFrom: TUnit = 'm' const ascentUnitFrom: TUnit = 'm'
const ascentUnitTo: TUnit = user.value.imperial_units const ascentUnitTo: TUnit = user.value.imperial_units
? units[ascentUnitFrom].defaultTarget ? units[ascentUnitFrom].defaultTarget
: ascentUnitFrom : ascentUnitFrom
const totalAscent: ComputedRef<number> = computed(() => const totalAscent: ComputedRef<number> = computed(() =>
user.value.imperial_units user.value.imperial_units
? convertDistance(user.value.total_ascent, ascentUnitFrom, ascentUnitTo, 2) ? convertDistance(
: parseFloat(user.value.total_ascent.toFixed(2))) user.value.total_ascent,
ascentUnitFrom,
ascentUnitTo,
2
)
: parseFloat(user.value.total_ascent.toFixed(2))
)
function get_duration(total_duration: ComputedRef<string>) { function get_duration(total_duration: ComputedRef<string>) {
const duration = total_duration.value.match(/day/g) const duration = total_duration.value.match(/day/g)

View File

@ -93,12 +93,13 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ComputedRef, Ref, computed, ref, capitalize } from 'vue' import { computed, ref, capitalize } from 'vue'
import type { ComputedRef, Ref } from 'vue'
import UserPicture from '@/components/User/UserPicture.vue' import UserPicture from '@/components/User/UserPicture.vue'
import { AUTH_USER_STORE, ROOT_STORE } from '@/store/constants' import { AUTH_USER_STORE, ROOT_STORE } from '@/store/constants'
import { IDropdownOption } from '@/types/forms' import type { IDropdownOption } from '@/types/forms'
import { IAuthUserProfile } from '@/types/user' import type { IAuthUserProfile } from '@/types/user'
import { useStore } from '@/use/useStore' import { useStore } from '@/use/useStore'
import { availableLanguages } from '@/utils/locales' import { availableLanguages } from '@/utils/locales'

View File

@ -25,11 +25,12 @@
<script lang="ts" setup> <script lang="ts" setup>
import snarkdown from 'snarkdown' import snarkdown from 'snarkdown'
import { ComputedRef, capitalize, computed } from 'vue' import { capitalize, computed } from 'vue'
import type { ComputedRef } from 'vue'
import { AUTH_USER_STORE, ROOT_STORE } from '@/store/constants' import { AUTH_USER_STORE, ROOT_STORE } from '@/store/constants'
import { TAppConfig } from '@/types/application' import type { TAppConfig } from '@/types/application'
import { IAuthUserProfile } from '@/types/user' import type { IAuthUserProfile } from '@/types/user'
import { useStore } from '@/use/useStore' import { useStore } from '@/use/useStore'
import { dateStringFormats, formatDate } from '@/utils/dates' import { dateStringFormats, formatDate } from '@/utils/dates'
import { linkifyAndClean } from '@/utils/inputs' import { linkifyAndClean } from '@/utils/inputs'

View File

@ -10,12 +10,9 @@
</div> </div>
</template> </template>
<script setup lang="ts">
</script>
<style scoped lang="scss"> <style scoped lang="scss">
@import '~@/scss/vars.scss'; @import '~@/scss/vars.scss';
.privacy-policy-message { .privacy-policy-message {
background: var(--alert-background-color); background: var(--alert-background-color);
color: var(--alert-color); color: var(--alert-color);

View File

@ -8,7 +8,7 @@
> >
<input <input
type="checkbox" type="checkbox"
:id="sport.id" :id="`${sport.id}`"
:name="sport.label" :name="sport.label"
:checked="selectedSportIds.includes(sport.id)" :checked="selectedSportIds.includes(sport.id)"
@input="updateSelectedSportIds(sport.id)" @input="updateSelectedSportIds(sport.id)"
@ -20,10 +20,11 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ComputedRef, computed, inject, withDefaults, toRefs } from 'vue' import { computed, inject, toRefs } from 'vue'
import type { ComputedRef } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { ISport, ITranslatedSport } from '@/types/sports' import type { ISport, ITranslatedSport } from '@/types/sports'
import { translateSports } from '@/utils/sports' import { translateSports } from '@/utils/sports'
interface Props { interface Props {
@ -38,7 +39,7 @@
const { t } = useI18n() const { t } = useI18n()
const sportColors = inject('sportColors') const sportColors: Record<string, string> | undefined = inject('sportColors')
const { selectedSportIds } = toRefs(props) const { selectedSportIds } = toRefs(props)
const translatedSports: ComputedRef<ITranslatedSport[]> = computed(() => const translatedSports: ComputedRef<ITranslatedSport[]> = computed(() =>
translateSports(props.userSports, t) translateSports(props.userSports, t)

View File

@ -22,15 +22,16 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ComputedRef, Ref, computed, ref, toRefs, watch } from 'vue' import { computed, ref, toRefs, watch } from 'vue'
import type { ComputedRef, Ref } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import StatChart from '@/components/Common/StatsChart/index.vue' import StatChart from '@/components/Common/StatsChart/index.vue'
import StatsMenu from '@/components/Statistics/StatsMenu.vue' import StatsMenu from '@/components/Statistics/StatsMenu.vue'
import SportsMenu from '@/components/Statistics/StatsSportsMenu.vue' import SportsMenu from '@/components/Statistics/StatsSportsMenu.vue'
import { ISport, ITranslatedSport } from '@/types/sports' import type { ISport, ITranslatedSport } from '@/types/sports'
import { IStatisticsDateParams } from '@/types/statistics' import type { IStatisticsDateParams } from '@/types/statistics'
import { IAuthUserProfile } from '@/types/user' import type { IAuthUserProfile } from '@/types/user'
import { translateSports } from '@/utils/sports' import { translateSports } from '@/utils/sports'
import { getStatsDateParams, updateChartParams } from '@/utils/statistics' import { getStatsDateParams, updateChartParams } from '@/utils/statistics'

View File

@ -10,7 +10,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { toRefs, withDefaults } from 'vue' import { toRefs } from 'vue'
import UserAuthForm from '@/components/User/UserAuthForm.vue' import UserAuthForm from '@/components/User/UserAuthForm.vue'

View File

@ -34,11 +34,12 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { computed, ComputedRef, toRefs } from 'vue' import { computed, toRefs } from 'vue'
import type { ComputedRef } from 'vue'
import UserPicture from '@/components/User/UserPicture.vue' import UserPicture from '@/components/User/UserPicture.vue'
import { AUTH_USER_STORE } from '@/store/constants' import { AUTH_USER_STORE } from '@/store/constants'
import { IAuthUserProfile, IUserProfile } from '@/types/user' import type { IAuthUserProfile, IUserProfile } from '@/types/user'
import { useStore } from '@/use/useStore' import { useStore } from '@/use/useStore'
interface Props { interface Props {

View File

@ -120,20 +120,12 @@
<script setup lang="ts"> <script setup lang="ts">
import { format } from 'date-fns' import { format } from 'date-fns'
import { import { computed, ref, toRefs, watch, onUnmounted } from 'vue'
ComputedRef, import type { ComputedRef, Ref } from 'vue'
Ref,
computed,
ref,
toRefs,
withDefaults,
watch,
onUnmounted,
} from 'vue'
import { AUTH_USER_STORE, ROOT_STORE, USERS_STORE } from '@/store/constants' import { AUTH_USER_STORE, ROOT_STORE, USERS_STORE } from '@/store/constants'
import { TAppConfig } from '@/types/application' import type { TAppConfig } from '@/types/application'
import { IAuthUserProfile, IUserProfile } from '@/types/user' import type { IAuthUserProfile, IUserProfile } from '@/types/user'
import { useStore } from '@/use/useStore' import { useStore } from '@/use/useStore'
import { formatDate, getDateFormat } from '@/utils/dates' import { formatDate, getDateFormat } from '@/utils/dates'
import { localeFromLanguage } from '@/utils/locales' import { localeFromLanguage } from '@/utils/locales'

View File

@ -56,10 +56,11 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { computed, ComputedRef } from 'vue' import { computed } from 'vue'
import type { ComputedRef } from 'vue'
import { ROOT_STORE } from '@/store/constants' import { ROOT_STORE } from '@/store/constants'
import { IAuthUserProfile } from '@/types/user' import type { IAuthUserProfile } from '@/types/user'
import { useStore } from '@/use/useStore' import { useStore } from '@/use/useStore'
import { getDateFormat } from '@/utils/dates' import { getDateFormat } from '@/utils/dates'
import { languageLabels } from '@/utils/locales' import { languageLabels } from '@/utils/locales'

View File

@ -13,7 +13,7 @@
import UserHeader from '@/components/User/ProfileDisplay/UserHeader.vue' import UserHeader from '@/components/User/ProfileDisplay/UserHeader.vue'
import UserProfileTabs from '@/components/User/UserProfileTabs.vue' import UserProfileTabs from '@/components/User/UserProfileTabs.vue'
import { IUserProfile } from '@/types/user' import type { IUserProfile } from '@/types/user'
interface Props { interface Props {
user: IUserProfile user: IUserProfile

View File

@ -28,7 +28,8 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { Ref, ref, toRefs, watch, withDefaults } from 'vue' import { ref, toRefs, watch } from 'vue'
import type { Ref } from 'vue'
import { timeZones } from '@/utils/timezone' import { timeZones } from '@/utils/timezone'

View File

@ -105,8 +105,6 @@
<script setup lang="ts"> <script setup lang="ts">
import { isBefore, subDays } from 'date-fns' import { isBefore, subDays } from 'date-fns'
import { import {
ComputedRef,
Ref,
computed, computed,
reactive, reactive,
ref, ref,
@ -115,12 +113,13 @@
watch, watch,
onUnmounted, onUnmounted,
} from 'vue' } from 'vue'
import type { ComputedRef, Ref } from 'vue'
import authApi from '@/api/authApi' import authApi from '@/api/authApi'
import PasswordInput from '@/components/Common/PasswordInput.vue' import PasswordInput from '@/components/Common/PasswordInput.vue'
import { AUTH_USER_STORE, ROOT_STORE } from '@/store/constants' import { AUTH_USER_STORE, ROOT_STORE } from '@/store/constants'
import { TAppConfig } from '@/types/application' import type { TAppConfig } from '@/types/application'
import { import type {
IAuthUserProfile, IAuthUserProfile,
IUserAccountPayload, IUserAccountPayload,
IExportRequest, IExportRequest,

View File

@ -62,10 +62,15 @@
<script setup lang="ts"> <script setup lang="ts">
import { format } from 'date-fns' import { format } from 'date-fns'
import { ComputedRef, computed, reactive, onMounted, onUnmounted } from 'vue' import { computed, reactive, onMounted, onUnmounted } from 'vue'
import type { ComputedRef } from 'vue'
import { AUTH_USER_STORE, ROOT_STORE } from '@/store/constants' import { AUTH_USER_STORE, ROOT_STORE } from '@/store/constants'
import { IUserProfile, IUserPayload, IAuthUserProfile } from '@/types/user' import type {
IUserProfile,
IUserPayload,
IAuthUserProfile,
} from '@/types/user'
import { useStore } from '@/use/useStore' import { useStore } from '@/use/useStore'
import { formatDate } from '@/utils/dates' import { formatDate } from '@/utils/dates'

View File

@ -33,12 +33,13 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ComputedRef, Ref, computed, ref, toRefs, onUnmounted } from 'vue' import { computed, ref, toRefs, onUnmounted } from 'vue'
import type { ComputedRef, Ref } from 'vue'
import UserPicture from '@/components/User/UserPicture.vue' import UserPicture from '@/components/User/UserPicture.vue'
import { AUTH_USER_STORE, ROOT_STORE } from '@/store/constants' import { AUTH_USER_STORE, ROOT_STORE } from '@/store/constants'
import { TAppConfig } from '@/types/application' import type { TAppConfig } from '@/types/application'
import { IUserProfile } from '@/types/user' import type { IUserProfile } from '@/types/user'
import { useStore } from '@/use/useStore' import { useStore } from '@/use/useStore'
import { getReadableFileSize } from '@/utils/files' import { getReadableFileSize } from '@/utils/files'

View File

@ -165,11 +165,12 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ComputedRef, computed, reactive, onMounted, onUnmounted } from 'vue' import { computed, reactive, onMounted, onUnmounted } from 'vue'
import type { ComputedRef } from 'vue'
import TimezoneDropdown from '@/components/User/ProfileEdition/TimezoneDropdown.vue' import TimezoneDropdown from '@/components/User/ProfileEdition/TimezoneDropdown.vue'
import { AUTH_USER_STORE, ROOT_STORE } from '@/store/constants' import { AUTH_USER_STORE, ROOT_STORE } from '@/store/constants'
import { IUserPreferencesPayload, IAuthUserProfile } from '@/types/user' import type { IUserPreferencesPayload, IAuthUserProfile } from '@/types/user'
import { useStore } from '@/use/useStore' import { useStore } from '@/use/useStore'
import { availableDateFormatOptions } from '@/utils/dates' import { availableDateFormatOptions } from '@/utils/dates'
import { availableLanguages } from '@/utils/locales' import { availableLanguages } from '@/utils/locales'

View File

@ -17,10 +17,7 @@
<div class="policy-content"> <div class="policy-content">
<PrivacyPolicy /> <PrivacyPolicy />
</div> </div>
<label <label for="accepted_policy" class="accepted_policy">
for="accepted_policy"
class="accepted_policy"
>
<input <input
type="checkbox" type="checkbox"
id="accepted_policy" id="accepted_policy"
@ -49,11 +46,12 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ComputedRef, computed, ref, onUnmounted, toRefs } from 'vue' import { computed, ref, onUnmounted, toRefs } from 'vue'
import type { ComputedRef } from 'vue'
import PrivacyPolicy from '@/components/PrivacyPolicy.vue' import PrivacyPolicy from '@/components/PrivacyPolicy.vue'
import { AUTH_USER_STORE, ROOT_STORE } from '@/store/constants' import { AUTH_USER_STORE, ROOT_STORE } from '@/store/constants'
import { IAuthUserProfile } from '@/types/user' import type { IAuthUserProfile } from '@/types/user'
import { useStore } from '@/use/useStore' import { useStore } from '@/use/useStore'
interface Props { interface Props {
@ -71,7 +69,8 @@
function onSubmit() { function onSubmit() {
store.dispatch( store.dispatch(
AUTH_USER_STORE.ACTIONS.ACCEPT_PRIVACY_POLICY, acceptedPolicy.value AUTH_USER_STORE.ACTIONS.ACCEPT_PRIVACY_POLICY,
acceptedPolicy.value
) )
} }
@ -100,7 +99,7 @@
@media screen and (max-width: $small-limit) { @media screen and (max-width: $small-limit) {
margin: $default-margin 0; margin: $default-margin 0;
font-size: .9em; font-size: 0.9em;
} }
.privacy-policy-text { .privacy-policy-text {

View File

@ -22,7 +22,7 @@
import UserProfileTabs from '@/components/User/UserProfileTabs.vue' import UserProfileTabs from '@/components/User/UserProfileTabs.vue'
import { AUTH_USER_STORE } from '@/store/constants' import { AUTH_USER_STORE } from '@/store/constants'
import { IUserProfile } from '@/types/user' import type { IUserProfile } from '@/types/user'
import { useStore } from '@/use/useStore' import { useStore } from '@/use/useStore'
interface Props { interface Props {
@ -34,7 +34,14 @@
const store = useStore() const store = useStore()
const { user, tab } = toRefs(props) const { user, tab } = toRefs(props)
const tabs = ['PROFILE', 'ACCOUNT', 'PICTURE', 'PREFERENCES', 'SPORTS', 'PRIVACY-POLICY'] const tabs = [
'PROFILE',
'ACCOUNT',
'PICTURE',
'PREFERENCES',
'SPORTS',
'PRIVACY-POLICY',
]
const loading = computed( const loading = computed(
() => store.getters[AUTH_USER_STORE.GETTERS.USER_LOADING] () => store.getters[AUTH_USER_STORE.GETTERS.USER_LOADING]
) )

View File

@ -89,8 +89,8 @@
import { computed, reactive } from 'vue' import { computed, reactive } from 'vue'
import { OAUTH2_STORE } from '@/store/constants' import { OAUTH2_STORE } from '@/store/constants'
import { IOAuth2ClientPayload } from '@/types/oauth' import type { IOAuth2ClientPayload } from '@/types/oauth'
import { IAuthUserProfile } from '@/types/user' import type { IAuthUserProfile } from '@/types/user'
import { useStore } from '@/use/useStore' import { useStore } from '@/use/useStore'
import { admin_oauth2_scopes, oauth2_scopes } from '@/utils/oauth' import { admin_oauth2_scopes, oauth2_scopes } from '@/utils/oauth'

View File

@ -39,11 +39,12 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { computed, ComputedRef, onBeforeMount } from 'vue' import { computed, onBeforeMount } from 'vue'
import type { ComputedRef } from 'vue'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import { OAUTH2_STORE, ROOT_STORE } from '@/store/constants' import { OAUTH2_STORE, ROOT_STORE } from '@/store/constants'
import { IOAuth2Client } from '@/types/oauth' import type { IOAuth2Client } from '@/types/oauth'
import { useStore } from '@/use/useStore' import { useStore } from '@/use/useStore'
const route = useRoute() const route = useRoute()

View File

@ -110,17 +110,15 @@
<script setup lang="ts"> <script setup lang="ts">
import { import {
ComputedRef,
Ref,
capitalize, capitalize,
computed, computed,
onBeforeMount, onBeforeMount,
toRefs, toRefs,
ref, ref,
onUnmounted, onUnmounted,
withDefaults,
watch, watch,
} from 'vue' } from 'vue'
import type { ComputedRef, Ref } from 'vue'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import { OAUTH2_STORE, ROOT_STORE } from '@/store/constants' import { OAUTH2_STORE, ROOT_STORE } from '@/store/constants'

View File

@ -37,14 +37,16 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ComputedRef, computed, onBeforeMount, toRefs, watch } from 'vue' import { computed, onBeforeMount, toRefs, watch } from 'vue'
import { LocationQuery, useRoute } from 'vue-router' import type { ComputedRef } from 'vue'
import { useRoute } from 'vue-router'
import type { LocationQuery } from 'vue-router'
import Pagination from '@/components/Common/Pagination.vue' import Pagination from '@/components/Common/Pagination.vue'
import { OAUTH2_STORE } from '@/store/constants' import { OAUTH2_STORE } from '@/store/constants'
import { IPagination } from '@/types/api' import type { IPagination } from '@/types/api'
import { IOAuth2Client, IOauth2ClientsPayload } from '@/types/oauth' import type { IOAuth2Client, IOauth2ClientsPayload } from '@/types/oauth'
import { IAuthUserProfile } from '@/types/user' import type { IAuthUserProfile } from '@/types/user'
import { useStore } from '@/use/useStore' import { useStore } from '@/use/useStore'
import { defaultPage, getNumberQueryValue } from '@/utils/api' import { defaultPage, getNumberQueryValue } from '@/utils/api'
import { formatDate } from '@/utils/dates' import { formatDate } from '@/utils/dates'

View File

@ -8,7 +8,7 @@
import { onUnmounted, toRefs } from 'vue' import { onUnmounted, toRefs } from 'vue'
import { OAUTH2_STORE, ROOT_STORE } from '@/store/constants' import { OAUTH2_STORE, ROOT_STORE } from '@/store/constants'
import { IAuthUserProfile } from '@/types/user' import type { IAuthUserProfile } from '@/types/user'
import { useStore } from '@/use/useStore' import { useStore } from '@/use/useStore'
interface Props { interface Props {

View File

@ -163,22 +163,14 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { import { computed, onUnmounted, reactive, ref, toRefs, watch } from 'vue'
ComputedRef, import type { ComputedRef } from 'vue'
computed,
onUnmounted,
reactive,
ref,
toRefs,
watch,
withDefaults,
} from 'vue'
import { useRoute } from 'vue-router' import { useRoute } from 'vue-router'
import PasswordInput from '@/components/Common/PasswordInput.vue' import PasswordInput from '@/components/Common/PasswordInput.vue'
import { AUTH_USER_STORE, ROOT_STORE } from '@/store/constants' import { AUTH_USER_STORE, ROOT_STORE } from '@/store/constants'
import { TAppConfig } from '@/types/application' import type { TAppConfig } from '@/types/application'
import { ILoginRegisterFormData } from '@/types/user' import type { ILoginRegisterFormData } from '@/types/user'
import { useStore } from '@/use/useStore' import { useStore } from '@/use/useStore'
interface Props { interface Props {
@ -197,7 +189,7 @@
username: '', username: '',
email: '', email: '',
password: '', password: '',
accepted_policy: false accepted_policy: false,
}) })
const buttonText: ComputedRef<string> = computed(() => const buttonText: ComputedRef<string> = computed(() =>
getButtonText(props.action) getButtonText(props.action)
@ -336,7 +328,7 @@
.accepted_policy { .accepted_policy {
display: flex; display: flex;
align-items: center; align-items: center;
font-size: .85em; font-size: 0.85em;
font-weight: normal; font-weight: normal;
} }
} }

View File

@ -15,7 +15,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { computed } from 'vue' import { computed } from 'vue'
import { IUserProfile } from '@/types/user' import type { IUserProfile } from '@/types/user'
import { getApiUrl } from '@/utils' import { getApiUrl } from '@/utils'
interface Props { interface Props {

View File

@ -26,7 +26,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { onMounted, toRefs, withDefaults } from 'vue' import { onMounted, toRefs } from 'vue'
interface Props { interface Props {
tabs: string[] tabs: string[]

View File

@ -165,12 +165,13 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ComputedRef, computed, inject, reactive, toRefs, watch } from 'vue' import { computed, inject, reactive, toRefs, watch } from 'vue'
import type { ComputedRef } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { AUTH_USER_STORE, ROOT_STORE, SPORTS_STORE } from '@/store/constants' import { AUTH_USER_STORE, ROOT_STORE, SPORTS_STORE } from '@/store/constants'
import { ISport, ITranslatedSport } from '@/types/sports' import type { ISport, ITranslatedSport } from '@/types/sports'
import { IUserProfile, IUserSportPreferencesPayload } from '@/types/user' import type { IUserProfile, IUserSportPreferencesPayload } from '@/types/user'
import { useStore } from '@/use/useStore' import { useStore } from '@/use/useStore'
import { translateSports } from '@/utils/sports' import { translateSports } from '@/utils/sports'

View File

@ -138,15 +138,17 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { Locale, formatDistance } from 'date-fns' import { formatDistance } from 'date-fns'
import { ComputedRef, computed, toRefs, withDefaults } from 'vue' import type { Locale } from 'date-fns'
import { computed, toRefs } from 'vue'
import type { ComputedRef } from 'vue'
import StaticMap from '@/components/Common/StaticMap.vue' import StaticMap from '@/components/Common/StaticMap.vue'
import UserPicture from '@/components/User/UserPicture.vue' import UserPicture from '@/components/User/UserPicture.vue'
import { ROOT_STORE } from '@/store/constants' import { ROOT_STORE } from '@/store/constants'
import { ISport } from '@/types/sports' import type { ISport } from '@/types/sports'
import { IUserProfile } from '@/types/user' import type { IUserProfile } from '@/types/user'
import { IWorkout } from '@/types/workouts' import type { IWorkout } from '@/types/workouts'
import { useStore } from '@/use/useStore' import { useStore } from '@/use/useStore'
import { formatDate } from '@/utils/dates' import { formatDate } from '@/utils/dates'
@ -157,8 +159,8 @@
sport?: ISport sport?: ISport
} }
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
workout: () => ({} as IWorkout), workout: () => ({}) as IWorkout,
sport: () => ({} as ISport), sport: () => ({}) as ISport,
}) })
const store = useStore() const store = useStore()

View File

@ -19,7 +19,7 @@
import { toRefs } from 'vue' import { toRefs } from 'vue'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { IWeather } from '@/types/workouts' import type { IWeather } from '@/types/workouts'
import { getWindSpeed } from '@/utils/units' import { getWindSpeed } from '@/utils/units'
import { convertDegreeToDirection } from '@/utils/weather' import { convertDegreeToDirection } from '@/utils/weather'

View File

@ -100,8 +100,8 @@
import { toRefs } from 'vue' import { toRefs } from 'vue'
import authApi from '@/api/authApi' import authApi from '@/api/authApi'
import { ISport } from '@/types/sports' import type { ISport } from '@/types/sports'
import { IWorkoutObject } from '@/types/workouts' import type { IWorkoutObject } from '@/types/workouts'
interface Props { interface Props {
sport: ISport sport: ISport

View File

@ -51,15 +51,16 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { ChartData, ChartOptions } from 'chart.js' import type { ChartData, ChartOptions } from 'chart.js'
import { ComputedRef, computed, ref, toRefs } from 'vue' import { computed, ref, toRefs } from 'vue'
import type { ComputedRef } from 'vue'
import { LineChart, useLineChart } from 'vue-chart-3' import { LineChart, useLineChart } from 'vue-chart-3'
import { useI18n } from 'vue-i18n' import { useI18n } from 'vue-i18n'
import { htmlLegendPlugin } from '@/components/Workout/WorkoutDetail/WorkoutChart/legend' import { htmlLegendPlugin } from '@/components/Workout/WorkoutDetail/WorkoutChart/legend'
import { TUnit } from '@/types/units' import type { TUnit } from '@/types/units'
import { IAuthUserProfile } from '@/types/user' import type { IAuthUserProfile } from '@/types/user'
import { import type {
IWorkoutChartData, IWorkoutChartData,
IWorkoutData, IWorkoutData,
TCoordinates, TCoordinates,

View File

@ -1,4 +1,5 @@
import { Chart, LegendItem } from 'chart.js' import { Chart } from 'chart.js'
import type { LegendItem } from 'chart.js'
const getOrCreateLegendList = (id: string): HTMLUListElement => { const getOrCreateLegendList = (id: string): HTMLUListElement => {
const legendContainer = document.getElementById(id) const legendContainer = document.getElementById(id)

View File

@ -114,7 +114,7 @@
import WorkoutRecord from '@/components/Workout/WorkoutDetail/WorkoutRecord.vue' import WorkoutRecord from '@/components/Workout/WorkoutDetail/WorkoutRecord.vue'
import WorkoutWeather from '@/components/Workout/WorkoutDetail/WorkoutWeather.vue' import WorkoutWeather from '@/components/Workout/WorkoutDetail/WorkoutWeather.vue'
import { IWorkoutObject } from '@/types/workouts' import type { IWorkoutObject } from '@/types/workouts'
interface Props { interface Props {
workoutObject: IWorkoutObject workoutObject: IWorkoutObject

View File

@ -14,7 +14,7 @@
import { LIcon, LMarker } from '@vue-leaflet/vue-leaflet' import { LIcon, LMarker } from '@vue-leaflet/vue-leaflet'
import { toRefs } from 'vue' import { toRefs } from 'vue'
import { TCoordinates } from '@/types/workouts' import type { TCoordinates } from '@/types/workouts'
interface Props { interface Props {
markerCoordinates: TCoordinates markerCoordinates: TCoordinates

View File

@ -16,6 +16,7 @@
:zoomAnimation="false" :zoomAnimation="false"
ref="workoutMap" ref="workoutMap"
@ready="fitBounds(bounds)" @ready="fitBounds(bounds)"
:use-global-leaflet="false"
> >
<LControlLayers /> <LControlLayers />
<LControl <LControl
@ -90,14 +91,15 @@
LMarker, LMarker,
LTileLayer, LTileLayer,
} from '@vue-leaflet/vue-leaflet' } from '@vue-leaflet/vue-leaflet'
import { ComputedRef, computed, ref, toRefs, withDefaults } from 'vue' import { computed, ref, toRefs } from 'vue'
import type { ComputedRef } from 'vue'
import 'leaflet/dist/leaflet.css' import 'leaflet/dist/leaflet.css'
import CustomMarker from '@/components/Workout/WorkoutDetail/WorkoutMap/CustomMarker.vue' import CustomMarker from '@/components/Workout/WorkoutDetail/WorkoutMap/CustomMarker.vue'
import { ROOT_STORE } from '@/store/constants' import { ROOT_STORE } from '@/store/constants'
import { TAppConfig } from '@/types/application' import type { TAppConfig } from '@/types/application'
import { GeoJSONData } from '@/types/geojson' import type { GeoJSONData } from '@/types/geojson'
import { IWorkoutData, TCoordinates } from '@/types/workouts' import type { IWorkoutData, TCoordinates } from '@/types/workouts'
import { useStore } from '@/use/useStore' import { useStore } from '@/use/useStore'
import { getApiUrl } from '@/utils' import { getApiUrl } from '@/utils'
@ -106,7 +108,7 @@
markerCoordinates?: TCoordinates markerCoordinates?: TCoordinates
} }
const props = withDefaults(defineProps<Props>(), { const props = withDefaults(defineProps<Props>(), {
markerCoordinates: () => ({} as TCoordinates), markerCoordinates: () => ({}) as TCoordinates,
}) })
const store = useStore() const store = useStore()

View File

@ -16,7 +16,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { toRefs, withDefaults } from 'vue' import { toRefs } from 'vue'
import { linkifyAndClean } from '@/utils/inputs' import { linkifyAndClean } from '@/utils/inputs'

View File

@ -15,7 +15,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { toRefs } from 'vue' import { toRefs } from 'vue'
import { IWorkoutObject } from '@/types/workouts' import type { IWorkoutObject } from '@/types/workouts'
interface Props { interface Props {
recordType: string recordType: string

View File

@ -31,7 +31,7 @@
<script setup lang="ts"> <script setup lang="ts">
import { toRefs } from 'vue' import { toRefs } from 'vue'
import { IWorkoutSegment } from '@/types/workouts' import type { IWorkoutSegment } from '@/types/workouts'
interface Props { interface Props {
segments: IWorkoutSegment[] segments: IWorkoutSegment[]

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