mirror of
https://github.com/joaovitoriasilva/endurain.git
synced 2026-01-09 15:57:59 -05:00
[aux] added auxiliary scripts [backend] added error logic to error printing [backend] rollbacked changes from Datetime to Timestamp [backend] added body composition sync from Garmin [backend] added additional validations for empty .gpx files [backend] add calculate BMI logic [backend] add BMI calculation in migration [backend] added Timezone logic to Strava activity import [frontend] removed block that prevent deleting Strava or GC activity [frontend] added new generic modal for single number input [frontend] replaced modal that retrieves Strava and GC activities for number of days with new generic modal [frontend] added shoes gear in add gear to walk and hike activities [frontend] minor bug fixes
300 lines
13 KiB
Vue
300 lines
13 KiB
Vue
<template>
|
|
<div class="col">
|
|
<!-- list zone -->
|
|
<ul class="list-group list-group-flush">
|
|
<!-- strava zone -->
|
|
<li class="list-group-item d-flex justify-content-between">
|
|
<div class="d-flex align-items-center">
|
|
<font-awesome-icon class="me-2" :icon="['fab', 'strava']" size="2x" />
|
|
<div class="ms-3">
|
|
<div class="fw-bold">
|
|
{{ $t("settingsIntegrationsZone.stravaIntegrationTitle") }}
|
|
</div>
|
|
{{ $t("settingsIntegrationsZone.stravaIntegrationBody") }}
|
|
</div>
|
|
</div>
|
|
<div class="d-flex align-items-center">
|
|
<!-- connect button -->
|
|
<a href="#" class="btn btn-primary" v-if="authStore.user.is_strava_linked == 0" @click="submitConnectStrava">{{ $t("settingsIntegrationsZone.buttonConnect") }}</a>
|
|
|
|
<!-- retrieve activities and other buttons -->
|
|
<div class="dropdown" v-else>
|
|
<button class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
|
{{ $t("settingsIntegrationsZone.buttonDropdownOptions") }}
|
|
</button>
|
|
<ul class="dropdown-menu">
|
|
<li>
|
|
<!-- retrieve strava activities by days -->
|
|
<a class="dropdown-item" href="#" role="button" data-bs-toggle="modal" data-bs-target="#retrieveStravaActivitiesByDaysModal">{{ $t("settingsIntegrationsZone.modalRetrieveActivitiesByDaysTitle") }}</a>
|
|
</li>
|
|
<li>
|
|
<!-- retrieve gear -->
|
|
<a href="#" class="dropdown-item" @click="submitRetrieveStravaGear">{{ $t("settingsIntegrationsZone.buttonRetrieveGear") }}</a>
|
|
</li>
|
|
<li>
|
|
<!-- unlink Strava -->
|
|
<a href="#" class="dropdown-item" role="button" data-bs-toggle="modal" data-bs-target="#unlinkStravaModal">{{ $t("settingsIntegrationsZone.buttonUnlink") }}</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</li>
|
|
<!-- bulk import zone -->
|
|
<li class="list-group-item d-flex justify-content-between">
|
|
<div class="d-flex align-items-center">
|
|
<font-awesome-icon :icon="['fas', 'file-import']" size="2x" />
|
|
<div class="ms-3">
|
|
<div class="fw-bold">
|
|
{{ $t("settingsIntegrationsZone.bulkImportIntegrationTitle") }}
|
|
</div>
|
|
{{ $t("settingsIntegrationsZone.bulkImportIntegrationBody") }}
|
|
</div>
|
|
</div>
|
|
<div class="d-flex align-items-center">
|
|
<!-- import button -->
|
|
<a href="#" class="btn btn-primary" role="button" @click="submitBulkImport">{{ $t("settingsIntegrationsZone.buttonBulkImport") }}</a>
|
|
</div>
|
|
</li>
|
|
<!-- Garmin Connect zone -->
|
|
<li class="list-group-item d-flex justify-content-between">
|
|
<div class="d-flex align-items-center">
|
|
<!--<font-awesome-icon :icon="['fas', 'file-import']" size="2x" />-->
|
|
<img src="/src/assets/garminconnect/Garmin_Connect_app_1024x1024-02.png" alt="Garmin Connect logo" height="32" />
|
|
<div class="ms-3">
|
|
<div class="fw-bold">
|
|
{{ $t("settingsIntegrationsZone.garminConnectIntegrationTitle") }}
|
|
</div>
|
|
{{ $t("settingsIntegrationsZone.garminConnectIntegrationBody") }}
|
|
</div>
|
|
</div>
|
|
<div class="d-flex align-items-center">
|
|
<!-- connect button -->
|
|
<a href="#" class="btn btn-primary" v-if="authStore.user.is_garminconnect_linked == 0" data-bs-toggle="modal" data-bs-target="#garminConnectAuthModal">{{ $t("settingsIntegrationsZone.buttonConnect") }}</a>
|
|
|
|
<!-- retrieve activities and other buttons -->
|
|
<div class="dropdown" v-else>
|
|
<button class="btn btn-secondary dropdown-toggle" type="button" data-bs-toggle="dropdown" aria-expanded="false">
|
|
{{ $t("settingsIntegrationsZone.buttonDropdownOptions") }}
|
|
</button>
|
|
<ul class="dropdown-menu">
|
|
<li>
|
|
<!-- retrieve garmin connect activities by days -->
|
|
<a class="dropdown-item" href="#" role="button" data-bs-toggle="modal" data-bs-target="#retrieveGarminConnectActivitiesByDaysModal">{{ $t("settingsIntegrationsZone.modalRetrieveActivitiesByDaysTitle") }}</a>
|
|
</li>
|
|
<li>
|
|
<!-- retrieve gear -->
|
|
<a href="#" class="dropdown-item" @click="submitRetrieveGarminConnectGear">{{ $t("settingsIntegrationsZone.buttonRetrieveGear") }}</a>
|
|
</li>
|
|
<li>
|
|
<!-- unlink Garmin Connect -->
|
|
<a href="#" class="dropdown-item" role="button" data-bs-toggle="modal" data-bs-target="#unlinkGarminConnectModal">{{ $t("settingsIntegrationsZone.buttonUnlink") }}</a>
|
|
</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
</li>
|
|
</ul>
|
|
|
|
<!-- modal retrieve Strava activities by days -->
|
|
<ModalComponentNumberInput modalId="retrieveStravaActivitiesByDaysModal" :title="t('settingsIntegrationsZone.modalRetrieveActivitiesByDaysTitle')" :numberFieldLabel="`${t('settingsIntegrationsZone.modalRetrieveActivitiesByDaysLabel')}`" :actionButtonType="`success`" :actionButtonText="t('settingsIntegrationsZone.modalRetrieveButton')" @numberToEmitAction="submitRetrieveStravaActivities"/>
|
|
|
|
<!-- modal unlink Strava -->
|
|
<ModalComponent modalId="unlinkStravaModal" :title="t('settingsIntegrationsZone.modalUnlinkStravaTitle')" :body="`${t('settingsIntegrationsZone.modalUnlinkStravaBody')}`" :actionButtonType="`danger`" :actionButtonText="t('settingsIntegrationsZone.modalUnlinkStravaTitle')" @submitAction="buttonStravaUnlink"/>
|
|
|
|
<!-- modal garmin connect auth -->
|
|
<GarminConnectLoginModalComponent />
|
|
|
|
<!-- modal retrieve Garmin Connect activities by days -->
|
|
<ModalComponentNumberInput modalId="retrieveGarminConnectActivitiesByDaysModal" :title="t('settingsIntegrationsZone.modalRetrieveActivitiesByDaysTitle')" :numberFieldLabel="`${t('settingsIntegrationsZone.modalRetrieveActivitiesByDaysLabel')}`" :actionButtonType="`success`" :actionButtonText="t('settingsIntegrationsZone.modalRetrieveButton')" @numberToEmitAction="submitRetrieveGarminConnectActivities"/>
|
|
|
|
<!-- modal unlink Garmin Connect -->
|
|
<ModalComponent modalId="unlinkGarminConnectModal" :title="t('settingsIntegrationsZone.modalUnlinkGarminConnectTitle')" :body="`${t('settingsIntegrationsZone.modalUnlinkGarminConnectBody')}`" :actionButtonType="`danger`" :actionButtonText="t('settingsIntegrationsZone.modalUnlinkGarminConnectTitle')" @submitAction="buttonGarminConnectUnlink"/>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import { ref } from "vue";
|
|
import { useI18n } from "vue-i18n";
|
|
// Import Notivue push
|
|
import { push } from "notivue";
|
|
// Importing the stores
|
|
import { useAuthStore } from "@/stores/authStore";
|
|
// Importing the services
|
|
import { strava } from "@/services/stravaService";
|
|
import { activities } from "@/services/activitiesService";
|
|
import { garminConnect } from "@/services/garminConnectService";
|
|
// Import the components
|
|
import ModalComponent from "@/components/Modals/ModalComponent.vue";
|
|
import ModalComponentNumberInput from "@/components/Modals/ModalComponentNumberInput.vue";
|
|
import GarminConnectLoginModalComponent from "./SettingsIntegrations/GarminConnectLoginModalComponent.vue";
|
|
|
|
//import Modal from 'bootstrap/js/dist/modal';
|
|
|
|
export default {
|
|
components: {
|
|
ModalComponent,
|
|
ModalComponentNumberInput,
|
|
GarminConnectLoginModalComponent,
|
|
},
|
|
setup() {
|
|
const authStore = useAuthStore();
|
|
const { locale, t } = useI18n();
|
|
|
|
async function submitConnectStrava() {
|
|
const array = new Uint8Array(16);
|
|
window.crypto.getRandomValues(array);
|
|
const state = Array.from(array, (byte) =>
|
|
byte.toString(16).padStart(2, "0"),
|
|
).join("");
|
|
|
|
try {
|
|
await strava.setUniqueUserStateStravaLink(state);
|
|
|
|
strava.linkStrava(state);
|
|
} catch (error) {
|
|
// If there is an error, show the error alert.
|
|
push.error(
|
|
`${t("settingsIntegrationsZone.errorMessageUnableToLinkStrava")} - ${error}`,
|
|
);
|
|
}
|
|
}
|
|
|
|
async function submitRetrieveStravaActivities(daysToRetrieveStrava) {
|
|
try {
|
|
await strava.getStravaActivitiesLastDays(daysToRetrieveStrava);
|
|
|
|
// Show the loading alert.
|
|
push.info(
|
|
t(
|
|
"settingsIntegrationsZone.loadingMessageRetrievingStravaActivities",
|
|
),
|
|
);
|
|
} catch (error) {
|
|
// If there is an error, show the error alert.
|
|
push.error(
|
|
`${t("settingsIntegrationsZone.errorMessageUnableToGetStravaActivities")} - ${error}`,
|
|
);
|
|
}
|
|
}
|
|
|
|
async function submitRetrieveStravaGear() {
|
|
try {
|
|
await strava.getStravaGear();
|
|
|
|
// Show the loading alert.
|
|
push.success(
|
|
t("settingsIntegrationsZone.loadingMessageRetrievingStravaGear"),
|
|
);
|
|
} catch (error) {
|
|
// If there is an error, show the error alert.
|
|
push.error(
|
|
`${t("settingsIntegrationsZone.errorMessageUnableToGetStravaGear")} - ${error}`,
|
|
);
|
|
}
|
|
}
|
|
|
|
async function buttonStravaUnlink() {
|
|
// Set the loading message
|
|
const notification = push.promise(t('settingsIntegrationsZone.processingMessageUnlinkStrava'));
|
|
try {
|
|
await strava.unlinkStrava();
|
|
|
|
// Set the user object with the is_strava_linked property set to 0.
|
|
const user = authStore.user;
|
|
user.is_strava_linked = 0;
|
|
authStore.setUser(user, locale);
|
|
|
|
// Show the success alert.
|
|
notification.resolve(t("settingsIntegrationsZone.successMessageStravaUnlinked"));
|
|
} catch (error) {
|
|
// If there is an error, show the error alert.
|
|
notification.reject(
|
|
`${t("settingsIntegrationsZone.errorMessageUnableToUnlinkStrava")} - ${error}`,
|
|
);
|
|
}
|
|
}
|
|
|
|
async function submitBulkImport() {
|
|
try {
|
|
await activities.bulkImportActivities();
|
|
|
|
// Show the loading alert.
|
|
push.info(t("settingsIntegrationsZone.loadingMessageBulkImport"));
|
|
} catch (error) {
|
|
// If there is an error, show the error alert.
|
|
push.error(
|
|
`${t("settingsIntegrationsZone.errorMessageUnableToImportActivities")} - ${error}`,
|
|
);
|
|
}
|
|
}
|
|
|
|
async function submitRetrieveGarminConnectActivities(daysToRetrieveGarmin) {
|
|
try {
|
|
await garminConnect.getGarminConnectActivitiesLastDays(daysToRetrieveGarmin);
|
|
|
|
// Show the loading alert.
|
|
push.info(
|
|
t(
|
|
"settingsIntegrationsZone.loadingMessageRetrievingGarminConnectActivities",
|
|
),
|
|
);
|
|
} catch (error) {
|
|
// If there is an error, show the error alert.
|
|
push.error(
|
|
`${t("settingsIntegrationsZone.errorMessageUnableToGetGarminConnectActivities")} - ${error}`,
|
|
);
|
|
}
|
|
}
|
|
|
|
async function submitRetrieveGarminConnectGear() {
|
|
try {
|
|
await garminConnect.getGarminConnectGear();
|
|
|
|
// Show the loading alert.
|
|
push.success(
|
|
t("settingsIntegrationsZone.loadingMessageRetrievingGarminConnectGear"),
|
|
);
|
|
} catch (error) {
|
|
// If there is an error, show the error alert.
|
|
push.error(
|
|
`${t("settingsIntegrationsZone.errorMessageUnableToGetGarminConnectGear")} - ${error}`,
|
|
);
|
|
}
|
|
}
|
|
|
|
async function buttonGarminConnectUnlink() {
|
|
// Set the loading message
|
|
const notification = push.promise(t('settingsIntegrationsZone.processingMessageUnlinkGarminConnect'));
|
|
try {
|
|
await garminConnect.unlinkGarminConnect();
|
|
|
|
// Set the user object with the is_garminconnect_linked property set to 0.
|
|
const user = authStore.user;
|
|
user.is_garminconnect_linked = 0;
|
|
authStore.setUser(user, locale);
|
|
|
|
// Show the success alert.
|
|
notification.resolve(t("settingsIntegrationsZone.successMessageGarminConnectUnlinked"));
|
|
} catch (error) {
|
|
// If there is an error, show the error alert.
|
|
notification.reject(
|
|
`${t("settingsIntegrationsZone.errorMessageUnableToUnlinkGarminConnect")} - ${error}`,
|
|
);
|
|
}
|
|
}
|
|
|
|
return {
|
|
authStore,
|
|
t,
|
|
submitConnectStrava,
|
|
submitRetrieveStravaActivities,
|
|
submitRetrieveStravaGear,
|
|
buttonStravaUnlink,
|
|
submitBulkImport,
|
|
submitRetrieveGarminConnectActivities,
|
|
submitRetrieveGarminConnectGear,
|
|
buttonGarminConnectUnlink,
|
|
};
|
|
},
|
|
};
|
|
</script> |