Skip to content

Commit

Permalink
wip: useUiNotification
Browse files Browse the repository at this point in the history
  • Loading branch information
lukaszjedrasik committed Jan 5, 2021
1 parent d40c163 commit fcbac55
Show file tree
Hide file tree
Showing 5 changed files with 146 additions and 5 deletions.
25 changes: 22 additions & 3 deletions packages/core/nuxt-theme-module/theme/components/CartSidebar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -118,9 +118,9 @@ import {
SfCollectedProduct,
SfImage
} from '@storefront-ui/vue';
import { computed } from '@vue/composition-api';
import { computed, watch } from '@vue/composition-api';
import { useCart, useUser, cartGetters } from '<%= options.generate.replace.composables %>';
import { useUiState } from '~/composables';
import { useUiState, useUINotification } from '~/composables';
import { onSSR } from '@vue-storefront/core';
export default {
Expand All @@ -135,10 +135,11 @@ export default {
SfCollectedProduct,
SfImage
},
setup() {
setup(_, { root }) {
const { isCartSidebarOpen, toggleCartSidebar } = useUiState();
const { cart, removeItem, updateItemQty, load: loadCart } = useCart();
const { isAuthenticated } = useUser();
const { spawnNotification } = useUINotification();
const products = computed(() => cartGetters.getItems(cart.value));
const totals = computed(() => cartGetters.getTotals(cart.value));
const totalItems = computed(() => cartGetters.getTotalItems(cart.value));
Expand All @@ -147,6 +148,24 @@ export default {
await loadCart();
});
watch(totalItems, () => {
spawnNotification({
type: 'info',
message: `Total items: ${totalItems.value}`,
title: 'title',
action: {
text: 'test action',
onClick: () => {
root.$router.push('/');
}
},
options: {
persist: true,
icon: 'heart'
}
});
});
return {
isAuthenticated,
products,
Expand Down
62 changes: 62 additions & 0 deletions packages/core/nuxt-theme-module/theme/components/Notification.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
<template>
<div class="notifications">
<SfNotification
v-for="notification in notifications"
:key="notification.id"
:visible="!!notification.id"
:title="notification.title"
:message="notification.message"
:action="notification.action && notification.action.text"
:type="notification.type"
@click:close="removeNotification(notification.id)"
@click:action="notification.action && notification.action.onClick()"
>
<template #icon="{icon}" v-if="notification.options && notification.options.icon">
<SfIcon :icon="notification.options.icon" :color="notification.options.iconColor || 'white'"/>
</template>
</SfNotification>
</div>
</template>

<script>
import { SfNotification, SfIcon } from '@storefront-ui/vue';
import { useUINotification } from '~/composables';
export default {
name: 'Notification',
components: {
SfNotification,
SfIcon
},
setup () {
const { notifications, removeNotification } = useUINotification();
return {
notifications,
removeNotification
};
}
};
</script>

<style scoped lang="scss">
.notifications {
position: fixed;
width: 100%;
left: 0;
right: 0;
bottom: var(--bottom-navigation-height, 3.75rem);
z-index: 9;
@include for-desktop {
left: auto;
right: 5%;
width: 320px;
}
}
.sf-notification {
margin: 0 auto var(--spacer-xs) auto;
@include for-desktop {
margin: 0 0 var(--spacer-xs) 0;
}
}
</style>
4 changes: 3 additions & 1 deletion packages/core/nuxt-theme-module/theme/composables/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import useUiHelpers from './useUiHelpers';
import useUiState from './useUiState';
import useUINotification from './useUINotification';

export {
useUiHelpers,
useUiState
useUiState,
useUINotification
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import { computed, reactive } from '@vue/composition-api';

interface Options {
persist: boolean;
timeToLive?: number;
icon?: string;
iconColor?: string;
}

interface Action {
text: string;
onClick?: Function;
}

interface Notification {
type: string;
title?: string;
message: string;
action: Action;
options?: Options;
}

const state = reactive({
notifications: []
});

const useUINotification = () => {
const removeNotification = (id: symbol) => {
const index = state.notifications.findIndex(notification => notification.id === id);

if (index !== -1) state.notifications.splice(index, 1);
};

const spawnNotification = (notification: Notification) => {
const id = Symbol();
const newNotification = { id, ...notification };

state.notifications.push(newNotification);
if (state.notifications.length > 3) state.notifications.shift();

if (!notification.options?.persist) {
setTimeout(() => {
removeNotification(id);
}, notification.options?.timeToLive || 3000);
}
};

return {
spawnNotification,
removeNotification,
notifications: computed(() => state.notifications)
};
};

export default useUINotification;
5 changes: 4 additions & 1 deletion packages/core/nuxt-theme-module/theme/layouts/default.vue
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
<CartSidebar />
<WishlistSidebar />
<LoginModal />
<Notification />
</div>
</div>
</template>
Expand All @@ -35,6 +36,7 @@ import CartSidebar from '~/components/CartSidebar.vue';
import WishlistSidebar from '~/components/WishlistSidebar.vue';
import LoginModal from '~/components/LoginModal.vue';
import LazyHydrate from 'vue-lazy-hydration';
import Notification from '~/components/Notification';
export default {
components: {
Expand All @@ -45,7 +47,8 @@ export default {
AppFooter,
CartSidebar,
WishlistSidebar,
LoginModal
LoginModal,
Notification
}
};
</script>
Expand Down

0 comments on commit fcbac55

Please sign in to comment.