Comparatif.vue 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411
  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>* Payable annuellement</span>
  163. </div>
  164. </v-row>
  165. </div>
  166. </LayoutContainer>
  167. </template>
  168. <script setup lang="ts">
  169. import { useDisplay } from 'vuetify'
  170. import type { PropType } from 'vue'
  171. import type { ComparisonItem } from '~/types/interface'
  172. const { mdAndUp } = useDisplay()
  173. const props = defineProps({
  174. standardPrice: {
  175. type: String,
  176. required: true,
  177. },
  178. premiumPrice: {
  179. type: String,
  180. required: true,
  181. },
  182. items: {
  183. type: Array as PropType<Array<ComparisonItem>>,
  184. required: true,
  185. },
  186. showFrom: {
  187. type: Boolean,
  188. required: false,
  189. default: false,
  190. },
  191. })
  192. const height = computed(() => 150 + props.items.length * 48)
  193. const carouselPos = ref(0)
  194. const goToPrevious = () => {
  195. carouselPos.value = 0
  196. }
  197. const goToNext = () => {
  198. carouselPos.value = 1
  199. }
  200. </script>
  201. <style scoped lang="scss">
  202. .v-row {
  203. align-items: center;
  204. display: flex;
  205. flex-direction: row;
  206. justify-content: center;
  207. }
  208. table {
  209. width: 70%;
  210. margin-top: 1rem;
  211. margin-right: auto;
  212. margin-left: auto;
  213. border: none;
  214. border-collapse: collapse;
  215. @media (max-width: 940px) {
  216. width: 100%;
  217. }
  218. }
  219. th {
  220. height: 8rem;
  221. font-weight: 400;
  222. font-size: 30px;
  223. line-height: 34px;
  224. @media (max-width: 600px) {
  225. font-size: 18px;
  226. }
  227. }
  228. tr {
  229. height: 3rem;
  230. text-align: center;
  231. }
  232. tbody tr:nth-child(even) {
  233. background-color: var(--secondary-color);
  234. }
  235. td {
  236. padding-right: 5rem;
  237. @media (max-width: 600px) {
  238. padding-right: 0;
  239. }
  240. }
  241. td:first-child {
  242. text-align: left;
  243. padding-left: 20px;
  244. font-weight: 600;
  245. font-size: 12px;
  246. line-height: 16px;
  247. letter-spacing: 0.18em;
  248. text-transform: uppercase;
  249. color: var(--on-neutral-color-alt);
  250. @media (max-width: 600px) {
  251. padding-left: 5px;
  252. }
  253. }
  254. .standard {
  255. font-weight: 600;
  256. font-size: 12px;
  257. line-height: 16px;
  258. text-align: center;
  259. letter-spacing: 0.18em;
  260. text-transform: uppercase;
  261. padding-right: 5rem;
  262. margin-bottom: 1rem;
  263. }
  264. .from,
  265. .ttc {
  266. font-weight: 300;
  267. font-size: 12px;
  268. line-height: 14px;
  269. text-align: center;
  270. color: var(--on-neutral-color-alt);
  271. padding-right: 5rem;
  272. }
  273. .ttc {
  274. text-transform: uppercase;
  275. }
  276. .price,
  277. .month {
  278. font-size: 30px;
  279. line-height: 34px;
  280. text-align: center;
  281. color: var(--on-neutral-color-alt);
  282. }
  283. .month {
  284. padding-right: 5rem;
  285. @media (max-width: 600px) {
  286. padding-right: 0;
  287. }
  288. }
  289. .v-carousel {
  290. h4 {
  291. text-align: center;
  292. margin: 24px auto 12px auto;
  293. text-transform: uppercase;
  294. letter-spacing: 0.25em;
  295. }
  296. p {
  297. padding-right: 0;
  298. }
  299. .price {
  300. margin-top: 12px;
  301. }
  302. .ttc {
  303. padding-right: 10px;
  304. }
  305. }
  306. .asterisk {
  307. display: flex;
  308. margin: 4px auto 0 auto;
  309. width: 70%;
  310. justify-content: flex-end;
  311. font-style: italic;
  312. }
  313. table tr th:nth-child(3),
  314. table tr td:nth-child(3) {
  315. border-left: 2px solid black;
  316. border-right: 2px solid black;
  317. width: 15rem;
  318. border-radius: 50px;
  319. padding: 1rem;
  320. position: relative;
  321. }
  322. table tr:nth-child(1) th:nth-child(3) {
  323. border-bottom: none !important;
  324. }
  325. .premium-column {
  326. position: relative;
  327. z-index: 10;
  328. border-radius: 0 15px 15px 0;
  329. }
  330. .premium-column p,
  331. .premium-column .month,
  332. .premium-column .price {
  333. border: none !important;
  334. }
  335. thead th:nth-child(3) {
  336. border-top: 2px solid black;
  337. }
  338. tbody tr:last-child td:nth-child(3) {
  339. border-bottom: 2px solid black;
  340. border-radius: 0 0 15px 0;
  341. }
  342. .premium-column p,
  343. .premium-column .month,
  344. .premium-column .price,
  345. .premium-column .ttc
  346. {
  347. margin: 0;
  348. padding: 0;
  349. }
  350. </style>