validation.vue 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. <template>
  2. <v-card>
  3. <div v-if="loading" class="text-center pa-8">
  4. <v-progress-circular indeterminate color="primary" />
  5. <p class="mt-4">Validation en cours...</p>
  6. </div>
  7. <div v-else-if="validationSuccess">
  8. <v-card-title class="text-center">
  9. <v-icon icon="fas fa-check mr-2" color="success" max-height="48" />
  10. Félicitations !
  11. </v-card-title>
  12. <v-card-text class="text-center">
  13. <p>Merci d'avoir validé votre demande.</p>
  14. <p>Votre compte est en cours de création.</p>
  15. <p>
  16. Vous recevrez un email dès que votre compte sera prêt à être utilisé.
  17. </p>
  18. </v-card-text>
  19. <v-card-actions class="justify-center">
  20. <v-btn
  21. variant="elevated"
  22. prepend-icon="fas fa-arrow-left"
  23. color="secondary"
  24. to="/opentalent-artist"
  25. >
  26. {{ smAndUp ? 'Retour à la page Opentalent Artist' : 'Retour' }}
  27. </v-btn>
  28. </v-card-actions>
  29. </div>
  30. <div v-else class="text-center pa-8">
  31. <v-card-title class="text-center">
  32. <v-icon
  33. icon="fas fa-exclamation-triangle mr-2"
  34. color="warning"
  35. max-height="48"
  36. />
  37. Erreur de validation
  38. </v-card-title>
  39. <v-card-text class="text-center">
  40. <p class="error-message">
  41. {{ errorMsg }}
  42. </p>
  43. <p class="mt-4">
  44. Si le problème persiste, n'hésitez pas à nous contacter.
  45. </p>
  46. </v-card-text>
  47. <v-card-actions class="justify-center">
  48. <v-btn color="primary" to="/nous-contacter">Nous contacter</v-btn>
  49. </v-card-actions>
  50. </div>
  51. </v-card>
  52. </template>
  53. <script setup lang="ts">
  54. import { useRoute } from 'vue-router'
  55. import { useDisplay } from 'vuetify'
  56. import { useAp2iRequestService } from '~/composables/data/useAp2iRequestService'
  57. import { useAp2iErrorHandler } from '~/composables/utils/useAp2iErrorHandler'
  58. import UrlUtils from '~/services/utils/urlUtils'
  59. const route = useRoute()
  60. const { ap2iRequestService } = useAp2iRequestService(false)
  61. const runtimeConfig = useRuntimeConfig()
  62. const { processApiError } = useAp2iErrorHandler()
  63. const { smAndUp } = useDisplay()
  64. const loading = ref(true)
  65. const validationSuccess: Ref<boolean | null> = ref(null)
  66. const errorMsg: Ref<string | null> = ref(null)
  67. // UUID validation regex
  68. const uuidRegex =
  69. /^[0-9a-f]{8}-[0-9a-f]{4}-4[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i
  70. // Get token from query parameters
  71. const token = computed(() => {
  72. const queryToken = route.query.token
  73. return typeof queryToken === 'string' ? queryToken : ''
  74. })
  75. const validate = async () => {
  76. try {
  77. // Check if token is present
  78. if (!token.value) {
  79. errorMsg.value = "Aucun jeton de validation n'a été fourni."
  80. return
  81. }
  82. // Validate token format (UUID)
  83. if (!uuidRegex.test(token.value)) {
  84. errorMsg.value = 'Le format du jeton de validation est invalide.'
  85. return
  86. }
  87. // Make API request to validate token
  88. await ap2iRequestService.get(
  89. UrlUtils.join(
  90. runtimeConfig.public.ap2iBaseUrl,
  91. '/api/public/shop/validate/',
  92. token.value
  93. )
  94. )
  95. // If we get here, the validation was successful
  96. validationSuccess.value = true
  97. } catch (error) {
  98. console.error('Error validating token:', error)
  99. validationSuccess.value = false
  100. errorMsg.value = processApiError(error)
  101. }
  102. }
  103. onMounted(async () => {
  104. await validate()
  105. loading.value = false
  106. })
  107. </script>
  108. <style scoped lang="scss">
  109. .v-card {
  110. margin: 4rem 20%;
  111. padding: 2rem;
  112. // Responsive breakpoints for small screens
  113. @media (max-width: 960px) {
  114. margin: 2rem 10%;
  115. }
  116. @media (max-width: 640px) {
  117. margin: 1rem 5%;
  118. padding: 1.5rem;
  119. }
  120. @media (max-width: 480px) {
  121. margin: 0.5rem 2%;
  122. padding: 1rem;
  123. }
  124. }
  125. .v-card-title {
  126. font-size: 1.8rem;
  127. font-weight: 700;
  128. color: var(--primary-color);
  129. // Responsive font sizes
  130. @media (max-width: 640px) {
  131. font-size: 1.5rem;
  132. }
  133. @media (max-width: 480px) {
  134. font-size: 1.3rem;
  135. }
  136. }
  137. .v-card-text {
  138. font-size: 1.1rem;
  139. line-height: 1.6;
  140. // Responsive font sizes
  141. @media (max-width: 640px) {
  142. font-size: 1rem;
  143. }
  144. @media (max-width: 480px) {
  145. font-size: 0.95rem;
  146. }
  147. p {
  148. margin-bottom: 1rem;
  149. }
  150. }
  151. // Make buttons responsive on small screens
  152. .v-card-actions {
  153. @media (max-width: 640px) {
  154. .v-btn {
  155. font-size: 0.9rem;
  156. padding: 8px 16px;
  157. // Allow button text to wrap on very small screens
  158. white-space: normal;
  159. text-align: center;
  160. line-height: 1.2;
  161. }
  162. }
  163. @media (max-width: 480px) {
  164. .v-btn {
  165. font-size: 0.85rem;
  166. padding: 6px 12px;
  167. min-width: auto;
  168. // Stack button text on multiple lines if needed
  169. flex-direction: column;
  170. gap: 4px;
  171. }
  172. }
  173. }
  174. .error-message {
  175. color: var(--warning-color);
  176. font-weight: 500;
  177. }
  178. </style>