index.vue 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328
  1. <template>
  2. <LayoutNavigation />
  3. <h1 class="title mt-12 mb-12">Toutes les news</h1>
  4. <div v-if="pending">{{ t("pending") }}</div>
  5. <div v-else>
  6. <v-row>
  7. <v-col>
  8. <div class="d-flex align-items-center ml-12 mt-6 mb-6">
  9. <div class="carousel-button">
  10. <i class="fa-solid fa-arrow-left" />
  11. </div>
  12. <nuxt-link to="/actualites" class="ml-2 back-button mt-6">
  13. Retour à l'accueil
  14. </nuxt-link>
  15. </div>
  16. </v-col>
  17. <v-pagination
  18. v-model="page"
  19. :length="Math.ceil(totalItems / itemsPerPage)"
  20. total-visible="9"
  21. @input="updatePage"
  22. rounded="circle"
  23. max="10"
  24. class="pagination mr-10 mt-6"
  25. :prev-icon="page !== 1 ? 'fas fa-arrow-left' : ''"
  26. :next-icon="
  27. page !== Math.ceil(totalItems / itemsPerPage)
  28. ? 'fas fa-arrow-right'
  29. : ''
  30. "
  31. />
  32. </v-row>
  33. <v-row
  34. class="d-flex align-center mr-10"
  35. v-for="(news, index) in news"
  36. :key="index"
  37. >
  38. <v-card class="container-green">
  39. <v-card-item>
  40. <v-container fluid>
  41. <v-row align="center">
  42. <v-col cols="3">
  43. <v-img
  44. :src="getImageUrl(news.attachment)"
  45. alt="poster"
  46. class="image-actu"
  47. height="200"
  48. width="400"
  49. />
  50. </v-col>
  51. <v-col cols="9">
  52. <div class="border">
  53. <NuxtLink
  54. :to="`/actualites/${news.id}`"
  55. class="text-decoration-none"
  56. >
  57. <v-card-title class="card-title">
  58. <!-- Icône étoile pour les actualités 'featured' -->
  59. <!-- Titre de l'actualité -->
  60. {{ news.title }}
  61. <v-icon
  62. size="16"
  63. v-if="news.featured"
  64. class="fas fa-star"
  65. style="color: yellow"
  66. ></v-icon>
  67. </v-card-title>
  68. </NuxtLink>
  69. <v-card-text class="infos">
  70. <div class="flex-container">
  71. <div class="text-container">
  72. <table>
  73. <tr>
  74. <td class="leadtext">
  75. {{ news.leadText }}
  76. </td>
  77. </tr>
  78. </table>
  79. </div>
  80. <div class="button-container">
  81. <v-card-actions class="justify-end">
  82. <NuxtLink
  83. :to="`/actualites/${news.id}`"
  84. class="text-decoration-none"
  85. >
  86. <v-btn class="btn" text>
  87. <v-icon class="fas fa-info mr-2"></v-icon>En
  88. savoir plus
  89. </v-btn>
  90. </NuxtLink>
  91. </v-card-actions>
  92. </div>
  93. </div>
  94. </v-card-text>
  95. <v-col :cols="actionsColumnWidth"> </v-col>
  96. </div>
  97. </v-col>
  98. </v-row>
  99. </v-container>
  100. </v-card-item>
  101. </v-card>
  102. </v-row>
  103. <v-pagination
  104. v-model="page"
  105. :length="Math.ceil(totalItems / itemsPerPage)"
  106. total-visible="9"
  107. @input="updatePage"
  108. rounded="circle"
  109. max="10"
  110. class="pagination mr-10"
  111. :prev-icon="page !== 1 ? 'fas fa-arrow-left' : ''"
  112. :next-icon="
  113. page !== Math.ceil(totalItems / itemsPerPage)
  114. ? 'fas fa-arrow-right'
  115. : ''
  116. "
  117. />
  118. </div>
  119. <LayoutFooterPrefooter />
  120. <LayoutFooter />
  121. </template>
  122. <script setup lang="ts">
  123. import { ref, watch } from "vue";
  124. import { useMaestroRequestService } from "~/composables/useMaestroRequestService";
  125. // Base URL for API requests
  126. const config = useRuntimeConfig();
  127. const baseUrl = `${config.public.apiBaseUrl}/api/news`;
  128. const getImageUrl = (attachment) =>
  129. `${config.public.apiBaseUrl}/uploads/news/${attachment}`;
  130. const { apiRequestService } = useMaestroRequestService();
  131. const currentPage = ref(1);
  132. const totalPages = ref(0);
  133. const page: Ref<number> = ref(1);
  134. const itemsPerPage: Ref<number> = ref(10);
  135. const { t } = useI18n();
  136. const updatePage = (newPage: number) => {
  137. console.log("updatePage", newPage);
  138. page.value = newPage;
  139. };
  140. const query = computed(() => {
  141. const queryParams: {
  142. page: number;
  143. type?: string;
  144. [key: string]: number | string;
  145. } = {
  146. page: page.value,
  147. type: "ENTREPRISE",
  148. };
  149. return queryParams;
  150. });
  151. const totalItems = ref(0);
  152. const {
  153. data: news = [],
  154. pending,
  155. refresh,
  156. } = useLazyAsyncData("files", async () => {
  157. const response = await apiRequestService.get(baseUrl, query.value);
  158. const collection = response["hydra:member"];
  159. const currentDate = new Date();
  160. // Séparer les actualités en fonction de la propriété 'featured'
  161. const featuredNews = collection
  162. .filter((item) => item.featured)
  163. .sort((a, b) => new Date(b.startPublication) - new Date(a.startPublication))
  164. .slice(0, 3); // Prendre les trois dernières actualités 'featured'
  165. const regularNews = collection.filter((item) => {
  166. const startPublicationDate = new Date(item.startPublication);
  167. const endPublicationDate = new Date(item.endPublication);
  168. return (
  169. !item.featured &&
  170. item.type === "ENTREPRISE" &&
  171. endPublicationDate >= currentDate &&
  172. startPublicationDate <= currentDate
  173. );
  174. });
  175. // Combinez les actualités 'featured' et les autres actualités
  176. const combinedNews = [...featuredNews, ...regularNews];
  177. totalItems.value = combinedNews.length;
  178. console.log(combinedNews);
  179. return combinedNews;
  180. });
  181. watch(page, () => {
  182. refresh();
  183. });
  184. </script>
  185. <style scoped>
  186. .v-container {
  187. padding: 0 !important;
  188. }
  189. .v-card-text {
  190. letter-spacing: 0 !important;
  191. padding: 0 !important;
  192. }
  193. .v-card-item {
  194. padding: 0 !important;
  195. }
  196. .title {
  197. color: #d1cdc7;
  198. margin-left: 3rem;
  199. margin-top: 2rem;
  200. font-family: Barlow;
  201. font-size: 4rem;
  202. font-style: normal;
  203. font-weight: 600;
  204. line-height: 42px;
  205. }
  206. .border {
  207. border: 1px solid white !important;
  208. padding: 9px;
  209. border-radius: 20px;
  210. width: 99%;
  211. }
  212. .image-actu {
  213. width: 80%;
  214. margin-left: auto;
  215. margin-right: auto;
  216. }
  217. .btn {
  218. background: var(--Vert-60, #64afb7);
  219. display: flex;
  220. left: 0;
  221. padding: 25px 28px;
  222. align-items: center;
  223. gap: 9px;
  224. color: var(--NEUTRAL---BLANC, #fff);
  225. font-family: Barlow;
  226. font-size: 0.9rem;
  227. border-radius: 5px;
  228. font-style: normal;
  229. font-weight: 700;
  230. line-height: 15px;
  231. letter-spacing: 1.3px;
  232. text-transform: uppercase;
  233. margin-bottom: -1rem;
  234. }
  235. .card-title {
  236. color: #fff;
  237. font-family: Barlow;
  238. font-size: 36px;
  239. font-style: normal;
  240. font-weight: 600;
  241. line-height: 39px;
  242. }
  243. .container-green {
  244. border-radius: 10px;
  245. min-width: 100%;
  246. background: #112528;
  247. margin-bottom: 1rem;
  248. margin-left: 2rem;
  249. margin-right: 2rem;
  250. padding-top: 0.2rem;
  251. padding-bottom: 0.2rem;
  252. height: 60%;
  253. }
  254. .infos {
  255. color: #fff;
  256. }
  257. .pagination {
  258. align-items: center;
  259. margin-top: 16px;
  260. margin-bottom: 16px;
  261. color: #112528;
  262. }
  263. .leadtext {
  264. color: #fff;
  265. font-family: Barlow;
  266. font-size: 22px;
  267. font-style: normal;
  268. font-weight: 500;
  269. line-height: 26px;
  270. margin-left: 1rem;
  271. }
  272. .carousel-button {
  273. display: flex;
  274. justify-content: center;
  275. align-items: center;
  276. width: 60px;
  277. height: 60px;
  278. background-color: transparent;
  279. border: 2px solid #000000;
  280. cursor: pointer;
  281. margin-right: 1rem;
  282. }
  283. .back-button {
  284. text-decoration: none;
  285. color: #000000;
  286. font-family: Barlow;
  287. font-size: 0.9rem;
  288. font-style: normal;
  289. font-weight: 700;
  290. line-height: 15px;
  291. letter-spacing: 1.8px;
  292. text-transform: uppercase;
  293. }
  294. </style>