| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208 |
- <template>
- <v-card>
- <div v-if="loading" class="text-center pa-8">
- <v-progress-circular indeterminate color="primary" />
- <p class="mt-4">Validation en cours...</p>
- </div>
- <div v-else-if="validationSuccess">
- <v-card-title class="text-center">
- <v-icon icon="fas fa-check mr-2" color="success" max-height="48" />
- Félicitations !
- </v-card-title>
- <v-card-text class="text-center">
- <p>Merci d'avoir validé votre demande.</p>
- <p>Votre compte est en cours de création.</p>
- <p>
- Vous recevrez un email dès que votre compte sera prêt à être utilisé.
- </p>
- </v-card-text>
- <v-card-actions class="justify-center">
- <v-btn
- variant="elevated"
- prepend-icon="fas fa-arrow-left"
- color="secondary"
- to="/opentalent-artist"
- >
- {{ smAndUp ? 'Retour à la page Opentalent Artist' : 'Retour' }}
- </v-btn>
- </v-card-actions>
- </div>
- <div v-else class="text-center pa-8">
- <v-card-title class="text-center">
- <v-icon
- icon="fas fa-exclamation-triangle mr-2"
- color="warning"
- max-height="48"
- />
- Erreur de validation
- </v-card-title>
- <v-card-text class="text-center">
- <p class="error-message">
- {{ errorMsg }}
- </p>
- <p class="mt-4">
- Si le problème persiste, n'hésitez pas à nous contacter.
- </p>
- </v-card-text>
- <v-card-actions class="justify-center">
- <v-btn color="primary" to="/nous-contacter">Nous contacter</v-btn>
- </v-card-actions>
- </div>
- </v-card>
- </template>
- <script setup lang="ts">
- import { useRoute } from 'vue-router'
- import { useDisplay } from 'vuetify'
- import { useAp2iRequestService } from '~/composables/data/useAp2iRequestService'
- import { useAp2iErrorHandler } from '~/composables/utils/useAp2iErrorHandler'
- import UrlUtils from '~/services/utils/urlUtils'
- const route = useRoute()
- const { ap2iRequestService } = useAp2iRequestService(false)
- const runtimeConfig = useRuntimeConfig()
- const { processApiError } = useAp2iErrorHandler()
- const { smAndUp } = useDisplay()
- const loading = ref(true)
- const validationSuccess: Ref<boolean | null> = ref(null)
- const errorMsg: Ref<string | null> = ref(null)
- // UUID validation regex
- const uuidRegex =
- /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i
- // Get token from query parameters
- const token = computed(() => {
- const queryToken = route.query.token
- return typeof queryToken === 'string' ? queryToken : ''
- })
- const validate = async () => {
- try {
- // Check if token is present
- if (!token.value) {
- errorMsg.value = "Aucun jeton de validation n'a été fourni."
- return
- }
- // Validate token format (UUID)
- if (!uuidRegex.test(token.value)) {
- errorMsg.value = 'Le format du jeton de validation est invalide.'
- return
- }
- // Make API request to validate token
- await ap2iRequestService.get(
- UrlUtils.join(
- runtimeConfig.public.ap2iBaseUrl,
- '/api/public/shop/validate/',
- token.value
- )
- )
- // If we get here, the validation was successful
- validationSuccess.value = true
- } catch (error) {
- console.error('Error validating token:', error)
- validationSuccess.value = false
- errorMsg.value = processApiError(error)
- }
- }
- onMounted(async () => {
- await validate()
- loading.value = false
- })
- </script>
- <style scoped lang="scss">
- .v-card {
- margin: 4rem 20%;
- padding: 2rem;
- // Responsive breakpoints for small screens
- @media (max-width: 960px) {
- margin: 2rem 10%;
- }
- @media (max-width: 640px) {
- margin: 1rem 5%;
- padding: 1.5rem;
- }
- @media (max-width: 480px) {
- margin: 0.5rem 2%;
- padding: 1rem;
- }
- }
- .v-card-title {
- font-size: 1.8rem;
- font-weight: 700;
- color: var(--primary-color);
- // Responsive font sizes
- @media (max-width: 640px) {
- font-size: 1.5rem;
- }
- @media (max-width: 480px) {
- font-size: 1.3rem;
- }
- }
- .v-card-text {
- font-size: 1.1rem;
- line-height: 1.6;
- // Responsive font sizes
- @media (max-width: 640px) {
- font-size: 1rem;
- }
- @media (max-width: 480px) {
- font-size: 0.95rem;
- }
- p {
- margin-bottom: 1rem;
- }
- }
- // Make buttons responsive on small screens
- .v-card-actions {
- @media (max-width: 640px) {
- .v-btn {
- font-size: 0.9rem;
- padding: 8px 16px;
- // Allow button text to wrap on very small screens
- white-space: normal;
- text-align: center;
- line-height: 1.2;
- }
- }
- @media (max-width: 480px) {
- .v-btn {
- font-size: 0.85rem;
- padding: 6px 12px;
- min-width: auto;
- // Stack button text on multiple lines if needed
- flex-direction: column;
- gap: 4px;
- }
- }
- }
- .error-message {
- color: var(--warning-color);
- font-weight: 500;
- }
- </style>
|