move items to route
This commit is contained in:
parent
41c42d5880
commit
a065a1328d
10 changed files with 138 additions and 85 deletions
4
.env
4
.env
|
|
@ -1,5 +1,5 @@
|
||||||
VITE_STRAPI_URL=http://localhost:1337
|
VITE_STRAPI_URL=http://localhost:1337
|
||||||
VITE_STRAPI_API_TOKEN=7e379ac0df1d055e91f1add3c97947068f60dc943a208524c7e10201c9d66210d6dee3ab48155581892e2cabe7a285d12395ace15a1f982e68fe5078abce0aebb826ae7c701302aa932d638ec57cb10f71fee7971e0a2b87a7fdf8eeb848eea90fb97d45fc8af69e818d1d5a59dc79cbc24f0bd1830d78670b85775ad6e05c6b
|
VITE_STRAPI_API_TOKEN=7e379ac0df1d055e91f1add3c97947068f60dc943a208524c7e10201c9d66210d6dee3ab48155581892e2cabe7a285d12395ace15a1f982e68fe5078abce0aebb826ae7c701302aa932d638ec57cb10f71fee7971e0a2b87a7fdf8eeb848eea90fb97d45fc8af69e818d1d5a59dc79cbc24f0bd1830d78670b85775ad6e05c6b
|
||||||
|
|
||||||
VITE_STRAPI_URL=https://cms.nicwands.com
|
# VITE_STRAPI_URL=https://cms.nicwands.com
|
||||||
VITE_STRAPI_API_TOKEN=5934fb84b89fdca49ef58e4f493381848289fcfb09a5664c5a61d4673a6b81b10bdf1d364fa250d185049c14487b7297758c3653dbf37390f567d6d08d559b4c40aaf4dc10730a60b98011d6dc0553f2bd633b373739579d579e39a162f67ca6d8f0e5c5adb3537a7e94b303d79c4cb7f3f877e39158e37e5bd6838596ee9afe
|
# VITE_STRAPI_API_TOKEN=5934fb84b89fdca49ef58e4f493381848289fcfb09a5664c5a61d4673a6b81b10bdf1d364fa250d185049c14487b7297758c3653dbf37390f567d6d08d559b4c40aaf4dc10730a60b98011d6dc0553f2bd633b373739579d579e39a162f67ca6d8f0e5c5adb3537a7e94b303d79c4cb7f3f877e39158e37e5bd6838596ee9afe
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,7 @@
|
||||||
<lenis root :options="{ duration: 1 }">
|
<lenis root :options="{ duration: 1 }">
|
||||||
<div :class="classes" :style="styles" id="container">
|
<div :class="classes" :style="styles" id="container">
|
||||||
<suspense>
|
<suspense>
|
||||||
<site-header />
|
<layout />
|
||||||
</suspense>
|
|
||||||
|
|
||||||
<suspense>
|
|
||||||
<router-view />
|
|
||||||
</suspense>
|
</suspense>
|
||||||
</div>
|
</div>
|
||||||
</lenis>
|
</lenis>
|
||||||
|
|
@ -16,7 +12,6 @@
|
||||||
import { ref, computed, onMounted } from 'vue'
|
import { ref, computed, onMounted } from 'vue'
|
||||||
import loadFonts from '@fuzzco/font-loader'
|
import loadFonts from '@fuzzco/font-loader'
|
||||||
import { useWindowSize } from '@vueuse/core'
|
import { useWindowSize } from '@vueuse/core'
|
||||||
import useLenis from './composables/useLenis'
|
|
||||||
|
|
||||||
const { height } = useWindowSize()
|
const { height } = useWindowSize()
|
||||||
|
|
||||||
|
|
|
||||||
1
src/components.d.ts
vendored
1
src/components.d.ts
vendored
|
|
@ -13,6 +13,7 @@ declare module 'vue' {
|
||||||
export interface GlobalComponents {
|
export interface GlobalComponents {
|
||||||
DlRow: typeof import('./components/DlRow.vue')['default']
|
DlRow: typeof import('./components/DlRow.vue')['default']
|
||||||
InfiniteScrollContainer: typeof import('./components/InfiniteScrollContainer.vue')['default']
|
InfiniteScrollContainer: typeof import('./components/InfiniteScrollContainer.vue')['default']
|
||||||
|
Layout: typeof import('./components/Layout.vue')['default']
|
||||||
Lenis: typeof import('./components/Lenis.vue')['default']
|
Lenis: typeof import('./components/Lenis.vue')['default']
|
||||||
LoadingSpinner: typeof import('./components/LoadingSpinner.vue')['default']
|
LoadingSpinner: typeof import('./components/LoadingSpinner.vue')['default']
|
||||||
MosaicModal: typeof import('./components/MosaicModal.vue')['default']
|
MosaicModal: typeof import('./components/MosaicModal.vue')['default']
|
||||||
|
|
|
||||||
40
src/components/Layout.vue
Normal file
40
src/components/Layout.vue
Normal file
|
|
@ -0,0 +1,40 @@
|
||||||
|
<template>
|
||||||
|
<div v-if="global" class="layout">
|
||||||
|
<site-header :copy="headerCopy" :dl="headerDl" />
|
||||||
|
|
||||||
|
<mosaic-scroll :items="mosaicItems" />
|
||||||
|
|
||||||
|
<suspense>
|
||||||
|
<router-view />
|
||||||
|
</suspense>
|
||||||
|
</div>
|
||||||
|
</template async>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { computed } from 'vue';
|
||||||
|
import { useSeoMeta } from '@unhead/vue'
|
||||||
|
import { useStrapiGlobal } from '@/composables/useStrapi'
|
||||||
|
|
||||||
|
const { data: global } = await useStrapiGlobal()
|
||||||
|
|
||||||
|
const headerCopy = computed(() => global.value?.header_copy)
|
||||||
|
const headerDl = computed(() => global.value?.header_dl)
|
||||||
|
const mosaicItems = computed(() => global.value?.mosaic_items || [])
|
||||||
|
|
||||||
|
// SEO
|
||||||
|
const seo = computed(() => global.value?.seo)
|
||||||
|
useSeoMeta({
|
||||||
|
title: seo.value?.title || '',
|
||||||
|
description: seo.value?.description || '',
|
||||||
|
ogImage: {
|
||||||
|
url: seo.value?.image?.url || '',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
.layout {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -1,10 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div class="mosaic-modal theme-dark layout-grid-inner" @click="onClose">
|
||||||
class="mosaic-modal theme-dark layout-grid-inner"
|
|
||||||
@click="emit('close')"
|
|
||||||
>
|
|
||||||
<div class="meta">
|
<div class="meta">
|
||||||
<div class="window dl" @click.stop>
|
<div v-if="item.dl?.length" class="window dl" @click.stop>
|
||||||
<dl-row v-for="row in item.dl" :row="row" />
|
<dl-row v-for="row in item.dl" :row="row" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
@ -28,15 +25,17 @@
|
||||||
</lenis>
|
</lenis>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button class="window close" @click="emit('close')">Close X</button>
|
<button class="window close" @click="onClose">Close X</button>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
const props = defineProps({ item: Object })
|
import { useRouter } from 'vue-router'
|
||||||
console.log(props.item)
|
|
||||||
|
|
||||||
const emit = defineEmits(['close'])
|
const props = defineProps({ item: Object })
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
const onClose = () => router.push('/')
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|
@ -60,6 +59,7 @@ const emit = defineEmits(['close'])
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
gap: desktop-vw(8px);
|
gap: desktop-vw(8px);
|
||||||
|
margin-bottom: var(--layout-margin);
|
||||||
|
|
||||||
.dl-row:first-child {
|
.dl-row:first-child {
|
||||||
border-top: none;
|
border-top: none;
|
||||||
|
|
@ -67,7 +67,6 @@ const emit = defineEmits(['close'])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&.gif {
|
&.gif {
|
||||||
margin-top: var(--layout-margin);
|
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div class="mosaic-viewport">
|
<div class="mosaic-viewport">
|
||||||
<div class="mosaic-container">
|
<div class="mosaic-container">
|
||||||
<div
|
<router-link
|
||||||
v-for="cell in content.cells"
|
v-for="cell in content.cells"
|
||||||
:class="[
|
:class="[
|
||||||
'mosaic-cell',
|
'mosaic-cell',
|
||||||
|
|
@ -13,26 +13,20 @@
|
||||||
width: cell.width * 100 + 'vw',
|
width: cell.width * 100 + 'vw',
|
||||||
height: cell.height * 100 + 'vh',
|
height: cell.height * 100 + 'vh',
|
||||||
}"
|
}"
|
||||||
|
:to="{
|
||||||
|
name: 'mosaic-item',
|
||||||
|
params: { id: cell.content.slug },
|
||||||
|
}"
|
||||||
:key="`${viewport.index}-${cell.id}`"
|
:key="`${viewport.index}-${cell.id}`"
|
||||||
@click="openModal(cell.content)"
|
|
||||||
>
|
>
|
||||||
<strapi-media
|
<strapi-media
|
||||||
:image="cell.content.image"
|
:image="cell.content.image"
|
||||||
:aspect="100"
|
:aspect="100"
|
||||||
fit="contain"
|
fit="contain"
|
||||||
/>
|
/>
|
||||||
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
|
|
||||||
<!-- Content modal -->
|
|
||||||
<teleport to="#container">
|
|
||||||
<mosaic-modal
|
|
||||||
v-if="selectedItem"
|
|
||||||
:item="selectedItem"
|
|
||||||
@close="closeModal"
|
|
||||||
/>
|
|
||||||
</teleport>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
|
|
@ -52,47 +46,47 @@ const props = defineProps({
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
|
|
||||||
const route = useRoute()
|
// const route = useRoute()
|
||||||
const router = useRouter()
|
// const router = useRouter()
|
||||||
|
|
||||||
const selectedItem = computed(() => {
|
// const selectedItem = computed(() => {
|
||||||
const { item } = route.query
|
// const { item } = route.query
|
||||||
|
|
||||||
return props.content.cells.find((cell) => {
|
// return props.content.cells.find((cell) => {
|
||||||
return cell?.content?.slug === item
|
// return cell?.content?.slug === item
|
||||||
})?.content
|
// })?.content
|
||||||
})
|
// })
|
||||||
|
|
||||||
const openModal = (cellContent) => {
|
// const openModal = (cellContent) => {
|
||||||
router.push({
|
// router.push({
|
||||||
query: {
|
// query: {
|
||||||
item: cellContent.slug,
|
// item: cellContent.slug,
|
||||||
},
|
// },
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
const closeModal = () => {
|
// const closeModal = () => {
|
||||||
router.push({
|
// router.push({
|
||||||
query: null,
|
// query: null,
|
||||||
})
|
// })
|
||||||
}
|
// }
|
||||||
|
|
||||||
// Close note on Escape key
|
// // Close note on Escape key
|
||||||
const handleKeydown = (event) => {
|
// const handleKeydown = (event) => {
|
||||||
if (event.key === 'Escape' && selectedItem.value) {
|
// if (event.key === 'Escape' && selectedItem.value) {
|
||||||
closeModal()
|
// closeModal()
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
useEventListener('keydown', handleKeydown)
|
// useEventListener('keydown', handleKeydown)
|
||||||
|
|
||||||
// Pause scroll when modal is open
|
// // Pause scroll when modal is open
|
||||||
const lenis = useLenis()
|
// const lenis = useLenis()
|
||||||
watch(selectedItem, (newItem, oldItem) => {
|
// watch(selectedItem, (newItem, oldItem) => {
|
||||||
if (newItem && !oldItem) {
|
// if (newItem && !oldItem) {
|
||||||
lenis.value.stop()
|
// lenis.value.stop()
|
||||||
} else if (oldItem && !newItem) {
|
// } else if (oldItem && !newItem) {
|
||||||
lenis.value.start()
|
// lenis.value.start()
|
||||||
}
|
// }
|
||||||
})
|
// })
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,20 @@
|
||||||
<template>
|
<template>
|
||||||
<header v-if="data" class="site-header layout-grid-inner">
|
<header class="site-header layout-grid-inner">
|
||||||
<img class="logo" src="/images/output.gif" />
|
<img class="logo" src="/images/output.gif" />
|
||||||
|
|
||||||
<div class="info theme-red">
|
<div class="info theme-red">
|
||||||
<strapi-content class="copy" :content="data.header_copy" />
|
<strapi-content class="copy" :content="copy" />
|
||||||
|
|
||||||
<dl-row v-for="row in data.header_dl" :row="row" />
|
<dl-row v-for="row in dl" :row="row" />
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { useStrapiGlobal } from '@/composables/useStrapi'
|
const props = defineProps({
|
||||||
|
copy: Array,
|
||||||
const { data } = await useStrapiGlobal()
|
dl: Array,
|
||||||
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,8 @@
|
||||||
<template>
|
<template>
|
||||||
<main class="home">
|
<main class="home"></main>
|
||||||
<mosaic-scroll :items="mosaicItems" />
|
|
||||||
</main>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup></script>
|
||||||
import { useStrapiSingle } from '@/composables/useStrapi'
|
|
||||||
import useStrapiHead from '@/composables/useStrapiHead'
|
|
||||||
import { computed } from 'vue'
|
|
||||||
|
|
||||||
const { data } = await useStrapiSingle('home')
|
|
||||||
useStrapiHead()
|
|
||||||
|
|
||||||
const mosaicItems = computed(() => data.value?.mosaic_items || [])
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
main.home {
|
main.home {
|
||||||
|
|
|
||||||
28
src/pages/mosaic-item.vue
Normal file
28
src/pages/mosaic-item.vue
Normal file
|
|
@ -0,0 +1,28 @@
|
||||||
|
<template>
|
||||||
|
<main class="mosaic-item">
|
||||||
|
<mosaic-modal :item="activeItem" />
|
||||||
|
</main>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { useStrapiGlobal } from '@/composables/useStrapi'
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import { useRoute } from 'vue-router'
|
||||||
|
|
||||||
|
const route = useRoute()
|
||||||
|
const id = route.params.id
|
||||||
|
|
||||||
|
const { data: global } = await useStrapiGlobal()
|
||||||
|
|
||||||
|
const mosaicItems = computed(() => global.value?.mosaic_items || [])
|
||||||
|
const activeItem = computed(() =>
|
||||||
|
mosaicItems.value.find((item) => item.slug === id),
|
||||||
|
)
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss">
|
||||||
|
main.mosaic-item {
|
||||||
|
position: relative;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import index from './pages/index.vue'
|
import index from './pages/index.vue'
|
||||||
|
import mosaicItem from './pages/mosaic-item.vue'
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
routes: [
|
routes: [
|
||||||
|
|
@ -7,5 +8,10 @@ export default {
|
||||||
component: index,
|
component: index,
|
||||||
name: 'home',
|
name: 'home',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/:id',
|
||||||
|
component: mosaicItem,
|
||||||
|
name: 'mosaic-item',
|
||||||
|
},
|
||||||
],
|
],
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue