| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- <!--
- Administration de la connexion Opentalent / HelloAsso
- -->
- <template>
- <LayoutContainer>
- <v-card>
- <v-row>
- <v-col cols="12" md="4" class="d-flex justify-center">
- <v-img src="/images/logos/Logo-HelloAsso.svg" class="logo" />
- </v-col>
- <v-col cols="12" md="8" class="presentation">
- {{ $t('helloasso_presentation') }}
- </v-col>
- </v-row>
- <v-row>
- <v-col cols="12" class="d-flex justify-center align-center w-100 mt-6">
- <v-progress-circular
- v-if="
- statusHelloAssoProfile === FETCHING_STATUS.PENDING ||
- unlinkingPending
- "
- indeterminate
- size="32"
- />
- <UiButtonHelloAssoConnect
- v-else-if="!helloAssoProfile || !helloAssoProfile.token"
- @click="onHelloAssoConnectClicked"
- />
- <div v-else class="d-flex flex-column align-center">
- <v-row>
- <v-icon icon="fas fa-check" color="success" class="mr-3" />
- {{ $t('your_helloasso_account_is_linked') }}
- </v-row>
- <v-row>
- <v-btn class="theme-warning mt-4" @click="onUnlinkAccountClick">
- {{ $t('unlink_your_helloasso_account') }}
- </v-btn>
- </v-row>
- </div>
- </v-col>
- </v-row>
- </v-card>
- </LayoutContainer>
- </template>
- <script setup lang="ts">
- import AuthUrl from '~/models/HelloAsso/AuthUrl'
- import HelloAssoProfile from '~/models/HelloAsso/HelloAssoProfile'
- import { useEntityManager } from '~/composables/data/useEntityManager'
- import { useEntityFetch } from '~/composables/data/useEntityFetch'
- import { FETCHING_STATUS } from '~/types/enum/data'
- import UnlinkRequest from '~/models/HelloAsso/UnlinkRequest'
- const { em } = useEntityManager()
- const organizationProfile = useOrganizationProfileStore()
- const onHelloAssoConnectClicked = async () => {
- // Important de régénérer une URL avec un nouveau challenge à chaque
- // essai (entre autres pour supporter le HMR pendant les tests en local,
- // ou en cas d'erreur et de ré-essai)
- const authUrl = await em.fetch(AuthUrl)
- navigateTo(authUrl.authUrl, {
- external: true,
- open: {
- target: '_blank',
- windowFeatures: {
- popup: true,
- width: 900,
- height: 600,
- },
- },
- })
- }
- onMounted(() => {
- window.addEventListener('message', (event) => {
- if (event.origin !== window.location.origin) {
- return
- }
- if (!event.data || !event.data.code) {
- return
- }
- onHelloAssoConnected()
- })
- })
- const { fetch } = useEntityFetch()
- const { status: statusHelloAssoProfile, refresh: refreshHelloAssoProfile } =
- await fetch(HelloAssoProfile)
- const helloAssoProfile: ComputedRef<HelloAssoProfile | null> = computed(() => {
- if (statusHelloAssoProfile.value !== FETCHING_STATUS.SUCCESS) {
- return null
- }
- return em.find(HelloAssoProfile, 1)
- })
- const onHelloAssoConnected = async () => {
- // On attend 200ms pour laisser en attente du message SSE
- await new Promise((r) => setTimeout(r, 200))
- if (!helloAssoProfile.value || !helloAssoProfile.value.token) {
- // Fallback en cas de défaut de fonctionnement du SSE
- console.log('Helloasso connected (fallback SSE)')
- await refreshHelloAssoProfile()
- }
- }
- const unlinkingPending: Ref<boolean> = ref(false)
- const onUnlinkAccountClick = async () => {
- const unlinkRequest = em.newInstance(UnlinkRequest, {
- organizationId: organizationProfile.id,
- })
- unlinkingPending.value = true
- try {
- await em.persist(unlinkRequest)
- await refreshHelloAssoProfile()
- } finally {
- unlinkingPending.value = false
- }
- }
- </script>
- <style scoped lang="scss">
- .v-card {
- padding: 48px;
- max-width: 70%;
- margin: 36px auto;
- @media (max-width: 600px) {
- max-width: 90%;
- }
- }
- .logo {
- max-width: 80%;
- }
- .presentation {
- border-left: 3px solid rgb(var(--v-theme-info));
- padding: 0 24px;
- color: rgb(var(--v-theme-on-neutral));
- }
- .authDialog {
- max-width: 90%;
- }
- </style>
|