Files
moalem-shop/src/lib/format.ts
T
amirhosein.ashourlooandClaude Sonnet 5 4ffdf03727 Rewrite cart as client-only guest cart per AI_PROMPT.md spec
Replaces the previous server-cart implementation (which wrongly called
the customer-dashboard-only /businesses/{id}/cart* API) with the
documented guest-cart architecture:

- src/lib/guestCart.ts: storage key/cookie name, cookie attributes,
  line shape, and encodeGuestCart() copied verbatim from AI_PROMPT.md
- CartProvider/CartButton: pure client state (localStorage + mirrored
  cookie), no bearer auth, no businessId
- CartButton's "ادامه" builds the exact documented Continue URL,
  branching on hasCustomerSessionCookie() to either
  customer.<domain>/checkout/cart?guestCart=<encoded> or
  .../login?redirect=<encoded checkout path>
- Auth cookie corrected to the real documented name
  (meshkee_customer_access_token, possibly chunked) via a shared
  reassembleChunkedCookie() helper used by both auth.ts (server) and
  authUser.ts (client)
- ProductBuyPanel/product pages switched to the documented
  GET .../store-items/by-product/{id} endpoint (getStoreItemByProduct)
- isInStock() treats stockQuantity === null as unlimited stock, not
  out-of-stock, per spec
- AGENTS.md updated to describe this architecture and remove the
  incorrect server-cart documentation

Manually verified in-browser: badge count, popup lines/qty/remove/
total all update correctly against injected guest-cart data; tsc,
eslint, and next build all pass clean.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-09-06 13:29:30 +03:30

31 lines
1.3 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const FA_DIGITS = ["۰", "۱", "۲", "۳", "۴", "۵", "۶", "۷", "۸", "۹"];
export function toFaDigits(input: string | number): string {
return String(input).replace(/\d/g, (d) => FA_DIGITS[Number(d)]);
}
// Prices come from the API in Toman.
export function formatPrice(value: number | null | undefined): string {
if (value === null || value === undefined) return "";
return toFaDigits(value.toLocaleString("en-US"));
}
export function discountPercent(price: number, oldPrice: number): number {
if (!oldPrice || oldPrice <= price) return 0;
return Math.round(((oldPrice - price) / oldPrice) * 100);
}
// Per AI_PROMPT.md "Shopping cart" step 3: a variant's stockQuantity of
// `null` means unlimited stock (in stock), not zero/out of stock — never
// treat it as falsy.
export function isInStock(stockQuantity: number | null | undefined): boolean {
return stockQuantity === null || (stockQuantity ?? 0) > 0;
}
// The static-image-slot API documents aspectRatio as "16:9", but CSS's
// aspect-ratio property needs a slash ("16/9"), not a colon.
export function toCssAspectRatio(value: string | number | null | undefined): string | undefined {
if (value === null || value === undefined || value === "") return undefined;
return String(value).replace(":", "/");
}