enh
This commit is contained in:
parent
1f801f2146
commit
ccde89b5c8
2 changed files with 198 additions and 86 deletions
|
|
@ -96,6 +96,10 @@ export default function Dashboard() {
|
|||
const [gradientHeight, setGradientHeight] = useState(0);
|
||||
const [stickyBarLayout, setStickyBarLayout] = useState({ y: 0, height: 0 });
|
||||
const [whiteSectionLayout, setWhiteSectionLayout] = useState({ y: 0 });
|
||||
const [displayedProducts, setDisplayedProducts] = useState<any[]>([]);
|
||||
const [page, setPage] = useState(1);
|
||||
const [hasMore, setHasMore] = useState(true);
|
||||
const [isLoadingMore, setIsLoadingMore] = useState(false);
|
||||
const { backgroundColor } = useStatusBarStore();
|
||||
|
||||
const {
|
||||
|
|
@ -121,6 +125,47 @@ export default function Dashboard() {
|
|||
const defaultAddress = defaultAddressResponse?.data;
|
||||
const { getQuickestSlot } = useProductSlotIdentifier();
|
||||
|
||||
// Function to load more products
|
||||
const loadMoreProducts = () => {
|
||||
if (!hasMore || isLoadingMore) return;
|
||||
|
||||
setIsLoadingMore(true);
|
||||
|
||||
// Simulate loading more products by taking the next batch
|
||||
// In a real app, you would make an API call with pagination params
|
||||
setTimeout(() => {
|
||||
const batchSize = 10;
|
||||
const startIndex = page * batchSize;
|
||||
const endIndex = startIndex + batchSize;
|
||||
|
||||
// Get the next batch of products
|
||||
const nextBatch = products.slice(startIndex, endIndex);
|
||||
|
||||
if (nextBatch.length > 0) {
|
||||
setDisplayedProducts(prev => [...prev, ...nextBatch]);
|
||||
setPage(prev => prev + 1);
|
||||
setHasMore(endIndex < products.length);
|
||||
} else {
|
||||
setHasMore(false);
|
||||
}
|
||||
|
||||
setIsLoadingMore(false);
|
||||
}, 500); // Simulate network delay
|
||||
};
|
||||
|
||||
// Initialize with the first batch of products
|
||||
React.useEffect(() => {
|
||||
if (products.length > 0) {
|
||||
const initialBatch = products.slice(0, 10); // First 10 products
|
||||
setDisplayedProducts(initialBatch);
|
||||
setHasMore(products.length > 10);
|
||||
setPage(1);
|
||||
} else {
|
||||
setDisplayedProducts([]);
|
||||
setHasMore(false);
|
||||
}
|
||||
}, [products]);
|
||||
|
||||
// Extract popular items IDs as an array to preserve order
|
||||
const popularItemIds = (() => {
|
||||
const popularItems = essentialConsts?.popularItems;
|
||||
|
|
@ -202,7 +247,20 @@ export default function Dashboard() {
|
|||
<ScrollView
|
||||
style={[tw`flex-1 bg-white`, { position: 'relative' }]}
|
||||
stickyHeaderIndices={[2]}
|
||||
onScroll={handleScroll}
|
||||
onScroll={(e) => {
|
||||
handleScroll(e);
|
||||
|
||||
// Check if we're near the end of the scroll for vertical loading
|
||||
const { layoutMeasurement, contentOffset, contentSize } = e.nativeEvent;
|
||||
const paddingToBottom = 40;
|
||||
|
||||
if (layoutMeasurement.height + contentOffset.y >= contentSize.height - paddingToBottom) {
|
||||
// Load more products when reaching near the end
|
||||
if (!isLoadingMore && hasMore) {
|
||||
loadMoreProducts();
|
||||
}
|
||||
}
|
||||
}}
|
||||
scrollEventThrottle={16}
|
||||
>
|
||||
<LinearGradient
|
||||
|
|
@ -363,7 +421,7 @@ export default function Dashboard() {
|
|||
<MyText
|
||||
style={tw`text-2xl font-extrabold text-gray-900 tracking-tight`}
|
||||
>
|
||||
Delivery Slots
|
||||
Upcoming Delivery Slots
|
||||
</MyText>
|
||||
<MyText style={tw`text-sm text-gray-500 font-medium mt-1`}>
|
||||
Plan your fresh deliveries ahead
|
||||
|
|
@ -516,6 +574,49 @@ export default function Dashboard() {
|
|||
</ScrollView>
|
||||
</View>
|
||||
)}
|
||||
|
||||
{/* All Products Section - Vertical Infinite Scroll */}
|
||||
<View style={tw`mt-2 mb-4`}>
|
||||
<View style={tw`flex-row items-center justify-between px-1 mb-6`}>
|
||||
<View>
|
||||
<MyText
|
||||
style={tw`text-2xl font-extrabold text-gray-900 tracking-tight`}
|
||||
>
|
||||
All Available Products
|
||||
</MyText>
|
||||
<MyText style={tw`text-sm text-gray-500 font-medium mt-1`}>
|
||||
Browse our complete selection
|
||||
</MyText>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{/* Product Grid */}
|
||||
<View style={tw`flex-row flex-wrap`}>
|
||||
{displayedProducts.map((item, index: number) => (
|
||||
|
||||
<ProductCard
|
||||
item={item}
|
||||
itemWidth={(screenWidth * 0.9) / 2} // Half of screen width minus padding
|
||||
onPress={() =>
|
||||
router.push(
|
||||
`/(drawer)/(tabs)/home/product-detail/${item.id}`
|
||||
)
|
||||
}
|
||||
showDeliveryInfo={true}
|
||||
miniView={false}
|
||||
nullIfNotAvailable={true}
|
||||
containerComp={({children}) => <View key={item.id} style={tw`w-1/2 pr-2 pb-4`}>{children}</View>}
|
||||
/>
|
||||
))}
|
||||
</View>
|
||||
|
||||
{isLoadingMore && (
|
||||
<View style={tw`items-center py-4`}>
|
||||
<MyText>Loading more...</MyText>
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
|
||||
</View>
|
||||
|
||||
<LoadingDialog open={isLoadingDialogOpen} message="Adding to cart..." />
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ interface ProductCardProps {
|
|||
onPress?: () => void;
|
||||
showDeliveryInfo?: boolean;
|
||||
miniView?: boolean;
|
||||
nullIfNotAvailable?: boolean;
|
||||
containerComp?: React.ComponentType<any> | React.JSXElementConstructor<any>;
|
||||
}
|
||||
|
||||
const formatQuantity = (quantity: number, unit: string): { value: string; display: string } => {
|
||||
|
|
@ -36,6 +38,8 @@ const ProductCard: React.FC<ProductCardProps> = ({
|
|||
onPress,
|
||||
showDeliveryInfo = true,
|
||||
miniView = false,
|
||||
nullIfNotAvailable = false,
|
||||
containerComp: ContainerComp = React.Fragment,
|
||||
}) => {
|
||||
const { data: cartData } = useGetCart();
|
||||
const { getQuickestSlot } = useProductSlotIdentifier();
|
||||
|
|
@ -63,6 +67,11 @@ const ProductCard: React.FC<ProductCardProps> = ({
|
|||
const slotId = getQuickestSlot(item.id);
|
||||
const displayIsOutOfStock = item.isOutOfStock || !slotId;
|
||||
|
||||
// Return null if nullIfNotAvailable is true and the product is out of stock
|
||||
if (nullIfNotAvailable && displayIsOutOfStock) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const handleQuantityChange = (newQuantity: number) => {
|
||||
if (newQuantity === 0 && cartItem) {
|
||||
removeFromCart.mutate({ itemId: cartItem.id });
|
||||
|
|
@ -79,9 +88,10 @@ const ProductCard: React.FC<ProductCardProps> = ({
|
|||
};
|
||||
|
||||
return (
|
||||
<ContainerComp>
|
||||
<MyTouchableOpacity
|
||||
style={[
|
||||
tw`bg-white rounded-2xl overflow-hidden border border-gray-200`,
|
||||
tw`bg-white rounded-2xl overflow-hidden border border-gray-200 pb-2`,
|
||||
{ width: itemWidth },
|
||||
]}
|
||||
onPress={onPress || (() => {/* TODO: Navigate to product detail */})}
|
||||
|
|
@ -168,6 +178,7 @@ const ProductCard: React.FC<ProductCardProps> = ({
|
|||
)}
|
||||
</View>
|
||||
</MyTouchableOpacity>
|
||||
</ContainerComp>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue