Skip to content

Commit

Permalink
fix: redirect on hidden category after login (#893)
Browse files Browse the repository at this point in the history
  • Loading branch information
rbedeoan-plenty authored Dec 20, 2024
1 parent 846864e commit b1b65b1
Show file tree
Hide file tree
Showing 9 changed files with 72 additions and 62 deletions.
5 changes: 1 addition & 4 deletions apps/web/components/LoginComponent/LoginComponent.vue
Original file line number Diff line number Diff line change
Expand Up @@ -46,10 +46,7 @@ const loginUser = async () => {
const success = await login(email.value, password.value);
if (success) {
send({ message: t('auth.login.success'), type: 'positive' });
emits('loggedIn');
if (!skipReload) {
window.location.reload();
}
emits('loggedIn', skipReload);
}
};
</script>
7 changes: 6 additions & 1 deletion apps/web/components/ui/Header.vue
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@
</SfDropdown>
<UiButton
v-else
@click="openAuthentication"
@click="navigateToLogin"
class="group relative text-white hover:text-white active:text-white hover:bg-primary-800 active:bg-primary-700 mr-1 -ml-0.5 rounded-md"
variant="tertiary"
:aria-label="t('auth.login.openLoginForm')"
Expand Down Expand Up @@ -275,4 +275,9 @@ const accountDropdown = computed(() => [
label: t('account.logout'),
},
]);
const navigateToLogin = () => {
if (route.path !== localePath(paths.authLogin)) {
openAuthentication();
}
};
</script>
6 changes: 3 additions & 3 deletions apps/web/composables/useCategoryFilter/useCategoryFilter.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { Filters, GetFacetsFromURLResponse, UseCategoryFiltersResponse } from './types';

import type { RouteLocationNormalizedGeneric } from 'vue-router';
const nonFilters = new Set(['page', 'sort', 'term', 'facets', 'itemsPerPage', 'priceMin', 'priceMax']);

const reduceFilters =
Expand Down Expand Up @@ -42,8 +42,8 @@ const mergeFilters = (oldFilters: Filters, filters: Filters): Filters => {
* } = useCategoryFilter();
* ```
*/
export const useCategoryFilter = (): UseCategoryFiltersResponse => {
const route = useRoute();
export const useCategoryFilter = (to?: RouteLocationNormalizedGeneric): UseCategoryFiltersResponse => {
const route = to ?? useRoute();

/**
* @description Function for getting facets from url.
Expand Down
2 changes: 2 additions & 0 deletions apps/web/composables/useProducts/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type { Facet, FacetSearchCriteria, Product } from '@plentymarkets/shop-ap

export interface UseProductsState {
data: Facet;
checkingPermission: boolean;
loading: boolean;
productsPerPage: number;
currentProduct: Product;
Expand All @@ -13,6 +14,7 @@ export type SetCurrentProduct = (product: Product) => void;
export interface UseProducts {
data: Readonly<Ref<UseProductsState['data']>>;
loading: Readonly<Ref<boolean>>;
checkingPermission: Ref<boolean>;
productsPerPage: Readonly<Ref<number>>;
currentProduct: Readonly<Ref<UseProductsState['currentProduct']>>;
fetchProducts: FetchProducts;
Expand Down
10 changes: 2 additions & 8 deletions apps/web/composables/useProducts/useProducts.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { categoryGetters, FacetSearchCriteria, Product } from '@plentymarkets/shop-api';
import { FacetSearchCriteria, Product } from '@plentymarkets/shop-api';
import { Facet } from '@plentymarkets/shop-api';
import { defaults, type SetCurrentProduct } from '~/composables';
import { type FetchProducts, type UseProductsReturn, UseProductsState } from '~/composables/useProducts/types';
import { paths } from '~/utils/paths';

/**
* @description Composable for managing products.
Expand All @@ -16,6 +15,7 @@ export const useProducts: UseProductsReturn = (category = '') => {
const state = useState<UseProductsState>(`useProducts${category}`, () => ({
data: {} as Facet,
loading: false,
checkingPermission: false,
productsPerPage: defaults.DEFAULT_ITEMS_PER_PAGE,
currentProduct: {} as Product,
}));
Expand Down Expand Up @@ -47,12 +47,6 @@ export const useProducts: UseProductsReturn = (category = '') => {
state.value.productsPerPage = params.itemsPerPage || defaults.DEFAULT_ITEMS_PER_PAGE;

if (data.value?.data) {
if (categoryGetters.hasCustomerRight(data.value?.data.category) && !isAuthorized.value) {
state.value.data = {} as Facet;
await navigateTo(localePath(paths.authLogin));
return state.value.data;
}

data.value.data.pagination.perPageOptions = defaults.PER_PAGE_STEPS;
state.value.data = data.value.data;
}
Expand Down
31 changes: 31 additions & 0 deletions apps/web/middleware/category-guard.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/**
* This middleware is used to check if category can be accesed without being authenticatedd.
*
* If the user is not authenticated, the user will be redirected to the login page.
*/
import { categoryGetters } from '@plentymarkets/shop-api';
export default defineNuxtRouteMiddleware(async (to) => {
const { getFacetsFromURL, checkFiltersInURL } = useCategoryFilter(to);
const { setCategoriesPageMeta } = useCanonical();
const { isAuthorized, getSession } = useCustomer();
await getSession();
const { data: productsCatalog, fetchProducts, checkingPermission } = useProducts();
const localePath = useLocalePath();
checkingPermission.value = true;
const params = getFacetsFromURL();
await fetchProducts(params).then(() => checkFiltersInURL());
if (!productsCatalog.value.category) {
throw createError({ statusCode: 404, statusMessage: 'Not found', fatal: true });
}
setCategoriesPageMeta(productsCatalog.value, params);

const category = productsCatalog.value?.category;
if (category && categoryGetters.hasCustomerRight(category) && !isAuthorized.value) {
const targetUrl = to.fullPath;
return navigateTo({
path: localePath(paths.authLogin),
query: { redirect: targetUrl },
});
}
checkingPermission.value = false;
});
62 changes: 23 additions & 39 deletions apps/web/pages/[...slug].vue
Original file line number Diff line number Diff line change
Expand Up @@ -5,52 +5,43 @@
class="relative"
:class="{ 'pointer-events-none opacity-50': loading }"
>
<SfLoaderCircular v-if="loading" class="fixed top-[50%] right-0 left-0 m-auto z-[99999]" size="2xl" />
<CategoryPageContent
v-if="productsCatalog?.products"
:title="categoryGetters.getCategoryName(productsCatalog.category)"
:total-products="productsCatalog.pagination.totals"
:products="productsCatalog.products"
:items-per-page="Number(productsPerPage)"
>
<template #sidebar>
<CategoryTree :category="productsCatalog.category" />
<CategorySorting />
<CategoryItemsPerPage class="mt-6" :total-products="productsCatalog.pagination.totals" />
<CategoryFilters v-if="facetGetters.hasFilters(productsCatalog.facets)" :facets="productsCatalog.facets" />
</template>
</CategoryPageContent>
<SfLoaderCircular
v-if="loading || checkingPermission"
class="fixed top-[50%] right-0 left-0 m-auto z-[99999]"
size="2xl"
/>
<template v-else>
<CategoryPageContent
v-if="productsCatalog?.products"
:title="categoryGetters.getCategoryName(productsCatalog.category)"
:total-products="productsCatalog.pagination.totals"
:products="productsCatalog.products"
:items-per-page="Number(productsPerPage)"
>
<template #sidebar>
<CategoryTree :category="productsCatalog.category" />
<CategorySorting />
<CategoryItemsPerPage class="mt-6" :total-products="productsCatalog.pagination.totals" />
<CategoryFilters v-if="facetGetters.hasFilters(productsCatalog.facets)" :facets="productsCatalog.facets" />
</template>
</CategoryPageContent>
</template>
</NuxtLayout>
</template>

<script setup lang="ts">
import { categoryGetters, categoryTreeGetters, facetGetters } from '@plentymarkets/shop-api';
import { SfLoaderCircular } from '@storefront-ui/vue';
definePageMeta({ layout: false });
definePageMeta({ layout: false, middleware: ['category-guard'] });
const { setCategoriesPageMeta } = useCanonical();
const { t, locale } = useI18n();
const route = useRoute();
const router = useRouter();
const { getFacetsFromURL, checkFiltersInURL } = useCategoryFilter();
const { fetchProducts, data: productsCatalog, productsPerPage, loading } = useProducts();
const { data: productsCatalog, productsPerPage, loading, checkingPermission } = useProducts();
const { data: categoryTree } = useCategoryTree();
const { buildCategoryLanguagePath } = useLocalization();
const handleQueryUpdate = async () => {
await fetchProducts(getFacetsFromURL()).then(() => checkFiltersInURL());
if (!productsCatalog.value.category) {
throw new Response(null, {
status: 404,
statusText: 'Not found',
});
}
};
await handleQueryUpdate().then(() => setCategoriesPageMeta(productsCatalog.value, getFacetsFromURL()));
const breadcrumbs = computed(() => {
if (productsCatalog.value.category) {
const breadcrumb = categoryTreeGetters.generateBreadcrumbFromCategory(
Expand All @@ -75,13 +66,6 @@ watch(
},
);
watch(
() => route.query,
async () => {
await handleQueryUpdate().then(() => setCategoriesPageMeta(productsCatalog.value, getFacetsFromURL()));
},
);
const headTitle = computed(() =>
productsCatalog.value?.category
? (categoryGetters.getMetaTitle(productsCatalog.value.category) || process.env.METATITLE) ?? ''
Expand Down
10 changes: 3 additions & 7 deletions apps/web/pages/login.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,14 +15,10 @@ const router = useRouter();
const localePath = useLocalePath();
const isLogin = ref(true);
const navigateAfterAuth = () => {
const navigateAfterAuth = (skipReload: boolean) => {
const redirectUrl = router.currentRoute.value.query.redirect as string;
if (redirectUrl) {
router.push(localePath(redirectUrl));
return;
if (redirectUrl && !skipReload) {
window.location.href = localePath(redirectUrl);
}
router.go(-1);
};
</script>
1 change: 1 addition & 0 deletions docs/changelog/changelog_en.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ NPM_AUTH_TOKEN="<TOKEN>"

### 🩹 Fixed

- Redirect on hidden category after user was logged in.
- Fixed an unhandled scenario where a blocked payment method remained available during the checkout process
- Fixed the styling of HTML entered in a PlentyONE system's editor by adding a `no-preflight` CSS class that accounts for Tailwind's preflight configuration.
- Fixed the checkout layout for tablet screen sizes.
Expand Down

0 comments on commit b1b65b1

Please sign in to comment.