enh
This commit is contained in:
parent
c14e32522a
commit
f7c55ea492
11 changed files with 4366 additions and 124 deletions
|
|
@ -1,4 +1,7 @@
|
||||||
import { scaffoldProducts } from '@/src/trpc/apis/common-apis/common'
|
import { scaffoldProducts } from '@/src/trpc/apis/common-apis/common'
|
||||||
|
import { scaffoldEssentialConsts } from '@/src/trpc/apis/common-apis/common-trpc-index'
|
||||||
|
import { scaffoldStores } from '@/src/trpc/apis/user-apis/apis/stores'
|
||||||
|
import { scaffoldSlotsWithProducts } from '@/src/trpc/apis/user-apis/apis/slots'
|
||||||
import { imageUploadS3 } from '@/src/lib/s3-client'
|
import { imageUploadS3 } from '@/src/lib/s3-client'
|
||||||
import { apiCacheKey } from '@/src/lib/env-exporter'
|
import { apiCacheKey } from '@/src/lib/env-exporter'
|
||||||
|
|
||||||
|
|
@ -17,3 +20,51 @@ export async function createProductsFile(): Promise<string> {
|
||||||
|
|
||||||
return s3Key
|
return s3Key
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function createEssentialConstsFile(): Promise<string> {
|
||||||
|
// Get essential consts data from the API method
|
||||||
|
const essentialConstsData = await scaffoldEssentialConsts()
|
||||||
|
|
||||||
|
// Convert to JSON string with pretty formatting
|
||||||
|
const jsonContent = JSON.stringify(essentialConstsData, null, 2)
|
||||||
|
|
||||||
|
// Convert to Buffer for S3 upload
|
||||||
|
const buffer = Buffer.from(jsonContent, 'utf-8')
|
||||||
|
|
||||||
|
// Upload to S3 at the specified path using apiCacheKey
|
||||||
|
const s3Key = await imageUploadS3(buffer, 'application/json', `${apiCacheKey}/essential-consts.json`)
|
||||||
|
|
||||||
|
return s3Key
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function createStoresFile(): Promise<string> {
|
||||||
|
// Get stores data from the API method
|
||||||
|
const storesData = await scaffoldStores()
|
||||||
|
|
||||||
|
// Convert to JSON string with pretty formatting
|
||||||
|
const jsonContent = JSON.stringify(storesData, null, 2)
|
||||||
|
|
||||||
|
// Convert to Buffer for S3 upload
|
||||||
|
const buffer = Buffer.from(jsonContent, 'utf-8')
|
||||||
|
|
||||||
|
// Upload to S3 at the specified path using apiCacheKey
|
||||||
|
const s3Key = await imageUploadS3(buffer, 'application/json', `${apiCacheKey}/stores.json`)
|
||||||
|
|
||||||
|
return s3Key
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function createSlotsFile(): Promise<string> {
|
||||||
|
// Get slots data from the API method
|
||||||
|
const slotsData = await scaffoldSlotsWithProducts()
|
||||||
|
|
||||||
|
// Convert to JSON string with pretty formatting
|
||||||
|
const jsonContent = JSON.stringify(slotsData, null, 2)
|
||||||
|
|
||||||
|
// Convert to Buffer for S3 upload
|
||||||
|
const buffer = Buffer.from(jsonContent, 'utf-8')
|
||||||
|
|
||||||
|
// Upload to S3 at the specified path using apiCacheKey
|
||||||
|
const s3Key = await imageUploadS3(buffer, 'application/json', `${apiCacheKey}/slots.json`)
|
||||||
|
|
||||||
|
return s3Key
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ import { initializeAllStores } from '@/src/stores/store-initializer'
|
||||||
import { initializeUserNegativityStore } from '@/src/stores/user-negativity-store'
|
import { initializeUserNegativityStore } from '@/src/stores/user-negativity-store'
|
||||||
import { startOrderHandler, startCancellationHandler, publishOrder } from '@/src/lib/post-order-handler'
|
import { startOrderHandler, startCancellationHandler, publishOrder } from '@/src/lib/post-order-handler'
|
||||||
import { deleteOrders } from '@/src/lib/delete-orders'
|
import { deleteOrders } from '@/src/lib/delete-orders'
|
||||||
import { createProductsFile } from '@/src/lib/cloud_cache'
|
import { createProductsFile, createEssentialConstsFile, createStoresFile, createSlotsFile } from '@/src/lib/cloud_cache'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize all application services
|
* Initialize all application services
|
||||||
|
|
@ -26,9 +26,14 @@ export const initFunc = async (): Promise<void> => {
|
||||||
startCancellationHandler(),
|
startCancellationHandler(),
|
||||||
]);
|
]);
|
||||||
|
|
||||||
// Create products cache file after stores are initialized
|
// Create cache files in parallel after stores are initialized
|
||||||
await createProductsFile();
|
await Promise.all([
|
||||||
console.log('Products cache file created successfully');
|
createProductsFile(),
|
||||||
|
createEssentialConstsFile(),
|
||||||
|
createStoresFile(),
|
||||||
|
createSlotsFile(),
|
||||||
|
]);
|
||||||
|
console.log('Cache files created successfully');
|
||||||
|
|
||||||
console.log('Application initialization completed successfully');
|
console.log('Application initialization completed successfully');
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,28 @@ import { assetsDomain, apiCacheKey } from '@/src/lib/env-exporter'
|
||||||
|
|
||||||
const polygon = turf.polygon(mbnrGeoJson.features[0].geometry.coordinates);
|
const polygon = turf.polygon(mbnrGeoJson.features[0].geometry.coordinates);
|
||||||
|
|
||||||
|
export async function scaffoldEssentialConsts() {
|
||||||
|
const consts = await getAllConstValues();
|
||||||
|
|
||||||
|
return {
|
||||||
|
freeDeliveryThreshold: consts[CONST_KEYS.freeDeliveryThreshold] ?? 200,
|
||||||
|
deliveryCharge: consts[CONST_KEYS.deliveryCharge] ?? 0,
|
||||||
|
flashFreeDeliveryThreshold: consts[CONST_KEYS.flashFreeDeliveryThreshold] ?? 500,
|
||||||
|
flashDeliveryCharge: consts[CONST_KEYS.flashDeliveryCharge] ?? 69,
|
||||||
|
popularItems: consts[CONST_KEYS.popularItems] ?? '5,3,2,4,1',
|
||||||
|
versionNum: consts[CONST_KEYS.versionNum] ?? '1.1.0',
|
||||||
|
playStoreUrl: consts[CONST_KEYS.playStoreUrl] ?? 'https://play.google.com/store/apps/details?id=in.freshyo.app',
|
||||||
|
appStoreUrl: consts[CONST_KEYS.appStoreUrl] ?? 'https://apps.apple.com/in/app/freshyo/id6756889077',
|
||||||
|
webViewHtml: null,
|
||||||
|
isWebviewClosable: true,
|
||||||
|
isFlashDeliveryEnabled: consts[CONST_KEYS.isFlashDeliveryEnabled] ?? true,
|
||||||
|
supportMobile: consts[CONST_KEYS.supportMobile] ?? '',
|
||||||
|
supportEmail: consts[CONST_KEYS.supportEmail] ?? '',
|
||||||
|
assetsDomain,
|
||||||
|
apiCacheKey,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export const commonApiRouter = router({
|
export const commonApiRouter = router({
|
||||||
product: commonRouter,
|
product: commonRouter,
|
||||||
getStoresSummary: publicProcedure
|
getStoresSummary: publicProcedure
|
||||||
|
|
@ -100,25 +122,8 @@ export const commonApiRouter = router({
|
||||||
}),
|
}),
|
||||||
essentialConsts: publicProcedure
|
essentialConsts: publicProcedure
|
||||||
.query(async () => {
|
.query(async () => {
|
||||||
const consts = await getAllConstValues();
|
const response = await scaffoldEssentialConsts();
|
||||||
|
return response;
|
||||||
return {
|
|
||||||
freeDeliveryThreshold: consts[CONST_KEYS.freeDeliveryThreshold] ?? 200,
|
|
||||||
deliveryCharge: consts[CONST_KEYS.deliveryCharge] ?? 0,
|
|
||||||
flashFreeDeliveryThreshold: consts[CONST_KEYS.flashFreeDeliveryThreshold] ?? 500,
|
|
||||||
flashDeliveryCharge: consts[CONST_KEYS.flashDeliveryCharge] ?? 69,
|
|
||||||
popularItems: consts[CONST_KEYS.popularItems] ?? '5,3,2,4,1',
|
|
||||||
versionNum: consts[CONST_KEYS.versionNum] ?? '1.1.0',
|
|
||||||
playStoreUrl: consts[CONST_KEYS.playStoreUrl] ?? 'https://play.google.com/store/apps/details?id=in.freshyo.app',
|
|
||||||
appStoreUrl: consts[CONST_KEYS.appStoreUrl] ?? 'https://apps.apple.com/in/app/freshyo/id6756889077',
|
|
||||||
webViewHtml: null,
|
|
||||||
isWebviewClosable: true,
|
|
||||||
isFlashDeliveryEnabled: consts[CONST_KEYS.isFlashDeliveryEnabled] ?? true,
|
|
||||||
supportMobile: consts[CONST_KEYS.supportMobile] ?? '',
|
|
||||||
supportEmail: consts[CONST_KEYS.supportEmail] ?? '',
|
|
||||||
assetsDomain,
|
|
||||||
apiCacheKey,
|
|
||||||
};
|
|
||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -84,7 +84,8 @@ export const commonRouter = router({
|
||||||
|
|
||||||
getAllProductsSummary: publicProcedure
|
getAllProductsSummary: publicProcedure
|
||||||
.query(async () => {
|
.query(async () => {
|
||||||
return scaffoldProducts();
|
const response = await scaffoldProducts();
|
||||||
|
return response;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getStoresSummary: publicProcedure
|
getStoresSummary: publicProcedure
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,23 @@ async function getSlotData(slotId: number) {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function scaffoldSlotsWithProducts() {
|
||||||
|
const allSlots = await getAllSlotsFromCache();
|
||||||
|
const currentTime = new Date();
|
||||||
|
const validSlots = allSlots
|
||||||
|
.filter((slot) => {
|
||||||
|
return dayjs(slot.freezeTime).isAfter(currentTime) &&
|
||||||
|
dayjs(slot.deliveryTime).isAfter(currentTime) &&
|
||||||
|
!slot.isCapacityFull;
|
||||||
|
})
|
||||||
|
.sort((a, b) => dayjs(a.deliveryTime).valueOf() - dayjs(b.deliveryTime).valueOf());
|
||||||
|
|
||||||
|
return {
|
||||||
|
slots: validSlots,
|
||||||
|
count: validSlots.length,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export const slotsRouter = router({
|
export const slotsRouter = router({
|
||||||
getSlots: publicProcedure.query(async () => {
|
getSlots: publicProcedure.query(async () => {
|
||||||
const slots = await db.query.deliverySlotInfo.findMany({
|
const slots = await db.query.deliverySlotInfo.findMany({
|
||||||
|
|
@ -44,20 +61,8 @@ export const slotsRouter = router({
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getSlotsWithProducts: publicProcedure.query(async () => {
|
getSlotsWithProducts: publicProcedure.query(async () => {
|
||||||
const allSlots = await getAllSlotsFromCache();
|
const response = await scaffoldSlotsWithProducts();
|
||||||
const currentTime = new Date();
|
return response;
|
||||||
const validSlots = allSlots
|
|
||||||
.filter((slot) => {
|
|
||||||
return dayjs(slot.freezeTime).isAfter(currentTime) &&
|
|
||||||
dayjs(slot.deliveryTime).isAfter(currentTime) &&
|
|
||||||
!slot.isCapacityFull;
|
|
||||||
})
|
|
||||||
.sort((a, b) => dayjs(a.deliveryTime).valueOf() - dayjs(b.deliveryTime).valueOf());
|
|
||||||
|
|
||||||
return {
|
|
||||||
slots: validSlots,
|
|
||||||
count: validSlots.length,
|
|
||||||
};
|
|
||||||
}),
|
}),
|
||||||
|
|
||||||
nextMajorDelivery: publicProcedure.query(async () => {
|
nextMajorDelivery: publicProcedure.query(async () => {
|
||||||
|
|
|
||||||
|
|
@ -6,66 +6,71 @@ import { eq, and, sql } from 'drizzle-orm';
|
||||||
import { scaffoldAssetUrl } from '@/src/lib/s3-client';
|
import { scaffoldAssetUrl } from '@/src/lib/s3-client';
|
||||||
import { ApiError } from '@/src/lib/api-error';
|
import { ApiError } from '@/src/lib/api-error';
|
||||||
|
|
||||||
export const storesRouter = router({
|
export async function scaffoldStores() {
|
||||||
getStores: publicProcedure
|
const storesData = await db
|
||||||
.query(async () => {
|
.select({
|
||||||
const storesData = await db
|
id: storeInfo.id,
|
||||||
|
name: storeInfo.name,
|
||||||
|
description: storeInfo.description,
|
||||||
|
imageUrl: storeInfo.imageUrl,
|
||||||
|
productCount: sql<number>`count(${productInfo.id})`.as('productCount'),
|
||||||
|
})
|
||||||
|
.from(storeInfo)
|
||||||
|
.leftJoin(
|
||||||
|
productInfo,
|
||||||
|
and(eq(productInfo.storeId, storeInfo.id), eq(productInfo.isSuspended, false))
|
||||||
|
)
|
||||||
|
.groupBy(storeInfo.id);
|
||||||
|
|
||||||
|
// Generate signed URLs for store images and fetch sample products
|
||||||
|
const storesWithDetails = await Promise.all(
|
||||||
|
storesData.map(async (store) => {
|
||||||
|
const signedImageUrl = store.imageUrl ? scaffoldAssetUrl(store.imageUrl) : null;
|
||||||
|
|
||||||
|
// Fetch up to 3 products for this store
|
||||||
|
const sampleProducts = await db
|
||||||
.select({
|
.select({
|
||||||
id: storeInfo.id,
|
id: productInfo.id,
|
||||||
name: storeInfo.name,
|
name: productInfo.name,
|
||||||
description: storeInfo.description,
|
images: productInfo.images,
|
||||||
imageUrl: storeInfo.imageUrl,
|
|
||||||
productCount: sql<number>`count(${productInfo.id})`.as('productCount'),
|
|
||||||
})
|
})
|
||||||
.from(storeInfo)
|
.from(productInfo)
|
||||||
.leftJoin(
|
.where(and(eq(productInfo.storeId, store.id), eq(productInfo.isSuspended, false)))
|
||||||
productInfo,
|
.limit(3);
|
||||||
and(eq(productInfo.storeId, storeInfo.id), eq(productInfo.isSuspended, false))
|
|
||||||
)
|
|
||||||
.groupBy(storeInfo.id);
|
|
||||||
|
|
||||||
// Generate signed URLs for store images and fetch sample products
|
|
||||||
const storesWithDetails = await Promise.all(
|
|
||||||
storesData.map(async (store) => {
|
|
||||||
const signedImageUrl = store.imageUrl ? scaffoldAssetUrl(store.imageUrl) : null;
|
|
||||||
|
|
||||||
// Fetch up to 3 products for this store
|
|
||||||
const sampleProducts = await db
|
|
||||||
.select({
|
|
||||||
id: productInfo.id,
|
|
||||||
name: productInfo.name,
|
|
||||||
images: productInfo.images,
|
|
||||||
})
|
|
||||||
.from(productInfo)
|
|
||||||
.where(and(eq(productInfo.storeId, store.id), eq(productInfo.isSuspended, false)))
|
|
||||||
.limit(3);
|
|
||||||
|
|
||||||
// Generate signed URLs for product images
|
|
||||||
const productsWithSignedUrls = await Promise.all(
|
|
||||||
sampleProducts.map(async (product) => {
|
|
||||||
const images = product.images as string[];
|
|
||||||
return {
|
|
||||||
id: product.id,
|
|
||||||
name: product.name,
|
|
||||||
signedImageUrl: (images && images.length > 0) ? scaffoldAssetUrl(images[0]) : null,
|
|
||||||
};
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
|
// Generate signed URLs for product images
|
||||||
|
const productsWithSignedUrls = await Promise.all(
|
||||||
|
sampleProducts.map(async (product) => {
|
||||||
|
const images = product.images as string[];
|
||||||
return {
|
return {
|
||||||
id: store.id,
|
id: product.id,
|
||||||
name: store.name,
|
name: product.name,
|
||||||
description: store.description,
|
signedImageUrl: (images && images.length > 0) ? scaffoldAssetUrl(images[0]) : null,
|
||||||
signedImageUrl,
|
|
||||||
productCount: store.productCount,
|
|
||||||
sampleProducts: productsWithSignedUrls,
|
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
stores: storesWithDetails,
|
id: store.id,
|
||||||
|
name: store.name,
|
||||||
|
description: store.description,
|
||||||
|
signedImageUrl,
|
||||||
|
productCount: store.productCount,
|
||||||
|
sampleProducts: productsWithSignedUrls,
|
||||||
};
|
};
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
return {
|
||||||
|
stores: storesWithDetails,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export const storesRouter = router({
|
||||||
|
getStores: publicProcedure
|
||||||
|
.query(async () => {
|
||||||
|
const response = await scaffoldStores();
|
||||||
|
return response;
|
||||||
}),
|
}),
|
||||||
|
|
||||||
getStoreWithProducts: publicProcedure
|
getStoreWithProducts: publicProcedure
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,9 @@ import { adminRouter } from '@/src/trpc/apis/admin-apis/apis/admin-trpc-index'
|
||||||
import { userRouter } from '@/src/trpc/apis/user-apis/apis/user-trpc-index'
|
import { userRouter } from '@/src/trpc/apis/user-apis/apis/user-trpc-index'
|
||||||
import { commonApiRouter } from '@/src/trpc/apis/common-apis/common-trpc-index'
|
import { commonApiRouter } from '@/src/trpc/apis/common-apis/common-trpc-index'
|
||||||
import { scaffoldProducts } from './apis/common-apis/common';
|
import { scaffoldProducts } from './apis/common-apis/common';
|
||||||
|
import { scaffoldStores } from './apis/user-apis/apis/stores';
|
||||||
|
import { scaffoldSlotsWithProducts } from './apis/user-apis/apis/slots';
|
||||||
|
import { scaffoldEssentialConsts } from './apis/common-apis/common-trpc-index';
|
||||||
|
|
||||||
// Create the main app router
|
// Create the main app router
|
||||||
export const appRouter = router({
|
export const appRouter = router({
|
||||||
|
|
@ -22,3 +25,6 @@ export const appRouter = router({
|
||||||
export type AppRouter = typeof appRouter;
|
export type AppRouter = typeof appRouter;
|
||||||
|
|
||||||
export type AllProductsApiType = Awaited<ReturnType<typeof scaffoldProducts>>;
|
export type AllProductsApiType = Awaited<ReturnType<typeof scaffoldProducts>>;
|
||||||
|
export type StoresApiType = Awaited<ReturnType<typeof scaffoldStores>>;
|
||||||
|
export type SlotsApiType = Awaited<ReturnType<typeof scaffoldSlotsWithProducts>>;
|
||||||
|
export type EssentialConstsApiType = Awaited<ReturnType<typeof scaffoldEssentialConsts>>;
|
||||||
|
|
|
||||||
|
|
@ -21,14 +21,13 @@ import AddToCartDialog from "@/src/components/AddToCartDialog";
|
||||||
import MyFlatList from "common-ui/src/components/flat-list";
|
import MyFlatList from "common-ui/src/components/flat-list";
|
||||||
|
|
||||||
import { trpc } from "@/src/trpc-client";
|
import { trpc } from "@/src/trpc-client";
|
||||||
import { useAllProducts } from "@/src/hooks/prominent-api-hooks";
|
import { useAllProducts, useStores, useSlots, useGetEssentialConsts } from "@/src/hooks/prominent-api-hooks";
|
||||||
import { useProductSlotIdentifier } from "@/hooks/useProductSlotIdentifier";
|
import { useProductSlotIdentifier } from "@/hooks/useProductSlotIdentifier";
|
||||||
import FloatingCartBar from "@/components/floating-cart-bar";
|
import FloatingCartBar from "@/components/floating-cart-bar";
|
||||||
import BannerCarousel from "@/components/BannerCarousel";
|
import BannerCarousel from "@/components/BannerCarousel";
|
||||||
import { useUserDetails } from "@/src/contexts/AuthContext";
|
import { useUserDetails } from "@/src/contexts/AuthContext";
|
||||||
import TabLayoutWrapper from "@/components/TabLayoutWrapper";
|
import TabLayoutWrapper from "@/components/TabLayoutWrapper";
|
||||||
import { useNavigationStore } from "@/src/store/navigationStore";
|
import { useNavigationStore } from "@/src/store/navigationStore";
|
||||||
import { useGetEssentialConsts } from "@/src/hooks/prominent-api-hooks";
|
|
||||||
import NextOrderGlimpse from "@/components/NextOrderGlimpse";
|
import NextOrderGlimpse from "@/components/NextOrderGlimpse";
|
||||||
dayjs.extend(relativeTime);
|
dayjs.extend(relativeTime);
|
||||||
|
|
||||||
|
|
@ -379,8 +378,8 @@ export default function Dashboard() {
|
||||||
|
|
||||||
const { data: essentialConsts, isLoading: isLoadingConsts, error: constsError, refetch: refetchConsts } = useGetEssentialConsts();
|
const { data: essentialConsts, isLoading: isLoadingConsts, error: constsError, refetch: refetchConsts } = useGetEssentialConsts();
|
||||||
|
|
||||||
const { data: storesData, refetch: refetchStores } = trpc.user.stores.getStores.useQuery();
|
const { data: storesData, refetch: refetchStores } = useStores();
|
||||||
const { data: slotsData, refetch: refetchSlots } = trpc.user.slots.getSlotsWithProducts.useQuery();
|
const { data: slotsData, refetch: refetchSlots } = useSlots();
|
||||||
|
|
||||||
const products = productsData?.products || [];
|
const products = productsData?.products || [];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,7 @@ import {
|
||||||
} from "common-ui";
|
} from "common-ui";
|
||||||
import MaterialIcons from "@expo/vector-icons/MaterialIcons";
|
import MaterialIcons from "@expo/vector-icons/MaterialIcons";
|
||||||
import { Ionicons } from "@expo/vector-icons";
|
import { Ionicons } from "@expo/vector-icons";
|
||||||
import { trpc } from "@/src/trpc-client";
|
import { useStores } from "@/src/hooks/prominent-api-hooks";
|
||||||
import { LinearGradient } from "expo-linear-gradient";
|
import { LinearGradient } from "expo-linear-gradient";
|
||||||
import TabLayoutWrapper from "@/components/TabLayoutWrapper";
|
import TabLayoutWrapper from "@/components/TabLayoutWrapper";
|
||||||
import FloatingCartBar from "@/components/floating-cart-bar";
|
import FloatingCartBar from "@/components/floating-cart-bar";
|
||||||
|
|
@ -157,7 +157,7 @@ export default function Stores() {
|
||||||
isLoading,
|
isLoading,
|
||||||
error,
|
error,
|
||||||
refetch,
|
refetch,
|
||||||
} = trpc.user.stores.getStores.useQuery();
|
} = useStores();
|
||||||
|
|
||||||
const stores = storesData?.stores || [];
|
const stores = storesData?.stores || [];
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,8 @@
|
||||||
import { useQuery } from '@tanstack/react-query'
|
import { useQuery } from '@tanstack/react-query'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import { trpc } from '@/src/trpc-client'
|
import { trpc } from '@/src/trpc-client'
|
||||||
import { AllProductsApiType } from "@backend/trpc/router";
|
import { AllProductsApiType, StoresApiType, SlotsApiType, EssentialConstsApiType } from "@backend/trpc/router";
|
||||||
|
|
||||||
// Local useGetEssentialConsts hook
|
// Local useGetEssentialConsts hook
|
||||||
export const useGetEssentialConsts = () => {
|
export const useGetEssentialConsts = () => {
|
||||||
const query = trpc.common.essentialConsts.useQuery(undefined, {
|
const query = trpc.common.essentialConsts.useQuery(undefined, {
|
||||||
|
|
@ -10,40 +11,24 @@ export const useGetEssentialConsts = () => {
|
||||||
return { ...query, refetch: query.refetch }
|
return { ...query, refetch: query.refetch }
|
||||||
}
|
}
|
||||||
|
|
||||||
// // Type definitions matching the backend response
|
|
||||||
// interface ProductSummary {
|
|
||||||
// id: number
|
|
||||||
// name: string
|
|
||||||
// shortDescription: string | null
|
|
||||||
// price: number
|
|
||||||
// marketPrice: number | null
|
|
||||||
// unit: string
|
|
||||||
// unitNotation: string
|
|
||||||
// incrementStep: number
|
|
||||||
// productQuantity: number
|
|
||||||
// storeId: number | null
|
|
||||||
// isOutOfStock: boolean
|
|
||||||
// isFlashAvailable: boolean
|
|
||||||
// nextDeliveryDate: string | null
|
|
||||||
// images: string[]
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// interface ProductsResponse {
|
|
||||||
// products: ProductSummary[]
|
|
||||||
// count: number
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
type ProductsResponse = AllProductsApiType;
|
type ProductsResponse = AllProductsApiType;
|
||||||
|
type StoresResponse = StoresApiType;
|
||||||
|
type SlotsResponse = SlotsApiType;
|
||||||
|
type EssentialConstsResponse = EssentialConstsApiType;
|
||||||
|
|
||||||
export function useAllProducts() {
|
function useCacheUrl(filename: string): string | null {
|
||||||
const { data: essentialConsts } = useGetEssentialConsts()
|
const { data: essentialConsts } = useGetEssentialConsts()
|
||||||
|
|
||||||
const assetsDomain = essentialConsts?.assetsDomain
|
const assetsDomain = essentialConsts?.assetsDomain
|
||||||
const apiCacheKey = essentialConsts?.apiCacheKey
|
const apiCacheKey = essentialConsts?.apiCacheKey
|
||||||
|
|
||||||
const cacheUrl = assetsDomain && apiCacheKey
|
return assetsDomain && apiCacheKey
|
||||||
? `${assetsDomain}${apiCacheKey}/products.json`
|
? `${assetsDomain}${apiCacheKey}/${filename}`
|
||||||
: null
|
: null
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useAllProducts() {
|
||||||
|
const cacheUrl = useCacheUrl('products.json')
|
||||||
|
|
||||||
return useQuery<ProductsResponse>({
|
return useQuery<ProductsResponse>({
|
||||||
queryKey: ['all-products', cacheUrl],
|
queryKey: ['all-products', cacheUrl],
|
||||||
|
|
@ -58,3 +43,37 @@ export function useAllProducts() {
|
||||||
enabled: !!cacheUrl,
|
enabled: !!cacheUrl,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function useStores() {
|
||||||
|
const cacheUrl = useCacheUrl('stores.json')
|
||||||
|
|
||||||
|
return useQuery<StoresResponse>({
|
||||||
|
queryKey: ['stores', cacheUrl],
|
||||||
|
queryFn: async () => {
|
||||||
|
if (!cacheUrl) {
|
||||||
|
throw new Error('Cache URL not available')
|
||||||
|
}
|
||||||
|
const response = await axios.get<StoresResponse>(cacheUrl)
|
||||||
|
return response.data
|
||||||
|
},
|
||||||
|
staleTime: 60000, // 1 minute
|
||||||
|
enabled: !!cacheUrl,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
export function useSlots() {
|
||||||
|
const cacheUrl = useCacheUrl('slots.json')
|
||||||
|
|
||||||
|
return useQuery<SlotsResponse>({
|
||||||
|
queryKey: ['slots', cacheUrl],
|
||||||
|
queryFn: async () => {
|
||||||
|
if (!cacheUrl) {
|
||||||
|
throw new Error('Cache URL not available')
|
||||||
|
}
|
||||||
|
const response = await axios.get<SlotsResponse>(cacheUrl)
|
||||||
|
return response.data
|
||||||
|
},
|
||||||
|
staleTime: 60000, // 1 minute
|
||||||
|
enabled: !!cacheUrl,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
|
||||||
4146
session-ses_32c7.md
Normal file
4146
session-ses_32c7.md
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Add table
Reference in a new issue