### Vue 3 Composition API with ` ``` -------------------------------- ### Install Dependencies Source: https://github.com/virtocommerce/vc-frontend/blob/dev/README.md Installs project dependencies using Yarn with the --immutable flag to ensure correct versions. ```bash yarn install --immutable ``` -------------------------------- ### Register Extension Component using EXTENSION_NAMES Source: https://github.com/virtocommerce/vc-frontend/blob/dev/client-app/shared/common/composables/extensionRegistry/README.md This example demonstrates the recommended way to register an extension component by importing and utilizing the `EXTENSION_NAMES` constant for type safety and consistency. ```typescript import { EXTENSION_NAMES } from "@/shared/common/constants/extensionPointsNames.ts"; const { register } = useExtensionRegistry(); register("productCard", EXTENSION_NAMES.productCard.cardButton, { component: MyComponent }); ``` -------------------------------- ### Module Initialization and Route Registration Source: https://github.com/virtocommerce/vc-frontend/blob/dev/client-app/modules/README.md Example of a module's entry point (index.ts) that exports an async init function. This function registers a new route with the Vue Router instance. ```typescript // modules/your-module/index.ts import { Router } from "vue-router"; import { I18n } from "@/i18n"; // Define your components const YourModulePage = () => import("./pages/YourModulePage.vue"); // By using () => import('./pages/YourModulePage.vue'), you ensure that Vue Router can handle the component as a lazy-loaded route, which is the intended usage pattern. export async function init(router: Router, i18n: I18n): Promise { const route = { path: "/your-module", name: "YourModule", component: YourModulePage, beforeEnter(to: any, from: any, next: Function) { // Add any route guards or logic here next(); }, }; router.addRoute(route); } ``` -------------------------------- ### Check Yarn Version Source: https://github.com/virtocommerce/vc-frontend/blob/dev/README.md Checks the installed version of Yarn. Ensure it is 4.1.0 or greater. ```bash yarn -v ``` -------------------------------- ### Generate Dependency Graph Source: https://github.com/virtocommerce/vc-frontend/blob/dev/README.md Creates a visual representation of the project's dependency graph. Requires graphviz to be installed. The generated graph is saved in the artifacts folder. ```bash yarn generate:dependency-graph client-app/main.ts client-app/shared/account/components/checkout-default-success-modal.vue ``` -------------------------------- ### Add Dev-Only Console Warning in Component File Source: https://github.com/virtocommerce/vc-frontend/blob/dev/client-app/ui-kit/DEPRECATION.md Include a dev-only `console.warn` in ` ``` -------------------------------- ### useUser() Source: https://context7.com/virtocommerce/vc-frontend/llms.txt Global reactive state for the current user: authentication status, permissions, corporate membership, and all account mutations. Broadcasts cross-tab events on user lock or password expiry. ```APIDOC ## useUser() ### Description Global reactive state for the current user: authentication status, permissions, corporate membership, and all account mutations (register, forgot/reset/change password, invite, impersonate switch). Broadcasts cross-tab events on user lock or password expiry. ### State - **user**: Current user object. - **isAuthenticated**: Boolean indicating if the user is authenticated. - **isCorporateMember**: Boolean indicating if the user is a corporate member. - **isOrganizationMaintainer**: Boolean indicating if the user is an organization maintainer. - **organization**: Current organization object. - **operator**: Current operator object. - **userGroups**: Array of user groups. - **loading**: Boolean indicating if data is being loaded. ### Methods - **fetchUser()**: Fetches user data. - **updateUser(userData)**: Updates user data. - **registerUser(userData)**: Registers a new user account. - **registerOrganization(userData)**: Registers a new user with an organization. - **forgotPassword(emailData)**: Sends a password reset email. - **resetPassword(passwordData)**: Resets the password using a token. - **changePassword(passwordData)**: Changes the password for an authenticated user. - **inviteUser(userData)**: Invites a user to the organization. - **registerByInvite(userData)**: Registers a user by invitation. - **sendVerifyEmail(email)**: Sends an email verification link. - **confirmEmail(token)**: Confirms the user's email. - **switchOrganization(organizationId)**: Switches the user to a different organization. - **checkPermissions(permission)**: Checks if the user has a specific permission. ### Usage ```typescript import { useUser } from "@/shared/account/composables/useUser"; const { registerUser, forgotPassword, checkPermissions, switchOrganization } = useUser(); // Register user await registerUser({ firstName: "Jane", lastName: "Doe", email: "jane@example.com", userName: "jane.doe", password: "Secure!1", }); // Check permissions if (checkPermissions("order:manage")) { // user has permission } // Switch organization await switchOrganization("org-456"); ``` ``` -------------------------------- ### Notifications — `useNotifications()` Source: https://context7.com/virtocommerce/vc-frontend/llms.txt Global, stackable notification system with four severity levels, auto-close timers, grouping, single/singleGroup/singleInGroup deduplication, and imperative close handles. ```APIDOC ## Notifications — `useNotifications()` Global, stackable notification system with four severity levels, auto-close timers, grouping, single/singleGroup/singleInGroup deduplication, and imperative close handles. ```typescript // client-app/shared/notification/composables/useNotifications.ts import { useNotifications } from "@/shared/notification"; const { info, success, warning, error, close, clear, update, stack } = useNotifications(); // Basic notifications const closeInfo = info({ text: "Loading your data…" }); const closeSuccess = success({ text: "Order placed successfully!", duration: 5000 }); const closeWarning = warning({ text: "Stock is low for this item." }); const closeError = error({ text: "Payment failed. Please try again." }); // Auto-close after 3 seconds success({ text: "Saved!", duration: 3000 }); // Deduplicated notifications (only one of this group at a time) error({ text: "Session expired.", singleGroup: true, group: "auth-errors" }); // Close a specific notification programmatically closeSuccess(); // or: close("notification-id") // Update a notification in-place (e.g. progress update) const closeProgress = info({ text: "Uploading… 0%" }); // later: update("notification-id", { text: "Uploading… 75%" }); // Clear all notifications in a group clear("auth-errors"); // Read the current stack reactively // stack.value → INotificationExtended[] ``` ``` -------------------------------- ### Modal System — `useModal()` Source: https://context7.com/virtocommerce/vc-frontend/llms.txt Lightweight modal stack: push any component + props onto a reactive stack; the `ModalStack` organism renders them in order. Returns a close handle and restores keyboard focus to the trigger element on close. ```APIDOC ## Modal System — `useModal()` Lightweight modal stack: push any component + props onto a reactive stack; the `ModalStack` organism renders them in order. Returns a close handle and restores keyboard focus to the trigger element on close. ```typescript // client-app/shared/modal/composables/useModal.ts import { useModal } from "@/shared/modal"; import MyDialogComponent from "@/shared/catalog/components/product-details-dialog.vue"; const { openModal, closeModal, modalStack } = useModal(); // Open a modal — returns a close handle const closeHandle = openModal({ component: MyDialogComponent, props: { productId: "prod-123", onConfirm(data: unknown) { console.log("Confirmed:", data); closeHandle(); }, onCancel() { closeHandle(); }, }, triggerElement: document.activeElement as HTMLElement, // focus restored on close }); // Close by handle closeHandle(); // Close the topmost modal closeModal(); // Close a specific modal by id openModal({ id: "confirm-delete", component: ConfirmModal, props: {} }); closeModal("confirm-delete"); // The stack is reactive — use in templates to conditionally show a backdrop // modalStack.value.length > 0 ``` ``` -------------------------------- ### createRouter() Source: https://context7.com/virtocommerce/vc-frontend/llms.txt Creates a Vue Router instance with HTML5 history mode and a locale-aware base path. It enforces authentication and organization membership before each navigation and redirects authenticated users away from public-only routes. ```APIDOC ## createRouter() ### Description Creates a Vue Router instance with HTML5 history mode and a locale-aware base path. Before each navigation it enforces authentication, organization membership, and redirects authenticated users away from public-only routes (sign-in, sign-up) to the Catalog page or a saved return URL. ### Usage ```typescript import { createRouter } from "@/router"; const router = createRouter({ base: "/" }); ``` ``` -------------------------------- ### useAnalytics() Source: https://context7.com/virtocommerce/vc-frontend/llms.txt Global event bus for eCommerce analytics. Allows registering multiple tracker implementations and dispatches events to all registered trackers. Skips events in development mode. ```APIDOC ## useAnalytics() ### Description Global event bus for eCommerce analytics. Any number of tracker implementations (e.g., Google Analytics, Hotjar) can be registered; each event is dispatched to every registered tracker. Silently skips events in development mode. ### Usage ```typescript import { useAnalytics } from "@/core/composables/useAnalytics"; import type { TrackerType } from "@/core/types/analytics"; const { analytics, addTracker } = useAnalytics(); // Register a custom tracker const myTracker: TrackerType = { meta: { name: "MyTracker" }, events: { addItemToCart: async (product, quantity) => { /* ... */ }, removeItemFromCart: async (product) => { /* ... */ }, placeOrder: async (order) => { /* ... */ }, clearCart: async (cart) => { /* ... */ }, addBulkItemsToCart: async (items, context) => { /* ... */ }, updateCartItem: async (sku, newQty, oldQty) => { /* ... */ }, }, }; addTracker(myTracker); // Dispatch events analytics("addItemToCart", product, 1); analytics("placeOrder", completedOrder); ``` ``` -------------------------------- ### Generate Bundle Size Map Source: https://github.com/virtocommerce/vc-frontend/blob/dev/README.md Analyzes and generates a map of chunk sizes (e.g., vendor.js, index.js) for optimization. Results are saved in the artifacts folder. ```bash yarn generate:bundle-map ``` -------------------------------- ### Configure Queued Mutations Link Source: https://github.com/virtocommerce/vc-frontend/blob/dev/client-app/core/api/graphql/config/links/queued-mutations/README.md Configure the link with specific mutation targets, debounce time, and custom merge logic. The `createQueueTarget` helper ensures type safety for mutation variables. ```typescript const myConfig: IQueueTargetConfig = { debounceMs: 1000, mergeQueued: (a, b) => { // Custom merge logic with full type safety for MyMutationVariables return { ...a, ...b }; }, }; createQueuedMutationsLink({ targets: [ createQueueTarget("MyMutation", myConfig), ], }) ``` -------------------------------- ### Import useFocusManagement Composable Source: https://github.com/virtocommerce/vc-frontend/blob/dev/llms/ui-kit/llms-detailed.txt Import the useFocusManagement composable from the UI Kit's composables directory. This composable helps manage focus within components. ```typescript import { useFocusManagement } from "@/ui-kit/composables" ``` -------------------------------- ### Product Catalog Operations Source: https://context7.com/virtocommerce/vc-frontend/llms.txt Provides a feature-rich composable for paginated product listing with faceted search, filters, and URL query parameter synchronization. Supports infinite scroll or load-more pagination. ```APIDOC ## Product Catalog Operations ### Description Composable function for paginated product listing with advanced features like faceted search, various filters (in-stock, purchased-before, branch), URL query parameter sync, and flexible pagination (infinite scroll or load-more). ### Methods - `useProducts(options)`: Initializes the product catalog composable with configuration options. - `withFacets`: Boolean to include facets in the response. - `withImages`: Boolean to include product images. - `withZeroPrice`: Boolean to include products with zero price. - `useQueryParams`: Boolean to sync with URL query parameters. - `catalogPaginationMode`: Sets the pagination mode (e.g., `CATALOG_PAGINATION_MODES.infiniteScroll`). - `fetchProducts(params)`: Fetches the initial list of products based on provided parameters. - `fetchMoreProducts(params)`: Fetches the next page of products. - `applyFilters(filters)`: Applies selected filters and controls to the product list. - `resetFacetAndControlsFilters()`: Resets all applied filters and controls. - `showFiltersSidebar()`: Shows the filters sidebar. - `hideFiltersSidebar()`: Hides the filters sidebar. - `openBranchesModal()`: Opens a modal for selecting branches. - `getFacets()`: Retrieves the available facets. ### State - `products`: Reactive reference to the list of products. - `facets`: Reactive reference to the available facets. - `totalProductsCount`: Total number of products matching the criteria. - `pagesCount`: Total number of pages. - `currentPage`: Current page number. - `productsFilters`: Reactive reference to the current filters and controls. - `fetchingProducts`: Boolean indicating if products are being fetched. - `fetchingMoreProducts`: Boolean indicating if more products are being loaded. - `localStorageInStock`: Boolean related to in-stock status in local storage. - `sortQueryParam`: Reactive reference for the sort query parameter. - `searchQueryParam`: Reactive reference for the search query parameter. - `hasSelectedFilters`: Boolean indicating if any filters are selected. - `isFiltersSidebarVisible`: Boolean indicating if the filters sidebar is visible. ### Example Usage ```typescript import { useProducts } from "@/shared/catalog/composables"; import { CATALOG_PAGINATION_MODES } from "@/shared/catalog/constants/catalog"; const { products, facets, totalProductsCount, pagesCount, currentPage, productsFilters, fetchingProducts, fetchingMoreProducts, localStorageInStock, sortQueryParam, searchQueryParam, hasSelectedFilters, fetchProducts, fetchMoreProducts, applyFilters, resetFacetAndControlsFilters, showFiltersSidebar, hideFiltersSidebar, isFiltersSidebarVisible, openBranchesModal, getFacets } = useProducts({ withFacets: true, withImages: true, withZeroPrice: false, useQueryParams: true, catalogPaginationMode: CATALOG_PAGINATION_MODES.infiniteScroll, }); // Fetch first page in a category await fetchProducts({ categoryId: "cat-electronics", itemsPerPage: 16, sort: "priority:desc", filter: "price:[10 TO 500]", cultureName: "en-US", currencyCode: "USD", storeId: "Electronics", }); // Load more (infinite scroll) await fetchMoreProducts({ categoryId: "cat-electronics", itemsPerPage: 16, page: currentPage.value + 1, }); // Apply user-selected facets & controls await applyFilters({ inStock: true, purchasedBefore: false, branches: ["warehouse-1"], facets: productsFilters.value.facets, filters: productsFilters.value.filters, }); // Reset all filters await resetFacetAndControlsFilters(); ``` ``` -------------------------------- ### Import useModal Composable Source: https://github.com/virtocommerce/vc-frontend/blob/dev/llms/ui-kit/llms-detailed.txt Import the useModal composable from the UI Kit's composables directory. This is necessary for using modal-related functionalities. ```typescript import { useModal } from "@/ui-kit/composables" ``` -------------------------------- ### Manage Page Head and SEO with `usePageHead()` Source: https://context7.com/virtocommerce/vc-frontend/llms.txt A wrapper around `@unhead/vue`'s `useHead` that applies store-aware title templates and normalizes meta tags for any page. ```typescript // client-app/core/composables/usePageHead.ts import { usePageHead } from "@/core/composables"; import { computed } from "vue"; // In a page component setup() const { product } = useProduct("prod-123"); usePageHead({ title: computed(() => product.value?.name ?? ""), meta: { description: computed(() => product.value?.description ?? ""), keywords: computed(() => product.value?.metaKeywords ?? ""), // robots: "noindex" for private pages }, }); // iPhone 15 | My Store // ``` -------------------------------- ### Import useComponentId Composable Source: https://github.com/virtocommerce/vc-frontend/blob/dev/llms/ui-kit/llms-detailed.txt Import the useComponentId composable from the UI Kit's composables directory. This is used for generating unique component IDs. ```typescript import { useComponentId } from "@/ui-kit/composables" ``` -------------------------------- ### Vue Template Placeholders Source: https://github.com/virtocommerce/vc-frontend/blob/dev/llms/ui-kit/llms-page-builder-prompt.md Use plain text directly within UI Kit components for placeholders. Localization will be handled separately. ```vue ```