Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
6 changes: 3 additions & 3 deletions app/[locale]/admin/configuration/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 { requireAdmin } from '@/shared/authorization/require-admin';
import { ListCategoriesUseCase } from '@/modules/products/application/list-categories-use-case';
import { ConfigurationForm } from './configuration-form';
import { resolveCategoryDisplay } from '@/modules/products/domain/entities/category-translation';
import styles from './page.module.css';
Expand All @@ -16,8 +15,9 @@ export default async function AdminConfigurationPage({
await requireAdmin(locale);

const dict = await getDictionary(locale as 'es' | 'cat');
const useCase = new ListCategoriesUseCase(container.getCategoryRepository());
const categories = await useCase.execute(locale === 'cat' ? 'cat' : 'es');
const categories = await container
.getListCategoriesUseCase()
.execute(locale === 'cat' ? 'cat' : 'es');

return (
<div className={styles.container}>
Expand Down
4 changes: 1 addition & 3 deletions app/[locale]/admin/sellers/[sellerId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { notFound } from 'next/navigation';
import { container } from '@/composition-root/container';
import { getDictionary } from '@/shared/i18n/get-dictionary';
import { NotFoundError } from '@/shared/kernel/app-error';
import { GetSellerUseCase } from '@/modules/sellers/application/use-cases/get-seller-use-case';
import { requireAdmin } from '@/shared/authorization/require-admin';
import { BackLink } from '@/shared/ui/back-link';
import { Card } from '@/shared/ui/card';
Expand All @@ -19,8 +18,7 @@ export default async function AdminSellerDetailPage({
await requireAdmin(locale);

const dict = await getDictionary(locale as 'es' | 'cat');
const sellerRepository = container.getSellerRepository();
const getSeller = new GetSellerUseCase(sellerRepository);
const getSeller = container.getSellerUseCase();

let seller;
try {
Expand Down
12 changes: 4 additions & 8 deletions app/[locale]/admin/sellers/[sellerId]/products/page.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { BackLink } from '@/shared/ui/back-link';
import { container } from '@/composition-root/container';
import { ProductListQueryUseCase } from '@/modules/products/application/product-list-query-use-case';
import { productListQuerySchema } from '@/modules/products/presentation/schemas/product-list-query-schema';
import { GetSellerUseCase } from '@/modules/sellers/application/use-cases/get-seller-use-case';
import { getDictionary } from '@/shared/i18n/get-dictionary';
import { PaginationDefaults } from '@/shared/kernel/domain/value-objects/pagination';
import { SearchForm } from '@/shared/ui/search-form';
Expand Down Expand Up @@ -40,14 +38,12 @@ export default async function AdminSellerProductsPage({

const dict = await getDictionary(locale as 'es' | 'cat');

const sellerRepository = container.getSellerRepository();
const getSeller = new GetSellerUseCase(sellerRepository);
const seller = await getSeller.execute({ sellerId });
const seller = await container.getSellerUseCase().execute({ sellerId });
const sellerName = seller.name;

const productRepository = container.getProductRepository();
const useCase = new ProductListQueryUseCase(productRepository);
const result = await useCase.execute({ ...filter, audience: 'admin' });
const result = await container
.getProductListQueryUseCase()
.execute({ ...filter, audience: 'admin' });
const { items: products, totalPages } = result;
let page = result.page;

Expand Down
5 changes: 1 addition & 4 deletions app/[locale]/admin/sellers/page.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { redirect } from 'next/navigation';
import Link from 'next/link';
import { container } from '@/composition-root/container';
import { ListSellersUseCase } from '@/modules/sellers/application/use-cases/list-sellers-use-case';
import { listSellersQuerySchema } from '@/modules/sellers/presentation/schemas/seller-schemas';
import { getDictionary } from '@/shared/i18n/get-dictionary';
import { LocalizedDate } from '@/shared/kernel/domain/value-objects/localized-date';
Expand Down Expand Up @@ -56,9 +55,7 @@ export default async function AdminSellersPage({
});

const dict = await getDictionary(locale as 'es' | 'cat');
const sellerRepository = container.getSellerRepository();
const useCase = new ListSellersUseCase(sellerRepository);
const result = await useCase.execute(filter);
const result = await container.getListSellersUseCase().execute(filter);
const { items: sellers, page: currentPage, pageSize, totalPages } = result;

// Redirect to valid page if current page is out of range
Expand Down
99 changes: 9 additions & 90 deletions app/[locale]/cart/page.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,9 @@
import { getServerSession } from 'next-auth';
import { authOptions } from '@/shared/infrastructure/auth-options';
import { container } from '@/composition-root/container';
import { GetCart } from '@/modules/cart/application/get-cart';
import { getDictionary } from '@/shared/i18n/get-dictionary';
import {
CartView,
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';
import { resolveDisplay } from '@/modules/products/domain/entities/product-translation';
import { CartView } from '@/modules/cart/presentation/components/cart-view';
import type { CartViewItem } from '@/modules/cart/application/get-cart-view-use-case';

/**
* Cart page — RSC shell.
Expand All @@ -33,73 +27,15 @@ export default async function CartPage({
const session = await getServerSession(authOptions);
const isAuthenticated = !!session?.user?.id;

let items: CartItemDTO[] = [];
let items: CartViewItem[] = [];

if (isAuthenticated) {
const cartRepository = container.getCartRepository();
const getCart = new GetCart(cartRepository);
const cart = await getCart.execute(session.user.id);

if (cart.items.length > 0) {
// Enrich items with product display data.
const productRepository = container.getProductRepository();
const productIds = [...new Set(cart.items.map((i) => i.productId.value))];
const products = await Promise.all(
productIds.map((id) => productRepository.findById(id, locale)),
);
const productMap = new Map<string, ProductEntity>();
for (const p of products) {
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,
productName:
resolveDisplay(product?.translations ?? [], locale)?.name ??
'Unknown Product',
productImageUrl: product?.images?.[0]?.url ?? null,
sellerId: item.sellerId.value,
sellerName: product?.sellerName ?? 'Unknown Seller',
quantity: item.quantity,
unitPrice: item.unitPriceSnapshot.amount,
lineTotal: +(item.unitPriceSnapshot.amount * item.quantity).toFixed(
2,
),
customization: {
text: snapshot?.text ?? null,
color: snapshot?.color ?? null,
size: snapshot?.size ?? null,
imageUrl: snapshot?.imageUrl ?? null,
imageUploadId: null,
colorImageUrl: null,
designPosition: snapshot?.designPosition ?? null,
},
};
});
}
({ items } = await container.getCartViewUseCase().execute({
userId: session.user.id,
locale,
unknownProductName: dict.common.unknownProduct,
unknownSellerName: dict.common.unknownSeller,
}));
}

return (
Expand Down Expand Up @@ -130,20 +66,3 @@ export default async function CartPage({
/>
);
}

/**
* 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;
}
Loading
Loading