From c01d81844c51cc37a2f6d4d38cc21054572d03e1 Mon Sep 17 00:00:00 2001 From: Lindsey Zylstra Date: Wed, 6 Nov 2024 14:03:50 -0800 Subject: [PATCH 01/29] Double Ticker --- components/Block/LogoCloud.vue | 1 + components/LogoDoubleTicker.vue | 150 ++++++++++++++++++++++++ types/schema/blocks/block-logo-cloud.ts | 2 +- 3 files changed, 152 insertions(+), 1 deletion(-) create mode 100644 components/LogoDoubleTicker.vue diff --git a/components/Block/LogoCloud.vue b/components/Block/LogoCloud.vue index c7645283..e7468101 100644 --- a/components/Block/LogoCloud.vue +++ b/components/Block/LogoCloud.vue @@ -32,5 +32,6 @@ const logos = computed(() => { diff --git a/components/LogoDoubleTicker.vue b/components/LogoDoubleTicker.vue new file mode 100644 index 00000000..836133bf --- /dev/null +++ b/components/LogoDoubleTicker.vue @@ -0,0 +1,150 @@ + + + + + diff --git a/types/schema/blocks/block-logo-cloud.ts b/types/schema/blocks/block-logo-cloud.ts index e540cd55..5a79ba2f 100644 --- a/types/schema/blocks/block-logo-cloud.ts +++ b/types/schema/blocks/block-logo-cloud.ts @@ -4,7 +4,7 @@ import type { File } from '../system/index.js'; export interface BlockLogoCloud { id: string; - type: 'ticker' | 'grid' | 'title' | null; + type: 'ticker' | 'grid' | 'title' | 'double' | null; logos: number[] | BlockLogoCloudLogo[]; } From 50d8b82fac6ab19c443cf5012504878e45a71dde Mon Sep 17 00:00:00 2001 From: Lindsey Zylstra Date: Thu, 7 Nov 2024 12:46:01 -0800 Subject: [PATCH 02/29] Paper Image Background --- components/Block/Paper.vue | 29 ++++++++++++++++++++++++++--- types/schema/blocks/block-paper.ts | 3 ++- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/components/Block/Paper.vue b/components/Block/Paper.vue index 0ba52d82..9d31a070 100644 --- a/components/Block/Paper.vue +++ b/components/Block/Paper.vue @@ -3,23 +3,46 @@ import type { BlockProps } from './types'; const { $directus, $readItem } = useNuxtApp(); +const { + public: { directusUrl }, +} = useRuntimeConfig(); + const props = defineProps(); const { data: block } = useAsyncData(props.uuid, () => $directus.request( $readItem('block_paper', props.uuid, { - fields: ['background', 'padding', { blocks: ['id', 'collection', 'item'] }], + fields: ['background', 'padding', 'background_image', { blocks: ['id', 'collection', 'item'] }], }), ), ); + +const backgroundImageUrl = computed(() => { + if (block.value && block.value.background === 'image' && block.value.background_image) { + const url = new URL(`/assets/${block.value.background_image}`, directusUrl as string); + return url.toString(); + } + + return null; +}); diff --git a/components/Carousel/CarouselContent.vue b/components/Carousel/CarouselContent.vue new file mode 100644 index 00000000..66006878 --- /dev/null +++ b/components/Carousel/CarouselContent.vue @@ -0,0 +1,51 @@ + + + + + diff --git a/components/Carousel/CarouselControls.vue b/components/Carousel/CarouselControls.vue new file mode 100644 index 00000000..9a04cdd4 --- /dev/null +++ b/components/Carousel/CarouselControls.vue @@ -0,0 +1,16 @@ + + + diff --git a/components/Carousel/CarouselItem.vue b/components/Carousel/CarouselItem.vue new file mode 100644 index 00000000..97589532 --- /dev/null +++ b/components/Carousel/CarouselItem.vue @@ -0,0 +1,14 @@ + + + diff --git a/components/Carousel/interface.ts b/components/Carousel/interface.ts new file mode 100644 index 00000000..5a553672 --- /dev/null +++ b/components/Carousel/interface.ts @@ -0,0 +1,25 @@ +import type { HTMLAttributes, UnwrapRef } from 'vue'; +import type useEmblaCarousel from 'embla-carousel-vue'; +import type { EmblaCarouselVueType } from 'embla-carousel-vue'; + +type CarouselApi = EmblaCarouselVueType[1]; +type UseCarouselParameters = Parameters; +type CarouselOptions = UseCarouselParameters[0]; +type CarouselPlugin = UseCarouselParameters[1]; + +export type UnwrapRefCarouselApi = UnwrapRef; + +export interface CarouselProps { + opts?: CarouselOptions; + plugins?: CarouselPlugin; + orientation?: 'horizontal' | 'vertical'; +} + +export interface CarouselEmits { + (e: 'init-api', payload: UnwrapRefCarouselApi): void; +} + +export interface WithClassAsProps { + class?: HTMLAttributes['class']; + variant?: string; +} diff --git a/components/Carousel/useCarousel.ts b/components/Carousel/useCarousel.ts new file mode 100644 index 00000000..9f18bd48 --- /dev/null +++ b/components/Carousel/useCarousel.ts @@ -0,0 +1,62 @@ +import { createInjectionState } from '@vueuse/core'; +import emblaCarouselVue from 'embla-carousel-vue'; +import { onMounted, ref } from 'vue'; +import type { UnwrapRefCarouselApi as CarouselApi, CarouselEmits, CarouselProps } from './interface'; + +const [useProvideCarousel, useInjectCarousel] = createInjectionState( + ({ opts, orientation, plugins }: CarouselProps, emits: CarouselEmits) => { + const [emblaNode, emblaApi] = emblaCarouselVue( + { + ...opts, + axis: orientation === 'horizontal' ? 'x' : 'y', + }, + plugins, + ); + + function scrollPrev() { + emblaApi.value?.scrollPrev(); + } + + function scrollNext() { + emblaApi.value?.scrollNext(); + } + + const canScrollNext = ref(false); + const canScrollPrev = ref(false); + + function onSelect(api: CarouselApi) { + canScrollNext.value = api?.canScrollNext() || false; + canScrollPrev.value = api?.canScrollPrev() || false; + } + + onMounted(() => { + if (!emblaApi.value) return; + + emblaApi.value?.on('init', onSelect); + emblaApi.value?.on('reInit', onSelect); + emblaApi.value?.on('select', onSelect); + + emits('init-api', emblaApi.value); + }); + + return { + carouselRef: emblaNode, + carouselApi: emblaApi, + canScrollPrev, + canScrollNext, + scrollPrev, + scrollNext, + orientation, + }; + }, +); + +function useCarousel() { + const carouselState = useInjectCarousel(); + + if (!carouselState) throw new Error('useCarousel must be used within a '); + + return carouselState; +} + +export { useCarousel, useProvideCarousel }; diff --git a/package.json b/package.json index 35ee9533..56d819bf 100644 --- a/package.json +++ b/package.json @@ -58,6 +58,8 @@ "pnpm": ">=8.15.0" }, "dependencies": { + "embla-carousel": "^8.3.1", + "embla-carousel-class-names": "^8.3.1", "embla-carousel-vue": "^8.3.1" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index a384b71e..23026b1a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -8,6 +8,12 @@ importers: .: dependencies: + embla-carousel: + specifier: ^8.3.1 + version: 8.3.1 + embla-carousel-class-names: + specifier: ^8.3.1 + version: 8.3.1(embla-carousel@8.3.1) embla-carousel-vue: specifier: ^8.3.1 version: 8.3.1(vue@3.5.3(typescript@5.5.4)) @@ -2430,6 +2436,11 @@ packages: electron-to-chromium@1.5.18: resolution: {integrity: sha512-1OfuVACu+zKlmjsNdcJuVQuVE61sZOLbNM4JAQ1Rvh6EOj0/EUKhMJjRH73InPlXSh8HIJk1cVZ8pyOV/FMdUQ==} + embla-carousel-class-names@8.3.1: + resolution: {integrity: sha512-Hap1Y+ILMV3cJopGUC0HAcIqts3KCIHFxcwojYTre2QeH+bf4yFzdPiGVPZ3nooTx7rFgEu9noidw4SnLBqoNw==} + peerDependencies: + embla-carousel: 8.3.1 + embla-carousel-reactive-utils@8.3.1: resolution: {integrity: sha512-Js6rTTINNGnUGPu7l5kTcheoSbEnP5Ak2iX0G9uOoI8okTNLMzuWlEIpYFd1WP0Sq82FFcLkKM2oiO6jcElZ/Q==} peerDependencies: @@ -7693,6 +7704,10 @@ snapshots: electron-to-chromium@1.5.18: {} + embla-carousel-class-names@8.3.1(embla-carousel@8.3.1): + dependencies: + embla-carousel: 8.3.1 + embla-carousel-reactive-utils@8.3.1(embla-carousel@8.3.1): dependencies: embla-carousel: 8.3.1 From b7727e4b72010ceb5a11c6d284a1a8f73bf1353d Mon Sep 17 00:00:00 2001 From: Lindsey Zylstra Date: Tue, 12 Nov 2024 16:07:58 -0800 Subject: [PATCH 07/29] WIP Masonry Grid --- components/Base/Block.vue | 2 + components/Block/MasonryGrid/MasonryGrid.vue | 79 ++++++++++++++++ .../Block/MasonryGrid/MasonryGridCard.vue | 89 +++++++++++++++++++ .../schema/blocks/block-masonry-grid-card.ts | 8 ++ types/schema/blocks/block-masonry-grid.ts | 11 +++ types/schema/blocks/block.ts | 14 ++- types/schema/blocks/index.ts | 2 + types/schema/schema.ts | 4 + 8 files changed, 207 insertions(+), 2 deletions(-) create mode 100644 components/Block/MasonryGrid/MasonryGrid.vue create mode 100644 components/Block/MasonryGrid/MasonryGridCard.vue create mode 100644 types/schema/blocks/block-masonry-grid-card.ts create mode 100644 types/schema/blocks/block-masonry-grid.ts diff --git a/components/Base/Block.vue b/components/Base/Block.vue index 750c89e9..b7221803 100644 --- a/components/Base/Block.vue +++ b/components/Base/Block.vue @@ -21,6 +21,8 @@ const components: Record> = { block_card: resolveComponent('BlockCard'), block_carousel: resolveComponent('BlockCarousel'), block_carousel_cards: resolveComponent('BlockCarouselCard'), + block_masonry_grid: resolveComponent('BlockMasonryGrid'), + block_masonry_grid_card: resolveComponent('BlockMasonryGridCard'), block_code: resolveComponent('BlockCode'), block_columns: resolveComponent('BlockColumns'), block_cta: resolveComponent('BlockCta'), diff --git a/components/Block/MasonryGrid/MasonryGrid.vue b/components/Block/MasonryGrid/MasonryGrid.vue new file mode 100644 index 00000000..d401b793 --- /dev/null +++ b/components/Block/MasonryGrid/MasonryGrid.vue @@ -0,0 +1,79 @@ + + + + + diff --git a/components/Block/MasonryGrid/MasonryGridCard.vue b/components/Block/MasonryGrid/MasonryGridCard.vue new file mode 100644 index 00000000..3b5f6f25 --- /dev/null +++ b/components/Block/MasonryGrid/MasonryGridCard.vue @@ -0,0 +1,89 @@ + + + + + diff --git a/types/schema/blocks/block-masonry-grid-card.ts b/types/schema/blocks/block-masonry-grid-card.ts new file mode 100644 index 00000000..c185b337 --- /dev/null +++ b/types/schema/blocks/block-masonry-grid-card.ts @@ -0,0 +1,8 @@ +export interface BlockMasonryGridCard { + id: string; + sort: number; + title: string; + description: string | null; + image: string | File | null; + type: 'single' | 'double' | null; +} diff --git a/types/schema/blocks/block-masonry-grid.ts b/types/schema/blocks/block-masonry-grid.ts new file mode 100644 index 00000000..99cd49e5 --- /dev/null +++ b/types/schema/blocks/block-masonry-grid.ts @@ -0,0 +1,11 @@ +export interface BlockMasonryGrid { + id: string; + grid_layout: 'six_cards' | 'four_cards' | 'two_cards'; + cards: BlockMasonryGridBlockMasonryGridCards[]; +} + +export interface BlockMasonryGridBlockMasonryGridCards { + id: string; + block_masonry_grid_id: string; + block_masonry_grid_card_id: string; +} diff --git a/types/schema/blocks/block.ts b/types/schema/blocks/block.ts index dc77f899..4ce9d157 100644 --- a/types/schema/blocks/block.ts +++ b/types/schema/blocks/block.ts @@ -26,6 +26,10 @@ import type { BlockTestimonialSlider } from './block-testimonial-slider.js'; import type { BlockTierGroup } from './block-tier-group.js'; import type { BlockTier } from './block-tier.js'; import type { BlockDirectory } from './block-directory.js'; +import type { BlockCarousel } from './block-carousel.js'; +import type { BlockCarouselCards } from './block-carousel-cards.js'; +import type { BlockMasonryGrid } from './block-masonry-grid.js'; +import type { BlockMasonryGridCard } from './block-masonry-grid-card.js'; export type BlockType = | 'block_accordion_group' @@ -58,7 +62,9 @@ export type BlockType = | 'block_tier' | 'block_directory' | 'block_carousel' - | 'block_carousel_cards'; + | 'block_carousel_cards' + | 'block_masonry_grid' + | 'block_masonry_grid_card'; export type Block = | BlockAccordion @@ -89,4 +95,8 @@ export type Block = | BlockTestimonialSlider | BlockTier | BlockTierGroup - | BlockDirectory; + | BlockDirectory + | BlockCarousel + | BlockCarouselCards + | BlockMasonryGrid + | BlockMasonryGridCard; diff --git a/types/schema/blocks/index.ts b/types/schema/blocks/index.ts index 12f58f4d..94bc5038 100644 --- a/types/schema/blocks/index.ts +++ b/types/schema/blocks/index.ts @@ -30,3 +30,5 @@ export type * from './block-directory.js'; export type * from './block.js'; export type * from './block-carousel.js'; export type * from './block-carousel-cards.js'; +export type * from './block-masonry-grid.js'; +export type * from './block-masonry-grid-card.js'; diff --git a/types/schema/schema.ts b/types/schema/schema.ts index e35f97c8..b8cce900 100644 --- a/types/schema/schema.ts +++ b/types/schema/schema.ts @@ -42,6 +42,8 @@ import type { BlockDirectory, BlockCarousel, BlockCarouselCards, + BlockMasonryGrid, + BlockMasonryGridCard, } from './blocks/index.js'; import type { Form, @@ -132,6 +134,8 @@ export interface Schema { block_directory: BlockDirectory[]; block_carousel: BlockCarousel[]; block_carousel_cards: BlockCarouselCards[]; + block_masonry_grid: BlockMasonryGrid[]; + block_masonry_grid_card: BlockMasonryGridCard[]; // Meta globals: Globals; From 77e44e93831ee0dfb61011d94c31c7c9fd66965a Mon Sep 17 00:00:00 2001 From: bryantgillespie Date: Tue, 12 Nov 2024 18:23:51 -0500 Subject: [PATCH 08/29] fixes --- components/Block/Carousel/Carousel.vue | 51 ++++++++++++---------- components/Block/Carousel/CarouselCard.vue | 41 +++++++++++------ components/Carousel/CarouselControls.vue | 7 +-- components/Carousel/useCarousel.ts | 17 ++++++++ 4 files changed, 74 insertions(+), 42 deletions(-) diff --git a/components/Block/Carousel/Carousel.vue b/components/Block/Carousel/Carousel.vue index 05da7134..0bac658d 100644 --- a/components/Block/Carousel/Carousel.vue +++ b/components/Block/Carousel/Carousel.vue @@ -26,17 +26,18 @@ onMounted(async () => { - diff --git a/components/Carousel/CarouselContent.vue b/components/Carousel/CarouselContent.vue index 66006878..4e5a8b26 100644 --- a/components/Carousel/CarouselContent.vue +++ b/components/Carousel/CarouselContent.vue @@ -48,4 +48,10 @@ const { carouselRef, orientation } = useCarousel(); linear-gradient(to left, transparent, white var(--buff) calc(100% - var(--buff)), transparent); mask-composite: intersect; } + +@media (max-width: 768px) { + .carousel-content.horizontal { + margin-left: 0; + } +} From 8ba5bd857281a1fbf4521e8a212369b2c7322b35 Mon Sep 17 00:00:00 2001 From: Lindsey Zylstra Date: Tue, 12 Nov 2024 19:45:49 -0800 Subject: [PATCH 11/29] Masonry Grid and Small Carousel Update --- components/Block/Carousel/Carousel.vue | 11 +++-- components/Block/MasonryGrid/MasonryGrid.vue | 37 ++++++++-------- .../Block/MasonryGrid/MasonryGridCard.vue | 44 ++++++++++++++----- 3 files changed, 60 insertions(+), 32 deletions(-) diff --git a/components/Block/Carousel/Carousel.vue b/components/Block/Carousel/Carousel.vue index 5ac26722..0b9dabec 100644 --- a/components/Block/Carousel/Carousel.vue +++ b/components/Block/Carousel/Carousel.vue @@ -103,13 +103,18 @@ onMounted(async () => { } } &__controls { - position: absolute; - top: 250px; + position: relative; + justify-content: center; left: 0; right: 0; display: flex; - justify-content: center; gap: 30%; + bottom: 80px; + top: auto; + @media (max-width: 1704px) { + bottom: 60px; + top: auto; + } @media (max-width: 847px) { bottom: 40px; top: auto; diff --git a/components/Block/MasonryGrid/MasonryGrid.vue b/components/Block/MasonryGrid/MasonryGrid.vue index d401b793..00e8a8f1 100644 --- a/components/Block/MasonryGrid/MasonryGrid.vue +++ b/components/Block/MasonryGrid/MasonryGrid.vue @@ -39,41 +39,42 @@ const limitedCards = computed(() => { diff --git a/components/Block/MasonryGrid/MasonryGridCard.vue b/components/Block/MasonryGrid/MasonryGridCard.vue index 3b5f6f25..247e6258 100644 --- a/components/Block/MasonryGrid/MasonryGridCard.vue +++ b/components/Block/MasonryGrid/MasonryGridCard.vue @@ -32,14 +32,17 @@ const { data: cardData } = useAsyncData(`masonry-grid-card-${props.uuid}`, () => overflow: hidden; position: relative; height: 290px; + width: 100%; transition: transform 0.3s ease; &.single-card { - width: 290px; // Single card width + min-width: 290px; + flex-grow: 1; } &.double-card { - width: 500px; // Double card width + min-width: 500px; + flex-grow: 2; } img { @@ -58,32 +61,51 @@ const { data: cardData } = useAsyncData(`masonry-grid-card-${props.uuid}`, () => } .title { - position: relative; + position: absolute; + top: 0; + left: 0; z-index: 2; + background-color: rgba(255, 255, 255, 0.8); padding: 8px; border-radius: 4px; margin: 8px; font-size: 16px; + font-weight: bold; } } -@media (max-width: 1024px) { + +@media (max-width: 911px) { .masonry-card-content { - &.single-card { - width: 200px; // Adjust width for smaller screens + &.double-card { + grid-column: span 2; + width: 100%; } + } +} +@media (max-width: 819px) { + .masonry-card-content { &.double-card { - width: 350px; // Adjust width for smaller screens + grid-column: span 1; + } + + &.single-card { + min-width: 250px; } } } + @media (max-width: 768px) { .masonry-card-content { height: 180px; - width: 100%; - } - img { - display: none; + min-width: 100%; + &.single-card { + min-width: 100px; + } + + &.double-card { + min-width: 250px; + } } } From 1c8b7522d8339d3ee93f11a971013eb612f6854e Mon Sep 17 00:00:00 2001 From: Lindsey Zylstra Date: Wed, 13 Nov 2024 16:09:05 -0800 Subject: [PATCH 12/29] Wall of Love --- assets/svg/placeholder-avatar.svg | 13 ++ assets/svg/star.svg | 3 + components/Base/Block.vue | 2 + components/Block/WallOfLove/Testimonials.vue | 158 +++++++++++++++++++ components/Block/WallOfLove/WallOfLove.vue | 117 ++++++++++++++ types/schema/blocks/block-testimonials.ts | 11 ++ types/schema/blocks/block-wall-of-love.ts | 11 ++ types/schema/blocks/block.ts | 10 +- types/schema/blocks/index.ts | 2 + types/schema/schema.ts | 4 + 10 files changed, 329 insertions(+), 2 deletions(-) create mode 100644 assets/svg/placeholder-avatar.svg create mode 100644 assets/svg/star.svg create mode 100644 components/Block/WallOfLove/Testimonials.vue create mode 100644 components/Block/WallOfLove/WallOfLove.vue create mode 100644 types/schema/blocks/block-testimonials.ts create mode 100644 types/schema/blocks/block-wall-of-love.ts diff --git a/assets/svg/placeholder-avatar.svg b/assets/svg/placeholder-avatar.svg new file mode 100644 index 00000000..7b675da3 --- /dev/null +++ b/assets/svg/placeholder-avatar.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/assets/svg/star.svg b/assets/svg/star.svg new file mode 100644 index 00000000..70dd551c --- /dev/null +++ b/assets/svg/star.svg @@ -0,0 +1,3 @@ + + + diff --git a/components/Base/Block.vue b/components/Base/Block.vue index b7221803..2ced5632 100644 --- a/components/Base/Block.vue +++ b/components/Base/Block.vue @@ -23,6 +23,8 @@ const components: Record> = { block_carousel_cards: resolveComponent('BlockCarouselCard'), block_masonry_grid: resolveComponent('BlockMasonryGrid'), block_masonry_grid_card: resolveComponent('BlockMasonryGridCard'), + block_wall_of_love: resolveComponent('BlockWallOfLove'), + testimonials: resolveComponent('BlockTestimonials'), block_code: resolveComponent('BlockCode'), block_columns: resolveComponent('BlockColumns'), block_cta: resolveComponent('BlockCta'), diff --git a/components/Block/WallOfLove/Testimonials.vue b/components/Block/WallOfLove/Testimonials.vue new file mode 100644 index 00000000..9f0929f4 --- /dev/null +++ b/components/Block/WallOfLove/Testimonials.vue @@ -0,0 +1,158 @@ + + + + + diff --git a/components/Block/WallOfLove/WallOfLove.vue b/components/Block/WallOfLove/WallOfLove.vue new file mode 100644 index 00000000..8803ac23 --- /dev/null +++ b/components/Block/WallOfLove/WallOfLove.vue @@ -0,0 +1,117 @@ + + + + + diff --git a/types/schema/blocks/block-testimonials.ts b/types/schema/blocks/block-testimonials.ts new file mode 100644 index 00000000..2ca7a790 --- /dev/null +++ b/types/schema/blocks/block-testimonials.ts @@ -0,0 +1,11 @@ +export interface BlockTestimonials { + id: string; + sort: number; + name: string; + company: string | null; + role: string | null; + quote: string; + logo: string | File | null; + avatar: string | File | null; + avatar_url: string | null; +} diff --git a/types/schema/blocks/block-wall-of-love.ts b/types/schema/blocks/block-wall-of-love.ts new file mode 100644 index 00000000..fd80b0c2 --- /dev/null +++ b/types/schema/blocks/block-wall-of-love.ts @@ -0,0 +1,11 @@ +export interface BlockWallOfLove { + id: string; + heading: string | null; + testimonials: BlockWallOfLoveTestimonials[]; +} + +export interface BlockWallOfLoveTestimonials { + id: string; + block_wall_of_love_id: string; + testimonials_id: string; +} diff --git a/types/schema/blocks/block.ts b/types/schema/blocks/block.ts index 4ce9d157..4289be3f 100644 --- a/types/schema/blocks/block.ts +++ b/types/schema/blocks/block.ts @@ -30,6 +30,8 @@ import type { BlockCarousel } from './block-carousel.js'; import type { BlockCarouselCards } from './block-carousel-cards.js'; import type { BlockMasonryGrid } from './block-masonry-grid.js'; import type { BlockMasonryGridCard } from './block-masonry-grid-card.js'; +import type { BlockWallOfLove } from './block-wall-of-love.js'; +import type { BlockTestimonials } from './block-testimonials.js'; export type BlockType = | 'block_accordion_group' @@ -64,7 +66,9 @@ export type BlockType = | 'block_carousel' | 'block_carousel_cards' | 'block_masonry_grid' - | 'block_masonry_grid_card'; + | 'block_masonry_grid_card' + | 'testimonials' + | 'block_wall_of_love'; export type Block = | BlockAccordion @@ -99,4 +103,6 @@ export type Block = | BlockCarousel | BlockCarouselCards | BlockMasonryGrid - | BlockMasonryGridCard; + | BlockMasonryGridCard + | BlockTestimonials + | BlockWallOfLove; diff --git a/types/schema/blocks/index.ts b/types/schema/blocks/index.ts index 94bc5038..b7c2d4c7 100644 --- a/types/schema/blocks/index.ts +++ b/types/schema/blocks/index.ts @@ -32,3 +32,5 @@ export type * from './block-carousel.js'; export type * from './block-carousel-cards.js'; export type * from './block-masonry-grid.js'; export type * from './block-masonry-grid-card.js'; +export type * from './block-testimonials.js'; +export type * from './block-wall-of-love.js'; diff --git a/types/schema/schema.ts b/types/schema/schema.ts index a4896596..0b0e34b0 100644 --- a/types/schema/schema.ts +++ b/types/schema/schema.ts @@ -44,6 +44,8 @@ import type { BlockCarouselCards, BlockMasonryGrid, BlockMasonryGridCard, + BlockTestimonials, + BlockWallOfLove, } from './blocks/index.js'; import type { Form, @@ -139,6 +141,8 @@ export interface Schema { block_carousel_cards: BlockCarouselCards[]; block_masonry_grid: BlockMasonryGrid[]; block_masonry_grid_card: BlockMasonryGridCard[]; + block_wall_of_love: BlockWallOfLove[]; + testimonials: BlockTestimonials[]; // Meta globals: Globals; From 9ed79fc09eccd3b9f0fb92c169c7a3cd3d033312 Mon Sep 17 00:00:00 2001 From: Lindsey Zylstra Date: Wed, 13 Nov 2024 17:04:34 -0800 Subject: [PATCH 13/29] Cleanup Carousel, MasonryGrid, and Wall of Love --- components/Block/Carousel/Carousel.vue | 24 +------- components/Block/MasonryGrid/MasonryGrid.vue | 42 ++----------- .../Block/MasonryGrid/MasonryGridCard.vue | 61 ++++--------------- components/Block/WallOfLove/Testimonials.vue | 38 +++++++++++- components/Block/WallOfLove/WallOfLove.vue | 10 +-- 5 files changed, 61 insertions(+), 114 deletions(-) diff --git a/components/Block/Carousel/Carousel.vue b/components/Block/Carousel/Carousel.vue index 0b9dabec..3a8f0a76 100644 --- a/components/Block/Carousel/Carousel.vue +++ b/components/Block/Carousel/Carousel.vue @@ -103,31 +103,13 @@ onMounted(async () => { } } &__controls { - position: relative; - justify-content: center; - left: 0; - right: 0; display: flex; - gap: 30%; - bottom: 80px; - top: auto; - @media (max-width: 1704px) { - bottom: 60px; - top: auto; - } - @media (max-width: 847px) { - bottom: 40px; - top: auto; - } - @media (max-width: 768px) { - top: auto; - bottom: 20px; - gap: 60%; - } + justify-content: center; + gap: 60px; + margin-top: 40px; } &__button { - z-index: 10; color: #333; padding: 8px; &__svg { diff --git a/components/Block/MasonryGrid/MasonryGrid.vue b/components/Block/MasonryGrid/MasonryGrid.vue index 00e8a8f1..36acec60 100644 --- a/components/Block/MasonryGrid/MasonryGrid.vue +++ b/components/Block/MasonryGrid/MasonryGrid.vue @@ -38,43 +38,9 @@ const limitedCards = computed(() => { diff --git a/components/Block/MasonryGrid/MasonryGridCard.vue b/components/Block/MasonryGrid/MasonryGridCard.vue index 247e6258..2ab090e5 100644 --- a/components/Block/MasonryGrid/MasonryGridCard.vue +++ b/components/Block/MasonryGrid/MasonryGridCard.vue @@ -32,23 +32,19 @@ const { data: cardData } = useAsyncData(`masonry-grid-card-${props.uuid}`, () => overflow: hidden; position: relative; height: 290px; - width: 100%; transition: transform 0.3s ease; &.single-card { - min-width: 290px; - flex-grow: 1; + flex: 1 1 290px; + margin: 0 1% 1% 0; } &.double-card { - min-width: 500px; - flex-grow: 2; + flex: 2 1 500px; + margin: 0 1% 1% 0; } img { - position: absolute; - top: 0; - left: 0; width: 100%; height: 100%; object-fit: cover; @@ -64,48 +60,13 @@ const { data: cardData } = useAsyncData(`masonry-grid-card-${props.uuid}`, () => position: absolute; top: 0; left: 0; - z-index: 2; - background-color: rgba(255, 255, 255, 0.8); - padding: 8px; - border-radius: 4px; - margin: 8px; - font-size: 16px; - font-weight: bold; - } -} - -@media (max-width: 911px) { - .masonry-card-content { - &.double-card { - grid-column: span 2; - width: 100%; - } - } -} - -@media (max-width: 819px) { - .masonry-card-content { - &.double-card { - grid-column: span 1; - } - - &.single-card { - min-width: 250px; - } - } -} - -@media (max-width: 768px) { - .masonry-card-content { - height: 180px; - min-width: 100%; - &.single-card { - min-width: 100px; - } - - &.double-card { - min-width: 250px; - } + padding: 28px; + color: var(--Foreground-Normal, #455466); + font-family: Poppins; + font-size: 24px; + font-style: normal; + font-weight: 600; + line-height: 32px; } } diff --git a/components/Block/WallOfLove/Testimonials.vue b/components/Block/WallOfLove/Testimonials.vue index 9f0929f4..1a7c00e8 100644 --- a/components/Block/WallOfLove/Testimonials.vue +++ b/components/Block/WallOfLove/Testimonials.vue @@ -79,6 +79,14 @@ const logoImageUrl = computed(() => { flex-direction: column; gap: 32px; + @media (max-width: 768px) { + padding: 24px; + } + + @media (max-width: 480px) { + padding: 16px; + } + .header { display: flex; align-items: center; @@ -90,6 +98,11 @@ const logoImageUrl = computed(() => { height: 50px; border-radius: 50%; margin-right: 12px; + + @media (max-width: 480px) { + width: 40px; + height: 40px; + } } .info { @@ -98,18 +111,28 @@ const logoImageUrl = computed(() => { strong { font-size: 1.1em; + + @media (max-width: 480px) { + font-size: 1em; + } } .role { font-size: 0.9em; color: #666; + + @media (max-width: 480px) { + font-size: 0.8em; + } } } } + .quote { margin-bottom: 12px; font-style: italic; flex-grow: 1; + :deep(> *) { quotes: auto; @@ -134,8 +157,16 @@ const logoImageUrl = computed(() => { .company-logo { max-height: 40px; - max-width: 200px; + max-width: 150px; width: auto; + + @media (max-width: 768px) { + max-width: 150px; + } + + @media (max-width: 480px) { + max-width: 100px; + } } .logo-placeholder { @@ -151,6 +182,11 @@ const logoImageUrl = computed(() => { .star-icon { width: 16px; height: 16px; + + @media (max-width: 480px) { + width: 14px; + height: 14px; + } } } } diff --git a/components/Block/WallOfLove/WallOfLove.vue b/components/Block/WallOfLove/WallOfLove.vue index 8803ac23..2c6224e4 100644 --- a/components/Block/WallOfLove/WallOfLove.vue +++ b/components/Block/WallOfLove/WallOfLove.vue @@ -62,10 +62,12 @@ const toggleShowAll = () => { align-items: center; .wall-heading { - margin-bottom: 16px; - text-align: center; - font-size: 1.5em; - font-weight: bold; + color: var(--Foreground-Normal, #455466); + font-family: Poppins; + font-size: 24px; + font-style: normal; + font-weight: 600; + line-height: 32px; } .testimonial-container { From c2552ffb17eacad80b3101372f075dc433375141 Mon Sep 17 00:00:00 2001 From: Lindsey Zylstra Date: Thu, 14 Nov 2024 12:47:11 -0800 Subject: [PATCH 14/29] Logo ticker updates and carousel buttons --- components/Block/Carousel/Carousel.vue | 2 +- components/LogoDoubleTicker.vue | 115 ++++--------------------- components/LogoTicker.vue | 95 +++----------------- package.json | 3 +- pnpm-lock.yaml | 50 ++++------- 5 files changed, 49 insertions(+), 216 deletions(-) diff --git a/components/Block/Carousel/Carousel.vue b/components/Block/Carousel/Carousel.vue index 3a8f0a76..9c5d56b7 100644 --- a/components/Block/Carousel/Carousel.vue +++ b/components/Block/Carousel/Carousel.vue @@ -106,7 +106,7 @@ onMounted(async () => { display: flex; justify-content: center; gap: 60px; - margin-top: 40px; + margin-top: 65px; } &__button { diff --git a/components/LogoDoubleTicker.vue b/components/LogoDoubleTicker.vue index 836133bf..2ea43b9c 100644 --- a/components/LogoDoubleTicker.vue +++ b/components/LogoDoubleTicker.vue @@ -1,8 +1,7 @@ diff --git a/components/LogoTicker.vue b/components/LogoTicker.vue index 8dd0c84f..48d62b66 100644 --- a/components/LogoTicker.vue +++ b/components/LogoTicker.vue @@ -1,112 +1,41 @@ diff --git a/package.json b/package.json index c99cc0a7..a980547b 100644 --- a/package.json +++ b/package.json @@ -60,6 +60,7 @@ "dependencies": { "embla-carousel": "^8.3.1", "embla-carousel-class-names": "^8.3.1", - "embla-carousel-vue": "^8.3.1" + "embla-carousel-vue": "^8.3.1", + "vue3-marquee": "^4.2.2" } } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 58b90a99..30d40960 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -16,13 +16,10 @@ importers: version: 8.3.1(embla-carousel@8.3.1) embla-carousel-vue: specifier: ^8.3.1 - version: 8.3.1(vue@3.5.3(typescript@5.5.4)) - radix-vue: - specifier: ^1.9.8 - version: 1.9.8(vue@3.5.12(typescript@5.5.4)) - reka-ui: - specifier: 1.0.0-alpha.2 - version: 1.0.0-alpha.2(vue@3.5.12(typescript@5.5.4)) + version: 8.3.1(vue@3.5.12(typescript@5.5.4)) + vue3-marquee: + specifier: ^4.2.2 + version: 4.2.2(vue@3.5.12(typescript@5.5.4)) devDependencies: '@directus/format-title': specifier: 11.0.0 @@ -123,6 +120,9 @@ importers: prettier: specifier: 3.3.3 version: 3.3.3 + radix-vue: + specifier: ^1.9.8 + version: 1.9.8(vue@3.5.12(typescript@5.5.4)) sass: specifier: 1.80.4 version: 1.80.4 @@ -4341,11 +4341,6 @@ packages: resolution: {integrity: sha512-iETxpjK6YoRWJG5o6hXLwvjYAoW+FEZn9os0PD/b6AP6xQwsa/Y7lCVgIixBbUPMfhu+i2LtdeAqVTgGlQarfA==} hasBin: true - reka-ui@1.0.0-alpha.2: - resolution: {integrity: sha512-RYBeKo0Nm2+JRLsR+KDvuoJlMFn3stz2juWhoxDZC1y1xcv0nXT0DoS40eKuUnrMD4hxbeU4fRDU/IZxAonoSw==} - peerDependencies: - vue: '>= 3.2.0' - require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} @@ -5148,6 +5143,12 @@ packages: peerDependencies: typescript: '>=5.0.0' + vue3-marquee@4.2.2: + resolution: {integrity: sha512-FeFvGUVInKfFilXFcnl8sDRBJBZCZSNLlQDquJErB9db6W2xICRVqbRV/jtdzsEP0rftarLQhx9MeEAU0+TPuQ==} + engines: {node: '>=12'} + peerDependencies: + vue: ^3.2 + vue@3.5.12: resolution: {integrity: sha512-CLVZtXtn2ItBIi/zHZ0Sg1Xkb7+PU32bJJ8Bmy7ts3jxXTcbfsEfBivFYYWz1Hur+lalqGAh65Coin0r+HRUfg==} peerDependencies: @@ -8220,11 +8221,11 @@ snapshots: dependencies: embla-carousel: 8.3.1 - embla-carousel-vue@8.3.1(vue@3.5.3(typescript@5.5.4)): + embla-carousel-vue@8.3.1(vue@3.5.12(typescript@5.5.4)): dependencies: embla-carousel: 8.3.1 embla-carousel-reactive-utils: 8.3.1(embla-carousel@8.3.1) - vue: 3.5.3(typescript@5.5.4) + vue: 3.5.12(typescript@5.5.4) embla-carousel@8.3.1: {} @@ -10380,23 +10381,6 @@ snapshots: regexp-tree@0.1.27: {} - reka-ui@1.0.0-alpha.2(vue@3.5.12(typescript@5.5.4)): - dependencies: - '@floating-ui/dom': 1.6.11 - '@floating-ui/vue': 1.1.5(vue@3.5.12(typescript@5.5.4)) - '@internationalized/date': 3.5.6 - '@internationalized/number': 3.5.4 - '@tanstack/vue-virtual': 3.10.8(vue@3.5.12(typescript@5.5.4)) - '@vueuse/core': 11.1.0(vue@3.5.12(typescript@5.5.4)) - '@vueuse/shared': 11.1.0(vue@3.5.12(typescript@5.5.4)) - aria-hidden: 1.2.4 - defu: 6.1.4 - fast-deep-equal: 3.1.3 - nanoid: 5.0.8 - vue: 3.5.12(typescript@5.5.4) - transitivePeerDependencies: - - '@vue/composition-api' - require-directory@2.1.1: {} require-from-string@2.0.2: {} @@ -11305,6 +11289,10 @@ snapshots: semver: 7.6.3 typescript: 5.5.4 + vue3-marquee@4.2.2(vue@3.5.12(typescript@5.5.4)): + dependencies: + vue: 3.5.12(typescript@5.5.4) + vue@3.5.12(typescript@5.5.4): dependencies: '@vue/compiler-dom': 3.5.12 From 0ae4afaa56faeeb697df64764d0aa1f4e09fc89d Mon Sep 17 00:00:00 2001 From: Lindsey Zylstra Date: Thu, 14 Nov 2024 15:45:14 -0800 Subject: [PATCH 15/29] Add links to masonry grid and adjust testimonials --- .../Block/MasonryGrid/MasonryGridCard.vue | 69 +++++++++++++++++-- components/Block/WallOfLove/Testimonials.vue | 2 +- .../schema/blocks/block-masonry-grid-card.ts | 10 ++- 3 files changed, 75 insertions(+), 6 deletions(-) diff --git a/components/Block/MasonryGrid/MasonryGridCard.vue b/components/Block/MasonryGrid/MasonryGridCard.vue index 2ab090e5..9e4db29a 100644 --- a/components/Block/MasonryGrid/MasonryGridCard.vue +++ b/components/Block/MasonryGrid/MasonryGridCard.vue @@ -1,5 +1,6 @@ @@ -64,9 +100,34 @@ const { data: cardData } = useAsyncData(`masonry-grid-card-${props.uuid}`, () => color: var(--Foreground-Normal, #455466); font-family: Poppins; font-size: 24px; - font-style: normal; font-weight: 600; line-height: 32px; + + a { + color: inherit; + text-decoration: none; + transition: color 0.3s ease; + + &:hover { + color: var(--primary-500); + } + } + } + + .description { + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + background: rgba(255, 255, 255, 0.8); + padding: 12px 16px; + border-radius: 6px; + color: #6b7b8c; + font-size: 16px; + font-family: 'Poppins', sans-serif; + line-height: 1.5; + text-align: center; + width: 80%; } } diff --git a/components/Block/WallOfLove/Testimonials.vue b/components/Block/WallOfLove/Testimonials.vue index 1a7c00e8..71d24acf 100644 --- a/components/Block/WallOfLove/Testimonials.vue +++ b/components/Block/WallOfLove/Testimonials.vue @@ -91,7 +91,7 @@ const logoImageUrl = computed(() => { display: flex; align-items: center; margin-bottom: 12px; - justify-content: center; + justify-content: left; .avatar { width: 50px; diff --git a/types/schema/blocks/block-masonry-grid-card.ts b/types/schema/blocks/block-masonry-grid-card.ts index c185b337..5f23b824 100644 --- a/types/schema/blocks/block-masonry-grid-card.ts +++ b/types/schema/blocks/block-masonry-grid-card.ts @@ -1,8 +1,16 @@ +import type { Resource } from '../content'; +import type { Page } from '../routes'; +import type { File } from '../system'; + export interface BlockMasonryGridCard { id: string; sort: number; title: string; description: string | null; image: string | File | null; - type: 'single' | 'double' | null; + type: 'pages' | 'resources' | 'external' | null; + size: 'single' | 'double' | null; + external_url: string | null; + page: string | Page | null; + resource: string | Resource | null; } From 1b92f4641e240d7b4cf7f976f3f6781e4f41ee54 Mon Sep 17 00:00:00 2001 From: Lindsey Zylstra Date: Fri, 15 Nov 2024 07:58:15 -0800 Subject: [PATCH 16/29] Logo Ticker updates --- components/LogoDoubleTicker.vue | 10 ++++++++-- components/LogoTicker.vue | 2 +- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/components/LogoDoubleTicker.vue b/components/LogoDoubleTicker.vue index 2ea43b9c..7c516e69 100644 --- a/components/LogoDoubleTicker.vue +++ b/components/LogoDoubleTicker.vue @@ -23,7 +23,7 @@ const bottomLogoArray = computed(() => {