From 441b487f35c6e3e95285db62ee94d3bb0f78ea95 Mon Sep 17 00:00:00 2001 From: Daniel McGee <134719124+mcgeeandme@users.noreply.github.com> Date: Wed, 1 Jul 2026 21:50:40 -0400 Subject: [PATCH] Attempting to theme the shopify elements like the vie elements --- webapp/src/views/Store.vue | 292 +++++++++++++++++++++---------------- 1 file changed, 168 insertions(+), 124 deletions(-) diff --git a/webapp/src/views/Store.vue b/webapp/src/views/Store.vue index ab1621e..4a3c4c0 100644 --- a/webapp/src/views/Store.vue +++ b/webapp/src/views/Store.vue @@ -23,7 +23,8 @@ - + + - + + T-shirts, stickers, yard signs, and more — proceeds support the anti-surveillance movement. + + + + + + + + + + - + + @@ -231,6 +254,7 @@ import { ref, onMounted, computed, watch } from 'vue'; import type { Ref } from 'vue'; import { useRoute, useRouter } from 'vue-router'; +import { useTheme } from 'vuetify'; import DefaultLayout from '@/layouts/DefaultLayout.vue'; import Hero from '@/components/layout/Hero.vue'; @@ -268,130 +292,144 @@ const COLLECTIONS: Record> = { 'Tech Accessories': { 'Phone Cases': '519708147994', 'Laptop Sleeves': '519708213530', - }, + }, 'Featured': { - 'No ALPRs': '520528560410'}, + 'No ALPRs': '520528560410', + }, }; -const SHOPIFY_OPTIONS = { - product: { - styles: { - product: { - '@media (min-width: 601px)': { - 'max-width': 'calc(33% - 20px)', - 'margin-left': '20px', - 'margin-bottom': '50px', - width: 'calc(33% - 20px)', +// Modal text uses a light-on-dark or dark-on-light palette depending on the +// active Vuetify theme. The product grid tiles always render on the SDK's own +// dark card surface so their text stays white regardless of theme. +function buildShopifyOptions(dark: boolean) { + const modalText = dark ? '#e0e0e0' : '#4c4c4c'; + const modalText2 = dark ? '#b0b0b0' : '#6b6b6b'; + + return { + product: { + styles: { + product: { + '@media (min-width: 601px)': { + 'max-width': 'calc(33% - 20px)', + 'margin-left': '20px', + 'margin-bottom': '50px', + width: 'calc(33% - 20px)', + }, + }, + title: { 'font-family': 'Raleway, sans-serif', 'font-size': '17px', color: '#ffffff' }, + button: { + 'font-family': 'Raleway, sans-serif', + 'font-weight': 'bold', + 'font-size': '16px', + 'padding-top': '16px', + 'padding-bottom': '16px', + ':hover': { 'background-color': '#0081ac', color: '#ffffff' }, + 'background-color': 'rgb(18, 151, 195)', + color: '#ffffff', + ':focus': { 'background-color': '#0081ac', color: '#ffffff' }, + 'border-radius': '4px', + 'padding-left': '20px', + 'padding-right': '20px', + }, + quantityInput: { 'font-size': '16px', 'padding-top': '16px', 'padding-bottom': '16px' }, + price: { 'font-family': 'Raleway, sans-serif', 'font-size': '17px', color: '#ffffff' }, + compareAt: { 'font-family': 'Raleway, sans-serif', 'font-size': '14.45px', color: '#ffffff' }, + unitPrice: { 'font-family': 'Raleway, sans-serif', 'font-size': '14.45px', color: '#ffffff' }, + description: { 'font-family': 'Raleway, sans-serif' }, + }, + buttonDestination: 'modal', + contents: { button: false, options: false }, + isButton: true, + text: { button: 'View Item' }, + googleFonts: ['Raleway'], + }, + productSet: { + styles: { + products: { '@media (min-width: 601px)': { 'margin-left': '-20px' } }, + }, + text: { + nextPageButton: 'Load more', + }, + }, + modalProduct: { + contents: { img: false, imgWithCarousel: true, button: false, buttonWithQuantity: true }, + styles: { + product: { '@media (min-width: 601px)': { 'max-width': '100%', 'margin-left': '0px', 'margin-bottom': '0px' } }, + button: { + 'font-family': 'Raleway, sans-serif', + 'font-weight': 'bold', + 'font-size': '16px', + 'padding-top': '16px', + 'padding-bottom': '16px', + ':hover': { 'background-color': '#0081ac', color: '#ffffff' }, + 'background-color': 'rgb(18, 151, 195)', + color: '#ffffff', + ':focus': { 'background-color': '#0081ac', color: '#ffffff' }, + 'border-radius': '4px', + 'padding-left': '20px', + 'padding-right': '20px', + }, + quantityInput: { 'font-size': '16px', 'padding-top': '16px', 'padding-bottom': '16px' }, + title: { 'font-family': 'Raleway, sans-serif', 'font-weight': 'bold', 'font-size': '26px', color: modalText }, + price: { 'font-family': 'Raleway, sans-serif', 'font-weight': 'normal', 'font-size': '18px', color: modalText }, + compareAt: { 'font-family': 'Raleway, sans-serif', 'font-weight': 'normal', 'font-size': '15.3px', color: modalText2 }, + unitPrice: { 'font-family': 'Raleway, sans-serif', 'font-weight': 'normal', 'font-size': '15.3px', color: modalText2 }, + description: { 'font-family': 'Raleway, sans-serif', 'font-weight': 'normal', 'font-size': '14px', color: modalText2 }, + }, + googleFonts: ['Raleway'], + text: { button: 'Add to cart' }, + }, + option: { + styles: { + label: { 'font-family': 'Raleway, sans-serif' }, + select: { 'font-family': 'Raleway, sans-serif' }, + }, + googleFonts: ['Raleway'], + }, + cart: { + styles: { + button: { + 'font-family': 'Raleway, sans-serif', + 'font-weight': 'bold', + 'font-size': '16px', + 'padding-top': '16px', + 'padding-bottom': '16px', + ':hover': { 'background-color': '#0081ac', color: '#ffffff' }, + 'background-color': 'rgb(18, 151, 195)', + color: '#ffffff', + ':focus': { 'background-color': '#0081ac', color: '#ffffff' }, + 'border-radius': '4px', }, }, - title: { 'font-family': 'Raleway, sans-serif', 'font-size': '17px', color: '#ffffff' }, - button: { - 'font-family': 'Raleway, sans-serif', - 'font-weight': 'bold', - 'font-size': '16px', - 'padding-top': '16px', - 'padding-bottom': '16px', - ':hover': { 'background-color': '#0081ac', color: '#ffffff' }, - 'background-color': 'rgb(18, 151, 195)', - color: '#ffffff', - ':focus': { 'background-color': '#0081ac', color: '#ffffff' }, - 'border-radius': '0px', - 'padding-left': '20px', - 'padding-right': '20px', + text: { + total: 'Subtotal', + notice: 'Shipping and discount codes are added at checkout - powered by Agora Markets', + button: 'Checkout', + noteDescription: 'Additional Information for the deflock.org team', }, - quantityInput: { 'font-size': '16px', 'padding-top': '16px', 'padding-bottom': '16px' }, - price: { 'font-family': 'Raleway, sans-serif', 'font-size': '17px', color: '#ffffff' }, - compareAt: { 'font-family': 'Raleway, sans-serif', 'font-size': '14.45px', color: '#ffffff' }, - unitPrice: { 'font-family': 'Raleway, sans-serif', 'font-size': '14.45px', color: '#ffffff' }, - description: { 'font-family': 'Raleway, sans-serif' }, + googleFonts: ['Raleway'], }, - buttonDestination: 'modal', - contents: { button: false, options: false }, - isButton: true, - text: { button: 'View Item' }, - googleFonts: ['Raleway'], - }, - productSet: { - styles: { - products: { '@media (min-width: 601px)': { 'margin-left': '-20px' } }, - }, - text: { - nextPageButton: 'Load more', - }, - }, - modalProduct: { - contents: { img: false, imgWithCarousel: true, button: false, buttonWithQuantity: true }, - styles: { - product: { '@media (min-width: 601px)': { 'max-width': '100%', 'margin-left': '0px', 'margin-bottom': '0px' } }, - button: { - 'font-family': 'Raleway, sans-serif', - 'font-weight': 'bold', - 'font-size': '16px', - 'padding-top': '16px', - 'padding-bottom': '16px', - ':hover': { 'background-color': '#0081ac', color: '#ffffff' }, - 'background-color': 'rgb(18, 151, 195)', - color: '#ffffff', - ':focus': { 'background-color': '#0081ac', color: '#ffffff' }, - 'border-radius': '0px', - 'padding-left': '20px', - 'padding-right': '20px', + toggle: { + styles: { + toggle: { + 'font-family': 'Raleway, sans-serif', + 'font-weight': 'bold', + 'background-color': 'rgb(18, 151, 195)', + color: '#ffffff', + ':hover': { 'background-color': '#0081ac', color: '#ffffff' }, + ':focus': { 'background-color': '#0081ac', color: '#ffffff' }, + }, + count: { 'font-size': '16px' }, }, - quantityInput: { 'font-size': '16px', 'padding-top': '16px', 'padding-bottom': '16px' }, - title: { 'font-family': 'Raleway, sans-serif', 'font-weight': 'bold', 'font-size': '26px', color: '#4c4c4c' }, - price: { 'font-family': 'Raleway, sans-serif', 'font-weight': 'normal', 'font-size': '18px', color: '#4c4c4c' }, - compareAt: { 'font-family': 'Raleway, sans-serif', 'font-weight': 'normal', 'font-size': '15.3px', color: '#4c4c4c' }, - unitPrice: { 'font-family': 'Raleway, sans-serif', 'font-weight': 'normal', 'font-size': '15.3px', color: '#4c4c4c' }, - description: { 'font-family': 'Raleway, sans-serif', 'font-weight': 'normal', 'font-size': '14px', color: '#4c4c4c' }, + googleFonts: ['Raleway'], }, - googleFonts: ['Raleway'], - text: { button: 'Add to cart' }, - }, - option: { - styles: { - label: { 'font-family': 'Raleway, sans-serif' }, - select: { 'font-family': 'Raleway, sans-serif' }, - }, - googleFonts: ['Raleway'], - }, - cart: { - styles: { - button: { - 'font-family': 'Raleway, sans-serif', - 'font-weight': 'bold', - 'font-size': '16px', - 'padding-top': '16px', - 'padding-bottom': '16px', - ':hover': { 'background-color': '#0081ac', color: '#ffffff' }, - 'background-color': 'rgb(18, 151, 195)', - color: '#ffffff', - ':focus': { 'background-color': '#0081ac', color: '#ffffff' }, - 'border-radius': '0px', - }, - }, - text: { - total: 'Subtotal', - notice: 'Shipping and discount codes are added at checkout - powered by Agora Markets', - button: 'Checkout', - noteDescription: 'Additional Information for the deflock.org team', - }, - googleFonts: ['Raleway'], - }, - toggle: { - styles: { - toggle: { - 'font-family': 'Raleway, sans-serif', - 'font-weight': 'bold', - 'background-color': 'rgb(18, 151, 195)', - color: '#ffffff', - ':hover': { 'background-color': '#0081ac', color: '#ffffff' }, - ':focus': { 'background-color': '#0081ac', color: '#ffffff' }, - }, - count: { 'font-size': '16px' }, - }, - googleFonts: ['Raleway'], - }, -}; + }; +} + +// ── Theme ─────────────────────────────────────────────────────────────────────── + +const theme = useTheme(); +const isDark = computed(() => theme.global.current.value.dark); // ── Tabs ──────────────────────────────────────────────────────────────────────── @@ -424,9 +462,9 @@ const collectionSelectItems = computed(() => { const collectionId = ref((route.query.category as string) || ALL_COLLECTION_ID); const shopifyContainer = ref(null); +const shopifyReady = ref(false); // Sync tab + category to URL so back/forward/refresh restores state. -// Guard prevents re-pushing when the ref update came FROM the router. watch([activeTab, collectionId], ([tab, category]) => { const currentTab = (route.query.tab as string) || 'shop'; const currentCategory = (route.query.category as string) || ALL_COLLECTION_ID; @@ -459,6 +497,7 @@ function initShopify(id: string) { const container = shopifyContainer.value; if (!container) return; + shopifyReady.value = false; container.innerHTML = ''; const client = window.ShopifyBuy.buildClient({ @@ -470,12 +509,20 @@ function initShopify(id: string) { id, node: container, moneyFormat: '%24%7B%7Bamount%7D%7D', - options: SHOPIFY_OPTIONS, + options: buildShopifyOptions(isDark.value), }); + // The SDK renders synchronously into the node before this callback resolves, + // so flipping the flag here reliably hides the skeleton at the right moment. + shopifyReady.value = true; }); - } +// Re-render the Shopify embed whenever the Vuetify theme flips so the modal +// text colours stay readable in both light and dark mode. +watch(isDark, () => { + if (window.ShopifyBuy?.UI) initShopify(collectionId.value); +}); + function loadShopifySDK() { if (window.ShopifyBuy?.UI) { initShopify(collectionId.value); @@ -552,9 +599,6 @@ const getTypeIcon = (type: string): string => const formatDate = (dateString: string) => new Date(dateString).toLocaleDateString('en-US', { year: 'numeric', month: 'short', day: 'numeric' }); -// Watch the container ref so we initialise only once the DOM element exists. -// The `eager` prop on the window item makes it available immediately, but -// watching is more robust than relying on onMounted timing. watch(shopifyContainer, (el) => { if (el) loadShopifySDK(); }, { once: true });
+ T-shirts, stickers, yard signs, and more — proceeds support the anti-surveillance movement. +