Home
Wiki
Home
Wiki
  1. 2. Components
  • Back to home
  • 1. Themes
  • Vs Code
    • Getting Started
  • Kitchenware
    • Layout
      • New Layout
      • Legacy Layout
    • Components
      • Announcement
      • Banner Carousel
      • Banner With Products Carousel
      • Blog Category List
      • Blog List
      • Brand List
      • Brands Carousel
      • Breadcrumb
      • Call To Action
      • Cart
      • Categories List
      • Change Password
      • Checkout
      • Cookie Manager
      • Filter list
      • Footer
      • Forgot Password
      • Form
      • Hero Carousel
      • Icon Block
      • Invitation
      • Last Visited Products
      • Layout
      • Login
      • Map
      • Nav Bar
      • Offer
      • Product Attachments
      • Product Attributes
      • Product Documentation
      • Product Expected
      • Product Modal
      • Products Block
      • Products Carousel
      • Product Single
      • Profile
      • Quote
      • Register
      • Related Products
      • Search
      • Stores
      • Subscribe Newsletter
      • Text with Image
      • Top Bar
      • Video
    • Reusables
      • Getting Started
    • Assets
      • Getting Started
    • SDK
      • Products
        • _findProductsByCategory
        • _findProductsByIds
        • _findProductsByTitle
        • _findProductsByFilter
        • _findProductsByCriteria
        • _findProductsAndCalculate
        • _findProductsThenCalculate
        • _getProductAttributeSet
        • _setLastVisited
      • Categories
        • _findCategoryTreeById
        • _findCategoriesByIds
        • _findCategoryByAlias
        • _findCategoryTreeByAlias
        • _getCategoryContent
      • Collections
        • _getCollectionContent
        • _findCollectionsByIds
        • _findCollectionsByIdsThenCalculate
      • Brands
        • _getBrandContent
        • _findBrandsByIds
      • Cart
        • _addToCartMulti
        • _addToCart
        • _setCart
        • _clearCart
        • _setCartListener
        • _removeFromCart
        • _calculateCart
      • Checkout
        • _startCheckout
        • _updateCheckout
        • _completeCheckout
      • Shopping Lists
        • _getShoppingLists
        • _updateShoppingList
        • _createShoppingList
        • _deleteShoppingList
        • _getShoppingListByAlias
      • Navigation
        • _getFooterMenu
        • _getHeaderMenu
      • Users
        • _getUserById
      • Utils
        • _calculateCurrency
        • _getCurrencySymbol
        • _getCulture
        • _subscribeToNewsletter
        • _findUnitsByIds
  • Noir
    • 0. Introduction
    • 1. Structure
      • _Overview
      • LayoutA.liquid
      • ComponentsList.liquid
      • Metas.liquid
      • CssVariables.liquid
      • Json.liquid
      • GoogleTagManager.liquid
      • StagingButton.liquid
    • 2. Components
      • _Overview
      • Announcement
      • BannerCarousel
      • BlogCategoryList
      • BlogList
      • BrandList
      • Breadcrumb
      • Cart
      • CategoriesList
      • ChangePassword
      • Checkout
      • CookieManager
      • FilterList
      • Footer
      • ForgotPassword
      • Form
      • IconBlock
      • Invitation
      • LastVisitedProducts
      • Login
      • Map
      • NavBar
      • ProductAttachments
      • ProductAttributes
      • ProductComparison
      • ProductDocumentation
      • ProductMixList
      • ProductsBlock
      • ProductsCarousel
      • ProductSingle
      • Profile
      • Quote
      • Register
      • RelatedProducts
      • SingleBlog
      • Stores
      • TextWithImage
      • ThankYouPage
      • TopBar
      • Wishlist
    • 3. Reusables
      • _Overview
      • Addresses
      • BillingRetail
      • AddressForm
      • AnnouncementModal
      • BackToTop
      • Company
      • General
      • Login
      • LoginModal
      • MonthlyTransactions
      • Orders
      • Payment
      • ProductAttachments
      • ProductAttributes
      • ProductComparisonButton
      • ProductComparisonFloatingButton
      • ProductGridItem
      • ProductListItem
      • ProductModal
      • ProfileInfo
      • PromptModal
      • Register
      • Services
      • Shipping
      • ShoppingLists
      • ShoppingListsButton
      • ShoppingListsNavbar
      • Toast
      • Transactions
      • Users
      • VariantContent
      • WishlistButton
      • Quotes
    • 4. Assets
      • Fonts
      • Images
      • Templates
      • Javascript
        • _Overview
        • theme.js
      • Css - Scss
        • _Overview
        • ThemeClasses
    • 5. SDK
      • _Overview
      • LiquidGlobals
      • ServicesSDK
  1. 2. Components

Profile

Purpose#

The Profile component renders the “My account” page.
It:
builds a vertical tab UI (Orders / Info / Addresses / Company / Users / Shopping lists depending on settings)
renders each tab content by delegating to reusables (Orders, Addresses, Company, Users, etc.)
keeps the current tab in sync with the URL (/profile/<tab>) and preserves sticky menu offset against the header height
allows logout via navbardefault.handleLogout(...)
For B2B customers (GlobalData.Settings.IsB2bCustomer == true) it also supports finance-related tabs:
transactions → Reusables/Transactions/Default
monthlytransactions → Reusables/MonthlyTransactions/Default

Inputs (model contract)#

Model shape (storefront example)#

{
  "companyLogoUrl": null,
  "currentTab": "orders",
  "countriesList": [
    {
      "code": "GR",
      "name": "Sample text"
    },
    "..."
  ],
  "addresses": [
    {
      "address": {
        "id": "Address Id",
        "firstName": "Sample text",
        "lastName": "Sample text",
        "phoneNumber": "Sample text",
        "email": "sample@example.com",
        "address1": "Sample text",
        "additionalInfo": "",
        "label": "",
        "city": "Sample text",
        "postalCode": "Sample text",
        "state": "Sample text",
        "country": "Sample text",
        "countryCode": "GR"
      },
      "isValid": true
    },
    "..."
  ],
  "headQuarterAddress": null,
  "branches": null,
  "orderData": {
    "totalPages": 1,
    "page": 1,
    "list": [
      {
        "id": "Order Id",
        "status": "Placed",
        "code": "Sample text",
        "placedAt": "2026-01-01T00:00:00.0000000+00:00",
        "billingAddress": {
          "firstName": "Sample text",
          "lastName": "Sample text",
          "phoneNumber": "Sample text",
          "email": "sample@example.com",
          "address1": "Sample text",
          "city": "Sample text",
          "postalCode": "Sample text",
          "state": "Sample text",
          "country": "Sample text"
        },
        "shippingAddress": {
          "firstName": "Sample text",
          "lastName": "Sample text",
          "phoneNumber": "Sample text",
          "email": "sample@example.com",
          "address1": "Sample text",
          "city": "Sample text",
          "postalCode": "Sample text",
          "state": "Sample text",
          "country": "Sample text"
        },
        "shippingLine": {
          "totalAmount": 5,
          "title": "Sample text",
          "totalAmountText": "Sample price text",
          "carrierId": "Carrier Id",
          "carrierCode": "sample",
          "netPrice": 5,
          "vatLines": []
        },
        "payment": {
          "serviceAmount": 2,
          "serviceAmountText": "Sample price text",
          "name": "Sample text",
          "provider": "COD",
          "amount": 0
        },
        "documentType": "Receipt",
        "invoiceData": {
          "tin": "",
          "taxOffice": "",
          "companyName": "",
          "profession": ""
        },
        "totalQuantity": 2,
        "totalAmountText": "Sample price text",
        "subTotalPriceText": "Sample price text",
        "discountPriceText": "Sample price text",
        "netValuePriceText": "Sample price text",
        "finalPriceText": "Sample price text",
        "vatAmountText": "Sample price text",
        "companyId": "Company Id",
        "cartToken": "Cart Token",
        "customerId": "Customer Id",
        "customerName": "Sample text",
        "discountRate": 0,
        "discountValue": 0,
        "totalAmount": 87,
        "expenseAmount": 0,
        "netAmount": 64.52,
        "vatAmount": 15.48,
        "financialStatus": "Pending",
        "fulfillmentStatus": "Fulfilled",
        "requiresCalculation": true,
        "lines": [
          {
            "id": "Order Line Id",
            "productId": "Product Id",
            "productVariantId": "Variant Id",
            "productTitle": "Sample text",
            "sku": "Sample text",
            "quantity": 2,
            "mediaItem": {
              "id": "Media Item Id",
              "link": "https://example.com/media/sample.jpg",
              "position": 0,
              "alt": "sample.jpg",
              "mediaType": "Image"
            },
            "link": "sample-product",
            "priceText": "Sample price text",
            "totalPriceText": "Sample price text",
            "netValue": 64.52,
            "price": 40,
            "lineValue": 64.52,
            "discountValue": 0,
            "discountRate": 0,
            "vatValue": 15.48,
            "vatRate": 24,
            "vatCode": ""
          },
          "..."
        ],
        "vatAnalysis": [
          {
            "vatRate": 24,
            "vatAmount": 15.48,
            "vatCode": "",
            "netAmount": 64.52
          },
          "..."
        ],
        "tags": [],
        "sourceTags": [],
        "updateDate": "2026-01-01T00:00:00.0000000+00:00",
        "insertDate": "2026-01-01T00:00:00.0000000+00:00",
        "favorite": false,
        "userId": "User Id",
        "loyaltyPricing": {
          "usePoints": false,
          "useCoupon": false,
          "couponCodes": []
        },
        "pricingBeforeDiscount": {
          "totalAmount": 0,
          "totalAmountText": "Sample price text",
          "netAmount": 0,
          "netAmountText": "Sample price text",
          "vatAmount": 0,
          "vatAmountText": "Sample price text",
          "expenseAmountText": "Sample price text"
        }
      },
      "..."
    ],
    "availableStatuses": [
      "Placed",
      "..."
    ],
    "availableYears": [
      "2026",
      "..."
    ]
  },
  "shoppingLists": [],
  "userManagement": null,
  "transactionData": {
    "pagination": {
      "pageNumber": 1,
      "numberOfPages": 28
    },
    "dateFrom": "2025-01-01",
    "dateTo": "2025-01-31",
    "lines": [
      {
        "id": "Transaction Id",
        "code": "CRN-2025-000007",
        "credit": 80.0,
        "creditText": "80.00 €",
        "debit": 0.0,
        "debitText": "0.00 €",
        "turnover": -80.0,
        "turnoverText": "-80.00 €",
        "progressiveBalance": 980.5,
        "progressiveBalanceText": "980.50 €",
        "description": "Sample description",
        "notes": "Sample notes",
        "transactionDate": "2025-01-25T16:05:00Z",
        "invoiceUrl": "https://example.com/sample"
      }
    ],
    "forward": {
      "credit": 1500.0,
      "debit": 2200.0,
      "turnover": 700.0,
      "balance": 700.0
    },
    "total": {
      "credit": 2080.0,
      "debit": 3760.5,
      "turnover": 1680.5,
      "balance": 1680.5
    }
  },
  "balSheetData": {
    "years": [
      {
        "fiscalYear": "2026",
        "lines": [
          {
            "period": "January",
            "fiscalYear": "2026",
            "credit": 1500.0,
            "creditText": "1,500.00 €",
            "debit": 1200.5,
            "debitText": "1,200.50 €",
            "turnover": 299.5,
            "turnoverText": "299.50 €"
          },
          "..."
        ],
        "total": {
          "credit": 2300.0,
          "creditText": "2,300.00 €",
          "debit": 2150.5,
          "debitText": "2,150.50 €",
          "turnover": 149.5,
          "turnoverText": "149.50 €",
          "balance": null,
          "balanceText": null
        }
      },
      "..."
    ],
    "availableFiscalYears": [
      "2026",
      "2025"
    ],
    "total": {
      "credit": 45000.0,
      "creditText": "45,000.00 €",
      "debit": 42500.0,
      "debitText": "42,500.00 €",
      "turnover": 2500.0,
      "turnoverText": "2,500.00 €",
      "balance": 2500.0,
      "balanceText": "2,500.00 €"
    }
  },
  "name": "Profile",
  "view": "Default",
  "section": "SectionA",
  "settings": {
    "id": "Component Id",
    "section": "SectionA",
    "type": "NoirProfile",
    "name": "Profile",
    "configuredInContentApi": true,
    "view": "Default",
    "displayName": "",
    "cssClass": ""
  },
  "translations": {
    "myAccount": "Sample text",
    "hello": "Sample text",
    "orders": "Sample text",
    "...": "..."
  }
}

Required fields#

settings.id

Optional fields#

currentTab (defaults to orders)
settings.cssClass / model.Settings.CssClass (string, optional)
Appended to the root <section> when it’s not empty and not (UNDEFINED).
orderData (consumed by Reusables\\Orders\\Default)
addresses, countriesList (consumed by Reusables\\Addresses\\Default)
headQuarterAddress, branches, companyLogoUrl (consumed by Reusables\\Company\\Default)
shoppingLists (consumed by Reusables\\ShoppingLists\\Default)
userManagement (consumed by Reusables\\Users\\Default)
transactionData (consumed by Reusables\\Transactions\\Default)
balSheetData (consumed by Reusables\\MonthlyTransactions\\Default)
translations.*

JavaScript#

Global object#

Components/Profile/Default.js exposes:
Liquid binds it via Alpine:
<section x-data="profiledefault.initComponent('{{ currentTab }}')">

initComponent(currentTab)#

What it does
Creates and returns the Alpine state object for the Profile tabs UI.
Tab routing behavior:
Watches tab changes and updates URL using history.replaceState(null, "", "/profile/" + value) (see Components/Profile/Default.js).
Calculates sticky offset by tracking the <header> height (updateHeaderHeight()) and binding it to the tab menu top style.

Rendering / Behavior#

Tabs list (B2B vs B2C)#

Tabs are decided in Liquid based on global settings (see Components/Profile/Default.liquid):
If GlobalData.Settings.IsB2bCustomer:
base tabs: orders,transactions,monthlytransactions
optionally adds:
shoppingLists when GlobalData.Settings.EnableShoppingLists
quotes when GlobalData.Settings.ShowQuote
always appends: users,info,company
Else (B2C):
base tabs: orders
optionally adds: shoppingLists
always appends: info,addresses

Tab pane rendering#

Each tab delegates to a reusable:
orders → Reusables\\Orders\\Default (orderData)
shoppingLists → Reusables\\ShoppingLists\\Default (shoppingLists)
transactions → Reusables\\Transactions\\Default (transactionData)
monthlytransactions → Reusables\\MonthlyTransactions\\Default (balSheetData)
users → Reusables\\Users\\Default (userManagement)
info → Reusables\\ProfileInfo\\Default
addresses → Reusables\\Addresses\\Default (addresses, countriesList)
company → Reusables\\Company\\Default (headQuarterAddress, branches, companyLogoUrl)
quotes → Reusables\\Quotes\\Default (quoteData)

Global Alpine stores#

On tab button click, the template triggers several store interactions (see Components/Profile/Default.liquid):
Alpine.store("toast").removeAll()
Alpine.store("profile").tabChanged = !Alpine.store("profile").tabChanged
Alpine.store("sharedAddresses").runToast = (tab === 'addresses')
These stores are assumed to be initialized elsewhere in the theme runtime.

init()#

What it does
Watches tab and updates the URL path to /profile/<tab>.
Tracks header height to compute the sticky menu offset.
Key behaviors / edge cases
Uses history.replaceState(...) (no navigation), so it’s safe to call frequently.
Attaches resize and scroll listeners; header height can change during scroll.

updateHeaderHeight()#

What it does
Reads <header> height and stores it in headerHeight.

scrollToTopOfSection()#

What it does
When a tab changes, it can scroll the page so the active tab panel is not hidden behind the fixed header.
Key behaviors / edge cases
Scrolls only when the panel is already above the viewport (rect.top < headerHeight + 20).

Global Alpine stores (used by Profile)#

Alpine.store("toast") (clear tab errors)#

The tab click handler clears the toast stack whenever the user switches tabs:
Alpine.store("toast").removeAll()

Alpine.store("profile") (tabChanged)#

The tab click handler toggles a shared store property:
Alpine.store("profile").tabChanged = !Alpine.store("profile").tabChanged
This is used as a cross-component “something changed” signal (typically for reusables rendered inside the tabs).

Alpine.store("sharedAddresses") (addresses tab behavior)#

When the user navigates to the addresses tab, the click handler sets:
Alpine.store("sharedAddresses").runToast = (tab === 'addresses')
This is used by the Addresses reusable to decide whether it should show validation feedback.

Dependencies#

Alpine.js
Liquid globals:
GlobalData.User.* (initials + greeting)
GlobalData.Settings.* (feature flags for tabs)
External JS objects:
navbardefault.handleLogout(...)
Alpine stores:
toast
profile
sharedAddresses
Reusables:
Reusables\\Orders\\Default
Reusables\\ShoppingLists\\Default
Reusables\\Transactions\\Default
Reusables\\MonthlyTransactions\\Default
Reusables\\Users\\Default
Reusables\\ProfileInfo\\Default
Reusables\\Addresses\\Default
Reusables\\Company\\Default
Reusables\\Quotes\\Default

Notes#

The set of tabs rendered depends on GlobalData.Settings.IsB2bCustomer and GlobalData.Settings.EnableShoppingLists.
Tabs like points and coupons are conditionally hidden based on feature flags (isRewardPointsActive, isCouponsActive).
The template shows user initials based on GlobalData.User.FirstName/LastName (fallback to Email).

Extras#

Template behavior (Liquid + Alpine)#

Builds a tabs list differently for B2B vs B2C.
Computes initials in Liquid and shows them only on desktop.
Renders vertical tab buttons and panels.
Each panel renders a reusable based on the tab name.
The tab menu is sticky and uses headerHeight (computed in JS) as top offset.
Modified at 2026-05-04 08:52:05
Previous
ProductSingle
Next
Quote
Built with