/profile/<tab>), so switching tabs is a full page loadnavbardefault.handleLogout(...)GlobalData.Settings.IsB2bCustomer == true) it also supports finance-related tabs:transactions → Reusables/Transactions/Defaultmonthlytransactions → Reusables/MonthlyTransactions/Default{
"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",
"...": "..."
}
}settings.idcurrentTab (defaults to orders)tabQueryString (defaults to empty) — query string appended to every tab link so the Adminenv, templateCode) survives navigationsettings.cssClass / model.Settings.CssClass (string, optional)<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)offerData (consumed by Reusables\\Offers\\Default)quoteData (consumed by Reusables\\Quotes\\Default)transactionData (consumed by Reusables\\Transactions\\Default)balSheetData (consumed by Reusables\\MonthlyTransactions\\Default)translations.*tabs list differently for B2B vs B2C (see "Tabs list" below).initials in Liquid from GlobalData.User.* and shows them only on desktop.<a href="/profile/{tab}{{ tabQueryString }}"> links; the active one getsactive + aria-current="page".currentTab — and delegates it to a reusable.headerHeight (computed in JS) as its top offset.Components/Profile/Default.js exposes:<section x-data="profiledefault.initComponent()"><a href="/profile/{tab}">), so switching tabs is a full<header> height and stores it in headerHeight./profile/orders, /profile/addresses, /profile/monthlytransactions, ...)ProfileViewModelComponentConverter.GetCurrentTabFromUrl() resolves theConvertAsync only fetches the data for that tab —Components/Profile/Default.liquid (the loop over tabs renders a<div class="tab__content"> matching currentTab, not one per tab with the rest hidden).<a href="/profile/{tab}"> links, not buttons with @click handlers.Alpine.store("profile").tabChanged to reset state when the usershoppingLists tab links to/profile/shoppinglists (and /profile/shoppinglists/{alias} for a single list). Client code thatwindow.location.pathname must compare case-insensitively — seeReusables/ShoppingLists/Default.js.tabQueryString carries the Admin preview parameters (env, templateCode) of the current requestResolveTabForContext mirrors the Liquid tab list: a tab the current customer cannot see (a B2C tabEnableShoppingLists / ShowQuote / ShowOffer) resolves backorders. Without this the backend would fetch a section that Components/Profile/Default.liquid never renders,Components/Profile/Default.liquid):GlobalData.Settings.IsB2bCustomer:orders,transactions,monthlytransactionsshoppingLists when GlobalData.Settings.EnableShoppingListsoffers when GlobalData.Settings.ShowOfferquotes when GlobalData.Settings.ShowQuoteusers,info,companyordersshoppingLists, offers, quotes (same flags as above)info,addressesorders → Reusables\\Orders\\Default (orderData)shoppingLists → Reusables\\ShoppingLists\\Default (shoppingLists)transactions → Reusables\\Transactions\\Default (transactionData)monthlytransactions → Reusables\\MonthlyTransactions\\Default (balSheetData)offers → Reusables\\Offers\\Default (offerData)users → Reusables\\Users\\Default (userManagement)info → Reusables\\ProfileInfo\\Defaultaddresses → Reusables\\Addresses\\Default (addresses, countriesList)company → Reusables\\Company\\Default (headQuarterAddress, branches, companyLogoUrl)quotes → Reusables\\Quotes\\Default (quoteData)runToast based on the current URL (window.location.pathname)/profile/addresses is now a full page load:Alpine.store("sharedAddresses").runToast is driven by the Addresses reusable's own init().Alpine.store("profile")(tabChanged) and thetoastclearing on tab click were removed along
with the client-side tab switching — see "Tab routing" above.
GlobalData.User.* (initials + greeting)GlobalData.Settings.* (feature flags for tabs)navbardefault.handleLogout(...)sharedAddressesReusables\\Orders\\DefaultReusables\\ShoppingLists\\DefaultReusables\\Transactions\\DefaultReusables\\MonthlyTransactions\\DefaultReusables\\Offers\\DefaultReusables\\Users\\DefaultReusables\\ProfileInfo\\DefaultReusables\\Addresses\\DefaultReusables\\Company\\DefaultReusables\\Quotes\\DefaultGlobalData.Settings.IsB2bCustomer,GlobalData.Settings.EnableShoppingLists, GlobalData.Settings.ShowOffer andGlobalData.Settings.ShowQuote.role="tab" / aria-controls would point at elements that do not exist. The rendered panel usesrole="region" + aria-labelledby.GlobalData.User.FirstName/LastName (fallback to Email).