feat: Wabenhain Honig-Shop Anwendung
Vollstaendige Next.js/Prisma-E-Commerce-Anwendung fuer eine Imkerei: Shop, Warenkorb, Stripe-Checkout, Kundenkonto mit 2FA, Admin-Bereich (Produkte, Ernten, Chargen, Bestellungen, Gutscheine, admin-editierbare Website-Inhalte), i18n (DE/EN), Rate-Limiting/CSP/Audit-Log-Haertung, PostgreSQL- und MySQL-Unterstuetzung ueber austauschbare Prisma- Treiber-Adapter, Unit-/Komponenten-/E2E-Tests.
This commit is contained in:
1 parent
5c76fcc266
commit
c7927f2883
240 files changed
+26096
-137
No files matched your search
@@ -0,0 +1,47 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { useRecentlyViewedStore } from "@/store/recently-viewed-store";
|
||||
import { getRecentlyViewedProducts } from "@/app/shop/actions";
|
||||
import { ProductCard } from "@/components/product-card";
|
||||
import { useI18n } from "@/i18n/i18n-provider";
|
||||
import type { ProductWithRelations } from "@/lib/data";
|
||||
|
||||
/**
|
||||
* Zeigt zuletzt angesehene Produkte (aus dem lokalen Verlauf) als Raster,
|
||||
* optional ohne das aktuell angezeigte Produkt selbst. Rendert nichts, wenn
|
||||
* (noch) keine oder keine anzeigbaren Produkte vorliegen.
|
||||
*/
|
||||
export function RecentlyViewedSection({ excludeProductId }: { excludeProductId?: string }) {
|
||||
const { t } = useI18n();
|
||||
const viewedIds = useRecentlyViewedStore((s) => s.viewedIds);
|
||||
const [products, setProducts] = useState<ProductWithRelations[]>([]);
|
||||
|
||||
useEffect(() => {
|
||||
const ids = viewedIds.filter((id) => id !== excludeProductId);
|
||||
if (ids.length === 0) {
|
||||
setProducts([]);
|
||||
return;
|
||||
}
|
||||
let cancelled = false;
|
||||
getRecentlyViewedProducts(ids).then((result) => {
|
||||
if (!cancelled) setProducts(result);
|
||||
});
|
||||
return () => {
|
||||
cancelled = true;
|
||||
};
|
||||
}, [viewedIds, excludeProductId]);
|
||||
|
||||
if (products.length === 0) return null;
|
||||
|
||||
return (
|
||||
<div className="mt-20">
|
||||
<h2 className="text-2xl text-forest mb-8">{t.productPage.recentlyViewedHeading}</h2>
|
||||
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 gap-x-8 gap-y-14">
|
||||
{products.map((product) => (
|
||||
<ProductCard key={product.id} product={product} />
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user