Skip to content
Draft
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: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
},
"dependencies": {
"@heroicons/vue": "^2.2.0",
"@relewise/client": "^2.15.0",
"@relewise/client": "file:/./relewise-client-2.23.0.tgz",
"@relewise/web-components": "^1.12.0",
"@vueform/slider": "^2.1.10",
"@vueuse/core": "^13.9.0",
Expand Down
17 changes: 7 additions & 10 deletions src/components/ContentTile.vue
Original file line number Diff line number Diff line change
Expand Up @@ -39,22 +39,19 @@ const displayName = computed(() => {
</script>

<template>
<RouterLink
:to="{ name: 'content', params: { id: content.contentId } }"
class="relative flex flex-col overflow-hidden bg-white text-slate-900 hover:!text-brand-500 transition duration-200 h-full">
<RouterLink :to="{ name: 'content', params: { id: content.contentId } }"
class="relative flex flex-col overflow-hidden text-slate-900 hover:!text-brand-500 transition duration-200 h-full">
<div class="mt-2 flex gap-4 items-start h-full">
<div v-if="findImage(content)"
class="flex-shrink-0"
:class="showSummary ? 'w-36 h-36' : 'w-28 h-28'">
<Image :entity="content"/>
<div v-if="findImage(content)" class="flex-shrink-0" :class="showSummary ? 'w-36 h-36' : 'w-28 h-28'">
<Image :entity="content" />
</div>

<div class="text-left flex flex-col flex-1 h-full">
<h5 class="tracking-tight font-medium"
:class="showSummary ? 'text-2xl' : 'text-lg'"
<h5 class="tracking-tight font-medium" :class="showSummary ? 'text-2xl' : 'text-lg'"
v-html="displayName">
</h5>
<span v-if="showSummary" class="text-slate-700 flex-1 mt-1 overflow-hidden line-clamp-2" v-html="summarySnippet"></span>
<span v-if="showSummary" class="text-slate-700 flex-1 mt-1 overflow-hidden line-clamp-2"
v-html="summarySnippet"></span>
</div>
</div>
</RouterLink>
Expand Down
53 changes: 53 additions & 0 deletions src/components/FeedContentTile.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
<template>
<RouterLink :to="{ name: 'content', params: { id: content.contentId } }"
class="relative flex flex-col overflow-hidden text-slate-900 hover:!text-brand-500 transition duration-200 h-full">
<div class="gap-4 items-start h-full flex flex-col">
<div v-if="findImage(content)" class="flex-shrink-0">
<Image :entity="content" />
</div>

<div class="text-left flex flex-col flex-1 h-full">
<h5 class="tracking-tight text-lg font-semibold leading-tight line-clamp-2 h-12">
{{ content.displayName }}
</h5>
<div class="flex justify-between">
<span class="text-sm text-neutral-500">{{ content.data!['ByLine']?.value }}</span>
<span class="flex gap-3 text-neutral-400">
<HandThumbUpIcon class="h-5 hover:text-neutral-800" @click.prevent.stop="giveFeedback('Like')"/>
<HandThumbDownIcon class="h-5 hover:text-neutral-800" @click.prevent.stop="giveFeedback('Dislike')" />
</span>
</div>
</div>
</div>
</RouterLink>
</template>

<script setup lang="ts">
import type { ContentResult } from '@relewise/client';
import { toRefs, type PropType } from 'vue';
import Image from './Image.vue';
import { findImage } from '@/helpers/imageHelper';
import { HandThumbDownIcon, HandThumbUpIcon } from '@heroicons/vue/24/solid';
import contextStore from '@/stores/context.store';

const props = defineProps({
content: { type: Object as PropType<ContentResult>, required: true },
feedId: { type: String, required: true }
});

const { content: content, feedId } = toRefs(props);

function giveFeedback(kind: "Like" | "Dislike") {
if (!feedId.value) return;

const item = content.value.contentId!;

contextStore.getTracker().trackContentEngagement({
user: contextStore.user.value,
engagement: {
sentiment: kind
},
id: item
});
}
</script>
31 changes: 26 additions & 5 deletions src/components/ProductTile.vue
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
<script setup lang="ts">
import type { ProductResult } from '@relewise/client';
import type { ProductAndVariantId, ProductResult } from '@relewise/client';
import { computed, toRefs, type PropType } from 'vue';
import Image from './Image.vue';
import Popover from '@/components/Popover.vue';
import { ExclamationCircleIcon } from '@heroicons/vue/24/outline';
import contextStore from '@/stores/context.store';
import { highlightWithOffsets } from '@/helpers/highligther';
import { HandThumbDownIcon, HandThumbUpIcon } from '@heroicons/vue/24/solid';

const props = defineProps({
product: { type: Object as PropType<ProductResult>, required: true },
isPromotion: { type: Boolean, required: false, default: false },
feedId: { type: String, required: false },
});

const { product } = toRefs(props);
const { product, feedId } = toRefs(props);

const showScore = contextStore.context.value.showProductRelevanceScore;

Expand All @@ -25,6 +27,20 @@ const displayName = computed(() => {

return highlightWithOffsets(product.value.displayName, matchedOffsets);
});

function giveFeedback(kind: "Like" | "Dislike") {
if (!feedId?.value) return;

const item: ProductAndVariantId = { productId: product.value.productId!, variantId: product.value.variant?.variantId };

contextStore.getTracker().trackProductEngagement({
user: contextStore.user.value,
engagement: {
sentiment: kind
},
product: item
});
}
</script>

<template>
Expand Down Expand Up @@ -79,15 +95,20 @@ const displayName = computed(() => {
</div>
<div class="my-2 flex items-center justify-between">
<p>
<span class="text-lg font-semibold text-slate-900 mr-1 leading-none">{{ $format(product.salesPrice)
}}</span>
<span class="text-lg font-semibold text-slate-900 mr-1 leading-none">
{{ $format(product.salesPrice) }}
</span>
<span
v-if="product.salesPrice !== product.listPrice && product.listPrice !== null && product.listPrice !== undefined"
class="text-slate-900 line-through">
{{ $format(product.listPrice) }}
</span>
</p>
</div>
<span class="flex gap-3 text-neutral-400" v-if="feedId">
<HandThumbUpIcon class="h-5 hover:text-neutral-800" @click.prevent.stop="giveFeedback('Like')"/>
<HandThumbDownIcon class="h-5 hover:text-neutral-800" @click.prevent.stop="giveFeedback('Dislike')" />
</span>
</div>
</div>
</RouterLink>
</template>
61 changes: 33 additions & 28 deletions src/layout/Header.vue
Original file line number Diff line number Diff line change
Expand Up @@ -62,25 +62,27 @@ onBeforeUnmount(() => {
<div class="grid xl:flex gap-2 xl:gap-8 py-2" @mouseover="handleMouseLeave">
<div class="flex items-center">
<div class="xl:hidden">
<SideMenu :main-categories="mainCategories"/>
<SideMenu :main-categories="mainCategories" />
</div>
<RouterLink to="/"
class="font-semibold text-2xl uppercase text-black leading-normal block hover:opacity-70 transitions ease-in-out delay-150">
class="font-semibold text-2xl uppercase text-black leading-normal block hover:opacity-70 transitions ease-in-out delay-150">
<img src="/demoshopwise.png" style="height: 40px;">
</RouterLink>
</div>
<div class="ml-0 flex gap-2 flex-grow">
<div class="xl:items-center flex-grow">
<SearchOverlay/>
<SearchOverlay />
</div>
<div class="flex items-center gap-6">
<Popover placement="bottom-end">
<div class="flex items-center gap-4 leading-none rounded-lg bg-slate-100 px-4 py-2 cursor-pointer hover:bg-slate-200 text-slate-800 hidden xl:flex">
<div
class="flex items-center gap-4 leading-none rounded-lg bg-slate-100 px-4 py-2 cursor-pointer hover:bg-slate-200 text-slate-800 hidden xl:flex">
<div>
<div class="font-medium text-sm">
{{ contextStore.context.value.displayName }}
</div>
<div v-if="contextStore.context.value.users && contextStore.context.value.selectedUserIndex !== undefined" class="text-xs">
<div v-if="contextStore.context.value.users && contextStore.context.value.selectedUserIndex !== undefined"
class="text-xs">
User: {{
displayUser(contextStore.context.value.users[contextStore.context.value.selectedUserIndex])
}}
Expand All @@ -89,19 +91,19 @@ onBeforeUnmount(() => {
User: Unknown
</div>
</div>
<ChevronDownIcon class="h-4"/>
<ChevronDownIcon class="h-4" />
</div>
<template #content>
<div class="w-96">
<ContextSwitcher/>
<ContextSwitcher />
</div>
</template>
</Popover>
<RouterLink to="/cart" class="relative flex flex-col items-center text-slate-600">
<ShoppingBagIcon class="h-8 w-8"/>
<ShoppingBagIcon class="h-8 w-8" />
<span class="text-[9px] mt-1 font-bold">CART</span>
<span v-if="lineItemsCount > 0"
class="absolute top-0 right-0 leading-none inline-flex items-center justify-center h-5 w-5 pb-0.5 bg-brand-700 rounded-full text-white font-bold text-[11px]">
class="absolute top-0 right-0 leading-none inline-flex items-center justify-center h-5 w-5 pb-0.5 bg-brand-700 rounded-full text-white font-bold text-[11px]">
{{ lineItemsCount }}
</span>
</RouterLink>
Expand All @@ -111,31 +113,29 @@ onBeforeUnmount(() => {
<nav class="hidden xl:block">
<ul class="flex w-full gap-2">
<ul v-if="hasChildCategories" class="flex overflow-y-auto scrollable-element">
<li v-for="category in mainCategories"
:key="category.id ?? ''"
<li v-for="category in mainCategories" :key="category.id ?? ''"
class="inline-flex relative pr-5">
<RouterLink :to="{ name: 'category', params: { id: category.id } }"
class="flex items-center font-semibold uppercase py-3 leading-none text-md text-slate-700 hover:text-brand-700 whitespace-nowrap hover:text-brand-500 transitions ease-in-out delay-150 cursor-pointer"
@mouseover="handleMouseOver(category.id)">
class="flex items-center font-semibold uppercase py-3 leading-none text-md text-slate-700 hover:text-brand-700 whitespace-nowrap hover:text-brand-500 transitions ease-in-out delay-150 cursor-pointer"
@mouseover="handleMouseOver(category.id)">
{{ category.category.displayName ?? category.category.categoryId }}
<ChevronDownIcon class="ml-2 mt-1 inline-block h-3 text-slade-500"/>
<ChevronDownIcon class="ml-2 mt-1 inline-block h-3 text-slade-500" />
</RouterLink>
<div v-if="open === category.id" to="#navigationmodal">
<div ref="navigationmodal"
class="navigationmodal"
@mouseover="handleMouseOver(category.id)">
<div ref="navigationmodal" class="navigationmodal"
@mouseover="handleMouseOver(category.id)">
<div class="bg-white overflow-x-auto modalcontent pb-10">
<div class="container mx-auto">
<h4 class="my-4 text-xl -mx-1">
<RouterLink :to="{ name: 'category', params: { id: category.id } }" class="text-slate-900 hover:underline" @click="handleMouseLeave">
<RouterLink :to="{ name: 'category', params: { id: category.id } }"
class="text-slate-900 hover:underline" @click="handleMouseLeave">
{{ category.category.displayName ?? category.category.categoryId }}
</RouterLink>
</h4>
<ul v-if="category.children.length > 0"
class="text-base z-10 list-none grid grid-cols-2 mb-3 -mx-1">
<li v-for="child in category.children"
:key="child.category.categoryId ?? ''"
class="text-sm block">
:key="child.category.categoryId ?? ''" class="text-sm block">
<RouterLink
:to="{ name: 'sub-category', params: { parent: category.id, id: child.category.categoryId } }"
class="block py-2 rounded cursor-pointer hover:underline text-gray-700"
Expand All @@ -150,26 +150,31 @@ onBeforeUnmount(() => {
</div>
</div>
</li>
<li class="inline-flex relative pr-5">
<RouterLink to="/feed"
class="flex items-center font-semibold uppercase py-3 leading-none text-md text-slate-700 hover:text-brand-700 whitespace-nowrap hover:text-brand-500 transitions ease-in-out delay-150 cursor-pointer">
Shoppertainment
</RouterLink>
</li>
</ul>
<ul v-else-if="mainCategories.length > 0">
<div class="font-semibold uppercase py-3 leading-none text-lg text-slate-700 whitespace-nowrap hover:text-brand-500 transitions ease-in-out delay-150 cursor-pointer"
@mouseover="handleMouseOver('1')">
@mouseover="handleMouseOver('1')">
Categories
</div>
<div v-if="open === '1'" to="#navigationmodal">
<div ref="navigationmodal" class="navigationmodal">
<div class="bg-white overflow-x-auto mb-5 modalcontent">
<div class="container mx-auto">
<ul class="text-base z-10 max-h-96 list-none grid grid-cols-4 mb-3">
<li v-for="category in mainCategories"
:key="category.id ?? ''"
<li v-for="category in mainCategories" :key="category.id ?? ''"
class="text-sm block">
<RouterLink :to="{ name: 'category', params: { id: category.id } }"
class="block px-2 py-1 rounded cursor-pointer hover:bg-gray-100 text-gray-700"
@click="() => {
open = null;
handleMouseLeave();
}">
class="block px-2 py-1 rounded cursor-pointer hover:bg-gray-100 text-gray-700"
@click="() => {
open = null;
handleMouseLeave();
}">
{{ category.category.displayName }}
</RouterLink>
</li>
Expand Down
5 changes: 5 additions & 0 deletions src/router/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ const router = createRouter({
name: 'content',
component: () => import('../views/ContentDetails.vue'),
},
{
path: "/feed",
name: "feed",
component: () => import('../views/Feed.vue'),
}
],
});

Expand Down
Loading
Loading