diff --git a/CHANGELOG.md b/CHANGELOG.md
index 31953dca2f..b3f73a8613 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5,14 +5,19 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## Draft
+- Add new create-return page [#2669](https://github.com/bigcommerce/cornerstone/pull/2669)
- Fix duplicate `id="default_instrument"` on Update Payment Method page [#2661](https://github.com/bigcommerce/cornerstone/pull/2661)
- Respect `available_to_sell` on PDP so the Sold Out alert is hidden and the Add to Cart button stays enabled for backorderable products, and is disabled when quantity exceeds `available_to_sell` [#2659](https://github.com/bigcommerce/cornerstone/pull/2659)
- Updated accessibility features [2656](https://github.com/bigcommerce/cornerstone/pull/2656)
+- Adds new guest-return-portal page. [2645](https://github.com/bigcommerce/cornerstone/pull/2645)
- Update 'Ship to' copy for multi address orders [#2655](https://github.com/bigcommerce/cornerstone/pull/2655)
- Fixed typo in category page reset-filters live region handler [#2643](https://github.com/bigcommerce/cornerstone/pull/2643)
- Swap content/data keys in onProductOptionsChanged event detail [#2640](https://github.com/bigcommerce/cornerstone/pull/2640)
+- Gate Order Details "Return" button on `settings.returns_v2_enabled` with `settings.returns_enabled` fallback (ORDERS-7705)
- Fix shipment info showing for cancelled orders [#2654](https://github.com/bigcommerce/cornerstone/pull/2654)
- Render backorder prompts on My Account "Your orders" page [#2650](https://github.com/bigcommerce/cornerstone/pull/2650)
+- Gate account orders list "Return Items" link on returns settings (ORDERS-7704) [#2653](https://github.com/bigcommerce/cornerstone/pull/2653)
+- Added new Return list view (ORDERS-7717) [#2664] (https://github.com/bigcommerce/cornerstone/pull/2664)
## 6.19.1 (04-09-2026)
- Update stencil-utils versionto 6.23.0 [#2638](https://github.com/bigcommerce/cornerstone/pull/2638)
diff --git a/assets/js/app.js b/assets/js/app.js
index b9e92bfdc8..b9a03f8aad 100644
--- a/assets/js/app.js
+++ b/assets/js/app.js
@@ -3,6 +3,7 @@ __webpack_public_path__ = window.__webpack_public_path__; // eslint-disable-line
import Global from './theme/global';
const getAccount = () => import('./theme/account');
+const getCreateReturn = () => import('./theme/create-return');
const getLogin = () => import('./theme/auth');
const noop = null;
@@ -12,6 +13,7 @@ const pageClasses = {
account_addressbook: getAccount,
shippingaddressform: getAccount,
account_new_return: getAccount,
+ create_return: getCreateReturn,
'add-wishlist': () => import('./theme/wishlist'),
account_recentitems: getAccount,
account_downloaditem: getAccount,
diff --git a/assets/js/theme/create-return.js b/assets/js/theme/create-return.js
new file mode 100644
index 0000000000..498fcc70d8
--- /dev/null
+++ b/assets/js/theme/create-return.js
@@ -0,0 +1,72 @@
+import PageManager from './page-manager';
+
+export default class CreateReturn extends PageManager {
+ onReady() {
+ const form = document.querySelector('[data-new-return-form]');
+ if (!form) return;
+
+ this.bindOrderLineItemEvents();
+ this.bindSubmit(form);
+ }
+
+ bindOrderLineItemEvents() {
+ // All three selects per row (qty, resolution, reason) trigger a submit-state check.
+ document.querySelectorAll('.newReturn-orderLineItem select').forEach(sel => {
+ sel.addEventListener('change', () => this.updateSubmitState());
+ });
+ }
+
+ updateSubmitState() {
+ const selectedItems = this.getSelectedItems();
+ const isValid = selectedItems.length > 0 && selectedItems.every(itemRow => {
+ const itemId = itemRow.dataset?.itemId;
+ if (!itemId) return false;
+ const resolutionEl = document.getElementById(`resolution-${itemId}`);
+ const reasonEl = document.getElementById(`reason-${itemId}`);
+ return resolutionEl && resolutionEl.value && reasonEl && reasonEl.value;
+ });
+
+ document.getElementById('return-new-submitBtn').disabled = !isValid;
+ }
+
+ // Returns only row containers (not buttons) with a non-zero quantity selected.
+ getSelectedItems() {
+ return [...document.querySelectorAll('.newReturn-orderLineItem')].filter(itemRow => {
+ const itemId = itemRow.dataset?.itemId;
+ if (!itemId) return false;
+ const qtyInput = document.getElementById(`qty-${itemId}`);
+ return qtyInput && parseInt(qtyInput.value, 10) > 0;
+ });
+ }
+
+ bindSubmit(form) {
+ form.addEventListener('submit', event => {
+ event.preventDefault();
+ // TODO ORDERS-7715: invoke createReturn Storefront GQL mutation using
+ // this.buildReturnInput() to get the payload.
+ });
+ }
+
+ /**
+ * Builds the createReturn mutation input.
+ * Called by ORDERS-7715 once the Storefront GQL mutation is wired up.
+ *
+ * @returns {{ orderEntityId: number, additionalNote: string, items: Array }}
+ */
+ buildReturnInput() {
+ return {
+ orderEntityId: parseInt(this.context.order?.id, 10),
+ additionalNote: document.querySelector('[data-new-return-note]')?.value || '',
+ items: this.getSelectedItems().flatMap(itemRow => {
+ const itemId = itemRow.dataset?.itemId;
+ if (!itemId) return [];
+ return [{
+ lineItemEntityId: parseInt(itemId, 10),
+ quantity: parseInt(document.getElementById(`qty-${itemId}`)?.value, 10),
+ resolution: document.getElementById(`resolution-${itemId}`)?.value,
+ reasonEntityId: document.getElementById(`reason-${itemId}`)?.value,
+ }];
+ }),
+ };
+ }
+}
diff --git a/assets/js/theme/return-details.js b/assets/js/theme/return-details.js
new file mode 100644
index 0000000000..6197a3c920
--- /dev/null
+++ b/assets/js/theme/return-details.js
@@ -0,0 +1,189 @@
+import { escape } from 'lodash';
+import PageManager from './page-manager';
+
+export default class ReturnDetails extends PageManager {
+ onReady() {
+ const root = document.querySelector('[data-return-details]');
+ if (!root) return;
+
+ this.root = root;
+
+ // ---------------------------------------------------------------------------
+ // Hardcoded page data which mirrors the returns-ui Return / Item interface
+ // Replace with the relevant stencil page context when it is surfaced.
+ // ---------------------------------------------------------------------------
+ this.pageData = {
+ id: '101',
+ rma: '101',
+ status: 'OPEN',
+ opened: 'January 1, 2024',
+ lastUpdated: 'January 1, 2024',
+ order: {
+ id: '222',
+ currency: 'USD',
+ },
+ shipping: {
+ address: {
+ fullName: 'John Doe',
+ address1: '1000 San Marcos Ave',
+ city: 'Austin',
+ state: 'TX',
+ zip: '78702',
+ country: 'United States',
+ },
+ method: 'UPS Ground',
+ trackingNumber: '1Z370170375602560',
+ dateShipped: 'May 15, 2024',
+ },
+ items: [
+ {
+ id: 'i1',
+ lineItemId: 'li1',
+ name: 'Product Name',
+ variant: 'Color: Blue · Size: Large',
+ thumbnailUrl: 'https://via.placeholder.com/72',
+ sku: 'SKU-001',
+ requestedResolution: { type: 'system', label: 'Exchange' },
+ requestedReason: 'Wrong item received',
+ quantity: 1,
+ formatted_price: '$123.99',
+ status: 'open',
+ },
+ {
+ id: 'i2',
+ lineItemId: 'li2',
+ name: 'Product Name',
+ variant: 'Color: Blue · Size: Large',
+ thumbnailUrl: 'https://via.placeholder.com/72',
+ sku: 'SKU-002',
+ requestedResolution: { type: 'system', label: 'Refund' },
+ requestedReason: 'Did not like',
+ quantity: 1,
+ formatted_price: '$123.99',
+ status: 'open',
+ },
+ {
+ id: 'i3',
+ lineItemId: 'li3',
+ name: 'Product Name',
+ variant: 'Color: Blue · Size: Large',
+ thumbnailUrl: 'https://via.placeholder.com/72',
+ sku: 'SKU-003',
+ requestedResolution: { type: 'system', label: 'Refund' },
+ requestedReason: 'Did not like',
+ quantity: 1,
+ formatted_price: '$123.99',
+ status: 'open',
+ },
+ ],
+ };
+
+ this.renderHeader();
+ this.renderShipping();
+ this.renderItems();
+ this.renderSummary();
+ }
+
+ renderHeader() {
+ const { rma, status } = this.pageData;
+ const titleEl = this.root.querySelector('[data-return-title]');
+ const statusEl = this.root.querySelector('[data-return-status]');
+
+ if (titleEl) titleEl.textContent = `Return #${rma}`;
+ if (statusEl) {
+ // Map the raw status enum to the localized label injected by the
+ // template (same labels as the returns list); fall back to the raw value.
+ const statusLabels = {
+ OPEN: this.context.returnStatusOpen,
+ IN_PROGRESS: this.context.returnStatusInProgress,
+ CLOSED: this.context.returnStatusClosed,
+ };
+ statusEl.textContent = statusLabels[status] || status;
+ statusEl.classList.add(`returnDetails-statusBadge--${status.toLowerCase()}`);
+ }
+ }
+
+ renderShipping() {
+ const container = this.root.querySelector('[data-return-shipping]');
+ if (!container) return;
+
+ const { address, method, trackingNumber, dateShipped } = this.pageData.shipping;
+ const addressLine = [
+ address.fullName,
+ address.address1,
+ `${address.city}, ${address.state} ${address.zip}`,
+ address.country,
+ ].filter(Boolean).join(', ');
+ const methodLine = `${method} (${trackingNumber}). Shipped on ${dateShipped}`;
+
+ const rows = [
+ { label: 'Shipping address', value: addressLine },
+ { label: 'Shipping method', value: methodLine },
+ ];
+
+ container.innerHTML = rows.map(({ label, value }) => `
+
+
${escape(label)}
+ ${escape(value)}
+ `).join('');
+ }
+
+ renderItems() {
+ const list = this.root.querySelector('[data-return-items]');
+ if (!list) return;
+
+ const { items } = this.pageData;
+
+ list.innerHTML = items.map(item => this.itemTemplate(item)).join('');
+ }
+
+ itemTemplate(item) {
+ const resolutionLabel = item.requestedResolution ? item.requestedResolution.label : '';
+
+ return `
+
+
+
+
+
+
${escape(item.name)}
+ ${item.variant ? `
${escape(item.variant)}
` : ''}
+
${escape(item.formatted_price)}
+
+
+
+
Return Quantity:
+ ${escape(item.quantity)}
+
+
+
Request
+ ${escape(resolutionLabel)}
+
+
+
Reason
+ ${escape(item.requestedReason)}
+
+
+ `;
+ }
+
+ renderSummary() {
+ const summary = this.root.querySelector('[data-return-summary]');
+ if (!summary) return;
+
+ const { opened, lastUpdated, order } = this.pageData;
+ const rows = [
+ { label: 'Submitted:', value: opened },
+ { label: 'Last update:', value: lastUpdated },
+ { label: 'Order#:', value: order.id },
+ ];
+
+ summary.innerHTML = rows.map(({ label, value }) => `
+
+
${escape(label)}
+ ${escape(value)}
+ `).join('');
+ }
+}
diff --git a/assets/scss/components/_components.scss b/assets/scss/components/_components.scss
index 82482864d3..0bd4222272 100644
--- a/assets/scss/components/_components.scss
+++ b/assets/scss/components/_components.scss
@@ -105,9 +105,15 @@
// Write a Review
@import "stencil/writeReview/component";
-// Add Return
+// Add Return (legacy)
@import "stencil/addReturn/component";
+// Return Details
+@import "stencil/returnDetails/component";
+
+// Create Return
+@import "stencil/createReturn/component";
+
// Product Carousel
@import "stencil/productCarousel/component";
diff --git a/assets/scss/components/stencil/account/_account.scss b/assets/scss/components/stencil/account/_account.scss
index 4c6e9d3a6d..6055fe1f3b 100644
--- a/assets/scss/components/stencil/account/_account.scss
+++ b/assets/scss/components/stencil/account/_account.scss
@@ -49,6 +49,32 @@
}
}
+.account-listItem-summary {
+ align-items: center;
+ display: flex;
+ flex-wrap: wrap;
+ gap: spacing("single");
+ justify-content: space-between;
+ margin-bottom: spacing("single");
+}
+
+.account-listItem-summary-main {
+ align-items: center;
+ display: flex;
+ flex: 1 1 auto;
+ flex-wrap: wrap;
+ gap: spacing("half");
+ min-width: 0;
+
+ .account-product-title {
+ margin: 0;
+ }
+
+ .account-orderStatus-label {
+ margin: 0;
+ }
+}
+
.account-listShipping {
border-bottom: container("border");
font-weight: fontWeight("bold");
@@ -341,6 +367,21 @@
padding: spacing("eighth") spacing("third");
}
+.account-orderStatus-label--open {
+ background-color: color("warning", "light");
+ color: stencilColor("color-textBase");
+}
+
+.account-orderStatus-label--inProgress {
+ background-color: color("success", "light");
+ color: stencilColor("color-textBase");
+}
+
+.account-orderStatus-label--closed {
+ background-color: color("greys", "lighter");
+ color: stencilColor("color-textBase");
+}
+
.account-orderStatus-action {
color: stencilColor("color-textSecondary");
display: inline-block;
diff --git a/assets/scss/components/stencil/addReturn/_addReturn.scss b/assets/scss/components/stencil/addReturn/_addReturn.scss
index 1c120b9746..2360918089 100644
--- a/assets/scss/components/stencil/addReturn/_addReturn.scss
+++ b/assets/scss/components/stencil/addReturn/_addReturn.scss
@@ -137,3 +137,5 @@
width: grid-calc(6, $total-columns);
}
}
+
+
diff --git a/assets/scss/components/stencil/createReturn/_component.scss b/assets/scss/components/stencil/createReturn/_component.scss
new file mode 100644
index 0000000000..99d4c0f164
--- /dev/null
+++ b/assets/scss/components/stencil/createReturn/_component.scss
@@ -0,0 +1,7 @@
+// =============================================================================
+// CREATE RETURN PAGE
+// =============================================================================
+
+
+// Component
+@import "createReturn";
diff --git a/assets/scss/components/stencil/createReturn/_createReturn.scss b/assets/scss/components/stencil/createReturn/_createReturn.scss
new file mode 100644
index 0000000000..18c4072c6f
--- /dev/null
+++ b/assets/scss/components/stencil/createReturn/_createReturn.scss
@@ -0,0 +1,237 @@
+// =============================================================================
+// CREATE RETURN PAGE (.newReturn)
+// =============================================================================
+
+.newReturn {
+ color: color("link");
+ max-width: remCalc(1100px);
+ margin: 0 auto;
+ padding: 0 spacing("single") spacing("double");
+}
+
+.newReturn-header {
+ display: flex;
+ align-items: center;
+ justify-content: space-between;
+ flex-wrap: wrap;
+ gap: spacing("quarter");
+ margin-bottom: spacing("eighth");
+}
+
+.newReturn-titleGroup {
+ display: flex;
+ align-items: center;
+ gap: spacing("half");
+}
+
+.newReturn-title {
+ font-size: remCalc(28px);
+ font-weight: fontWeight("bold");
+ margin: 0;
+}
+
+.newReturn-statusBadge {
+ display: inline-block;
+ padding: spacing("eighth") spacing("quarter");
+ border: remCalc(1.5px) solid color("orderStatus", "completed");
+ border-radius: remCalc(4px);
+ font-size: remCalc(11px);
+ font-weight: fontWeight("bold");
+ letter-spacing: remCalc(1px);
+ color: color("orderStatus", "completed");
+ text-transform: uppercase;
+}
+
+.newReturn-headerActions {
+ display: flex;
+ align-items: center;
+ gap: spacing("half");
+}
+
+.newReturn-headerActions .button {
+ font-size: fontSize("smallest");
+ padding: spacing("quarter") spacing("half");
+ margin: 0;
+}
+
+.newReturn-orderDate {
+ font-size: remCalc(13px);
+ color: color("greys", "base");
+ margin: spacing("eighth") 0 spacing("single") * 0.83;
+}
+
+.newReturn-divider {
+ border: 0;
+ border-top: container("border");
+ margin: spacing("single") 0;
+}
+
+
+.newReturn-orderLineItem {
+ display: flex;
+ align-items: flex-start; // controls column is tallest when stacked (mobile/tablet)
+ gap: remCalc(16px);
+ padding: remCalc(16px) 0;
+
+ @include breakpoint("large") {
+ align-items: center; // desktop: everything inline so vertical-center is fine
+ }
+}
+
+.newReturn-orderLineItemThumbnailWrapper {
+ flex-shrink: 0;
+ line-height: 0; // collapse inline whitespace around the img
+
+ img {
+ border: remCalc(1px) solid color("greys", "lightest");
+ }
+}
+
+.newReturn-orderLineItemThumbnail {
+ width: remCalc(72px);
+ height: remCalc(72px);
+ object-fit: cover;
+ border-radius: remCalc(6px);
+ flex-shrink: 0;
+ background: color("greys", "lighter");
+}
+
+.newReturn-orderLineItemInfo {
+ flex: 1;
+ min-width: 0;
+}
+
+.newReturn-orderLineItemName {
+ font-size: remCalc(15px);
+ font-weight: fontWeight("semibold");
+ margin: 0 0 remCalc(2px);
+}
+
+.newReturn-orderLineItemVariant {
+ font-size: remCalc(13px);
+ color: color("greys", "base");
+ margin: 0 0 remCalc(2px);
+}
+
+.newReturn-orderLineItemPrice {
+ font-size: remCalc(13px);
+ color: color("greys", "base");
+ margin: 0;
+}
+
+.newReturn-orderLineItemControls {
+ display: flex;
+ flex-direction: column;
+ align-items: stretch;
+ gap: spacing("quarter");
+ flex-shrink: 0;
+ width: remCalc(180px);
+
+ @include breakpoint("large") {
+ flex-direction: row;
+ align-items: center;
+ gap: spacing("half");
+ width: auto;
+ }
+}
+
+.newReturn-divider--headers {
+ display: none;
+
+ @include breakpoint("large") {
+ display: block;
+ }
+}
+
+.newReturn-columnHeaders {
+ display: none;
+
+ @include breakpoint("large") {
+ display: flex;
+ align-items: center;
+ gap: remCalc(16px);
+ font-size: remCalc(12px);
+ font-weight: fontWeight("semibold");
+ color: color("greys", "base");
+ letter-spacing: remCalc(0.5px);
+ }
+}
+
+// "Item" aligns with the thumbnail left edge, not the item name.
+.newReturn-columnHeaders-spacer {
+ display: none;
+}
+
+.newReturn-columnHeaders-item {
+ flex: 1;
+ min-width: 0;
+}
+
+.newReturn-columnHeaders-controls {
+ display: flex;
+ align-items: center;
+ gap: spacing("half");
+}
+
+// Shared widths — keeps header labels and control cells in sync.
+$newReturn-col-qty: remCalc(120px);
+$newReturn-col-select: remCalc(200px);
+
+.newReturn-columnHeaders-quantity {
+ width: $newReturn-col-qty;
+ flex-shrink: 0;
+}
+
+.newReturn-columnHeaders-request,
+.newReturn-columnHeaders-reason {
+ width: $newReturn-col-select;
+ flex-shrink: 0;
+}
+
+.newReturn-orderLineItemQtyWrapper {
+ display: flex;
+ align-items: center;
+ gap: spacing("quarter");
+
+ @include breakpoint("large") {
+ width: $newReturn-col-qty;
+ flex-shrink: 0;
+ }
+}
+
+.newReturn-orderLineItemMaxQty {
+ font-size: remCalc(13px);
+ color: color("greys", "base");
+ white-space: nowrap;
+}
+
+.newReturn-orderLineItemControls [id^="qty-"] {
+ width: 100%;
+
+ @include breakpoint("large") {
+ width: auto;
+ }
+}
+
+.newReturn-orderLineItemControls [id^="resolution-"],
+.newReturn-orderLineItemControls [id^="reason-"] {
+ width: 100%;
+
+ @include breakpoint("large") {
+ width: $newReturn-col-select;
+ flex-shrink: 0;
+ }
+}
+
+.newReturn-footer {
+ margin-top: spacing("single");
+
+ @include breakpoint("medium") {
+ width: 50%;
+ margin-left: auto;
+ }
+
+ .form-actions {
+ text-align: right;
+ }
+}
diff --git a/assets/scss/components/stencil/returnDetails/_component.scss b/assets/scss/components/stencil/returnDetails/_component.scss
new file mode 100644
index 0000000000..c7a8c1582a
--- /dev/null
+++ b/assets/scss/components/stencil/returnDetails/_component.scss
@@ -0,0 +1,7 @@
+// =============================================================================
+// RETURN DETAILS
+// =============================================================================
+
+
+// Component
+@import "returnDetails";
diff --git a/assets/scss/components/stencil/returnDetails/_returnDetails.scss b/assets/scss/components/stencil/returnDetails/_returnDetails.scss
new file mode 100644
index 0000000000..ba78ea6ea3
--- /dev/null
+++ b/assets/scss/components/stencil/returnDetails/_returnDetails.scss
@@ -0,0 +1,241 @@
+// =============================================================================
+// RETURN DETAILS PAGE (.returnDetails)
+// =============================================================================
+
+
+.returnDetails {
+ color: stencilColor("color-textBase");
+ max-width: remCalc(1200px);
+ margin: 0 auto;
+ padding: 0 spacing("single") spacing("double");
+}
+
+.returnDetails-titleGroup {
+ display: flex;
+ align-items: center;
+ gap: spacing("half");
+}
+
+.returnDetails-title {
+ font-family: $header-font-family;
+ font-size: $h1-font-size;
+ font-weight: $header-font-weight;
+ margin: 0;
+}
+
+.returnDetails-statusBadge {
+ display: inline-block;
+ padding: spacing("eighth") spacing("quarter");
+ border-radius: remCalc(4px);
+ font-size: remCalc(11px);
+ font-weight: fontWeight("bold");
+ letter-spacing: remCalc(1px);
+ text-transform: uppercase;
+ background-color: stencilColor("label-backgroundColor");
+ color: stencilColor("label-color");
+}
+
+.returnDetails-statusBadge--open {
+ background-color: color("warning", "light");
+ color: stencilColor("color-textBase");
+}
+
+.returnDetails-statusBadge--in_progress {
+ background-color: color("success", "light");
+ color: stencilColor("color-textBase");
+}
+
+.returnDetails-statusBadge--closed {
+ background-color: color("greys", "lighter");
+ color: stencilColor("color-textBase");
+}
+
+.returnDetails-divider {
+ border: 0;
+ border-top: container("border");
+ margin: spacing("single") 0;
+}
+
+.returnDetails-sectionHeading {
+ font-family: $header-font-family;
+ font-size: $h1-font-size;
+ font-weight: $header-font-weight;
+ margin: 0;
+ color: stencilColor("color-textBase");
+}
+
+
+// =============================================================================
+// SHIPPING — single address + method, shown above the line items
+// =============================================================================
+
+.returnDetails-shipping {
+ margin: 0 0 spacing("single");
+ display: flex;
+ flex-direction: column;
+ gap: remCalc(6px);
+}
+
+.returnDetails-shippingRow {
+ display: flex;
+ align-items: baseline;
+ gap: remCalc(8px);
+ font-size: remCalc(14px);
+}
+
+.returnDetails-shippingLabel {
+ flex-shrink: 0;
+ font-weight: fontWeight("semibold");
+ color: stencilColor("color-textSecondary");
+ margin: 0;
+}
+
+.returnDetails-shippingValue {
+ margin: 0;
+ color: stencilColor("color-textBase");
+}
+
+
+// =============================================================================
+// LAYOUT — main items column + sidebar
+// =============================================================================
+
+.returnDetails-layout {
+ display: grid;
+ grid-template-columns: 1fr;
+ gap: spacing("single") * 2;
+
+ @include breakpoint("medium") {
+ grid-template-columns: minmax(0, 2fr) minmax(0, 1fr);
+ }
+}
+
+.returnDetails-main {
+ min-width: 0;
+}
+
+.returnDetails-sidebar {
+ min-width: 0;
+}
+
+
+// =============================================================================
+// ITEM LIST (flat, by line items)
+// =============================================================================
+
+.returnDetails-itemList {
+ list-style: none;
+ margin: 0;
+ padding: 0;
+}
+
+.returnDetails-item {
+ display: flex;
+ align-items: flex-start;
+ gap: remCalc(16px);
+ padding: remCalc(16px) 0;
+ border-bottom: container("border");
+
+ &:last-child {
+ border-bottom: 0;
+ }
+
+ @include breakpoint("large") {
+ align-items: center;
+ }
+}
+
+.returnDetails-itemThumbnailWrapper {
+ flex-shrink: 0;
+ line-height: 0;
+}
+
+.returnDetails-itemThumbnail {
+ width: remCalc(72px);
+ height: remCalc(72px);
+ object-fit: cover;
+ border-radius: remCalc(6px);
+ background: color("greys", "lighter");
+}
+
+.returnDetails-itemInfo {
+ flex: 1;
+ min-width: 0;
+}
+
+.returnDetails-itemName {
+ font-size: remCalc(15px);
+ font-weight: fontWeight("semibold");
+ margin: 0 0 remCalc(2px);
+ color: stencilColor("color-textBase");
+}
+
+.returnDetails-itemVariant {
+ font-size: remCalc(13px);
+ color: stencilColor("color-textSecondary");
+ margin: 0 0 remCalc(2px);
+}
+
+.returnDetails-itemPrice {
+ font-size: remCalc(13px);
+ color: color("greys", "dark");
+ margin: 0;
+}
+
+// Right-aligned key/value column for Return Quantity / Request / Reason.
+.returnDetails-itemMeta {
+ flex-shrink: 0;
+ width: remCalc(240px);
+ margin: 0;
+ display: flex;
+ flex-direction: column;
+ gap: remCalc(4px);
+}
+
+.returnDetails-itemMetaRow {
+ display: flex;
+ align-items: baseline;
+ gap: remCalc(6px);
+ font-size: remCalc(13px);
+}
+
+.returnDetails-itemMetaLabel {
+ font-weight: fontWeight("semibold");
+ color: stencilColor("color-textSecondary");
+ margin: 0;
+}
+
+.returnDetails-itemMetaValue {
+ margin: 0;
+ color: stencilColor("color-textBase");
+}
+
+
+// =============================================================================
+// SIDEBAR — Summary
+// =============================================================================
+
+.returnDetails-summaryList {
+ margin: 0;
+ display: flex;
+ flex-direction: column;
+ gap: remCalc(6px);
+}
+
+.returnDetails-summaryRow {
+ display: flex;
+ align-items: baseline;
+ gap: remCalc(6px);
+ font-size: remCalc(14px);
+}
+
+.returnDetails-summaryLabel {
+ font-weight: fontWeight("semibold");
+ color: stencilColor("color-textSecondary");
+ margin: 0;
+}
+
+.returnDetails-summaryValue {
+ margin: 0;
+ color: stencilColor("color-textBase");
+}
diff --git a/lang/en.json b/lang/en.json
index 6234f8b366..c7c732a195 100755
--- a/lang/en.json
+++ b/lang/en.json
@@ -340,6 +340,8 @@
"order_item": "Item",
"item_price": "Price",
"quantity": "Qty To Return",
+ "of_max": "of {max}",
+ "items_label": "Items in this order",
"why": "Why are you returning these items?",
"reason": "Return Reason",
"action": "Return Action",
@@ -446,7 +448,10 @@
"error_no_qty": "Please select one or more items to return.",
"none": "You haven't placed any returns with us. When you do, they will appear on this page.",
"new_return": "New Return",
- "from_order": "Return Items from Order #{id}",
+ "from_order": "Request Return for Order #{id}",
+ "order_date": "Order date",
+ "select_resolution": "Select preferred resolution",
+ "select_reason": "Select a return reason",
"date_requested": "Return Requested",
"successful_heading": "Return Request Submitted",
"successful": "Your return was submitted successfully. We'll respond as soon as we can.",
@@ -456,11 +461,28 @@
"action": "Return Action",
"comments": "Your Comments",
"submit_request": "Submit Return Request",
+ "additional_note_placeholder": "Please describe any additional details of this return request.",
+ "submit": "Submit Return",
+ "summary": "Summary",
+ "back": "Back",
+ "view_return_policy": "View return policy",
+ "additional_note": "Additional Note",
+ "request": "Preferred resolution",
+ "reason_header": "Return reason",
+ "qty": "Qty:",
+ "total_price": "Total:",
"list": {
+ "last_update":"Last Update",
+ "return_submitted": "Return Submitted",
"return_number": "Return #{id}",
- "product_details": "Returning {num_products}"
+ "product_details": "Returning {num_products}",
+ "return_items": "Return Items",
+ "view_details": "View details"
},
"status": {
+ "open":"OPEN",
+ "closed": "CLOSED",
+ "in_progress":"IN PROGRESS",
"pending": "Pending",
"received": "Received",
"authorized": "Authorized",
diff --git a/templates/components/account/orders-list.html b/templates/components/account/orders-list.html
index d54f78c772..7da8381ccd 100644
--- a/templates/components/account/orders-list.html
+++ b/templates/components/account/orders-list.html
@@ -23,12 +23,12 @@ {{lang 'account.orders.heading' }}
{{this.status}}
- {{#if ../settings.returns_enabled}}
- {{#if this.return_url}}
+ {{#if this.return_url}}
+ {{#or ../settings.returns_v2_enabled ../settings.returns_enabled}}
{{lang 'account.orders.return_items' }}
- {{/if}}
+ {{/or}}
{{/if}}
diff --git a/templates/components/account/returns-list-v2.html b/templates/components/account/returns-list-v2.html
new file mode 100644
index 0000000000..faf527db8f
--- /dev/null
+++ b/templates/components/account/returns-list-v2.html
@@ -0,0 +1,36 @@
+
{{lang 'account.returns.heading' }}
+
+
+ {{#each returns}}
+
+
+
+
{{lang 'account.returns.list.return_number' id=rma}}
+ {{#if status '===' 'OPEN'}}
+ {{lang 'account.returns.status.open'}}
+ {{else if status '===' 'IN_PROGRESS'}}
+ {{lang 'account.returns.status.in_progress'}}
+ {{else if status '===' 'CLOSED'}}
+ {{lang 'account.returns.status.closed'}}
+ {{/if}}
+
+
{{lang 'account.returns.list.view_details'}}
+
+
+
+
+
{{lang 'account.returns.list.return_submitted' }}
+ {{moment dateSubmitted format="Do MMM YYYY"}}
+
+
+
{{lang 'account.returns.list.last_update' }}
+ {{#if lastUpdated}}{{moment lastUpdated format="Do MMM YYYY"}}{{else}}{{moment dateSubmitted format="Do MMM YYYY"}}{{/if}}
+
+
+
{{lang 'account.returns.list.return_items' }}
+ {{items.length}}
+
+
+
+ {{/each}}
+
\ No newline at end of file
diff --git a/templates/pages/account/add-return.html b/templates/pages/account/add-return.html
index 0bda0cc689..9130fc8813 100644
--- a/templates/pages/account/add-return.html
+++ b/templates/pages/account/add-return.html
@@ -20,7 +20,7 @@
{{lang 'account.returns.from_order' id=forms.return.
>
-
+
{{lang 'account.orders.return.order_item'}}
@@ -44,8 +44,8 @@ {{lang 'account.returns.from_order' id=forms.return.
{{price.formatted}}
- {{lang 'account.orders.return.quantity'}}:
-
+ {{lang 'account.orders.return.quantity'}}:
+
{{#for 0 quantity}}
{{$index}}
{{/for}}
diff --git a/templates/pages/account/orders/details.html b/templates/pages/account/orders/details.html
index c669ad5627..f10eb976b1 100644
--- a/templates/pages/account/orders/details.html
+++ b/templates/pages/account/orders/details.html
@@ -183,11 +183,11 @@ {{lang 'account.orders.details.actions'}}
{{/each}}
- {{#if settings.returns_enabled}}
+ {{#or settings.returns_v2_enabled settings.returns_enabled}}
{{#if order.is_complete}}
{{lang 'account.orders.details.return'}}
{{/if}}
- {{/if}}
+ {{/or}}
diff --git a/templates/pages/account/return-details.html b/templates/pages/account/return-details.html
new file mode 100644
index 0000000000..11e558e81b
--- /dev/null
+++ b/templates/pages/account/return-details.html
@@ -0,0 +1,48 @@
+{{#partial "page"}}
+
+{{!--
+ Standalone return-details page. Not yet routed — a page type still needs to be
+ mapped to this template (and `getReturnDetails` wired up in assets/js/app.js)
+ before it's reachable. For now it exists to hold the correct layout.
+
+ The JS module at assets/js/theme/return-details.js owns the mock data
+ (shaped after the returns-ui Return/Item interfaces in
+ returns-ui/src/apps/ManageReturn/Page/index.tsx) and renders into the
+ [data-*] hooks below.
+--}}
+
+{{!-- Localized status labels for the JS status badge (mirrors the returns list). --}}
+{{~inject 'returnStatusOpen' (lang 'account.returns.status.open')}}
+{{~inject 'returnStatusInProgress' (lang 'account.returns.status.in_progress')}}
+{{~inject 'returnStatusClosed' (lang 'account.returns.status.closed')}}
+
+{{> components/common/breadcrumbs breadcrumbs=breadcrumbs}}
+{{> components/account/navigation account_page='returns'}}
+
+
+
+
+
+{{/partial}}
+{{> layout/base}}
diff --git a/templates/pages/account/returns.html b/templates/pages/account/returns.html
index 15047bf7c1..8b1c4cf883 100644
--- a/templates/pages/account/returns.html
+++ b/templates/pages/account/returns.html
@@ -7,14 +7,30 @@ {{lang 'account.returns.heading' }}
- {{#if customer.returns}}
- {{> components/account/returns-list returns=customer.returns}}
+
+ {{#if settings.returns_v2_enabled}}
+
+ {{#if returns.length}}
+ {{!-- TODO: ORDERS-7751 When a per-return details route (e.g. action=view_return&return_id=X) exists, this list should link to it. --}}
+ {{> components/account/returns-list-v2 returns=returns}}
+ {{else}}
+ {{> components/common/alert/alert-info (lang 'account.returns.none')}}
+ {{/if}}
+
{{else}}
- {{> components/common/alert/alert-info (lang 'account.returns.none')}}
+
+ {{#if customer.returns}}
+ {{> components/account/returns-list returns=customer.returns}}
+ {{else}}
+ {{> components/common/alert/alert-info (lang 'account.returns.none')}}
+ {{/if}}
+
{{/if}}
+
{{/partial}}
{{> layout/base}}
+
diff --git a/templates/pages/create-return.html b/templates/pages/create-return.html
new file mode 100644
index 0000000000..6cfc282378
--- /dev/null
+++ b/templates/pages/create-return.html
@@ -0,0 +1,123 @@
+{{#partial "page"}}
+
+{{~inject 'order' order}}
+
+
+ {{#with order}}
+
+
+ {{#if date}}{{lang 'account.returns.order_date'}}: {{date}}
{{/if}}
+
+
+
+
+
+ {{/with}}
+
+
+
+{{/partial}}
+{{> layout/base}}
diff --git a/templates/pages/guest-return-portal.html b/templates/pages/guest-return-portal.html
new file mode 100644
index 0000000000..9546e3843d
--- /dev/null
+++ b/templates/pages/guest-return-portal.html
@@ -0,0 +1,9 @@
+{{#partial "page"}}
+
+{{> components/common/breadcrumbs breadcrumbs=breadcrumbs}}
+
+ Guest Return Portal
+
+{{/partial}}
+
+{{> layout/base}}