Client - use <script setup> in components

This commit is contained in:
Sam 2021-11-10 21:19:27 +01:00
parent 857c0ecd2d
commit 1bede62d80
126 changed files with 2133 additions and 3207 deletions

View File

@ -1 +1 @@
<!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"><!--[if IE]><link rel="icon" href="/favicon.ico"><![endif]--><link rel="stylesheet" href="/static/css/fork-awesome.min.css"><link rel="stylesheet" href="/static/css/leaflet.css"><title>FitTrackee</title><link href="/static/css/admin.2e1912ed.css" rel="prefetch"><link href="/static/css/main.0baa26a6.css" rel="prefetch"><link href="/static/css/main~workouts.2563ccfd.css" rel="prefetch"><link href="/static/css/profile.14a2947f.css" rel="prefetch"><link href="/static/css/reset.3e6931c7.css" rel="prefetch"><link href="/static/css/workouts.d952f3cf.css" rel="prefetch"><link href="/static/js/admin.4047df15.js" rel="prefetch"><link href="/static/js/chunk-2d0c9189.c81458cc.js" rel="prefetch"><link href="/static/js/chunk-2d0cf391.020c75ea.js" rel="prefetch"><link href="/static/js/chunk-2d0da8f3.c8c3e7e8.js" rel="prefetch"><link href="/static/js/chunk-2d2248b6.d84473c1.js" rel="prefetch"><link href="/static/js/chunk-2d22523a.4b710d99.js" rel="prefetch"><link href="/static/js/main.265d6693.js" rel="prefetch"><link href="/static/js/main~workouts.aa540c70.js" rel="prefetch"><link href="/static/js/profile.7e87449f.js" rel="prefetch"><link href="/static/js/reset.98679f6c.js" rel="prefetch"><link href="/static/js/workouts.52ba33b8.js" rel="prefetch"><link href="/static/css/app.88c1cb13.css" rel="preload" as="style"><link href="/static/js/app.e01bf3f7.js" rel="preload" as="script"><link href="/static/js/chunk-vendors.5928fb7f.js" rel="preload" as="script"><link href="/static/css/app.88c1cb13.css" rel="stylesheet"><link rel="icon" type="image/png" sizes="32x32" href="/img/icons/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="/img/icons/favicon-16x16.png"><link rel="manifest" href="/manifest.json"><meta name="theme-color" content="#4DBA87"><meta name="apple-mobile-web-app-capable" content="no"><meta name="apple-mobile-web-app-status-bar-style" content="default"><meta name="apple-mobile-web-app-title" content="fittrackee_client"><link rel="apple-touch-icon" href="/img/icons/apple-touch-icon-152x152.png"><link rel="mask-icon" href="/img/icons/safari-pinned-tab.svg" color="#4DBA87"><meta name="msapplication-TileImage" content="/img/icons/msapplication-icon-144x144.png"><meta name="msapplication-TileColor" content="#000000"></head><body><noscript><strong>We're sorry but FitTrackee doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="/static/js/chunk-vendors.5928fb7f.js"></script><script src="/static/js/app.e01bf3f7.js"></script></body></html>
<!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"><!--[if IE]><link rel="icon" href="/favicon.ico"><![endif]--><link rel="stylesheet" href="/static/css/fork-awesome.min.css"><link rel="stylesheet" href="/static/css/leaflet.css"><title>FitTrackee</title><link href="/static/css/admin.e96a4210.css" rel="prefetch"><link href="/static/css/main.2ee3c9ac.css" rel="prefetch"><link href="/static/css/main~workouts.ca97ac72.css" rel="prefetch"><link href="/static/css/profile.b792256b.css" rel="prefetch"><link href="/static/css/reset.dc50c1a7.css" rel="prefetch"><link href="/static/css/workouts.9c79c3ad.css" rel="prefetch"><link href="/static/js/admin.2f1d393d.js" rel="prefetch"><link href="/static/js/chunk-2d0c9189.c81458cc.js" rel="prefetch"><link href="/static/js/chunk-2d0cf391.020c75ea.js" rel="prefetch"><link href="/static/js/chunk-2d0da8f3.c8c3e7e8.js" rel="prefetch"><link href="/static/js/chunk-2d2248b6.d84473c1.js" rel="prefetch"><link href="/static/js/chunk-2d22523a.4b710d99.js" rel="prefetch"><link href="/static/js/main.c3f36893.js" rel="prefetch"><link href="/static/js/main~workouts.a74990d7.js" rel="prefetch"><link href="/static/js/profile.6a786c1d.js" rel="prefetch"><link href="/static/js/reset.6f6516bc.js" rel="prefetch"><link href="/static/js/workouts.ed2b92d6.js" rel="prefetch"><link href="/static/css/app.1b990916.css" rel="preload" as="style"><link href="/static/js/app.47532afb.js" rel="preload" as="script"><link href="/static/js/chunk-vendors.71654064.js" rel="preload" as="script"><link href="/static/css/app.1b990916.css" rel="stylesheet"><link rel="icon" type="image/png" sizes="32x32" href="/img/icons/favicon-32x32.png"><link rel="icon" type="image/png" sizes="16x16" href="/img/icons/favicon-16x16.png"><link rel="manifest" href="/manifest.json"><meta name="theme-color" content="#4DBA87"><meta name="apple-mobile-web-app-capable" content="no"><meta name="apple-mobile-web-app-status-bar-style" content="default"><meta name="apple-mobile-web-app-title" content="fittrackee_client"><link rel="apple-touch-icon" href="/img/icons/apple-touch-icon-152x152.png"><link rel="mask-icon" href="/img/icons/safari-pinned-tab.svg" color="#4DBA87"><meta name="msapplication-TileImage" content="/img/icons/msapplication-icon-144x144.png"><meta name="msapplication-TileColor" content="#000000"></head><body><noscript><strong>We're sorry but FitTrackee doesn't work properly without JavaScript enabled. Please enable it to continue.</strong></noscript><div id="app"></div><script src="/static/js/chunk-vendors.71654064.js"></script><script src="/static/js/app.47532afb.js"></script></body></html>

View File

@ -64,7 +64,7 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([
"url": "/img/workouts/mountains.svg"
},
{
"revision": "ac27cacdce535196c127b4f950b04fcf",
"revision": "2d61b8f556cfd6b2fd8cb6bb5d04b8e3",
"url": "/index.html"
},
{
@ -76,12 +76,12 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([
"url": "/robots.txt"
},
{
"revision": "2a55f1c804bfc2c51c03",
"url": "/static/css/admin.2e1912ed.css"
"revision": "a1d50ec70acd25b1b70a",
"url": "/static/css/admin.e96a4210.css"
},
{
"revision": "45aeb8689961e0a5de78",
"url": "/static/css/app.88c1cb13.css"
"revision": "abfdfe6ff6e351d4cef8",
"url": "/static/css/app.1b990916.css"
},
{
"revision": "82c1118c918377daaa71a320ab8eea42",
@ -92,24 +92,24 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([
"url": "/static/css/leaflet.css"
},
{
"revision": "4f21a8566a32a3eaa6cc",
"url": "/static/css/main.0baa26a6.css"
"revision": "2afbe9449a719e10f79a",
"url": "/static/css/main.2ee3c9ac.css"
},
{
"revision": "44ec9db1f0dd0bd662ad",
"url": "/static/css/main~workouts.2563ccfd.css"
"revision": "d37b7cc3f4be1d095e98",
"url": "/static/css/main~workouts.ca97ac72.css"
},
{
"revision": "d13a074cdc41830448c5",
"url": "/static/css/profile.14a2947f.css"
"revision": "46a831b0d7a94cbae773",
"url": "/static/css/profile.b792256b.css"
},
{
"revision": "eaff42a53248eac38103",
"url": "/static/css/reset.3e6931c7.css"
"revision": "9ef2fa45c16d6788a6e2",
"url": "/static/css/reset.dc50c1a7.css"
},
{
"revision": "c3c3a3c7444bd3448bda",
"url": "/static/css/workouts.d952f3cf.css"
"revision": "8a364ff438b4214d5d65",
"url": "/static/css/workouts.9c79c3ad.css"
},
{
"revision": "e719f9244c69e28e7d00e725ca1e280e",
@ -192,12 +192,12 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([
"url": "/static/img/pt-sans-v9-latin-regular.f1f73e45.svg"
},
{
"revision": "2a55f1c804bfc2c51c03",
"url": "/static/js/admin.4047df15.js"
"revision": "a1d50ec70acd25b1b70a",
"url": "/static/js/admin.2f1d393d.js"
},
{
"revision": "45aeb8689961e0a5de78",
"url": "/static/js/app.e01bf3f7.js"
"revision": "abfdfe6ff6e351d4cef8",
"url": "/static/js/app.47532afb.js"
},
{
"revision": "bd7d183c9f68e5f4027d",
@ -220,27 +220,27 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([
"url": "/static/js/chunk-2d22523a.4b710d99.js"
},
{
"revision": "639fd68690c8714c6f5c",
"url": "/static/js/chunk-vendors.5928fb7f.js"
"revision": "1631aa1204c2ef00fa57",
"url": "/static/js/chunk-vendors.71654064.js"
},
{
"revision": "4f21a8566a32a3eaa6cc",
"url": "/static/js/main.265d6693.js"
"revision": "2afbe9449a719e10f79a",
"url": "/static/js/main.c3f36893.js"
},
{
"revision": "44ec9db1f0dd0bd662ad",
"url": "/static/js/main~workouts.aa540c70.js"
"revision": "d37b7cc3f4be1d095e98",
"url": "/static/js/main~workouts.a74990d7.js"
},
{
"revision": "d13a074cdc41830448c5",
"url": "/static/js/profile.7e87449f.js"
"revision": "46a831b0d7a94cbae773",
"url": "/static/js/profile.6a786c1d.js"
},
{
"revision": "eaff42a53248eac38103",
"url": "/static/js/reset.98679f6c.js"
"revision": "9ef2fa45c16d6788a6e2",
"url": "/static/js/reset.6f6516bc.js"
},
{
"revision": "c3c3a3c7444bd3448bda",
"url": "/static/js/workouts.52ba33b8.js"
"revision": "8a364ff438b4214d5d65",
"url": "/static/js/workouts.ed2b92d6.js"
}
]);

View File

@ -14,7 +14,7 @@
importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js");
importScripts(
"/precache-manifest.4d775da2b435165a0140d391654cdbc7.js"
"/precache-manifest.2c04e97988213eb1aa1ce038eb4a9e1d.js"
);
workbox.core.setCacheNameDetails({prefix: "fittrackee_client"});

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,2 @@
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["admin"],{3409:function(e,t,n){"use strict";n("ca8b")},"4d13":function(e,t,n){"use strict";n("4fbb")},"4fbb":function(e,t,n){},"89b3":function(e,t,n){"use strict";n.r(t);var c=n("7a23"),o=n("f7f9"),r=n("dad5"),u=n("2906"),a=function(e){return Object(c["pushScopeId"])("data-v-21f8956c"),e=e(),Object(c["popScopeId"])(),e},b={id:"admin",class:"view"},i={key:0,class:"container"},s=a((function(){return Object(c["createElementVNode"])("div",{id:"bottom"},null,-1)})),O=Object(c["defineComponent"])({setup:function(e){var t=Object(u["a"])(),n=Object(c["computed"])((function(){return t.getters[r["b"].GETTERS.APP_CONFIG]})),a=Object(c["computed"])((function(){return t.getters[r["b"].GETTERS.APP_STATS]})),O=Object(c["computed"])((function(){return t.getters[r["a"].GETTERS.IS_ADMIN]})),l=Object(c["computed"])((function(){return t.getters[r["a"].GETTERS.USER_LOADING]}));return Object(c["onBeforeMount"])((function(){return t.dispatch(r["b"].ACTIONS.GET_APPLICATION_STATS)})),function(e,t){var r=Object(c["resolveComponent"])("router-view");return Object(c["openBlock"])(),Object(c["createElementBlock"])("div",b,[Object(c["unref"])(l)?Object(c["createCommentVNode"])("",!0):(Object(c["openBlock"])(),Object(c["createElementBlock"])("div",i,[Object(c["unref"])(O)?(Object(c["openBlock"])(),Object(c["createBlock"])(r,{key:0,appConfig:Object(c["unref"])(n),appStatistics:Object(c["unref"])(a)},null,8,["appConfig","appStatistics"])):(Object(c["openBlock"])(),Object(c["createBlock"])(o["a"],{key:1})),s]))])}}}),l=(n("4d13"),n("6b0d")),p=n.n(l);const f=p()(O,[["__scopeId","data-v-21f8956c"]]);t["default"]=f},ca8b:function(e,t,n){},f7f9:function(e,t,n){"use strict";var c=n("7a23"),o={id:"error"},r={class:"error-content"},u=Object(c["defineComponent"])({props:{title:null,message:null,buttonText:null,path:{default:"/"}},setup:function(e){var t=e,n=Object(c["toRefs"])(t),u=n.buttonText,a=n.title,b=n.message,i=n.path;return function(e,t){return Object(c["openBlock"])(),Object(c["createElementBlock"])("div",o,[Object(c["createElementVNode"])("div",r,[Object(c["createElementVNode"])("h1",null,Object(c["toDisplayString"])(Object(c["unref"])(a)),1),Object(c["createElementVNode"])("p",null,Object(c["toDisplayString"])(Object(c["unref"])(b)),1),Object(c["unref"])(u)?(Object(c["openBlock"])(),Object(c["createElementBlock"])("button",{key:0,onClick:t[0]||(t[0]=function(t){return e.$router.push(Object(c["unref"])(i))}),class:"upper"},Object(c["toDisplayString"])(Object(c["unref"])(u)),1)):Object(c["createCommentVNode"])("",!0)])])}}}),a=(n("3409"),n("6b0d")),b=n.n(a);const i=b()(u,[["__scopeId","data-v-79ec50fd"]]);var s=i,O=Object(c["defineComponent"])({props:{target:{default:"PAGE"}},setup:function(e){var t=e,n=Object(c["toRefs"])(t),o=n.target;return function(e,t){return Object(c["openBlock"])(),Object(c["createBlock"])(s,{title:"404",message:e.$t("error.NOT_FOUND.".concat(Object(c["unref"])(o))),"button-text":e.$t("common.HOME")},null,8,["message","button-text"])}}});const l=O;t["a"]=l}}]);
//# sourceMappingURL=admin.2f1d393d.js.map

File diff suppressed because one or more lines are too long

View File

@ -1,2 +0,0 @@
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["admin"],{"726e":function(e,t,n){},8185:function(e,t,n){"use strict";n("a27b")},"89b3":function(e,t,n){"use strict";n.r(t);var o=n("7a23"),c=function(e){return Object(o["pushScopeId"])("data-v-2fbe41f1"),e=e(),Object(o["popScopeId"])(),e},r={id:"admin",class:"view"},a={key:0,class:"container"},i=c((function(){return Object(o["createElementVNode"])("div",{id:"bottom"},null,-1)}));function u(e,t,n,c,u,p){var s=Object(o["resolveComponent"])("router-view"),b=Object(o["resolveComponent"])("NotFound");return Object(o["openBlock"])(),Object(o["createElementBlock"])("div",r,[e.userLoading?Object(o["createCommentVNode"])("",!0):(Object(o["openBlock"])(),Object(o["createElementBlock"])("div",a,[e.isAuthUserAmin?(Object(o["openBlock"])(),Object(o["createBlock"])(s,{key:0,appConfig:e.appConfig,appStatistics:e.appStatistics},null,8,["appConfig","appStatistics"])):(Object(o["openBlock"])(),Object(o["createBlock"])(b,{key:1})),i]))])}var p=n("f7f9"),s=n("dad5"),b=n("2906"),d=Object(o["defineComponent"])({name:"Admin",components:{NotFound:p["a"]},setup:function(){var e=Object(b["a"])();Object(o["onBeforeMount"])((function(){return e.dispatch(s["b"].ACTIONS.GET_APPLICATION_STATS)}));var t=Object(o["computed"])((function(){return e.getters[s["b"].GETTERS.APP_LOADING]})),n=Object(o["computed"])((function(){return e.getters[s["b"].GETTERS.APP_CONFIG]})),c=Object(o["computed"])((function(){return e.getters[s["b"].GETTERS.APP_STATS]})),r=Object(o["computed"])((function(){return e.getters[s["a"].GETTERS.IS_ADMIN]})),a=Object(o["computed"])((function(){return e.getters[s["a"].GETTERS.USER_LOADING]}));return{appConfig:n,appLoading:t,appStatistics:c,isAuthUserAmin:r,userLoading:a}}}),l=(n("d14e"),n("6b0d")),O=n.n(l);const m=O()(d,[["render",u],["__scopeId","data-v-2fbe41f1"]]);t["default"]=m},a27b:function(e,t,n){},d14e:function(e,t,n){"use strict";n("726e")},f7f9:function(e,t,n){"use strict";var o=n("7a23");function c(e,t,n,c,r,a){var i=Object(o["resolveComponent"])("Error");return Object(o["openBlock"])(),Object(o["createBlock"])(i,{title:"404",message:e.$t("error.NOT_FOUND.".concat(e.target)),"button-text":e.$t("common.HOME")},null,8,["message","button-text"])}var r={id:"error"},a={class:"error-content"};function i(e,t,n,c,i,u){return Object(o["openBlock"])(),Object(o["createElementBlock"])("div",r,[Object(o["createElementVNode"])("div",a,[Object(o["createElementVNode"])("h1",null,Object(o["toDisplayString"])(e.title),1),Object(o["createElementVNode"])("p",null,Object(o["toDisplayString"])(e.message),1),e.buttonText?(Object(o["openBlock"])(),Object(o["createElementBlock"])("button",{key:0,onClick:t[0]||(t[0]=function(t){return e.$router.push(e.path)}),class:"upper"},Object(o["toDisplayString"])(e.buttonText),1)):Object(o["createCommentVNode"])("",!0)])])}var u=Object(o["defineComponent"])({name:"Error",props:{title:{type:String,required:!0},message:{type:String},buttonText:{type:String},path:{type:String,default:"/"}}}),p=(n("8185"),n("6b0d")),s=n.n(p);const b=s()(u,[["render",i],["__scopeId","data-v-58e20d75"]]);var d=b,l=Object(o["defineComponent"])({name:"NotFound",components:{Error:d},props:{target:{type:String,default:"PAGE"}}});const O=s()(l,[["render",c]]);t["a"]=O}}]);
//# sourceMappingURL=admin.4047df15.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1,2 @@
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["profile"],{"36e8":function(e,t,n){"use strict";n.r(t);var c=n("7a23"),r=n("dad5"),o=n("2906"),u={key:0,id:"profile",class:"container view"},a=Object(c["defineComponent"])({setup:function(e){var t=Object(o["a"])(),n=Object(c["computed"])((function(){return t.getters[r["a"].GETTERS.AUTH_USER_PROFILE]}));return function(e,t){var r=Object(c["resolveComponent"])("router-view");return Object(c["unref"])(n).username?(Object(c["openBlock"])(),Object(c["createElementBlock"])("div",u,[Object(c["createVNode"])(r,{user:Object(c["unref"])(n)},null,8,["user"])])):Object(c["createCommentVNode"])("",!0)}}}),s=(n("44ab"),n("6b0d")),b=n.n(s);const i=b()(a,[["__scopeId","data-v-bb090bfa"]]);t["default"]=i},"44ab":function(e,t,n){"use strict";n("4fe6")},"4fe6":function(e,t,n){},"9b98":function(e,t,n){"use strict";n("d332")},ad3d:function(e,t,n){"use strict";n.r(t);var c=n("7a23"),r=n("6c02"),o=n("3c44"),u=n("71a7"),a=n("dad5"),s=n("2906"),b={key:0,id:"user",class:"view"},i={class:"box"},d=Object(c["defineComponent"])({setup:function(e){var t=Object(r["c"])(),n=Object(s["a"])(),d=Object(c["computed"])((function(){return n.getters[a["e"].GETTERS.USER]}));return Object(c["onBeforeMount"])((function(){t.params.username&&"string"===typeof t.params.username&&n.dispatch(a["e"].ACTIONS.GET_USER,t.params.username)})),Object(c["onBeforeUnmount"])((function(){n.dispatch(a["e"].ACTIONS.EMPTY_USER)})),function(e,t){return Object(c["unref"])(d).username?(Object(c["openBlock"])(),Object(c["createElementBlock"])("div",b,[Object(c["createVNode"])(o["a"],{user:Object(c["unref"])(d)},null,8,["user"]),Object(c["createElementVNode"])("div",i,[Object(c["createVNode"])(u["a"],{user:Object(c["unref"])(d),"from-admin":!0},null,8,["user"])])])):Object(c["createCommentVNode"])("",!0)}}}),f=(n("9b98"),n("6b0d")),O=n.n(f);const j=O()(d,[["__scopeId","data-v-218f8f1e"]]);t["default"]=j},d332:function(e,t,n){}}]);
//# sourceMappingURL=profile.6a786c1d.js.map

File diff suppressed because one or more lines are too long

View File

@ -1,2 +0,0 @@
(window["webpackJsonp"]=window["webpackJsonp"]||[]).push([["profile"],{"0ab6":function(e,t,n){},"36e8":function(e,t,n){"use strict";n.r(t);var r=n("7a23"),c={key:0,id:"profile",class:"container view"};function o(e,t,n,o,a,s){var u=Object(r["resolveComponent"])("router-view");return e.authUser.username?(Object(r["openBlock"])(),Object(r["createElementBlock"])("div",c,[Object(r["createVNode"])(u,{user:e.authUser},null,8,["user"])])):Object(r["createCommentVNode"])("",!0)}var a=n("dad5"),s=n("2906"),u=Object(r["defineComponent"])({name:"ProfileView",setup:function(){var e=Object(s["a"])(),t=Object(r["computed"])((function(){return e.getters[a["a"].GETTERS.AUTH_USER_PROFILE]}));return{authUser:t}}}),i=(n("a6f2"),n("6b0d")),d=n.n(i);const f=d()(u,[["render",o],["__scopeId","data-v-37d55f74"]]);t["default"]=f},"7ffc":function(e,t,n){"use strict";n("b288")},a6f2:function(e,t,n){"use strict";n("0ab6")},ad3d:function(e,t,n){"use strict";n.r(t);var r=n("7a23"),c={key:0,id:"user",class:"view"},o={class:"box"};function a(e,t,n,a,s,u){var i=Object(r["resolveComponent"])("UserHeader"),d=Object(r["resolveComponent"])("UserInfos");return e.user.username?(Object(r["openBlock"])(),Object(r["createElementBlock"])("div",c,[Object(r["createVNode"])(i,{user:e.user},null,8,["user"]),Object(r["createElementVNode"])("div",o,[Object(r["createVNode"])(d,{user:e.user,"from-admin":!0},null,8,["user"])])])):Object(r["createCommentVNode"])("",!0)}var s=n("6c02"),u=n("3c44"),i=n("71a7"),d=n("dad5"),f=n("2906"),b=Object(r["defineComponent"])({name:"UserView",components:{UserHeader:u["a"],UserInfos:i["a"]},setup:function(){var e=Object(s["c"])(),t=Object(f["a"])(),n=Object(r["computed"])((function(){return t.getters[d["e"].GETTERS.USER]}));return Object(r["onBeforeMount"])((function(){e.params.username&&"string"===typeof e.params.username&&t.dispatch(d["e"].ACTIONS.GET_USER,e.params.username)})),Object(r["onBeforeUnmount"])((function(){t.dispatch(d["e"].ACTIONS.EMPTY_USER)})),{user:n}}}),m=(n("7ffc"),n("6b0d")),p=n.n(m);const O=p()(b,[["render",a],["__scopeId","data-v-82f4bbf6"]]);t["default"]=O},b288:function(e,t,n){}}]);
//# sourceMappingURL=profile.7e87449f.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -70,6 +70,12 @@
"plugin:import/recommended",
"plugin:import/typescript"
],
"globals": {
"defineProps": "readonly",
"defineEmits": "readonly",
"defineExpose": "readonly",
"withDefaults": "readonly"
},
"settings": {
"import/resolver": "typescript"
},

View File

@ -22,15 +22,8 @@
<Footer v-if="appConfig" :version="appConfig ? appConfig.version : ''" />
</template>
<script lang="ts">
import {
ComputedRef,
computed,
defineComponent,
ref,
onBeforeMount,
onMounted,
} from 'vue'
<script setup lang="ts">
import { ComputedRef, computed, ref, onBeforeMount, onMounted } from 'vue'
import Footer from '@/components/Footer.vue'
import NavBar from '@/components/NavBar.vue'
@ -39,14 +32,6 @@
import { TAppConfig } from '@/types/application'
import { useStore } from '@/use/useStore'
export default defineComponent({
name: 'App',
components: {
Footer,
NavBar,
NoConfig,
},
setup() {
const store = useStore()
const appConfig: ComputedRef<TAppConfig> = computed(
@ -58,15 +43,12 @@
const hideScrollBar = ref(false)
const displayScrollButton = ref(false)
onBeforeMount(() =>
store.dispatch(ROOT_STORE.ACTIONS.GET_APPLICATION_CONFIG)
)
onBeforeMount(() => store.dispatch(ROOT_STORE.ACTIONS.GET_APPLICATION_CONFIG))
onMounted(() => scroll())
function updateHideScrollBar(isMenuOpen: boolean) {
hideScrollBar.value = isMenuOpen
}
function isScrolledToBottom(element: Element): boolean {
return (
element.getBoundingClientRect().top < window.innerHeight &&
@ -76,8 +58,7 @@
function scroll() {
window.onscroll = () => {
let bottom = document.querySelector('#bottom')
displayScrollButton.value =
bottom !== null && isScrolledToBottom(bottom)
displayScrollButton.value = bottom !== null && isScrolledToBottom(bottom)
}
}
function scrollToTop() {
@ -89,17 +70,6 @@
displayScrollButton.value = false
}, 300)
}
return {
appConfig,
appLoading,
hideScrollBar,
displayScrollButton,
scrollToTop,
updateHideScrollBar,
}
},
})
</script>
<style lang="scss" scoped>

View File

@ -82,13 +82,12 @@
</div>
</template>
<script lang="ts">
<script setup lang="ts">
import {
ComputedRef,
PropType,
computed,
defineComponent,
reactive,
withDefaults,
onBeforeMount,
} from 'vue'
import { useRouter } from 'vue-router'
@ -98,21 +97,17 @@
import { useStore } from '@/use/useStore'
import { getFileSizeInMB } from '@/utils/files'
export default defineComponent({
name: 'AdminApplication',
props: {
appConfig: {
type: Object as PropType<TAppConfig>,
required: true,
},
edition: {
type: Boolean,
default: false,
},
},
setup(props) {
interface Props {
appConfig: TAppConfig
edition?: boolean
}
const props = withDefaults(defineProps<Props>(), {
edition: false,
})
const store = useStore()
const router = useRouter()
const appData: TAppConfigForm = reactive({
max_users: 0,
max_single_file_size: 0,
@ -140,7 +135,6 @@
(appData[key] = appConfig[key])
})
}
function onCancel() {
updateForm(props.appConfig)
store.commit(ROOT_STORE.MUTATIONS.EMPTY_ERROR_MESSAGES)
@ -152,10 +146,6 @@
formData.max_zip_file_size *= 1048576
store.dispatch(ROOT_STORE.ACTIONS.UPDATE_APPLICATION_CONFIG, formData)
}
return { appData, errorMessages, onCancel, onSubmit }
},
})
</script>
<style lang="scss" scoped>

View File

@ -3,7 +3,7 @@
<Card>
<template #title>{{ $t('admin.ADMINISTRATION') }}</template>
<template #content>
<AppStatsCards :app-statistics="appStatistics" />
<AppStatsCards :appStatistics="appStatistics" />
<div class="admin-menu description-list">
<dl>
<dt>
@ -46,32 +46,22 @@
</div>
</template>
<script lang="ts">
import { PropType, capitalize, defineComponent } from 'vue'
<script setup lang="ts">
import { capitalize, toRefs, withDefaults } from 'vue'
import AppStatsCards from '@/components/Administration/AppStatsCards.vue'
import Card from '@/components/Common/Card.vue'
import { IAppStatistics, TAppConfig } from '@/types/application'
export default defineComponent({
name: 'AdminMenu',
components: {
AppStatsCards,
Card,
},
props: {
appConfig: {
type: Object as PropType<TAppConfig>,
required: true,
},
appStatistics: {
type: Object as PropType<IAppStatistics>,
},
},
setup() {
return { capitalize }
},
interface Props {
appConfig: TAppConfig
appStatistics?: IAppStatistics
}
const props = withDefaults(defineProps<Props>(), {
appStatistics: () => ({} as IAppStatistics),
})
const { appConfig, appStatistics } = toRefs(props)
</script>
<style lang="scss" scoped>

View File

@ -82,8 +82,8 @@
</div>
</template>
<script lang="ts">
import { ComputedRef, computed, defineComponent } from 'vue'
<script setup lang="ts">
import { ComputedRef, computed } from 'vue'
import { useI18n } from 'vue-i18n'
import { ROOT_STORE, SPORTS_STORE } from '@/store/constants'
@ -91,11 +91,9 @@
import { useStore } from '@/use/useStore'
import { translateSports } from '@/utils/sports'
export default defineComponent({
name: 'AdminSports',
setup() {
const { t } = useI18n()
const store = useStore()
const translatedSports: ComputedRef<ITranslatedSport[]> = computed(() =>
translateSports(store.getters[SPORTS_STORE.GETTERS.SPORTS], t)
)
@ -109,10 +107,6 @@
isActive,
})
}
return { errorMessages, translatedSports, updateSportStatus }
},
})
</script>
<style lang="scss" scoped>

View File

@ -115,12 +115,11 @@
</div>
</template>
<script lang="ts">
<script setup lang="ts">
import { format } from 'date-fns'
import {
ComputedRef,
computed,
defineComponent,
reactive,
watch,
capitalize,
@ -139,14 +138,6 @@
import { getQuery, sortList } from '@/utils/api'
import { getDateWithTZ } from '@/utils/dates'
export default defineComponent({
name: 'AdminUsers',
components: {
FilterSelects,
Pagination,
UserPicture,
},
setup() {
const store = useStore()
const route = useRoute()
const router = useRouter()
@ -161,7 +152,6 @@
let query: TPaginationPayload = reactive(
getQuery(route.query, orderByList, defaultOrderBy)
)
const authUser: ComputedRef<IUserProfile> = computed(
() => store.getters[AUTH_USER_STORE.GETTERS.AUTH_USER_PROFILE]
)
@ -175,6 +165,8 @@
() => store.getters[ROOT_STORE.GETTERS.ERROR_MESSAGES]
)
onBeforeMount(() => loadUsers(query))
function loadUsers(queryParams: TPaginationPayload) {
store.dispatch(USERS_STORE.ACTIONS.GET_USERS, queryParams)
}
@ -192,7 +184,9 @@
router.push({ path: '/admin/users', query })
}
onBeforeMount(() => loadUsers(query))
onUnmounted(() => {
store.dispatch(USERS_STORE.ACTIONS.EMPTY_USERS)
})
watch(
() => route.query,
@ -201,27 +195,6 @@
loadUsers(query)
}
)
onUnmounted(() => {
store.dispatch(USERS_STORE.ACTIONS.EMPTY_USERS)
})
return {
authUser,
errorMessages,
orderByList,
pagination,
query,
sortList,
users,
capitalize,
format,
getDateWithTZ,
reloadUsers,
updateUser,
}
},
})
</script>
<style lang="scss" scoped>

View File

@ -23,45 +23,34 @@
</div>
</template>
<script lang="ts">
import { PropType, defineComponent, computed } from 'vue'
<script setup lang="ts">
import { computed, withDefaults } from 'vue'
import StatCard from '@/components/Common/StatCard.vue'
import { IAppStatistics } from '@/types/application'
import { getReadableFileSize } from '@/utils/files'
export default defineComponent({
name: 'UserStatsCards',
components: {
StatCard,
},
props: {
appStatistics: {
type: Object as PropType<IAppStatistics>,
default: () => {
return {}
},
},
},
setup(props) {
return {
uploadDirSize: computed(() =>
interface Props {
appStatistics?: IAppStatistics
}
const props = withDefaults(defineProps<Props>(), {
appStatistics: () => ({} as IAppStatistics),
})
const uploadDirSize = computed(() =>
props.appStatistics.uploads_dir_size
? getReadableFileSize(props.appStatistics.uploads_dir_size, false)
: { size: 0, suffix: 'bytes' }
),
usersCount: computed(() =>
)
const usersCount = computed(() =>
props.appStatistics.users ? props.appStatistics.users : 0
),
sportsCount: computed(() =>
)
const sportsCount = computed(() =>
props.appStatistics.sports ? props.appStatistics.sports : 0
),
workoutCount: computed(() =>
)
const workoutCount = computed(() =>
props.appStatistics.workouts ? props.appStatistics.workouts : 0
),
}
},
})
)
</script>
<style lang="scss">

View File

@ -1,19 +1,13 @@
<template>
<div id="about">
<div id="bike">
<img class="bike-img" :src="'/img/bike.svg'" alt="mountain bike" />
</div>
</template>
<script>
export default {
name: 'About',
}
</script>
<style scoped lang="scss">
@import '~@/scss/base';
#about {
#bike {
display: flex;
justify-content: center;

View File

@ -4,15 +4,12 @@
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
name: 'AlertMessage',
props: {
message: String,
},
})
<script setup lang="ts">
import { toRefs } from 'vue'
const props = defineProps<{
message: string
}>()
const { message } = toRefs(props)
</script>
<style scoped lang="scss">

View File

@ -9,13 +9,6 @@
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
name: 'Card',
})
</script>
<style lang="scss">
@import '~@/scss/base';

View File

@ -14,31 +14,23 @@
</div>
</template>
<script lang="ts">
import { defineComponent, ref, watch } from 'vue'
<script setup lang="ts">
import { ref, watch, withDefaults } from 'vue'
interface Props {
name: string
charLimit?: number
disabled?: boolean
input?: string
}
const props = withDefaults(defineProps<Props>(), {
charLimit: 500,
disabled: false,
input: '',
})
const emit = defineEmits(['updateValue'])
export default defineComponent({
name: 'CustomTextArea',
props: {
charLimit: {
type: Number,
default: 500,
},
disabled: {
type: Boolean,
default: false,
},
input: {
type: String,
default: '',
},
name: {
type: String,
required: true,
},
},
emits: ['updateValue'],
setup(props, { emit }) {
let text = ref('')
function updateText(event: Event & { target: HTMLInputElement }) {
@ -51,10 +43,6 @@
text.value = value
}
)
return { text, updateText }
},
})
</script>
<style lang="scss" scoped>

View File

@ -17,28 +17,21 @@
</div>
</template>
<script lang="ts">
import { PropType, defineComponent, ref, watch } from 'vue'
<script setup lang="ts">
import { ref, watch } from 'vue'
import { useRoute } from 'vue-router'
import { IDropdownOption, TDropdownOptions } from '@/types/forms'
interface Props {
options: TDropdownOptions
selected: string
}
const props = defineProps<Props>()
export default defineComponent({
name: 'Dropdown',
props: {
options: {
type: Object as PropType<TDropdownOptions>,
required: true,
},
selected: {
type: String,
required: true,
},
},
emits: {
const emit = defineEmits({
selected: (option: IDropdownOption) => option,
},
setup(props, { emit }) {
})
const route = useRoute()
let isOpen = ref(false)
let dropdownOptions = props.options.map((option) => option)
@ -55,15 +48,6 @@
() => route.path,
() => (isOpen.value = false)
)
return {
dropdownOptions,
isOpen,
toggleDropdown,
updateSelected,
}
},
})
</script>
<style scoped lang="scss">

View File

@ -10,28 +10,19 @@
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
<script setup lang="ts">
import { toRefs, withDefaults } from 'vue'
export default defineComponent({
name: 'Error',
props: {
title: {
type: String,
required: true,
},
message: {
type: String,
},
buttonText: {
type: String,
},
path: {
type: String,
default: '/',
},
},
interface Props {
title: string
message: string
buttonText: string
path?: string
}
const props = withDefaults(defineProps<Props>(), {
path: '/',
})
const { buttonText, title, message, path } = toRefs(props)
</script>
<style scoped lang="scss">

View File

@ -9,15 +9,14 @@
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
<script setup lang="ts">
import { toRefs } from 'vue'
export default defineComponent({
name: 'ErrorMessage',
props: {
message: [String, Array],
},
})
interface Props {
message: string | string[]
}
const props = defineProps<Props>()
const { message } = toRefs(props)
</script>
<style scoped lang="scss">

View File

@ -34,7 +34,7 @@
:value="query.per_page"
@change="onSelectUpdate"
>
<option v-for="nb in per_page" :value="nb" :key="nb">
<option v-for="nb in perPage" :value="nb" :key="nb">
{{ nb }}
</option>
</select>
@ -42,43 +42,27 @@
</div>
</template>
<script lang="ts">
import { PropType, defineComponent } from 'vue'
<script setup lang="ts">
import { toRefs } from 'vue'
import { TPaginationPayload } from '@/types/api'
export default defineComponent({
name: 'FilterSelects',
props: {
order_by: {
type: Object as PropType<string[]>,
required: true,
},
query: {
type: Object as PropType<TPaginationPayload>,
required: true,
},
sort: {
type: Object as PropType<string[]>,
required: true,
},
message: {
type: String,
required: true,
},
},
emits: ['updateSelect'],
setup(props, { emit }) {
interface Props {
order_by: string[]
query: TPaginationPayload
sort: string[]
message: string
}
const props = defineProps<Props>()
const emit = defineEmits(['updateSelect'])
const { order_by, query, sort, message } = toRefs(props)
const perPage = [10, 25, 50, 100]
function onSelectUpdate(event: Event & { target: HTMLInputElement }) {
emit('updateSelect', event.target.id, event.target.value)
}
return {
per_page: [10, 25, 50, 100],
onSelectUpdate,
}
},
})
</script>
<style lang="scss" scoped>

View File

@ -20,8 +20,8 @@
</div>
</template>
<script lang="ts">
import { defineComponent, inject } from 'vue'
<script setup lang="ts">
import { inject, toRefs, withDefaults } from 'vue'
import CyclingSport from '@/components/Common/Images/SportImage/CyclingSport.vue'
import CyclingTransport from '@/components/Common/Images/SportImage/CyclingTransport.vue'
@ -35,33 +35,14 @@
import Trail from '@/components/Common/Images/SportImage/Trail.vue'
import Walking from '@/components/Common/Images/SportImage/Walking.vue'
export default defineComponent({
name: 'SportImage',
components: {
CyclingSport,
CyclingTransport,
Hiking,
MountainBiking,
MountainBikingElectric,
Rowing,
Running,
SkiingAlpine,
SkiingCrossCountry,
Trail,
Walking,
},
props: {
sportLabel: {
type: String,
required: true,
},
title: {
type: String,
required: false,
},
},
setup() {
return { sportColors: inject('sportColors') }
},
interface Props {
sportLabel: string
title?: string
}
const props = withDefaults(defineProps<Props>(), {
title: '',
})
const { sportLabel, title } = toRefs(props)
const sportColors = inject('sportColors')
</script>

View File

@ -2,13 +2,6 @@
<div class="loader" />
</template>
<script lang="ts">
import { defineComponent } from 'vue'
export default defineComponent({
name: 'Loader',
})
</script>
<style scoped lang="scss">
@import '~@/scss/base';
.loader {

View File

@ -31,38 +31,30 @@
</div>
</template>
<script lang="ts">
import { ComputedRef, computed, defineComponent, onUnmounted } from 'vue'
<script setup lang="ts">
import { ComputedRef, computed, toRefs, withDefaults, onUnmounted } from 'vue'
import { ROOT_STORE } from '@/store/constants'
import { useStore } from '@/use/useStore'
export default defineComponent({
name: 'Modal',
props: {
title: {
type: String,
required: true,
},
message: {
type: String,
required: true,
},
strongMessage: {
type: String || null,
default: null,
},
},
emits: ['cancelAction', 'confirmAction'],
setup(props, { emit }) {
interface Props {
title: string
message: string
strongMessage?: string | null
}
const props = withDefaults(defineProps<Props>(), {
strongMessage: () => null,
})
const emit = defineEmits(['cancelAction', 'confirmAction'])
const store = useStore()
const { title, message, strongMessage } = toRefs(props)
const errorMessages: ComputedRef<string | string[] | null> = computed(
() => store.getters[ROOT_STORE.GETTERS.ERROR_MESSAGES]
)
onUnmounted(() => store.commit(ROOT_STORE.MUTATIONS.EMPTY_ERROR_MESSAGES))
return { errorMessages, emit }
},
})
</script>
<style lang="scss" scoped>

View File

@ -6,21 +6,15 @@
/>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
<script setup lang="ts">
import { toRefs, withDefaults } from 'vue'
import Error from '@/components/Common/Error.vue'
export default defineComponent({
name: 'NotFound',
components: {
Error,
},
props: {
target: {
type: String,
default: 'PAGE',
},
},
interface Props {
target?: string
}
const props = withDefaults(defineProps<Props>(), {
target: 'PAGE',
})
const { target } = toRefs(props)
</script>

View File

@ -42,37 +42,27 @@
</nav>
</template>
<script lang="ts">
import { PropType, defineComponent } from 'vue'
<script setup lang="ts">
import { toRefs } from 'vue'
import { IPagination, TPaginationPayload } from '@/types/api'
import { IPagination } from '@/types/api'
import { TWorkoutsPayload } from '@/types/workouts'
import { rangePagination } from '@/utils/api'
export default defineComponent({
name: 'Pagination',
props: {
pagination: {
type: Object as PropType<IPagination>,
required: true,
},
path: {
type: String,
required: true,
},
query: {
type: Object as PropType<TPaginationPayload>,
required: true,
},
},
setup(props) {
function getQuery(page: number, cursor?: number): TPaginationPayload {
const newQuery = Object.assign({}, props.query)
interface Props {
pagination: IPagination
path: string
query: TWorkoutsPayload
}
const props = defineProps<Props>()
const { pagination, path, query } = toRefs(props)
function getQuery(page: number, cursor?: number): TWorkoutsPayload {
const newQuery = Object.assign({}, query.value)
newQuery.page = cursor ? page + cursor : page
return newQuery
}
return { rangePagination, getQuery }
},
})
</script>
<style lang="scss" scoped>

View File

@ -12,26 +12,16 @@
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
<script setup lang="ts">
import { toRefs } from 'vue'
export default defineComponent({
name: 'StatCard',
props: {
icon: {
type: String,
required: true,
},
value: {
type: [String, Number],
required: true,
},
text: {
type: String,
required: true,
},
},
})
interface Props {
icon: string
text: string
value: string | number
}
const props = defineProps<Props>()
const { icon, text, value } = toRefs(props)
</script>
<style lang="scss">

View File

@ -22,29 +22,21 @@
</div>
</template>
<script lang="ts">
import { defineComponent, PropType } from 'vue'
<script setup lang="ts">
import { toRefs, withDefaults } from 'vue'
import { IWorkout } from '@/types/workouts'
import { getApiUrl } from '@/utils'
export default defineComponent({
name: 'StaticMap',
props: {
workout: {
type: Object as PropType<IWorkout>,
required: true,
},
displayHover: {
type: Boolean,
default: false,
},
},
setup(props) {
const imageUrl = `${getApiUrl()}workouts/map/${props.workout.map}`
return { imageUrl }
},
interface Props {
workout: IWorkout
displayHover?: boolean
}
const props = withDefaults(defineProps<Props>(), {
displayHover: false,
})
const { displayHover } = toRefs(props)
const imageUrl = `${getApiUrl()}workouts/map/${props.workout.map}`
</script>
<style lang="scss">

View File

@ -30,15 +30,8 @@
</div>
</template>
<script lang="ts">
import {
ComputedRef,
PropType,
computed,
defineComponent,
ref,
onBeforeMount,
} from 'vue'
<script setup lang="ts">
import { ComputedRef, computed, ref, onBeforeMount, toRefs } from 'vue'
import WorkoutCard from '@/components/Workout/WorkoutCard.vue'
import NoWorkouts from '@/components/Workouts/NoWorkouts.vue'
@ -49,31 +42,20 @@
import { useStore } from '@/use/useStore'
import { defaultOrder } from '@/utils/workouts'
export default defineComponent({
name: 'Timeline',
components: {
NoWorkouts,
WorkoutCard,
},
props: {
sports: {
type: Object as PropType<ISport[]>,
required: true,
},
user: {
type: Object as PropType<IUserProfile>,
required: true,
},
},
setup(props) {
interface Props {
sports: ISport[]
user: IUserProfile
}
const props = defineProps<Props>()
const store = useStore()
const { sports, user } = toRefs(props)
let page = ref(1)
const per_page = 5
const initWorkoutsCount =
props.user.nb_workouts >= per_page ? per_page : props.user.nb_workouts
onBeforeMount(() => loadWorkouts())
const workouts: ComputedRef<IWorkout[]> = computed(
() => store.getters[WORKOUTS_STORE.GETTERS.TIMELINE_WORKOUTS]
)
@ -98,16 +80,6 @@
...defaultOrder,
})
}
return {
initWorkoutsCount,
moreWorkoutsExist,
per_page,
workouts,
loadMoreWorkouts,
}
},
})
</script>
<style lang="scss" scoped>

View File

@ -23,61 +23,36 @@
</div>
</template>
<script lang="ts">
<script setup lang="ts">
import { addDays, format, isSameDay, isSameMonth, isToday } from 'date-fns'
import {
PropType,
Ref,
defineComponent,
ref,
toRefs,
watch,
onMounted,
} from 'vue'
import { Ref, ref, toRefs, watch, onMounted } from 'vue'
import CalendarWorkouts from '@/components/Dashboard/UserCalendar/CalendarWorkouts.vue'
import { ISport } from '@/types/sports'
import { IWorkout } from '@/types/workouts'
import { getDateWithTZ } from '@/utils/dates'
export default defineComponent({
name: 'CalendarCells',
components: {
CalendarWorkouts,
},
props: {
currentDay: {
type: Date,
required: true,
},
endDate: {
type: Date,
required: true,
},
sports: {
type: Object as PropType<ISport[]>,
required: true,
},
startDate: {
type: Date,
required: true,
},
timezone: {
type: String,
required: true,
},
weekStartingMonday: {
type: Boolean,
required: true,
},
workouts: {
type: Object as PropType<IWorkout[]>,
required: true,
},
},
setup(props) {
interface Props {
currentDay: Date
endDate: Date
sports: ISport[]
startDate: Date
timezone: string
weekStartingMonday: boolean
workouts: IWorkout[]
}
const props = defineProps<Props>()
const {
currentDay,
endDate,
sports,
startDate,
timezone,
weekStartingMonday,
workouts,
} = toRefs(props)
const rows: Ref<Date[][]> = ref([])
let { startDate, endDate, weekStartingMonday } = toRefs(props)
onMounted(() => getDays())
@ -93,21 +68,16 @@
rows.value.push(days)
}
}
function isWeekEnd(day: number): boolean {
return weekStartingMonday.value
? [5, 6].includes(day)
: [0, 6].includes(day)
}
function filterWorkouts(day: Date, workouts: IWorkout[]) {
if (workouts) {
return workouts
.filter((workout) =>
isSameDay(
getDateWithTZ(workout.workout_date, props.timezone),
day
)
isSameDay(getDateWithTZ(workout.workout_date, timezone), day)
)
.reverse()
}
@ -118,10 +88,6 @@
() => props.currentDay,
() => getDays()
)
return { rows, format, isSameMonth, isToday, isWeekEnd, filterWorkouts }
},
})
</script>
<style lang="scss">

View File

@ -6,30 +6,19 @@
</div>
</template>
<script lang="ts">
<script setup lang="ts">
import { format, addDays } from 'date-fns'
import { defineComponent } from 'vue'
export default defineComponent({
name: 'CalendarDays',
props: {
startDate: {
type: Date,
required: true,
},
localeOptions: {
type: String,
required: true,
},
},
setup(props) {
interface Props {
startDate: Date
localeOptions: string
}
const props = defineProps<Props>()
const days = []
for (let i = 0; i < 7; i++) {
days.push(addDays(props.startDate, i))
}
return { days, addDays, format }
},
})
</script>
<style lang="scss">

View File

@ -20,27 +20,19 @@
</div>
</template>
<script lang="ts">
<script setup lang="ts">
import { format } from 'date-fns'
import { defineComponent } from 'vue'
import { toRefs } from 'vue'
export default defineComponent({
name: 'CalendarHeader',
props: {
day: {
type: Date,
required: true,
},
localeOptions: {
type: String,
required: true,
},
},
emits: ['displayNextMonth', 'displayPreviousMonth'],
setup(props, { emit }) {
return { emit, format }
},
})
interface Props {
day: Date
localeOptions: string
}
const props = defineProps<Props>()
const emit = defineEmits(['displayNextMonth', 'displayPreviousMonth'])
const { day, localeOptions } = toRefs(props)
</script>
<style lang="scss">

View File

@ -13,7 +13,7 @@
aria-hidden="true"
:title="
workout.records.map(
(record) => ` ${t(`workouts.RECORD_${record.record_type}`)}`
(record) => ` ${$t(`workouts.RECORD_${record.record_type}`)}`
)
"
/>
@ -21,29 +21,17 @@
</div>
</template>
<script lang="ts">
import { defineComponent, PropType } from 'vue'
import { useI18n } from 'vue-i18n'
<script setup lang="ts">
import { toRefs } from 'vue'
import { IWorkout } from '@/types/workouts'
interface Props {
workout: IWorkout
sportLabel: string
}
const props = defineProps<Props>()
export default defineComponent({
name: 'CalendarWorkout',
props: {
workout: {
type: Object as PropType<IWorkout>,
required: true,
},
sportLabel: {
type: String,
required: true,
},
},
setup() {
const { t } = useI18n()
return { t }
},
})
const { workout, sportLabel } = toRefs(props)
</script>
<style lang="scss">

View File

@ -34,8 +34,8 @@
</div>
</template>
<script lang="ts">
import { PropType, computed, defineComponent } from 'vue'
<script setup lang="ts">
import { computed, toRefs } from 'vue'
import CalendarWorkout from '@/components/Dashboard/UserCalendar/CalendarWorkout.vue'
import CalendarWorkoutsChart from '@/components/Dashboard/UserCalendar/CalendarWorkoutsChart.vue'
@ -44,31 +44,16 @@
import { getSportLabel, sportIdColors } from '@/utils/sports'
import { getDonutDatasets } from '@/utils/workouts'
export default defineComponent({
name: 'CalendarWorkouts',
components: {
CalendarWorkout,
CalendarWorkoutsChart,
},
props: {
workouts: {
type: Object as PropType<IWorkout[]>,
required: true,
},
sports: {
type: Object as PropType<ISport[]>,
required: true,
},
},
setup(props) {
return {
chartDatasets: computed(() => getDonutDatasets(props.workouts)),
colors: computed(() => sportIdColors(props.sports)),
displayedWorkoutCount: 6,
getSportLabel,
interface Props {
workouts: IWorkout[]
sports: ISport[]
}
},
})
const props = defineProps<Props>()
const { workouts, sports } = toRefs(props)
const chartDatasets = computed(() => getDonutDatasets(props.workouts))
const colors = computed(() => sportIdColors(props.sports))
const displayedWorkoutCount = 6
</script>
<style lang="scss">

View File

@ -22,8 +22,8 @@
</div>
</template>
<script lang="ts">
import { PropType, defineComponent, ref } from 'vue'
<script setup lang="ts">
import { ref, toRefs } from 'vue'
import CalendarWorkout from '@/components/Dashboard/UserCalendar/CalendarWorkout.vue'
import DonutChart from '@/components/Dashboard/UserCalendar/DonutChart.vue'
@ -31,39 +31,21 @@
import { IWorkout } from '@/types/workouts'
import { getSportLabel } from '@/utils/sports'
export default defineComponent({
name: 'CalendarWorkoutsChart',
components: {
CalendarWorkout,
DonutChart,
},
props: {
colors: {
type: Object as PropType<Record<number, string>>,
required: true,
},
datasets: {
type: Object as PropType<Record<number, Record<string, number>>>,
required: true,
},
sports: {
type: Object as PropType<ISport[]>,
required: true,
},
workouts: {
type: Object as PropType<IWorkout[]>,
required: true,
},
},
setup() {
interface Props {
colors: Record<number, string>
datasets: Record<number, Record<string, number>>
sports: ISport[]
workouts: IWorkout[]
}
const props = defineProps<Props>()
const { colors, datasets, sports, workouts } = toRefs(props)
const isHidden = ref(true)
function togglePane(event: Event & { target: HTMLElement }) {
event.stopPropagation()
isHidden.value = !isHidden.value
}
return { isHidden, getSportLabel, togglePane }
},
})
</script>
<style lang="scss" scoped>

View File

@ -22,22 +22,16 @@
</div>
</template>
<script lang="ts">
import { PropType, defineComponent } from 'vue'
<script setup lang="ts">
import { toRefs } from 'vue'
export default defineComponent({
name: 'DonutChart',
props: {
colors: {
type: Object as PropType<Record<number, string>>,
required: true,
},
datasets: {
type: Object as PropType<Record<number, Record<string, number>>>,
required: true,
},
},
setup() {
interface Props {
colors: Record<number, string>
datasets: Record<number, Record<string, number>>
}
const props = defineProps<Props>()
const { colors, datasets } = toRefs(props)
let angleOffset = -90
const cx = 16
const cy = 16
@ -58,16 +52,4 @@
angleOffset = percentage * 360 + angleOffset
return rotation
}
return {
angleOffset,
circumference,
cx,
cy,
radius,
calculateStrokeDashOffset,
returnCircleTransformValue,
}
},
})
</script>

View File

@ -21,16 +21,9 @@
</div>
</template>
<script lang="ts">
<script setup lang="ts">
import { addMonths, format, subMonths } from 'date-fns'
import {
ComputedRef,
PropType,
computed,
defineComponent,
ref,
onBeforeMount,
} from 'vue'
import { ComputedRef, computed, ref, toRefs, onBeforeMount } from 'vue'
import CalendarCells from '@/components/Dashboard/UserCalendar/CalendarCells.vue'
import CalendarDays from '@/components/Dashboard/UserCalendar/CalendarDays.vue'
@ -43,42 +36,26 @@
import { getCalendarStartAndEnd } from '@/utils/dates'
import { defaultOrder } from '@/utils/workouts'
export default defineComponent({
name: 'UserCalendar',
components: {
CalendarCells,
CalendarDays,
CalendarHeader,
},
props: {
sports: {
type: Object as PropType<ISport[]>,
required: true,
},
user: {
type: Object as PropType<IUserProfile>,
required: true,
},
},
setup(props) {
interface Props {
sports: ISport[]
user: IUserProfile
}
const props = defineProps<Props>()
const store = useStore()
onBeforeMount(() => getCalendarWorkouts())
const { sports, user } = toRefs(props)
const dateFormat = 'yyyy-MM-dd'
let day = ref(new Date())
let calendarDates = ref(
getCalendarStartAndEnd(day.value, props.user.weekm)
)
let calendarDates = ref(getCalendarStartAndEnd(day.value, props.user.weekm))
const calendarWorkouts: ComputedRef<IWorkout[]> = computed(
() => store.getters[WORKOUTS_STORE.GETTERS.CALENDAR_WORKOUTS]
)
onBeforeMount(() => getCalendarWorkouts())
function getCalendarWorkouts() {
calendarDates.value = getCalendarStartAndEnd(
day.value,
props.user.weekm
)
calendarDates.value = getCalendarStartAndEnd(day.value, props.user.weekm)
const apiParams: TWorkoutsPayload = {
from: format(calendarDates.value.start, dateFormat),
to: format(calendarDates.value.end, dateFormat),
@ -88,7 +65,6 @@
}
store.dispatch(WORKOUTS_STORE.ACTIONS.GET_CALENDAR_WORKOUTS, apiParams)
}
function displayNextMonth() {
day.value = addMonths(day.value, 1)
getCalendarWorkouts()
@ -97,16 +73,6 @@
day.value = subMonths(day.value, 1)
getCalendarWorkouts()
}
return {
day,
calendarDates,
calendarWorkouts,
displayNextMonth,
displayPreviousMonth,
}
},
})
</script>
<style lang="scss">

View File

@ -15,41 +15,28 @@
</div>
</template>
<script lang="ts">
<script setup lang="ts">
import { endOfMonth, startOfMonth } from 'date-fns'
import { PropType, defineComponent } from 'vue'
import { toRefs } from 'vue'
import StatChart from '@/components/Common/StatsChart/index.vue'
import { ISport } from '@/types/sports'
import { IUserProfile } from '@/types/user'
export default defineComponent({
name: 'UserMonthStats',
components: {
StatChart,
},
props: {
sports: {
type: Object as PropType<ISport[]>,
required: true,
},
user: {
type: Object as PropType<IUserProfile>,
required: true,
},
},
setup(props) {
interface Props {
sports: ISport[]
user: IUserProfile
}
const props = defineProps<Props>()
const { sports, user } = toRefs(props)
const date = new Date()
return {
chartParams: {
const chartParams = {
duration: 'week',
start: startOfMonth(date),
end: endOfMonth(date),
},
selectedSportIds: props.sports.map((sport) => sport.id),
}
},
})
const selectedSportIds = props.sports.map((sport) => sport.id)
</script>
<style lang="scss" scoped>

View File

@ -7,9 +7,9 @@
</template>
<template #content>
<div class="record" v-for="record in records.records" :key="record.id">
<span class="record-type">{{
t(`workouts.RECORD_${record.record_type}`)
}}</span>
<span class="record-type">
{{ $t(`workouts.RECORD_${record.record_type}`) }}
</span>
<span class="record-value">{{ record.value }}</span>
<span class="record-date">
<router-link
@ -17,8 +17,9 @@
name: 'Workout',
params: { workoutId: record.workout_id },
}"
>{{ record.workout_date }}</router-link
>
{{ record.workout_date }}
</router-link>
</span>
</div>
</template>
@ -26,29 +27,18 @@
</div>
</template>
<script lang="ts">
import { PropType, defineComponent } from 'vue'
import { useI18n } from 'vue-i18n'
<script setup lang="ts">
import { toRefs } from 'vue'
import { IRecord } from '@/types/workouts'
import { IRecordsBySports } from '@/types/workouts'
export default defineComponent({
name: 'RecordsCard',
props: {
records: {
type: Object as PropType<IRecord[]>,
required: true,
},
sportTranslatedLabel: {
type: String,
required: true,
},
},
setup() {
const { t } = useI18n()
return { t }
},
})
interface Props {
records: IRecordsBySports
sportTranslatedLabel: string
}
const props = defineProps<Props>()
const { records, sportTranslatedLabel } = toRefs(props)
</script>
<style lang="scss" scoped>

View File

@ -18,8 +18,8 @@
</div>
</template>
<script lang="ts">
import { computed, defineComponent, PropType } from 'vue'
<script setup lang="ts">
import { computed } from 'vue'
import { useI18n } from 'vue-i18n'
import RecordsCard from '@/components/Dashboard/UserRecords/RecordsCard.vue'
@ -28,23 +28,14 @@
import { getRecordsBySports } from '@/utils/records'
import { translateSports } from '@/utils/sports'
export default defineComponent({
name: 'UserRecords',
components: {
RecordsCard,
},
props: {
sports: {
type: Object as PropType<ISport[]>,
required: true,
},
user: {
type: Object as PropType<IUserProfile>,
required: true,
},
},
setup(props) {
interface Props {
sports: ISport[]
user: IUserProfile
}
const props = defineProps<Props>()
const { t } = useI18n()
const recordsBySport = computed(() =>
getRecordsBySports(
props.user.records,
@ -52,9 +43,6 @@
props.user.timezone
)
)
return { recordsBySport }
},
})
</script>
<style lang="scss" scoped>

View File

@ -12,8 +12,8 @@
/>
<StatCard
icon="clock-o"
:value="total_duration.days"
:text="total_duration.duration"
:value="totalDuration.days"
:text="totalDuration.duration"
/>
<StatCard
icon="tags"
@ -23,29 +23,24 @@
</div>
</template>
<script lang="ts">
import { ComputedRef, PropType, defineComponent, computed } from 'vue'
<script setup lang="ts">
import { ComputedRef, computed, toRefs } from 'vue'
import { useI18n } from 'vue-i18n'
import StatCard from '@/components/Common/StatCard.vue'
import { IUserProfile } from '@/types/user'
interface Props {
user: IUserProfile
}
const props = defineProps<Props>()
export default defineComponent({
name: 'UserStatsCards',
components: {
StatCard,
},
props: {
user: {
type: Object as PropType<IUserProfile>,
required: true,
},
},
setup(props) {
const { t } = useI18n()
const total_duration: ComputedRef<string> = computed(
const { user } = toRefs(props)
const userTotalDuration: ComputedRef<string> = computed(
() => props.user.total_duration
)
const totalDuration = computed(() => get_duration(userTotalDuration))
function get_duration(total_duration: ComputedRef<string>) {
const duration = total_duration.value.match(/day/g)
@ -62,10 +57,6 @@
duration: `${duration.split(':')[0]}h ${duration.split(':')[1]}min`,
}
}
return { total_duration: computed(() => get_duration(total_duration)) }
},
})
</script>
<style lang="scss">

View File

@ -37,18 +37,15 @@
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
<script setup lang="ts">
import { toRefs } from 'vue'
export default defineComponent({
name: 'Footer',
props: {
version: {
type: String,
required: true,
},
},
})
interface Props {
version: string
}
const props = defineProps<Props>()
const { version } = toRefs(props)
</script>
<style scoped lang="scss">

View File

@ -77,8 +77,8 @@
</div>
</template>
<script lang="ts">
import { ComputedRef, computed, defineComponent, ref, capitalize } from 'vue'
<script setup lang="ts">
import { ComputedRef, computed, ref, capitalize } from 'vue'
import { useI18n } from 'vue-i18n'
import UserPicture from '@/components/User/UserPicture.vue'
@ -86,16 +86,10 @@
import { IDropdownOption } from '@/types/forms'
import { IUserProfile } from '@/types/user'
import { useStore } from '@/use/useStore'
import { getApiUrl } from '@/utils'
import { availableLanguages } from '@/utils/locales'
export default defineComponent({
name: 'NavBar',
components: {
UserPicture,
},
emits: ['menuInteraction'],
setup(props, { emit }) {
const emit = defineEmits(['menuInteraction'])
const { locale } = useI18n()
const store = useStore()
@ -105,13 +99,6 @@
const isAuthenticated: ComputedRef<boolean> = computed(
() => store.getters[AUTH_USER_STORE.GETTERS.IS_AUTHENTICATED]
)
const authUserPictureUrl: ComputedRef<string> = computed(() =>
isAuthenticated.value && authUser.value.picture
? `${getApiUrl()}/users/${
authUser.value.username
}/picture?${Date.now()}`
: ''
)
const language: ComputedRef<string> = computed(
() => store.getters[ROOT_STORE.GETTERS.LANGUAGE]
)
@ -132,22 +119,6 @@
function logout() {
store.dispatch(AUTH_USER_STORE.ACTIONS.LOGOUT)
}
return {
availableLanguages,
authUser,
authUserPictureUrl,
isAuthenticated,
isMenuOpen,
language,
capitalize,
openMenu,
closeMenu,
updateLanguage,
logout,
}
},
})
</script>
<style scoped lang="scss">

View File

@ -28,19 +28,6 @@
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
import { useI18n } from 'vue-i18n'
export default defineComponent({
name: 'NoConfig',
setup() {
const { t } = useI18n()
return { t }
},
})
</script>
<style scoped lang="scss">
@import '~@/scss/base';

View File

@ -37,13 +37,11 @@
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue'
<script setup lang="ts">
import { ref } from 'vue'
const emit = defineEmits(['arrowClick', 'timeFrameUpdate'])
export default defineComponent({
name: 'StatsMenu',
emits: ['arrowClick', 'timeFrameUpdate'],
setup(props, { emit }) {
let selectedTimeFrame = ref('month')
const timeFrames = ['week', 'month', 'year']
@ -51,15 +49,6 @@
selectedTimeFrame.value = timeFrame
emit('timeFrameUpdate', timeFrame)
}
return {
selectedTimeFrame,
timeFrames,
onUpdateTimeFrame,
emit,
}
},
})
</script>
<style lang="scss" scoped>

View File

@ -19,28 +19,27 @@
</div>
</template>
<script lang="ts">
import { ComputedRef, PropType, computed, defineComponent, inject } from 'vue'
<script setup lang="ts">
import { ComputedRef, computed, inject, withDefaults, toRefs } from 'vue'
import { useI18n } from 'vue-i18n'
import { ISport, ITranslatedSport } from '@/types/sports'
import { translateSports } from '@/utils/sports'
export default defineComponent({
name: 'SportsMenu',
props: {
selectedSportIds: {
type: Array as PropType<number[]>,
default: () => [],
},
userSports: {
type: Object as PropType<ISport[]>,
required: true,
},
},
emits: ['selectedSportIdsUpdate'],
setup(props, { emit }) {
interface Props {
userSports: ISport[]
selectedSportIds?: number[]
}
const props = withDefaults(defineProps<Props>(), {
selectedSportIds: () => [],
})
const emit = defineEmits(['selectedSportIdsUpdate'])
const { t } = useI18n()
const sportColors = inject('sportColors')
const { selectedSportIds } = toRefs(props)
const translatedSports: ComputedRef<ITranslatedSport[]> = computed(() =>
translateSports(props.userSports, t)
)
@ -48,14 +47,6 @@
function updateSelectedSportIds(sportId: number) {
emit('selectedSportIdsUpdate', sportId)
}
return {
sportColors: inject('sportColors'),
translatedSports,
updateSelectedSportIds,
}
},
})
</script>
<style lang="scss">

View File

@ -19,16 +19,8 @@
</div>
</template>
<script lang="ts">
import {
ComputedRef,
PropType,
Ref,
computed,
defineComponent,
ref,
watch,
} from 'vue'
<script setup lang="ts">
import { ComputedRef, Ref, computed, ref, toRefs, watch } from 'vue'
import { useI18n } from 'vue-i18n'
import StatChart from '@/components/Common/StatsChart/index.vue'
@ -40,27 +32,16 @@
import { translateSports } from '@/utils/sports'
import { getStatsDateParams, updateChartParams } from '@/utils/statistics'
export default defineComponent({
name: 'Statistics',
components: {
SportsMenu,
StatChart,
StatsMenu,
},
props: {
sports: {
type: Object as PropType<ISport[]>,
required: true,
},
user: {
type: Object as PropType<IUserProfile>,
required: true,
},
},
setup(props) {
interface Props {
sports: ISport[]
user: IUserProfile
}
const props = defineProps<Props>()
const { t } = useI18n()
const { sports, user } = toRefs(props)
let selectedTimeFrame = ref('month')
const timeFrames = ['week', 'month', 'year']
const chartParams: Ref<IStatisticsDateParams> = ref(
getChartParams(selectedTimeFrame.value)
)
@ -102,19 +83,6 @@
selectedSportIds.value = getSports(newSports)
}
)
return {
chartParams,
selectedTimeFrame,
timeFrames,
translatedSports,
selectedSportIds,
handleOnClickArrows,
updateSelectedSportIds,
updateTimeFrame,
}
},
})
</script>
<style lang="scss" scoped>

View File

@ -15,25 +15,18 @@
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
<script setup lang="ts">
import { toRefs } from 'vue'
import EmailSent from '@/components/Common/Images/EmailSent.vue'
import Password from '@/components/Common/Images/Password.vue'
export default defineComponent({
name: 'PasswordActionDone',
components: {
EmailSent,
Password,
},
props: {
action: {
type: String,
required: true,
},
},
})
interface Props {
action: string
}
const props = defineProps<Props>()
const { action } = toRefs(props)
</script>
<style scoped lang="scss">

View File

@ -9,27 +9,20 @@
</div>
</template>
<script lang="ts">
import { defineComponent } from 'vue'
<script setup lang="ts">
import { toRefs, withDefaults } from 'vue'
import UserAuthForm from '@/components/User/UserAuthForm.vue'
export default defineComponent({
name: 'PasswordResetForm',
components: {
UserAuthForm,
},
props: {
action: {
type: String,
required: true,
},
token: {
type: String,
default: '',
},
},
interface Props {
action: string
token?: string
}
const props = withDefaults(defineProps<Props>(), {
token: '',
})
const { action, token } = toRefs(props)
</script>
<style scoped lang="scss">

View File

@ -27,24 +27,18 @@
</div>
</template>
<script lang="ts">
import { PropType, defineComponent } from 'vue'
<script setup lang="ts">
import { toRefs } from 'vue'
import UserPicture from '@/components/User/UserPicture.vue'
import { IUserProfile } from '@/types/user'
export default defineComponent({
name: 'ProfileDisplay',
components: {
UserPicture,
},
props: {
user: {
type: Object as PropType<IUserProfile>,
required: true,
},
},
})
interface Props {
user: IUserProfile
}
const props = defineProps<Props>()
const { user } = toRefs(props)
</script>
<style lang="scss" scoped>

View File

@ -43,35 +43,25 @@
</div>
</template>
<script lang="ts">
<script setup lang="ts">
import { format } from 'date-fns'
import {
ComputedRef,
PropType,
Ref,
computed,
defineComponent,
ref,
} from 'vue'
import { ComputedRef, Ref, computed, ref, toRefs, withDefaults } from 'vue'
import { AUTH_USER_STORE } from '@/store/constants'
import { IUserProfile } from '@/types/user'
import { useStore } from '@/use/useStore'
export default defineComponent({
name: 'UserInfos',
props: {
user: {
type: Object as PropType<IUserProfile>,
required: true,
},
fromAdmin: {
type: Boolean,
default: false,
},
},
setup(props) {
interface Props {
user: IUserProfile
fromAdmin?: boolean
}
const props = withDefaults(defineProps<Props>(), {
fromAdmin: false,
})
const store = useStore()
const { user, fromAdmin } = toRefs(props)
const authUser: ComputedRef<IUserProfile> = computed(
() => store.getters[AUTH_USER_STORE.GETTERS.AUTH_USER_PROFILE]
)
@ -93,17 +83,6 @@
function deleteUserAccount(username: string) {
store.dispatch(AUTH_USER_STORE.ACTIONS.DELETE_ACCOUNT, { username })
}
return {
authUser,
birthDate,
displayModal,
registrationDate,
deleteUserAccount,
updateDisplayModal,
}
},
})
</script>
<style lang="scss" scoped>

View File

@ -17,35 +17,26 @@
</div>
</template>
<script lang="ts">
import { PropType, computed, defineComponent } from 'vue'
<script setup lang="ts">
import { computed } from 'vue'
import { IUserProfile } from '@/types/user'
import { languageLabels } from '@/utils/locales'
export default defineComponent({
name: 'UserPreferences',
props: {
user: {
type: Object as PropType<IUserProfile>,
required: true,
},
},
setup(props) {
interface Props {
user: IUserProfile
}
const props = defineProps<Props>()
const language = computed(() =>
props.user.language
? languageLabels[props.user.language]
: languageLabels['en']
)
const fistDayOfWeek = computed(() =>
props.user.weekm ? 'MONDAY' : 'SUNDAY'
)
const fistDayOfWeek = computed(() => (props.user.weekm ? 'MONDAY' : 'SUNDAY'))
const timezone = computed(() =>
props.user.timezone ? props.user.timezone : 'Europe/Paris'
)
return { fistDayOfWeek, language, timezone }
},
})
</script>
<style lang="scss" scoped>

View File

@ -8,35 +8,21 @@
</div>
</template>
<script lang="ts">
import { PropType, defineComponent } from 'vue'
<script setup lang="ts">
import { toRefs } from 'vue'
import UserHeader from '@/components/User/ProfileDisplay/UserHeader.vue'
import UserProfileTabs from '@/components/User/UserProfileTabs.vue'
import { IUserProfile } from '@/types/user'
export default defineComponent({
name: 'ProfileDisplay',
components: {
UserHeader,
UserProfileTabs,
},
props: {
user: {
type: Object as PropType<IUserProfile>,
required: true,
},
tab: {
type: String,
required: true,
},
},
setup() {
return {
tabs: ['PROFILE', 'PREFERENCES'],
interface Props {
user: IUserProfile
tab: string
}
},
})
const props = defineProps<Props>()
const { user, tab } = toRefs(props)
const tabs = ['PROFILE', 'PREFERENCES']
</script>
<style lang="scss" scoped>

View File

@ -27,25 +27,22 @@
</div>
</template>
<script lang="ts">
import { Ref, defineComponent, ref, watch } from 'vue'
<script setup lang="ts">
import { Ref, ref, toRefs, watch, withDefaults } from 'vue'
import { timeZones } from '@/utils/timezone'
export default defineComponent({
name: 'TimezoneDropdown',
props: {
disabled: {
type: Boolean,
default: false,
},
input: {
type: String,
required: true,
},
},
emits: ['updateTimezone'],
setup(props, { emit }) {
interface Props {
input: string
disabled?: boolean
}
const props = withDefaults(defineProps<Props>(), {
disabled: false,
})
const emit = defineEmits(['updateTimezone'])
const { input, disabled } = toRefs(props)
const timezone: Ref<string> = ref(props.input)
const isOpen: Ref<boolean> = ref(false)
const tzList: Ref<HTMLInputElement | null> = ref(null)
@ -80,21 +77,6 @@
timezone.value = value
}
)
return {
focusItemIndex,
isOpen,
timezone,
timeZones,
tzList,
matchTimezone,
onEnter,
onMouseOver,
onUpdateTimezone,
openDropdown,
}
},
})
</script>
<style lang="scss" scoped>

View File

@ -93,16 +93,15 @@
</div>
</template>
<script lang="ts">
<script setup lang="ts">
import { format } from 'date-fns'
import {
ComputedRef,
PropType,
Ref,
computed,
defineComponent,
reactive,
ref,
toRefs,
onMounted,
} from 'vue'
@ -110,16 +109,14 @@
import { IUserProfile, IUserPayload } from '@/types/user'
import { useStore } from '@/use/useStore'
export default defineComponent({
name: 'UserInfosEdition',
props: {
user: {
type: Object as PropType<IUserProfile>,
required: true,
},
},
setup(props) {
interface Props {
user: IUserProfile
}
const props = defineProps<Props>()
const store = useStore()
const { user } = toRefs(props)
const userForm: IUserPayload = reactive({
password: '',
password_conf: '',
@ -169,20 +166,6 @@
function deleteAccount(username: string) {
store.dispatch(AUTH_USER_STORE.ACTIONS.DELETE_ACCOUNT, { username })
}
return {
displayModal,
errorMessages,
loading,
registrationDate,
userForm,
deleteAccount,
updateBio,
updateDisplayModal,
updateProfile,
}
},
})
</script>
<style lang="scss">

View File

@ -32,15 +32,8 @@
</div>
</template>
<script lang="ts">
import {
ComputedRef,
PropType,
Ref,
defineComponent,
computed,
ref,
} from 'vue'
<script setup lang="ts">
import { ComputedRef, Ref, computed, ref, toRefs } from 'vue'
import UserPicture from '@/components/User/UserPicture.vue'
import { AUTH_USER_STORE, ROOT_STORE } from '@/store/constants'
@ -49,19 +42,14 @@
import { useStore } from '@/use/useStore'
import { getReadableFileSize } from '@/utils/files'
export default defineComponent({
name: 'UserPictureEdition',
components: {
UserPicture,
},
props: {
user: {
type: Object as PropType<IUserProfile>,
required: true,
},
},
setup() {
interface Props {
user: IUserProfile
}
const props = defineProps<Props>()
const store = useStore()
const { user } = toRefs(props)
const errorMessages: ComputedRef<string | string[] | null> = computed(
() => store.getters[ROOT_STORE.GETTERS.ERROR_MESSAGES]
)
@ -88,17 +76,6 @@
})
}
}
return {
errorMessages,
fileSizeLimit,
pictureFile,
deleteUserPicture,
updateUserPicture,
updatePictureFile,
}
},
})
</script>
<style lang="scss" scoped>

View File

@ -51,15 +51,8 @@
</div>
</template>
<script lang="ts">
import {
ComputedRef,
PropType,
computed,
defineComponent,
reactive,
onMounted,
} from 'vue'
<script setup lang="ts">
import { ComputedRef, computed, reactive, onMounted } from 'vue'
import TimezoneDropdown from '@/components/User/ProfileEdition/TimezoneDropdown.vue'
import { AUTH_USER_STORE, ROOT_STORE } from '@/store/constants'
@ -67,19 +60,13 @@
import { useStore } from '@/use/useStore'
import { availableLanguages } from '@/utils/locales'
export default defineComponent({
name: 'UserPreferencesEdition',
components: {
TimezoneDropdown,
},
props: {
user: {
type: Object as PropType<IUserProfile>,
required: true,
},
},
setup(props) {
interface Props {
user: IUserProfile
}
const props = defineProps<Props>()
const store = useStore()
const userForm: IUserPreferencesPayload = reactive({
language: '',
timezone: 'Europe/Paris',
@ -114,24 +101,9 @@
userForm.weekm = user.weekm ? user.weekm : false
}
function updateProfile() {
store.dispatch(
AUTH_USER_STORE.ACTIONS.UPDATE_USER_PREFERENCES,
userForm
)
store.dispatch(AUTH_USER_STORE.ACTIONS.UPDATE_USER_PREFERENCES, userForm)
}
function updateTZ(value: string) {
userForm.timezone = value
}
return {
availableLanguages,
errorMessages,
loading,
userForm,
weekStart,
updateProfile,
updateTZ,
}
},
})
</script>

View File

@ -17,37 +17,25 @@
</div>
</template>
<script lang="ts">
import { computed, defineComponent, PropType } from 'vue'
<script setup lang="ts">
import { computed, toRefs } from 'vue'
import UserProfileTabs from '@/components/User/UserProfileTabs.vue'
import { AUTH_USER_STORE } from '@/store/constants'
import { IUserProfile } from '@/types/user'
import { useStore } from '@/use/useStore'
export default defineComponent({
name: 'ProfileEdition',
components: {
UserProfileTabs,
},
props: {
user: {
type: Object as PropType<IUserProfile>,
required: true,
},
tab: {
type: String,
required: true,
},
},
setup() {
const store = useStore()
return {
loading: computed(
() => store.getters[AUTH_USER_STORE.GETTERS.USER_LOADING]
),
tabs: ['PROFILE', 'PICTURE', 'PREFERENCES'],
interface Props {
user: IUserProfile
tab: string
}
},
})
const props = defineProps<Props>()
const store = useStore()
const { user, tab } = toRefs(props)
const tabs = ['PROFILE', 'PICTURE', 'PREFERENCES']
const loading = computed(
() => store.getters[AUTH_USER_STORE.GETTERS.USER_LOADING]
)
</script>

View File

@ -86,8 +86,15 @@
</div>
</template>
<script lang="ts">
import { ComputedRef, computed, defineComponent, reactive, watch } from 'vue'
<script setup lang="ts">
import {
ComputedRef,
computed,
reactive,
toRefs,
watch,
withDefaults,
} from 'vue'
import { useRoute } from 'vue-router'
import { AUTH_USER_STORE, ROOT_STORE } from '@/store/constants'
@ -95,28 +102,24 @@
import { ILoginRegisterFormData } from '@/types/user'
import { useStore } from '@/use/useStore'
export default defineComponent({
name: 'UserAuthForm',
props: {
action: {
type: String,
required: true,
},
token: {
type: String,
default: '',
},
},
setup(props) {
interface Props {
action: string
token?: string
}
const props = withDefaults(defineProps<Props>(), {
token: '',
})
const route = useRoute()
const store = useStore()
const { action } = toRefs(props)
const formData: ILoginRegisterFormData = reactive({
username: '',
email: '',
password: '',
password_conf: '',
})
const route = useRoute()
const store = useStore()
const buttonText: ComputedRef<string> = computed(() =>
getButtonText(props.action)
)
@ -128,8 +131,7 @@
)
const registration_disabled: ComputedRef<boolean> = computed(
() =>
props.action === 'register' &&
!appConfig.value.is_registration_enabled
props.action === 'register' && !appConfig.value.is_registration_enabled
)
function getButtonText(action: string): string {
@ -176,6 +178,7 @@
formData.password = ''
formData.password_conf = ''
}
watch(
() => route.path,
async () => {
@ -183,16 +186,6 @@
resetFormData()
}
)
return {
appConfig,
buttonText,
errorMessages,
formData,
registration_disabled,
onSubmit,
}
},
})
</script>
<style scoped lang="scss">

View File

@ -12,30 +12,22 @@
</div>
</template>
<script lang="ts">
import { PropType, computed, defineComponent } from 'vue'
<script setup lang="ts">
import { computed } from 'vue'
import { IUserProfile } from '@/types/user'
import { getApiUrl } from '@/utils'
export default defineComponent({
name: 'UserPicture',
props: {
user: {
type: Object as PropType<IUserProfile>,
required: true,
},
},
setup(props) {
return {
authUserPictureUrl: computed(() =>
interface Props {
user: IUserProfile
}
const props = defineProps<Props>()
const authUserPictureUrl = computed(() =>
props.user.picture
? `${getApiUrl()}users/${props.user.username}/picture`
: ''
),
}
},
})
)
</script>
<style lang="scss">

View File

@ -18,30 +18,21 @@
</div>
</template>
<script lang="ts">
import { PropType, defineComponent } from 'vue'
<script setup lang="ts">
import { toRefs, withDefaults } from 'vue'
interface Props {
tabs: string[]
selectedTab: string
edition: boolean
disabled?: boolean
}
const props = withDefaults(defineProps<Props>(), {
disabled: false,
})
const { tabs, selectedTab, disabled } = toRefs(props)
export default defineComponent({
name: 'UserProfileTabs',
props: {
tabs: {
type: Object as PropType<string[]>,
required: true,
},
selectedTab: {
type: String,
required: true,
},
edition: {
type: Boolean,
required: true,
},
disabled: {
type: Boolean,
default: false,
},
},
setup(props) {
function getPath(tab: string) {
switch (tab) {
case 'PICTURE':
@ -53,9 +44,6 @@
return `/profile${props.edition ? '/edit' : ''}`
}
}
return { getPath }
},
})
</script>
<style lang="scss">

View File

@ -17,7 +17,7 @@
</div>
<router-link
class="workout-title"
v-if="workout"
v-if="workout.id"
:to="{
name: 'Workout',
params: { workoutId: workout.id },
@ -27,7 +27,7 @@
</router-link>
<div
class="workout-date"
v-if="workout && user"
v-if="workout.workout_date && user"
:title="
format(
getDateWithTZ(workout.workout_date, user.timezone),
@ -47,7 +47,7 @@
class="workout-map"
:class="{ 'no-cursor': !workout }"
@click="
workout
workout.id
? $router.push({
name: 'Workout',
params: { workoutId: workout.id },
@ -66,11 +66,16 @@
class="workout-data"
:class="{ 'without-gpx': workout && !workout.with_gpx }"
@click="
$router.push({ name: 'Workout', params: { workoutId: workout.id } })
workout.id
? $router.push({
name: 'Workout',
params: { workoutId: workout.id },
})
: null
"
>
<div class="img">
<SportImage v-if="sport" :sport-label="sport.label" />
<SportImage v-if="sport.label" :sport-label="sport.label" />
</div>
<div class="data">
<i class="fa fa-clock-o" aria-hidden="true" />
@ -103,9 +108,9 @@
</div>
</template>
<script lang="ts">
<script setup lang="ts">
import { Locale, format, formatDistance } from 'date-fns'
import { PropType, defineComponent, ComputedRef, computed } from 'vue'
import { ComputedRef, computed, toRefs, withDefaults } from 'vue'
import StaticMap from '@/components/Common/StaticMap.vue'
import UserPicture from '@/components/User/UserPicture.vue'
@ -116,39 +121,22 @@
import { useStore } from '@/use/useStore'
import { getDateWithTZ } from '@/utils/dates'
export default defineComponent({
name: 'WorkoutCard',
components: {
StaticMap,
UserPicture,
},
props: {
workout: {
type: Object as PropType<IWorkout>,
required: false,
},
user: {
type: Object as PropType<IUserProfile>,
required: true,
},
sport: {
type: Object as PropType<ISport>,
required: false,
},
},
setup() {
interface Props {
user: IUserProfile
workout?: IWorkout
sport?: ISport
}
const props = withDefaults(defineProps<Props>(), {
workout: () => ({} as IWorkout),
sport: () => ({} as ISport),
})
const store = useStore()
const { user, workout, sport } = toRefs(props)
const locale: ComputedRef<Locale> = computed(
() => store.getters[ROOT_STORE.GETTERS.LOCALE]
)
return {
format,
formatDistance,
getDateWithTZ,
locale,
}
},
})
</script>
<style lang="scss" scoped>

View File

@ -36,9 +36,9 @@
</div>
</template>
<script lang="ts">
<script setup lang="ts">
import { ChartData, ChartOptions } from 'chart.js'
import { ComputedRef, PropType, computed, defineComponent, ref } from 'vue'
import { ComputedRef, computed, ref } from 'vue'
import { LineChart, useLineChart } from 'vue-chart-3'
import { useI18n } from 'vue-i18n'
@ -50,23 +50,14 @@
} from '@/types/workouts'
import { getDatasets } from '@/utils/workouts'
export default defineComponent({
name: 'WorkoutChart',
components: {
LineChart,
},
props: {
authUser: {
type: Object as PropType<IUserProfile>,
required: true,
},
workoutData: {
type: Object as PropType<IWorkoutData>,
required: true,
},
},
emits: ['getCoordinates'],
setup(props, { emit }) {
interface Props {
authUser: IUserProfile
workoutData: IWorkoutData
}
const props = defineProps<Props>()
const emit = defineEmits(['getCoordinates'])
const { t } = useI18n()
let displayDistance = ref(true)
@ -178,6 +169,10 @@
},
},
}))
const { lineChartProps } = useLineChart({
chartData,
options,
})
function updateDisplayDistance() {
displayDistance.value = !displayDistance.value
@ -191,19 +186,6 @@
function emitEmptyCoordinates() {
emitCoordinates({ latitude: null, longitude: null })
}
const { lineChartProps } = useLineChart({
chartData,
options,
})
return {
displayDistance,
lineChartProps,
emitEmptyCoordinates,
updateDisplayDistance,
}
},
})
</script>
<style lang="scss" scoped>

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