Comparatif.vue 8.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407
  1. <template>
  2. <LayoutContainer>
  3. <div class="premium-container">
  4. <v-row class="center-90">
  5. <table v-if="mdAndUp">
  6. <thead>
  7. <tr>
  8. <th />
  9. <th>
  10. <p class="standard">Standard</p>
  11. <p v-if="showFrom" class="from">À partir de</p>
  12. <p class="price">
  13. {{ standardPrice }} <span class="ttc">ttc</span>
  14. </p>
  15. <p class="month">/mois *</p>
  16. </th>
  17. <th class="premium-column">
  18. <p class="standard">Premium</p>
  19. <p v-if="showFrom" class="from">À partir de</p>
  20. <p class="price">
  21. {{ premiumPrice }} <span class="ttc">ttc</span>
  22. </p>
  23. <p class="month">/mois *</p>
  24. </th>
  25. </tr>
  26. </thead>
  27. <tbody>
  28. <tr v-for="item in items" :key="item.label">
  29. <td class="label-column">
  30. {{ item.label }}
  31. </td>
  32. <td>
  33. <v-icon
  34. v-if="item.includedInStandard === true"
  35. icon="far fa-check-circle"
  36. size="18"
  37. />
  38. <v-icon
  39. v-else-if="item.includedInStandard === false"
  40. icon="far fa-times-circle"
  41. size="18"
  42. color="red"
  43. />
  44. <span v-else>
  45. {{ item.includedInStandard }}
  46. </span>
  47. </td>
  48. <td>
  49. <v-icon
  50. v-if="item.includedInPremium === true"
  51. icon="far fa-check-circle"
  52. size="18"
  53. />
  54. <v-icon
  55. v-else-if="item.includedInPremium === false"
  56. icon="far fa-times-circle"
  57. size="18"
  58. color="red"
  59. />
  60. <span v-else>
  61. {{ item.includedInPremium }}
  62. </span>
  63. </td>
  64. </tr>
  65. </tbody>
  66. </table>
  67. <div v-else>
  68. <div class="d-flex flex-row flex-grow-1 justify-center mt-2">
  69. <v-btn
  70. :disabled="carouselPos === 0"
  71. icon="fas fa-chevron-left"
  72. class="mr-6"
  73. aria-label="Précédent"
  74. @click="goToPrevious"
  75. />
  76. <v-btn
  77. :disabled="carouselPos === 1"
  78. icon="fas fa-chevron-right"
  79. aria-label="Suivant"
  80. @click="goToNext"
  81. />
  82. </div>
  83. <v-carousel
  84. v-model="carouselPos"
  85. :hide-delimiters="true"
  86. :show-arrows="false"
  87. :height="height"
  88. >
  89. <v-carousel-item>
  90. <h4>Standard</h4>
  91. <div>
  92. <p class="from">À partir de</p>
  93. <p class="price">
  94. {{ standardPrice }} <span class="ttc">ttc</span>
  95. <span class="month">/mois</span>
  96. </p>
  97. </div>
  98. <table>
  99. <tbody>
  100. <tr v-for="item in items" :key="item.label">
  101. <td class="label-column">
  102. {{ item.label }}
  103. </td>
  104. <td>
  105. <v-icon
  106. v-if="item.includedInStandard === true"
  107. icon="far fa-check-circle"
  108. size="18"
  109. />
  110. <v-icon
  111. v-else-if="item.includedInStandard === false"
  112. icon="far fa-times-circle"
  113. size="18"
  114. color="red"
  115. />
  116. <span v-else>
  117. {{ item.includedInStandard }}
  118. </span>
  119. </td>
  120. </tr>
  121. </tbody>
  122. </table>
  123. </v-carousel-item>
  124. <v-carousel-item>
  125. <h4>Premium</h4>
  126. <div>
  127. <p class="from">À partir de</p>
  128. <p class="price">
  129. {{ premiumPrice }} <span class="ttc">ttc</span>
  130. <span class="month">/mois</span>
  131. </p>
  132. </div>
  133. <table>
  134. <tbody>
  135. <tr v-for="item in items" :key="item.label">
  136. <td class="label-column">
  137. {{ item.label }}
  138. </td>
  139. <td>
  140. <v-icon
  141. v-if="item.includedInPremium === true"
  142. icon="far fa-check-circle"
  143. size="18"
  144. />
  145. <v-icon
  146. v-else-if="item.includedInPremium === false"
  147. icon="far fa-times-circle"
  148. size="18"
  149. color="red"
  150. />
  151. <span v-else>
  152. {{ item.includedInPremium }}
  153. </span>
  154. </td>
  155. </tr>
  156. </tbody>
  157. </table>
  158. </v-carousel-item>
  159. </v-carousel>
  160. </div>
  161. <div class="asterisk">
  162. <span>
  163. * Tarif public 2025. Abonnement payable annuellement.
  164. </span>
  165. </div>
  166. </v-row>
  167. </div>
  168. </LayoutContainer>
  169. </template>
  170. <script setup lang="ts">
  171. import { useDisplay } from 'vuetify'
  172. import type { PropType } from 'vue'
  173. import type { ComparisonItem } from '~/types/interface'
  174. const { mdAndUp } = useDisplay()
  175. const props = defineProps({
  176. standardPrice: {
  177. type: String,
  178. required: true,
  179. },
  180. premiumPrice: {
  181. type: String,
  182. required: true,
  183. },
  184. items: {
  185. type: Array as PropType<Array<ComparisonItem>>,
  186. required: true,
  187. },
  188. showFrom: {
  189. type: Boolean,
  190. required: false,
  191. default: false,
  192. },
  193. })
  194. const height = computed(() => 150 + props.items.length * 48)
  195. const carouselPos = ref(0)
  196. const goToPrevious = () => {
  197. carouselPos.value = 0
  198. }
  199. const goToNext = () => {
  200. carouselPos.value = 1
  201. }
  202. </script>
  203. <style scoped lang="scss">
  204. .v-row {
  205. align-items: center;
  206. display: flex;
  207. flex-direction: row;
  208. justify-content: center;
  209. }
  210. table {
  211. width: 70%;
  212. margin-top: 1rem;
  213. margin-right: auto;
  214. margin-left: auto;
  215. border: none;
  216. border-collapse: collapse;
  217. @media (max-width: 940px) {
  218. width: 100%;
  219. }
  220. }
  221. th {
  222. height: 8rem;
  223. font-weight: 400;
  224. font-size: 30px;
  225. line-height: 34px;
  226. @media (max-width: 600px) {
  227. font-size: 18px;
  228. }
  229. }
  230. tr {
  231. height: 3rem;
  232. text-align: center;
  233. }
  234. tbody tr:nth-child(even) {
  235. background-color: var(--secondary-color);
  236. }
  237. td {
  238. padding-right: 5rem;
  239. @media (max-width: 600px) {
  240. padding-right: 0;
  241. }
  242. }
  243. td:first-child {
  244. text-align: left;
  245. padding-left: 20px;
  246. font-weight: 600;
  247. font-size: 12px;
  248. line-height: 16px;
  249. letter-spacing: 0.18em;
  250. text-transform: uppercase;
  251. color: var(--on-neutral-color-alt);
  252. @media (max-width: 600px) {
  253. padding-left: 5px;
  254. }
  255. }
  256. .standard {
  257. font-weight: 600;
  258. font-size: 12px;
  259. line-height: 16px;
  260. text-align: center;
  261. letter-spacing: 0.18em;
  262. text-transform: uppercase;
  263. padding-right: 5rem;
  264. margin-bottom: 1rem;
  265. }
  266. .from,
  267. .ttc {
  268. font-weight: 300;
  269. font-size: 12px;
  270. line-height: 14px;
  271. text-align: center;
  272. color: var(--on-neutral-color-alt);
  273. padding-right: 5rem;
  274. }
  275. .ttc {
  276. text-transform: uppercase;
  277. }
  278. .price,
  279. .month {
  280. font-size: 30px;
  281. line-height: 34px;
  282. text-align: center;
  283. color: var(--on-neutral-color-alt);
  284. }
  285. .month {
  286. padding-right: 5rem;
  287. @media (max-width: 600px) {
  288. padding-right: 0;
  289. }
  290. }
  291. .v-carousel {
  292. h4 {
  293. text-align: center;
  294. margin: 24px auto 12px auto;
  295. text-transform: uppercase;
  296. letter-spacing: 0.25em;
  297. }
  298. p {
  299. padding-right: 0;
  300. }
  301. .price {
  302. margin-top: 12px;
  303. }
  304. .ttc {
  305. padding-right: 10px;
  306. }
  307. }
  308. .asterisk {
  309. display: flex;
  310. margin: 4px auto 0 auto;
  311. width: 70%;
  312. justify-content: flex-end;
  313. font-style: italic;
  314. }
  315. table tr th:nth-child(3),
  316. table tr td:nth-child(3) {
  317. border-left: 2px solid black;
  318. border-right: 2px solid black;
  319. width: 15rem;
  320. padding: 1rem;
  321. position: relative;
  322. }
  323. table tr:nth-child(1) th:nth-child(3) {
  324. border-bottom: none !important;
  325. }
  326. .premium-column {
  327. position: relative;
  328. z-index: 10;
  329. border-radius: 0 15px 15px 0;
  330. }
  331. .premium-column p,
  332. .premium-column .month,
  333. .premium-column .price {
  334. border: none !important;
  335. }
  336. thead th:nth-child(3) {
  337. border-top: 2px solid black;
  338. }
  339. tbody tr:last-child td:nth-child(3) {
  340. border-bottom: 2px solid black;
  341. border-radius: 0 0 15px 0;
  342. }
  343. .premium-column p,
  344. .premium-column .month,
  345. .premium-column .price,
  346. .premium-column .ttc {
  347. margin: 0;
  348. padding: 0;
  349. }
  350. </style>