Client - upgrade Vue to 3.3 and move to Vite
This commit is contained in:
parent
91455251e1
commit
1befae927d
7
Makefile
7
Makefile
@ -194,7 +194,7 @@ lint-client:
|
||||
cd fittrackee_client && $(NPM) lint
|
||||
|
||||
lint-client-fix:
|
||||
cd fittrackee_client && $(NPM) lint-fix
|
||||
cd fittrackee_client && $(NPM) format
|
||||
|
||||
lint-python:
|
||||
$(PYTEST) --isort --black -m "isort or black" fittrackee e2e --ignore=fittrackee/migrations
|
||||
@ -233,7 +233,7 @@ serve-dev:
|
||||
|
||||
serve-client:
|
||||
# for dev environments
|
||||
cd fittrackee_client && PORT=3000 $(NPM) serve
|
||||
cd fittrackee_client && PORT=3000 $(NPM) dev
|
||||
|
||||
serve-python:
|
||||
# for dev environments
|
||||
@ -269,6 +269,9 @@ type-check:
|
||||
echo 'Running mypy...'
|
||||
$(MYPY) fittrackee
|
||||
|
||||
type-check-client:
|
||||
cd fittrackee_client && $(NPM) type-check
|
||||
|
||||
upgrade-db:
|
||||
$(FTCLI) db upgrade
|
||||
|
||||
|
@ -1,2 +1,2 @@
|
||||
VUE_APP_API_URL=http://localhost:5000
|
||||
VITE_APP_API_URL=http://localhost:5000
|
||||
PORT=3000
|
18
fittrackee_client/.eslintrc.cjs
Normal file
18
fittrackee_client/.eslintrc.cjs
Normal 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
28
fittrackee_client/.gitignore
vendored
Normal 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?
|
@ -1,4 +1,5 @@
|
||||
{
|
||||
"$schema": "https://json.schemastore.org/prettierrc",
|
||||
"tabWidth": 2,
|
||||
"semi": false,
|
||||
"singleQuote": true,
|
||||
@ -9,4 +10,4 @@
|
||||
"printWidth": 80,
|
||||
"endOfLine": "auto",
|
||||
"vueIndentScriptAndStyle": true
|
||||
}
|
||||
}
|
@ -1,29 +1,46 @@
|
||||
# fittrackee_client
|
||||
|
||||
## Project setup
|
||||
```
|
||||
yarn install
|
||||
This template should help get you started developing with Vue 3 in Vite.
|
||||
|
||||
## 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
|
||||
```
|
||||
yarn serve
|
||||
### Compile and Hot-Reload for Development
|
||||
|
||||
```sh
|
||||
yarn dev
|
||||
```
|
||||
|
||||
### Compiles and minifies for production
|
||||
```
|
||||
### Type-Check, Compile and Minify for Production
|
||||
|
||||
```sh
|
||||
yarn build
|
||||
```
|
||||
|
||||
### Run your unit tests
|
||||
```
|
||||
yarn test:unit
|
||||
```
|
||||
### Lint with [ESLint](https://eslint.org/)
|
||||
|
||||
### Lints and fixes files
|
||||
```
|
||||
```sh
|
||||
yarn lint
|
||||
```
|
||||
|
||||
### Customize configuration
|
||||
See [Configuration Reference](https://cli.vuejs.org/config/).
|
||||
|
@ -1,3 +0,0 @@
|
||||
module.exports = {
|
||||
presets: ['@vue/cli-plugin-babel/preset'],
|
||||
}
|
1
fittrackee_client/env.d.ts
vendored
Normal file
1
fittrackee_client/env.d.ts
vendored
Normal file
@ -0,0 +1 @@
|
||||
/// <reference types="vite/client" />
|
15
fittrackee_client/index.html
Normal file
15
fittrackee_client/index.html
Normal 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>
|
@ -3,127 +3,63 @@
|
||||
"version": "0.7.25",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"serve": "vue-cli-service serve",
|
||||
"build": "vue-cli-service build",
|
||||
"test:unit": "vue-cli-service test:unit",
|
||||
"lint": "vue-cli-service lint",
|
||||
"lint-fix": "vue-cli-service lint --fix",
|
||||
"i18n:report": "vue-cli-service i18n:report --src \"./src/**/*.?(js|vue)\" --locales \"./src/locales/**/*.json\""
|
||||
"dev": "vite",
|
||||
"build": "run-p type-check \"build-only {@}\" --",
|
||||
"preview": "vite preview",
|
||||
"build-only": "vite build",
|
||||
"type-check": "vue-tsc --noEmit -p tsconfig.app.json --composite false",
|
||||
"lint": "eslint . --ext .vue,.js,.jsx,.cjs,.mjs,.ts,.tsx,.cts,.mts --fix --ignore-path .gitignore",
|
||||
"format": "prettier --write src/"
|
||||
},
|
||||
"dependencies": {
|
||||
"@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/language-common": "^3.0.3",
|
||||
"@zxcvbn-ts/language-common": "^3.0.4",
|
||||
"@zxcvbn-ts/language-de": "^3.0.2",
|
||||
"@zxcvbn-ts/language-en": "^3.0.2",
|
||||
"@zxcvbn-ts/language-es-es": "^3.0.2",
|
||||
"@zxcvbn-ts/language-fr": "^3.0.2",
|
||||
"@zxcvbn-ts/language-it": "^3.0.2",
|
||||
"@zxcvbn-ts/language-pl": "^3.0.2",
|
||||
"axios": "^1.5.1",
|
||||
"axios": "^1.6.1",
|
||||
"chart.js": "^4.4.0",
|
||||
"chartjs-plugin-datalabels": "^2.2.0",
|
||||
"core-js": "^3.33.0",
|
||||
"date-fns": "2.29.3",
|
||||
"core-js": "^3.33.2",
|
||||
"date-fns": "2.30.0",
|
||||
"date-fns-tz": "^2.0.0",
|
||||
"leaflet": "^1.9.4",
|
||||
"linkify-html": "^4.1.1",
|
||||
"linkifyjs": "^4.1.1",
|
||||
"register-service-worker": "^1.7.1",
|
||||
"linkify-html": "^4.1.2",
|
||||
"linkifyjs": "^4.1.2",
|
||||
"sanitize-html": "^2.11.0",
|
||||
"snarkdown": "^2.0.0",
|
||||
"vue": "3.2.47",
|
||||
"vue-chart-3": "3.1.1",
|
||||
"vue": "^3.3.8",
|
||||
"vue-chart-3": "^3.1.8",
|
||||
"vue-fullscreen": "^3.1.1",
|
||||
"vue-i18n": "^9.5.0",
|
||||
"vue-i18n": "^9.6.5",
|
||||
"vue-router": "^4.2.5",
|
||||
"vuex": "^4.1.0"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@intlify/vue-i18n-loader": "^4.2.0",
|
||||
"@types/chai": "^4.3.6",
|
||||
"@types/mocha": "^10.0.2",
|
||||
"@types/sanitize-html": "^2.9.1",
|
||||
"@typescript-eslint/eslint-plugin": "^5.60.0",
|
||||
"@typescript-eslint/parser": "^5.60.0",
|
||||
"@vue/cli-plugin-babel": "~5.0.8",
|
||||
"@vue/cli-plugin-eslint": "~5.0.8",
|
||||
"@vue/cli-plugin-pwa": "~5.0.8",
|
||||
"@vue/cli-plugin-router": "~5.0.8",
|
||||
"@vue/cli-plugin-typescript": "~5.0.8",
|
||||
"@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",
|
||||
"@rushstack/eslint-patch": "^1.3.3",
|
||||
"@tsconfig/node18": "^18.2.2",
|
||||
"@types/chai": "^4.3.10",
|
||||
"@types/mocha": "^10.0.4",
|
||||
"@types/node": "^20.9.0",
|
||||
"@types/sanitize-html": "^2.9.4",
|
||||
"@vitejs/plugin-vue": "^4.4.0",
|
||||
"@vue/eslint-config-prettier": "^8.0.0",
|
||||
"@vue/eslint-config-typescript": "^12.0.0",
|
||||
"@vue/tsconfig": "^0.4.0",
|
||||
"chai": "^4.3.10",
|
||||
"eslint": "8.42.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": "^8.49.0",
|
||||
"eslint-plugin-vue": "^9.17.0",
|
||||
"prettier": "^2.8.8",
|
||||
"sass": "^1.68.0",
|
||||
"sass-loader": "^13.3.2",
|
||||
"typescript": "5.0.4",
|
||||
"vue-cli-plugin-i18n": "~2.3.2"
|
||||
},
|
||||
"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"
|
||||
]
|
||||
"npm-run-all2": "^6.1.1",
|
||||
"prettier": "^3.0.3",
|
||||
"sass": "^1.69.5",
|
||||
"typescript": "~5.2.0",
|
||||
"vite": "^4.4.11",
|
||||
"vue-tsc": "^1.8.19"
|
||||
}
|
||||
}
|
||||
|
@ -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>
|
@ -29,13 +29,14 @@
|
||||
</template>
|
||||
|
||||
<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 NavBar from '@/components/NavBar.vue'
|
||||
import NoConfig from '@/components/NoConfig.vue'
|
||||
import { ROOT_STORE } from '@/store/constants'
|
||||
import { TAppConfig } from '@/types/application'
|
||||
import type { TAppConfig } from '@/types/application'
|
||||
import { useStore } from '@/use/useStore'
|
||||
import { localeFromLanguage } from '@/utils/locales'
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { AxiosRequestConfig } from 'axios'
|
||||
import type { AxiosRequestConfig } from 'axios'
|
||||
|
||||
export const pendingRequests = new Map()
|
||||
|
||||
|
@ -49,9 +49,7 @@
|
||||
</div>
|
||||
<template v-if="appConfig.about">
|
||||
<p class="about-instance">{{ $t('about.ABOUT_THIS_INSTANCE') }}</p>
|
||||
<div
|
||||
v-html="snarkdown(linkifyAndClean(appConfig.about))"
|
||||
/>
|
||||
<div v-html="snarkdown(linkifyAndClean(appConfig.about))" />
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
@ -59,10 +57,11 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
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 { TAppConfig } from '@/types/application'
|
||||
import type { TAppConfig } from '@/types/application'
|
||||
import { useStore } from '@/use/useStore'
|
||||
import { linkifyAndClean } from '@/utils/inputs'
|
||||
|
||||
@ -113,7 +112,7 @@
|
||||
}
|
||||
.about-instance {
|
||||
font-weight: bold;
|
||||
margin-top: $default-margin*3;
|
||||
margin-top: $default-margin * 3;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -73,7 +73,7 @@
|
||||
:disabled="!edition"
|
||||
/>
|
||||
</label>
|
||||
<label class="about-label" for="about">
|
||||
<label class="about-label" for="about">
|
||||
{{ $t('admin.ABOUT.TEXT') }}:
|
||||
</label>
|
||||
<span class="textarea-description">
|
||||
@ -88,7 +88,13 @@
|
||||
/>
|
||||
<div
|
||||
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"
|
||||
/>
|
||||
<label class="privacy-policy-label" for="privacy_policy">
|
||||
@ -106,7 +112,15 @@
|
||||
/>
|
||||
<div
|
||||
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"
|
||||
/>
|
||||
<ErrorMessage :message="errorMessages" v-if="errorMessages" />
|
||||
@ -137,19 +151,12 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import snarkdown from 'snarkdown'
|
||||
import {
|
||||
ComputedRef,
|
||||
capitalize,
|
||||
computed,
|
||||
reactive,
|
||||
withDefaults,
|
||||
onBeforeMount,
|
||||
toRefs,
|
||||
} from 'vue'
|
||||
import { capitalize, computed, reactive, onBeforeMount, toRefs } from 'vue'
|
||||
import type { ComputedRef } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
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 { getFileSizeInMB } from '@/utils/files'
|
||||
import { linkifyAndClean } from '@/utils/inputs'
|
||||
@ -187,19 +194,17 @@
|
||||
|
||||
function updateForm(appConfig: TAppConfig) {
|
||||
Object.keys(appData).map((key) => {
|
||||
['max_single_file_size', 'max_zip_file_size'].includes(key)
|
||||
? // eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
(appData[key] = getFileSizeInMB(appConfig[key]))
|
||||
: ['about', 'privacy_policy'].includes(key)
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
? appData[key] = appConfig[key]!== null
|
||||
? appConfig[key]
|
||||
: ''
|
||||
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
: (appData[key] = appConfig[key])
|
||||
;['max_single_file_size', 'max_zip_file_size'].includes(key)
|
||||
? // eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
(appData[key] = getFileSizeInMB(appConfig[key]))
|
||||
: ['about', 'privacy_policy'].includes(key)
|
||||
? // eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
(appData[key] = appConfig[key] !== null ? appConfig[key] : '')
|
||||
: // eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
||||
// @ts-ignore
|
||||
(appData[key] = appConfig[key])
|
||||
})
|
||||
}
|
||||
function onCancel() {
|
||||
@ -232,7 +237,7 @@
|
||||
font-style: italic;
|
||||
}
|
||||
|
||||
textarea {
|
||||
textarea {
|
||||
margin-bottom: $default-padding;
|
||||
}
|
||||
.textarea-description {
|
||||
@ -242,6 +247,5 @@
|
||||
margin-bottom: $default-margin;
|
||||
padding: $default-padding;
|
||||
}
|
||||
|
||||
}
|
||||
</style>
|
||||
|
@ -54,18 +54,18 @@
|
||||
</template>
|
||||
|
||||
<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 Card from '@/components/Common/Card.vue'
|
||||
import { IAppStatistics, TAppConfig } from '@/types/application'
|
||||
import type { IAppStatistics, TAppConfig } from '@/types/application'
|
||||
|
||||
interface Props {
|
||||
appConfig: TAppConfig
|
||||
appStatistics?: IAppStatistics
|
||||
}
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
appStatistics: () => ({} as IAppStatistics),
|
||||
appStatistics: () => ({}) as IAppStatistics,
|
||||
})
|
||||
|
||||
const { appConfig, appStatistics } = toRefs(props)
|
||||
|
@ -84,11 +84,12 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ComputedRef, computed } from 'vue'
|
||||
import { computed } from 'vue'
|
||||
import type { ComputedRef } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
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 { translateSports } from '@/utils/sports'
|
||||
|
||||
|
@ -134,8 +134,6 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
ComputedRef,
|
||||
Ref,
|
||||
computed,
|
||||
reactive,
|
||||
watch,
|
||||
@ -143,15 +141,17 @@
|
||||
onBeforeMount,
|
||||
onUnmounted,
|
||||
} 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 Pagination from '@/components/Common/Pagination.vue'
|
||||
import UserPicture from '@/components/User/UserPicture.vue'
|
||||
import UsersNameFilter from '@/components/Users/UsersNameFilter.vue'
|
||||
import { AUTH_USER_STORE, ROOT_STORE, USERS_STORE } from '@/store/constants'
|
||||
import { IPagination, TPaginationPayload } from '@/types/api'
|
||||
import { IAuthUserProfile, IUserProfile } from '@/types/user'
|
||||
import type { IPagination, TPaginationPayload } from '@/types/api'
|
||||
import type { IAuthUserProfile, IUserProfile } from '@/types/user'
|
||||
import { useStore } from '@/use/useStore'
|
||||
import { getQuery, sortList } from '@/utils/api'
|
||||
import { formatDate } from '@/utils/dates'
|
||||
|
@ -27,7 +27,7 @@
|
||||
import { computed, toRefs } from 'vue'
|
||||
|
||||
import StatCard from '@/components/Common/StatCard.vue'
|
||||
import { IAppStatistics } from '@/types/application'
|
||||
import type { IAppStatistics } from '@/types/application'
|
||||
import { getReadableFileSize } from '@/utils/files'
|
||||
|
||||
interface Props {
|
||||
|
@ -15,7 +15,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ref, watch, withDefaults } from 'vue'
|
||||
import { ref, watch } from 'vue'
|
||||
|
||||
interface Props {
|
||||
name: string
|
||||
|
@ -7,9 +7,10 @@
|
||||
</template>
|
||||
|
||||
<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'
|
||||
|
||||
interface Props {
|
||||
|
@ -29,7 +29,7 @@
|
||||
import { ref, toRefs, watch } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
import { IDropdownOption, TDropdownOptions } from '@/types/forms'
|
||||
import type { IDropdownOption, TDropdownOptions } from '@/types/forms'
|
||||
interface Props {
|
||||
options: TDropdownOptions
|
||||
selected: string
|
||||
|
@ -11,7 +11,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { toRefs, withDefaults } from 'vue'
|
||||
import { toRefs } from 'vue'
|
||||
|
||||
interface Props {
|
||||
title: string
|
||||
|
@ -45,7 +45,7 @@
|
||||
<script setup lang="ts">
|
||||
import { toRefs } from 'vue'
|
||||
|
||||
import { TPaginationPayload } from '@/types/api'
|
||||
import type { TPaginationPayload } from '@/types/api'
|
||||
|
||||
interface Props {
|
||||
order_by: string[]
|
||||
|
@ -56,7 +56,7 @@
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'EmailSent',
|
||||
}
|
||||
|
@ -21,7 +21,7 @@
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'ErrorImg',
|
||||
}
|
||||
|
@ -87,7 +87,7 @@
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'Password',
|
||||
}
|
||||
|
@ -44,7 +44,7 @@
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'CyclingSport',
|
||||
}
|
||||
|
@ -26,7 +26,7 @@
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'CyclingTransport',
|
||||
}
|
||||
|
@ -1,38 +1,47 @@
|
||||
<template>
|
||||
<svg
|
||||
version="1.1"
|
||||
id="Capa_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 491.737 491.737"
|
||||
style="enable-background: new 0 0 491.737 491.737"
|
||||
xml:space="preserve"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg">
|
||||
<desc
|
||||
id="cyclingVirtualDescription">
|
||||
<svg
|
||||
version="1.1"
|
||||
id="Capa_1"
|
||||
x="0px"
|
||||
y="0px"
|
||||
viewBox="0 0 491.737 491.737"
|
||||
style="enable-background: new 0 0 491.737 491.737"
|
||||
xml:space="preserve"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<desc id="cyclingVirtualDescription">
|
||||
silhouette of a person riding a bicycle with virtual indicator
|
||||
</desc>
|
||||
<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"
|
||||
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"
|
||||
id="path5" />
|
||||
<g
|
||||
id="g10174"
|
||||
transform="rotate(-45,60.058765,120.50397)"><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"
|
||||
id="path3370"
|
||||
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"
|
||||
id="path3372"
|
||||
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"
|
||||
id="path3378"
|
||||
style="stroke-width:1.09578" /></g></svg>
|
||||
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
|
||||
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"
|
||||
/>
|
||||
<g id="g10174" transform="rotate(-45,60.058765,120.50397)">
|
||||
<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"
|
||||
id="path3370"
|
||||
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"
|
||||
id="path3372"
|
||||
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"
|
||||
id="path3378"
|
||||
style="stroke-width: 1.09578"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'CyclingVirtual',
|
||||
}
|
||||
|
@ -31,7 +31,7 @@
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'Hiking',
|
||||
}
|
||||
|
@ -44,7 +44,7 @@
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'MountainBiking',
|
||||
}
|
||||
|
@ -64,7 +64,7 @@
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'MountainBikingElectric',
|
||||
}
|
||||
|
@ -50,7 +50,7 @@
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'Mountaineering',
|
||||
}
|
||||
|
@ -138,7 +138,7 @@
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'OpenWaterSwimming',
|
||||
}
|
||||
|
@ -33,7 +33,7 @@
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'Paragliding',
|
||||
}
|
||||
|
@ -31,7 +31,7 @@
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'Rowing',
|
||||
}
|
||||
|
@ -31,7 +31,7 @@
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'Running',
|
||||
}
|
||||
|
@ -35,7 +35,7 @@
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'SkiingAlpine',
|
||||
}
|
||||
|
@ -31,7 +31,7 @@
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'SkiingCrossCountry',
|
||||
}
|
||||
|
@ -55,7 +55,7 @@
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'Snowshoes',
|
||||
}
|
||||
|
@ -37,7 +37,7 @@
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'Trail',
|
||||
}
|
||||
|
@ -25,7 +25,7 @@
|
||||
</svg>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
<script lang="ts">
|
||||
export default {
|
||||
name: 'Walking',
|
||||
}
|
||||
|
@ -38,14 +38,8 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
ComputedRef,
|
||||
computed,
|
||||
onUnmounted,
|
||||
onMounted,
|
||||
toRefs,
|
||||
withDefaults,
|
||||
} from 'vue'
|
||||
import { computed, onUnmounted, onMounted, toRefs } from 'vue'
|
||||
import type { ComputedRef } from 'vue'
|
||||
|
||||
import { ROOT_STORE } from '@/store/constants'
|
||||
import { useStore } from '@/use/useStore'
|
||||
|
@ -8,7 +8,8 @@
|
||||
</template>
|
||||
|
||||
<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'
|
||||
interface Props {
|
||||
|
@ -51,9 +51,9 @@
|
||||
<script setup lang="ts">
|
||||
import { toRefs } from 'vue'
|
||||
|
||||
import { IPagination, TPaginationPayload } from '@/types/api'
|
||||
import { IOauth2ClientsPayload } from '@/types/oauth'
|
||||
import { TWorkoutsPayload } from '@/types/workouts'
|
||||
import type { IPagination, TPaginationPayload } from '@/types/api'
|
||||
import type { IOauth2ClientsPayload } from '@/types/oauth'
|
||||
import type { TWorkoutsPayload } from '@/types/workouts'
|
||||
import { rangePagination } from '@/utils/api'
|
||||
|
||||
interface Props {
|
||||
|
@ -30,7 +30,8 @@
|
||||
</template>
|
||||
|
||||
<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'
|
||||
|
||||
|
@ -29,15 +29,8 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { zxcvbn } from '@zxcvbn-ts/core'
|
||||
import {
|
||||
ComputedRef,
|
||||
Ref,
|
||||
computed,
|
||||
ref,
|
||||
onBeforeMount,
|
||||
toRefs,
|
||||
watch,
|
||||
} from 'vue'
|
||||
import { computed, ref, onBeforeMount, toRefs, watch } from 'vue'
|
||||
import type { ComputedRef, Ref } from 'vue'
|
||||
|
||||
import { AUTH_USER_STORE, ROOT_STORE } from '@/store/constants'
|
||||
import { useStore } from '@/use/useStore'
|
||||
|
@ -23,9 +23,9 @@
|
||||
</template>
|
||||
|
||||
<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'
|
||||
|
||||
interface Props {
|
||||
|
@ -5,13 +5,14 @@
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { ChartOptions, LayoutItem } from 'chart.js'
|
||||
import { PropType, computed, defineComponent } from 'vue'
|
||||
import type { ChartOptions, LayoutItem } from 'chart.js'
|
||||
import { computed, defineComponent } from 'vue'
|
||||
import type { PropType } from 'vue'
|
||||
import { BarChart, useBarChart } from 'vue-chart-3'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import { IChartDataset } from '@/types/chart'
|
||||
import { TStatisticsDatasetKeys } from '@/types/statistics'
|
||||
import type { IChartDataset } from '@/types/chart'
|
||||
import type { TStatisticsDatasetKeys } from '@/types/statistics'
|
||||
import { formatTooltipValue } from '@/utils/tooltip'
|
||||
|
||||
export default defineComponent({
|
||||
|
@ -81,28 +81,20 @@
|
||||
|
||||
<script lang="ts">
|
||||
import { format } from 'date-fns'
|
||||
import {
|
||||
ComputedRef,
|
||||
PropType,
|
||||
Ref,
|
||||
computed,
|
||||
defineComponent,
|
||||
ref,
|
||||
watch,
|
||||
onBeforeMount,
|
||||
} from 'vue'
|
||||
import { computed, defineComponent, ref, watch, onBeforeMount } from 'vue'
|
||||
import type { ComputedRef, PropType, Ref } from 'vue'
|
||||
|
||||
import Chart from '@/components/Common/StatsChart/Chart.vue'
|
||||
import { STATS_STORE } from '@/store/constants'
|
||||
import { ISport } from '@/types/sports'
|
||||
import {
|
||||
import type { ISport } from '@/types/sports'
|
||||
import type {
|
||||
IStatisticsChartData,
|
||||
TStatisticsDatasetKeys,
|
||||
IStatisticsDateParams,
|
||||
TStatisticsFromApi,
|
||||
IStatisticsParams,
|
||||
} from '@/types/statistics'
|
||||
import { IAuthUserProfile } from '@/types/user'
|
||||
import type { IAuthUserProfile } from '@/types/user'
|
||||
import { useStore } from '@/use/useStore'
|
||||
import { formatStats } from '@/utils/statistics'
|
||||
|
||||
|
@ -33,14 +33,15 @@
|
||||
</template>
|
||||
|
||||
<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 NoWorkouts from '@/components/Workouts/NoWorkouts.vue'
|
||||
import { WORKOUTS_STORE } from '@/store/constants'
|
||||
import { ISport } from '@/types/sports'
|
||||
import { IUserProfile } from '@/types/user'
|
||||
import { IWorkout } from '@/types/workouts'
|
||||
import type { ISport } from '@/types/sports'
|
||||
import type { IUserProfile } from '@/types/user'
|
||||
import type { IWorkout } from '@/types/workouts'
|
||||
import { useStore } from '@/use/useStore'
|
||||
import { defaultOrder } from '@/utils/workouts'
|
||||
|
||||
|
@ -26,11 +26,12 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
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 { ISport } from '@/types/sports'
|
||||
import { IWorkout } from '@/types/workouts'
|
||||
import type { ISport } from '@/types/sports'
|
||||
import type { IWorkout } from '@/types/workouts'
|
||||
import { getDateWithTZ } from '@/utils/dates'
|
||||
|
||||
interface Props {
|
||||
|
@ -7,7 +7,8 @@
|
||||
</template>
|
||||
|
||||
<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 {
|
||||
startDate: Date
|
||||
|
@ -21,7 +21,8 @@
|
||||
</template>
|
||||
|
||||
<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'
|
||||
|
||||
interface Props {
|
||||
|
@ -30,7 +30,7 @@
|
||||
<script setup lang="ts">
|
||||
import { toRefs } from 'vue'
|
||||
|
||||
import { IWorkout } from '@/types/workouts'
|
||||
import type { IWorkout } from '@/types/workouts'
|
||||
interface Props {
|
||||
displayHARecord: boolean
|
||||
workout: IWorkout
|
||||
|
@ -41,8 +41,8 @@
|
||||
|
||||
import CalendarWorkout from '@/components/Dashboard/UserCalendar/CalendarWorkout.vue'
|
||||
import CalendarWorkoutsChart from '@/components/Dashboard/UserCalendar/CalendarWorkoutsChart.vue'
|
||||
import { ISport } from '@/types/sports'
|
||||
import { IWorkout } from '@/types/workouts'
|
||||
import type { ISport } from '@/types/sports'
|
||||
import type { IWorkout } from '@/types/workouts'
|
||||
import { getSportColor, getSportLabel, sportIdColors } from '@/utils/sports'
|
||||
import { getDonutDatasets } from '@/utils/workouts'
|
||||
|
||||
|
@ -28,8 +28,8 @@
|
||||
|
||||
import CalendarWorkout from '@/components/Dashboard/UserCalendar/CalendarWorkout.vue'
|
||||
import DonutChart from '@/components/Dashboard/UserCalendar/DonutChart.vue'
|
||||
import { ISport } from '@/types/sports'
|
||||
import { IWorkout } from '@/types/workouts'
|
||||
import type { ISport } from '@/types/sports'
|
||||
import type { IWorkout } from '@/types/workouts'
|
||||
import { getSportColor, getSportLabel } from '@/utils/sports'
|
||||
|
||||
interface Props {
|
||||
@ -88,7 +88,8 @@
|
||||
.more-workouts {
|
||||
background: whitesmoke;
|
||||
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);
|
||||
position: absolute;
|
||||
top: 52px;
|
||||
|
@ -26,16 +26,18 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Locale, addMonths, format, subMonths } from 'date-fns'
|
||||
import { ComputedRef, computed, ref, toRefs, onBeforeMount } from 'vue'
|
||||
import { addMonths, format, subMonths } from 'date-fns'
|
||||
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 CalendarDays from '@/components/Dashboard/UserCalendar/CalendarDays.vue'
|
||||
import CalendarHeader from '@/components/Dashboard/UserCalendar/CalendarHeader.vue'
|
||||
import { ROOT_STORE, WORKOUTS_STORE } from '@/store/constants'
|
||||
import { ISport } from '@/types/sports'
|
||||
import { IAuthUserProfile } from '@/types/user'
|
||||
import { IWorkout, TWorkoutsPayload } from '@/types/workouts'
|
||||
import type { ISport } from '@/types/sports'
|
||||
import type { IAuthUserProfile } from '@/types/user'
|
||||
import type { IWorkout, TWorkoutsPayload } from '@/types/workouts'
|
||||
import { useStore } from '@/use/useStore'
|
||||
import { getCalendarStartAndEnd } from '@/utils/dates'
|
||||
import { defaultOrder } from '@/utils/workouts'
|
||||
|
@ -20,8 +20,8 @@
|
||||
import { toRefs } from 'vue'
|
||||
|
||||
import StatChart from '@/components/Common/StatsChart/index.vue'
|
||||
import { ISport } from '@/types/sports'
|
||||
import { IUserProfile } from '@/types/user'
|
||||
import type { ISport } from '@/types/sports'
|
||||
import type { IUserProfile } from '@/types/user'
|
||||
|
||||
interface Props {
|
||||
sports: ISport[]
|
||||
|
@ -35,7 +35,7 @@
|
||||
import { toRefs } from 'vue'
|
||||
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'
|
||||
|
||||
interface Props {
|
||||
|
@ -24,8 +24,8 @@
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import RecordsCard from '@/components/Dashboard/UserRecords/RecordsCard.vue'
|
||||
import { ISport } from '@/types/sports'
|
||||
import { IAuthUserProfile } from '@/types/user'
|
||||
import type { ISport } from '@/types/sports'
|
||||
import type { IAuthUserProfile } from '@/types/user'
|
||||
import { getRecordsBySports } from '@/utils/records'
|
||||
import { translateSports } from '@/utils/sports'
|
||||
|
||||
|
@ -31,12 +31,13 @@
|
||||
</template>
|
||||
|
||||
<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 StatCard from '@/components/Common/StatCard.vue'
|
||||
import { TUnit } from '@/types/units'
|
||||
import { IAuthUserProfile } from '@/types/user'
|
||||
import type { TUnit } from '@/types/units'
|
||||
import type { IAuthUserProfile } from '@/types/user'
|
||||
import { convertDistance, units } from '@/utils/units'
|
||||
interface Props {
|
||||
user: IAuthUserProfile
|
||||
@ -56,17 +57,28 @@
|
||||
: distanceUnitFrom
|
||||
const totalDistance: ComputedRef<number> = computed(() =>
|
||||
user.value.imperial_units
|
||||
? convertDistance(user.value.total_distance, distanceUnitFrom, distanceUnitTo, 2)
|
||||
: parseFloat(user.value.total_distance.toFixed(2)))
|
||||
? convertDistance(
|
||||
user.value.total_distance,
|
||||
distanceUnitFrom,
|
||||
distanceUnitTo,
|
||||
2
|
||||
)
|
||||
: parseFloat(user.value.total_distance.toFixed(2))
|
||||
)
|
||||
const ascentUnitFrom: TUnit = 'm'
|
||||
const ascentUnitTo: TUnit = user.value.imperial_units
|
||||
? units[ascentUnitFrom].defaultTarget
|
||||
: ascentUnitFrom
|
||||
const totalAscent: ComputedRef<number> = computed(() =>
|
||||
user.value.imperial_units
|
||||
? convertDistance(user.value.total_ascent, ascentUnitFrom, ascentUnitTo, 2)
|
||||
: parseFloat(user.value.total_ascent.toFixed(2)))
|
||||
|
||||
? convertDistance(
|
||||
user.value.total_ascent,
|
||||
ascentUnitFrom,
|
||||
ascentUnitTo,
|
||||
2
|
||||
)
|
||||
: parseFloat(user.value.total_ascent.toFixed(2))
|
||||
)
|
||||
|
||||
function get_duration(total_duration: ComputedRef<string>) {
|
||||
const duration = total_duration.value.match(/day/g)
|
||||
|
@ -93,12 +93,13 @@
|
||||
</template>
|
||||
|
||||
<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 { AUTH_USER_STORE, ROOT_STORE } from '@/store/constants'
|
||||
import { IDropdownOption } from '@/types/forms'
|
||||
import { IAuthUserProfile } from '@/types/user'
|
||||
import type { IDropdownOption } from '@/types/forms'
|
||||
import type { IAuthUserProfile } from '@/types/user'
|
||||
import { useStore } from '@/use/useStore'
|
||||
import { availableLanguages } from '@/utils/locales'
|
||||
|
||||
|
@ -25,11 +25,12 @@
|
||||
|
||||
<script lang="ts" setup>
|
||||
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 { TAppConfig } from '@/types/application'
|
||||
import { IAuthUserProfile } from '@/types/user'
|
||||
import type { TAppConfig } from '@/types/application'
|
||||
import type { IAuthUserProfile } from '@/types/user'
|
||||
import { useStore } from '@/use/useStore'
|
||||
import { dateStringFormats, formatDate } from '@/utils/dates'
|
||||
import { linkifyAndClean } from '@/utils/inputs'
|
||||
|
@ -10,16 +10,13 @@
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
@import '~@/scss/vars.scss';
|
||||
|
||||
.privacy-policy-message {
|
||||
background: var(--alert-background-color);
|
||||
color: var(--alert-color);
|
||||
border-radius: $border-radius;
|
||||
padding: $default-padding $default-padding*2;
|
||||
padding: $default-padding $default-padding * 2;
|
||||
}
|
||||
</style>
|
||||
|
@ -8,7 +8,7 @@
|
||||
>
|
||||
<input
|
||||
type="checkbox"
|
||||
:id="sport.id"
|
||||
:id="`${sport.id}`"
|
||||
:name="sport.label"
|
||||
:checked="selectedSportIds.includes(sport.id)"
|
||||
@input="updateSelectedSportIds(sport.id)"
|
||||
@ -20,10 +20,11 @@
|
||||
</template>
|
||||
|
||||
<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 { ISport, ITranslatedSport } from '@/types/sports'
|
||||
import type { ISport, ITranslatedSport } from '@/types/sports'
|
||||
import { translateSports } from '@/utils/sports'
|
||||
|
||||
interface Props {
|
||||
@ -38,7 +39,7 @@
|
||||
|
||||
const { t } = useI18n()
|
||||
|
||||
const sportColors = inject('sportColors')
|
||||
const sportColors: Record<string, string> | undefined = inject('sportColors')
|
||||
const { selectedSportIds } = toRefs(props)
|
||||
const translatedSports: ComputedRef<ITranslatedSport[]> = computed(() =>
|
||||
translateSports(props.userSports, t)
|
||||
|
@ -22,15 +22,16 @@
|
||||
</template>
|
||||
|
||||
<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 StatChart from '@/components/Common/StatsChart/index.vue'
|
||||
import StatsMenu from '@/components/Statistics/StatsMenu.vue'
|
||||
import SportsMenu from '@/components/Statistics/StatsSportsMenu.vue'
|
||||
import { ISport, ITranslatedSport } from '@/types/sports'
|
||||
import { IStatisticsDateParams } from '@/types/statistics'
|
||||
import { IAuthUserProfile } from '@/types/user'
|
||||
import type { ISport, ITranslatedSport } from '@/types/sports'
|
||||
import type { IStatisticsDateParams } from '@/types/statistics'
|
||||
import type { IAuthUserProfile } from '@/types/user'
|
||||
import { translateSports } from '@/utils/sports'
|
||||
import { getStatsDateParams, updateChartParams } from '@/utils/statistics'
|
||||
|
||||
|
@ -10,7 +10,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { toRefs, withDefaults } from 'vue'
|
||||
import { toRefs } from 'vue'
|
||||
|
||||
import UserAuthForm from '@/components/User/UserAuthForm.vue'
|
||||
|
||||
|
@ -34,11 +34,12 @@
|
||||
</template>
|
||||
|
||||
<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 { AUTH_USER_STORE } from '@/store/constants'
|
||||
import { IAuthUserProfile, IUserProfile } from '@/types/user'
|
||||
import type { IAuthUserProfile, IUserProfile } from '@/types/user'
|
||||
import { useStore } from '@/use/useStore'
|
||||
|
||||
interface Props {
|
||||
|
@ -120,20 +120,12 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import { format } from 'date-fns'
|
||||
import {
|
||||
ComputedRef,
|
||||
Ref,
|
||||
computed,
|
||||
ref,
|
||||
toRefs,
|
||||
withDefaults,
|
||||
watch,
|
||||
onUnmounted,
|
||||
} from 'vue'
|
||||
import { computed, ref, toRefs, watch, onUnmounted } from 'vue'
|
||||
import type { ComputedRef, Ref } from 'vue'
|
||||
|
||||
import { AUTH_USER_STORE, ROOT_STORE, USERS_STORE } from '@/store/constants'
|
||||
import { TAppConfig } from '@/types/application'
|
||||
import { IAuthUserProfile, IUserProfile } from '@/types/user'
|
||||
import type { TAppConfig } from '@/types/application'
|
||||
import type { IAuthUserProfile, IUserProfile } from '@/types/user'
|
||||
import { useStore } from '@/use/useStore'
|
||||
import { formatDate, getDateFormat } from '@/utils/dates'
|
||||
import { localeFromLanguage } from '@/utils/locales'
|
||||
|
@ -56,10 +56,11 @@
|
||||
</template>
|
||||
|
||||
<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 { IAuthUserProfile } from '@/types/user'
|
||||
import type { IAuthUserProfile } from '@/types/user'
|
||||
import { useStore } from '@/use/useStore'
|
||||
import { getDateFormat } from '@/utils/dates'
|
||||
import { languageLabels } from '@/utils/locales'
|
||||
|
@ -13,7 +13,7 @@
|
||||
|
||||
import UserHeader from '@/components/User/ProfileDisplay/UserHeader.vue'
|
||||
import UserProfileTabs from '@/components/User/UserProfileTabs.vue'
|
||||
import { IUserProfile } from '@/types/user'
|
||||
import type { IUserProfile } from '@/types/user'
|
||||
|
||||
interface Props {
|
||||
user: IUserProfile
|
||||
|
@ -28,7 +28,8 @@
|
||||
</template>
|
||||
|
||||
<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'
|
||||
|
||||
|
@ -105,8 +105,6 @@
|
||||
<script setup lang="ts">
|
||||
import { isBefore, subDays } from 'date-fns'
|
||||
import {
|
||||
ComputedRef,
|
||||
Ref,
|
||||
computed,
|
||||
reactive,
|
||||
ref,
|
||||
@ -115,12 +113,13 @@
|
||||
watch,
|
||||
onUnmounted,
|
||||
} from 'vue'
|
||||
import type { ComputedRef, Ref } from 'vue'
|
||||
|
||||
import authApi from '@/api/authApi'
|
||||
import PasswordInput from '@/components/Common/PasswordInput.vue'
|
||||
import { AUTH_USER_STORE, ROOT_STORE } from '@/store/constants'
|
||||
import { TAppConfig } from '@/types/application'
|
||||
import {
|
||||
import type { TAppConfig } from '@/types/application'
|
||||
import type {
|
||||
IAuthUserProfile,
|
||||
IUserAccountPayload,
|
||||
IExportRequest,
|
||||
|
@ -62,10 +62,15 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
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 { IUserProfile, IUserPayload, IAuthUserProfile } from '@/types/user'
|
||||
import type {
|
||||
IUserProfile,
|
||||
IUserPayload,
|
||||
IAuthUserProfile,
|
||||
} from '@/types/user'
|
||||
import { useStore } from '@/use/useStore'
|
||||
import { formatDate } from '@/utils/dates'
|
||||
|
||||
|
@ -33,12 +33,13 @@
|
||||
</template>
|
||||
|
||||
<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 { AUTH_USER_STORE, ROOT_STORE } from '@/store/constants'
|
||||
import { TAppConfig } from '@/types/application'
|
||||
import { IUserProfile } from '@/types/user'
|
||||
import type { TAppConfig } from '@/types/application'
|
||||
import type { IUserProfile } from '@/types/user'
|
||||
import { useStore } from '@/use/useStore'
|
||||
import { getReadableFileSize } from '@/utils/files'
|
||||
|
||||
|
@ -165,11 +165,12 @@
|
||||
</template>
|
||||
|
||||
<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 { 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 { availableDateFormatOptions } from '@/utils/dates'
|
||||
import { availableLanguages } from '@/utils/locales'
|
||||
|
@ -17,10 +17,7 @@
|
||||
<div class="policy-content">
|
||||
<PrivacyPolicy />
|
||||
</div>
|
||||
<label
|
||||
for="accepted_policy"
|
||||
class="accepted_policy"
|
||||
>
|
||||
<label for="accepted_policy" class="accepted_policy">
|
||||
<input
|
||||
type="checkbox"
|
||||
id="accepted_policy"
|
||||
@ -49,11 +46,12 @@
|
||||
</template>
|
||||
|
||||
<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 {AUTH_USER_STORE, ROOT_STORE} from '@/store/constants'
|
||||
import { IAuthUserProfile } from '@/types/user'
|
||||
import { AUTH_USER_STORE, ROOT_STORE } from '@/store/constants'
|
||||
import type { IAuthUserProfile } from '@/types/user'
|
||||
import { useStore } from '@/use/useStore'
|
||||
|
||||
interface Props {
|
||||
@ -67,11 +65,12 @@
|
||||
const errorMessages: ComputedRef<string | string[] | null> = computed(
|
||||
() => store.getters[ROOT_STORE.GETTERS.ERROR_MESSAGES]
|
||||
)
|
||||
const acceptedPolicy= ref(false)
|
||||
const acceptedPolicy = ref(false)
|
||||
|
||||
function onSubmit() {
|
||||
store.dispatch(
|
||||
AUTH_USER_STORE.ACTIONS.ACCEPT_PRIVACY_POLICY, acceptedPolicy.value
|
||||
AUTH_USER_STORE.ACTIONS.ACCEPT_PRIVACY_POLICY,
|
||||
acceptedPolicy.value
|
||||
)
|
||||
}
|
||||
|
||||
@ -93,14 +92,14 @@
|
||||
|
||||
.policy-content {
|
||||
height: 500px;
|
||||
border:1px solid #ccc;
|
||||
border: 1px solid #ccc;
|
||||
overflow: auto;
|
||||
margin: $default-margin;
|
||||
border-radius: $border-radius;
|
||||
|
||||
@media screen and (max-width: $small-limit) {
|
||||
margin: $default-margin 0;
|
||||
font-size: .9em;
|
||||
font-size: 0.9em;
|
||||
}
|
||||
|
||||
.privacy-policy-text {
|
||||
|
@ -22,7 +22,7 @@
|
||||
|
||||
import UserProfileTabs from '@/components/User/UserProfileTabs.vue'
|
||||
import { AUTH_USER_STORE } from '@/store/constants'
|
||||
import { IUserProfile } from '@/types/user'
|
||||
import type { IUserProfile } from '@/types/user'
|
||||
import { useStore } from '@/use/useStore'
|
||||
|
||||
interface Props {
|
||||
@ -34,7 +34,14 @@
|
||||
const store = useStore()
|
||||
|
||||
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(
|
||||
() => store.getters[AUTH_USER_STORE.GETTERS.USER_LOADING]
|
||||
)
|
||||
|
@ -89,8 +89,8 @@
|
||||
import { computed, reactive } from 'vue'
|
||||
|
||||
import { OAUTH2_STORE } from '@/store/constants'
|
||||
import { IOAuth2ClientPayload } from '@/types/oauth'
|
||||
import { IAuthUserProfile } from '@/types/user'
|
||||
import type { IOAuth2ClientPayload } from '@/types/oauth'
|
||||
import type { IAuthUserProfile } from '@/types/user'
|
||||
import { useStore } from '@/use/useStore'
|
||||
import { admin_oauth2_scopes, oauth2_scopes } from '@/utils/oauth'
|
||||
|
||||
|
@ -39,11 +39,12 @@
|
||||
</template>
|
||||
|
||||
<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 { OAUTH2_STORE, ROOT_STORE } from '@/store/constants'
|
||||
import { IOAuth2Client } from '@/types/oauth'
|
||||
import type { IOAuth2Client } from '@/types/oauth'
|
||||
import { useStore } from '@/use/useStore'
|
||||
|
||||
const route = useRoute()
|
||||
|
@ -110,17 +110,15 @@
|
||||
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
ComputedRef,
|
||||
Ref,
|
||||
capitalize,
|
||||
computed,
|
||||
onBeforeMount,
|
||||
toRefs,
|
||||
ref,
|
||||
onUnmounted,
|
||||
withDefaults,
|
||||
watch,
|
||||
} from 'vue'
|
||||
import type { ComputedRef, Ref } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
import { OAUTH2_STORE, ROOT_STORE } from '@/store/constants'
|
||||
|
@ -37,14 +37,16 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ComputedRef, computed, onBeforeMount, toRefs, watch } from 'vue'
|
||||
import { LocationQuery, useRoute } from 'vue-router'
|
||||
import { computed, onBeforeMount, toRefs, watch } from 'vue'
|
||||
import type { ComputedRef } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
import type { LocationQuery } from 'vue-router'
|
||||
|
||||
import Pagination from '@/components/Common/Pagination.vue'
|
||||
import { OAUTH2_STORE } from '@/store/constants'
|
||||
import { IPagination } from '@/types/api'
|
||||
import { IOAuth2Client, IOauth2ClientsPayload } from '@/types/oauth'
|
||||
import { IAuthUserProfile } from '@/types/user'
|
||||
import type { IPagination } from '@/types/api'
|
||||
import type { IOAuth2Client, IOauth2ClientsPayload } from '@/types/oauth'
|
||||
import type { IAuthUserProfile } from '@/types/user'
|
||||
import { useStore } from '@/use/useStore'
|
||||
import { defaultPage, getNumberQueryValue } from '@/utils/api'
|
||||
import { formatDate } from '@/utils/dates'
|
||||
|
@ -8,7 +8,7 @@
|
||||
import { onUnmounted, toRefs } from 'vue'
|
||||
|
||||
import { OAUTH2_STORE, ROOT_STORE } from '@/store/constants'
|
||||
import { IAuthUserProfile } from '@/types/user'
|
||||
import type { IAuthUserProfile } from '@/types/user'
|
||||
import { useStore } from '@/use/useStore'
|
||||
|
||||
interface Props {
|
||||
|
@ -163,22 +163,14 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {
|
||||
ComputedRef,
|
||||
computed,
|
||||
onUnmounted,
|
||||
reactive,
|
||||
ref,
|
||||
toRefs,
|
||||
watch,
|
||||
withDefaults,
|
||||
} from 'vue'
|
||||
import { computed, onUnmounted, reactive, ref, toRefs, watch } from 'vue'
|
||||
import type { ComputedRef } from 'vue'
|
||||
import { useRoute } from 'vue-router'
|
||||
|
||||
import PasswordInput from '@/components/Common/PasswordInput.vue'
|
||||
import { AUTH_USER_STORE, ROOT_STORE } from '@/store/constants'
|
||||
import { TAppConfig } from '@/types/application'
|
||||
import { ILoginRegisterFormData } from '@/types/user'
|
||||
import type { TAppConfig } from '@/types/application'
|
||||
import type { ILoginRegisterFormData } from '@/types/user'
|
||||
import { useStore } from '@/use/useStore'
|
||||
|
||||
interface Props {
|
||||
@ -197,7 +189,7 @@
|
||||
username: '',
|
||||
email: '',
|
||||
password: '',
|
||||
accepted_policy: false
|
||||
accepted_policy: false,
|
||||
})
|
||||
const buttonText: ComputedRef<string> = computed(() =>
|
||||
getButtonText(props.action)
|
||||
@ -336,7 +328,7 @@
|
||||
.accepted_policy {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-size: .85em;
|
||||
font-size: 0.85em;
|
||||
font-weight: normal;
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
<script setup lang="ts">
|
||||
import { computed } from 'vue'
|
||||
|
||||
import { IUserProfile } from '@/types/user'
|
||||
import type { IUserProfile } from '@/types/user'
|
||||
import { getApiUrl } from '@/utils'
|
||||
|
||||
interface Props {
|
||||
|
@ -26,7 +26,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { onMounted, toRefs, withDefaults } from 'vue'
|
||||
import { onMounted, toRefs } from 'vue'
|
||||
|
||||
interface Props {
|
||||
tabs: string[]
|
||||
|
@ -165,12 +165,13 @@
|
||||
</template>
|
||||
|
||||
<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 { AUTH_USER_STORE, ROOT_STORE, SPORTS_STORE } from '@/store/constants'
|
||||
import { ISport, ITranslatedSport } from '@/types/sports'
|
||||
import { IUserProfile, IUserSportPreferencesPayload } from '@/types/user'
|
||||
import type { ISport, ITranslatedSport } from '@/types/sports'
|
||||
import type { IUserProfile, IUserSportPreferencesPayload } from '@/types/user'
|
||||
import { useStore } from '@/use/useStore'
|
||||
import { translateSports } from '@/utils/sports'
|
||||
|
||||
|
@ -138,15 +138,17 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Locale, formatDistance } from 'date-fns'
|
||||
import { ComputedRef, computed, toRefs, withDefaults } from 'vue'
|
||||
import { formatDistance } from 'date-fns'
|
||||
import type { Locale } from 'date-fns'
|
||||
import { computed, toRefs } from 'vue'
|
||||
import type { ComputedRef } from 'vue'
|
||||
|
||||
import StaticMap from '@/components/Common/StaticMap.vue'
|
||||
import UserPicture from '@/components/User/UserPicture.vue'
|
||||
import { ROOT_STORE } from '@/store/constants'
|
||||
import { ISport } from '@/types/sports'
|
||||
import { IUserProfile } from '@/types/user'
|
||||
import { IWorkout } from '@/types/workouts'
|
||||
import type { ISport } from '@/types/sports'
|
||||
import type { IUserProfile } from '@/types/user'
|
||||
import type { IWorkout } from '@/types/workouts'
|
||||
import { useStore } from '@/use/useStore'
|
||||
import { formatDate } from '@/utils/dates'
|
||||
|
||||
@ -157,8 +159,8 @@
|
||||
sport?: ISport
|
||||
}
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
workout: () => ({} as IWorkout),
|
||||
sport: () => ({} as ISport),
|
||||
workout: () => ({}) as IWorkout,
|
||||
sport: () => ({}) as ISport,
|
||||
})
|
||||
|
||||
const store = useStore()
|
||||
|
@ -19,7 +19,7 @@
|
||||
import { toRefs } from 'vue'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import { IWeather } from '@/types/workouts'
|
||||
import type { IWeather } from '@/types/workouts'
|
||||
import { getWindSpeed } from '@/utils/units'
|
||||
import { convertDegreeToDirection } from '@/utils/weather'
|
||||
|
||||
|
@ -100,8 +100,8 @@
|
||||
import { toRefs } from 'vue'
|
||||
|
||||
import authApi from '@/api/authApi'
|
||||
import { ISport } from '@/types/sports'
|
||||
import { IWorkoutObject } from '@/types/workouts'
|
||||
import type { ISport } from '@/types/sports'
|
||||
import type { IWorkoutObject } from '@/types/workouts'
|
||||
|
||||
interface Props {
|
||||
sport: ISport
|
||||
|
@ -51,15 +51,16 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { ChartData, ChartOptions } from 'chart.js'
|
||||
import { ComputedRef, computed, ref, toRefs } from 'vue'
|
||||
import type { ChartData, ChartOptions } from 'chart.js'
|
||||
import { computed, ref, toRefs } from 'vue'
|
||||
import type { ComputedRef } from 'vue'
|
||||
import { LineChart, useLineChart } from 'vue-chart-3'
|
||||
import { useI18n } from 'vue-i18n'
|
||||
|
||||
import { htmlLegendPlugin } from '@/components/Workout/WorkoutDetail/WorkoutChart/legend'
|
||||
import { TUnit } from '@/types/units'
|
||||
import { IAuthUserProfile } from '@/types/user'
|
||||
import {
|
||||
import type { TUnit } from '@/types/units'
|
||||
import type { IAuthUserProfile } from '@/types/user'
|
||||
import type {
|
||||
IWorkoutChartData,
|
||||
IWorkoutData,
|
||||
TCoordinates,
|
||||
|
@ -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 legendContainer = document.getElementById(id)
|
||||
|
@ -114,7 +114,7 @@
|
||||
|
||||
import WorkoutRecord from '@/components/Workout/WorkoutDetail/WorkoutRecord.vue'
|
||||
import WorkoutWeather from '@/components/Workout/WorkoutDetail/WorkoutWeather.vue'
|
||||
import { IWorkoutObject } from '@/types/workouts'
|
||||
import type { IWorkoutObject } from '@/types/workouts'
|
||||
|
||||
interface Props {
|
||||
workoutObject: IWorkoutObject
|
||||
|
@ -14,7 +14,7 @@
|
||||
import { LIcon, LMarker } from '@vue-leaflet/vue-leaflet'
|
||||
import { toRefs } from 'vue'
|
||||
|
||||
import { TCoordinates } from '@/types/workouts'
|
||||
import type { TCoordinates } from '@/types/workouts'
|
||||
|
||||
interface Props {
|
||||
markerCoordinates: TCoordinates
|
||||
|
@ -16,6 +16,7 @@
|
||||
:zoomAnimation="false"
|
||||
ref="workoutMap"
|
||||
@ready="fitBounds(bounds)"
|
||||
:use-global-leaflet="false"
|
||||
>
|
||||
<LControlLayers />
|
||||
<LControl
|
||||
@ -90,14 +91,15 @@
|
||||
LMarker,
|
||||
LTileLayer,
|
||||
} 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 CustomMarker from '@/components/Workout/WorkoutDetail/WorkoutMap/CustomMarker.vue'
|
||||
import { ROOT_STORE } from '@/store/constants'
|
||||
import { TAppConfig } from '@/types/application'
|
||||
import { GeoJSONData } from '@/types/geojson'
|
||||
import { IWorkoutData, TCoordinates } from '@/types/workouts'
|
||||
import type { TAppConfig } from '@/types/application'
|
||||
import type { GeoJSONData } from '@/types/geojson'
|
||||
import type { IWorkoutData, TCoordinates } from '@/types/workouts'
|
||||
import { useStore } from '@/use/useStore'
|
||||
import { getApiUrl } from '@/utils'
|
||||
|
||||
@ -106,7 +108,7 @@
|
||||
markerCoordinates?: TCoordinates
|
||||
}
|
||||
const props = withDefaults(defineProps<Props>(), {
|
||||
markerCoordinates: () => ({} as TCoordinates),
|
||||
markerCoordinates: () => ({}) as TCoordinates,
|
||||
})
|
||||
|
||||
const store = useStore()
|
||||
|
@ -16,7 +16,7 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { toRefs, withDefaults } from 'vue'
|
||||
import { toRefs } from 'vue'
|
||||
|
||||
import { linkifyAndClean } from '@/utils/inputs'
|
||||
|
||||
|
@ -15,7 +15,7 @@
|
||||
<script setup lang="ts">
|
||||
import { toRefs } from 'vue'
|
||||
|
||||
import { IWorkoutObject } from '@/types/workouts'
|
||||
import type { IWorkoutObject } from '@/types/workouts'
|
||||
|
||||
interface Props {
|
||||
recordType: string
|
||||
|
@ -31,7 +31,7 @@
|
||||
<script setup lang="ts">
|
||||
import { toRefs } from 'vue'
|
||||
|
||||
import { IWorkoutSegment } from '@/types/workouts'
|
||||
import type { IWorkoutSegment } from '@/types/workouts'
|
||||
|
||||
interface Props {
|
||||
segments: IWorkoutSegment[]
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user