Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 0 additions & 8 deletions app/app.vue
Original file line number Diff line number Diff line change
@@ -1,12 +1,4 @@
<script setup lang="ts">
const shopStore = useShopStore()
const cartStore = useCartStore()

await Promise.all([
shopStore.getLocalization(),
cartStore.getCart(),
])

useHead({
titleTemplate: (title) => title ? `${title} · Nitrogen` : 'Nitrogen: A Nuxt Shopify Template',
meta: [
Expand Down
12 changes: 6 additions & 6 deletions app/components/shopify/product-card/product-card-tags.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ const props = defineProps<{
}>()

// Computed
const NewItem = computed(() => isNewItem(props.product?.publishedAt))
const SoldOut = computed(() => isSoldOut(props.product))
const OnSale = computed(() => {
const newItem = computed(() => isNewItem(props.product?.publishedAt))
const soldOut = computed(() => isSoldOut(props.product.availableForSale))
const onSale = computed(() => {
const price = props.product?.priceRange?.minVariantPrice
const compareAtPrice = props.product?.compareAtPriceRange?.minVariantPrice

Expand All @@ -26,19 +26,19 @@ const OnSale = computed(() => {
<template>
<div class="absolute flex gap-2 top-0 left-0 z-10 p-3 pointer-events-none">
<span
v-if="NewItem"
v-if="newItem"
class="px-2 py-0.5 max-w-fit uppercase text-sm bg-blue-50 text-blue-600 border border-blue-500 rounded"
>
New
</span>
<span
v-if="SoldOut"
v-if="soldOut"
class="px-2 py-0.5 max-w-fit uppercase text-sm bg-red-50 text-red-600 border border-red-500 rounded"
>
Sold Out
</span>
<span
v-if="OnSale"
v-if="onSale"
class="px-2 py-0.5 max-w-fit uppercase text-sm bg-yellow-50 text-yellow-600 border border-yellow-500 rounded"
>
Sale
Expand Down
38 changes: 15 additions & 23 deletions app/helpers/shopify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import type {
ProductCollectionSortKeys,
SearchSortKeys,
ProductFilter,
ProductFragment,
MoneyFragment,
VideoFragment,
MediaImageFragment,
Expand Down Expand Up @@ -35,16 +34,11 @@ export const getCollectionSortValues = (sortParam: string | null): {
sortKey: 'BEST_SELLING',
reverse: false,
}
case 'newest':
default:
return {
sortKey: 'CREATED',
reverse: true,
}
default:
return {
sortKey: 'MANUAL',
reverse: false,
}
}
}

Expand Down Expand Up @@ -83,16 +77,16 @@ export const getSearchSortValues = (sortParam: string | null): {
*/
export const getFilterValues = (query: Record<string, any>) => {
const filters: ProductFilter[] = []
const { color, size, productType } = query

if (query.color || query.size || query.productType) {
if (color || size || productType) {
filters.push({
available: true,
})
}

if (query.color) {
const colorValues = query.color.split(',')
colorValues.forEach((color: any) => {
if (color) {
color.split(',').forEach((color: any) => {
filters.push({
variantOption: {
name: 'Color',
Expand All @@ -102,9 +96,8 @@ export const getFilterValues = (query: Record<string, any>) => {
})
}

if (query.size) {
const sizeValues = query.size.split(',')
sizeValues.forEach((size: any) => {
if (size) {
size.split(',').forEach((size: any) => {
filters.push({
variantOption: {
name: 'Size',
Expand All @@ -114,9 +107,8 @@ export const getFilterValues = (query: Record<string, any>) => {
})
}

if (query.productType) {
const productTypeValues = query.productType.split(',')
productTypeValues.forEach((productType: any) => {
if (productType) {
productType.split(',').forEach((productType: any) => {
filters.push({
productType: productType,
})
Expand Down Expand Up @@ -163,19 +155,17 @@ export const sortSizeOptions = (sizes: string[]) => {
* @returns A boolean indicating if the product is new
*/
export const isNewItem = (date: string, daysOld = 30): boolean => {
return (
new Date(date).valueOf()
> new Date().setDate(new Date().getDate() - daysOld).valueOf()
)
const dayInMs = 24 * 60 * 60 * 1000
return new Date(date).getTime() > Date.now() - daysOld * dayInMs
}

/**
* Checks if a product is sold out based on its availability.
* @param product - The product object containing availability information
* @returns A boolean indicating if the product is sold out
*/
export const isSoldOut = (product: ProductFragment): boolean => {
return !product.availableForSale
export const isSoldOut = (availableForSale: boolean): boolean => {
return !availableForSale
}

/**
Expand Down Expand Up @@ -257,6 +247,7 @@ export const isSizeSoldOut = (variants: ProductVariantFragment[], sizeValue: str
),
)

if (!sizeVariants.length) return false
return sizeVariants.every((variant) => !variant.availableForSale)
}

Expand All @@ -273,5 +264,6 @@ export const isColorSoldOut = (variants: ProductVariantFragment[], colorValue: s
),
)

if (!colorVariants.length) return false
return colorVariants.every((variant) => !variant.availableForSale)
}
9 changes: 9 additions & 0 deletions app/plugins/shopify-init.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
export default defineNuxtPlugin(async () => {
const shopStore = useShopStore()
const cartStore = useCartStore()

await Promise.all([
shopStore.getLocalization(),
cartStore.getCart(),
])
})
2 changes: 1 addition & 1 deletion app/stores/auth.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export const useAuthStore = defineStore('@nikkoel/auth', {
addresses: response.addresses,
firstName: response.firstName,
lastName: response.lastName,
// Add more if needed...
// ...
}

this.customer = customerInfo
Expand Down
2 changes: 1 addition & 1 deletion app/stores/cart.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,9 +200,9 @@ export const useCartStore = defineStore('@nikkoel/cart', {
getters: {
buyerCountryCode: (state) => state.cart?.buyerIdentity?.countryCode,
checkoutUrl: (state) => state.cart?.checkoutUrl,
subtotalAmount: (state) => state.cart?.cost?.subtotalAmount,
lineItems: (state) => state.cart?.lines,
lineItemCount: (state) => state.cart?.totalQuantity,
subtotalAmount: (state) => state.cart?.cost?.subtotalAmount,
},

persist: {
Expand Down
30 changes: 15 additions & 15 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,34 +12,34 @@
},
"dependencies": {
"@nuxt/fonts": "^0.11.4",
"@nuxt/icon": "^2.0.0",
"@nuxtjs/robots": "^5.5.5",
"@nuxt/icon": "^2.1.0",
"@nuxtjs/robots": "^5.5.6",
"@nuxtjs/sitemap": "^7.4.7",
"@pinia/nuxt": "0.11.2",
"@vueuse/core": "^13.9.0",
"@vueuse/nuxt": "^13.9.0",
"dotenv": "^17.2.2",
"dotenv": "^17.2.3",
"embla-carousel-vue": "^8.6.0",
"graphql": "^16.11.0",
"graphql-tag": "^2.12.6",
"pinia": "^3.0.3",
"pinia-plugin-persistedstate": "^4.5.0"
},
"devDependencies": {
"@graphql-codegen/cli": "^6.0.0",
"@graphql-codegen/typescript": "^5.0.0",
"@graphql-codegen/typescript-operations": "^5.0.0",
"@graphql-codegen/cli": "^6.0.1",
"@graphql-codegen/typescript": "^5.0.2",
"@graphql-codegen/typescript-operations": "^5.0.2",
"@iconify-json/ph": "^1.2.2",
"@nuxt/eslint": "^1.9.0",
"@nuxthub/core": "0.9.0",
"@tailwindcss/vite": "^4.1.13",
"eslint": "^9.36.0",
"nuxt": "^4.1.2",
"tailwindcss": "^4.1.13",
"typescript": "^5.9.2",
"vue": "^3.5.21",
"vue-router": "^4.5.1",
"wrangler": "^4.38.0"
"@tailwindcss/vite": "^4.1.15",
"eslint": "^9.38.0",
"nuxt": "^4.1.3",
"tailwindcss": "^4.1.15",
"typescript": "^5.9.3",
"vue": "^3.5.22",
"vue-router": "^4.6.3",
"wrangler": "^4.44.0"
},
"packageManager": "pnpm@10.14.0"
"packageManager": "pnpm@10.18.0"
}
Loading