@burdenoff/microfe-devportal 2026.1024.1 → 2026.1026.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"SellerItemsPage.js","names":[],"sources":["../../../src/devportal/pages/SellerItemsPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useEffect, useState, useMemo } from \"react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport {\n Plus,\n Search,\n Grid,\n List,\n Package,\n Loader2,\n AlertCircle,\n Edit,\n Tag,\n} from \"lucide-react\";\nimport { EmphasisPanel, GlassCard } from \"@burdenoff/fe-libs/ui\";\nimport { PageLayout } from \"../components/PageLayout\";\nimport { EmptyState } from \"../components/EmptyState\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport { PermissionGuard } from \"../components\";\n\n// ---------------------------------------------------------------------------\n// Local types\n// ---------------------------------------------------------------------------\n\ntype ProductStatus =\n | \"DRAFT\"\n | \"PENDING_REVIEW\"\n | \"PUBLISHED\"\n | \"REJECTED\"\n | \"INACTIVE\";\n\ntype PhysicalProductType =\n | \"MERCHANDISE\"\n | \"HARDWARE\"\n | \"ACCESSORY\"\n | \"BOOK\"\n | \"EQUIPMENT\"\n | \"APPAREL\"\n | \"COLLECTIBLE\"\n | \"CONSUMABLE\";\n\ninterface PhysicalProductDetail {\n id: string;\n name: string;\n slug: string;\n type: string;\n status: ProductStatus;\n price: number;\n currency: string;\n stockQuantity: number;\n sku?: string | null;\n brand?: string | null;\n icon?: string | null;\n createdAt: string;\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/**\n * Digital product types to exclude even if `nature: PHYSICAL` is set wrong.\n */\nconst DIGITAL_TYPES = new Set([\"APP\", \"NODE\", \"WORKFLOW\"]);\n\nconst PRODUCT_TYPE_LABELS: Record<PhysicalProductType, string> = {\n MERCHANDISE: \"Merchandise\",\n HARDWARE: \"Hardware\",\n ACCESSORY: \"Accessory\",\n BOOK: \"Book\",\n EQUIPMENT: \"Equipment\",\n APPAREL: \"Apparel\",\n COLLECTIBLE: \"Collectible\",\n CONSUMABLE: \"Consumable\",\n};\n\nconst STATUS_BADGE_STYLES: Record<\n ProductStatus,\n { label: string; className: string }\n> = {\n PUBLISHED: {\n label: \"Published\",\n className: \"text-status-success-text bg-status-success-bg-subtle\",\n },\n PENDING_REVIEW: {\n label: \"Pending Review\",\n className: \"text-status-warning-text bg-status-warning-bg-subtle\",\n },\n DRAFT: {\n label: \"Draft\",\n className: \"text-text-muted bg-bg-muted\",\n },\n REJECTED: {\n label: \"Rejected\",\n className: \"text-status-error-text bg-status-error-bg/10\",\n },\n INACTIVE: {\n label: \"Inactive\",\n className: \"text-text-muted bg-bg-muted\",\n },\n};\n\nconst STATUS_OPTIONS: { value: ProductStatus | \"\"; label: string }[] = [\n { value: \"\", label: \"All Status\" },\n { value: \"DRAFT\", label: \"Draft\" },\n { value: \"PENDING_REVIEW\", label: \"Pending Review\" },\n { value: \"PUBLISHED\", label: \"Published\" },\n { value: \"REJECTED\", label: \"Rejected\" },\n { value: \"INACTIVE\", label: \"Inactive\" },\n];\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction formatPrice(price: number, currency: string): string {\n const curr = currency || \"USD\";\n const formatted = new Intl.NumberFormat(\"en-US\", {\n style: \"currency\",\n currency: curr,\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n }).format(price);\n return `${formatted} ${curr}`;\n}\n\nfunction resolveTypeLabel(type: string): string {\n return (\n PRODUCT_TYPE_LABELS[type as PhysicalProductType] ?? type.replace(/_/g, \" \")\n );\n}\n\n// ---------------------------------------------------------------------------\n// GraphQL query strings\n// ---------------------------------------------------------------------------\n\nconst SELLER_PUBLISHER_QUERY = `\n query SellerMyPublisher {\n myPublisher {\n id\n }\n }\n`;\n\nconst SELLER_ITEMS_QUERY = `\n query SellerItems($publisherId: String!) {\n products(filter: { publisherId: $publisherId, nature: PHYSICAL }, limit: 100, offset: 0) {\n id\n name\n slug\n type\n status\n price\n currency\n stockQuantity\n sku\n brand\n icon\n createdAt\n }\n }\n`;\n\n// ---------------------------------------------------------------------------\n// Page component\n// ---------------------------------------------------------------------------\n\nexport const SellerItemsPage: FC = () => {\n const { navigate, basePath, apiGatewayUrl, authToken } = useDevportal();\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n\n const gqlUrl = apiGatewayUrl ?? \"/global/graphql\";\n\n const [publisherLoading, setPublisherLoading] = useState(true);\n const [productsLoading, setProductsLoading] = useState(false);\n const [publisherId, setPublisherId] = useState<string | null>(null);\n const [products, setProducts] = useState<PhysicalProductDetail[]>([]);\n const [error, setError] = useState<string | null>(null);\n const [retryToken, setRetryToken] = useState(0);\n\n const [viewMode, setViewMode] = useState<\"grid\" | \"list\">(\"grid\");\n const [searchQuery, setSearchQuery] = useState(\"\");\n const [statusFilter, setStatusFilter] = useState<ProductStatus | \"\">(\"\");\n\n const handleNavigate = (path: string) => {\n navigate?.(`${basePath}${path}`);\n };\n\n // Fetch publisher first\n useEffect(() => {\n let cancelled = false;\n setPublisherLoading(true);\n setError(null);\n\n const run = async () => {\n try {\n const res = await fetch(gqlUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${authToken ?? \"\"}`,\n },\n body: JSON.stringify({ query: SELLER_PUBLISHER_QUERY }),\n });\n if (cancelled) return;\n if (!res.ok) {\n throw new Error(`Request failed with status ${res.status}`);\n }\n const json = (await res.json()) as {\n data?: { myPublisher?: { id: string } | null };\n errors?: { message: string }[];\n };\n if (cancelled) return;\n if (json.errors?.length) {\n throw new Error(json.errors[0]?.message ?? \"Unknown GraphQL error\");\n }\n setPublisherId(json.data?.myPublisher?.id ?? null);\n } catch (err) {\n if (!cancelled) {\n setError(\n err instanceof Error ? err.message : \"Failed to load publisher\",\n );\n }\n } finally {\n if (!cancelled) setPublisherLoading(false);\n }\n };\n\n void run();\n return () => {\n cancelled = true;\n };\n }, [gqlUrl, authToken, retryToken]);\n\n // Fetch products once publisher is resolved\n useEffect(() => {\n if (!publisherId) return;\n let cancelled = false;\n setProductsLoading(true);\n setError(null);\n\n const run = async () => {\n try {\n const res = await fetch(gqlUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${authToken ?? \"\"}`,\n },\n body: JSON.stringify({\n query: SELLER_ITEMS_QUERY,\n variables: { publisherId },\n }),\n });\n if (cancelled) return;\n if (!res.ok) {\n throw new Error(`Request failed with status ${res.status}`);\n }\n const json = (await res.json()) as {\n data?: {\n products?: Array<\n Omit<PhysicalProductDetail, \"status\"> & { status: string }\n >;\n };\n errors?: { message: string }[];\n };\n if (cancelled) return;\n if (json.errors?.length) {\n throw new Error(json.errors[0]?.message ?? \"Unknown GraphQL error\");\n }\n setProducts(\n (json.data?.products ?? []).map((p) => ({\n ...p,\n status: p.status as ProductStatus,\n })),\n );\n } catch (err) {\n if (!cancelled) {\n setError(err instanceof Error ? err.message : \"Failed to load items\");\n }\n } finally {\n if (!cancelled) setProductsLoading(false);\n }\n };\n\n void run();\n return () => {\n cancelled = true;\n };\n }, [publisherId, gqlUrl, authToken, retryToken]);\n\n // Exclude digital types defensively, then apply client-side filters\n const physicalItems = useMemo(\n () => products.filter((p) => !DIGITAL_TYPES.has(p.type)),\n [products],\n );\n\n const filteredItems = useMemo(\n () =>\n physicalItems.filter((item) => {\n const matchesSearch =\n !searchQuery ||\n item.name.toLowerCase().includes(searchQuery.toLowerCase());\n const matchesStatus = !statusFilter || item.status === statusFilter;\n return matchesSearch && matchesStatus;\n }),\n [physicalItems, searchQuery, statusFilter],\n );\n\n const stats = useMemo(\n () => ({\n total: physicalItems.length,\n published: physicalItems.filter((i) => i.status === \"PUBLISHED\").length,\n pendingReview: physicalItems.filter((i) => i.status === \"PENDING_REVIEW\")\n .length,\n outOfStock: physicalItems.filter((i) => i.stockQuantity === 0).length,\n }),\n [physicalItems],\n );\n\n const isInitialLoading = publisherLoading && products.length === 0 && !error;\n\n // Full-page loading state\n if (isInitialLoading) {\n return (\n <PageLayout\n title={tr(\"devportal.myItems\", \"My Items\")}\n description={tr(\n \"devportal.manageYourPhysicalProductListings\",\n \"Manage your physical product listings.\",\n )}\n >\n <div className=\"flex items-center justify-center py-12\">\n <Loader2 className=\"h-8 w-8 animate-spin text-text-secondary\" />\n <span className=\"ml-2 text-text-secondary\">\n {tr(\"devportal.loadingItems\", \"Loading items...\")}\n </span>\n </div>\n </PageLayout>\n );\n }\n\n // Full-page error state\n if (error && products.length === 0) {\n return (\n <PageLayout\n title={tr(\"devportal.myItems\", \"My Items\")}\n description={tr(\n \"devportal.manageYourPhysicalProductListings\",\n \"Manage your physical product listings.\",\n )}\n >\n <div className=\"rounded-lg border border-status-error-border/50 bg-status-error-bg/10 p-6 text-center\">\n <AlertCircle className=\"mx-auto h-8 w-8 text-status-error-text\" />\n <h3 className=\"mt-2 font-medium text-status-error-text\">\n {tr(\"devportal.failedToLoadItems\", \"Failed to load items\")}\n </h3>\n <p className=\"mt-1 text-sm text-text-secondary\">{error}</p>\n <button\n onClick={() => setRetryToken((n) => n + 1)}\n className=\"mt-4 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors\"\n >\n {tr(\"devportal.tryAgain\", \"Try Again\")}\n </button>\n </div>\n </PageLayout>\n );\n }\n\n const hasActiveFilters = Boolean(searchQuery || statusFilter);\n\n return (\n <PermissionGuard authOnly>\n <PageLayout\n title={tr(\"devportal.myItems\", \"My Items\")}\n description={tr(\n \"devportal.manageYourPhysicalProductListings\",\n \"Manage your physical product listings.\",\n )}\n actions={\n <button\n onClick={() => handleNavigate(\"/seller/items/new\")}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary\"\n >\n <Plus size={16} aria-hidden=\"true\" />\n {tr(\"devportal.listAnItem\", \"List an Item\")}\n </button>\n }\n >\n {/* Summary stats */}\n <EmphasisPanel className=\"mb-4\">\n <div className=\"grid grid-cols-2 gap-4 sm:grid-cols-4\">\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <p className=\"text-sm text-text-secondary\">\n {tr(\"devportal.totalItems\", \"Total Items\")}\n </p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums\">\n {productsLoading ? (\n <Loader2 className=\"h-5 w-5 animate-spin text-text-secondary\" />\n ) : (\n stats.total\n )}\n </p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <p className=\"text-sm text-status-success-text\">\n {tr(\"devportal.published\", \"Published\")}\n </p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums\">\n {productsLoading ? (\n <Loader2 className=\"h-5 w-5 animate-spin text-text-secondary\" />\n ) : (\n stats.published\n )}\n </p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <p className=\"text-sm text-status-warning-text\">\n {tr(\"devportal.pendingReview\", \"Pending Review\")}\n </p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums\">\n {productsLoading ? (\n <Loader2 className=\"h-5 w-5 animate-spin text-text-secondary\" />\n ) : (\n stats.pendingReview\n )}\n </p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <p className=\"text-sm text-status-error-text\">\n {tr(\"devportal.outOfStock\", \"Out of Stock\")}\n </p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums\">\n {productsLoading ? (\n <Loader2 className=\"h-5 w-5 animate-spin text-text-secondary\" />\n ) : (\n stats.outOfStock\n )}\n </p>\n </GlassCard>\n </div>\n </EmphasisPanel>\n\n {/* Filters + view toggle */}\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex flex-1 items-center gap-3\">\n {/* Search */}\n <div className=\"relative flex-1 max-w-md\">\n <Search\n size={16}\n className=\"absolute left-3 top-1/2 -translate-y-1/2 text-text-secondary\"\n />\n <input\n type=\"text\"\n placeholder={tr(\"devportal.searchItems\", \"Search items...\")}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"w-full rounded-md border border-border-seam bg-bg-surface pl-9 pr-4 py-2 text-sm text-text-primary placeholder:text-text-muted focus:outline-none focus:ring-2 focus:ring-primary\"\n />\n </div>\n\n {/* Status filter */}\n <select\n value={statusFilter}\n onChange={(e) =>\n setStatusFilter(e.target.value as ProductStatus | \"\")\n }\n className=\"rounded-md border border-border-seam bg-bg-surface px-3 py-2 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-primary scheme-normal dark:scheme-dark [&_option]:bg-bg-surface [&_option]:text-text-primary\"\n >\n {STATUS_OPTIONS.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n </div>\n\n {/* View toggle */}\n <div className=\"flex items-center gap-1 rounded-md border border-border-seam p-1\">\n <button\n onClick={() => setViewMode(\"grid\")}\n className={`rounded p-1.5 transition-colors ${\n viewMode === \"grid\"\n ? \"bg-bg-sunken text-text-primary\"\n : \"text-text-secondary hover:bg-bg-sunken/50\"\n }`}\n title={tr(\"devportal.gridView\", \"Grid view\")}\n >\n <Grid size={16} />\n </button>\n <button\n onClick={() => setViewMode(\"list\")}\n className={`rounded p-1.5 transition-colors ${\n viewMode === \"list\"\n ? \"bg-bg-sunken text-text-primary\"\n : \"text-text-secondary hover:bg-bg-sunken/50\"\n }`}\n title={tr(\"devportal.listView\", \"List view\")}\n >\n <List size={16} />\n </button>\n </div>\n </div>\n\n {/* Results count */}\n {physicalItems.length > 0 && (\n <p className=\"text-sm text-text-secondary\">\n {filteredItems.length} item\n {filteredItems.length !== 1 ? \"s\" : \"\"} found\n </p>\n )}\n\n {/* Content */}\n {!publisherId && !publisherLoading ? (\n <EmptyState\n illustration=\"empty-generic\"\n icon={<Package size={32} />}\n title={tr(\n \"devportal.noPublisherProfileYet\",\n \"No publisher profile yet\",\n )}\n description={tr(\n \"devportal.listAnItemToGetStarted\",\n \"List an item to get started. Your publisher profile will be created automatically.\",\n )}\n action={\n <button\n onClick={() => handleNavigate(\"/seller/items/new\")}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n <Plus size={16} />\n {tr(\"devportal.listAnItem\", \"List an Item\")}\n </button>\n }\n />\n ) : productsLoading ? (\n <div className=\"flex items-center justify-center py-12\">\n <Loader2 className=\"h-6 w-6 animate-spin text-text-secondary\" />\n <span className=\"ml-2 text-text-secondary\">\n {tr(\"devportal.loadingItems\", \"Loading items...\")}\n </span>\n </div>\n ) : filteredItems.length > 0 ? (\n viewMode === \"grid\" ? (\n <div className=\"grid gap-4 grid-cols-1 sm:grid-cols-2 lg:grid-cols-3\">\n {filteredItems.map((item) => (\n <ProductItemCard\n key={item.id}\n item={item}\n onEdit={() => handleNavigate(`/seller/items/${item.id}`)}\n />\n ))}\n </div>\n ) : (\n <div className=\"overflow-x-auto rounded-lg border border-border-seam\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b border-border-seam bg-bg-sunken\">\n <th className=\"px-4 py-3 text-left font-medium text-text-secondary\">\n Item\n </th>\n <th className=\"px-4 py-3 text-left font-medium text-text-secondary\">\n Type\n </th>\n <th className=\"px-4 py-3 text-left font-medium text-text-secondary\">\n Price\n </th>\n <th className=\"px-4 py-3 text-left font-medium text-text-secondary\">\n Stock\n </th>\n <th className=\"px-4 py-3 text-left font-medium text-text-secondary\">\n Status\n </th>\n <th className=\"px-4 py-3 text-right font-medium text-text-secondary\">\n Actions\n </th>\n </tr>\n </thead>\n <tbody>\n {filteredItems.map((item) => {\n const badge =\n STATUS_BADGE_STYLES[item.status] ??\n STATUS_BADGE_STYLES.DRAFT;\n return (\n <tr\n key={item.id}\n className=\"border-b border-border-subtle last:border-0 hover:bg-bg-sunken/50 transition-colors\"\n >\n <td className=\"px-4 py-3\">\n <div className=\"flex items-center gap-3\">\n {item.icon ? (\n <img\n src={item.icon}\n alt={item.name}\n className=\"h-8 w-8 rounded-lg object-cover shrink-0\"\n />\n ) : (\n <div className=\"flex h-8 w-8 items-center justify-center rounded-lg bg-bg-sunken shrink-0\">\n <Package\n size={14}\n className=\"text-text-muted\"\n />\n </div>\n )}\n <div className=\"min-w-0\">\n <p className=\"font-medium text-text-primary truncate\">\n {item.name}\n </p>\n {item.sku && (\n <p className=\"text-xs text-text-muted\">\n SKU: {item.sku}\n </p>\n )}\n </div>\n </div>\n </td>\n <td className=\"px-4 py-3 text-text-secondary\">\n {resolveTypeLabel(item.type)}\n </td>\n <td className=\"px-4 py-3 text-text-primary tabular-nums\">\n {formatPrice(item.price, item.currency)}\n </td>\n <td className=\"px-4 py-3\">\n {item.stockQuantity === 0 ? (\n <span className=\"text-status-error-text\">\n Out of stock\n </span>\n ) : (\n <span className=\"text-text-primary tabular-nums\">\n {item.stockQuantity}\n </span>\n )}\n </td>\n <td className=\"px-4 py-3\">\n <span\n className={`rounded-full px-2.5 py-0.5 text-xs font-medium ${badge.className}`}\n >\n {badge.label}\n </span>\n </td>\n <td className=\"px-4 py-3 text-right\">\n <button\n onClick={() =>\n handleNavigate(`/seller/items/${item.id}`)\n }\n className=\"inline-flex items-center gap-1.5 rounded-md border border-border-subtle px-3 py-1.5 text-xs font-medium text-text-secondary hover:text-text-primary hover:bg-bg-sunken transition-colors\"\n >\n <Edit size={12} />\n {tr(\"devportal.edit\", \"Edit\")}\n </button>\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n )\n ) : physicalItems.length > 0 && hasActiveFilters ? (\n <EmptyState\n illustration=\"empty-search\"\n title={tr(\n \"devportal.noItemsMatchYourSearch\",\n \"No items match your search\",\n )}\n description={tr(\n \"devportal.tryAdjustingFilters\",\n \"Try adjusting your search or filters\",\n )}\n />\n ) : (\n <EmptyState\n illustration=\"empty-data\"\n icon={<Package size={32} />}\n title={tr(\"devportal.noItemsYet\", \"No items yet\")}\n description={tr(\n \"devportal.addYourFirstPhysicalProduct\",\n \"Add your first physical product listing to start selling\",\n )}\n action={\n <button\n onClick={() => handleNavigate(\"/seller/items/new\")}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n <Plus size={16} />\n {tr(\"devportal.listAnItem\", \"List an Item\")}\n </button>\n }\n />\n )}\n </PageLayout>\n </PermissionGuard>\n );\n};\n\n// ---------------------------------------------------------------------------\n// Sub-components\n// ---------------------------------------------------------------------------\n\nconst ProductItemCard: FC<{\n item: PhysicalProductDetail;\n onEdit: () => void;\n}> = ({ item, onEdit }) => {\n const badge = STATUS_BADGE_STYLES[item.status] ?? STATUS_BADGE_STYLES.DRAFT;\n\n return (\n <GlassCard treatment=\"insight\" className=\"flex flex-col gap-3 p-4\">\n <div className=\"flex items-start gap-3\">\n {item.icon ? (\n <img\n src={item.icon}\n alt={item.name}\n className=\"h-20 w-20 rounded-xl object-cover shrink-0\"\n />\n ) : (\n <div className=\"flex h-20 w-20 items-center justify-center rounded-xl bg-bg-sunken shrink-0\">\n <Package size={32} className=\"text-text-muted\" />\n </div>\n )}\n <div className=\"min-w-0 flex-1\">\n <p className=\"font-semibold text-text-primary truncate\">\n {item.name}\n </p>\n {item.brand && (\n <p className=\"text-xs text-text-muted mt-0.5\">{item.brand}</p>\n )}\n <p className=\"text-sm text-text-secondary mt-1\">\n {formatPrice(item.price, item.currency)}\n </p>\n <div className=\"flex items-center gap-2 mt-2 flex-wrap\">\n <span\n className={`rounded-full px-2 py-0.5 text-xs font-medium ${badge.className}`}\n >\n {badge.label}\n </span>\n <span className=\"rounded-full px-2 py-0.5 text-xs font-medium bg-bg-muted text-text-secondary\">\n {resolveTypeLabel(item.type)}\n </span>\n </div>\n </div>\n </div>\n\n <div className=\"flex items-center justify-between pt-2 border-t border-border-subtle\">\n <div className=\"flex items-center gap-1.5 text-sm\">\n <Tag size={12} className=\"text-text-muted shrink-0\" />\n {item.stockQuantity === 0 ? (\n <span className=\"text-status-error-text\">Out of stock</span>\n ) : (\n <span className=\"text-text-secondary\">\n {item.stockQuantity} in stock\n </span>\n )}\n </div>\n <button\n onClick={onEdit}\n className=\"inline-flex items-center gap-1.5 rounded-md border border-border-subtle px-3 py-1.5 text-xs font-medium text-text-secondary hover:text-text-primary hover:bg-bg-sunken transition-colors\"\n >\n <Edit size={12} />\n Edit\n </button>\n </div>\n </GlassCard>\n );\n};\n"],"mappings":";;;;;;;;;;;AA+DA,IAAM,IAAgB,IAAI,IAAI;CAAC;CAAO;CAAQ;CAAW,CAAC,EAEpD,IAA2D;CAC/D,aAAa;CACb,UAAU;CACV,WAAW;CACX,MAAM;CACN,WAAW;CACX,SAAS;CACT,aAAa;CACb,YAAY;CACb,EAEK,IAGF;CACF,WAAW;EACT,OAAO;EACP,WAAW;EACZ;CACD,gBAAgB;EACd,OAAO;EACP,WAAW;EACZ;CACD,OAAO;EACL,OAAO;EACP,WAAW;EACZ;CACD,UAAU;EACR,OAAO;EACP,WAAW;EACZ;CACD,UAAU;EACR,OAAO;EACP,WAAW;EACZ;CACF,EAEK,IAAiE;CACrE;EAAE,OAAO;EAAI,OAAO;EAAc;CAClC;EAAE,OAAO;EAAS,OAAO;EAAS;CAClC;EAAE,OAAO;EAAkB,OAAO;EAAkB;CACpD;EAAE,OAAO;EAAa,OAAO;EAAa;CAC1C;EAAE,OAAO;EAAY,OAAO;EAAY;CACxC;EAAE,OAAO;EAAY,OAAO;EAAY;CACzC;AAMD,SAAS,EAAY,GAAe,GAA0B;CAC5D,IAAM,IAAO,KAAY;AAOzB,QAAO,GANW,IAAI,KAAK,aAAa,SAAS;EAC/C,OAAO;EACP,UAAU;EACV,uBAAuB;EACvB,uBAAuB;EACxB,CAAC,CAAC,OAAO,EAAM,CACI,GAAG;;AAGzB,SAAS,EAAiB,GAAsB;AAC9C,QACE,EAAoB,MAAgC,EAAK,QAAQ,MAAM,IAAI;;AAQ/E,IAAM,KAAyB,4EAQzB,KAAqB,mUAuBd,UAA4B;CACvC,IAAM,EAAE,aAAU,aAAU,kBAAe,iBAAc,GAAc,EACjE,EAAE,SAAM,GAAS,EACjB,KAAM,GAAa,MAA6B;EACpD,IAAM,IAAQ,EAAE,EAAI;AACpB,SAAO,MAAU,IAAM,IAAW;IAG9B,IAAS,KAAiB,mBAE1B,CAAC,GAAkB,KAAuB,EAAS,GAAK,EACxD,CAAC,GAAiB,KAAsB,EAAS,GAAM,EACvD,CAAC,GAAa,KAAkB,EAAwB,KAAK,EAC7D,CAAC,GAAU,KAAe,EAAkC,EAAE,CAAC,EAC/D,CAAC,GAAO,KAAY,EAAwB,KAAK,EACjD,CAAC,GAAY,KAAiB,EAAS,EAAE,EAEzC,CAAC,GAAU,KAAe,EAA0B,OAAO,EAC3D,CAAC,GAAa,KAAkB,EAAS,GAAG,EAC5C,CAAC,GAAc,KAAmB,EAA6B,GAAG,EAElE,KAAkB,MAAiB;AACvC,MAAW,GAAG,IAAW,IAAO;;AAkDlC,CA9CA,QAAgB;EACd,IAAI,IAAY;AAuChB,SAtCA,EAAoB,GAAK,EACzB,EAAS,KAAK,GAEF,YAAY;AACtB,OAAI;IACF,IAAM,IAAM,MAAM,MAAM,GAAQ;KAC9B,QAAQ;KACR,SAAS;MACP,gBAAgB;MAChB,eAAe,UAAU,KAAa;MACvC;KACD,MAAM,KAAK,UAAU,EAAE,OAAO,IAAwB,CAAC;KACxD,CAAC;AACF,QAAI,EAAW;AACf,QAAI,CAAC,EAAI,GACP,OAAU,MAAM,8BAA8B,EAAI,SAAS;IAE7D,IAAM,IAAQ,MAAM,EAAI,MAAM;AAI9B,QAAI,EAAW;AACf,QAAI,EAAK,QAAQ,OACf,OAAU,MAAM,EAAK,OAAO,IAAI,WAAW,wBAAwB;AAErE,MAAe,EAAK,MAAM,aAAa,MAAM,KAAK;YAC3C,GAAK;AACZ,IAAK,KACH,EACE,aAAe,QAAQ,EAAI,UAAU,2BACtC;aAEK;AACR,IAAK,KAAW,EAAoB,GAAM;;MAIpC,QACG;AACX,OAAY;;IAEb;EAAC;EAAQ;EAAW;EAAW,CAAC,EAGnC,QAAgB;AACd,MAAI,CAAC,EAAa;EAClB,IAAI,IAAY;AAiDhB,SAhDA,EAAmB,GAAK,EACxB,EAAS,KAAK,GAEF,YAAY;AACtB,OAAI;IACF,IAAM,IAAM,MAAM,MAAM,GAAQ;KAC9B,QAAQ;KACR,SAAS;MACP,gBAAgB;MAChB,eAAe,UAAU,KAAa;MACvC;KACD,MAAM,KAAK,UAAU;MACnB,OAAO;MACP,WAAW,EAAE,gBAAa;MAC3B,CAAC;KACH,CAAC;AACF,QAAI,EAAW;AACf,QAAI,CAAC,EAAI,GACP,OAAU,MAAM,8BAA8B,EAAI,SAAS;IAE7D,IAAM,IAAQ,MAAM,EAAI,MAAM;AAQ9B,QAAI,EAAW;AACf,QAAI,EAAK,QAAQ,OACf,OAAU,MAAM,EAAK,OAAO,IAAI,WAAW,wBAAwB;AAErE,OACG,EAAK,MAAM,YAAY,EAAE,EAAE,KAAK,OAAO;KACtC,GAAG;KACH,QAAQ,EAAE;KACX,EAAE,CACJ;YACM,GAAK;AACZ,IAAK,KACH,EAAS,aAAe,QAAQ,EAAI,UAAU,uBAAuB;aAE/D;AACR,IAAK,KAAW,EAAmB,GAAM;;MAInC,QACG;AACX,OAAY;;IAEb;EAAC;EAAa;EAAQ;EAAW;EAAW,CAAC;CAGhD,IAAM,IAAgB,QACd,EAAS,QAAQ,MAAM,CAAC,EAAc,IAAI,EAAE,KAAK,CAAC,EACxD,CAAC,EAAS,CACX,EAEK,IAAgB,QAElB,EAAc,QAAQ,MAAS;EAC7B,IAAM,IACJ,CAAC,KACD,EAAK,KAAK,aAAa,CAAC,SAAS,EAAY,aAAa,CAAC,EACvD,IAAgB,CAAC,KAAgB,EAAK,WAAW;AACvD,SAAO,KAAiB;GACxB,EACJ;EAAC;EAAe;EAAa;EAAa,CAC3C,EAEK,IAAQ,SACL;EACL,OAAO,EAAc;EACrB,WAAW,EAAc,QAAQ,MAAM,EAAE,WAAW,YAAY,CAAC;EACjE,eAAe,EAAc,QAAQ,MAAM,EAAE,WAAW,iBAAiB,CACtE;EACH,YAAY,EAAc,QAAQ,MAAM,EAAE,kBAAkB,EAAE,CAAC;EAChE,GACD,CAAC,EAAc,CAChB;AAKD,KAHyB,KAAoB,EAAS,WAAW,KAAK,CAAC,EAIrE,QACE,kBAAC,GAAD;EACE,OAAO,EAAG,qBAAqB,WAAW;EAC1C,aAAa,EACX,+CACA,yCACD;YAED,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,GAAD,EAAS,WAAU,4CAA6C,CAAA,EAChE,kBAAC,QAAD;IAAM,WAAU;cACb,EAAG,0BAA0B,mBAAmB;IAC5C,CAAA,CACH;;EACK,CAAA;AAKjB,KAAI,KAAS,EAAS,WAAW,EAC/B,QACE,kBAAC,GAAD;EACE,OAAO,EAAG,qBAAqB,WAAW;EAC1C,aAAa,EACX,+CACA,yCACD;YAED,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,GAAD,EAAa,WAAU,0CAA2C,CAAA;IAClE,kBAAC,MAAD;KAAI,WAAU;eACX,EAAG,+BAA+B,uBAAuB;KACvD,CAAA;IACL,kBAAC,KAAD;KAAG,WAAU;eAAoC;KAAU,CAAA;IAC3D,kBAAC,UAAD;KACE,eAAe,GAAe,MAAM,IAAI,EAAE;KAC1C,WAAU;eAET,EAAG,sBAAsB,YAAY;KAC/B,CAAA;IACL;;EACK,CAAA;CAIjB,IAAM,KAAmB,GAAQ,KAAe;AAEhD,QACE,kBAAC,GAAD;EAAiB,UAAA;YACf,kBAAC,GAAD;GACE,OAAO,EAAG,qBAAqB,WAAW;GAC1C,aAAa,EACX,+CACA,yCACD;GACD,SACE,kBAAC,UAAD;IACE,eAAe,EAAe,oBAAoB;IAClD,WAAU;cAFZ,CAIE,kBAAC,GAAD;KAAM,MAAM;KAAI,eAAY;KAAS,CAAA,EACpC,EAAG,wBAAwB,eAAe,CACpC;;aAbb;IAiBE,kBAAC,GAAD;KAAe,WAAU;eACvB,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,GAAD;QAAW,WAAU;QAAS,WAAU;kBAAxC,CACE,kBAAC,KAAD;SAAG,WAAU;mBACV,EAAG,wBAAwB,cAAc;SACxC,CAAA,EACJ,kBAAC,KAAD;SAAG,WAAU;mBACV,IACC,kBAAC,GAAD,EAAS,WAAU,4CAA6C,CAAA,GAEhE,EAAM;SAEN,CAAA,CACM;;OACZ,kBAAC,GAAD;QAAW,WAAU;QAAS,WAAU;kBAAxC,CACE,kBAAC,KAAD;SAAG,WAAU;mBACV,EAAG,uBAAuB,YAAY;SACrC,CAAA,EACJ,kBAAC,KAAD;SAAG,WAAU;mBACV,IACC,kBAAC,GAAD,EAAS,WAAU,4CAA6C,CAAA,GAEhE,EAAM;SAEN,CAAA,CACM;;OACZ,kBAAC,GAAD;QAAW,WAAU;QAAS,WAAU;kBAAxC,CACE,kBAAC,KAAD;SAAG,WAAU;mBACV,EAAG,2BAA2B,iBAAiB;SAC9C,CAAA,EACJ,kBAAC,KAAD;SAAG,WAAU;mBACV,IACC,kBAAC,GAAD,EAAS,WAAU,4CAA6C,CAAA,GAEhE,EAAM;SAEN,CAAA,CACM;;OACZ,kBAAC,GAAD;QAAW,WAAU;QAAS,WAAU;kBAAxC,CACE,kBAAC,KAAD;SAAG,WAAU;mBACV,EAAG,wBAAwB,eAAe;SACzC,CAAA,EACJ,kBAAC,KAAD;SAAG,WAAU;mBACV,IACC,kBAAC,GAAD,EAAS,WAAU,4CAA6C,CAAA,GAEhE,EAAM;SAEN,CAAA,CACM;;OACR;;KACQ,CAAA;IAGhB,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CAEE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD;QACE,MAAM;QACN,WAAU;QACV,CAAA,EACF,kBAAC,SAAD;QACE,MAAK;QACL,aAAa,EAAG,yBAAyB,kBAAkB;QAC3D,OAAO;QACP,WAAW,MAAM,EAAe,EAAE,OAAO,MAAM;QAC/C,WAAU;QACV,CAAA,CACE;UAGN,kBAAC,UAAD;OACE,OAAO;OACP,WAAW,MACT,EAAgB,EAAE,OAAO,MAA4B;OAEvD,WAAU;iBAET,EAAe,KAAK,MACnB,kBAAC,UAAD;QAAwB,OAAO,EAAI;kBAChC,EAAI;QACE,EAFI,EAAI,MAER,CACT;OACK,CAAA,CACL;SAGN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,UAAD;OACE,eAAe,EAAY,OAAO;OAClC,WAAW,mCACT,MAAa,SACT,mCACA;OAEN,OAAO,EAAG,sBAAsB,YAAY;iBAE5C,kBAAC,IAAD,EAAM,MAAM,IAAM,CAAA;OACX,CAAA,EACT,kBAAC,UAAD;OACE,eAAe,EAAY,OAAO;OAClC,WAAW,mCACT,MAAa,SACT,mCACA;OAEN,OAAO,EAAG,sBAAsB,YAAY;iBAE5C,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA;OACX,CAAA,CACL;QACF;;IAGL,EAAc,SAAS,KACtB,kBAAC,KAAD;KAAG,WAAU;eAAb;MACG,EAAc;MAAO;MACrB,EAAc,WAAW,IAAU,KAAN;MAAS;MACrC;;IAIL,CAAC,KAAe,CAAC,IAChB,kBAAC,GAAD;KACE,cAAa;KACb,MAAM,kBAAC,GAAD,EAAS,MAAM,IAAM,CAAA;KAC3B,OAAO,EACL,mCACA,2BACD;KACD,aAAa,EACX,oCACA,qFACD;KACD,QACE,kBAAC,UAAD;MACE,eAAe,EAAe,oBAAoB;MAClD,WAAU;gBAFZ,CAIE,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA,EACjB,EAAG,wBAAwB,eAAe,CACpC;;KAEX,CAAA,GACA,IACF,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD,EAAS,WAAU,4CAA6C,CAAA,EAChE,kBAAC,QAAD;MAAM,WAAU;gBACb,EAAG,0BAA0B,mBAAmB;MAC5C,CAAA,CACH;SACJ,EAAc,SAAS,IACzB,MAAa,SACX,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAc,KAAK,MAClB,kBAAC,GAAD;MAEQ;MACN,cAAc,EAAe,iBAAiB,EAAK,KAAK;MACxD,EAHK,EAAK,GAGV,CACF;KACE,CAAA,GAEN,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,SAAD;MAAO,WAAU;gBAAjB,CACE,kBAAC,SAAD,EAAA,UACE,kBAAC,MAAD;OAAI,WAAU;iBAAd;QACE,kBAAC,MAAD;SAAI,WAAU;mBAAsD;SAE/D,CAAA;QACL,kBAAC,MAAD;SAAI,WAAU;mBAAsD;SAE/D,CAAA;QACL,kBAAC,MAAD;SAAI,WAAU;mBAAsD;SAE/D,CAAA;QACL,kBAAC,MAAD;SAAI,WAAU;mBAAsD;SAE/D,CAAA;QACL,kBAAC,MAAD;SAAI,WAAU;mBAAsD;SAE/D,CAAA;QACL,kBAAC,MAAD;SAAI,WAAU;mBAAuD;SAEhE,CAAA;QACF;UACC,CAAA,EACR,kBAAC,SAAD,EAAA,UACG,EAAc,KAAK,MAAS;OAC3B,IAAM,IACJ,EAAoB,EAAK,WACzB,EAAoB;AACtB,cACE,kBAAC,MAAD;QAEE,WAAU;kBAFZ;SAIE,kBAAC,MAAD;UAAI,WAAU;oBACZ,kBAAC,OAAD;WAAK,WAAU;qBAAf,CACG,EAAK,OACJ,kBAAC,OAAD;YACE,KAAK,EAAK;YACV,KAAK,EAAK;YACV,WAAU;YACV,CAAA,GAEF,kBAAC,OAAD;YAAK,WAAU;sBACb,kBAAC,GAAD;aACE,MAAM;aACN,WAAU;aACV,CAAA;YACE,CAAA,EAER,kBAAC,OAAD;YAAK,WAAU;sBAAf,CACE,kBAAC,KAAD;aAAG,WAAU;uBACV,EAAK;aACJ,CAAA,EACH,EAAK,OACJ,kBAAC,KAAD;aAAG,WAAU;uBAAb,CAAuC,SAC/B,EAAK,IACT;eAEF;cACF;;UACH,CAAA;SACL,kBAAC,MAAD;UAAI,WAAU;oBACX,EAAiB,EAAK,KAAK;UACzB,CAAA;SACL,kBAAC,MAAD;UAAI,WAAU;oBACX,EAAY,EAAK,OAAO,EAAK,SAAS;UACpC,CAAA;SACL,kBAAC,MAAD;UAAI,WAAU;oBACX,EAAK,kBAAkB,IACtB,kBAAC,QAAD;WAAM,WAAU;qBAAyB;WAElC,CAAA,GAEP,kBAAC,QAAD;WAAM,WAAU;qBACb,EAAK;WACD,CAAA;UAEN,CAAA;SACL,kBAAC,MAAD;UAAI,WAAU;oBACZ,kBAAC,QAAD;WACE,WAAW,kDAAkD,EAAM;qBAElE,EAAM;WACF,CAAA;UACJ,CAAA;SACL,kBAAC,MAAD;UAAI,WAAU;oBACZ,kBAAC,UAAD;WACE,eACE,EAAe,iBAAiB,EAAK,KAAK;WAE5C,WAAU;qBAJZ,CAME,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA,EACjB,EAAG,kBAAkB,OAAO,CACtB;;UACN,CAAA;SACF;UAlEE,EAAK,GAkEP;QAEP,EACI,CAAA,CACF;;KACJ,CAAA,GAEN,EAAc,SAAS,KAAK,KAC9B,kBAAC,GAAD;KACE,cAAa;KACb,OAAO,EACL,oCACA,6BACD;KACD,aAAa,EACX,iCACA,uCACD;KACD,CAAA,GAEF,kBAAC,GAAD;KACE,cAAa;KACb,MAAM,kBAAC,GAAD,EAAS,MAAM,IAAM,CAAA;KAC3B,OAAO,EAAG,wBAAwB,eAAe;KACjD,aAAa,EACX,yCACA,2DACD;KACD,QACE,kBAAC,UAAD;MACE,eAAe,EAAe,oBAAoB;MAClD,WAAU;gBAFZ,CAIE,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA,EACjB,EAAG,wBAAwB,eAAe,CACpC;;KAEX,CAAA;IAEO;;EACG,CAAA;GAQhB,KAGA,EAAE,SAAM,gBAAa;CACzB,IAAM,IAAQ,EAAoB,EAAK,WAAW,EAAoB;AAEtE,QACE,kBAAC,GAAD;EAAW,WAAU;EAAU,WAAU;YAAzC,CACE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACG,EAAK,OACJ,kBAAC,OAAD;IACE,KAAK,EAAK;IACV,KAAK,EAAK;IACV,WAAU;IACV,CAAA,GAEF,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,GAAD;KAAS,MAAM;KAAI,WAAU;KAAoB,CAAA;IAC7C,CAAA,EAER,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,KAAD;MAAG,WAAU;gBACV,EAAK;MACJ,CAAA;KACH,EAAK,SACJ,kBAAC,KAAD;MAAG,WAAU;gBAAkC,EAAK;MAAU,CAAA;KAEhE,kBAAC,KAAD;MAAG,WAAU;gBACV,EAAY,EAAK,OAAO,EAAK,SAAS;MACrC,CAAA;KACJ,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,QAAD;OACE,WAAW,gDAAgD,EAAM;iBAEhE,EAAM;OACF,CAAA,EACP,kBAAC,QAAD;OAAM,WAAU;iBACb,EAAiB,EAAK,KAAK;OACvB,CAAA,CACH;;KACF;MACF;MAEN,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD;KAAK,MAAM;KAAI,WAAU;KAA6B,CAAA,EACrD,EAAK,kBAAkB,IACtB,kBAAC,QAAD;KAAM,WAAU;eAAyB;KAAmB,CAAA,GAE5D,kBAAC,QAAD;KAAM,WAAU;eAAhB,CACG,EAAK,eAAc,YACf;OAEL;OACN,kBAAC,UAAD;IACE,SAAS;IACT,WAAU;cAFZ,CAIE,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA,EAAA,OAEX;MACL;KACI"}
1
+ {"version":3,"file":"SellerItemsPage.js","names":[],"sources":["../../../src/devportal/pages/SellerItemsPage.tsx"],"sourcesContent":["import type { FC } from \"react\";\nimport { useEffect, useState, useMemo } from \"react\";\nimport { useI18n } from \"@burdenoff/fe-libs/shared/providers/shell/I18nProvider\";\nimport {\n Plus,\n Search,\n Grid,\n List,\n Package,\n Loader2,\n AlertCircle,\n Edit,\n Tag,\n} from \"lucide-react\";\nimport { EmphasisPanel, GlassCard } from \"@burdenoff/fe-libs/ui\";\nimport { PageLayout } from \"../components/PageLayout\";\nimport { EmptyState } from \"../components/EmptyState\";\nimport { useDevportal } from \"../providers/DevportalProvider\";\nimport { PermissionGuard } from \"../components\";\nimport { resolveGlobalGraphqlEndpoint } from \"../utils/graphqlEndpoint\";\n\n// ---------------------------------------------------------------------------\n// Local types\n// ---------------------------------------------------------------------------\n\ntype ProductStatus =\n | \"DRAFT\"\n | \"PENDING_REVIEW\"\n | \"PUBLISHED\"\n | \"REJECTED\"\n | \"INACTIVE\";\n\ntype PhysicalProductType =\n | \"MERCHANDISE\"\n | \"HARDWARE\"\n | \"ACCESSORY\"\n | \"BOOK\"\n | \"EQUIPMENT\"\n | \"APPAREL\"\n | \"COLLECTIBLE\"\n | \"CONSUMABLE\";\n\ninterface PhysicalProductDetail {\n id: string;\n name: string;\n slug: string;\n type: string;\n status: ProductStatus;\n price: number;\n currency: string;\n stockQuantity: number;\n sku?: string | null;\n brand?: string | null;\n icon?: string | null;\n createdAt: string;\n}\n\n// ---------------------------------------------------------------------------\n// Constants\n// ---------------------------------------------------------------------------\n\n/**\n * Digital product types to exclude even if `nature: PHYSICAL` is set wrong.\n */\nconst DIGITAL_TYPES = new Set([\"APP\", \"NODE\", \"WORKFLOW\"]);\n\nconst PRODUCT_TYPE_LABELS: Record<PhysicalProductType, string> = {\n MERCHANDISE: \"Merchandise\",\n HARDWARE: \"Hardware\",\n ACCESSORY: \"Accessory\",\n BOOK: \"Book\",\n EQUIPMENT: \"Equipment\",\n APPAREL: \"Apparel\",\n COLLECTIBLE: \"Collectible\",\n CONSUMABLE: \"Consumable\",\n};\n\nconst STATUS_BADGE_STYLES: Record<\n ProductStatus,\n { label: string; className: string }\n> = {\n PUBLISHED: {\n label: \"Published\",\n className: \"text-status-success-text bg-status-success-bg-subtle\",\n },\n PENDING_REVIEW: {\n label: \"Pending Review\",\n className: \"text-status-warning-text bg-status-warning-bg-subtle\",\n },\n DRAFT: {\n label: \"Draft\",\n className: \"text-text-muted bg-bg-muted\",\n },\n REJECTED: {\n label: \"Rejected\",\n className: \"text-status-error-text bg-status-error-bg/10\",\n },\n INACTIVE: {\n label: \"Inactive\",\n className: \"text-text-muted bg-bg-muted\",\n },\n};\n\nconst STATUS_OPTIONS: { value: ProductStatus | \"\"; label: string }[] = [\n { value: \"\", label: \"All Status\" },\n { value: \"DRAFT\", label: \"Draft\" },\n { value: \"PENDING_REVIEW\", label: \"Pending Review\" },\n { value: \"PUBLISHED\", label: \"Published\" },\n { value: \"REJECTED\", label: \"Rejected\" },\n { value: \"INACTIVE\", label: \"Inactive\" },\n];\n\n// ---------------------------------------------------------------------------\n// Helpers\n// ---------------------------------------------------------------------------\n\nfunction formatPrice(price: number, currency: string): string {\n const curr = currency || \"USD\";\n const formatted = new Intl.NumberFormat(\"en-US\", {\n style: \"currency\",\n currency: curr,\n minimumFractionDigits: 2,\n maximumFractionDigits: 2,\n }).format(price);\n return `${formatted} ${curr}`;\n}\n\nfunction resolveTypeLabel(type: string): string {\n return (\n PRODUCT_TYPE_LABELS[type as PhysicalProductType] ?? type.replace(/_/g, \" \")\n );\n}\n\n// ---------------------------------------------------------------------------\n// GraphQL query strings\n// ---------------------------------------------------------------------------\n\nconst SELLER_PUBLISHER_QUERY = `\n query SellerMyPublisher {\n myPublisher {\n id\n }\n }\n`;\n\nconst SELLER_ITEMS_QUERY = `\n query SellerItems($publisherId: String!) {\n products(filter: { publisherId: $publisherId, nature: PHYSICAL }, limit: 100, offset: 0) {\n id\n name\n slug\n type\n status\n price\n currency\n stockQuantity\n sku\n brand\n icon\n createdAt\n }\n }\n`;\n\n// ---------------------------------------------------------------------------\n// Page component\n// ---------------------------------------------------------------------------\n\nexport const SellerItemsPage: FC = () => {\n const { navigate, basePath, apiGatewayUrl, authToken } = useDevportal();\n const { t } = useI18n();\n const tr = (key: string, fallback: string): string => {\n const value = t(key);\n return value === key ? fallback : value;\n };\n\n const gqlUrl = resolveGlobalGraphqlEndpoint(apiGatewayUrl);\n\n const [publisherLoading, setPublisherLoading] = useState(true);\n const [productsLoading, setProductsLoading] = useState(false);\n const [publisherId, setPublisherId] = useState<string | null>(null);\n const [products, setProducts] = useState<PhysicalProductDetail[]>([]);\n const [error, setError] = useState<string | null>(null);\n const [retryToken, setRetryToken] = useState(0);\n\n const [viewMode, setViewMode] = useState<\"grid\" | \"list\">(\"grid\");\n const [searchQuery, setSearchQuery] = useState(\"\");\n const [statusFilter, setStatusFilter] = useState<ProductStatus | \"\">(\"\");\n\n const handleNavigate = (path: string) => {\n navigate?.(`${basePath}${path}`);\n };\n\n // Fetch publisher first\n useEffect(() => {\n let cancelled = false;\n setPublisherLoading(true);\n setError(null);\n\n const run = async () => {\n try {\n const res = await fetch(gqlUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${authToken ?? \"\"}`,\n },\n body: JSON.stringify({ query: SELLER_PUBLISHER_QUERY }),\n });\n if (cancelled) return;\n if (!res.ok) {\n throw new Error(`Request failed with status ${res.status}`);\n }\n const json = (await res.json()) as {\n data?: { myPublisher?: { id: string } | null };\n errors?: { message: string }[];\n };\n if (cancelled) return;\n if (json.errors?.length) {\n throw new Error(json.errors[0]?.message ?? \"Unknown GraphQL error\");\n }\n setPublisherId(json.data?.myPublisher?.id ?? null);\n } catch (err) {\n if (!cancelled) {\n setError(\n err instanceof Error ? err.message : \"Failed to load publisher\",\n );\n }\n } finally {\n if (!cancelled) setPublisherLoading(false);\n }\n };\n\n void run();\n return () => {\n cancelled = true;\n };\n }, [gqlUrl, authToken, retryToken]);\n\n // Fetch products once publisher is resolved\n useEffect(() => {\n if (!publisherId) return;\n let cancelled = false;\n setProductsLoading(true);\n setError(null);\n\n const run = async () => {\n try {\n const res = await fetch(gqlUrl, {\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${authToken ?? \"\"}`,\n },\n body: JSON.stringify({\n query: SELLER_ITEMS_QUERY,\n variables: { publisherId },\n }),\n });\n if (cancelled) return;\n if (!res.ok) {\n throw new Error(`Request failed with status ${res.status}`);\n }\n const json = (await res.json()) as {\n data?: {\n products?: Array<\n Omit<PhysicalProductDetail, \"status\"> & { status: string }\n >;\n };\n errors?: { message: string }[];\n };\n if (cancelled) return;\n if (json.errors?.length) {\n throw new Error(json.errors[0]?.message ?? \"Unknown GraphQL error\");\n }\n setProducts(\n (json.data?.products ?? []).map((p) => ({\n ...p,\n status: p.status as ProductStatus,\n })),\n );\n } catch (err) {\n if (!cancelled) {\n setError(err instanceof Error ? err.message : \"Failed to load items\");\n }\n } finally {\n if (!cancelled) setProductsLoading(false);\n }\n };\n\n void run();\n return () => {\n cancelled = true;\n };\n }, [publisherId, gqlUrl, authToken, retryToken]);\n\n // Exclude digital types defensively, then apply client-side filters\n const physicalItems = useMemo(\n () => products.filter((p) => !DIGITAL_TYPES.has(p.type)),\n [products],\n );\n\n const filteredItems = useMemo(\n () =>\n physicalItems.filter((item) => {\n const matchesSearch =\n !searchQuery ||\n item.name.toLowerCase().includes(searchQuery.toLowerCase());\n const matchesStatus = !statusFilter || item.status === statusFilter;\n return matchesSearch && matchesStatus;\n }),\n [physicalItems, searchQuery, statusFilter],\n );\n\n const stats = useMemo(\n () => ({\n total: physicalItems.length,\n published: physicalItems.filter((i) => i.status === \"PUBLISHED\").length,\n pendingReview: physicalItems.filter((i) => i.status === \"PENDING_REVIEW\")\n .length,\n outOfStock: physicalItems.filter((i) => i.stockQuantity === 0).length,\n }),\n [physicalItems],\n );\n\n const isInitialLoading = publisherLoading && products.length === 0 && !error;\n\n // Full-page loading state\n if (isInitialLoading) {\n return (\n <PageLayout\n title={tr(\"devportal.myItems\", \"My Items\")}\n description={tr(\n \"devportal.manageYourPhysicalProductListings\",\n \"Manage your physical product listings.\",\n )}\n >\n <div className=\"flex items-center justify-center py-12\">\n <Loader2 className=\"h-8 w-8 animate-spin text-text-secondary\" />\n <span className=\"ml-2 text-text-secondary\">\n {tr(\"devportal.loadingItems\", \"Loading items...\")}\n </span>\n </div>\n </PageLayout>\n );\n }\n\n // Full-page error state\n if (error && products.length === 0) {\n return (\n <PageLayout\n title={tr(\"devportal.myItems\", \"My Items\")}\n description={tr(\n \"devportal.manageYourPhysicalProductListings\",\n \"Manage your physical product listings.\",\n )}\n >\n <div className=\"rounded-lg border border-status-error-border/50 bg-status-error-bg/10 p-6 text-center\">\n <AlertCircle className=\"mx-auto h-8 w-8 text-status-error-text\" />\n <h3 className=\"mt-2 font-medium text-status-error-text\">\n {tr(\"devportal.failedToLoadItems\", \"Failed to load items\")}\n </h3>\n <p className=\"mt-1 text-sm text-text-secondary\">{error}</p>\n <button\n onClick={() => setRetryToken((n) => n + 1)}\n className=\"mt-4 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors\"\n >\n {tr(\"devportal.tryAgain\", \"Try Again\")}\n </button>\n </div>\n </PageLayout>\n );\n }\n\n const hasActiveFilters = Boolean(searchQuery || statusFilter);\n\n return (\n <PermissionGuard authOnly>\n <PageLayout\n title={tr(\"devportal.myItems\", \"My Items\")}\n description={tr(\n \"devportal.manageYourPhysicalProductListings\",\n \"Manage your physical product listings.\",\n )}\n actions={\n <button\n onClick={() => handleNavigate(\"/seller/items/new\")}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90 transition-colors focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-primary\"\n >\n <Plus size={16} aria-hidden=\"true\" />\n {tr(\"devportal.listAnItem\", \"List an Item\")}\n </button>\n }\n >\n {/* Summary stats */}\n <EmphasisPanel className=\"mb-4\">\n <div className=\"grid grid-cols-2 gap-4 sm:grid-cols-4\">\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <p className=\"text-sm text-text-secondary\">\n {tr(\"devportal.totalItems\", \"Total Items\")}\n </p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums\">\n {productsLoading ? (\n <Loader2 className=\"h-5 w-5 animate-spin text-text-secondary\" />\n ) : (\n stats.total\n )}\n </p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <p className=\"text-sm text-status-success-text\">\n {tr(\"devportal.published\", \"Published\")}\n </p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums\">\n {productsLoading ? (\n <Loader2 className=\"h-5 w-5 animate-spin text-text-secondary\" />\n ) : (\n stats.published\n )}\n </p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <p className=\"text-sm text-status-warning-text\">\n {tr(\"devportal.pendingReview\", \"Pending Review\")}\n </p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums\">\n {productsLoading ? (\n <Loader2 className=\"h-5 w-5 animate-spin text-text-secondary\" />\n ) : (\n stats.pendingReview\n )}\n </p>\n </GlassCard>\n <GlassCard treatment=\"metric\" className=\"p-4\">\n <p className=\"text-sm text-status-error-text\">\n {tr(\"devportal.outOfStock\", \"Out of Stock\")}\n </p>\n <p className=\"mt-1 text-2xl font-semibold tabular-nums\">\n {productsLoading ? (\n <Loader2 className=\"h-5 w-5 animate-spin text-text-secondary\" />\n ) : (\n stats.outOfStock\n )}\n </p>\n </GlassCard>\n </div>\n </EmphasisPanel>\n\n {/* Filters + view toggle */}\n <div className=\"flex flex-col gap-4 sm:flex-row sm:items-center sm:justify-between\">\n <div className=\"flex flex-1 items-center gap-3\">\n {/* Search */}\n <div className=\"relative flex-1 max-w-md\">\n <Search\n size={16}\n className=\"absolute left-3 top-1/2 -translate-y-1/2 text-text-secondary\"\n />\n <input\n type=\"text\"\n placeholder={tr(\"devportal.searchItems\", \"Search items...\")}\n value={searchQuery}\n onChange={(e) => setSearchQuery(e.target.value)}\n className=\"w-full rounded-md border border-border-seam bg-bg-surface pl-9 pr-4 py-2 text-sm text-text-primary placeholder:text-text-muted focus:outline-none focus:ring-2 focus:ring-primary\"\n />\n </div>\n\n {/* Status filter */}\n <select\n value={statusFilter}\n onChange={(e) =>\n setStatusFilter(e.target.value as ProductStatus | \"\")\n }\n className=\"rounded-md border border-border-seam bg-bg-surface px-3 py-2 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-primary scheme-normal dark:scheme-dark [&_option]:bg-bg-surface [&_option]:text-text-primary\"\n >\n {STATUS_OPTIONS.map((opt) => (\n <option key={opt.value} value={opt.value}>\n {opt.label}\n </option>\n ))}\n </select>\n </div>\n\n {/* View toggle */}\n <div className=\"flex items-center gap-1 rounded-md border border-border-seam p-1\">\n <button\n onClick={() => setViewMode(\"grid\")}\n className={`rounded p-1.5 transition-colors ${\n viewMode === \"grid\"\n ? \"bg-bg-sunken text-text-primary\"\n : \"text-text-secondary hover:bg-bg-sunken/50\"\n }`}\n title={tr(\"devportal.gridView\", \"Grid view\")}\n >\n <Grid size={16} />\n </button>\n <button\n onClick={() => setViewMode(\"list\")}\n className={`rounded p-1.5 transition-colors ${\n viewMode === \"list\"\n ? \"bg-bg-sunken text-text-primary\"\n : \"text-text-secondary hover:bg-bg-sunken/50\"\n }`}\n title={tr(\"devportal.listView\", \"List view\")}\n >\n <List size={16} />\n </button>\n </div>\n </div>\n\n {/* Results count */}\n {physicalItems.length > 0 && (\n <p className=\"text-sm text-text-secondary\">\n {filteredItems.length} item\n {filteredItems.length !== 1 ? \"s\" : \"\"} found\n </p>\n )}\n\n {/* Content */}\n {!publisherId && !publisherLoading ? (\n <EmptyState\n illustration=\"empty-generic\"\n icon={<Package size={32} />}\n title={tr(\n \"devportal.noPublisherProfileYet\",\n \"No publisher profile yet\",\n )}\n description={tr(\n \"devportal.listAnItemToGetStarted\",\n \"List an item to get started. Your publisher profile will be created automatically.\",\n )}\n action={\n <button\n onClick={() => handleNavigate(\"/seller/items/new\")}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n <Plus size={16} />\n {tr(\"devportal.listAnItem\", \"List an Item\")}\n </button>\n }\n />\n ) : productsLoading ? (\n <div className=\"flex items-center justify-center py-12\">\n <Loader2 className=\"h-6 w-6 animate-spin text-text-secondary\" />\n <span className=\"ml-2 text-text-secondary\">\n {tr(\"devportal.loadingItems\", \"Loading items...\")}\n </span>\n </div>\n ) : filteredItems.length > 0 ? (\n viewMode === \"grid\" ? (\n <div className=\"grid gap-4 grid-cols-1 sm:grid-cols-2 lg:grid-cols-3\">\n {filteredItems.map((item) => (\n <ProductItemCard\n key={item.id}\n item={item}\n onEdit={() => handleNavigate(`/seller/items/${item.id}`)}\n />\n ))}\n </div>\n ) : (\n <div className=\"overflow-x-auto rounded-lg border border-border-seam\">\n <table className=\"w-full text-sm\">\n <thead>\n <tr className=\"border-b border-border-seam bg-bg-sunken\">\n <th className=\"px-4 py-3 text-left font-medium text-text-secondary\">\n Item\n </th>\n <th className=\"px-4 py-3 text-left font-medium text-text-secondary\">\n Type\n </th>\n <th className=\"px-4 py-3 text-left font-medium text-text-secondary\">\n Price\n </th>\n <th className=\"px-4 py-3 text-left font-medium text-text-secondary\">\n Stock\n </th>\n <th className=\"px-4 py-3 text-left font-medium text-text-secondary\">\n Status\n </th>\n <th className=\"px-4 py-3 text-right font-medium text-text-secondary\">\n Actions\n </th>\n </tr>\n </thead>\n <tbody>\n {filteredItems.map((item) => {\n const badge =\n STATUS_BADGE_STYLES[item.status] ??\n STATUS_BADGE_STYLES.DRAFT;\n return (\n <tr\n key={item.id}\n className=\"border-b border-border-subtle last:border-0 hover:bg-bg-sunken/50 transition-colors\"\n >\n <td className=\"px-4 py-3\">\n <div className=\"flex items-center gap-3\">\n {item.icon ? (\n <img\n src={item.icon}\n alt={item.name}\n className=\"h-8 w-8 rounded-lg object-cover shrink-0\"\n />\n ) : (\n <div className=\"flex h-8 w-8 items-center justify-center rounded-lg bg-bg-sunken shrink-0\">\n <Package\n size={14}\n className=\"text-text-muted\"\n />\n </div>\n )}\n <div className=\"min-w-0\">\n <p className=\"font-medium text-text-primary truncate\">\n {item.name}\n </p>\n {item.sku && (\n <p className=\"text-xs text-text-muted\">\n SKU: {item.sku}\n </p>\n )}\n </div>\n </div>\n </td>\n <td className=\"px-4 py-3 text-text-secondary\">\n {resolveTypeLabel(item.type)}\n </td>\n <td className=\"px-4 py-3 text-text-primary tabular-nums\">\n {formatPrice(item.price, item.currency)}\n </td>\n <td className=\"px-4 py-3\">\n {item.stockQuantity === 0 ? (\n <span className=\"text-status-error-text\">\n Out of stock\n </span>\n ) : (\n <span className=\"text-text-primary tabular-nums\">\n {item.stockQuantity}\n </span>\n )}\n </td>\n <td className=\"px-4 py-3\">\n <span\n className={`rounded-full px-2.5 py-0.5 text-xs font-medium ${badge.className}`}\n >\n {badge.label}\n </span>\n </td>\n <td className=\"px-4 py-3 text-right\">\n <button\n onClick={() =>\n handleNavigate(`/seller/items/${item.id}`)\n }\n className=\"inline-flex items-center gap-1.5 rounded-md border border-border-subtle px-3 py-1.5 text-xs font-medium text-text-secondary hover:text-text-primary hover:bg-bg-sunken transition-colors\"\n >\n <Edit size={12} />\n {tr(\"devportal.edit\", \"Edit\")}\n </button>\n </td>\n </tr>\n );\n })}\n </tbody>\n </table>\n </div>\n )\n ) : physicalItems.length > 0 && hasActiveFilters ? (\n <EmptyState\n illustration=\"empty-search\"\n title={tr(\n \"devportal.noItemsMatchYourSearch\",\n \"No items match your search\",\n )}\n description={tr(\n \"devportal.tryAdjustingFilters\",\n \"Try adjusting your search or filters\",\n )}\n />\n ) : (\n <EmptyState\n illustration=\"empty-data\"\n icon={<Package size={32} />}\n title={tr(\"devportal.noItemsYet\", \"No items yet\")}\n description={tr(\n \"devportal.addYourFirstPhysicalProduct\",\n \"Add your first physical product listing to start selling\",\n )}\n action={\n <button\n onClick={() => handleNavigate(\"/seller/items/new\")}\n className=\"inline-flex items-center gap-2 rounded-md bg-action-primary-bg px-4 py-2 text-sm font-medium text-action-primary-text hover:bg-action-primary-bg/90\"\n >\n <Plus size={16} />\n {tr(\"devportal.listAnItem\", \"List an Item\")}\n </button>\n }\n />\n )}\n </PageLayout>\n </PermissionGuard>\n );\n};\n\n// ---------------------------------------------------------------------------\n// Sub-components\n// ---------------------------------------------------------------------------\n\nconst ProductItemCard: FC<{\n item: PhysicalProductDetail;\n onEdit: () => void;\n}> = ({ item, onEdit }) => {\n const badge = STATUS_BADGE_STYLES[item.status] ?? STATUS_BADGE_STYLES.DRAFT;\n\n return (\n <GlassCard treatment=\"insight\" className=\"flex flex-col gap-3 p-4\">\n <div className=\"flex items-start gap-3\">\n {item.icon ? (\n <img\n src={item.icon}\n alt={item.name}\n className=\"h-20 w-20 rounded-xl object-cover shrink-0\"\n />\n ) : (\n <div className=\"flex h-20 w-20 items-center justify-center rounded-xl bg-bg-sunken shrink-0\">\n <Package size={32} className=\"text-text-muted\" />\n </div>\n )}\n <div className=\"min-w-0 flex-1\">\n <p className=\"font-semibold text-text-primary truncate\">\n {item.name}\n </p>\n {item.brand && (\n <p className=\"text-xs text-text-muted mt-0.5\">{item.brand}</p>\n )}\n <p className=\"text-sm text-text-secondary mt-1\">\n {formatPrice(item.price, item.currency)}\n </p>\n <div className=\"flex items-center gap-2 mt-2 flex-wrap\">\n <span\n className={`rounded-full px-2 py-0.5 text-xs font-medium ${badge.className}`}\n >\n {badge.label}\n </span>\n <span className=\"rounded-full px-2 py-0.5 text-xs font-medium bg-bg-muted text-text-secondary\">\n {resolveTypeLabel(item.type)}\n </span>\n </div>\n </div>\n </div>\n\n <div className=\"flex items-center justify-between pt-2 border-t border-border-subtle\">\n <div className=\"flex items-center gap-1.5 text-sm\">\n <Tag size={12} className=\"text-text-muted shrink-0\" />\n {item.stockQuantity === 0 ? (\n <span className=\"text-status-error-text\">Out of stock</span>\n ) : (\n <span className=\"text-text-secondary\">\n {item.stockQuantity} in stock\n </span>\n )}\n </div>\n <button\n onClick={onEdit}\n className=\"inline-flex items-center gap-1.5 rounded-md border border-border-subtle px-3 py-1.5 text-xs font-medium text-text-secondary hover:text-text-primary hover:bg-bg-sunken transition-colors\"\n >\n <Edit size={12} />\n Edit\n </button>\n </div>\n </GlassCard>\n );\n};\n"],"mappings":";;;;;;;;;;;;AAgEA,IAAM,IAAgB,IAAI,IAAI;CAAC;CAAO;CAAQ;CAAW,CAAC,EAEpD,IAA2D;CAC/D,aAAa;CACb,UAAU;CACV,WAAW;CACX,MAAM;CACN,WAAW;CACX,SAAS;CACT,aAAa;CACb,YAAY;CACb,EAEK,IAGF;CACF,WAAW;EACT,OAAO;EACP,WAAW;EACZ;CACD,gBAAgB;EACd,OAAO;EACP,WAAW;EACZ;CACD,OAAO;EACL,OAAO;EACP,WAAW;EACZ;CACD,UAAU;EACR,OAAO;EACP,WAAW;EACZ;CACD,UAAU;EACR,OAAO;EACP,WAAW;EACZ;CACF,EAEK,KAAiE;CACrE;EAAE,OAAO;EAAI,OAAO;EAAc;CAClC;EAAE,OAAO;EAAS,OAAO;EAAS;CAClC;EAAE,OAAO;EAAkB,OAAO;EAAkB;CACpD;EAAE,OAAO;EAAa,OAAO;EAAa;CAC1C;EAAE,OAAO;EAAY,OAAO;EAAY;CACxC;EAAE,OAAO;EAAY,OAAO;EAAY;CACzC;AAMD,SAAS,EAAY,GAAe,GAA0B;CAC5D,IAAM,IAAO,KAAY;AAOzB,QAAO,GANW,IAAI,KAAK,aAAa,SAAS;EAC/C,OAAO;EACP,UAAU;EACV,uBAAuB;EACvB,uBAAuB;EACxB,CAAC,CAAC,OAAO,EAAM,CACI,GAAG;;AAGzB,SAAS,EAAiB,GAAsB;AAC9C,QACE,EAAoB,MAAgC,EAAK,QAAQ,MAAM,IAAI;;AAQ/E,IAAM,IAAyB,4EAQzB,IAAqB,mUAuBd,UAA4B;CACvC,IAAM,EAAE,aAAU,aAAU,kBAAe,iBAAc,GAAc,EACjE,EAAE,SAAM,GAAS,EACjB,KAAM,GAAa,MAA6B;EACpD,IAAM,IAAQ,EAAE,EAAI;AACpB,SAAO,MAAU,IAAM,IAAW;IAG9B,IAAS,EAA6B,EAAc,EAEpD,CAAC,GAAkB,KAAuB,EAAS,GAAK,EACxD,CAAC,GAAiB,KAAsB,EAAS,GAAM,EACvD,CAAC,GAAa,KAAkB,EAAwB,KAAK,EAC7D,CAAC,GAAU,KAAe,EAAkC,EAAE,CAAC,EAC/D,CAAC,GAAO,KAAY,EAAwB,KAAK,EACjD,CAAC,GAAY,KAAiB,EAAS,EAAE,EAEzC,CAAC,GAAU,KAAe,EAA0B,OAAO,EAC3D,CAAC,GAAa,MAAkB,EAAS,GAAG,EAC5C,CAAC,GAAc,MAAmB,EAA6B,GAAG,EAElE,KAAkB,MAAiB;AACvC,MAAW,GAAG,IAAW,IAAO;;AAkDlC,CA9CA,QAAgB;EACd,IAAI,IAAY;AAuChB,SAtCA,EAAoB,GAAK,EACzB,EAAS,KAAK,GAEF,YAAY;AACtB,OAAI;IACF,IAAM,IAAM,MAAM,MAAM,GAAQ;KAC9B,QAAQ;KACR,SAAS;MACP,gBAAgB;MAChB,eAAe,UAAU,KAAa;MACvC;KACD,MAAM,KAAK,UAAU,EAAE,OAAO,GAAwB,CAAC;KACxD,CAAC;AACF,QAAI,EAAW;AACf,QAAI,CAAC,EAAI,GACP,OAAU,MAAM,8BAA8B,EAAI,SAAS;IAE7D,IAAM,IAAQ,MAAM,EAAI,MAAM;AAI9B,QAAI,EAAW;AACf,QAAI,EAAK,QAAQ,OACf,OAAU,MAAM,EAAK,OAAO,IAAI,WAAW,wBAAwB;AAErE,MAAe,EAAK,MAAM,aAAa,MAAM,KAAK;YAC3C,GAAK;AACZ,IAAK,KACH,EACE,aAAe,QAAQ,EAAI,UAAU,2BACtC;aAEK;AACR,IAAK,KAAW,EAAoB,GAAM;;MAIpC,QACG;AACX,OAAY;;IAEb;EAAC;EAAQ;EAAW;EAAW,CAAC,EAGnC,QAAgB;AACd,MAAI,CAAC,EAAa;EAClB,IAAI,IAAY;AAiDhB,SAhDA,EAAmB,GAAK,EACxB,EAAS,KAAK,GAEF,YAAY;AACtB,OAAI;IACF,IAAM,IAAM,MAAM,MAAM,GAAQ;KAC9B,QAAQ;KACR,SAAS;MACP,gBAAgB;MAChB,eAAe,UAAU,KAAa;MACvC;KACD,MAAM,KAAK,UAAU;MACnB,OAAO;MACP,WAAW,EAAE,gBAAa;MAC3B,CAAC;KACH,CAAC;AACF,QAAI,EAAW;AACf,QAAI,CAAC,EAAI,GACP,OAAU,MAAM,8BAA8B,EAAI,SAAS;IAE7D,IAAM,IAAQ,MAAM,EAAI,MAAM;AAQ9B,QAAI,EAAW;AACf,QAAI,EAAK,QAAQ,OACf,OAAU,MAAM,EAAK,OAAO,IAAI,WAAW,wBAAwB;AAErE,OACG,EAAK,MAAM,YAAY,EAAE,EAAE,KAAK,OAAO;KACtC,GAAG;KACH,QAAQ,EAAE;KACX,EAAE,CACJ;YACM,GAAK;AACZ,IAAK,KACH,EAAS,aAAe,QAAQ,EAAI,UAAU,uBAAuB;aAE/D;AACR,IAAK,KAAW,EAAmB,GAAM;;MAInC,QACG;AACX,OAAY;;IAEb;EAAC;EAAa;EAAQ;EAAW;EAAW,CAAC;CAGhD,IAAM,IAAgB,QACd,EAAS,QAAQ,MAAM,CAAC,EAAc,IAAI,EAAE,KAAK,CAAC,EACxD,CAAC,EAAS,CACX,EAEK,IAAgB,QAElB,EAAc,QAAQ,MAAS;EAC7B,IAAM,IACJ,CAAC,KACD,EAAK,KAAK,aAAa,CAAC,SAAS,EAAY,aAAa,CAAC,EACvD,IAAgB,CAAC,KAAgB,EAAK,WAAW;AACvD,SAAO,KAAiB;GACxB,EACJ;EAAC;EAAe;EAAa;EAAa,CAC3C,EAEK,IAAQ,SACL;EACL,OAAO,EAAc;EACrB,WAAW,EAAc,QAAQ,MAAM,EAAE,WAAW,YAAY,CAAC;EACjE,eAAe,EAAc,QAAQ,MAAM,EAAE,WAAW,iBAAiB,CACtE;EACH,YAAY,EAAc,QAAQ,MAAM,EAAE,kBAAkB,EAAE,CAAC;EAChE,GACD,CAAC,EAAc,CAChB;AAKD,KAHyB,KAAoB,EAAS,WAAW,KAAK,CAAC,EAIrE,QACE,kBAAC,GAAD;EACE,OAAO,EAAG,qBAAqB,WAAW;EAC1C,aAAa,EACX,+CACA,yCACD;YAED,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,GAAD,EAAS,WAAU,4CAA6C,CAAA,EAChE,kBAAC,QAAD;IAAM,WAAU;cACb,EAAG,0BAA0B,mBAAmB;IAC5C,CAAA,CACH;;EACK,CAAA;AAKjB,KAAI,KAAS,EAAS,WAAW,EAC/B,QACE,kBAAC,GAAD;EACE,OAAO,EAAG,qBAAqB,WAAW;EAC1C,aAAa,EACX,+CACA,yCACD;YAED,kBAAC,OAAD;GAAK,WAAU;aAAf;IACE,kBAAC,GAAD,EAAa,WAAU,0CAA2C,CAAA;IAClE,kBAAC,MAAD;KAAI,WAAU;eACX,EAAG,+BAA+B,uBAAuB;KACvD,CAAA;IACL,kBAAC,KAAD;KAAG,WAAU;eAAoC;KAAU,CAAA;IAC3D,kBAAC,UAAD;KACE,eAAe,GAAe,MAAM,IAAI,EAAE;KAC1C,WAAU;eAET,EAAG,sBAAsB,YAAY;KAC/B,CAAA;IACL;;EACK,CAAA;CAIjB,IAAM,KAAmB,GAAQ,KAAe;AAEhD,QACE,kBAAC,GAAD;EAAiB,UAAA;YACf,kBAAC,GAAD;GACE,OAAO,EAAG,qBAAqB,WAAW;GAC1C,aAAa,EACX,+CACA,yCACD;GACD,SACE,kBAAC,UAAD;IACE,eAAe,EAAe,oBAAoB;IAClD,WAAU;cAFZ,CAIE,kBAAC,GAAD;KAAM,MAAM;KAAI,eAAY;KAAS,CAAA,EACpC,EAAG,wBAAwB,eAAe,CACpC;;aAbb;IAiBE,kBAAC,GAAD;KAAe,WAAU;eACvB,kBAAC,OAAD;MAAK,WAAU;gBAAf;OACE,kBAAC,GAAD;QAAW,WAAU;QAAS,WAAU;kBAAxC,CACE,kBAAC,KAAD;SAAG,WAAU;mBACV,EAAG,wBAAwB,cAAc;SACxC,CAAA,EACJ,kBAAC,KAAD;SAAG,WAAU;mBACV,IACC,kBAAC,GAAD,EAAS,WAAU,4CAA6C,CAAA,GAEhE,EAAM;SAEN,CAAA,CACM;;OACZ,kBAAC,GAAD;QAAW,WAAU;QAAS,WAAU;kBAAxC,CACE,kBAAC,KAAD;SAAG,WAAU;mBACV,EAAG,uBAAuB,YAAY;SACrC,CAAA,EACJ,kBAAC,KAAD;SAAG,WAAU;mBACV,IACC,kBAAC,GAAD,EAAS,WAAU,4CAA6C,CAAA,GAEhE,EAAM;SAEN,CAAA,CACM;;OACZ,kBAAC,GAAD;QAAW,WAAU;QAAS,WAAU;kBAAxC,CACE,kBAAC,KAAD;SAAG,WAAU;mBACV,EAAG,2BAA2B,iBAAiB;SAC9C,CAAA,EACJ,kBAAC,KAAD;SAAG,WAAU;mBACV,IACC,kBAAC,GAAD,EAAS,WAAU,4CAA6C,CAAA,GAEhE,EAAM;SAEN,CAAA,CACM;;OACZ,kBAAC,GAAD;QAAW,WAAU;QAAS,WAAU;kBAAxC,CACE,kBAAC,KAAD;SAAG,WAAU;mBACV,EAAG,wBAAwB,eAAe;SACzC,CAAA,EACJ,kBAAC,KAAD;SAAG,WAAU;mBACV,IACC,kBAAC,GAAD,EAAS,WAAU,4CAA6C,CAAA,GAEhE,EAAM;SAEN,CAAA,CACM;;OACR;;KACQ,CAAA;IAGhB,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,OAAD;MAAK,WAAU;gBAAf,CAEE,kBAAC,OAAD;OAAK,WAAU;iBAAf,CACE,kBAAC,GAAD;QACE,MAAM;QACN,WAAU;QACV,CAAA,EACF,kBAAC,SAAD;QACE,MAAK;QACL,aAAa,EAAG,yBAAyB,kBAAkB;QAC3D,OAAO;QACP,WAAW,MAAM,GAAe,EAAE,OAAO,MAAM;QAC/C,WAAU;QACV,CAAA,CACE;UAGN,kBAAC,UAAD;OACE,OAAO;OACP,WAAW,MACT,GAAgB,EAAE,OAAO,MAA4B;OAEvD,WAAU;iBAET,GAAe,KAAK,MACnB,kBAAC,UAAD;QAAwB,OAAO,EAAI;kBAChC,EAAI;QACE,EAFI,EAAI,MAER,CACT;OACK,CAAA,CACL;SAGN,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,UAAD;OACE,eAAe,EAAY,OAAO;OAClC,WAAW,mCACT,MAAa,SACT,mCACA;OAEN,OAAO,EAAG,sBAAsB,YAAY;iBAE5C,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA;OACX,CAAA,EACT,kBAAC,UAAD;OACE,eAAe,EAAY,OAAO;OAClC,WAAW,mCACT,MAAa,SACT,mCACA;OAEN,OAAO,EAAG,sBAAsB,YAAY;iBAE5C,kBAAC,IAAD,EAAM,MAAM,IAAM,CAAA;OACX,CAAA,CACL;QACF;;IAGL,EAAc,SAAS,KACtB,kBAAC,KAAD;KAAG,WAAU;eAAb;MACG,EAAc;MAAO;MACrB,EAAc,WAAW,IAAU,KAAN;MAAS;MACrC;;IAIL,CAAC,KAAe,CAAC,IAChB,kBAAC,GAAD;KACE,cAAa;KACb,MAAM,kBAAC,GAAD,EAAS,MAAM,IAAM,CAAA;KAC3B,OAAO,EACL,mCACA,2BACD;KACD,aAAa,EACX,oCACA,qFACD;KACD,QACE,kBAAC,UAAD;MACE,eAAe,EAAe,oBAAoB;MAClD,WAAU;gBAFZ,CAIE,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA,EACjB,EAAG,wBAAwB,eAAe,CACpC;;KAEX,CAAA,GACA,IACF,kBAAC,OAAD;KAAK,WAAU;eAAf,CACE,kBAAC,GAAD,EAAS,WAAU,4CAA6C,CAAA,EAChE,kBAAC,QAAD;MAAM,WAAU;gBACb,EAAG,0BAA0B,mBAAmB;MAC5C,CAAA,CACH;SACJ,EAAc,SAAS,IACzB,MAAa,SACX,kBAAC,OAAD;KAAK,WAAU;eACZ,EAAc,KAAK,MAClB,kBAAC,GAAD;MAEQ;MACN,cAAc,EAAe,iBAAiB,EAAK,KAAK;MACxD,EAHK,EAAK,GAGV,CACF;KACE,CAAA,GAEN,kBAAC,OAAD;KAAK,WAAU;eACb,kBAAC,SAAD;MAAO,WAAU;gBAAjB,CACE,kBAAC,SAAD,EAAA,UACE,kBAAC,MAAD;OAAI,WAAU;iBAAd;QACE,kBAAC,MAAD;SAAI,WAAU;mBAAsD;SAE/D,CAAA;QACL,kBAAC,MAAD;SAAI,WAAU;mBAAsD;SAE/D,CAAA;QACL,kBAAC,MAAD;SAAI,WAAU;mBAAsD;SAE/D,CAAA;QACL,kBAAC,MAAD;SAAI,WAAU;mBAAsD;SAE/D,CAAA;QACL,kBAAC,MAAD;SAAI,WAAU;mBAAsD;SAE/D,CAAA;QACL,kBAAC,MAAD;SAAI,WAAU;mBAAuD;SAEhE,CAAA;QACF;UACC,CAAA,EACR,kBAAC,SAAD,EAAA,UACG,EAAc,KAAK,MAAS;OAC3B,IAAM,IACJ,EAAoB,EAAK,WACzB,EAAoB;AACtB,cACE,kBAAC,MAAD;QAEE,WAAU;kBAFZ;SAIE,kBAAC,MAAD;UAAI,WAAU;oBACZ,kBAAC,OAAD;WAAK,WAAU;qBAAf,CACG,EAAK,OACJ,kBAAC,OAAD;YACE,KAAK,EAAK;YACV,KAAK,EAAK;YACV,WAAU;YACV,CAAA,GAEF,kBAAC,OAAD;YAAK,WAAU;sBACb,kBAAC,GAAD;aACE,MAAM;aACN,WAAU;aACV,CAAA;YACE,CAAA,EAER,kBAAC,OAAD;YAAK,WAAU;sBAAf,CACE,kBAAC,KAAD;aAAG,WAAU;uBACV,EAAK;aACJ,CAAA,EACH,EAAK,OACJ,kBAAC,KAAD;aAAG,WAAU;uBAAb,CAAuC,SAC/B,EAAK,IACT;eAEF;cACF;;UACH,CAAA;SACL,kBAAC,MAAD;UAAI,WAAU;oBACX,EAAiB,EAAK,KAAK;UACzB,CAAA;SACL,kBAAC,MAAD;UAAI,WAAU;oBACX,EAAY,EAAK,OAAO,EAAK,SAAS;UACpC,CAAA;SACL,kBAAC,MAAD;UAAI,WAAU;oBACX,EAAK,kBAAkB,IACtB,kBAAC,QAAD;WAAM,WAAU;qBAAyB;WAElC,CAAA,GAEP,kBAAC,QAAD;WAAM,WAAU;qBACb,EAAK;WACD,CAAA;UAEN,CAAA;SACL,kBAAC,MAAD;UAAI,WAAU;oBACZ,kBAAC,QAAD;WACE,WAAW,kDAAkD,EAAM;qBAElE,EAAM;WACF,CAAA;UACJ,CAAA;SACL,kBAAC,MAAD;UAAI,WAAU;oBACZ,kBAAC,UAAD;WACE,eACE,EAAe,iBAAiB,EAAK,KAAK;WAE5C,WAAU;qBAJZ,CAME,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA,EACjB,EAAG,kBAAkB,OAAO,CACtB;;UACN,CAAA;SACF;UAlEE,EAAK,GAkEP;QAEP,EACI,CAAA,CACF;;KACJ,CAAA,GAEN,EAAc,SAAS,KAAK,KAC9B,kBAAC,GAAD;KACE,cAAa;KACb,OAAO,EACL,oCACA,6BACD;KACD,aAAa,EACX,iCACA,uCACD;KACD,CAAA,GAEF,kBAAC,GAAD;KACE,cAAa;KACb,MAAM,kBAAC,GAAD,EAAS,MAAM,IAAM,CAAA;KAC3B,OAAO,EAAG,wBAAwB,eAAe;KACjD,aAAa,EACX,yCACA,2DACD;KACD,QACE,kBAAC,UAAD;MACE,eAAe,EAAe,oBAAoB;MAClD,WAAU;gBAFZ,CAIE,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA,EACjB,EAAG,wBAAwB,eAAe,CACpC;;KAEX,CAAA;IAEO;;EACG,CAAA;GAQhB,KAGA,EAAE,SAAM,gBAAa;CACzB,IAAM,IAAQ,EAAoB,EAAK,WAAW,EAAoB;AAEtE,QACE,kBAAC,GAAD;EAAW,WAAU;EAAU,WAAU;YAAzC,CACE,kBAAC,OAAD;GAAK,WAAU;aAAf,CACG,EAAK,OACJ,kBAAC,OAAD;IACE,KAAK,EAAK;IACV,KAAK,EAAK;IACV,WAAU;IACV,CAAA,GAEF,kBAAC,OAAD;IAAK,WAAU;cACb,kBAAC,GAAD;KAAS,MAAM;KAAI,WAAU;KAAoB,CAAA;IAC7C,CAAA,EAER,kBAAC,OAAD;IAAK,WAAU;cAAf;KACE,kBAAC,KAAD;MAAG,WAAU;gBACV,EAAK;MACJ,CAAA;KACH,EAAK,SACJ,kBAAC,KAAD;MAAG,WAAU;gBAAkC,EAAK;MAAU,CAAA;KAEhE,kBAAC,KAAD;MAAG,WAAU;gBACV,EAAY,EAAK,OAAO,EAAK,SAAS;MACrC,CAAA;KACJ,kBAAC,OAAD;MAAK,WAAU;gBAAf,CACE,kBAAC,QAAD;OACE,WAAW,gDAAgD,EAAM;iBAEhE,EAAM;OACF,CAAA,EACP,kBAAC,QAAD;OAAM,WAAU;iBACb,EAAiB,EAAK,KAAK;OACvB,CAAA,CACH;;KACF;MACF;MAEN,kBAAC,OAAD;GAAK,WAAU;aAAf,CACE,kBAAC,OAAD;IAAK,WAAU;cAAf,CACE,kBAAC,GAAD;KAAK,MAAM;KAAI,WAAU;KAA6B,CAAA,EACrD,EAAK,kBAAkB,IACtB,kBAAC,QAAD;KAAM,WAAU;eAAyB;KAAmB,CAAA,GAE5D,kBAAC,QAAD;KAAM,WAAU;eAAhB,CACG,EAAK,eAAc,YACf;OAEL;OACN,kBAAC,UAAD;IACE,SAAS;IACT,WAAU;cAFZ,CAIE,kBAAC,GAAD,EAAM,MAAM,IAAM,CAAA,EAAA,OAEX;MACL;KACI"}
@@ -1 +1 @@
1
- {"version":3,"file":"SellerOrdersPage.d.ts","sourceRoot":"","sources":["../../../src/devportal/pages/SellerOrdersPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAoNhC,eAAO,MAAM,gBAAgB,EAAE,EAmkB9B,CAAC"}
1
+ {"version":3,"file":"SellerOrdersPage.d.ts","sourceRoot":"","sources":["../../../src/devportal/pages/SellerOrdersPage.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC;AAqNhC,eAAO,MAAM,gBAAgB,EAAE,EAmkB9B,CAAC"}
@@ -4,13 +4,14 @@ import { PageLayout as n } from "../components/PageLayout.js";
4
4
  import { ReportOrderIssueModal as r } from "../components/ReportOrderIssueModal.js";
5
5
  import { PermissionGuard as i } from "../components/PermissionGuard.js";
6
6
  import "../components/index.js";
7
+ import { resolveGlobalGraphqlEndpoint as ee } from "../utils/graphqlEndpoint.js";
7
8
  import { formatCurrency as a } from "../utils/currency.js";
8
- import { useCallback as ee, useEffect as o, useMemo as s, useState as c } from "react";
9
- import { AlertCircle as l, CheckCircle2 as u, ChevronDown as d, Flag as f, Loader2 as p, Package as m, ShoppingBag as te } from "lucide-react";
10
- import { Fragment as ne, jsx as h, jsxs as g } from "react/jsx-runtime";
11
- import { useI18n as re } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
9
+ import { useCallback as te, useEffect as o, useMemo as s, useState as c } from "react";
10
+ import { AlertCircle as ne, CheckCircle2 as l, ChevronDown as u, Flag as d, Loader2 as f, Package as re, ShoppingBag as p } from "lucide-react";
11
+ import { Fragment as m, jsx as h, jsxs as g } from "react/jsx-runtime";
12
+ import { useI18n as ie } from "@burdenoff/fe-libs/shared/providers/shell/I18nProvider";
12
13
  //#region src/devportal/pages/SellerOrdersPage.tsx
13
- var ie = {
14
+ var ae = {
14
15
  OUT_OF_STOCK: "Out of stock",
15
16
  CANNOT_FULFILL: "Cannot fulfill",
16
17
  WRONG_ADDRESS: "Wrong address",
@@ -44,7 +45,7 @@ var ie = {
44
45
  label: "Cancelled",
45
46
  className: "text-text-muted bg-bg-muted"
46
47
  }
47
- }, v = [
48
+ }, oe = [
48
49
  {
49
50
  value: "",
50
51
  label: "All Orders"
@@ -73,11 +74,11 @@ var ie = {
73
74
  value: "CANCELLED",
74
75
  label: "Cancelled"
75
76
  }
76
- ], ae = "\n query SellerOrdersOrgs {\n myDeveloperOrganizations {\n id\n name\n slug\n kind\n }\n }\n", oe = "\n query SellerOrders($organizationId: ID!, $status: SaleStatus, $limit: Int, $offset: Int) {\n developerOrgSales(\n organizationId: $organizationId\n status: $status\n limit: $limit\n offset: $offset\n ) {\n totalCount\n edges {\n node {\n id\n storeOrderId\n storeProductId\n grossAmount\n netAmount\n platformFee\n currency\n status\n buyerUserId\n purchasedAt\n refundAmount\n refundedAt\n refundReason\n discountAmount\n taxAmount\n }\n }\n pageInfo { hasNextPage hasPreviousPage }\n }\n }\n", y = "\n mutation ResolveOrderIssue($id: ID!, $organizationId: ID) {\n resolveOrderIssueFlag(id: $id, organizationId: $organizationId) {\n id\n status\n }\n }\n", b = "id category note status raisedByOrgId createdAt";
77
- function x(e) {
78
- return `query SellerOrderIssueFlags {\n ${e.map((e, t) => `f${t}: orderIssueFlags(orderId: ${JSON.stringify(e)}) { ${b} }`).join("\n ")}\n }`;
77
+ ], se = "\n query SellerOrdersOrgs {\n myDeveloperOrganizations {\n id\n name\n slug\n kind\n }\n }\n", ce = "\n query SellerOrders($organizationId: ID!, $status: SaleStatus, $limit: Int, $offset: Int) {\n developerOrgSales(\n organizationId: $organizationId\n status: $status\n limit: $limit\n offset: $offset\n ) {\n totalCount\n edges {\n node {\n id\n storeOrderId\n storeProductId\n grossAmount\n netAmount\n platformFee\n currency\n status\n buyerUserId\n purchasedAt\n refundAmount\n refundedAt\n refundReason\n discountAmount\n taxAmount\n }\n }\n pageInfo { hasNextPage hasPreviousPage }\n }\n }\n", v = "\n mutation ResolveOrderIssue($id: ID!, $organizationId: ID) {\n resolveOrderIssueFlag(id: $id, organizationId: $organizationId) {\n id\n status\n }\n }\n", y = "id category note status raisedByOrgId createdAt";
78
+ function b(e) {
79
+ return `query SellerOrderIssueFlags {\n ${e.map((e, t) => `f${t}: orderIssueFlags(orderId: ${JSON.stringify(e)}) { ${y} }`).join("\n ")}\n }`;
79
80
  }
80
- function se(e) {
81
+ function le(e) {
81
82
  return new Date(e).toLocaleDateString("en-US", {
82
83
  year: "numeric",
83
84
  month: "short",
@@ -86,17 +87,17 @@ function se(e) {
86
87
  minute: "2-digit"
87
88
  });
88
89
  }
89
- function ce(e, t) {
90
+ function ue(e, t) {
90
91
  return e ? `#${e.slice(0, 8).toUpperCase()}` : `#${t.slice(0, 8).toUpperCase()}`;
91
92
  }
92
- var S = () => {
93
- let { apiGatewayUrl: b, authToken: S } = e(), { t: le } = re(), C = (e, t) => {
94
- let n = le(e);
93
+ var x = () => {
94
+ let { apiGatewayUrl: y, authToken: x } = e(), { t: S } = ie(), C = (e, t) => {
95
+ let n = S(e);
95
96
  return n === e ? t : n;
96
- }, w = b ?? "/global/graphql", [T, E] = c(!0), [D, ue] = c([]), [O, k] = c(null), [A, j] = c(!1), [M, N] = c([]), [P, F] = c(0), [I, L] = c(null), [R, z] = c(0), [B, V] = c(""), [H, U] = c(0), W = s(() => ({
97
+ }, w = ee(y), [T, E] = c(!0), [D, de] = c([]), [O, k] = c(null), [A, j] = c(!1), [M, N] = c([]), [P, F] = c(0), [I, L] = c(null), [R, z] = c(0), [B, V] = c(""), [H, U] = c(0), W = s(() => ({
97
98
  "Content-Type": "application/json",
98
- Authorization: `Bearer ${S ?? ""}`
99
- }), [S]);
99
+ Authorization: `Bearer ${x ?? ""}`
100
+ }), [x]);
100
101
  o(() => {
101
102
  let e = !1;
102
103
  return E(!0), (async () => {
@@ -104,11 +105,11 @@ var S = () => {
104
105
  let t = await (await fetch(w, {
105
106
  method: "POST",
106
107
  headers: W,
107
- body: JSON.stringify({ query: ae })
108
+ body: JSON.stringify({ query: se })
108
109
  })).json();
109
110
  if (e) return;
110
111
  let n = (t.data?.myDeveloperOrganizations ?? []).filter((e) => e.kind === "PHYSICAL");
111
- ue(n), n.length > 0 && k(n[0].id);
112
+ de(n), n.length > 0 && k(n[0].id);
112
113
  } catch {} finally {
113
114
  e || E(!1);
114
115
  }
@@ -130,7 +131,7 @@ var S = () => {
130
131
  method: "POST",
131
132
  headers: W,
132
133
  body: JSON.stringify({
133
- query: oe,
134
+ query: ce,
134
135
  variables: t
135
136
  })
136
137
  });
@@ -159,7 +160,7 @@ var S = () => {
159
160
  W,
160
161
  R
161
162
  ]);
162
- let G = s(() => M.filter((e) => e.storeProductId !== null), [M]), [de, K] = c({}), [q, J] = c(null), [Y, X] = c(null), Z = s(() => G.map((e) => e.storeOrderId).filter((e) => e !== null), [G]), Q = ee(async () => {
163
+ let G = s(() => M.filter((e) => e.storeProductId !== null), [M]), [fe, K] = c({}), [q, J] = c(null), [Y, X] = c(null), Z = s(() => G.map((e) => e.storeOrderId).filter((e) => e !== null), [G]), Q = te(async () => {
163
164
  if (Z.length === 0) {
164
165
  K({});
165
166
  return;
@@ -168,7 +169,7 @@ var S = () => {
168
169
  let e = await (await fetch(w, {
169
170
  method: "POST",
170
171
  headers: W,
171
- body: JSON.stringify({ query: x(Z) })
172
+ body: JSON.stringify({ query: b(Z) })
172
173
  })).json(), t = {};
173
174
  Z.forEach((n, r) => {
174
175
  t[n] = e.data?.[`f${r}`] ?? [];
@@ -182,14 +183,14 @@ var S = () => {
182
183
  o(() => {
183
184
  Q();
184
185
  }, [Q]);
185
- let fe = async (e, t) => {
186
+ let pe = async (e, t) => {
186
187
  X(e);
187
188
  try {
188
189
  await fetch(w, {
189
190
  method: "POST",
190
191
  headers: W,
191
192
  body: JSON.stringify({
192
- query: y,
193
+ query: v,
193
194
  variables: {
194
195
  id: e,
195
196
  organizationId: t
@@ -212,14 +213,14 @@ var S = () => {
212
213
  title: C("devportal.orders", "Orders"),
213
214
  children: /* @__PURE__ */ h("div", {
214
215
  className: "flex items-center justify-center py-20",
215
- children: /* @__PURE__ */ h(p, { className: "h-8 w-8 animate-spin text-text-secondary" })
216
+ children: /* @__PURE__ */ h(f, { className: "h-8 w-8 animate-spin text-text-secondary" })
216
217
  })
217
218
  }) : D.length === 0 ? /* @__PURE__ */ h(n, {
218
219
  title: C("devportal.orders", "Orders"),
219
220
  description: C("devportal.ordersDesc", "Orders placed by customers for your physical items."),
220
221
  children: /* @__PURE__ */ h(t, {
221
222
  illustration: "empty-generic",
222
- icon: /* @__PURE__ */ h(te, { size: 32 }),
223
+ icon: /* @__PURE__ */ h(p, { size: 32 }),
223
224
  title: C("devportal.noOrgForOrders", "No organization yet"),
224
225
  description: C("devportal.createOrgToSell", "Create a developer organization to start selling physical products and receive orders.")
225
226
  })
@@ -243,7 +244,7 @@ var S = () => {
243
244
  value: e.id,
244
245
  children: e.name
245
246
  }, e.id))
246
- }), /* @__PURE__ */ h(d, {
247
+ }), /* @__PURE__ */ h(u, {
247
248
  size: 14,
248
249
  className: "pointer-events-none absolute right-2.5 top-1/2 -translate-y-1/2 text-text-muted"
249
250
  })]
@@ -255,11 +256,11 @@ var S = () => {
255
256
  V(e.target.value), U(0);
256
257
  },
257
258
  className: "appearance-none rounded-md border border-border-seam bg-bg-surface pl-3 pr-8 py-2 text-sm text-text-primary focus:outline-none focus:ring-2 focus:ring-primary scheme-normal dark:scheme-dark [&_option]:bg-bg-surface [&_option]:text-text-primary",
258
- children: v.map((e) => /* @__PURE__ */ h("option", {
259
+ children: oe.map((e) => /* @__PURE__ */ h("option", {
259
260
  value: e.value,
260
261
  children: e.label
261
262
  }, e.value))
262
- }), /* @__PURE__ */ h(d, {
263
+ }), /* @__PURE__ */ h(u, {
263
264
  size: 14,
264
265
  className: "pointer-events-none absolute right-2.5 top-1/2 -translate-y-1/2 text-text-muted"
265
266
  })]
@@ -294,14 +295,14 @@ var S = () => {
294
295
  children: e.label
295
296
  }), /* @__PURE__ */ h("p", {
296
297
  className: "mt-1 text-xl font-semibold tabular-nums",
297
- children: A ? /* @__PURE__ */ h(p, { className: "h-4 w-4 animate-spin text-text-secondary" }) : e.value
298
+ children: A ? /* @__PURE__ */ h(f, { className: "h-4 w-4 animate-spin text-text-secondary" }) : e.value
298
299
  })]
299
300
  }, e.label))
300
301
  }),
301
302
  I && /* @__PURE__ */ g("div", {
302
303
  className: "mb-4 flex items-center gap-3 rounded-lg border border-status-error-border/50 bg-status-error-bg/10 px-4 py-3 text-sm",
303
304
  children: [
304
- /* @__PURE__ */ h(l, {
305
+ /* @__PURE__ */ h(ne, {
305
306
  size: 16,
306
307
  className: "shrink-0 text-status-error-text"
307
308
  }),
@@ -318,13 +319,13 @@ var S = () => {
318
319
  }),
319
320
  A ? /* @__PURE__ */ h("div", {
320
321
  className: "flex items-center justify-center py-16",
321
- children: /* @__PURE__ */ h(p, { className: "h-6 w-6 animate-spin text-text-secondary" })
322
+ children: /* @__PURE__ */ h(f, { className: "h-6 w-6 animate-spin text-text-secondary" })
322
323
  }) : G.length === 0 ? /* @__PURE__ */ h(t, {
323
324
  illustration: "empty-data",
324
- icon: /* @__PURE__ */ h(m, { size: 32 }),
325
+ icon: /* @__PURE__ */ h(re, { size: 32 }),
325
326
  title: B ? C("devportal.noOrdersForFilter", "No orders match this filter") : C("devportal.noOrdersYet", "No orders yet"),
326
327
  description: B ? C("devportal.tryDifferentFilter", "Try selecting a different status filter") : C("devportal.ordersWillAppear", "Orders placed for your physical items will appear here once customers make purchases.")
327
- }) : /* @__PURE__ */ g(ne, { children: [/* @__PURE__ */ h("div", {
328
+ }) : /* @__PURE__ */ g(m, { children: [/* @__PURE__ */ h("div", {
328
329
  className: "overflow-x-auto rounded-lg border border-border-seam",
329
330
  children: /* @__PURE__ */ g("table", {
330
331
  className: "w-full text-sm",
@@ -365,7 +366,7 @@ var S = () => {
365
366
  })
366
367
  ]
367
368
  }) }), /* @__PURE__ */ h("tbody", { children: G.map((e) => {
368
- let t = _[e.status] ?? _.PENDING, n = e.storeOrderId ? de[e.storeOrderId] ?? [] : [], r = n.find((e) => e.status === "OPEN");
369
+ let t = _[e.status] ?? _.PENDING, n = e.storeOrderId ? fe[e.storeOrderId] ?? [] : [], r = n.find((e) => e.status === "OPEN");
369
370
  return /* @__PURE__ */ g("tr", {
370
371
  className: "border-b border-border-subtle last:border-0 hover:bg-bg-sunken/50 transition-colors",
371
372
  children: [
@@ -373,7 +374,7 @@ var S = () => {
373
374
  className: "px-4 py-3",
374
375
  children: /* @__PURE__ */ h("span", {
375
376
  className: "font-mono text-xs font-semibold text-text-primary",
376
- children: ce(e.storeOrderId, e.id)
377
+ children: ue(e.storeOrderId, e.id)
377
378
  })
378
379
  }),
379
380
  /* @__PURE__ */ h("td", {
@@ -414,7 +415,7 @@ var S = () => {
414
415
  }),
415
416
  /* @__PURE__ */ h("td", {
416
417
  className: "px-4 py-3 text-xs text-text-secondary whitespace-nowrap",
417
- children: se(e.purchasedAt)
418
+ children: le(e.purchasedAt)
418
419
  }),
419
420
  /* @__PURE__ */ h("td", {
420
421
  className: "px-4 py-3",
@@ -423,19 +424,19 @@ var S = () => {
423
424
  children: [/* @__PURE__ */ g("span", {
424
425
  title: r.note ?? void 0,
425
426
  className: "flex items-center gap-1 rounded-full bg-status-warning-bg-subtle px-2.5 py-0.5 text-xs font-medium text-status-warning-text",
426
- children: [/* @__PURE__ */ h(f, { size: 11 }), ie[r.category]]
427
+ children: [/* @__PURE__ */ h(d, { size: 11 }), ae[r.category]]
427
428
  }), r.raisedByOrgId === O && /* @__PURE__ */ h("button", {
428
- onClick: () => void fe(r.id, r.raisedByOrgId),
429
+ onClick: () => void pe(r.id, r.raisedByOrgId),
429
430
  disabled: Y === r.id,
430
431
  className: "text-xs font-medium text-text-secondary underline hover:text-text-primary disabled:opacity-50",
431
- children: Y === r.id ? /* @__PURE__ */ h(p, { className: "h-3 w-3 animate-spin" }) : "Mark Resolved"
432
+ children: Y === r.id ? /* @__PURE__ */ h(f, { className: "h-3 w-3 animate-spin" }) : "Mark Resolved"
432
433
  })]
433
434
  }) : /* @__PURE__ */ g("div", {
434
435
  className: "flex items-center gap-2",
435
436
  children: [n.length > 0 && /* @__PURE__ */ g("span", {
436
437
  title: "Previously reported and resolved",
437
438
  className: "flex items-center gap-1 text-xs text-status-success-text",
438
- children: [/* @__PURE__ */ h(u, { size: 11 }), "Resolved"]
439
+ children: [/* @__PURE__ */ h(l, { size: 11 }), "Resolved"]
439
440
  }), /* @__PURE__ */ h("button", {
440
441
  onClick: () => J(e.storeOrderId),
441
442
  className: "text-xs font-medium text-text-secondary underline hover:text-text-primary",
@@ -492,6 +493,6 @@ var S = () => {
492
493
  });
493
494
  };
494
495
  //#endregion
495
- export { S as SellerOrdersPage };
496
+ export { x as SellerOrdersPage };
496
497
 
497
498
  //# sourceMappingURL=SellerOrdersPage.js.map