Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 48 additions & 5 deletions app/[locale]/cart/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,14 @@ import {
type CartItemDTO,
} from '@/modules/cart/presentation/components/cart-view';
import type { ProductEntity } from '@/modules/products/domain/product-repository';
import type { CustomizationSnapshot } from '@/modules/cart/domain/customization-lookup-port';

/**
* Cart page — RSC shell.
*
* - Authenticated users: fetches the server cart via GetCart, enriches
* items with product display data, and passes them to <CartView />.
* items with product display data and customization snapshots, and
* passes them to <CartView />.
* - Unauthenticated users: passes an empty items array; the <CartView />
* will be hydrated on the client via the GuestCartContext (which is
* provided at the layout level).
Expand Down Expand Up @@ -49,8 +51,28 @@ export default async function CartPage({
if (p) productMap.set(p.id, p);
}

// Resolve customization snapshots from customizationIdList.
// The cart module never imports the customizations module directly;
// the container wires a CustomizationLookupAdapter at runtime.
const allCustomizationIds = cart.items.flatMap(
(item) => item.customizationIdList,
);
const uniqueCustomizationIds = [...new Set(allCustomizationIds)];
const customizationLookup = container.getCustomizationLookup();
const customizationSnapshots =
uniqueCustomizationIds.length > 0
? await customizationLookup.findByIds(uniqueCustomizationIds)
: [];
const customizationMap = new Map(
customizationSnapshots.map((s: CustomizationSnapshot) => [s.id, s]),
);

items = cart.items.map((item) => {
const product = productMap.get(item.productId.value);
const snapshot = resolveCustomizationSnapshot(
item.customizationIdList,
customizationMap,
);
return {
id: item.id,
productId: item.productId.value,
Expand All @@ -64,10 +86,13 @@ export default async function CartPage({
2,
),
customization: {
text: null,
color: null,
size: null,
imageUrl: null,
text: snapshot?.text ?? null,
color: snapshot?.color ?? null,
size: snapshot?.size ?? null,
imageUrl: snapshot?.imageUrl ?? null,
imageUploadId: null,
colorImageUrl: null,
designPosition: snapshot?.designPosition ?? null,
},
};
});
Expand Down Expand Up @@ -95,9 +120,27 @@ export default async function CartPage({
customizationText: dict.common.customizationText,
increaseQuantity: dict.common.increaseQuantity,
decreaseQuantity: dict.common.decreaseQuantity,
customizationEditFromCart: dict.common.customizationEditFromCart,
customizationDesignImageAlt: dict.common.customizationDesignImageAlt,
price: dict.common.price,
}}
/>
);
}

/**
* Resolves a single item's customization snapshot from the pre-fetched map.
* Returns the first matching snapshot or null when the item has no
* customizations or all IDs were deleted.
*/
function resolveCustomizationSnapshot(
customizationIdList: string[],
customizationMap: Map<string, CustomizationSnapshot>,
): CustomizationSnapshot | null {
if (customizationIdList.length === 0) return null;
for (const id of customizationIdList) {
const snap = customizationMap.get(id);
if (snap) return snap;
}
return null;
}
7 changes: 3 additions & 4 deletions app/[locale]/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { container } from '@/composition-root/container';
import { getDictionary } from '@/shared/i18n/get-dictionary';
import { HeroSection } from '@/shared/ui/hero-section';
import { MiddleSection } from '@/shared/ui/middle-section';
import { WaveTransition } from '@/shared/ui/wave-transition';
import { InfiniteProductList } from '@/components/products/infinite-product-list';
import {
Expand All @@ -12,7 +11,7 @@ import { GetRecentSearchesUseCase } from '@/modules/search-history/application/g
import { ProductListQueryUseCase } from '@/modules/products/application/product-list-query-use-case';
import { serializeProduct } from '@/modules/products/presentation/product-response';

const PUBLIC_PAGE_SIZE = 10;
const PUBLIC_PAGE_SIZE = 12;

export default async function HomePage({
params,
Expand Down Expand Up @@ -82,7 +81,7 @@ export default async function HomePage({

<WaveTransition animatedText={dict.common.slogan} />

<MiddleSection ariaLabel={dict.common.products}>
<section aria-label={dict.common.products}>
<SearchInputWithSuggestions
initialValue={q}
recent={recent}
Expand Down Expand Up @@ -115,7 +114,7 @@ export default async function HomePage({
itemsLoadedMany: dict.common.itemsLoadedMany,
}}
/>
</MiddleSection>
</section>
</div>
);
}
Loading
Loading