-
Notifications
You must be signed in to change notification settings - Fork 0
feat: Support Lupus Decoupled Drupal recipes. #5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 1.x
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| <template> | ||
| <div class="view"> | ||
| <h1 class="text-4xl font-bold mb-8 text-center tracking-tight">{{ title }}</h1> | ||
| <div class="lg:flex lg:justify-around"> | ||
| <component | ||
| :is="renderCustomElements(row)" | ||
| v-for="(row, index) in rows" | ||
| :key="index" | ||
| class="w-full mb-8 lg:w-[33%]" | ||
| /> | ||
| </div> | ||
| <div class="text-center"> | ||
| <DrupalViewsPagination | ||
| :total-pages="pager.totalPages" | ||
| :current="pager.current" | ||
| /> | ||
| </div> | ||
| </div> | ||
| </template> | ||
|
|
||
| <script setup lang="ts"> | ||
| defineProps<{ | ||
| title: string | ||
| rows?: object[] | ||
| pager?: object | ||
| }>() | ||
|
|
||
| const {renderCustomElements} = useDrupalCe() | ||
| </script> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| <template> | ||
| <div class="relative"> | ||
| <img | ||
| :src="image.url" | ||
| :title="image.title" | ||
| :alt="image.alt" | ||
| :width="image.width" | ||
| :height="image.height" | ||
| > | ||
| <div v-if="copyright" class="absolute bottom-0 right-0 bg-black/50 text-white text-xs px-2 py-1"> | ||
| {{ copyright }} | ||
| </div> | ||
| </div> | ||
| </template> | ||
|
|
||
| <script setup lang="ts"> | ||
| defineProps<{ | ||
| image?: object | ||
| copyright?: string | ||
| }>() | ||
| </script> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,19 @@ | ||
| <template> | ||
| <div class="max-w-4xl mx-auto px-4 py-8"> | ||
| <div class="mb-8"> | ||
| <component :is="useDrupalCe().renderCustomElements(featuredImage)" class="w-full h-auto rounded-lg shadow-lg mb-6" /> | ||
| <h1 v-if="title" class="text-4xl font-bold mb-4">{{ title }}</h1> | ||
| </div> | ||
| <div class="prose max-w-none mb-8 dark:prose-invert" v-html="content"></div> | ||
| </div> | ||
| </template> | ||
|
|
||
| <script setup lang="ts"> | ||
| defineProps<{ | ||
| // Layout-builder support. | ||
| sections?: object; | ||
| title?: string; | ||
| featuredImage?: object; | ||
| content?: string; | ||
| }>(); | ||
| </script> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| // https://nuxt.com/docs/api/configuration/nuxt-config | ||
| export default defineNuxtConfig({ | ||
|
|
||
| }) | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,52 @@ | ||
| <template> | ||
| <nuxt-link :to="path.pathAlias" class="block"> | ||
| <article class="rounded-lg border border-gray-200 dark:border-gray-700 hover:border-gray-300 dark:hover:border-gray-600 transition-all duration-200 bg-white dark:bg-gray-800 shadow-sm hover:shadow-md dark:shadow-gray-900/50 overflow-hidden"> | ||
| <div class="overflow-hidden"> | ||
| <component | ||
| :is="renderCustomElements(featuredImage)" | ||
| class="w-full h-full object-cover transition-transform duration-300 hover:scale-105" | ||
| /> | ||
| </div> | ||
| <div class="p-4"> | ||
| <h2 v-if="title" class="text-lg font-semibold text-gray-900 dark:text-gray-100 mb-2"> | ||
| {{ title }} | ||
| </h2> | ||
| <div v-if="author || created" class="flex items-center gap-3 text-xs text-gray-600 dark:text-gray-400"> | ||
| <span v-if="author" class="flex items-center gap-1"> | ||
| <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> | ||
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"></path> | ||
| </svg> | ||
| {{ author }} | ||
| </span> | ||
| <span v-if="created" class="flex items-center gap-1"> | ||
| <svg class="w-3.5 h-3.5" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> | ||
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"></path> | ||
| </svg> | ||
| {{ formatDate(created) }} | ||
| </span> | ||
| </div> | ||
| </div> | ||
| </article> | ||
| </nuxt-link> | ||
| </template> | ||
|
|
||
| <script setup lang="ts"> | ||
| const { renderCustomElements } = useDrupalCe() | ||
| defineProps<{ | ||
| title?: String; | ||
| path?: object; | ||
| featuredImage?: CustomElementContent; | ||
| author?: string; | ||
| created?: string; | ||
| }>() | ||
|
|
||
| const formatDate = (dateString: string) => { | ||
| if (!dateString) return ''; | ||
| const date = new Date(dateString); | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. minor: but why not format the date with the formatter on the backend? |
||
| return new Intl.DateTimeFormat('en-US', { | ||
| year: 'numeric', | ||
| month: 'short', | ||
| day: 'numeric' | ||
| }).format(date); | ||
| } | ||
| </script> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,25 +1,45 @@ | ||
| <template> | ||
| <div class="node"> | ||
| <h2 v-if="title">Blog: {{ title }}</h2> | ||
| <slot name="image"> | ||
| <component :is="useDrupalCe().renderCustomElements($attrs.image)" /> | ||
| </slot> | ||
| <slot name="body"> | ||
| <component :is="useDrupalCe().renderCustomElements($attrs.body)" /> | ||
| </slot> | ||
| <div class="max-w-4xl mx-auto px-4 py-8"> | ||
| <div class="mb-8"> | ||
| <component :is="useDrupalCe().renderCustomElements(featuredImage)" class="w-full h-auto rounded-lg shadow-lg mb-6" /> | ||
| <h1 v-if="title" class="text-4xl font-bold mb-4">{{ title }}</h1> | ||
| <div v-if="author || created" class="flex items-center gap-4 text-sm text-gray-600 dark:text-gray-400"> | ||
| <span v-if="author" class="flex items-center gap-1"> | ||
| <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> | ||
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M16 7a4 4 0 11-8 0 4 4 0 018 0zM12 14a7 7 0 00-7 7h14a7 7 0 00-7-7z"></path> | ||
| </svg> | ||
| {{ author }} | ||
| </span> | ||
| <span v-if="created" class="flex items-center gap-1"> | ||
| <svg class="w-4 h-4" fill="none" stroke="currentColor" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"> | ||
| <path stroke-linecap="round" stroke-linejoin="round" stroke-width="2" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"></path> | ||
| </svg> | ||
| {{ formatDate(created) }} | ||
| </span> | ||
| </div> | ||
| </div> | ||
| </template> | ||
|
|
||
| <script setup lang="ts"> | ||
| defineSlots<{ | ||
| body(); | ||
| image(); | ||
| }>() | ||
| defineProps<{ | ||
| title?: string; | ||
| type?: string; | ||
| created?: number | string; | ||
| // Layout-builder support. | ||
| sections?: object; | ||
| }>() | ||
| </script> | ||
| <div class="prose max-w-none mb-8 dark:prose-invert" v-html="content"></div> | ||
| </div> | ||
| </template> | ||
|
|
||
| <script setup lang="ts"> | ||
| defineProps<{ | ||
| // Layout-builder support. | ||
| sections?: object; | ||
| title?: string; | ||
| featuredImage?: object; | ||
| content?: string; | ||
| author?: string; | ||
| created?: string; | ||
| }>(); | ||
|
|
||
| const formatDate = (dateString: string) => { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. would make sense to move it into composable to avoid defining it multiple times? |
||
| if (!dateString) return ''; | ||
| const date = new Date(dateString); | ||
| return new Intl.DateTimeFormat('en-US', { | ||
| year: 'numeric', | ||
| month: 'long', | ||
| day: 'numeric' | ||
| }).format(date); | ||
| }; | ||
| </script> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| <template> | ||
| <nuxt-link :to="path.pathAlias" class="block"> | ||
| <article class="rounded-lg border border-gray-200 dark:border-gray-700 hover:border-gray-300 dark:hover:border-gray-600 transition-all duration-200 bg-white dark:bg-gray-800 shadow-sm hover:shadow-md dark:shadow-gray-900/50 overflow-hidden"> | ||
| <div class="overflow-hidden"> | ||
| <component | ||
| :is="renderCustomElements(featuredImage)" | ||
| class="w-full h-full object-cover transition-transform duration-300 hover:scale-105" | ||
| /> | ||
| </div> | ||
| <div class="p-4"> | ||
| <h2 v-if="title" class="text-lg font-semibold text-gray-900 dark:text-gray-100"> | ||
| {{ title }} | ||
| </h2> | ||
| </div> | ||
| </article> | ||
| </nuxt-link> | ||
| </template> | ||
|
|
||
| <script setup lang="ts"> | ||
| const { renderCustomElements } = useDrupalCe() | ||
| defineProps<{ | ||
| title?: String; | ||
| path?: object; | ||
| featuredImage?: CustomElementContent; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. maybe define as slot also? |
||
| }>() | ||
| </script> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| <template> | ||
| <div class="max-w-4xl mx-auto px-4 py-8"> | ||
| <div class="mb-8"> | ||
| <component :is="useDrupalCe().renderCustomElements(featuredImage)" class="w-full h-auto rounded-lg shadow-lg mb-6" /> | ||
| <component :is="useDrupalCe().renderCustomElements(clientLogo)" class="w-80 mb-6" /> | ||
| <h1 v-if="title" class="text-4xl font-bold mb-4">{{ title }}</h1> | ||
| </div> | ||
| <div class="prose max-w-none mb-8 dark:prose-invert" v-html="content"></div> | ||
| <a v-if="clientLink" :href="clientLink.clientLinkUri" target="_blank" class="inline-block px-6 py-3 bg-blue-600 hover:bg-blue-700 text-white font-semibold rounded-lg shadow-md transition-colors duration-200">Visit website</a> | ||
| </div> | ||
| </template> | ||
|
|
||
| <script setup lang="ts"> | ||
| defineProps<{ | ||
| // Layout-builder support. | ||
| sections?: object; | ||
| title?: string; | ||
| featuredImage?: object; | ||
| clientLogo?: object; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. let's differ CustomElementContent vs some object? link is not very nice like this, would it make sense to flatten? |
||
| clientLink?: object; | ||
| content?: string; | ||
| }>(); | ||
| </script> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| // https://nuxt.com/docs/api/configuration/nuxt-config | ||
| export default defineNuxtConfig({ | ||
| }) |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| <template> | ||
| <nuxt-link :to="path.pathAlias" class="block"> | ||
| <article class="rounded-lg border border-gray-200 dark:border-gray-700 hover:border-gray-300 dark:hover:border-gray-600 transition-all duration-200 bg-white dark:bg-gray-800 shadow-sm hover:shadow-md dark:shadow-gray-900/50 overflow-hidden"> | ||
| <div class="overflow-hidden"> | ||
| <component | ||
| :is="renderCustomElements(featuredImage)" | ||
| class="w-full h-full object-cover transition-transform duration-300 hover:scale-105" | ||
| /> | ||
| </div> | ||
| <div class="p-4"> | ||
| <h2 v-if="title" class="text-lg font-semibold text-gray-900 dark:text-gray-100"> | ||
| {{ title }} | ||
| </h2> | ||
| </div> | ||
| </article> | ||
| </nuxt-link> | ||
| </template> | ||
|
|
||
| <script setup lang="ts"> | ||
| const { renderCustomElements } = useDrupalCe() | ||
| defineProps<{ | ||
| title?: String; | ||
| path?: object; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. there is now some solution for the path I think latest CE-release has some special formatter, see 3.1 release notes |
||
| featuredImage?: CustomElementContent; | ||
| }>() | ||
| </script> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,99 @@ | ||
| <template> | ||
| <div class="max-w-4xl mx-auto px-4 py-8"> | ||
| <div class="mb-8"> | ||
| <component :is="useDrupalCe().renderCustomElements(featuredImage)" class="w-full h-auto rounded-lg shadow-lg mb-6" /> | ||
| <h1 v-if="title" class="text-4xl font-bold mb-4">{{ title }}</h1> | ||
| </div> | ||
| <div class="bg-white rounded-lg shadow-md p-6 mb-8"> | ||
| <div v-if="date" class="mb-4"> | ||
| <h3 class="text-lg font-semibold mb-2">Date:</h3> | ||
| <p>{{ formatDate(date.value) }} - {{ formatDate(date.endValue) }}</p> | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this a defined structure? (endDate is sometimes optional) |
||
| </div> | ||
| <div v-if="locationName" class="mb-4"> | ||
| <h3 class="text-lg font-semibold mb-2">Venue:</h3> | ||
| <p>{{ locationName }}</p> | ||
| </div> | ||
| <div v-if="locationAddress" class="mb-4"> | ||
| <p>{{ locationAddress.addressLine1 }}</p> | ||
| <p>{{ locationAddress.locality }}, | ||
| {{ locationAddress.administrativeArea }} {{ locationAddress.postalCode }}</p> | ||
| </div> | ||
| <div v-if="link" class="mb-4"> | ||
| <a :href="link.uri" target="_blank">{{ link.title }}</a> | ||
| </div> | ||
| </div> | ||
| <div class="prose max-w-none mb-8 dark:prose-invert" v-html="content"></div> | ||
| <div v-if="geofield" class="rounded-lg overflow-hidden shadow-lg"> | ||
| <div class="h-[400px]"> | ||
| <LMap | ||
| ref="map" | ||
| :zoom="zoom" | ||
| :center="latlng" | ||
| :use-global-leaflet="false" | ||
| class="h-full w-full" | ||
| > | ||
| <LTileLayer | ||
| url="https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png" | ||
| attribution="© <a href='https://www.openstreetmap.org/'>OpenStreetMap</a> contributors" | ||
| layer-type="base" | ||
| name="OpenStreetMap" | ||
| /> | ||
| <LMarker :lat-lng="latlng" /> | ||
| </LMap> | ||
| </div> | ||
| </div> | ||
| </div> | ||
| </template> | ||
|
|
||
| <script setup lang="ts"> | ||
| import type { LatLngExpression } from 'leaflet'; | ||
|
|
||
| const props = defineProps<{ | ||
| // Layout-builder support. | ||
| sections?: object; | ||
| title?: string; | ||
| featuredImage?: object; | ||
| content?: string; | ||
| geofield?: { | ||
| lat: number; | ||
| lon: number; | ||
| }; | ||
| date?: { | ||
| value: string; | ||
| endValue: string; | ||
| duration: string; | ||
| rrule: string; | ||
| rruleIndex: string; | ||
| timezone: string; | ||
| }; | ||
| locationName?: string; | ||
| locationAddress?: { | ||
| addressLine1: string; | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. oh I was not aware it works like this also, that's nice, maybe we could use that for the link structure also? |
||
| locality: string; | ||
| administrativeArea: string; | ||
| postalCode: string; | ||
| }; | ||
| link?: { | ||
| uri: string; | ||
| title: string; | ||
| }; | ||
| }>(); | ||
|
|
||
| const zoom = ref(13); | ||
| const latlng = computed<LatLngExpression>(() => { | ||
| if (props.geofield) { | ||
| return [props.geofield.lat, props.geofield.lon]; | ||
| } | ||
| return [0, 0]; | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe find a better default location than south of coast of Africa. |
||
| }); | ||
|
|
||
| const formatDate = (timestamp: string) => { | ||
| if (!timestamp) return ''; | ||
| const date = new Date(Number(timestamp) * 1000); | ||
| return new Intl.DateTimeFormat('en-US', { | ||
| year: 'numeric', | ||
| month: 'long', | ||
| day: 'numeric' | ||
| }).format(date); | ||
| }; | ||
| </script> | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| // https://nuxt.com/docs/api/configuration/nuxt-config | ||
| export default defineNuxtConfig({ | ||
| modules: ['@nuxtjs/leaflet'] | ||
| }) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
index is following row, looks strange