_id.vue 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. <template>
  2. <LayoutContainer>
  3. <header class="mb-4">
  4. <v-layout>
  5. <v-btn
  6. :to="{path: '/structures', query: { parent: parent, view: view, theme: theme }}"
  7. nuxt
  8. plain
  9. >
  10. <font-awesome-icon class="icon mr-1" :icon="['fas', 'chevron-left']" />
  11. {{ $t('go_back') }}
  12. </v-btn>
  13. </v-layout>
  14. </header>
  15. <v-container class="content">
  16. <v-layout class="flex-row align-center mb-4">
  17. <nuxt-img
  18. :src="structure.logoId ? 'https://api.opentalent.fr/app.php/_internal/secure/files/' + structure.logoId + '/0x60' : '/images/default.jpg'"
  19. alt="logo"
  20. />
  21. <h2 class="flex mx-4 d-flex align-center">
  22. {{ structure.name }}
  23. </h2>
  24. <div class="d-flex flex-row align-center">
  25. <a v-if="structure.facebook" :href="structure.facebook" class="facebook" target="_blank" :title="$t('find_us_on') + ' Facebook'">
  26. <font-awesome-icon class="icon social-icon" :icon="['fab', 'facebook']" />
  27. </a>
  28. <a v-if="structure.instagram" :href="structure.instagram" class="instagram" target="_blank" :title="$t('find_us_on') + ' Instagram'">
  29. <font-awesome-icon class="icon social-icon" :icon="['fab', 'instagram-square']" />
  30. </a>
  31. <a v-if="structure.twitter" :href="structure.twitter" class="twitter" target="_blank" title="$t('find_us_on') + ' Twitter'">
  32. <font-awesome-icon class="icon social-icon" :icon="['fab', 'twitter']" />
  33. </a>
  34. </div>
  35. </v-layout>
  36. <v-row>
  37. <v-col class="d-flex justify-center" cols="12">
  38. <nuxt-img
  39. v-if="structure.imageId"
  40. :src="'https://api.opentalent.fr/app.php/_internal/secure/files/' + structure.imageId + '/raw'"
  41. alt="banner"
  42. />
  43. </v-col>
  44. </v-row>
  45. <v-row>
  46. <v-col cols="12">
  47. <v-chip-group v-if="structure.practices" :max="0" active-class="primary--text" class="justify-center">
  48. <v-chip v-for="practice in structure.practices" :key="practice">
  49. {{ $t(practice) }}
  50. </v-chip>
  51. </v-chip-group>
  52. </v-col>
  53. </v-row>
  54. <v-divider class="my-2" />
  55. <v-row class="my-2 py-2">
  56. <v-col
  57. cols="12"
  58. sm="6"
  59. class="description"
  60. >
  61. <div class="d-flex flex-row mb-3">
  62. <h4>{{ $t('descriptive') }}</h4>
  63. <v-spacer />
  64. </div>
  65. <div class="pa-2">
  66. <p v-if="structure.description" class="text-justify">
  67. {{ structure.description }}
  68. </p>
  69. <i v-else>({{ $t('no_description') }})</i>
  70. </div>
  71. </v-col>
  72. <v-col
  73. cols="12"
  74. sm="6"
  75. class="contact"
  76. >
  77. <div class="d-flex flex-row mb-3">
  78. <h4>{{ $t('contact') }}</h4>
  79. <v-spacer />
  80. </div>
  81. <table>
  82. <tr>
  83. <td>
  84. <font-awesome-icon class="icon" :icon="['fas', 'map-marker-alt']" />
  85. </td>
  86. <td class="mx-2">
  87. <span v-if="structure.streetAddress">{{ structure.streetAddress }}<br></span>
  88. <span v-if="structure.postalCode">{{ structure.postalCode }} </span>
  89. {{ structure.addressCity }}
  90. </td>
  91. </tr>
  92. <tr>
  93. <td>
  94. <font-awesome-icon class="icon" :icon="['fas', 'phone-alt']" />
  95. </td>
  96. <td class="phone">
  97. <div v-if="structure.telphone">
  98. <a v-if="showTel" :href="'tel:' + structure.telphone">{{ structure.telphone }}</a>
  99. <v-btn v-else small @click="showTel = 1">
  100. {{ $t('show_tel') }}
  101. </v-btn>
  102. </div>
  103. <span v-else>-</span>
  104. </td>
  105. </tr>
  106. <tr>
  107. <td>
  108. <font-awesome-icon class="icon" :icon="['fas', 'at']" />
  109. </td>
  110. <td class="mail">
  111. <div v-if="structure.email">
  112. <a v-if="showMail" :href="'mailto:' + structure.email">{{ structure.email }}</a>
  113. <v-btn v-else small @click="showMail = 1">
  114. {{ $t('show_email') }}
  115. </v-btn>
  116. </div>
  117. <span v-else>-</span>
  118. </td>
  119. </tr>
  120. <tr>
  121. <td>
  122. <font-awesome-icon class="icon" :icon="['fas', 'globe-europe']" />
  123. </td>
  124. <td class="website">
  125. <a :href="structure.website" target="_blank">{{ structure.website }}</a>
  126. </td>
  127. </tr>
  128. <tr>
  129. <td>
  130. <font-awesome-icon class="icon" :icon="['fas', 'project-diagram']" />
  131. </td>
  132. <td class="network">
  133. <NuxtLink
  134. v-if="structure.n1Id !== parent"
  135. :to="{path: '/structures/' + structure.n1Id, query: { parent: parent, view: view, theme: theme }}"
  136. nuxt
  137. >
  138. {{ structure.n1Name }}
  139. </NuxtLink>
  140. <div v-else>
  141. {{ structure.n1Name }}
  142. </div>
  143. </td>
  144. </tr>
  145. </table>
  146. </v-col>
  147. </v-row>
  148. <v-row class="mb-4">
  149. <v-col cols="12" >
  150. <v-btn
  151. v-for="article in structure.articles"
  152. :key="article.id"
  153. :href="(article.link.match(/https?:\/\/.*/) ? '' : 'https://') + article.link "
  154. small
  155. target="_blank"
  156. class="ma-2"
  157. >
  158. {{ $t('spot_on_from') + ' ' + new Date(article.date).toLocaleDateString($i18n.locale) }}
  159. </v-btn>
  160. </v-col>
  161. </v-row>
  162. <v-row v-if="structure.latitude && structure.longitude">
  163. <v-col cols="12">
  164. <v-responsive width="100%" height="450px">
  165. <no-ssr>
  166. <l-map
  167. id="map"
  168. :zoom="13"
  169. :center="[structure.latitude, structure.longitude]"
  170. :options="{ scrollWheelZoom: false, zoomSnap: 0.25 }"
  171. >
  172. <l-tile-layer
  173. url="http://{s}.tile.osm.org/{z}/{x}/{y}.png"
  174. attribution="&copy; <a href='http://osm.org/copyright'>OpenStreetMap</a> contributors"
  175. />
  176. <l-marker
  177. :key="structure.id"
  178. :lat-lng="[structure.latitude, structure.longitude]"
  179. >
  180. <l-popup>
  181. <b>{{ structure.name }}</b><br>
  182. {{ structure.postalCode }} {{ structure.addressCity }}<br>
  183. <a :href="structure.website" target="_blank">{{ structure.website }}</a>
  184. </l-popup>
  185. </l-marker>
  186. </l-map>
  187. </no-ssr>
  188. </v-responsive>
  189. </v-col>
  190. </v-row>
  191. </v-container>
  192. </LayoutContainer>
  193. </template>
  194. <script lang="ts">
  195. import Vue from 'vue'
  196. import StructuresProvider from '~/services/data/StructuresProvider'
  197. export default Vue.extend({
  198. validate ({ query }) {
  199. if (!/^\d+$/.test(query.parent as string ?? '')) {
  200. // eslint-disable-next-line no-console
  201. console.error('Missing parameter: parent')
  202. return false
  203. }
  204. return true
  205. },
  206. async asyncData ({
  207. params, $axios
  208. }): Promise<{ structure: Structure }> {
  209. return await new StructuresProvider($axios).getById(Number(params.id)).then((res) => {
  210. return { structure: res }
  211. })
  212. },
  213. data (): object {
  214. return {
  215. parent: parseInt(this.$route.query.parent as string),
  216. view: this.$route.query.view ?? 'map',
  217. theme: this.$route.query.theme ?? 'orange',
  218. showTel: false,
  219. showMail: false
  220. }
  221. }
  222. })
  223. </script>
  224. <style scoped lang="scss">
  225. @import 'assets/style/variables.scss';
  226. .content {
  227. margin: 18px 10%;
  228. max-width: 80%;
  229. }
  230. h2 {
  231. color: $theme;
  232. font-size: 22px;
  233. }
  234. h4 {
  235. color: #666;
  236. border-bottom: solid 1px $theme;
  237. font-size: 22px;
  238. }
  239. .social-icon {
  240. font-size: 22px;
  241. color: gray;
  242. margin: auto 8px;
  243. }
  244. .content {
  245. color: #666666;
  246. }
  247. @media screen and (min-width: 600px) {
  248. .description {
  249. border-right: solid 2px #e4611b;
  250. width: 45%;
  251. padding-right: 5%;
  252. }
  253. .contact {
  254. width: 45%;
  255. padding-left: 5%;
  256. }
  257. }
  258. .contact td {
  259. padding: 6px 12px;
  260. }
  261. .contact .icon {
  262. color: $theme;
  263. }
  264. </style>