import React, { useState, useEffect, useCallback } from 'react' import { createFileRoute } from '@tanstack/react-router' import { useQueryClient } from '@tanstack/react-query' import { DndContext, closestCenter, PointerSensor, useSensor, useSensors, type DragEndEvent } from '@dnd-kit/core' import { SortableContext, useSortable, arrayMove, verticalListSortingStrategy } from '@dnd-kit/sortable' import { CSS } from '@dnd-kit/utilities' import { GripVertical, Image as ImageIcon, XCircle, ChevronLeft, CircleAlert, Package } from 'lucide-react' import { AppContainer, p as MyText } from 'web-components' import { trpc } from '@/lib/trpc-client' import type { StoreProductCard } from '@packages/shared' import type { DragOrderItemProps } from '@/types/drag-order-item' export const Route = createFileRoute('/dashboard/customize-app/ordering')({ component: AllItemsOrder, }) type Product = Pick const itemStyle: React.CSSProperties = { width: '100%', height: 60, backgroundColor: 'white', borderRadius: 8, borderWidth: 1, borderStyle: 'solid', borderColor: '#e5e7eb', padding: 10, display: 'flex', flexDirection: 'row', alignItems: 'center', boxShadow: '0 1px 2px rgba(0,0,0,0.1)', marginTop: 4, marginBottom: 4, } const activeItemStyle: React.CSSProperties = { ...itemStyle, borderColor: '#3b82f6', boxShadow: '0 4px 8px rgba(59,130,246,0.3)', } const ProductItem: React.FC> = ({ item, isActive, }) => { const { attributes, listeners, setNodeRef, transform, transition, isDragging } = useSortable({ id: item.id }) const active = isActive || isDragging return (
{item.images?.[0] ? ( {item.name} ) : (
)}
{item.name.length > 30 ? item.name.substring(0, 30) + '...' : item.name} {item.isOutOfStock && ( )}
) } function AllItemsOrder() { const queryClient = useQueryClient() const [products, setProducts] = useState([]) const [hasChanges, setHasChanges] = useState(false) const { data: constants, isLoading: isLoadingConstants, error: constantsError } = trpc.admin.const.getConstants.useQuery() const { data: allProducts, isLoading: isLoadingProducts, error: productsError } = trpc.common.product.getAllProductsSummary.useQuery() const updateConstants = trpc.admin.const.updateConstants.useMutation() const sensors = useSensors(useSensor(PointerSensor, { activationConstraint: { distance: 8 } })) useEffect(() => { if (allProducts?.products) { const allItemsOrderConstant = constants?.find((c) => c.key === 'allItemsOrder') let orderedIds: number[] = [] if (allItemsOrderConstant) { const value = allItemsOrderConstant.value if (Array.isArray(value)) { orderedIds = value.map((id: any) => parseInt(id)) } else if (typeof value === 'string') { orderedIds = value.split(',').map((id: string) => parseInt(id.trim())).filter((id) => !isNaN(id)) } } const productMap = new Map(allProducts.products.map((p) => [p.id, p])) const sortedProducts: Product[] = [] for (const id of orderedIds) { const product = productMap.get(id) if (product) { sortedProducts.push({ id: product.id, name: product.name, images: product.images || [], isOutOfStock: product.isOutOfStock || false, }) productMap.delete(id) } } for (const product of productMap.values()) { sortedProducts.push({ id: product.id, name: product.name, images: product.images || [], isOutOfStock: product.isOutOfStock || false, }) } setProducts(sortedProducts) } }, [constants, allProducts]) const handleDragEnd = useCallback((event: DragEndEvent) => { const { active, over } = event if (over && active.id !== over.id) { setProducts((prev) => { const oldIndex = prev.findIndex((p) => p.id === active.id) const newIndex = prev.findIndex((p) => p.id === over.id) return arrayMove(prev, oldIndex, newIndex) }) setHasChanges(true) } }, []) const handleSave = () => { const productIds = products.map((p) => p.id) updateConstants.mutate( { constants: [{ key: 'allItemsOrder', value: productIds, }], }, { onSuccess: () => { setHasChanges(false) window.alert('All items order updated successfully!') queryClient.invalidateQueries({ queryKey: ['const.getConstants'] }) }, onError: (error) => { window.alert('Failed to update items order. Please try again.') console.error('Update all items order error:', error) }, } ) } if (isLoadingConstants || isLoadingProducts) { return (
All Items Order
{isLoadingConstants ? 'Loading order...' : 'Loading products...'}
) } if (constantsError || productsError) { return (
All Items Order
Error {constantsError ? 'Failed to load order' : 'Failed to load products'}
) } return (
All Items Order
{products.length === 0 ? (
No products available
) : (
Long press and drag to reorder • {products.length} items
p.id)} strategy={verticalListSortingStrategy}> {products.map((product) => ( {}} isActive={false} /> ))}
)}
) }