Compare commits
No commits in common. "0290c170bb41cc66e8e9ea09eae441c3322b9ae7" and "4199ff7d9b320d0db4e92085d323fb767a97ebd0" have entirely different histories.
0290c170bb
...
4199ff7d9b
303 changed files with 52698 additions and 119086 deletions
Binary file not shown.
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -30,7 +30,6 @@
|
||||||
"@trpc/server": "^11.6.0",
|
"@trpc/server": "^11.6.0",
|
||||||
"@turf/turf": "^7.2.0",
|
"@turf/turf": "^7.2.0",
|
||||||
"@types/bcryptjs": "^2.4.6",
|
"@types/bcryptjs": "^2.4.6",
|
||||||
"aws4fetch": "^1.0.20",
|
|
||||||
"axios": "^1.11.0",
|
"axios": "^1.11.0",
|
||||||
"bcryptjs": "^3.0.2",
|
"bcryptjs": "^3.0.2",
|
||||||
"dayjs": "^1.11.18",
|
"dayjs": "^1.11.18",
|
||||||
|
|
|
||||||
|
|
@ -14,9 +14,9 @@ export const createApp = () => {
|
||||||
|
|
||||||
// CORS middleware
|
// CORS middleware
|
||||||
app.use(cors({
|
app.use(cors({
|
||||||
origin: ['http://localhost:5174', 'http://localhost:4174', 'https://ui.freshyo.in', 'https://www.freshyo.in', 'https://webui.freshyo.in', 'https://app.freshyo.in'],
|
origin: ['http://localhost:5174', 'https://ui.freshyo.in'],
|
||||||
allowMethods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
|
allowMethods: ['GET', 'POST', 'PUT', 'PATCH', 'DELETE', 'OPTIONS'],
|
||||||
allowHeaders: ['Origin', 'X-Requested-With', 'Content-Type', 'Accept', 'Authorization', 'Caller-Interface'],
|
allowHeaders: ['Origin', 'X-Requested-With', 'Content-Type', 'Accept', 'Authorization'],
|
||||||
credentials: true,
|
credentials: true,
|
||||||
}))
|
}))
|
||||||
|
|
||||||
|
|
@ -26,31 +26,13 @@ export const createApp = () => {
|
||||||
// tRPC middleware
|
// tRPC middleware
|
||||||
app.use('/api/trpc/*', trpcServer({
|
app.use('/api/trpc/*', trpcServer({
|
||||||
router: appRouter,
|
router: appRouter,
|
||||||
createContext: async ({ req, c }) => {
|
createContext: async ({ req }) => {
|
||||||
let user = null
|
let user = null
|
||||||
let staffUser = null
|
let staffUser = null
|
||||||
const authHeader = req.headers.get('authorization')
|
const authHeader = req.headers.get('authorization')
|
||||||
const callerInterface = req.headers.get('caller-interface')
|
|
||||||
|
|
||||||
let token: string | null = null
|
|
||||||
|
|
||||||
if (authHeader?.startsWith('Bearer ')) {
|
if (authHeader?.startsWith('Bearer ')) {
|
||||||
token = authHeader.substring(7)
|
const token = authHeader.substring(7)
|
||||||
} else {
|
|
||||||
// Fallback: try reading token from cookie
|
|
||||||
const cookieHeader = req.headers.get('cookie')
|
|
||||||
if (cookieHeader) {
|
|
||||||
const cookies = Object.fromEntries(
|
|
||||||
cookieHeader.split(';').map((pair) => {
|
|
||||||
const [k, ...v] = pair.trim().split('=')
|
|
||||||
return [k, v.join('=')]
|
|
||||||
})
|
|
||||||
)
|
|
||||||
token = cookies['auth_token'] || null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (token) {
|
|
||||||
try {
|
try {
|
||||||
const { payload } = await jwtVerify(token, getEncodedJwtSecret())
|
const { payload } = await jwtVerify(token, getEncodedJwtSecret())
|
||||||
const decoded = payload as any
|
const decoded = payload as any
|
||||||
|
|
@ -85,7 +67,7 @@ export const createApp = () => {
|
||||||
// Invalid token, both user and staffUser remain null
|
// Invalid token, both user and staffUser remain null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return { req, c, user, staffUser, callerInterface }
|
return { req, user, staffUser }
|
||||||
},
|
},
|
||||||
onError({ error, path, type, ctx }) {
|
onError({ error, path, type, ctx }) {
|
||||||
console.error('🚨 tRPC Error :', {
|
console.error('🚨 tRPC Error :', {
|
||||||
|
|
|
||||||
|
|
@ -1,30 +0,0 @@
|
||||||
import { toggleKeyVal } from '@/src/dbService'
|
|
||||||
import { CONST_KEYS } from '@/src/lib/const-keys'
|
|
||||||
import { computeConstants } from '@/src/lib/const-store'
|
|
||||||
import { ensureWorkerInit } from '@/src/lib/worker-init'
|
|
||||||
|
|
||||||
|
|
||||||
const CRON_TURN_OFF_FLASH_DELIVERY = '0 16 * * *' // 9:30 PM IST
|
|
||||||
const CRON_TURN_ON_FLASH_DELIVERY = '0 1 * * *' // 6:30 PM IST
|
|
||||||
|
|
||||||
export async function runFlashDeliveryToggleCron(params: {
|
|
||||||
cron: string
|
|
||||||
env: any
|
|
||||||
}) {
|
|
||||||
console.log('from the cron job top level')
|
|
||||||
const { cron, env } = params
|
|
||||||
|
|
||||||
// Ensure DB bindings are initialized for this worker invocation
|
|
||||||
ensureWorkerInit(env)
|
|
||||||
|
|
||||||
if (cron !== CRON_TURN_OFF_FLASH_DELIVERY && cron !== CRON_TURN_ON_FLASH_DELIVERY) {
|
|
||||||
console.log('flash delivery cron: ignoring unknown cron', cron)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
const enabled = cron === CRON_TURN_ON_FLASH_DELIVERY
|
|
||||||
console.log('flash delivery cron: toggling isFlashDeliveryEnabled', { cron, enabled })
|
|
||||||
|
|
||||||
await toggleKeyVal(CONST_KEYS.isFlashDeliveryEnabled, enabled)
|
|
||||||
await computeConstants()
|
|
||||||
}
|
|
||||||
|
|
@ -81,8 +81,9 @@ export async function sendAdminNotification(data: {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const [ticket] = await expo.sendPushNotificationsAsync([message]);
|
const [ticket] = await expo.sendPushNotificationsAsync([message]);
|
||||||
|
console.log(`Notification sent:`, ticket);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log(`Failed to send notification:`, error);
|
console.error(`Failed to send notification:`, error);
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,27 +1,26 @@
|
||||||
import { sendAdminNotification } from '@/src/lib/notif-job'
|
import { sendAdminNotification } from '@/src/lib/notif-job'
|
||||||
import { handleOrderCancelled, handleOrderPlaced } from '@/src/lib/post-order-handler'
|
import { handleOrderCancelled, handleOrderPlaced } from '@/src/lib/post-order-handler'
|
||||||
|
|
||||||
export const handleNotifQueue =async (batch: any) => {
|
export const handleNotifQueue = (batch: any) => {
|
||||||
|
batch.messages.forEach((message: any) => {
|
||||||
for (const message of batch.messages || []) {
|
|
||||||
const body = message?.body
|
const body = message?.body
|
||||||
if (!body) {
|
if (!body) {
|
||||||
console.log('notif_queue message received with empty body')
|
console.log('notif_queue message received with empty body')
|
||||||
continue
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if (body.name === 'send-admin-notification' && body.jobData?.token) {
|
if (body.name === 'send-admin-notification' && body.jobData?.token) {
|
||||||
await sendAdminNotification({
|
void sendAdminNotification({
|
||||||
token: body.jobData.token,
|
token: body.jobData.token,
|
||||||
title: body.jobData.title,
|
title: body.jobData.title,
|
||||||
body: body.jobData.body,
|
body: body.jobData.body,
|
||||||
imageUrl: body.jobData.imageUrl ?? null,
|
imageUrl: body.jobData.imageUrl ?? null,
|
||||||
})
|
})
|
||||||
continue
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// console.log('notif_queue', body)
|
console.log('notif_queue message received', body)
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export const handleOrderPlacedQueue = async (batch: any) => {
|
export const handleOrderPlacedQueue = async (batch: any) => {
|
||||||
|
|
|
||||||
|
|
@ -105,7 +105,6 @@ export {
|
||||||
updateSlotCapacity,
|
updateSlotCapacity,
|
||||||
getSlotDeliverySequence,
|
getSlotDeliverySequence,
|
||||||
updateSlotDeliverySequence,
|
updateSlotDeliverySequence,
|
||||||
staleSlotsCleanup,
|
|
||||||
// Admin - Staff User
|
// Admin - Staff User
|
||||||
getStaffUserByName,
|
getStaffUserByName,
|
||||||
getStaffUserById,
|
getStaffUserById,
|
||||||
|
|
|
||||||
|
|
@ -42,19 +42,19 @@ async function transformSlotToStoreSlot(slot: SlotWithProductsData): Promise<Slo
|
||||||
freezeTime: slot.freezeTime,
|
freezeTime: slot.freezeTime,
|
||||||
isActive: slot.isActive,
|
isActive: slot.isActive,
|
||||||
isCapacityFull: slot.isCapacityFull,
|
isCapacityFull: slot.isCapacityFull,
|
||||||
products: slot.products.map((product) => ({
|
products: slot.productSlots.map((productSlot) => ({
|
||||||
id: product.id,
|
id: productSlot.product.id,
|
||||||
name: product.name,
|
name: productSlot.product.name,
|
||||||
productQuantity: product.productQuantity,
|
productQuantity: productSlot.product.productQuantity,
|
||||||
shortDescription: product.shortDescription,
|
shortDescription: productSlot.product.shortDescription,
|
||||||
price: product.price.toString(),
|
price: productSlot.product.price.toString(),
|
||||||
marketPrice: product.marketPrice?.toString() || null,
|
marketPrice: productSlot.product.marketPrice?.toString() || null,
|
||||||
unit: product.unit?.shortNotation || null,
|
unit: productSlot.product.unit?.shortNotation || null,
|
||||||
images: scaffoldAssetUrl(
|
images: scaffoldAssetUrl(
|
||||||
(product.images as string[]) || []
|
(productSlot.product.images as string[]) || []
|
||||||
),
|
),
|
||||||
isOutOfStock: product.isOutOfStock,
|
isOutOfStock: productSlot.product.isOutOfStock,
|
||||||
storeId: product.storeId,
|
storeId: productSlot.product.storeId,
|
||||||
nextDeliveryDate: slot.deliveryTime,
|
nextDeliveryDate: slot.deliveryTime,
|
||||||
})),
|
})),
|
||||||
}
|
}
|
||||||
|
|
@ -118,19 +118,19 @@ export async function initializeSlotStore(): Promise<void> {
|
||||||
isActive: slot.isActive,
|
isActive: slot.isActive,
|
||||||
isCapacityFull: slot.isCapacityFull,
|
isCapacityFull: slot.isCapacityFull,
|
||||||
products: await Promise.all(
|
products: await Promise.all(
|
||||||
slot.products.map(async (product) => ({
|
slot.productSlots.map(async (productSlot) => ({
|
||||||
id: product.id,
|
id: productSlot.product.id,
|
||||||
name: product.name,
|
name: productSlot.product.name,
|
||||||
productQuantity: product.productQuantity,
|
productQuantity: productSlot.product.productQuantity,
|
||||||
shortDescription: product.shortDescription,
|
shortDescription: productSlot.product.shortDescription,
|
||||||
price: product.price.toString(),
|
price: productSlot.product.price.toString(),
|
||||||
marketPrice: product.marketPrice?.toString() || null,
|
marketPrice: productSlot.product.marketPrice?.toString() || null,
|
||||||
unit: product.unit?.shortNotation || null,
|
unit: productSlot.product.unit?.shortNotation || null,
|
||||||
images: scaffoldAssetUrl(
|
images: scaffoldAssetUrl(
|
||||||
(product.images as string[]) || []
|
(productSlot.product.images as string[]) || []
|
||||||
),
|
),
|
||||||
isOutOfStock: product.isOutOfStock,
|
isOutOfStock: productSlot.product.isOutOfStock,
|
||||||
storeId: product.storeId,
|
storeId: productSlot.product.storeId,
|
||||||
nextDeliveryDate: slot.deliveryTime,
|
nextDeliveryDate: slot.deliveryTime,
|
||||||
}))
|
}))
|
||||||
),
|
),
|
||||||
|
|
@ -229,7 +229,7 @@ export async function getProductSlots(productId: number): Promise<SlotInfo[]> {
|
||||||
const productSlots: SlotInfo[] = []
|
const productSlots: SlotInfo[] = []
|
||||||
|
|
||||||
for (const slot of slots) {
|
for (const slot of slots) {
|
||||||
const hasProduct = slot.products.some(p => p.id === productId)
|
const hasProduct = slot.productSlots.some(ps => ps.product.id === productId)
|
||||||
if (hasProduct) {
|
if (hasProduct) {
|
||||||
productSlots.push(extractSlotInfo(slot))
|
productSlots.push(extractSlotInfo(slot))
|
||||||
}
|
}
|
||||||
|
|
@ -272,8 +272,8 @@ export async function getAllProductsSlots(): Promise<Record<number, SlotInfo[]>>
|
||||||
|
|
||||||
for (const slot of slots) {
|
for (const slot of slots) {
|
||||||
const slotInfo = extractSlotInfo(slot)
|
const slotInfo = extractSlotInfo(slot)
|
||||||
for (const product of slot.products) {
|
for (const productSlot of slot.productSlots) {
|
||||||
const productId = product.id
|
const productId = productSlot.product.id
|
||||||
if (!result[productId]) {
|
if (!result[productId]) {
|
||||||
result[productId] = []
|
result[productId] = []
|
||||||
}
|
}
|
||||||
|
|
@ -322,8 +322,8 @@ export async function getMultipleProductsSlots(
|
||||||
|
|
||||||
for (const slot of slots) {
|
for (const slot of slots) {
|
||||||
const slotInfo = extractSlotInfo(slot)
|
const slotInfo = extractSlotInfo(slot)
|
||||||
for (const product of slot.products) {
|
for (const productSlot of slot.productSlots) {
|
||||||
const pid = product.id
|
const pid = productSlot.product.id
|
||||||
if (productIdSet.has(pid) && !slot.isCapacityFull) {
|
if (productIdSet.has(pid) && !slot.isCapacityFull) {
|
||||||
result[pid].push(slotInfo)
|
result[pid].push(slotInfo)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,7 +19,6 @@ import {
|
||||||
updateSlotDeliverySequence as updateSlotDeliverySequenceInDb,
|
updateSlotDeliverySequence as updateSlotDeliverySequenceInDb,
|
||||||
updateSlotProducts as updateSlotProductsInDb,
|
updateSlotProducts as updateSlotProductsInDb,
|
||||||
getSlotsProductIds as getSlotsProductIdsInDb,
|
getSlotsProductIds as getSlotsProductIdsInDb,
|
||||||
staleSlotsCleanup,
|
|
||||||
} from '@/src/dbService'
|
} from '@/src/dbService'
|
||||||
import type {
|
import type {
|
||||||
AdminDeliverySequenceResult,
|
AdminDeliverySequenceResult,
|
||||||
|
|
@ -94,7 +93,7 @@ export const slotsRouter = router({
|
||||||
throw new TRPCError({ code: "UNAUTHORIZED", message: "Access denied" });
|
throw new TRPCError({ code: "UNAUTHORIZED", message: "Access denied" });
|
||||||
}
|
}
|
||||||
|
|
||||||
const slots = await getActiveSlotsWithProductsInDb(20)
|
const slots = await getActiveSlotsWithProductsInDb()
|
||||||
|
|
||||||
/*
|
/*
|
||||||
// Old implementation - direct DB queries:
|
// Old implementation - direct DB queries:
|
||||||
|
|
@ -363,11 +362,6 @@ export const slotsRouter = router({
|
||||||
// Reinitialize stores to reflect changes (outside transaction)
|
// Reinitialize stores to reflect changes (outside transaction)
|
||||||
await scheduleStoreInitialization()
|
await scheduleStoreInitialization()
|
||||||
|
|
||||||
// Fire and forget: cleanup stale product slot associations
|
|
||||||
staleSlotsCleanup().catch((error) => {
|
|
||||||
console.error('Failed to cleanup stale slots:', error)
|
|
||||||
})
|
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}),
|
}),
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -233,8 +233,6 @@ export const userRouter = {
|
||||||
tokens = userTokens.map(t => t.token);
|
tokens = userTokens.map(t => t.token);
|
||||||
}
|
}
|
||||||
|
|
||||||
// tokens = ['ExponentPushToken[w4KTsLKnnp8SbURdl5-Q6x]', 'ExponentPushToken[81Io9TG3Qg0s3N0V8L86T-]', 'ExponentPushToken[YJRSQmMUEUbaI2VCZLaoN_]', 'ExponentPushToken[LQZgYkFG_3CweaUbv0fBKJ]']
|
|
||||||
|
|
||||||
// Queue one job per token
|
// Queue one job per token
|
||||||
let queuedCount = 0;
|
let queuedCount = 0;
|
||||||
for (const token of tokens) {
|
for (const token of tokens) {
|
||||||
|
|
@ -255,14 +253,6 @@ export const userRouter = {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
// await queueDataPusher.pushNotifQueue({
|
|
||||||
// jobData: {
|
|
||||||
// token,
|
|
||||||
// title,
|
|
||||||
// body: text,
|
|
||||||
// imageUrl: imageUrl || null,
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
queuedCount++;
|
queuedCount++;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(`Failed to queue notification for token:`, error);
|
console.error(`Failed to queue notification for token:`, error);
|
||||||
|
|
|
||||||
|
|
@ -44,18 +44,11 @@ interface RegisterRequest {
|
||||||
const generateToken = async (userId: number): Promise<string> => {
|
const generateToken = async (userId: number): Promise<string> => {
|
||||||
return await new SignJWT({ userId })
|
return await new SignJWT({ userId })
|
||||||
.setProtectedHeader({ alg: 'HS256' })
|
.setProtectedHeader({ alg: 'HS256' })
|
||||||
.setExpirationTime('90d')
|
.setExpirationTime('7d')
|
||||||
.sign(getEncodedJwtSecret());
|
.sign(getEncodedJwtSecret());
|
||||||
};
|
};
|
||||||
|
|
||||||
const setAuthCookie = (ctx: any, token: string) => {
|
|
||||||
if (ctx.callerInterface === 'web' && ctx.c) {
|
|
||||||
ctx.c.header(
|
|
||||||
'Set-Cookie',
|
|
||||||
`auth_token=${token}; HttpOnly; Secure; SameSite=Lax; Path=/; Max-Age=604800`
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export const authRouter = router({
|
export const authRouter = router({
|
||||||
login: publicProcedure
|
login: publicProcedure
|
||||||
|
|
@ -63,7 +56,7 @@ export const authRouter = router({
|
||||||
identifier: z.string().min(1, 'Email/mobile is required'),
|
identifier: z.string().min(1, 'Email/mobile is required'),
|
||||||
password: z.string().min(1, 'Password is required'),
|
password: z.string().min(1, 'Password is required'),
|
||||||
}))
|
}))
|
||||||
.mutation(async ({ input, ctx }): Promise<UserAuthResult> => {
|
.mutation(async ({ input }): Promise<UserAuthResult> => {
|
||||||
const { identifier, password }: LoginRequest = input;
|
const { identifier, password }: LoginRequest = input;
|
||||||
|
|
||||||
if (!identifier || !password) {
|
if (!identifier || !password) {
|
||||||
|
|
@ -106,7 +99,6 @@ export const authRouter = router({
|
||||||
}
|
}
|
||||||
|
|
||||||
const token = await generateToken(foundUser.id);
|
const token = await generateToken(foundUser.id);
|
||||||
setAuthCookie(ctx, token);
|
|
||||||
|
|
||||||
const response: UserAuthResponse = {
|
const response: UserAuthResponse = {
|
||||||
token,
|
token,
|
||||||
|
|
@ -140,7 +132,7 @@ export const authRouter = router({
|
||||||
password: z.string().min(1, 'Password is required'),
|
password: z.string().min(1, 'Password is required'),
|
||||||
profileImageUrl: z.string().nullable().optional(),
|
profileImageUrl: z.string().nullable().optional(),
|
||||||
}))
|
}))
|
||||||
.mutation(async ({ input, ctx }): Promise<UserAuthResult> => {
|
.mutation(async ({ input }): Promise<UserAuthResult> => {
|
||||||
const { name, email, mobile, password, profileImageUrl }: RegisterRequest = input;
|
const { name, email, mobile, password, profileImageUrl }: RegisterRequest = input;
|
||||||
|
|
||||||
if (!name || !email || !mobile || !password) {
|
if (!name || !email || !mobile || !password) {
|
||||||
|
|
@ -186,7 +178,6 @@ export const authRouter = router({
|
||||||
})
|
})
|
||||||
|
|
||||||
const token = await generateToken(newUser.id);
|
const token = await generateToken(newUser.id);
|
||||||
setAuthCookie(ctx, token);
|
|
||||||
|
|
||||||
const profileImageSignedUrl = profileImageUrl
|
const profileImageSignedUrl = profileImageUrl
|
||||||
? await generateSignedUrlFromS3Url(profileImageUrl)
|
? await generateSignedUrlFromS3Url(profileImageUrl)
|
||||||
|
|
@ -224,7 +215,7 @@ export const authRouter = router({
|
||||||
mobile: z.string(),
|
mobile: z.string(),
|
||||||
otp: z.string(),
|
otp: z.string(),
|
||||||
}))
|
}))
|
||||||
.mutation(async ({ input, ctx }): Promise<UserOtpVerifyResponse> => {
|
.mutation(async ({ input }): Promise<UserOtpVerifyResponse> => {
|
||||||
const verificationId = getOtpCreds(input.mobile);
|
const verificationId = getOtpCreds(input.mobile);
|
||||||
if (!verificationId) {
|
if (!verificationId) {
|
||||||
throw new ApiError("OTP not sent or expired", 400);
|
throw new ApiError("OTP not sent or expired", 400);
|
||||||
|
|
@ -245,7 +236,6 @@ export const authRouter = router({
|
||||||
|
|
||||||
// Generate JWT
|
// Generate JWT
|
||||||
const token = await generateToken(user.id);
|
const token = await generateToken(user.id);
|
||||||
setAuthCookie(ctx, token);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
success: true,
|
success: true,
|
||||||
|
|
|
||||||
|
|
@ -57,6 +57,31 @@ export const productRouter = router({
|
||||||
// If not in cache, fetch from database (fallback)
|
// If not in cache, fetch from database (fallback)
|
||||||
const productData = await getUserProductDetailByIdInDb(productId)
|
const productData = await getUserProductDetailByIdInDb(productId)
|
||||||
|
|
||||||
|
/*
|
||||||
|
// Old implementation - direct DB queries:
|
||||||
|
const productData = await db
|
||||||
|
.select({
|
||||||
|
id: productInfo.id,
|
||||||
|
name: productInfo.name,
|
||||||
|
shortDescription: productInfo.shortDescription,
|
||||||
|
longDescription: productInfo.longDescription,
|
||||||
|
price: productInfo.price,
|
||||||
|
marketPrice: productInfo.marketPrice,
|
||||||
|
images: productInfo.images,
|
||||||
|
isOutOfStock: productInfo.isOutOfStock,
|
||||||
|
storeId: productInfo.storeId,
|
||||||
|
unitShortNotation: units.shortNotation,
|
||||||
|
incrementStep: productInfo.incrementStep,
|
||||||
|
productQuantity: productInfo.productQuantity,
|
||||||
|
isFlashAvailable: productInfo.isFlashAvailable,
|
||||||
|
flashPrice: productInfo.flashPrice,
|
||||||
|
})
|
||||||
|
.from(productInfo)
|
||||||
|
.innerJoin(units, eq(productInfo.unitId, units.id))
|
||||||
|
.where(eq(productInfo.id, productId))
|
||||||
|
.limit(1);
|
||||||
|
*/
|
||||||
|
|
||||||
if (!productData) {
|
if (!productData) {
|
||||||
throw new Error('Product not found')
|
throw new Error('Product not found')
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,13 +3,11 @@ import type { Context as HonoContext } from 'hono';
|
||||||
|
|
||||||
export interface Context {
|
export interface Context {
|
||||||
req: HonoContext['req'];
|
req: HonoContext['req'];
|
||||||
c: HonoContext;
|
|
||||||
user?: any;
|
user?: any;
|
||||||
staffUser?: {
|
staffUser?: {
|
||||||
id: number;
|
id: number;
|
||||||
name: string;
|
name: string;
|
||||||
} | null;
|
} | null;
|
||||||
callerInterface?: string | null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const t = initTRPC.context<Context>().create();
|
const t = initTRPC.context<Context>().create();
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import type {
|
||||||
import { CacheCreator } from './src/jobs/cache-creator'
|
import { CacheCreator } from './src/jobs/cache-creator'
|
||||||
import { createApp } from './src/app'
|
import { createApp } from './src/app'
|
||||||
import { ensureWorkerInit } from './src/lib/worker-init'
|
import { ensureWorkerInit } from './src/lib/worker-init'
|
||||||
import { runFlashDeliveryToggleCron } from './src/lib/flash-delivery-cron'
|
|
||||||
import {
|
import {
|
||||||
handleNotifQueue,
|
handleNotifQueue,
|
||||||
handleOrderPlacedQueue,
|
handleOrderPlacedQueue,
|
||||||
|
|
@ -59,7 +58,7 @@ export default {
|
||||||
ensureWorkerInit(env)
|
ensureWorkerInit(env)
|
||||||
console.log('from the queue handler')
|
console.log('from the queue handler')
|
||||||
if (batch?.queue === env.NOTIF_QUEUE_NAME) {
|
if (batch?.queue === env.NOTIF_QUEUE_NAME) {
|
||||||
await handleNotifQueue(batch)
|
handleNotifQueue(batch)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -75,15 +74,4 @@ export default {
|
||||||
|
|
||||||
handleNotifQueue(batch)
|
handleNotifQueue(batch)
|
||||||
},
|
},
|
||||||
async scheduled(
|
|
||||||
event: any,
|
|
||||||
env: Record<string, string> & {
|
|
||||||
DB?: D1Database
|
|
||||||
},
|
|
||||||
ctx: ExecutionContext
|
|
||||||
) {
|
|
||||||
console.log('from the cron trigger first func');
|
|
||||||
await runFlashDeliveryToggleCron({cron: event.cron, env});
|
|
||||||
// ctx.waitUntil(runFlashDeliveryToggleCron({ cron: event.cron, env }))
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ bindings = [
|
||||||
[[migrations]]
|
[[migrations]]
|
||||||
tag = "cache-creator-v1"
|
tag = "cache-creator-v1"
|
||||||
new_classes = ["CacheCreator"]
|
new_classes = ["CacheCreator"]
|
||||||
migrations_dir = "../../packages/db_helper_sqlite/drizzle/"
|
|
||||||
|
|
||||||
[[queues.producers]]
|
[[queues.producers]]
|
||||||
binding = "NOTIF_QUEUE"
|
binding = "NOTIF_QUEUE"
|
||||||
|
|
@ -92,12 +91,5 @@ DELIVERY_CHARGE = "20"
|
||||||
TELEGRAM_BOT_TOKEN = "8410461852:AAGXQCwRPFbndqwTgLJh8kYxST4Z0vgh72U"
|
TELEGRAM_BOT_TOKEN = "8410461852:AAGXQCwRPFbndqwTgLJh8kYxST4Z0vgh72U"
|
||||||
TELEGRAM_CHAT_IDS = "5147760058"
|
TELEGRAM_CHAT_IDS = "5147760058"
|
||||||
|
|
||||||
[triggers]
|
|
||||||
#crons = ["* * * * *"]
|
|
||||||
crons = [
|
|
||||||
"30 18 * * *", # 12:00 AM IST
|
|
||||||
"35 18 * * *" # 12:05 AM IST
|
|
||||||
]
|
|
||||||
|
|
||||||
[build]
|
[build]
|
||||||
upload_source_maps = true
|
upload_source_maps = true
|
||||||
|
|
|
||||||
|
|
@ -92,10 +92,5 @@ TELEGRAM_BOT_TOKEN = "8410461852:AAGXQCwRPFbndqwTgLJh8kYxST4Z0vgh72U"
|
||||||
# TELEGRAM_CHAT_IDS = "5147760058"
|
# TELEGRAM_CHAT_IDS = "5147760058"
|
||||||
TELEGRAM_CHAT_IDS = "-5075171894"
|
TELEGRAM_CHAT_IDS = "-5075171894"
|
||||||
|
|
||||||
[triggers]
|
|
||||||
crons = ["0 16 * * *", "0 1 * * *"]
|
|
||||||
# crons = ["* * * * *"]
|
|
||||||
# crons = ["7 18 * * *", "10 18 * * *"]
|
|
||||||
|
|
||||||
[build]
|
[build]
|
||||||
upload_source_maps = true
|
upload_source_maps = true
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,7 @@ app.use(express.static(path.join(__dirname, 'public')));
|
||||||
// Home route
|
// Home route
|
||||||
app.get('/', (_, res) => {
|
app.get('/', (_, res) => {
|
||||||
res.render('index', {
|
res.render('index', {
|
||||||
title: 'Freshyo - Delivering Freshness',
|
title: 'Freshyo - Freshness Redefined',
|
||||||
year: new Date().getFullYear()
|
year: new Date().getFullYear()
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"express": "^4.18.2",
|
"express": "^4.18.2",
|
||||||
"mime": "^1.6.0",
|
|
||||||
"pug": "^3.0.2"
|
"pug": "^3.0.2"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
File diff suppressed because it is too large
Load diff
Binary file not shown.
|
Before Width: | Height: | Size: 80 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 80 KiB |
BIN
apps/info-site/public/logo.png
Normal file
BIN
apps/info-site/public/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 45 KiB |
|
|
@ -4,23 +4,27 @@ html(lang="en")
|
||||||
meta(charset="utf-8")
|
meta(charset="utf-8")
|
||||||
meta(name="viewport" content="width=device-width, initial-scale=1")
|
meta(name="viewport" content="width=device-width, initial-scale=1")
|
||||||
title= title
|
title= title
|
||||||
link(rel="icon" type="image/png" href="/favicon.png")
|
|
||||||
link(rel="stylesheet" href="/css/styles.css")
|
link(rel="stylesheet" href="/css/styles.css")
|
||||||
|
|
||||||
body
|
body
|
||||||
.app-container
|
.app-container
|
||||||
|
// Navigation
|
||||||
nav.nav
|
nav.nav
|
||||||
a.nav-logo(href="/")
|
a.nav-logo(href="/")
|
||||||
img(src="/freshyo-logo.png" alt="Freshyo" width="36" height="36")
|
svg(width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2")
|
||||||
|
path(d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2z")
|
||||||
|
path(d="M12 6v6l4 2")
|
||||||
span Freshyo
|
span Freshyo
|
||||||
ul.nav-links
|
ul.nav-links
|
||||||
li: a(href="/privacy-policy") Back to Policy
|
li: a(href="/privacy-policy") Back to Policy
|
||||||
|
|
||||||
|
// Main Content
|
||||||
.app-content
|
.app-content
|
||||||
.delete-card
|
.delete-card
|
||||||
a.back-link(href="/privacy-policy") ← Back to Privacy Policy
|
a.back-link(href="/privacy-policy")
|
||||||
|
span ← Back to Privacy Policy
|
||||||
|
|
||||||
span.warning-icon ⚠️
|
span.warning-icon !
|
||||||
h1 Delete Account
|
h1 Delete Account
|
||||||
p To delete your account and personal data, please verify your mobile number. This action cannot be undone.
|
p To delete your account and personal data, please verify your mobile number. This action cannot be undone.
|
||||||
|
|
||||||
|
|
@ -29,16 +33,19 @@ html(lang="en")
|
||||||
label.form-label(for="mobile") Mobile Number
|
label.form-label(for="mobile") Mobile Number
|
||||||
input#mobile.form-input(type="tel" name="mobile" placeholder="+91 99999 99999" required minlength="10")
|
input#mobile.form-input(type="tel" name="mobile" placeholder="+91 99999 99999" required minlength="10")
|
||||||
|
|
||||||
button.btn.btn-danger(type="submit") Delete My Account
|
button.btn.btn-danger(type="submit")
|
||||||
|
span Delete My Account
|
||||||
|
|
||||||
|
// Footer
|
||||||
footer.footer
|
footer.footer
|
||||||
.footer-content
|
.footer-content
|
||||||
.footer-brand
|
.footer-brand
|
||||||
img(src="/freshyo-logo.png" alt="Freshyo" width="32" height="32")
|
svg(width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2")
|
||||||
|
path(d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2z")
|
||||||
span Freshyo
|
span Freshyo
|
||||||
.footer-links
|
.footer-links
|
||||||
a(href="#") For Farmers
|
a(href="#") For Farmers
|
||||||
a(href="#") For Consumers
|
a(href="#") For Consumers
|
||||||
a(href="/privacy-policy") Privacy Policy
|
a(href="/privacy-policy") Privacy Policy
|
||||||
a(href="/delete-account") Delete Account
|
a(href="/delete-account") Delete Account
|
||||||
p.footer-copyright © #{year} Freshyo Inc. All rights reserved.
|
p.footer-copyright © #{year} Freshyo Inc.
|
||||||
|
|
|
||||||
|
|
@ -4,9 +4,6 @@ html(lang="en")
|
||||||
meta(charset="utf-8")
|
meta(charset="utf-8")
|
||||||
meta(name="viewport" content="width=device-width, initial-scale=1")
|
meta(name="viewport" content="width=device-width, initial-scale=1")
|
||||||
title= title
|
title= title
|
||||||
link(rel="icon" type="image/png" href="/favicon.png")
|
|
||||||
link(rel="preconnect" href="https://fonts.googleapis.com")
|
|
||||||
link(rel="preconnect" href="https://fonts.gstatic.com" crossorigin)
|
|
||||||
link(rel="stylesheet" href="/css/styles.css")
|
link(rel="stylesheet" href="/css/styles.css")
|
||||||
|
|
||||||
body
|
body
|
||||||
|
|
@ -14,140 +11,83 @@ html(lang="en")
|
||||||
// Navigation
|
// Navigation
|
||||||
nav.nav
|
nav.nav
|
||||||
a.nav-logo(href="/")
|
a.nav-logo(href="/")
|
||||||
img(src="/freshyo-logo.png" alt="Freshyo" width="40" height="40")
|
svg(width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2")
|
||||||
|
path(d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2z")
|
||||||
|
path(d="M12 6v6l4 2")
|
||||||
span Freshyo
|
span Freshyo
|
||||||
ul.nav-links
|
ul.nav-links
|
||||||
li: a(href="#features") Features
|
li: a(href="#features") Features
|
||||||
li: a(href="#stats") Stats
|
|
||||||
li: a(href="/privacy-policy") Privacy
|
li: a(href="/privacy-policy") Privacy
|
||||||
|
|
||||||
// Main Content
|
// Main Content
|
||||||
.app-content
|
.app-content
|
||||||
// Hero Section
|
// Hero Section
|
||||||
section.hero
|
section.hero
|
||||||
.hero-content
|
span.hero-badge Fresh & Healthy
|
||||||
span.hero-badge Freshness Delivered, Smiles Picked Up
|
h1 Fresh Meat, Fruits & Veggies
|
||||||
h1 Fresh Meat, Fruits & Veggies
|
p Experience the true taste of nature. 100% organic, fresh products delivered to your doorstep.
|
||||||
p.hero-subtitle Experience the true taste of nature. 100% fresh products delivered straight to your doorstep with care and quality.
|
.hero-actions
|
||||||
.hero-actions
|
a.btn.btn-primary(href="/qr-based-download")
|
||||||
a.btn.btn-primary(href="/qr-based-download") Get the App
|
span Download App
|
||||||
a.btn.btn-secondary(href="#features") Learn More
|
span.icon-sm →
|
||||||
|
a.btn.btn-secondary(href="#features") Learn More
|
||||||
// Social Proof
|
|
||||||
.social-proof
|
|
||||||
.avatars
|
|
||||||
img.avatar(src="/freshyo-logo.png" alt="Farmer")
|
|
||||||
img.avatar(src="/freshyo-logo.png" alt="Customer")
|
|
||||||
img.avatar(src="/freshyo-logo.png" alt="Partner")
|
|
||||||
span.avatar-count +500
|
|
||||||
p.social-text Join 10,000+ happy families
|
|
||||||
|
|
||||||
// Features Section
|
// Features Section
|
||||||
section.section-header#features
|
section.section-header#features
|
||||||
h2 Why Choose Freshyo?
|
h2 Why Choose Freshyo?
|
||||||
p.section-subtitle Quality you can trust, freshness you can taste
|
p Building an ecosystem where freshness meets fairness
|
||||||
|
|
||||||
.feature-grid
|
.feature-grid
|
||||||
.feature-card
|
.feature-item(data-aos="fade-up")
|
||||||
.feature-icon-wrapper
|
.feature-icon
|
||||||
svg(width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2")
|
svg(width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2")
|
||||||
path(d="M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10z")
|
path(d="M12 22c5.523 0 10-4.477 10-10S17.523 2 12 2 2 6.477 2 12s4.477 10 10 10z")
|
||||||
path(d="M12 6v6l4 2")
|
path(d="M12 6v6l4 2")
|
||||||
.feature-content
|
.feature-content
|
||||||
h3 Farm Fresh & Healthy
|
h3 Farm Fresh & Healthy
|
||||||
p Nutrient-rich products straight from nature, packed with health and vitality
|
p Nutrient-rich products straight from nature, packed with health and vitality
|
||||||
|
|
||||||
.feature-card
|
.feature-item(data-aos="fade-up")
|
||||||
.feature-icon-wrapper
|
.feature-icon
|
||||||
svg(width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2")
|
svg(width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2")
|
||||||
rect(x="1" y="3" width="15" height="13")
|
rect(x="1" y="3" width="15" height="13")
|
||||||
polygon(points="16 8 20 8 23 11 23 16 16 16 16 8")
|
polygon(points="16 8 20 8 23 11 23 16 16 16 16 8")
|
||||||
circle(cx="5.5" cy="18.5" r="2.5")
|
circle cx="5.5" cy="18.5" r="2.5"
|
||||||
circle(cx="18.5" cy="18.5" r="2.5")
|
circle cx="18.5" cy="18.5" r="2.5"
|
||||||
.feature-content
|
.feature-content
|
||||||
h3 Trusted Delivery
|
h3 Trusted Delivery
|
||||||
p Farm to your doorstep with care. Freshness guaranteed, no preservatives
|
p Farm to your doorstep with care. Freshness guaranteed, no preservatives
|
||||||
|
|
||||||
.feature-card
|
.feature-item(data-aos="fade-up")
|
||||||
.feature-icon-wrapper
|
.feature-icon
|
||||||
svg(width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2")
|
svg(width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2")
|
||||||
path(d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z")
|
path(d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z")
|
||||||
.feature-content
|
.feature-content
|
||||||
h3 Quality Assured
|
h3 Quality Assured
|
||||||
p Every product vetted for quality. If it's not good enough for our family, it's not for yours
|
p Every product vetted for quality. If it's not good enough for our family, it's not for yours
|
||||||
|
|
||||||
// Stats Section
|
// Stats Section
|
||||||
.stats-section#stats
|
.stats-row
|
||||||
h2.stats-title Our Growing Family
|
.stat-item
|
||||||
.stats-grid
|
span.stat-value 500+
|
||||||
.stat-card
|
span.stat-label Farmers
|
||||||
.stat-value(data-target="500") 0
|
.stat-item
|
||||||
span.stat-suffix +
|
span.stat-value 10K+
|
||||||
span.stat-label Happy Farmers
|
span.stat-label Families
|
||||||
.stat-card
|
.stat-item
|
||||||
.stat-value(data-target="10000") 0
|
span.stat-value 100%
|
||||||
span.stat-suffix +
|
span.stat-label Organic
|
||||||
span.stat-label Families Served
|
|
||||||
.stat-card
|
|
||||||
.stat-value(data-target="100") 0
|
|
||||||
span.stat-suffix %
|
|
||||||
span.stat-label Organic Products
|
|
||||||
|
|
||||||
// CTA Section
|
|
||||||
section.cta-section
|
|
||||||
.cta-content
|
|
||||||
h2 Ready to Experience Freshness?
|
|
||||||
p Download the app and get fresh products delivered to your door
|
|
||||||
a.btn.btn-white(href="/qr-based-download") Download Now
|
|
||||||
|
|
||||||
// Footer
|
// Footer
|
||||||
footer.footer
|
footer.footer
|
||||||
.footer-content
|
.footer-content
|
||||||
.footer-brand
|
.footer-brand
|
||||||
img(src="/freshyo-logo.png" alt="Freshyo" width="32" height="32")
|
svg(width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2")
|
||||||
|
path(d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2z")
|
||||||
span Freshyo
|
span Freshyo
|
||||||
.footer-links
|
.footer-links
|
||||||
a(href="#") For Farmers
|
a(href="#") For Farmers
|
||||||
a(href="#") For Consumers
|
a(href="#") For Consumers
|
||||||
a(href="/privacy-policy") Privacy Policy
|
a(href="/privacy-policy") Privacy Policy
|
||||||
a(href="/delete-account") Delete Account
|
a(href="/delete-account") Delete Account
|
||||||
p.footer-copyright © #{year} Freshyo Inc. All rights reserved.
|
p.footer-copyright © #{year} Freshyo Inc.
|
||||||
|
|
||||||
script.
|
|
||||||
// Stats counter animation
|
|
||||||
const statsObserver = new IntersectionObserver((entries) => {
|
|
||||||
entries.forEach(entry => {
|
|
||||||
if (entry.isIntersecting) {
|
|
||||||
const valueEl = entry.target.querySelector('.stat-value');
|
|
||||||
const target = parseInt(valueEl.dataset.target);
|
|
||||||
animateValue(valueEl, 0, target, 2000);
|
|
||||||
statsObserver.unobserve(entry.target);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}, { threshold: 0.5 });
|
|
||||||
|
|
||||||
document.querySelectorAll('.stat-card').forEach(card => {
|
|
||||||
statsObserver.observe(card);
|
|
||||||
});
|
|
||||||
|
|
||||||
function animateValue(element, start, end, duration) {
|
|
||||||
const startTime = performance.now();
|
|
||||||
function update(currentTime) {
|
|
||||||
const elapsed = currentTime - startTime;
|
|
||||||
const progress = Math.min(elapsed / duration, 1);
|
|
||||||
const easeOutQuart = 1 - Math.pow(1 - progress, 4);
|
|
||||||
const current = Math.floor(start + (end - start) * easeOutQuart);
|
|
||||||
element.textContent = current.toLocaleString();
|
|
||||||
if (progress < 1) requestAnimationFrame(update);
|
|
||||||
}
|
|
||||||
requestAnimationFrame(update);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Smooth scroll
|
|
||||||
document.querySelectorAll('a[href^="#"]').forEach(anchor => {
|
|
||||||
anchor.addEventListener('click', function(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
const target = document.querySelector(this.getAttribute('href'));
|
|
||||||
if (target) target.scrollIntoView({ behavior: 'smooth' });
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
|
||||||
|
|
@ -4,27 +4,31 @@ html(lang="en")
|
||||||
meta(charset="utf-8")
|
meta(charset="utf-8")
|
||||||
meta(name="viewport" content="width=device-width, initial-scale=1")
|
meta(name="viewport" content="width=device-width, initial-scale=1")
|
||||||
title= title
|
title= title
|
||||||
link(rel="icon" type="image/png" href="/favicon.png")
|
|
||||||
link(rel="stylesheet" href="/css/styles.css")
|
link(rel="stylesheet" href="/css/styles.css")
|
||||||
|
|
||||||
body
|
body
|
||||||
.app-container
|
.app-container
|
||||||
|
// Navigation
|
||||||
nav.nav
|
nav.nav
|
||||||
a.nav-logo(href="/")
|
a.nav-logo(href="/")
|
||||||
img(src="/freshyo-logo.png" alt="Freshyo" width="36" height="36")
|
svg(width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2")
|
||||||
|
path(d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2z")
|
||||||
|
path(d="M12 6v6l4 2")
|
||||||
span Freshyo
|
span Freshyo
|
||||||
ul.nav-links
|
ul.nav-links
|
||||||
li: a(href="/") Home
|
li: a(href="/") Home
|
||||||
li: a(href="/privacy-policy") Privacy
|
li: a(href="/privacy-policy" class="active") Privacy
|
||||||
|
|
||||||
|
// Main Content
|
||||||
.app-content
|
.app-content
|
||||||
.policy-content
|
.policy-content
|
||||||
a.back-link(href="/") ← Back to Home
|
a.back-link(href="/")
|
||||||
|
span ← Back to Home
|
||||||
|
|
||||||
h1 Privacy Policy
|
h1 Privacy Policy
|
||||||
p.last-updated Last Updated: December 18, 2025
|
p.last-updated Last Updated: December 18, 2025
|
||||||
|
|
||||||
p.lead At Freshyo, we value your trust and are committed to protecting your personal information. This Privacy Policy explains how we collect, use, and safeguard your data.
|
p At Freshyo, we value your trust and are committed to protecting your personal information. This Privacy Policy explains how we collect, use, and safeguard your data when you use our website and services.
|
||||||
|
|
||||||
h2 1. Information We Collect
|
h2 1. Information We Collect
|
||||||
p We collect information that you provide directly to us, such as when you create an account, place an order, or contact customer support. This may include your name, email address, phone number, and delivery address.
|
p We collect information that you provide directly to us, such as when you create an account, place an order, or contact customer support. This may include your name, email address, phone number, and delivery address.
|
||||||
|
|
@ -47,14 +51,16 @@ html(lang="en")
|
||||||
p You have the right to request the deletion of your personal data. If you wish to delete your account:
|
p You have the right to request the deletion of your personal data. If you wish to delete your account:
|
||||||
a.btn.btn-danger(href="/delete-account" style="margin-top: 1rem; display: inline-flex;") Delete My Account
|
a.btn.btn-danger(href="/delete-account" style="margin-top: 1rem; display: inline-flex;") Delete My Account
|
||||||
|
|
||||||
|
// Footer
|
||||||
footer.footer
|
footer.footer
|
||||||
.footer-content
|
.footer-content
|
||||||
.footer-brand
|
.footer-brand
|
||||||
img(src="/freshyo-logo.png" alt="Freshyo" width="32" height="32")
|
svg(width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2")
|
||||||
|
path(d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2z")
|
||||||
span Freshyo
|
span Freshyo
|
||||||
.footer-links
|
.footer-links
|
||||||
a(href="#") For Farmers
|
a(href="#") For Farmers
|
||||||
a(href="#") For Consumers
|
a(href="#") For Consumers
|
||||||
a(href="/privacy-policy") Privacy Policy
|
a(href="/privacy-policy") Privacy Policy
|
||||||
a(href="/delete-account") Delete Account
|
a(href="/delete-account") Delete Account
|
||||||
p.footer-copyright © #{year} Freshyo Inc. All rights reserved.
|
p.footer-copyright © #{year} Freshyo Inc.
|
||||||
|
|
|
||||||
|
|
@ -4,18 +4,16 @@ html(lang="en")
|
||||||
meta(charset="utf-8")
|
meta(charset="utf-8")
|
||||||
meta(name="viewport" content="width=device-width, initial-scale=1")
|
meta(name="viewport" content="width=device-width, initial-scale=1")
|
||||||
title= title
|
title= title
|
||||||
link(rel="icon" type="image/png" href="/favicon.png")
|
link(rel="stylesheet", href="/css/styles.css")
|
||||||
link(rel="stylesheet" href="/css/styles.css")
|
|
||||||
|
|
||||||
body
|
body
|
||||||
.download-container
|
.download-container
|
||||||
.download-card
|
.download-card
|
||||||
a.back-link(href="/") ← Back to Home
|
a.back-link(href="/")
|
||||||
|
span ← Back to Home
|
||||||
|
|
||||||
img(src="/freshyo-logo.png" alt="Freshyo" width="80" height="80")
|
|
||||||
h1 Download Freshyo
|
h1 Download Freshyo
|
||||||
p.tagline Freshness Delivered, Smiles Picked Up
|
p Experience the true taste of nature on your device
|
||||||
p Choose your platform to get started
|
|
||||||
|
|
||||||
.download-options
|
.download-options
|
||||||
a.download-option.android(href="intent://play.google.com/store/apps/details?id=in.freshyo.app#Intent;scheme=https;package=com.android.vending;end;", onclick="handleAndroidClick(event)")
|
a.download-option.android(href="intent://play.google.com/store/apps/details?id=in.freshyo.app#Intent;scheme=https;package=com.android.vending;end;", onclick="handleAndroidClick(event)")
|
||||||
|
|
@ -34,22 +32,11 @@ html(lang="en")
|
||||||
h3 iOS
|
h3 iOS
|
||||||
p Apple App Store
|
p Apple App Store
|
||||||
|
|
||||||
a.download-option.browser(href="https://app.freshyo.in" onclick="handleBrowserClick(event)")
|
p.mt-lg(style="font-size: 0.75rem; color: var(--gray-500);") If you are not redirected automatically, tap above
|
||||||
.download-icon.browser
|
|
||||||
svg(width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2")
|
|
||||||
circle(cx="12" cy="12" r="10")
|
|
||||||
path(d="M2 12h20")
|
|
||||||
path(d="M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z")
|
|
||||||
.download-info
|
|
||||||
h3 Use in Browser
|
|
||||||
p No download required
|
|
||||||
|
|
||||||
p.mt-lg(style="font-size: 0.875rem; color: var(--gray-500);") Not redirected? Tap an option above
|
|
||||||
|
|
||||||
script.
|
script.
|
||||||
const ANDROID_URL = 'intent://play.google.com/store/apps/details?id=in.freshyo.app#Intent;scheme=https;package=com.android.vending;end;';
|
const ANDROID_URL = 'intent://play.google.com/store/apps/details?id=in.freshyo.app#Intent;scheme=https;package=com.android.vending;end;';
|
||||||
const IOS_URL = 'https://apps.apple.com/in/app/freshyo/id6756889077';
|
const IOS_URL = 'https://apps.apple.com/in/app/freshyo/id6756889077';
|
||||||
const BROWSER_URL = 'https://app.freshyo.in';
|
|
||||||
|
|
||||||
function detectOS() {
|
function detectOS() {
|
||||||
const userAgent = navigator.userAgent || navigator.vendor || window.opera;
|
const userAgent = navigator.userAgent || navigator.vendor || window.opera;
|
||||||
|
|
@ -60,8 +47,12 @@ html(lang="en")
|
||||||
|
|
||||||
function redirectToStore() {
|
function redirectToStore() {
|
||||||
const os = detectOS();
|
const os = detectOS();
|
||||||
if (os === 'android') window.location.href = ANDROID_URL;
|
|
||||||
else if (os === 'ios') window.location.href = IOS_URL;
|
if (os === 'android') {
|
||||||
|
window.location.href = ANDROID_URL;
|
||||||
|
} else if (os === 'ios') {
|
||||||
|
window.location.href = IOS_URL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleAndroidClick(event) {
|
function handleAndroidClick(event) {
|
||||||
|
|
@ -74,9 +65,4 @@ html(lang="en")
|
||||||
window.location.href = IOS_URL;
|
window.location.href = IOS_URL;
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleBrowserClick(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
window.location.href = BROWSER_URL;
|
|
||||||
}
|
|
||||||
|
|
||||||
window.addEventListener('load', redirectToStore);
|
window.addEventListener('load', redirectToStore);
|
||||||
|
|
|
||||||
|
|
@ -4,33 +4,38 @@ html(lang="en")
|
||||||
meta(charset="utf-8")
|
meta(charset="utf-8")
|
||||||
meta(name="viewport" content="width=device-width, initial-scale=1")
|
meta(name="viewport" content="width=device-width, initial-scale=1")
|
||||||
title= title
|
title= title
|
||||||
link(rel="icon" type="image/png" href="/favicon.png")
|
|
||||||
link(rel="stylesheet" href="/css/styles.css")
|
link(rel="stylesheet" href="/css/styles.css")
|
||||||
|
|
||||||
body
|
body
|
||||||
.app-container
|
.app-container
|
||||||
|
// Navigation
|
||||||
nav.nav
|
nav.nav
|
||||||
a.nav-logo(href="/")
|
a.nav-logo(href="/")
|
||||||
img(src="/freshyo-logo.png" alt="Freshyo" width="36" height="36")
|
svg(width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2")
|
||||||
|
path(d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2z")
|
||||||
|
path(d="M12 6v6l4 2")
|
||||||
span Freshyo
|
span Freshyo
|
||||||
ul.nav-links
|
ul.nav-links
|
||||||
li: a(href="/") Back to Home
|
li: a(href="/") Back to Home
|
||||||
|
|
||||||
|
// Main Content
|
||||||
.app-content
|
.app-content
|
||||||
.success-card
|
.success-card
|
||||||
span.success-icon ✓
|
span.success-icon ✓
|
||||||
h1 Request Received
|
h1 Request Received
|
||||||
p Your account deletion request has been submitted. Your data will be permanently removed within 7 days.
|
p Your request to delete your account has been submitted successfully. Your data will be permanently removed within 7 days.
|
||||||
a.btn.btn-primary(href="/") Back to Home
|
a.btn.btn-primary(href="/") Back to Home
|
||||||
|
|
||||||
|
// Footer
|
||||||
footer.footer
|
footer.footer
|
||||||
.footer-content
|
.footer-content
|
||||||
.footer-brand
|
.footer-brand
|
||||||
img(src="/freshyo-logo.png" alt="Freshyo" width="32" height="32")
|
svg(width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2")
|
||||||
|
path(d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2z")
|
||||||
span Freshyo
|
span Freshyo
|
||||||
.footer-links
|
.footer-links
|
||||||
a(href="#") For Farmers
|
a(href="#") For Farmers
|
||||||
a(href="#") For Consumers
|
a(href="#") For Consumers
|
||||||
a(href="/privacy-policy") Privacy Policy
|
a(href="/privacy-policy") Privacy Policy
|
||||||
a(href="/delete-account") Delete Account
|
a(href="/delete-account") Delete Account
|
||||||
p.footer-copyright © #{year} Freshyo Inc. All rights reserved.
|
p.footer-copyright © #{year} Freshyo Inc.
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,10 @@ import { useRouter } from 'expo-router';
|
||||||
import { tw, useManualRefresh, MyText, MyFlatList, useMarkDataFetchers, REFUND_STATUS, MyTouchableOpacity, theme } from 'common-ui';
|
import { tw, useManualRefresh, MyText, MyFlatList, useMarkDataFetchers, REFUND_STATUS, MyTouchableOpacity, theme } from 'common-ui';
|
||||||
|
|
||||||
import { trpc } from '@/src/trpc-client';
|
import { trpc } from '@/src/trpc-client';
|
||||||
|
// import RazorpayCheckout from 'react-native-razorpay';
|
||||||
|
import OrderMenu from '@/components/OrderMenu';
|
||||||
|
import dayjs from 'dayjs';
|
||||||
|
import { orderStatusManipulator } from '@/src/lib/string-manipulators';
|
||||||
|
|
||||||
// Type definitions
|
// Type definitions
|
||||||
interface OrderItem {
|
interface OrderItem {
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,8 @@ import { View, Alert, Platform } from 'react-native';
|
||||||
import { useRouter } from 'expo-router';
|
import { useRouter } from 'expo-router';
|
||||||
import { tw, MyTextInput, LoadingDialog, MyText, MyTouchableOpacity } from 'common-ui';
|
import { tw, MyTextInput, LoadingDialog, MyText, MyTouchableOpacity } from 'common-ui';
|
||||||
import MaterialIcons from '@expo/vector-icons/MaterialIcons';
|
import MaterialIcons from '@expo/vector-icons/MaterialIcons';
|
||||||
|
// import RazorpayCheckout from 'react-native-razorpay';
|
||||||
|
|
||||||
import { trpc } from '@/src/trpc-client';
|
import { trpc } from '@/src/trpc-client';
|
||||||
import { useCentralProductStore } from '@/src/store/centralProductStore';
|
import { useCentralProductStore } from '@/src/store/centralProductStore';
|
||||||
import { useCentralSlotStore } from '@/src/store/centralSlotStore';
|
import { useCentralSlotStore } from '@/src/store/centralSlotStore';
|
||||||
|
|
|
||||||
|
|
@ -213,7 +213,7 @@ export default function CartPage({ isFlashDelivery = false }: CartPageProps) {
|
||||||
const product = productsById[item.productId];
|
const product = productsById[item.productId];
|
||||||
const quantity = quantities[item.id] || item.quantity;
|
const quantity = quantities[item.id] || item.quantity;
|
||||||
const price = isFlashDelivery ? (product?.flashPrice ?? product?.price ?? 0) : (product?.price || 0);
|
const price = isFlashDelivery ? (product?.flashPrice ?? product?.price ?? 0) : (product?.price || 0);
|
||||||
return sum + Number(price) * quantity;
|
return sum + price * quantity;
|
||||||
}, 0);
|
}, 0);
|
||||||
const dropdownData = useMemo(
|
const dropdownData = useMemo(
|
||||||
() =>
|
() =>
|
||||||
|
|
@ -442,7 +442,7 @@ export default function CartPage({ isFlashDelivery = false }: CartPageProps) {
|
||||||
// }
|
// }
|
||||||
const quantity = quantities[item.id] || item.quantity;
|
const quantity = quantities[item.id] || item.quantity;
|
||||||
const price = isFlashDelivery ? (product?.flashPrice ?? product?.price ?? 0) : (product?.price || 0);
|
const price = isFlashDelivery ? (product?.flashPrice ?? product?.price ?? 0) : (product?.price || 0);
|
||||||
const itemPrice = (Number(price)) * quantity;
|
const itemPrice = price * quantity;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<View key={item.id}>
|
<View key={item.id}>
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@
|
||||||
"@trpc/client": "^11.6.0",
|
"@trpc/client": "^11.6.0",
|
||||||
"@trpc/react-query": "^11.6.0",
|
"@trpc/react-query": "^11.6.0",
|
||||||
"axios": "^1.11.0",
|
"axios": "^1.11.0",
|
||||||
|
"buffer": "^6.0.3",
|
||||||
"dayjs": "^1.11.18",
|
"dayjs": "^1.11.18",
|
||||||
"expo": "~53.0.22",
|
"expo": "~53.0.22",
|
||||||
"expo-blur": "~14.1.5",
|
"expo-blur": "~14.1.5",
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,8 @@ export default function AddToCartDialog() {
|
||||||
const { data: cartData } = useGetCart();
|
const { data: cartData } = useGetCart();
|
||||||
const { data: constsData } = useGetEssentialConsts();
|
const { data: constsData } = useGetEssentialConsts();
|
||||||
const productSlotsMap = useCentralSlotStore((state) => state.productSlotsMap);
|
const productSlotsMap = useCentralSlotStore((state) => state.productSlotsMap);
|
||||||
const isFlashDeliveryEnabled = constsData?.isFlashDeliveryEnabled === true;
|
// const isFlashDeliveryEnabled = constsData?.isFlashDeliveryEnabled === true;
|
||||||
|
const isFlashDeliveryEnabled = true;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,19 +0,0 @@
|
||||||
{
|
|
||||||
"projectName": "web-ui",
|
|
||||||
"mode": "file-router",
|
|
||||||
"typescript": true,
|
|
||||||
"tailwind": true,
|
|
||||||
"packageManager": "bun",
|
|
||||||
"git": true,
|
|
||||||
"install": true,
|
|
||||||
"intent": true,
|
|
||||||
"addOnOptions": {},
|
|
||||||
"includeExamples": false,
|
|
||||||
"envVarValues": {},
|
|
||||||
"routerOnly": false,
|
|
||||||
"version": 1,
|
|
||||||
"framework": "react",
|
|
||||||
"chosenAddOns": [
|
|
||||||
"nitro"
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
@ -1,17 +0,0 @@
|
||||||
{
|
|
||||||
"date": "2026-05-10T09:04:44.879Z",
|
|
||||||
"preset": "node-server",
|
|
||||||
"framework": {
|
|
||||||
"name": "nitro",
|
|
||||||
"version": "3.0.1-20260508-123613-d2e64906"
|
|
||||||
},
|
|
||||||
"versions": {
|
|
||||||
"nitro": "3.0.1-20260508-123613-d2e64906"
|
|
||||||
},
|
|
||||||
"serverEntry": "server/index.mjs",
|
|
||||||
"publicDir": "public",
|
|
||||||
"commands": {
|
|
||||||
"preview": "node ./server/index.mjs"
|
|
||||||
},
|
|
||||||
"config": {}
|
|
||||||
}
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{t as e}from"./createLucideIcon-7nArgiy8.js";var t=e(`ArrowLeft`,[[`path`,{d:`m12 19-7-7 7-7`,key:`1l729n`}],[`path`,{d:`M19 12H5`,key:`x3x0zl`}]]);export{t};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{d as e,l as t,r as n,s as r,t as i,u as a}from"./src-C0xjWfnx.js";import{t as o}from"./useNavigate-VRicZWJI.js";import{t as s}from"./trash-2-B2Qxo_rV.js";import{a as c,i as l,r as u}from"./cart-query-hooks-BCr0eax3.js";import{t as d}from"./prominent-api-hooks-DipwWw0H.js";var f=e();function p(){let e=o(),{data:p}=u(`regular`),{data:m}=d(),h=c(`regular`),g=l(`regular`),_=m?.products||[],v={};_.forEach(e=>{v[e.id]=e});let y=(p?.items||[]).filter(e=>v[e.productId]),b=0;return y.forEach(e=>{let t=v[e.productId];t&&(b+=t.price*e.quantity)}),(0,f.jsxs)(i,{children:[(0,f.jsx)(a,{weight:`bold`,className:`mb-4 text-xl`,children:`Your Cart`}),y.length===0?(0,f.jsxs)(`div`,{className:`flex flex-col items-center gap-4 py-20`,children:[(0,f.jsx)(a,{className:`text-gray-500`,children:`Your cart is empty`}),(0,f.jsx)(t,{textContent:`Browse Products`,onClick:()=>e({to:`/home`})})]}):(0,f.jsxs)(f.Fragment,{children:[(0,f.jsx)(`div`,{className:`flex flex-col gap-3`,children:y.map(e=>{let t=v[e.productId],i=t.price;return(0,f.jsxs)(`div`,{className:`flex items-center gap-3 rounded-xl border border-gray-100 bg-white p-3 shadow-sm`,children:[(0,f.jsx)(`img`,{src:t.images?.[0],alt:t.name,className:`h-16 w-16 rounded-lg object-cover`}),(0,f.jsxs)(`div`,{className:`flex-1`,children:[(0,f.jsx)(a,{weight:`semibold`,className:`text-sm`,numberOfLines:1,children:t.name}),(0,f.jsxs)(a,{className:`text-brand-600 text-sm font-bold`,children:[`₹`,i]}),(0,f.jsx)(n,{value:e.quantity,setValue:t=>h.mutate({productId:e.productId,quantity:t})})]}),(0,f.jsx)(r,{onClick:()=>g.mutate(e.productId),children:(0,f.jsx)(s,{className:`h-5 w-5 text-red-500`})})]},e.productId)})}),(0,f.jsxs)(`div`,{className:`fixed bottom-0 left-0 right-0 border-t border-gray-200 bg-white p-4 shadow-lg`,children:[(0,f.jsxs)(`div`,{className:`mb-3 flex items-center justify-between`,children:[(0,f.jsx)(a,{weight:`bold`,children:`Total`}),(0,f.jsxs)(a,{weight:`bold`,className:`text-lg text-brand-600`,children:[`₹`,b]})]}),(0,f.jsx)(t,{fullWidth:!0,textContent:`Proceed to Checkout`,onClick:()=>e({to:`/checkout`}),className:`bg-brand-500 text-white`})]})]})]})}export{p as component};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{m as e,n as t,t as n}from"./useMutation-DvG2_Fq3.js";function r(e){return`local-cart-${e}`}function i(e){try{let t=localStorage.getItem(r(e));return t?JSON.parse(t):[]}catch{return[]}}function a(e,t){localStorage.setItem(r(e),JSON.stringify(t))}function o(e=`regular`){return t({queryKey:[r(e)],queryFn:()=>{let t=i(e);return{items:t,totalItems:t.reduce((e,t)=>e+t.quantity,0),totalAmount:0}}})}function s(t=`regular`){let o=e();return n({mutationFn:async({productId:e,quantity:n,storeId:r,slotId:o,deliveryDate:s})=>{let c=i(t),l=c.find(t=>t.productId===e);l?(l.quantity+=n,o&&(l.slotId=o),s&&(l.deliveryDate=s)):c.push({id:Date.now(),productId:e,quantity:n,storeId:r,addedAt:Date.now(),slotId:o??null,deliveryDate:s??null}),a(t,c)},onSuccess:()=>{o.invalidateQueries({queryKey:[r(t)]})}})}function c(t=`regular`){let o=e();return n({mutationFn:async({productId:e,quantity:n,slotId:r,deliveryDate:o})=>{let s=i(t),c=s.find(t=>t.productId===e);c&&(c.quantity=n,r!==void 0&&(c.slotId=r),o!==void 0&&(c.deliveryDate=o)),a(t,s)},onSuccess:()=>{o.invalidateQueries({queryKey:[r(t)]})}})}function l(t=`regular`){let o=e();return n({mutationFn:async e=>{let n=i(t);n=n.filter(t=>t.productId!==e),a(t,n)},onSuccess:()=>{o.invalidateQueries({queryKey:[r(t)]})}})}function u(e=`regular`){localStorage.removeItem(r(e))}export{c as a,l as i,s as n,o as r,u as t};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{t as e}from"./react-BnURElzN.js";var t=e(e=>({products:[],productsById:{},setProducts:t=>{let n={};t.forEach(e=>{n[e.id]=e}),e({products:t,productsById:n})},refetchProducts:null,setRefetchProducts:t=>e({refetchProducts:t})}));export{t};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{d as e,f as t,h as n,l as r,o as i,s as a,t as o,u as s}from"./src-C0xjWfnx.js";import{t as c}from"./useNavigate-VRicZWJI.js";import{m as l}from"./useMutation-DvG2_Fq3.js";import{n as u}from"./trpc-client-QrVjRqP1.js";import{l as d}from"./index-BXnbw4dQ.js";import{r as f,t as p}from"./cart-query-hooks-BCr0eax3.js";import{t as m}from"./prominent-api-hooks-DipwWw0H.js";var h=n(t()),g=e();function _(){let e=c(),t=l(),{isAuthenticated:n}=d(),{data:_}=f(`regular`),{data:v}=m(),[y,b]=(0,h.useState)(!1),x=v?.products||[],S={};x.forEach(e=>{S[e.id]=e});let{data:C}=u.user.address.getUserAddresses.useQuery(void 0,{enabled:n}),[w,T]=(0,h.useState)(null),E=(_?.items||[]).filter(e=>S[e.productId]),D=0;E.forEach(e=>{let t=S[e.productId];t&&(D+=t.price*e.quantity)});let O=u.user.order.placeOrder.useMutation({onSuccess:n=>{let r=n.data?.[0];p(`regular`),t.invalidateQueries({queryKey:[`local-cart-regular`]}),e({to:`/home/order-success`,search:{orderId:r?.id,totalAmount:D}})},onSettled:()=>b(!1)});return(0,g.jsxs)(o,{children:[(0,g.jsx)(s,{weight:`bold`,className:`mb-4 text-xl`,children:`Checkout`}),(0,g.jsxs)(`div`,{className:`mb-6`,children:[(0,g.jsx)(s,{weight:`semibold`,className:`mb-2`,children:`Delivery Address`}),C?.data?.map(e=>(0,g.jsxs)(a,{onClick:()=>T(e.id),className:`mb-2 rounded-xl border p-3 ${w===e.id?`border-brand-500 bg-brand-50`:`border-gray-200`}`,children:[(0,g.jsx)(s,{weight:`semibold`,children:e.name}),(0,g.jsxs)(s,{className:`text-sm text-gray-600`,children:[e.addressLine1,`, `,e.city]}),(0,g.jsx)(s,{className:`text-sm text-gray-500`,children:e.phone})]},e.id))]}),(0,g.jsxs)(`div`,{className:`mb-6`,children:[(0,g.jsx)(s,{weight:`semibold`,className:`mb-2`,children:`Order Summary`}),E.map(e=>{let t=S[e.productId];return t?(0,g.jsxs)(`div`,{className:`flex items-center justify-between py-2`,children:[(0,g.jsxs)(s,{className:`text-sm`,numberOfLines:1,children:[t.name,` x`,e.quantity]}),(0,g.jsxs)(s,{className:`text-sm font-bold`,children:[`₹`,t.price*e.quantity]})]},e.productId):null}),(0,g.jsx)(`div`,{className:`mt-2 border-t border-gray-200 pt-2`,children:(0,g.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,g.jsx)(s,{weight:`bold`,children:`Total`}),(0,g.jsxs)(s,{weight:`bold`,className:`text-brand-600`,children:[`₹`,D]})]})})]}),(0,g.jsx)(r,{fullWidth:!0,textContent:`Place Order (COD)`,onClick:()=>{w&&(b(!0),O.mutate({selectedItems:E.map(e=>({productId:e.productId,quantity:e.quantity,slotId:null})),addressId:w,paymentMethod:`cod`,isFlashDelivery:!1}))},disabled:!w||O.isPending,className:`bg-brand-500 text-white`}),(0,g.jsx)(i,{open:y,message:`Placing your order...`})]})}export{_ as component};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{f as e,h as t}from"./src-C0xjWfnx.js";var n=t(e()),r=e=>e.replace(/([a-z0-9])([A-Z])/g,`$1-$2`).toLowerCase(),i=(...e)=>e.filter((e,t,n)=>!!e&&n.indexOf(e)===t).join(` `),a={xmlns:`http://www.w3.org/2000/svg`,width:24,height:24,viewBox:`0 0 24 24`,fill:`none`,stroke:`currentColor`,strokeWidth:2,strokeLinecap:`round`,strokeLinejoin:`round`},o=(0,n.forwardRef)(({color:e=`currentColor`,size:t=24,strokeWidth:r=2,absoluteStrokeWidth:o,className:s=``,children:c,iconNode:l,...u},d)=>(0,n.createElement)(`svg`,{ref:d,...a,width:t,height:t,stroke:e,strokeWidth:o?Number(r)*24/Number(t):r,className:i(`lucide`,s),...u},[...l.map(([e,t])=>(0,n.createElement)(e,t)),...Array.isArray(c)?c:[c]])),s=(e,t)=>{let a=(0,n.forwardRef)(({className:a,...s},c)=>(0,n.createElement)(o,{ref:c,iconNode:t,className:i(`lucide-${r(e)}`,a),...s}));return a.displayName=`${e}`,a};export{s as t};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{d as e,f as t,h as n,l as r,r as i,t as a,u as o}from"./src-C0xjWfnx.js";import{t as s}from"./useNavigate-VRicZWJI.js";import{t as c}from"./shopping-cart-BBNoSjWE.js";import{t as l}from"./zap-CufcM84a.js";import{n as u}from"./cart-query-hooks-BCr0eax3.js";import{t as d}from"./react-BnURElzN.js";import{t as f}from"./central-product-store-DGoerB5U.js";var p=n(t()),m=d(e=>({slots:[],productSlotsMap:{},setSlots:t=>e({slots:t}),setProductSlotsMap:t=>e({productSlotsMap:t}),refetchSlots:null,setRefetchSlots:t=>e({refetchSlots:t})})),h=e();function g(){let e=s(),t=f(e=>e.products),n=m(e=>e.productSlotsMap),[d,g]=(0,p.useState)({}),_=u(`flash`),v=t.filter(e=>n[e.id]?.isFlashAvailable&&!n[e.id]?.isOutOfStock),y=t=>{let n=d[t.id]||1;_.mutate({productId:t.id,quantity:n,storeId:t.storeId},{onSuccess:()=>e({to:`/flash/cart`})})};return(0,h.jsxs)(a,{children:[(0,h.jsxs)(`div`,{className:`mb-4 flex items-center gap-2`,children:[(0,h.jsx)(l,{className:`h-6 w-6 text-yellow-500`}),(0,h.jsx)(o,{weight:`bold`,className:`text-xl`,children:`1 Hr Delivery`})]}),(0,h.jsx)(`div`,{className:`mb-4 rounded-xl bg-yellow-50 p-3`,children:(0,h.jsx)(o,{className:`text-sm text-yellow-800`,children:`Get these products delivered within 1 hour! Only available for select items.`})}),(0,h.jsx)(`div`,{className:`grid grid-cols-2 gap-3`,children:v.map(e=>{let t=e.discountedPrice??e.price,n=d[e.id]||1;return(0,h.jsxs)(`div`,{className:`rounded-xl border border-gray-100 bg-white p-3 shadow-sm`,children:[(0,h.jsx)(`div`,{className:`mb-2 aspect-square w-full overflow-hidden rounded-lg bg-gray-100`,children:e.images?.[0]&&(0,h.jsx)(`img`,{src:e.images[0].uri,alt:e.name,className:`h-full w-full object-cover`})}),(0,h.jsx)(o,{weight:`semibold`,className:`text-sm`,numberOfLines:2,children:e.name}),(0,h.jsxs)(o,{weight:`bold`,className:`text-brand-600`,children:[`₹`,t]}),(0,h.jsx)(`div`,{className:`mt-2 flex items-center gap-2`,children:(0,h.jsx)(i,{value:n,setValue:t=>g(n=>({...n,[e.id]:t}))})}),(0,h.jsxs)(r,{fullWidth:!0,onClick:()=>y(e),className:`mt-2 flex items-center justify-center gap-1 bg-brand-500 text-white text-xs`,disabled:_.isPending,children:[(0,h.jsx)(c,{className:`h-3 w-3`}),`Add`]})]},e.id)})}),v.length===0&&(0,h.jsx)(`div`,{className:`py-20 text-center`,children:(0,h.jsx)(o,{className:`text-gray-500`,children:`No flash delivery products available`})})]})}export{g as component};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{d as e,l as t,r as n,s as r,t as i,u as a}from"./src-C0xjWfnx.js";import{t as o}from"./useNavigate-VRicZWJI.js";import{t as s}from"./trash-2-B2Qxo_rV.js";import{t as c}from"./zap-CufcM84a.js";import{a as l,i as u,r as d}from"./cart-query-hooks-BCr0eax3.js";import{t as f}from"./central-product-store-DGoerB5U.js";var p=e();function m(){let e=o(),{data:m}=d(`flash`),h=l(`flash`),g=u(`flash`),_=f(e=>e.productsById),v=(m?.items||[]).filter(e=>_[e.productId]),y=0;return v.forEach(e=>{let t=_[e.productId];t&&(y+=(t.discountedPrice??t.price)*e.quantity)}),(0,p.jsxs)(i,{children:[(0,p.jsxs)(`div`,{className:`mb-4 flex items-center gap-2`,children:[(0,p.jsx)(c,{className:`h-5 w-5 text-yellow-500`}),(0,p.jsx)(a,{weight:`bold`,className:`text-xl`,children:`Flash Cart`})]}),v.length===0?(0,p.jsxs)(`div`,{className:`flex flex-col items-center gap-4 py-20`,children:[(0,p.jsx)(a,{className:`text-gray-500`,children:`Your flash cart is empty`}),(0,p.jsx)(t,{textContent:`Browse Flash Products`,onClick:()=>e({to:`/flash`})})]}):(0,p.jsxs)(p.Fragment,{children:[(0,p.jsx)(`div`,{className:`flex flex-col gap-3`,children:v.map(e=>{let t=_[e.productId],i=t.discountedPrice??t.price;return(0,p.jsxs)(`div`,{className:`flex items-center gap-3 rounded-xl border border-gray-100 bg-white p-3 shadow-sm`,children:[(0,p.jsx)(`img`,{src:t.images?.[0],alt:t.name,className:`h-16 w-16 rounded-lg object-cover`}),(0,p.jsxs)(`div`,{className:`flex-1`,children:[(0,p.jsx)(a,{weight:`semibold`,className:`text-sm`,numberOfLines:1,children:t.name}),(0,p.jsxs)(a,{className:`text-brand-600 text-sm font-bold`,children:[`₹`,i]}),(0,p.jsx)(n,{value:e.quantity,setValue:t=>h.mutate({productId:e.productId,quantity:t})})]}),(0,p.jsx)(r,{onClick:()=>g.mutate(e.productId),children:(0,p.jsx)(s,{className:`h-5 w-5 text-red-500`})})]},e.productId)})}),(0,p.jsxs)(`div`,{className:`fixed bottom-0 left-0 right-0 border-t border-gray-200 bg-white p-4 shadow-lg`,children:[(0,p.jsxs)(`div`,{className:`mb-3 flex items-center justify-between`,children:[(0,p.jsx)(a,{weight:`bold`,children:`Total`}),(0,p.jsxs)(a,{weight:`bold`,className:`text-lg text-brand-600`,children:[`₹`,y]})]}),(0,p.jsx)(t,{fullWidth:!0,textContent:`Proceed to Checkout`,onClick:()=>e({to:`/flash/checkout`}),className:`bg-brand-500 text-white`})]})]})]})}export{m as component};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{d as e,f as t,h as n,l as r,o as i,t as a,u as o}from"./src-C0xjWfnx.js";import{t as s}from"./useNavigate-VRicZWJI.js";import{m as c}from"./useMutation-DvG2_Fq3.js";import{n as l}from"./trpc-client-QrVjRqP1.js";import{l as u}from"./index-BXnbw4dQ.js";import{r as d,t as f}from"./cart-query-hooks-BCr0eax3.js";import{t as p}from"./central-product-store-DGoerB5U.js";var m=n(t()),h=e();function g(){let e=s(),t=c(),{isAuthenticated:n}=u(),{data:g}=d(`flash`),_=p(e=>e.productsById),[v,y]=(0,m.useState)(!1),{data:b}=l.user.address.getUserAddresses.useQuery(void 0,{enabled:n}),[x,S]=(0,m.useState)(null),C=l.user.order.placeOrder.useMutation({onSuccess:n=>{let r=n.data?.[0];f(`flash`),t.invalidateQueries({queryKey:[`local-cart-flash`]}),e({to:`/flash/order-success`,search:{orderId:r?.id,totalAmount:T}})},onSettled:()=>y(!1)}),w=(g?.items||[]).filter(e=>_[e.productId]),T=0;return w.forEach(e=>{let t=_[e.productId];t&&(T+=(t.discountedPrice??t.price)*e.quantity)}),(0,h.jsxs)(a,{children:[(0,h.jsx)(o,{weight:`bold`,className:`mb-4 text-xl`,children:`Flash Checkout`}),(0,h.jsxs)(`div`,{className:`mb-6`,children:[(0,h.jsx)(o,{weight:`semibold`,className:`mb-2`,children:`Delivery Address`}),b?.data?.map(e=>(0,h.jsxs)(`button`,{onClick:()=>S(e.id),className:`mb-2 w-full rounded-xl border p-3 text-left ${x===e.id?`border-brand-500 bg-brand-50`:`border-gray-200`}`,children:[(0,h.jsx)(o,{weight:`semibold`,children:e.name}),(0,h.jsxs)(o,{className:`text-sm text-gray-600`,children:[e.addressLine1,`, `,e.city]}),(0,h.jsx)(o,{className:`text-sm text-gray-500`,children:e.phone})]},e.id))]}),(0,h.jsxs)(`div`,{className:`mb-6`,children:[(0,h.jsx)(o,{weight:`semibold`,className:`mb-2`,children:`Order Summary`}),w.map(e=>{let t=_[e.productId];return t?(0,h.jsxs)(`div`,{className:`flex items-center justify-between py-2`,children:[(0,h.jsxs)(o,{className:`text-sm`,numberOfLines:1,children:[t.name,` x`,e.quantity]}),(0,h.jsxs)(o,{className:`text-sm font-bold`,children:[`₹`,(t.discountedPrice??t.price)*e.quantity]})]},e.productId):null}),(0,h.jsx)(`div`,{className:`mt-2 border-t border-gray-200 pt-2`,children:(0,h.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,h.jsx)(o,{weight:`bold`,children:`Total`}),(0,h.jsxs)(o,{weight:`bold`,className:`text-brand-600`,children:[`₹`,T]})]})})]}),(0,h.jsx)(r,{fullWidth:!0,textContent:`Place Flash Order (COD)`,onClick:()=>{x&&(y(!0),C.mutate({selectedItems:w.map(e=>({productId:e.productId,quantity:e.quantity,slotId:null})),addressId:x,paymentMethod:`cod`,isFlashDelivery:!0}))},disabled:!x||C.isPending,className:`bg-brand-500 text-white`}),(0,h.jsx)(i,{open:v,message:`Placing flash order...`})]})}export{g as component};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{d as e,l as t,u as n}from"./src-C0xjWfnx.js";import{t as r}from"./useNavigate-VRicZWJI.js";import{t as i}from"./zap-CufcM84a.js";import{a}from"./index-BXnbw4dQ.js";var o=e();function s(){let e=r(),{orderId:s,totalAmount:c}=a.useSearch();return(0,o.jsxs)(`div`,{className:`flex min-h-screen flex-col items-center justify-center bg-yellow-50 p-6`,children:[(0,o.jsx)(`div`,{className:`mb-6 flex h-20 w-20 items-center justify-center rounded-full bg-yellow-100`,children:(0,o.jsx)(i,{className:`h-10 w-10 text-yellow-600`})}),(0,o.jsx)(n,{weight:`bold`,className:`mb-2 text-2xl text-gray-900`,children:`1 Hr Order Placed!`}),(0,o.jsxs)(n,{className:`mb-1 text-gray-600`,children:[`Order ID: #`,s]}),(0,o.jsxs)(n,{className:`mb-8 text-gray-600`,children:[`Total: ₹`,c]}),(0,o.jsx)(t,{textContent:`Continue Shopping`,onClick:()=>e({to:`/flash`}),className:`mb-3 bg-brand-500 text-white`}),(0,o.jsx)(t,{textContent:`View My Orders`,onClick:()=>e({to:`/me/orders`}),className:`bg-gray-100 text-gray-700`})]})}export{s as component};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{d as e,f as t,h as n,l as r,r as i,t as a,u as o}from"./src-C0xjWfnx.js";import{t as s}from"./useNavigate-VRicZWJI.js";import{t as c}from"./shopping-cart-BBNoSjWE.js";import{t as l}from"./zap-CufcM84a.js";import{n as u}from"./index-BXnbw4dQ.js";import{n as d}from"./cart-query-hooks-BCr0eax3.js";import{t as f}from"./central-product-store-DGoerB5U.js";var p=n(t()),m=e();function h(){let{id:e}=u.useParams(),t=Number(e),n=s(),[h,g]=(0,p.useState)(1),_=f(e=>e.productsById)[t],v=d(`flash`),y=()=>{_&&v.mutate({productId:_.id,quantity:h,storeId:_.storeId},{onSuccess:()=>n({to:`/flash/cart`})})};if(!_)return(0,m.jsx)(a,{children:(0,m.jsx)(o,{children:`Product not found`})});let b=_.discountedPrice??_.price,x=_.images?.[0];return(0,m.jsxs)(a,{children:[(0,m.jsxs)(`div`,{className:`mb-4 flex items-center gap-2`,children:[(0,m.jsx)(l,{className:`h-5 w-5 text-yellow-500`}),(0,m.jsx)(o,{className:`text-sm font-semibold text-yellow-600`,children:`1 Hr Delivery`})]}),x&&(0,m.jsx)(`div`,{className:`mb-4 aspect-square w-full overflow-hidden rounded-xl bg-gray-100`,children:(0,m.jsx)(`img`,{src:x,alt:_.name,className:`h-full w-full object-cover`})}),(0,m.jsx)(o,{weight:`bold`,className:`mb-1 text-xl`,children:_.name}),(0,m.jsxs)(o,{className:`mb-4 text-sm text-gray-500`,children:[_.unitValue,_.unit]}),(0,m.jsxs)(`div`,{className:`mb-4 flex items-baseline gap-2`,children:[(0,m.jsxs)(o,{weight:`bold`,className:`text-2xl text-brand-600`,children:[`₹`,b]}),_.discountedPrice&&(0,m.jsxs)(o,{className:`text-sm text-gray-400 line-through`,children:[`₹`,_.price]})]}),(0,m.jsx)(`div`,{className:`mb-6`,children:(0,m.jsx)(i,{value:h,setValue:g,max:10})}),(0,m.jsxs)(r,{fullWidth:!0,onClick:y,disabled:v.isPending,className:`flex items-center justify-center gap-2 bg-brand-500 text-white`,children:[(0,m.jsx)(c,{className:`h-4 w-4`}),v.isPending?`Adding...`:`Add to Cart`]})]})}export{h as component};
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1 +0,0 @@
|
||||||
import{d as e,l as t,r as n,s as r,t as i,u as a}from"./src-C0xjWfnx.js";import{t as o}from"./useNavigate-VRicZWJI.js";import{t as s}from"./trash-2-B2Qxo_rV.js";import{a as c,i as l,r as u}from"./cart-query-hooks-BCr0eax3.js";import{t as d}from"./prominent-api-hooks-DipwWw0H.js";var f=e();function p(){let e=o(),{data:p}=u(`regular`),{data:m}=d(),h=c(`regular`),g=l(`regular`),_=m?.products||[],v={};_.forEach(e=>{v[e.id]=e});let y=(p?.items||[]).filter(e=>v[e.productId]),b=0;return y.forEach(e=>{let t=v[e.productId];t&&(b+=t.price*e.quantity)}),(0,f.jsxs)(i,{children:[(0,f.jsx)(a,{weight:`bold`,className:`mb-4 text-xl`,children:`Your Cart`}),y.length===0?(0,f.jsxs)(`div`,{className:`flex flex-col items-center gap-4 py-20`,children:[(0,f.jsx)(a,{className:`text-gray-500`,children:`Your cart is empty`}),(0,f.jsx)(t,{textContent:`Browse Products`,onClick:()=>e({to:`/home`})})]}):(0,f.jsxs)(f.Fragment,{children:[(0,f.jsx)(`div`,{className:`flex flex-col gap-3`,children:y.map(e=>{let t=v[e.productId],i=t.price;return(0,f.jsxs)(`div`,{className:`flex items-center gap-3 rounded-xl border border-gray-100 bg-white p-3 shadow-sm`,children:[(0,f.jsx)(`img`,{src:t.images?.[0],alt:t.name,className:`h-16 w-16 rounded-lg object-cover`}),(0,f.jsxs)(`div`,{className:`flex-1`,children:[(0,f.jsx)(a,{weight:`semibold`,className:`text-sm`,numberOfLines:1,children:t.name}),(0,f.jsxs)(a,{className:`text-brand-600 text-sm font-bold`,children:[`₹`,i]}),(0,f.jsx)(n,{value:e.quantity,setValue:t=>h.mutate({productId:e.productId,quantity:t})})]}),(0,f.jsx)(r,{onClick:()=>g.mutate(e.productId),children:(0,f.jsx)(s,{className:`h-5 w-5 text-red-500`})})]},e.productId)})}),(0,f.jsxs)(`div`,{className:`fixed bottom-0 left-0 right-0 border-t border-gray-200 bg-white p-4 shadow-lg`,children:[(0,f.jsxs)(`div`,{className:`mb-3 flex items-center justify-between`,children:[(0,f.jsx)(a,{weight:`bold`,children:`Total`}),(0,f.jsxs)(a,{weight:`bold`,className:`text-lg text-brand-600`,children:[`₹`,b]})]}),(0,f.jsx)(t,{fullWidth:!0,textContent:`Proceed to Checkout`,onClick:()=>e({to:`/home/checkout`}),className:`bg-brand-500 text-white`})]})]})]})}export{p as component};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{d as e,f as t,h as n,l as r,o as i,s as a,t as o,u as s}from"./src-C0xjWfnx.js";import{t as c}from"./useNavigate-VRicZWJI.js";import{m as l}from"./useMutation-DvG2_Fq3.js";import{n as u}from"./trpc-client-QrVjRqP1.js";import{l as d}from"./index-BXnbw4dQ.js";import{r as f,t as p}from"./cart-query-hooks-BCr0eax3.js";import{t as m}from"./central-product-store-DGoerB5U.js";var h=n(t()),g=e();function _(){let e=c(),t=l(),{isAuthenticated:n}=d(),{data:_}=f(`regular`),v=m(e=>e.productsById),[y,b]=(0,h.useState)(!1),{data:x}=u.user.address.getUserAddresses.useQuery(void 0,{enabled:n}),[S,C]=(0,h.useState)(null),w=u.user.order.placeOrder.useMutation({onSuccess:n=>{let r=n.data?.[0];p(`regular`),t.invalidateQueries({queryKey:[`local-cart-regular`]}),e({to:`/home/order-success`,search:{orderId:r?.id,totalAmount:E}})},onSettled:()=>b(!1)}),T=(_?.items||[]).filter(e=>v[e.productId]),E=0;return T.forEach(e=>{let t=v[e.productId];t&&(E+=(t.discountedPrice??t.price)*e.quantity)}),(0,g.jsxs)(o,{children:[(0,g.jsx)(s,{weight:`bold`,className:`mb-4 text-xl`,children:`Checkout`}),(0,g.jsxs)(`div`,{className:`mb-6`,children:[(0,g.jsx)(s,{weight:`semibold`,className:`mb-2`,children:`Delivery Address`}),x?.data?.map(e=>(0,g.jsxs)(a,{onClick:()=>C(e.id),className:`mb-2 rounded-xl border p-3 ${S===e.id?`border-brand-500 bg-brand-50`:`border-gray-200`}`,children:[(0,g.jsx)(s,{weight:`semibold`,children:e.name}),(0,g.jsxs)(s,{className:`text-sm text-gray-600`,children:[e.addressLine1,`, `,e.city]}),(0,g.jsx)(s,{className:`text-sm text-gray-500`,children:e.phone})]},e.id))]}),(0,g.jsxs)(`div`,{className:`mb-6`,children:[(0,g.jsx)(s,{weight:`semibold`,className:`mb-2`,children:`Order Summary`}),T.map(e=>{let t=v[e.productId];return t?(0,g.jsxs)(`div`,{className:`flex items-center justify-between py-2`,children:[(0,g.jsxs)(s,{className:`text-sm`,numberOfLines:1,children:[t.name,` x`,e.quantity]}),(0,g.jsxs)(s,{className:`text-sm font-bold`,children:[`₹`,(t.discountedPrice??t.price)*e.quantity]})]},e.productId):null}),(0,g.jsx)(`div`,{className:`mt-2 border-t border-gray-200 pt-2`,children:(0,g.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,g.jsx)(s,{weight:`bold`,children:`Total`}),(0,g.jsxs)(s,{weight:`bold`,className:`text-brand-600`,children:[`₹`,E]})]})})]}),(0,g.jsx)(r,{fullWidth:!0,textContent:`Place Order (COD)`,onClick:()=>{S&&(b(!0),w.mutate({selectedItems:T.map(e=>({productId:e.productId,quantity:e.quantity,slotId:null})),addressId:S,paymentMethod:`cod`,isFlashDelivery:!1}))},disabled:!S||w.isPending,className:`bg-brand-500 text-white`}),(0,g.jsx)(i,{open:y,message:`Placing your order...`})]})}export{_ as component};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{d as e,l as t,u as n}from"./src-C0xjWfnx.js";import{t as r}from"./useNavigate-VRicZWJI.js";import{t as i}from"./package-CgMILU3n.js";import{o as a}from"./index-BXnbw4dQ.js";var o=e();function s(){let e=r(),{orderId:s,totalAmount:c}=a.useSearch();return(0,o.jsxs)(`div`,{className:`flex min-h-screen flex-col items-center justify-center bg-green-50 p-6`,children:[(0,o.jsx)(`div`,{className:`mb-6 flex h-20 w-20 items-center justify-center rounded-full bg-green-100`,children:(0,o.jsx)(i,{className:`h-10 w-10 text-green-600`})}),(0,o.jsx)(n,{weight:`bold`,className:`mb-2 text-2xl text-gray-900`,children:`Order Placed!`}),(0,o.jsxs)(n,{className:`mb-1 text-gray-600`,children:[`Order ID: #`,s]}),(0,o.jsxs)(n,{className:`mb-8 text-gray-600`,children:[`Total: ₹`,c]}),(0,o.jsx)(t,{textContent:`Continue Shopping`,onClick:()=>e({to:`/home`}),className:`mb-3 bg-brand-500 text-white`}),(0,o.jsx)(t,{textContent:`View My Orders`,onClick:()=>e({to:`/me/orders`}),fillColor:`gray`,className:`bg-gray-100 text-gray-700`})]})}export{s as component};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{d as e,f as t,h as n,l as r,r as i,t as a,u as o}from"./src-C0xjWfnx.js";import{t as s}from"./useNavigate-VRicZWJI.js";import{n as c}from"./trpc-client-QrVjRqP1.js";import{t as l}from"./createLucideIcon-7nArgiy8.js";import{t as u}from"./shopping-cart-BBNoSjWE.js";import{r as d}from"./index-BXnbw4dQ.js";import{n as f}from"./cart-query-hooks-BCr0eax3.js";import{t as p}from"./central-product-store-DGoerB5U.js";var m=l(`Star`,[[`polygon`,{points:`12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26 12 2`,key:`8f66p6`}]]),h=n(t()),g=e();function _(){let{id:e}=d.useParams(),t=Number(e),n=s(),[l,_]=(0,h.useState)(1),v=p(e=>e.productsById)[t],y=f(`regular`),{data:b}=c.user.product.getProductReviews.useQuery({productId:t},{enabled:!!t}),x=()=>{v&&y.mutate({productId:v.id,quantity:l,storeId:v.storeId},{onSuccess:()=>n({to:`/cart`})})};if(!v)return(0,g.jsx)(a,{children:(0,g.jsx)(o,{children:`Product not found`})});let S=v.discountedPrice??v.price,C=v.images?.[0];return(0,g.jsxs)(a,{children:[C&&(0,g.jsx)(`div`,{className:`mb-4 aspect-square w-full overflow-hidden rounded-xl bg-gray-100`,children:(0,g.jsx)(`img`,{src:C,alt:v.name,className:`h-full w-full object-cover`})}),(0,g.jsx)(o,{weight:`bold`,className:`mb-1 text-xl`,children:v.name}),(0,g.jsxs)(o,{className:`mb-2 text-sm text-gray-500`,children:[v.unitValue,v.unit]}),(0,g.jsxs)(`div`,{className:`mb-4 flex items-baseline gap-2`,children:[(0,g.jsxs)(o,{weight:`bold`,className:`text-2xl text-brand-600`,children:[`₹`,S]}),v.discountedPrice&&(0,g.jsxs)(o,{className:`text-sm text-gray-400 line-through`,children:[`₹`,v.price]})]}),v.description&&(0,g.jsx)(o,{className:`mb-4 text-gray-600`,children:v.description}),(0,g.jsx)(`div`,{className:`mb-6`,children:(0,g.jsx)(i,{value:l,setValue:_,max:10})}),(0,g.jsxs)(r,{fullWidth:!0,onClick:x,disabled:y.isPending,className:`flex items-center justify-center gap-2 bg-brand-500 text-white`,children:[(0,g.jsx)(u,{className:`h-4 w-4`}),y.isPending?`Adding...`:`Add to Cart`]}),b?.data&&b.data.length>0&&(0,g.jsxs)(`div`,{className:`mt-8`,children:[(0,g.jsx)(o,{weight:`bold`,className:`mb-3 text-lg`,children:`Reviews`}),b.data.map((e,t)=>(0,g.jsxs)(`div`,{className:`mb-3 rounded-lg border border-gray-100 p-3`,children:[(0,g.jsx)(`div`,{className:`mb-1 flex items-center gap-1`,children:Array.from({length:e.rating||5}).map((e,t)=>(0,g.jsx)(m,{className:`h-3 w-3 fill-yellow-400 text-yellow-400`},t))}),(0,g.jsx)(o,{className:`text-sm text-gray-600`,children:e.comment})]},t))]})]})}export{_ as component};
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1 +0,0 @@
|
||||||
import{t as e}from"./createLucideIcon-7nArgiy8.js";var t=e(`MapPin`,[[`path`,{d:`M20 10c0 6-8 12-8 12s-8-6-8-12a8 8 0 0 1 16 0Z`,key:`2oe9fu`}],[`circle`,{cx:`12`,cy:`10`,r:`3`,key:`ilqhr7`}]]);export{t};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{d as e,l as t,n,s as r,t as i,u as a}from"./src-C0xjWfnx.js";import{t as o}from"./useNavigate-VRicZWJI.js";import{t as s}from"./createLucideIcon-7nArgiy8.js";import{t as c}from"./map-pin-DbTySZl1.js";import{t as l}from"./message-square-BE-hnHXL.js";import{t as u}from"./package-CgMILU3n.js";import{t as d}from"./shopping-cart-BBNoSjWE.js";import{t as f}from"./ticket-DHIzx079.js";import{l as p}from"./index-BXnbw4dQ.js";var m=s(`FileText`,[[`path`,{d:`M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z`,key:`1rqfz7`}],[`path`,{d:`M14 2v4a2 2 0 0 0 2 2h4`,key:`tnqrlb`}],[`path`,{d:`M10 9H8`,key:`b1mrlr`}],[`path`,{d:`M16 13H8`,key:`t4e002`}],[`path`,{d:`M16 17H8`,key:`z1uh3a`}]]),h=s(`Info`,[[`circle`,{cx:`12`,cy:`12`,r:`10`,key:`1mglay`}],[`path`,{d:`M12 16v-4`,key:`1dtifu`}],[`path`,{d:`M12 8h.01`,key:`e9boi3`}]]),g=s(`User`,[[`path`,{d:`M19 21v-2a4 4 0 0 0-4-4H9a4 4 0 0 0-4 4v2`,key:`975kel`}],[`circle`,{cx:`12`,cy:`7`,r:`4`,key:`17ys0d`}]]),_=e();function v(){let e=o(),{user:s,logout:v}=p();if(!s)return(0,_.jsx)(i,{children:(0,_.jsxs)(`div`,{className:`flex flex-col items-center gap-4 py-20`,children:[(0,_.jsx)(a,{children:`Please sign in`}),(0,_.jsx)(t,{textContent:`Sign In`,onClick:()=>e({to:`/login`})})]})});let y=[{section:`Shopping & Activity`,items:[{icon:u,label:`My Orders`,to:`/me/orders`},{icon:d,label:`My Cart`,to:`/cart`},{icon:f,label:`Coupons`,to:`/me/coupons`}]},{section:`Saved Information`,items:[{icon:c,label:`Addresses`,to:`/me/addresses`},{icon:g,label:`Profile Settings`,to:`/me/edit-profile`}]},{section:`Support`,items:[{icon:l,label:`Help & Complaints`,to:`/me/complaints`},{icon:m,label:`Terms & Conditions`,to:`/me/terms`}]},{section:`About`,items:[{icon:h,label:`About Us`,to:`/me/about`}]}];return(0,_.jsxs)(i,{children:[(0,_.jsxs)(`div`,{className:`mb-6 flex items-center gap-4 rounded-xl bg-brand-50 p-4`,children:[(0,_.jsx)(n,{uri:s.profileImage,size:64}),(0,_.jsxs)(`div`,{children:[(0,_.jsx)(a,{weight:`bold`,className:`text-lg`,children:s.name||`User`}),(0,_.jsx)(a,{className:`text-sm text-gray-500`,children:s.mobile})]})]}),y.map(t=>(0,_.jsxs)(`div`,{className:`mb-6`,children:[(0,_.jsx)(a,{weight:`semibold`,className:`mb-2 text-sm text-gray-500 uppercase tracking-wide`,children:t.section}),(0,_.jsx)(`div`,{className:`rounded-xl border border-gray-100 bg-white shadow-sm`,children:t.items.map(t=>(0,_.jsxs)(r,{onClick:()=>e({to:t.to}),className:`flex w-full items-center gap-3 border-b border-gray-50 px-4 py-3.5 last:border-b-0`,children:[(0,_.jsx)(t.icon,{className:`h-5 w-5 text-gray-400`}),(0,_.jsx)(a,{className:`flex-1 text-left text-sm`,children:t.label})]},t.label))})]},t.section)),(0,_.jsx)(t,{fullWidth:!0,onClick:v,variant:`red`,className:`mb-8`,textContent:`Logout`}),(0,_.jsx)(a,{className:`mb-8 text-center text-xs text-gray-400`,children:`Version 1.0.0`})]})}export{v as component};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{d as e,t,u as n}from"./src-C0xjWfnx.js";import{t as r}from"./createLucideIcon-7nArgiy8.js";import{t as i}from"./truck-DbJZ8T2i.js";var a=r(`Heart`,[[`path`,{d:`M19 14c1.49-1.46 3-3.21 3-5.5A5.5 5.5 0 0 0 16.5 3c-1.76 0-3 .5-4.5 2-1.5-1.5-2.74-2-4.5-2A5.5 5.5 0 0 0 2 8.5c0 2.3 1.5 4.05 3 5.5l7 7Z`,key:`c3ymky`}]]),o=r(`Leaf`,[[`path`,{d:`M11 20A7 7 0 0 1 9.8 6.1C15.5 5 17 4.48 19 2c1 2 2 4.18 2 8 0 5.5-4.78 10-10 10Z`,key:`nnexq3`}],[`path`,{d:`M2 21c0-3 1.85-5.36 5.08-6C9.5 14.52 12 13 13 12`,key:`mt58a7`}]]),s=r(`Shield`,[[`path`,{d:`M20 13c0 5-3.5 7.5-7.66 8.95a1 1 0 0 1-.67-.01C7.5 20.5 4 18 4 13V6a1 1 0 0 1 1-1c2 0 4.5-1.2 6.24-2.72a1.17 1.17 0 0 1 1.52 0C14.51 3.81 17 5 19 5a1 1 0 0 1 1 1z`,key:`oel41y`}]]),c=e();function l(){return(0,c.jsxs)(t,{children:[(0,c.jsx)(n,{weight:`bold`,className:`mb-6 text-2xl`,children:`About Freshyo`}),(0,c.jsx)(`div`,{className:`grid grid-cols-2 gap-4`,children:[{icon:o,title:`Local Roots`,desc:`We source directly from local farmers to bring you the freshest meat.`},{icon:a,title:`Quality First`,desc:`Every cut is inspected for quality and freshness before delivery.`},{icon:i,title:`Fast Delivery`,desc:`Get your order delivered within 1 hour in select areas.`},{icon:s,title:`Farmers First`,desc:`We ensure fair prices and sustainable practices for our farmers.`}].map(e=>(0,c.jsxs)(`div`,{className:`rounded-xl border border-gray-100 bg-white p-4 shadow-sm`,children:[(0,c.jsx)(e.icon,{className:`mb-2 h-8 w-8 text-brand-500`}),(0,c.jsx)(n,{weight:`semibold`,className:`mb-1`,children:e.title}),(0,c.jsx)(n,{className:`text-sm text-gray-600`,children:e.desc})]},e.title))}),(0,c.jsxs)(`div`,{className:`mt-8`,children:[(0,c.jsx)(n,{weight:`bold`,className:`mb-3 text-lg`,children:`Sourcing & Quality`}),(0,c.jsx)(n,{className:`mb-6 text-sm leading-relaxed text-gray-600`,children:`We partner with trusted local farmers who follow ethical and sustainable farming practices. Every product undergoes rigorous quality checks to ensure you receive only the freshest meat.`})]})]})}export{l as component};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{d as e,f as t,t as n,u as r}from"./src-C0xjWfnx.js";import{n as i}from"./trpc-client-QrVjRqP1.js";import{t as a}from"./map-pin-DbTySZl1.js";t();var o=e();function s(){let e=i.useUtils(),{data:t}=i.user.address.getUserAddresses.useQuery(),s=i.user.address.deleteAddress.useMutation({onSuccess:()=>e.user.address.getUserAddresses.invalidate()}),c=t?.data||[];return(0,o.jsxs)(n,{children:[(0,o.jsx)(r,{weight:`bold`,className:`mb-4 text-xl`,children:`My Addresses`}),c.length===0?(0,o.jsxs)(`div`,{className:`flex flex-col items-center gap-4 py-20`,children:[(0,o.jsx)(a,{className:`h-12 w-12 text-gray-300`}),(0,o.jsx)(r,{className:`text-gray-500`,children:`No addresses saved`})]}):(0,o.jsx)(`div`,{className:`flex flex-col gap-3`,children:c.map(e=>(0,o.jsx)(`div`,{className:`rounded-xl border border-gray-100 bg-white p-4 shadow-sm`,children:(0,o.jsxs)(`div`,{className:`flex items-start justify-between`,children:[(0,o.jsxs)(`div`,{className:`flex-1`,children:[(0,o.jsx)(r,{weight:`semibold`,children:e.name}),(0,o.jsxs)(r,{className:`text-sm text-gray-600`,children:[e.addressLine1,e.addressLine2?`, ${e.addressLine2}`:``]}),(0,o.jsxs)(r,{className:`text-sm text-gray-600`,children:[e.city,`, `,e.state,` - `,e.pincode]}),(0,o.jsx)(r,{className:`text-sm text-gray-500`,children:e.phone}),e.isDefault&&(0,o.jsx)(`span`,{className:`mt-1 inline-block rounded-full bg-brand-100 px-2 py-0.5 text-xs text-brand-700`,children:`Default`})]}),(0,o.jsx)(`button`,{onClick:()=>s.mutate({id:e.id}),className:`text-sm text-red-500 hover:text-red-700`,children:`Delete`})]})},e.id))})]})}export{s as component};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{d as e,f as t,h as n,l as r,s as i,t as a,u as o}from"./src-C0xjWfnx.js";import{n as s}from"./trpc-client-QrVjRqP1.js";import{t as c}from"./createLucideIcon-7nArgiy8.js";import{t as l}from"./message-square-BE-hnHXL.js";var u=c(`Plus`,[[`path`,{d:`M5 12h14`,key:`1ays0h`}],[`path`,{d:`M12 5v14`,key:`s699le`}]]),d=n(t()),f=e();function p(){let{data:e}=s.user.complaint.getAll.useQuery(),t=s.user.complaint.raise.useMutation(),n=s.useUtils(),[c,p]=(0,d.useState)(!1),[m,h]=(0,d.useState)(``),g=e?.data||[];return(0,f.jsxs)(a,{children:[(0,f.jsxs)(`div`,{className:`mb-4 flex items-center justify-between`,children:[(0,f.jsx)(o,{weight:`bold`,className:`text-xl`,children:`Help & Complaints`}),(0,f.jsxs)(i,{onClick:()=>p(!c),className:`flex items-center gap-1 text-brand-600`,children:[(0,f.jsx)(u,{className:`h-4 w-4`}),(0,f.jsx)(o,{className:`text-sm`,children:`New`})]})]}),c&&(0,f.jsxs)(`div`,{className:`mb-6 rounded-xl border border-gray-100 bg-white p-4 shadow-sm`,children:[(0,f.jsx)(o,{weight:`semibold`,className:`mb-3`,children:`Raise a Complaint`}),(0,f.jsx)(`textarea`,{className:`mb-3 min-h-24 w-full rounded-lg border border-gray-200 p-3 text-sm`,value:m,onChange:e=>h(e.target.value),placeholder:`Describe your issue...`,rows:4}),(0,f.jsx)(r,{onClick:()=>{m.trim()&&t.mutate({body:m.trim()},{onSuccess:()=>{h(``),p(!1),n.user.complaint.getAll.invalidate()}})},disabled:t.isPending||!m.trim(),textContent:t.isPending?`Submitting...`:`Submit`})]}),g.length===0?(0,f.jsxs)(`div`,{className:`flex flex-col items-center gap-4 py-20`,children:[(0,f.jsx)(l,{className:`h-12 w-12 text-gray-300`}),(0,f.jsx)(o,{className:`text-gray-500`,children:`No complaints yet`})]}):(0,f.jsx)(`div`,{className:`flex flex-col gap-3`,children:g.map(e=>(0,f.jsxs)(`div`,{className:`rounded-xl border border-gray-100 bg-white p-4 shadow-sm`,children:[(0,f.jsxs)(`div`,{className:`mb-2 flex items-center justify-between`,children:[(0,f.jsx)(`span`,{className:`rounded-full px-2 py-0.5 text-xs font-medium ${e.status===`resolved`?`bg-green-100 text-green-700`:`bg-yellow-100 text-yellow-700`}`,children:e.status||`pending`}),(0,f.jsx)(o,{className:`text-xs text-gray-400`,children:e.createdAt?new Date(e.createdAt).toLocaleDateString():``})]}),(0,f.jsx)(o,{className:`text-sm text-gray-700`,children:e.body}),e.adminResponse&&(0,f.jsx)(`div`,{className:`mt-2 rounded-lg bg-blue-50 p-2`,children:(0,f.jsxs)(o,{className:`text-xs text-blue-600`,children:[`Response: `,e.adminResponse]})})]},e.id))})]})}export{p as component};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{c as e,d as t,f as n,h as r,l as i,t as a,u as o}from"./src-C0xjWfnx.js";import{n as s}from"./trpc-client-QrVjRqP1.js";import{t as c}from"./ticket-DHIzx079.js";var l=r(n()),u=t();function d(){let[t,n]=(0,l.useState)(``),{data:r}=s.user.coupon.getMyCoupons.useQuery(),d=s.user.coupon.redeemReservedCoupon.useMutation(),f=s.useUtils(),p=r?.data||[];return(0,u.jsxs)(a,{children:[(0,u.jsx)(o,{weight:`bold`,className:`mb-4 text-xl`,children:`My Coupons`}),(0,u.jsxs)(`div`,{className:`mb-6 flex gap-2`,children:[(0,u.jsx)(e,{placeholder:`Enter coupon code`,value:t,onChange:e=>n(e.target.value),className:`flex-1`}),(0,u.jsx)(i,{onClick:()=>{t.trim()&&d.mutate({couponCode:t.trim()},{onSuccess:()=>{n(``),f.user.coupon.getMyCoupons.invalidate()}})},disabled:d.isPending||!t.trim(),textContent:d.isPending?`Redeeming...`:`Redeem`})]}),p.length===0?(0,u.jsxs)(`div`,{className:`flex flex-col items-center gap-4 py-20`,children:[(0,u.jsx)(c,{className:`h-12 w-12 text-gray-300`}),(0,u.jsx)(o,{className:`text-gray-500`,children:`No coupons yet`})]}):(0,u.jsx)(`div`,{className:`flex flex-col gap-3`,children:p.map(e=>(0,u.jsxs)(`div`,{className:`rounded-xl border border-dashed border-brand-200 bg-brand-50 p-4`,children:[(0,u.jsx)(o,{weight:`bold`,className:`text-brand-700`,children:e.code}),(0,u.jsx)(o,{className:`text-sm text-gray-600`,children:e.description||`${e.discountPercent||0}% off`}),e.expiresAt&&(0,u.jsxs)(o,{className:`mt-1 text-xs text-gray-400`,children:[`Expires: `,new Date(e.expiresAt).toLocaleDateString()]})]},e.id))})]})}export{d as component};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{c as e,d as t,f as n,h as r,l as i,t as a,u as o}from"./src-C0xjWfnx.js";import{t as s}from"./useNavigate-VRicZWJI.js";import{n as c}from"./trpc-client-QrVjRqP1.js";import{l}from"./index-BXnbw4dQ.js";var u=r(n()),d=t();function f(){s();let{user:t,logout:n,loginWithToken:r}=l(),[f,p]=(0,u.useState)(t?.name||``),[m,h]=(0,u.useState)(t?.email||``),g=c.user.auth.updateProfile.useMutation({onSuccess:e=>{e.token&&e.user&&r(e.token,e.user)}}),_=c.user.auth.deleteAccount.useMutation({onSuccess:()=>n()});return(0,d.jsxs)(a,{children:[(0,d.jsx)(o,{weight:`bold`,className:`mb-4 text-xl`,children:`Edit Profile`}),(0,d.jsxs)(`form`,{onSubmit:e=>{e.preventDefault(),g.mutate({name:f,email:m})},className:`flex flex-col gap-4`,children:[(0,d.jsx)(e,{placeholder:`Name`,value:f,onChange:e=>p(e.target.value)}),(0,d.jsx)(e,{placeholder:`Email`,type:`email`,value:m,onChange:e=>h(e.target.value)}),(0,d.jsx)(e,{placeholder:`Mobile`,value:t?.mobile||``,disabled:!0,className:`bg-gray-50`}),(0,d.jsx)(i,{type:`submit`,fullWidth:!0,disabled:g.isPending,textContent:g.isPending?`Saving...`:`Save Changes`,className:`bg-brand-500 text-white`})]}),(0,d.jsxs)(`div`,{className:`mt-8 border-t border-gray-200 pt-8`,children:[(0,d.jsx)(i,{fullWidth:!0,variant:`red`,onClick:()=>n(),textContent:`Logout`}),(0,d.jsx)(i,{fullWidth:!0,variant:`red`,onClick:()=>{window.confirm(`Are you sure you want to delete your account?`)&&_.mutate({mobile:t?.mobile||``})},disabled:_.isPending,textContent:_.isPending?`Deleting...`:`Delete My Account`,className:`mt-3 bg-red-600 text-white`})]})]})}export{f as component};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{d as e,s as t,t as n,u as r}from"./src-C0xjWfnx.js";import{t as i}from"./useNavigate-VRicZWJI.js";import{n as a}from"./trpc-client-QrVjRqP1.js";import{t as o}from"./createLucideIcon-7nArgiy8.js";import{t as s}from"./package-CgMILU3n.js";var c=o(`ChevronRight`,[[`path`,{d:`m9 18 6-6-6-6`,key:`mthhwq`}]]),l=e();function u(){let e=i(),{data:o}=a.user.order.getOrders.useQuery({page:0,limit:20}),u=o?.data||[];return(0,l.jsxs)(n,{children:[(0,l.jsx)(r,{weight:`bold`,className:`mb-4 text-xl`,children:`My Orders`}),u.length===0?(0,l.jsxs)(`div`,{className:`flex flex-col items-center gap-4 py-20`,children:[(0,l.jsx)(s,{className:`h-12 w-12 text-gray-300`}),(0,l.jsx)(r,{className:`text-gray-500`,children:`No orders yet`})]}):(0,l.jsx)(`div`,{className:`flex flex-col gap-3`,children:u.map(n=>(0,l.jsxs)(t,{onClick:()=>e({to:`/me/orders/$id`,params:{id:String(n.id)}}),className:`rounded-xl border border-gray-100 bg-white p-4 shadow-sm`,children:[(0,l.jsxs)(`div`,{className:`flex items-center justify-between`,children:[(0,l.jsxs)(`div`,{children:[(0,l.jsxs)(r,{weight:`semibold`,className:`text-sm`,children:[`Order #`,n.id]}),(0,l.jsx)(r,{className:`text-xs text-gray-500`,children:n.createdAt?new Date(n.createdAt).toLocaleDateString():``})]}),(0,l.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,l.jsx)(`span`,{className:`rounded-full px-2 py-0.5 text-xs font-medium ${n.status===`delivered`?`bg-green-100 text-green-700`:n.status===`cancelled`?`bg-red-100 text-red-700`:`bg-yellow-100 text-yellow-700`}`,children:n.status}),(0,l.jsx)(c,{className:`h-4 w-4 text-gray-400`})]})]}),(0,l.jsxs)(r,{className:`mt-1 text-xs text-gray-400`,children:[`Total: ₹`,n.totalAmount||0]})]},n.id))})]})}export{u as component};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{d as e,f as t,h as n,l as r,o as i,s as a,t as o,u as s}from"./src-C0xjWfnx.js";import{t as c}from"./useNavigate-VRicZWJI.js";import{n as l}from"./trpc-client-QrVjRqP1.js";import{t as u}from"./arrow-left-9Wn53Zfu.js";import{i as d}from"./index-BXnbw4dQ.js";var f=n(t()),p=e();function m(){let{id:e}=d.useParams(),t=c(),n=Number(e),[m,h]=(0,f.useState)(!1),{data:g}=l.user.order.getOrderById.useQuery({orderId:n}),_=l.user.order.cancelOrder.useMutation(),v=g?.data;return v?(0,p.jsxs)(o,{children:[(0,p.jsxs)(a,{onClick:()=>t({to:`/me/orders`}),className:`mb-4 flex items-center gap-2`,children:[(0,p.jsx)(u,{className:`h-5 w-5`}),(0,p.jsx)(s,{children:`Back to Orders`})]}),(0,p.jsxs)(`div`,{className:`mb-4`,children:[(0,p.jsxs)(s,{weight:`bold`,className:`text-xl`,children:[`Order #`,v.id]}),(0,p.jsx)(`span`,{className:`mt-1 inline-block rounded-full px-3 py-1 text-xs font-medium ${v.status===`delivered`?`bg-green-100 text-green-700`:v.status===`cancelled`?`bg-red-100 text-red-700`:`bg-yellow-100 text-yellow-700`}`,children:v.status})]}),(0,p.jsxs)(`div`,{className:`mb-6`,children:[(0,p.jsx)(s,{weight:`semibold`,className:`mb-2`,children:`Items`}),(v.items||[]).map((e,t)=>(0,p.jsxs)(`div`,{className:`flex items-center justify-between border-b border-gray-100 py-2`,children:[(0,p.jsxs)(s,{className:`text-sm`,children:[e.product?.name||`Product #${e.productId}`,` x`,e.quantity]}),(0,p.jsxs)(s,{className:`text-sm font-bold`,children:[`₹`,e.price||0]})]},t)),(0,p.jsxs)(`div`,{className:`flex items-center justify-between pt-2`,children:[(0,p.jsx)(s,{weight:`bold`,children:`Total`}),(0,p.jsxs)(s,{weight:`bold`,className:`text-brand-600`,children:[`₹`,v.totalAmount||0]})]})]}),v.address&&(0,p.jsxs)(`div`,{className:`mb-6`,children:[(0,p.jsx)(s,{weight:`semibold`,className:`mb-2`,children:`Delivery Address`}),(0,p.jsxs)(`div`,{className:`rounded-xl border border-gray-100 bg-gray-50 p-3`,children:[(0,p.jsx)(s,{weight:`semibold`,children:v.address.name}),(0,p.jsxs)(s,{className:`text-sm text-gray-600`,children:[v.address.addressLine1,`, `,v.address.city]}),(0,p.jsx)(s,{className:`text-sm text-gray-500`,children:v.address.phone})]})]}),v.status!==`cancelled`&&v.status!==`delivered`&&(0,p.jsx)(r,{variant:`red`,fullWidth:!0,textContent:_.isPending?`Cancelling...`:`Cancel Order`,onClick:()=>h(!0),disabled:_.isPending}),m&&(0,p.jsx)(`div`,{className:`fixed inset-0 z-50 flex items-center justify-center bg-black/50`,children:(0,p.jsxs)(`div`,{className:`mx-4 w-full max-w-sm rounded-xl bg-white p-6`,children:[(0,p.jsx)(s,{weight:`bold`,className:`mb-2 text-lg`,children:`Cancel Order?`}),(0,p.jsx)(s,{className:`mb-6 text-sm text-gray-600`,children:`Are you sure you want to cancel this order?`}),(0,p.jsxs)(`div`,{className:`flex gap-3`,children:[(0,p.jsx)(r,{textContent:`No, Keep It`,onClick:()=>h(!1),className:`flex-1 bg-gray-100 text-gray-700`}),(0,p.jsx)(r,{variant:`red`,textContent:`Yes, Cancel`,onClick:()=>{_.mutate({orderId:n},{onSuccess:()=>h(!1)})},className:`flex-1`,disabled:_.isPending})]})]})}),(0,p.jsx)(i,{open:_.isPending,message:`Cancelling order...`})]}):(0,p.jsx)(o,{children:(0,p.jsx)(s,{children:`Loading...`})})}export{m as component};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{d as e,t,u as n}from"./src-C0xjWfnx.js";var r=e();function i(){return(0,r.jsxs)(t,{children:[(0,r.jsx)(n,{weight:`bold`,className:`mb-6 text-2xl`,children:`Terms & Conditions`}),(0,r.jsxs)(`div`,{className:`prose prose-sm max-w-none text-gray-600`,children:[(0,r.jsx)(n,{weight:`semibold`,className:`mb-2 mt-4 text-gray-900`,children:`1. Acceptance of Terms`}),(0,r.jsx)(n,{className:`mb-4`,children:`By using Freshyo, you agree to these terms. If you do not agree, please do not use our service.`}),(0,r.jsx)(n,{weight:`semibold`,className:`mb-2 mt-4 text-gray-900`,children:`2. Orders and Payments`}),(0,r.jsx)(n,{className:`mb-4`,children:`All orders are subject to availability. We reserve the right to cancel any order. Payments are collected at the time of delivery (COD).`}),(0,r.jsx)(n,{weight:`semibold`,className:`mb-2 mt-4 text-gray-900`,children:`3. Delivery Policy`}),(0,r.jsx)(n,{className:`mb-4`,children:`Delivery times are estimates. We strive to deliver within the promised time window but delays may occur due to unforeseen circumstances.`}),(0,r.jsx)(n,{weight:`semibold`,className:`mb-2 mt-4 text-gray-900`,children:`4. Returns and Refunds`}),(0,r.jsx)(n,{className:`mb-4`,children:`If you are not satisfied with the quality of your order, please contact us within 24 hours of delivery. Refunds will be processed after quality assessment.`}),(0,r.jsx)(n,{weight:`semibold`,className:`mb-2 mt-4 text-gray-900`,children:`5. Privacy`}),(0,r.jsx)(n,{className:`mb-4`,children:`We respect your privacy. Your personal information is used only for order processing and delivery purposes.`})]})]})}export{i as component};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{t as e}from"./createLucideIcon-7nArgiy8.js";var t=e(`MessageSquare`,[[`path`,{d:`M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z`,key:`1lielz`}]]);export{t};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{t as e}from"./createLucideIcon-7nArgiy8.js";var t=e(`Package`,[[`path`,{d:`m7.5 4.27 9 5.15`,key:`1c824w`}],[`path`,{d:`M21 8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73l7 4a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16Z`,key:`hh9hay`}],[`path`,{d:`m3.3 7 8.7 5 8.7-5`,key:`g66t2b`}],[`path`,{d:`M12 22V12`,key:`d0xqtd`}]]);export{t};
|
|
||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -1 +0,0 @@
|
||||||
import{f as e,h as t}from"./src-C0xjWfnx.js";var n=t(e(),1),r=e=>{let t,n=new Set,r=(e,r)=>{let i=typeof e==`function`?e(t):e;if(!Object.is(i,t)){let e=t;t=r??(typeof i!=`object`||!i)?i:Object.assign({},t,i),n.forEach(n=>n(t,e))}},i=()=>t,a={setState:r,getState:i,getInitialState:()=>o,subscribe:e=>(n.add(e),()=>n.delete(e))},o=t=e(r,i,a);return a},i=(e=>e?r(e):r),a=e=>e;function o(e,t=a){let r=n.useSyncExternalStore(e.subscribe,n.useCallback(()=>t(e.getState()),[e,t]),n.useCallback(()=>t(e.getInitialState()),[e,t]));return n.useDebugValue(r),r}var s=e=>{let t=i(e),n=e=>o(t,e);return Object.assign(n,t),n},c=(e=>e?s(e):s);export{c as t};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{c as e,d as t,f as n,h as r,l as i,u as a}from"./src-C0xjWfnx.js";import{t as o}from"./useNavigate-VRicZWJI.js";import{n as s}from"./trpc-client-QrVjRqP1.js";import{l as c}from"./index-BXnbw4dQ.js";var l=r(n()),u=t();function d(){let{register:t}=c(),n=o(),[r,d]=(0,l.useState)(``),[f,p]=(0,l.useState)(``),[m,h]=(0,l.useState)(``),[g,_]=(0,l.useState)(``),v=s.user.auth.register.useMutation({onSuccess:e=>{e.token&&e.user&&(t(e.token,e.user),n({to:`/home`}))}});return(0,u.jsx)(`div`,{className:`flex min-h-screen items-center justify-center bg-gradient-to-b from-brand-400 to-brand-700 p-4`,children:(0,u.jsxs)(`div`,{className:`w-full max-w-md`,children:[(0,u.jsx)(a,{weight:`bold`,className:`mb-2 text-center text-4xl text-white`,children:`Create Account`}),(0,u.jsx)(a,{className:`mb-8 text-center text-lg text-blue-100`,children:`Join Freshyo today`}),(0,u.jsx)(`div`,{className:`rounded-2xl bg-white p-8 shadow-xl`,children:(0,u.jsxs)(`form`,{onSubmit:e=>{e.preventDefault(),v.mutate({name:r,email:f,mobile:m,password:g})},className:`flex flex-col gap-4`,children:[(0,u.jsx)(e,{placeholder:`Full Name`,value:r,onChange:e=>d(e.target.value),required:!0}),(0,u.jsx)(e,{placeholder:`Email`,type:`email`,value:f,onChange:e=>p(e.target.value)}),(0,u.jsx)(e,{placeholder:`Mobile Number`,value:m,onChange:e=>{let t=e.target.value.replace(/\D/g,``);t.length<=10&&h(t)},required:!0}),(0,u.jsx)(e,{placeholder:`Password`,type:`password`,value:g,onChange:e=>_(e.target.value),required:!0}),(0,u.jsx)(i,{type:`submit`,fullWidth:!0,className:`mt-2 h-12 rounded-xl bg-brand-600 text-white shadow-lg`,disabled:v.isPending,textContent:v.isPending?`Creating...`:`Register`})]})})]})})}export{d as component};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{t as e}from"./createLucideIcon-7nArgiy8.js";var t=e(`ShoppingCart`,[[`circle`,{cx:`8`,cy:`21`,r:`1`,key:`jimo8o`}],[`circle`,{cx:`19`,cy:`21`,r:`1`,key:`13723u`}],[`path`,{d:`M2.05 2.05h2l2.66 12.42a2 2 0 0 0 2 1.58h9.78a2 2 0 0 0 1.95-1.57l1.65-7.43H5.12`,key:`9zh506`}]]);export{t};
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1 +0,0 @@
|
||||||
import{d as e,s as t,t as n,u as r}from"./src-C0xjWfnx.js";import{t as i}from"./useNavigate-VRicZWJI.js";import{t as a}from"./createLucideIcon-7nArgiy8.js";import{a as o}from"./prominent-api-hooks-DipwWw0H.js";var s=a(`Store`,[[`path`,{d:`m2 7 4.41-4.41A2 2 0 0 1 7.83 2h8.34a2 2 0 0 1 1.42.59L22 7`,key:`ztvudi`}],[`path`,{d:`M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8`,key:`1b2hhj`}],[`path`,{d:`M15 22v-4a2 2 0 0 0-2-2h-2a2 2 0 0 0-2 2v4`,key:`2ebpfo`}],[`path`,{d:`M2 7h20`,key:`1fcdvo`}],[`path`,{d:`M22 7v3a2 2 0 0 1-2 2a2.7 2.7 0 0 1-1.59-.63.7.7 0 0 0-.82 0A2.7 2.7 0 0 1 16 12a2.7 2.7 0 0 1-1.59-.63.7.7 0 0 0-.82 0A2.7 2.7 0 0 1 12 12a2.7 2.7 0 0 1-1.59-.63.7.7 0 0 0-.82 0A2.7 2.7 0 0 1 8 12a2.7 2.7 0 0 1-1.59-.63.7.7 0 0 0-.82 0A2.7 2.7 0 0 1 4 12a2 2 0 0 1-2-2V7`,key:`6c3vgh`}]]),c=e();function l(){let e=i(),{data:a}=o(),l=a?.data||[];return(0,c.jsxs)(n,{children:[(0,c.jsx)(r,{weight:`bold`,className:`mb-4 text-xl`,children:`Our Stores`}),(0,c.jsx)(`div`,{className:`grid grid-cols-2 gap-4`,children:l.map(n=>(0,c.jsxs)(t,{onClick:()=>e({to:`/stores/$storeId`,params:{storeId:String(n.id)}}),className:`rounded-xl border border-gray-100 bg-white p-4 shadow-sm`,children:[(0,c.jsx)(`div`,{className:`mb-3 flex h-32 w-full items-center justify-center overflow-hidden rounded-lg bg-gray-100`,children:n.imageUrl?(0,c.jsx)(`img`,{src:n.imageUrl,alt:n.name,className:`h-full w-full object-cover`}):(0,c.jsx)(s,{className:`h-10 w-10 text-gray-400`})}),(0,c.jsx)(r,{weight:`semibold`,className:`text-sm`,children:n.name}),(0,c.jsxs)(r,{className:`text-xs text-gray-500`,children:[n.productCount||0,` products`]})]},n.id))})]})}export{l as component};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{d as e,f as t,h as n,s as r,t as i,u as a}from"./src-C0xjWfnx.js";import{t as o}from"./useNavigate-VRicZWJI.js";import{t as s}from"./arrow-left-9Wn53Zfu.js";import{c}from"./index-BXnbw4dQ.js";import{i as l}from"./prominent-api-hooks-DipwWw0H.js";var u=n(t()),d=e();function f(){let{storeId:e}=c.useParams(),t=o(),{data:n}=l(Number(e)),[f,p]=(0,u.useState)(null),m=n?.store,h=n?.products||[],g=(0,u.useMemo)(()=>{let e=new Set;return h.forEach(t=>{let n=t.category||`All`;e.add(n)}),[`All`,...Array.from(e)]},[h]),_=(0,u.useMemo)(()=>!f||f===`All`?h:h.filter(e=>(e.category||`All`)===f),[h,f]);return(0,d.jsxs)(i,{children:[(0,d.jsxs)(`div`,{className:`mb-4 flex items-center gap-3`,children:[(0,d.jsx)(r,{onClick:()=>t({to:`/stores`}),children:(0,d.jsx)(s,{className:`h-5 w-5`})}),(0,d.jsx)(a,{weight:`bold`,className:`text-xl`,children:m?.name||`Store`})]}),(0,d.jsx)(`div`,{className:`mb-4 flex gap-2 overflow-x-auto pb-2`,children:g.map(e=>(0,d.jsx)(`button`,{onClick:()=>p(e===`All`?null:e),className:`whitespace-nowrap rounded-full px-4 py-1.5 text-sm ${e===`All`&&!f||f===e?`bg-brand-500 text-white`:`bg-gray-100 text-gray-600`}`,children:e},e))}),(0,d.jsx)(`div`,{className:`grid grid-cols-2 gap-3`,children:_.map(n=>(0,d.jsxs)(r,{onClick:()=>t({to:`/stores/$storeId/product/$productId`,params:{storeId:e,productId:String(n.id)}}),className:`rounded-xl border border-gray-100 bg-white p-3 shadow-sm`,children:[(0,d.jsx)(`div`,{className:`mb-2 aspect-square w-full overflow-hidden rounded-lg bg-gray-100`,children:n.images?.[0]&&(0,d.jsx)(`img`,{src:n.images[0].uri,alt:n.name,className:`h-full w-full object-cover`})}),(0,d.jsx)(a,{weight:`semibold`,className:`text-sm`,numberOfLines:2,children:n.name}),(0,d.jsxs)(a,{weight:`bold`,className:`mt-1 text-brand-600`,children:[`₹`,n.discountedPrice??n.price]})]},n.id))})]})}export{f as component};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{d as e,f as t,h as n,l as r,r as i,s as a,t as o,u as s}from"./src-C0xjWfnx.js";import{t as c}from"./useNavigate-VRicZWJI.js";import{t as l}from"./arrow-left-9Wn53Zfu.js";import{t as u}from"./shopping-cart-BBNoSjWE.js";import{t as d}from"./index-BXnbw4dQ.js";import{n as f}from"./cart-query-hooks-BCr0eax3.js";import{t as p}from"./central-product-store-DGoerB5U.js";var m=n(t()),h=e();function g(){let{productId:e,storeId:t}=d.useParams(),n=Number(e),g=c(),[_,v]=(0,m.useState)(1),y=p(e=>e.productsById)[n],b=f(`regular`),x=()=>{y&&b.mutate({productId:y.id,quantity:_,storeId:y.storeId},{onSuccess:()=>g({to:`/cart`})})};if(!y)return(0,h.jsx)(o,{children:(0,h.jsx)(s,{children:`Product not found`})});let S=y.discountedPrice??y.price,C=y.images?.[0];return(0,h.jsxs)(o,{children:[(0,h.jsx)(a,{onClick:()=>g({to:`/stores/$storeId`,params:{storeId:t}}),className:`mb-4 flex items-center gap-2`,children:(0,h.jsx)(l,{className:`h-5 w-5`})}),C&&(0,h.jsx)(`div`,{className:`mb-4 aspect-square w-full overflow-hidden rounded-xl bg-gray-100`,children:(0,h.jsx)(`img`,{src:C,alt:y.name,className:`h-full w-full object-cover`})}),(0,h.jsx)(s,{weight:`bold`,className:`mb-1 text-xl`,children:y.name}),(0,h.jsxs)(s,{className:`mb-2 text-sm text-gray-500`,children:[y.unitValue,y.unit]}),(0,h.jsxs)(`div`,{className:`mb-4 flex items-baseline gap-2`,children:[(0,h.jsxs)(s,{weight:`bold`,className:`text-2xl text-brand-600`,children:[`₹`,S]}),y.discountedPrice&&(0,h.jsxs)(s,{className:`text-sm text-gray-400 line-through`,children:[`₹`,y.price]})]}),y.description&&(0,h.jsx)(s,{className:`mb-4 text-gray-600`,children:y.description}),(0,h.jsx)(`div`,{className:`mb-6`,children:(0,h.jsx)(i,{value:_,setValue:v,max:10})}),(0,h.jsxs)(r,{fullWidth:!0,onClick:x,disabled:b.isPending,className:`flex items-center justify-center gap-2 bg-brand-500 text-white`,children:[(0,h.jsx)(u,{className:`h-4 w-4`}),b.isPending?`Adding...`:`Add to Cart`]})]})}export{g as component};
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1 +0,0 @@
|
||||||
import{t as e}from"./createLucideIcon-7nArgiy8.js";var t=e(`Ticket`,[[`path`,{d:`M2 9a3 3 0 0 1 0 6v2a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-2a3 3 0 0 1 0-6V7a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2Z`,key:`qn84l0`}],[`path`,{d:`M13 5v2`,key:`dyzc3o`}],[`path`,{d:`M13 17v2`,key:`1ont0d`}],[`path`,{d:`M13 11v2`,key:`1wjjxi`}]]);export{t};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{t as e}from"./createLucideIcon-7nArgiy8.js";var t=e(`Trash2`,[[`path`,{d:`M3 6h18`,key:`d0wm0j`}],[`path`,{d:`M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6`,key:`4alrt4`}],[`path`,{d:`M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2`,key:`v07s0e`}],[`line`,{x1:`10`,x2:`10`,y1:`11`,y2:`17`,key:`1uufr5`}],[`line`,{x1:`14`,x2:`14`,y1:`11`,y2:`17`,key:`xtxkd`}]]);export{t};
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1 +0,0 @@
|
||||||
import{t as e}from"./createLucideIcon-7nArgiy8.js";var t=e(`Truck`,[[`path`,{d:`M14 18V6a2 2 0 0 0-2-2H4a2 2 0 0 0-2 2v11a1 1 0 0 0 1 1h2`,key:`wrbu53`}],[`path`,{d:`M15 18H9`,key:`1lyqi6`}],[`path`,{d:`M19 18h2a1 1 0 0 0 1-1v-3.65a1 1 0 0 0-.22-.624l-3.48-4.35A1 1 0 0 0 17.52 8H14`,key:`lysw3i`}],[`circle`,{cx:`17`,cy:`18`,r:`2`,key:`332jqn`}],[`circle`,{cx:`7`,cy:`18`,r:`2`,key:`19iecd`}]]);export{t};
|
|
||||||
File diff suppressed because one or more lines are too long
|
|
@ -1 +0,0 @@
|
||||||
import{f as e,h as t}from"./src-C0xjWfnx.js";var n=t(e(),1),r=n.use,i=typeof window<`u`?n.useLayoutEffect:n.useEffect;function a(e){let t=n.useRef({value:e,prev:null}),r=t.current.value;return e!==r&&(t.current={value:e,prev:r}),t.current.prev}function o(e,t,r={},i={}){n.useEffect(()=>{if(!e.current||i.disabled||typeof IntersectionObserver!=`function`)return;let n=new IntersectionObserver(([e])=>{t(e)},r);return n.observe(e.current),()=>{n.disconnect()}},[t,r,i.disabled,e])}function s(e){let t=n.useRef(null);return n.useImperativeHandle(e,()=>t.current,[]),t}var c=n.createContext(null);function l(e){return n.useContext(c)}function u(e){let t=l();return n.useCallback(n=>t.navigate({...n,from:n.from??e?.from}),[e?.from,t])}export{s as a,a as c,r as i,l as n,o,c as r,i as s,u as t};
|
|
||||||
|
|
@ -1 +0,0 @@
|
||||||
import{t as e}from"./createLucideIcon-7nArgiy8.js";var t=e(`Zap`,[[`path`,{d:`M4 14a1 1 0 0 1-.78-1.63l9.9-10.2a.5.5 0 0 1 .86.46l-1.92 6.02A1 1 0 0 0 13 10h7a1 1 0 0 1 .78 1.63l-9.9 10.2a.5.5 0 0 1-.86-.46l1.92-6.02A1 1 0 0 0 11 14z`,key:`1xq2db`}]]);export{t};
|
|
||||||
Binary file not shown.
|
Before Width: | Height: | Size: 3.8 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 5.2 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 9.4 KiB |
|
|
@ -1,25 +0,0 @@
|
||||||
{
|
|
||||||
"short_name": "FreshYo App",
|
|
||||||
"name": "FreshYo - Freshness Delivered Smiles Picked Up",
|
|
||||||
"icons": [
|
|
||||||
{
|
|
||||||
"src": "favicon.png",
|
|
||||||
"sizes": "64x64 32x32 24x24 16x16",
|
|
||||||
"type": "image/x-icon"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"src": "logo192.png",
|
|
||||||
"type": "image/png",
|
|
||||||
"sizes": "192x192"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"src": "logo512.png",
|
|
||||||
"type": "image/png",
|
|
||||||
"sizes": "512x512"
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"start_url": ".",
|
|
||||||
"display": "standalone",
|
|
||||||
"theme_color": "#000000",
|
|
||||||
"background_color": "#ffffff"
|
|
||||||
}
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
# https://www.robotstxt.org/robotstxt.html
|
|
||||||
User-agent: *
|
|
||||||
Disallow:
|
|
||||||
|
|
@ -1,5 +0,0 @@
|
||||||
//#region node_modules/.nitro/vite/services/ssr/assets/__23tanstack-start-plugin-adapters-y_fshQDY.js
|
|
||||||
var pluginSerializationAdapters = [];
|
|
||||||
var hasPluginAdapters = false;
|
|
||||||
//#endregion
|
|
||||||
export { hasPluginAdapters, pluginSerializationAdapters };
|
|
||||||
|
|
@ -1,15 +0,0 @@
|
||||||
import { n as HTTPError, o as toRequest } from "../_libs/h3+rou3+srvx.mjs";
|
|
||||||
//#region node_modules/nitro/dist/runtime/vite.mjs
|
|
||||||
function fetchViteEnv(viteEnvName, input, init) {
|
|
||||||
const viteEnv = (globalThis.__nitro_vite_envs__ || {})[viteEnvName];
|
|
||||||
if (!viteEnv) throw HTTPError.status(404);
|
|
||||||
return Promise.resolve(viteEnv.fetch(toRequest(input, init)));
|
|
||||||
}
|
|
||||||
//#endregion
|
|
||||||
//#region node_modules/nitro/dist/runtime/internal/vite/ssr-renderer.mjs
|
|
||||||
/** @param {{ req: Request }} HTTPEvent */
|
|
||||||
function ssrRenderer({ req }) {
|
|
||||||
return fetchViteEnv("ssr", req);
|
|
||||||
}
|
|
||||||
//#endregion
|
|
||||||
export { ssrRenderer as default };
|
|
||||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,259 +0,0 @@
|
||||||
import { t as __commonJSMin } from "../_runtime.mjs";
|
|
||||||
//#region node_modules/asynckit/lib/defer.js
|
|
||||||
var require_defer = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
||||||
module.exports = defer;
|
|
||||||
/**
|
|
||||||
* Runs provided function on next iteration of the event loop
|
|
||||||
*
|
|
||||||
* @param {function} fn - function to run
|
|
||||||
*/
|
|
||||||
function defer(fn) {
|
|
||||||
var nextTick = typeof setImmediate == "function" ? setImmediate : typeof process == "object" && typeof process.nextTick == "function" ? process.nextTick : null;
|
|
||||||
if (nextTick) nextTick(fn);
|
|
||||||
else setTimeout(fn, 0);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
//#endregion
|
|
||||||
//#region node_modules/asynckit/lib/async.js
|
|
||||||
var require_async = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
||||||
var defer = require_defer();
|
|
||||||
module.exports = async;
|
|
||||||
/**
|
|
||||||
* Runs provided callback asynchronously
|
|
||||||
* even if callback itself is not
|
|
||||||
*
|
|
||||||
* @param {function} callback - callback to invoke
|
|
||||||
* @returns {function} - augmented callback
|
|
||||||
*/
|
|
||||||
function async(callback) {
|
|
||||||
var isAsync = false;
|
|
||||||
defer(function() {
|
|
||||||
isAsync = true;
|
|
||||||
});
|
|
||||||
return function async_callback(err, result) {
|
|
||||||
if (isAsync) callback(err, result);
|
|
||||||
else defer(function nextTick_callback() {
|
|
||||||
callback(err, result);
|
|
||||||
});
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
//#endregion
|
|
||||||
//#region node_modules/asynckit/lib/abort.js
|
|
||||||
var require_abort = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
||||||
module.exports = abort;
|
|
||||||
/**
|
|
||||||
* Aborts leftover active jobs
|
|
||||||
*
|
|
||||||
* @param {object} state - current state object
|
|
||||||
*/
|
|
||||||
function abort(state) {
|
|
||||||
Object.keys(state.jobs).forEach(clean.bind(state));
|
|
||||||
state.jobs = {};
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Cleans up leftover job by invoking abort function for the provided job id
|
|
||||||
*
|
|
||||||
* @this state
|
|
||||||
* @param {string|number} key - job id to abort
|
|
||||||
*/
|
|
||||||
function clean(key) {
|
|
||||||
if (typeof this.jobs[key] == "function") this.jobs[key]();
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
//#endregion
|
|
||||||
//#region node_modules/asynckit/lib/iterate.js
|
|
||||||
var require_iterate = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
||||||
var async = require_async(), abort = require_abort();
|
|
||||||
module.exports = iterate;
|
|
||||||
/**
|
|
||||||
* Iterates over each job object
|
|
||||||
*
|
|
||||||
* @param {array|object} list - array or object (named list) to iterate over
|
|
||||||
* @param {function} iterator - iterator to run
|
|
||||||
* @param {object} state - current job status
|
|
||||||
* @param {function} callback - invoked when all elements processed
|
|
||||||
*/
|
|
||||||
function iterate(list, iterator, state, callback) {
|
|
||||||
var key = state["keyedList"] ? state["keyedList"][state.index] : state.index;
|
|
||||||
state.jobs[key] = runJob(iterator, key, list[key], function(error, output) {
|
|
||||||
if (!(key in state.jobs)) return;
|
|
||||||
delete state.jobs[key];
|
|
||||||
if (error) abort(state);
|
|
||||||
else state.results[key] = output;
|
|
||||||
callback(error, state.results);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* Runs iterator over provided job element
|
|
||||||
*
|
|
||||||
* @param {function} iterator - iterator to invoke
|
|
||||||
* @param {string|number} key - key/index of the element in the list of jobs
|
|
||||||
* @param {mixed} item - job description
|
|
||||||
* @param {function} callback - invoked after iterator is done with the job
|
|
||||||
* @returns {function|mixed} - job abort function or something else
|
|
||||||
*/
|
|
||||||
function runJob(iterator, key, item, callback) {
|
|
||||||
var aborter;
|
|
||||||
if (iterator.length == 2) aborter = iterator(item, async(callback));
|
|
||||||
else aborter = iterator(item, key, async(callback));
|
|
||||||
return aborter;
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
//#endregion
|
|
||||||
//#region node_modules/asynckit/lib/state.js
|
|
||||||
var require_state = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
||||||
module.exports = state;
|
|
||||||
/**
|
|
||||||
* Creates initial state object
|
|
||||||
* for iteration over list
|
|
||||||
*
|
|
||||||
* @param {array|object} list - list to iterate over
|
|
||||||
* @param {function|null} sortMethod - function to use for keys sort,
|
|
||||||
* or `null` to keep them as is
|
|
||||||
* @returns {object} - initial state object
|
|
||||||
*/
|
|
||||||
function state(list, sortMethod) {
|
|
||||||
var isNamedList = !Array.isArray(list), initState = {
|
|
||||||
index: 0,
|
|
||||||
keyedList: isNamedList || sortMethod ? Object.keys(list) : null,
|
|
||||||
jobs: {},
|
|
||||||
results: isNamedList ? {} : [],
|
|
||||||
size: isNamedList ? Object.keys(list).length : list.length
|
|
||||||
};
|
|
||||||
if (sortMethod) initState.keyedList.sort(isNamedList ? sortMethod : function(a, b) {
|
|
||||||
return sortMethod(list[a], list[b]);
|
|
||||||
});
|
|
||||||
return initState;
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
//#endregion
|
|
||||||
//#region node_modules/asynckit/lib/terminator.js
|
|
||||||
var require_terminator = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
||||||
var abort = require_abort(), async = require_async();
|
|
||||||
module.exports = terminator;
|
|
||||||
/**
|
|
||||||
* Terminates jobs in the attached state context
|
|
||||||
*
|
|
||||||
* @this AsyncKitState#
|
|
||||||
* @param {function} callback - final callback to invoke after termination
|
|
||||||
*/
|
|
||||||
function terminator(callback) {
|
|
||||||
if (!Object.keys(this.jobs).length) return;
|
|
||||||
this.index = this.size;
|
|
||||||
abort(this);
|
|
||||||
async(callback)(null, this.results);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
//#endregion
|
|
||||||
//#region node_modules/asynckit/parallel.js
|
|
||||||
var require_parallel = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
||||||
var iterate = require_iterate(), initState = require_state(), terminator = require_terminator();
|
|
||||||
module.exports = parallel;
|
|
||||||
/**
|
|
||||||
* Runs iterator over provided array elements in parallel
|
|
||||||
*
|
|
||||||
* @param {array|object} list - array or object (named list) to iterate over
|
|
||||||
* @param {function} iterator - iterator to run
|
|
||||||
* @param {function} callback - invoked when all elements processed
|
|
||||||
* @returns {function} - jobs terminator
|
|
||||||
*/
|
|
||||||
function parallel(list, iterator, callback) {
|
|
||||||
var state = initState(list);
|
|
||||||
while (state.index < (state["keyedList"] || list).length) {
|
|
||||||
iterate(list, iterator, state, function(error, result) {
|
|
||||||
if (error) {
|
|
||||||
callback(error, result);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (Object.keys(state.jobs).length === 0) {
|
|
||||||
callback(null, state.results);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
state.index++;
|
|
||||||
}
|
|
||||||
return terminator.bind(state, callback);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
//#endregion
|
|
||||||
//#region node_modules/asynckit/serialOrdered.js
|
|
||||||
var require_serialOrdered = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
||||||
var iterate = require_iterate(), initState = require_state(), terminator = require_terminator();
|
|
||||||
module.exports = serialOrdered;
|
|
||||||
module.exports.ascending = ascending;
|
|
||||||
module.exports.descending = descending;
|
|
||||||
/**
|
|
||||||
* Runs iterator over provided sorted array elements in series
|
|
||||||
*
|
|
||||||
* @param {array|object} list - array or object (named list) to iterate over
|
|
||||||
* @param {function} iterator - iterator to run
|
|
||||||
* @param {function} sortMethod - custom sort function
|
|
||||||
* @param {function} callback - invoked when all elements processed
|
|
||||||
* @returns {function} - jobs terminator
|
|
||||||
*/
|
|
||||||
function serialOrdered(list, iterator, sortMethod, callback) {
|
|
||||||
var state = initState(list, sortMethod);
|
|
||||||
iterate(list, iterator, state, function iteratorHandler(error, result) {
|
|
||||||
if (error) {
|
|
||||||
callback(error, result);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
state.index++;
|
|
||||||
if (state.index < (state["keyedList"] || list).length) {
|
|
||||||
iterate(list, iterator, state, iteratorHandler);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
callback(null, state.results);
|
|
||||||
});
|
|
||||||
return terminator.bind(state, callback);
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* sort helper to sort array elements in ascending order
|
|
||||||
*
|
|
||||||
* @param {mixed} a - an item to compare
|
|
||||||
* @param {mixed} b - an item to compare
|
|
||||||
* @returns {number} - comparison result
|
|
||||||
*/
|
|
||||||
function ascending(a, b) {
|
|
||||||
return a < b ? -1 : a > b ? 1 : 0;
|
|
||||||
}
|
|
||||||
/**
|
|
||||||
* sort helper to sort array elements in descending order
|
|
||||||
*
|
|
||||||
* @param {mixed} a - an item to compare
|
|
||||||
* @param {mixed} b - an item to compare
|
|
||||||
* @returns {number} - comparison result
|
|
||||||
*/
|
|
||||||
function descending(a, b) {
|
|
||||||
return -1 * ascending(a, b);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
//#endregion
|
|
||||||
//#region node_modules/asynckit/serial.js
|
|
||||||
var require_serial = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
||||||
var serialOrdered = require_serialOrdered();
|
|
||||||
module.exports = serial;
|
|
||||||
/**
|
|
||||||
* Runs iterator over provided array elements in series
|
|
||||||
*
|
|
||||||
* @param {array|object} list - array or object (named list) to iterate over
|
|
||||||
* @param {function} iterator - iterator to run
|
|
||||||
* @param {function} callback - invoked when all elements processed
|
|
||||||
* @returns {function} - jobs terminator
|
|
||||||
*/
|
|
||||||
function serial(list, iterator, callback) {
|
|
||||||
return serialOrdered(list, iterator, null, callback);
|
|
||||||
}
|
|
||||||
}));
|
|
||||||
//#endregion
|
|
||||||
//#region node_modules/asynckit/index.js
|
|
||||||
var require_asynckit = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
||||||
module.exports = {
|
|
||||||
parallel: require_parallel(),
|
|
||||||
serial: require_serial(),
|
|
||||||
serialOrdered: require_serialOrdered()
|
|
||||||
};
|
|
||||||
}));
|
|
||||||
//#endregion
|
|
||||||
export { require_asynckit as t };
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,16 +0,0 @@
|
||||||
//#region node_modules/clsx/dist/clsx.mjs
|
|
||||||
function r(e) {
|
|
||||||
var t, f, n = "";
|
|
||||||
if ("string" == typeof e || "number" == typeof e) n += e;
|
|
||||||
else if ("object" == typeof e) if (Array.isArray(e)) {
|
|
||||||
var o = e.length;
|
|
||||||
for (t = 0; t < o; t++) e[t] && (f = r(e[t])) && (n && (n += " "), n += f);
|
|
||||||
} else for (f in e) e[f] && (n && (n += " "), n += f);
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
function clsx() {
|
|
||||||
for (var e, t, f = 0, n = "", o = arguments.length; f < o; f++) (e = arguments[f]) && (t = r(e)) && (n && (n += " "), n += t);
|
|
||||||
return n;
|
|
||||||
}
|
|
||||||
//#endregion
|
|
||||||
export { clsx as t };
|
|
||||||
|
|
@ -1,300 +0,0 @@
|
||||||
import { t as __commonJSMin } from "../_runtime.mjs";
|
|
||||||
//#region node_modules/dayjs/dayjs.min.js
|
|
||||||
var require_dayjs_min = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
||||||
(function(t, e) {
|
|
||||||
"object" == typeof exports && "undefined" != typeof module ? module.exports = e() : "function" == typeof define && define.amd ? define(e) : (t = "undefined" != typeof globalThis ? globalThis : t || self).dayjs = e();
|
|
||||||
})(exports, (function() {
|
|
||||||
"use strict";
|
|
||||||
var t = 1e3, e = 6e4, n = 36e5, r = "millisecond", i = "second", s = "minute", u = "hour", a = "day", o = "week", c = "month", f = "quarter", h = "year", d = "date", l = "Invalid Date", $ = /^(\d{4})[-/]?(\d{1,2})?[-/]?(\d{0,2})[Tt\s]*(\d{1,2})?:?(\d{1,2})?:?(\d{1,2})?[.:]?(\d+)?$/, y = /\[([^\]]+)]|Y{1,4}|M{1,4}|D{1,2}|d{1,4}|H{1,2}|h{1,2}|a|A|m{1,2}|s{1,2}|Z{1,2}|SSS/g, M = {
|
|
||||||
name: "en",
|
|
||||||
weekdays: "Sunday_Monday_Tuesday_Wednesday_Thursday_Friday_Saturday".split("_"),
|
|
||||||
months: "January_February_March_April_May_June_July_August_September_October_November_December".split("_"),
|
|
||||||
ordinal: function(t) {
|
|
||||||
var e = [
|
|
||||||
"th",
|
|
||||||
"st",
|
|
||||||
"nd",
|
|
||||||
"rd"
|
|
||||||
], n = t % 100;
|
|
||||||
return "[" + t + (e[(n - 20) % 10] || e[n] || e[0]) + "]";
|
|
||||||
}
|
|
||||||
}, m = function(t, e, n) {
|
|
||||||
var r = String(t);
|
|
||||||
return !r || r.length >= e ? t : "" + Array(e + 1 - r.length).join(n) + t;
|
|
||||||
}, v = {
|
|
||||||
s: m,
|
|
||||||
z: function(t) {
|
|
||||||
var e = -t.utcOffset(), n = Math.abs(e), r = Math.floor(n / 60), i = n % 60;
|
|
||||||
return (e <= 0 ? "+" : "-") + m(r, 2, "0") + ":" + m(i, 2, "0");
|
|
||||||
},
|
|
||||||
m: function t(e, n) {
|
|
||||||
if (e.date() < n.date()) return -t(n, e);
|
|
||||||
var r = 12 * (n.year() - e.year()) + (n.month() - e.month()), i = e.clone().add(r, c), s = n - i < 0, u = e.clone().add(r + (s ? -1 : 1), c);
|
|
||||||
return +(-(r + (n - i) / (s ? i - u : u - i)) || 0);
|
|
||||||
},
|
|
||||||
a: function(t) {
|
|
||||||
return t < 0 ? Math.ceil(t) || 0 : Math.floor(t);
|
|
||||||
},
|
|
||||||
p: function(t) {
|
|
||||||
return {
|
|
||||||
M: c,
|
|
||||||
y: h,
|
|
||||||
w: o,
|
|
||||||
d: a,
|
|
||||||
D: d,
|
|
||||||
h: u,
|
|
||||||
m: s,
|
|
||||||
s: i,
|
|
||||||
ms: r,
|
|
||||||
Q: f
|
|
||||||
}[t] || String(t || "").toLowerCase().replace(/s$/, "");
|
|
||||||
},
|
|
||||||
u: function(t) {
|
|
||||||
return void 0 === t;
|
|
||||||
}
|
|
||||||
}, g = "en", D = {};
|
|
||||||
D[g] = M;
|
|
||||||
var p = "$isDayjsObject", S = function(t) {
|
|
||||||
return t instanceof _ || !(!t || !t[p]);
|
|
||||||
}, w = function t(e, n, r) {
|
|
||||||
var i;
|
|
||||||
if (!e) return g;
|
|
||||||
if ("string" == typeof e) {
|
|
||||||
var s = e.toLowerCase();
|
|
||||||
D[s] && (i = s), n && (D[s] = n, i = s);
|
|
||||||
var u = e.split("-");
|
|
||||||
if (!i && u.length > 1) return t(u[0]);
|
|
||||||
} else {
|
|
||||||
var a = e.name;
|
|
||||||
D[a] = e, i = a;
|
|
||||||
}
|
|
||||||
return !r && i && (g = i), i || !r && g;
|
|
||||||
}, O = function(t, e) {
|
|
||||||
if (S(t)) return t.clone();
|
|
||||||
var n = "object" == typeof e ? e : {};
|
|
||||||
return n.date = t, n.args = arguments, new _(n);
|
|
||||||
}, b = v;
|
|
||||||
b.l = w, b.i = S, b.w = function(t, e) {
|
|
||||||
return O(t, {
|
|
||||||
locale: e.$L,
|
|
||||||
utc: e.$u,
|
|
||||||
x: e.$x,
|
|
||||||
$offset: e.$offset
|
|
||||||
});
|
|
||||||
};
|
|
||||||
var _ = function() {
|
|
||||||
function M(t) {
|
|
||||||
this.$L = w(t.locale, null, !0), this.parse(t), this.$x = this.$x || t.x || {}, this[p] = !0;
|
|
||||||
}
|
|
||||||
var m = M.prototype;
|
|
||||||
return m.parse = function(t) {
|
|
||||||
this.$d = function(t) {
|
|
||||||
var e = t.date, n = t.utc;
|
|
||||||
if (null === e) return /* @__PURE__ */ new Date(NaN);
|
|
||||||
if (b.u(e)) return /* @__PURE__ */ new Date();
|
|
||||||
if (e instanceof Date) return new Date(e);
|
|
||||||
if ("string" == typeof e && !/Z$/i.test(e)) {
|
|
||||||
var r = e.match($);
|
|
||||||
if (r) {
|
|
||||||
var i = r[2] - 1 || 0, s = (r[7] || "0").substring(0, 3);
|
|
||||||
return n ? new Date(Date.UTC(r[1], i, r[3] || 1, r[4] || 0, r[5] || 0, r[6] || 0, s)) : new Date(r[1], i, r[3] || 1, r[4] || 0, r[5] || 0, r[6] || 0, s);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return new Date(e);
|
|
||||||
}(t), this.init();
|
|
||||||
}, m.init = function() {
|
|
||||||
var t = this.$d;
|
|
||||||
this.$y = t.getFullYear(), this.$M = t.getMonth(), this.$D = t.getDate(), this.$W = t.getDay(), this.$H = t.getHours(), this.$m = t.getMinutes(), this.$s = t.getSeconds(), this.$ms = t.getMilliseconds();
|
|
||||||
}, m.$utils = function() {
|
|
||||||
return b;
|
|
||||||
}, m.isValid = function() {
|
|
||||||
return !(this.$d.toString() === l);
|
|
||||||
}, m.isSame = function(t, e) {
|
|
||||||
var n = O(t);
|
|
||||||
return this.startOf(e) <= n && n <= this.endOf(e);
|
|
||||||
}, m.isAfter = function(t, e) {
|
|
||||||
return O(t) < this.startOf(e);
|
|
||||||
}, m.isBefore = function(t, e) {
|
|
||||||
return this.endOf(e) < O(t);
|
|
||||||
}, m.$g = function(t, e, n) {
|
|
||||||
return b.u(t) ? this[e] : this.set(n, t);
|
|
||||||
}, m.unix = function() {
|
|
||||||
return Math.floor(this.valueOf() / 1e3);
|
|
||||||
}, m.valueOf = function() {
|
|
||||||
return this.$d.getTime();
|
|
||||||
}, m.startOf = function(t, e) {
|
|
||||||
var n = this, r = !!b.u(e) || e, f = b.p(t), l = function(t, e) {
|
|
||||||
var i = b.w(n.$u ? Date.UTC(n.$y, e, t) : new Date(n.$y, e, t), n);
|
|
||||||
return r ? i : i.endOf(a);
|
|
||||||
}, $ = function(t, e) {
|
|
||||||
return b.w(n.toDate()[t].apply(n.toDate("s"), (r ? [
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0
|
|
||||||
] : [
|
|
||||||
23,
|
|
||||||
59,
|
|
||||||
59,
|
|
||||||
999
|
|
||||||
]).slice(e)), n);
|
|
||||||
}, y = this.$W, M = this.$M, m = this.$D, v = "set" + (this.$u ? "UTC" : "");
|
|
||||||
switch (f) {
|
|
||||||
case h: return r ? l(1, 0) : l(31, 11);
|
|
||||||
case c: return r ? l(1, M) : l(0, M + 1);
|
|
||||||
case o:
|
|
||||||
var g = this.$locale().weekStart || 0, D = (y < g ? y + 7 : y) - g;
|
|
||||||
return l(r ? m - D : m + (6 - D), M);
|
|
||||||
case a:
|
|
||||||
case d: return $(v + "Hours", 0);
|
|
||||||
case u: return $(v + "Minutes", 1);
|
|
||||||
case s: return $(v + "Seconds", 2);
|
|
||||||
case i: return $(v + "Milliseconds", 3);
|
|
||||||
default: return this.clone();
|
|
||||||
}
|
|
||||||
}, m.endOf = function(t) {
|
|
||||||
return this.startOf(t, !1);
|
|
||||||
}, m.$set = function(t, e) {
|
|
||||||
var n, o = b.p(t), f = "set" + (this.$u ? "UTC" : ""), l = (n = {}, n[a] = f + "Date", n[d] = f + "Date", n[c] = f + "Month", n[h] = f + "FullYear", n[u] = f + "Hours", n[s] = f + "Minutes", n[i] = f + "Seconds", n[r] = f + "Milliseconds", n)[o], $ = o === a ? this.$D + (e - this.$W) : e;
|
|
||||||
if (o === c || o === h) {
|
|
||||||
var y = this.clone().set(d, 1);
|
|
||||||
y.$d[l]($), y.init(), this.$d = y.set(d, Math.min(this.$D, y.daysInMonth())).$d;
|
|
||||||
} else l && this.$d[l]($);
|
|
||||||
return this.init(), this;
|
|
||||||
}, m.set = function(t, e) {
|
|
||||||
return this.clone().$set(t, e);
|
|
||||||
}, m.get = function(t) {
|
|
||||||
return this[b.p(t)]();
|
|
||||||
}, m.add = function(r, f) {
|
|
||||||
var d, l = this;
|
|
||||||
r = Number(r);
|
|
||||||
var $ = b.p(f), y = function(t) {
|
|
||||||
var e = O(l);
|
|
||||||
return b.w(e.date(e.date() + Math.round(t * r)), l);
|
|
||||||
};
|
|
||||||
if ($ === c) return this.set(c, this.$M + r);
|
|
||||||
if ($ === h) return this.set(h, this.$y + r);
|
|
||||||
if ($ === a) return y(1);
|
|
||||||
if ($ === o) return y(7);
|
|
||||||
var M = (d = {}, d[s] = e, d[u] = n, d[i] = t, d)[$] || 1, m = this.$d.getTime() + r * M;
|
|
||||||
return b.w(m, this);
|
|
||||||
}, m.subtract = function(t, e) {
|
|
||||||
return this.add(-1 * t, e);
|
|
||||||
}, m.format = function(t) {
|
|
||||||
var e = this, n = this.$locale();
|
|
||||||
if (!this.isValid()) return n.invalidDate || l;
|
|
||||||
var r = t || "YYYY-MM-DDTHH:mm:ssZ", i = b.z(this), s = this.$H, u = this.$m, a = this.$M, o = n.weekdays, c = n.months, f = n.meridiem, h = function(t, n, i, s) {
|
|
||||||
return t && (t[n] || t(e, r)) || i[n].slice(0, s);
|
|
||||||
}, d = function(t) {
|
|
||||||
return b.s(s % 12 || 12, t, "0");
|
|
||||||
}, $ = f || function(t, e, n) {
|
|
||||||
var r = t < 12 ? "AM" : "PM";
|
|
||||||
return n ? r.toLowerCase() : r;
|
|
||||||
};
|
|
||||||
return r.replace(y, (function(t, r) {
|
|
||||||
return r || function(t) {
|
|
||||||
switch (t) {
|
|
||||||
case "YY": return String(e.$y).slice(-2);
|
|
||||||
case "YYYY": return b.s(e.$y, 4, "0");
|
|
||||||
case "M": return a + 1;
|
|
||||||
case "MM": return b.s(a + 1, 2, "0");
|
|
||||||
case "MMM": return h(n.monthsShort, a, c, 3);
|
|
||||||
case "MMMM": return h(c, a);
|
|
||||||
case "D": return e.$D;
|
|
||||||
case "DD": return b.s(e.$D, 2, "0");
|
|
||||||
case "d": return String(e.$W);
|
|
||||||
case "dd": return h(n.weekdaysMin, e.$W, o, 2);
|
|
||||||
case "ddd": return h(n.weekdaysShort, e.$W, o, 3);
|
|
||||||
case "dddd": return o[e.$W];
|
|
||||||
case "H": return String(s);
|
|
||||||
case "HH": return b.s(s, 2, "0");
|
|
||||||
case "h": return d(1);
|
|
||||||
case "hh": return d(2);
|
|
||||||
case "a": return $(s, u, !0);
|
|
||||||
case "A": return $(s, u, !1);
|
|
||||||
case "m": return String(u);
|
|
||||||
case "mm": return b.s(u, 2, "0");
|
|
||||||
case "s": return String(e.$s);
|
|
||||||
case "ss": return b.s(e.$s, 2, "0");
|
|
||||||
case "SSS": return b.s(e.$ms, 3, "0");
|
|
||||||
case "Z": return i;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}(t) || i.replace(":", "");
|
|
||||||
}));
|
|
||||||
}, m.utcOffset = function() {
|
|
||||||
return 15 * -Math.round(this.$d.getTimezoneOffset() / 15);
|
|
||||||
}, m.diff = function(r, d, l) {
|
|
||||||
var $, y = this, M = b.p(d), m = O(r), v = (m.utcOffset() - this.utcOffset()) * e, g = this - m, D = function() {
|
|
||||||
return b.m(y, m);
|
|
||||||
};
|
|
||||||
switch (M) {
|
|
||||||
case h:
|
|
||||||
$ = D() / 12;
|
|
||||||
break;
|
|
||||||
case c:
|
|
||||||
$ = D();
|
|
||||||
break;
|
|
||||||
case f:
|
|
||||||
$ = D() / 3;
|
|
||||||
break;
|
|
||||||
case o:
|
|
||||||
$ = (g - v) / 6048e5;
|
|
||||||
break;
|
|
||||||
case a:
|
|
||||||
$ = (g - v) / 864e5;
|
|
||||||
break;
|
|
||||||
case u:
|
|
||||||
$ = g / n;
|
|
||||||
break;
|
|
||||||
case s:
|
|
||||||
$ = g / e;
|
|
||||||
break;
|
|
||||||
case i:
|
|
||||||
$ = g / t;
|
|
||||||
break;
|
|
||||||
default: $ = g;
|
|
||||||
}
|
|
||||||
return l ? $ : b.a($);
|
|
||||||
}, m.daysInMonth = function() {
|
|
||||||
return this.endOf(c).$D;
|
|
||||||
}, m.$locale = function() {
|
|
||||||
return D[this.$L];
|
|
||||||
}, m.locale = function(t, e) {
|
|
||||||
if (!t) return this.$L;
|
|
||||||
var n = this.clone(), r = w(t, e, !0);
|
|
||||||
return r && (n.$L = r), n;
|
|
||||||
}, m.clone = function() {
|
|
||||||
return b.w(this.$d, this);
|
|
||||||
}, m.toDate = function() {
|
|
||||||
return new Date(this.valueOf());
|
|
||||||
}, m.toJSON = function() {
|
|
||||||
return this.isValid() ? this.toISOString() : null;
|
|
||||||
}, m.toISOString = function() {
|
|
||||||
return this.$d.toISOString();
|
|
||||||
}, m.toString = function() {
|
|
||||||
return this.$d.toUTCString();
|
|
||||||
}, M;
|
|
||||||
}(), k = _.prototype;
|
|
||||||
return O.prototype = k, [
|
|
||||||
["$ms", r],
|
|
||||||
["$s", i],
|
|
||||||
["$m", s],
|
|
||||||
["$H", u],
|
|
||||||
["$W", a],
|
|
||||||
["$M", c],
|
|
||||||
["$y", h],
|
|
||||||
["$D", d]
|
|
||||||
].forEach((function(t) {
|
|
||||||
k[t[1]] = function(e) {
|
|
||||||
return this.$g(e, t[0], t[1]);
|
|
||||||
};
|
|
||||||
})), O.extend = function(t, e) {
|
|
||||||
return t.$i || (t(e, _, O), t.$i = !0), O;
|
|
||||||
}, O.locale = w, O.isDayjs = S, O.unix = function(t) {
|
|
||||||
return O(1e3 * t);
|
|
||||||
}, O.en = D[g], O.Ls = D, O.p = {}, O;
|
|
||||||
}));
|
|
||||||
}));
|
|
||||||
//#endregion
|
|
||||||
export { require_dayjs_min as t };
|
|
||||||
File diff suppressed because it is too large
Load diff
File diff suppressed because it is too large
Load diff
|
|
@ -1,285 +0,0 @@
|
||||||
import { c as NodeResponse, s as NullProtoObj, u as FastURL } from "./h3+rou3+srvx.mjs";
|
|
||||||
//#region node_modules/h3-v2/dist/h3-Bz4OPZv_.mjs
|
|
||||||
function decodePathname(pathname) {
|
|
||||||
return decodeURI(pathname.includes("%25") ? pathname.replace(/%25/g, "%2525") : pathname);
|
|
||||||
}
|
|
||||||
var kEventNS = "h3.internal.event.";
|
|
||||||
var kEventRes = /* @__PURE__ */ Symbol.for(`${kEventNS}res`);
|
|
||||||
var kEventResHeaders = /* @__PURE__ */ Symbol.for(`${kEventNS}res.headers`);
|
|
||||||
var kEventResErrHeaders = /* @__PURE__ */ Symbol.for(`${kEventNS}res.err.headers`);
|
|
||||||
var H3Event = class {
|
|
||||||
app;
|
|
||||||
req;
|
|
||||||
url;
|
|
||||||
context;
|
|
||||||
static __is_event__ = true;
|
|
||||||
constructor(req, context, app) {
|
|
||||||
this.context = context || req.context || new NullProtoObj();
|
|
||||||
this.req = req;
|
|
||||||
this.app = app;
|
|
||||||
const _url = req._url;
|
|
||||||
const url = _url && _url instanceof URL ? _url : new FastURL(req.url);
|
|
||||||
if (url.pathname.includes("%")) url.pathname = decodePathname(url.pathname);
|
|
||||||
this.url = url;
|
|
||||||
}
|
|
||||||
get res() {
|
|
||||||
return this[kEventRes] ||= new H3EventResponse();
|
|
||||||
}
|
|
||||||
get runtime() {
|
|
||||||
return this.req.runtime;
|
|
||||||
}
|
|
||||||
waitUntil(promise) {
|
|
||||||
this.req.waitUntil?.(promise);
|
|
||||||
}
|
|
||||||
toString() {
|
|
||||||
return `[${this.req.method}] ${this.req.url}`;
|
|
||||||
}
|
|
||||||
toJSON() {
|
|
||||||
return this.toString();
|
|
||||||
}
|
|
||||||
get node() {
|
|
||||||
return this.req.runtime?.node;
|
|
||||||
}
|
|
||||||
get headers() {
|
|
||||||
return this.req.headers;
|
|
||||||
}
|
|
||||||
get path() {
|
|
||||||
return this.url.pathname + this.url.search;
|
|
||||||
}
|
|
||||||
get method() {
|
|
||||||
return this.req.method;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var H3EventResponse = class {
|
|
||||||
status;
|
|
||||||
statusText;
|
|
||||||
get headers() {
|
|
||||||
return this[kEventResHeaders] ||= new Headers();
|
|
||||||
}
|
|
||||||
get errHeaders() {
|
|
||||||
return this[kEventResErrHeaders] ||= new Headers();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
var DISALLOWED_STATUS_CHARS = /[^\u0009\u0020-\u007E]/g;
|
|
||||||
function sanitizeStatusMessage(statusMessage = "") {
|
|
||||||
return statusMessage.replace(DISALLOWED_STATUS_CHARS, "");
|
|
||||||
}
|
|
||||||
function sanitizeStatusCode(statusCode, defaultStatusCode = 200) {
|
|
||||||
if (!statusCode) return defaultStatusCode;
|
|
||||||
if (typeof statusCode === "string") statusCode = +statusCode;
|
|
||||||
if (statusCode < 100 || statusCode > 599) return defaultStatusCode;
|
|
||||||
return statusCode;
|
|
||||||
}
|
|
||||||
var HTTPError = class HTTPError extends Error {
|
|
||||||
get name() {
|
|
||||||
return "HTTPError";
|
|
||||||
}
|
|
||||||
status;
|
|
||||||
statusText;
|
|
||||||
headers;
|
|
||||||
cause;
|
|
||||||
data;
|
|
||||||
body;
|
|
||||||
unhandled;
|
|
||||||
static isError(input) {
|
|
||||||
return input instanceof Error && input?.name === "HTTPError";
|
|
||||||
}
|
|
||||||
static status(status, statusText, details) {
|
|
||||||
return new HTTPError({
|
|
||||||
...details,
|
|
||||||
statusText,
|
|
||||||
status
|
|
||||||
});
|
|
||||||
}
|
|
||||||
constructor(arg1, arg2) {
|
|
||||||
let messageInput;
|
|
||||||
let details;
|
|
||||||
if (typeof arg1 === "string") {
|
|
||||||
messageInput = arg1;
|
|
||||||
details = arg2;
|
|
||||||
} else details = arg1;
|
|
||||||
const status = sanitizeStatusCode(details?.status || details?.statusCode || (details?.cause)?.status || (details?.cause)?.statusCode, 500);
|
|
||||||
const statusText = sanitizeStatusMessage(details?.statusText || details?.statusMessage || (details?.cause)?.statusText || (details?.cause)?.statusMessage);
|
|
||||||
const message = messageInput || details?.message || (details?.cause)?.message || details?.statusText || details?.statusMessage || [
|
|
||||||
"HTTPError",
|
|
||||||
status,
|
|
||||||
statusText
|
|
||||||
].filter(Boolean).join(" ");
|
|
||||||
super(message, { cause: details });
|
|
||||||
this.cause = details;
|
|
||||||
this.status = status;
|
|
||||||
this.statusText = statusText || void 0;
|
|
||||||
const rawHeaders = details?.headers || (details?.cause)?.headers;
|
|
||||||
this.headers = rawHeaders ? new Headers(rawHeaders) : void 0;
|
|
||||||
this.unhandled = details?.unhandled ?? (details?.cause)?.unhandled ?? void 0;
|
|
||||||
this.data = details?.data;
|
|
||||||
this.body = details?.body;
|
|
||||||
}
|
|
||||||
get statusCode() {
|
|
||||||
return this.status;
|
|
||||||
}
|
|
||||||
get statusMessage() {
|
|
||||||
return this.statusText;
|
|
||||||
}
|
|
||||||
toJSON() {
|
|
||||||
const unhandled = this.unhandled;
|
|
||||||
return {
|
|
||||||
status: this.status,
|
|
||||||
statusText: this.statusText,
|
|
||||||
unhandled,
|
|
||||||
message: unhandled ? "HTTPError" : this.message,
|
|
||||||
data: unhandled ? void 0 : this.data,
|
|
||||||
...unhandled ? void 0 : this.body
|
|
||||||
};
|
|
||||||
}
|
|
||||||
};
|
|
||||||
function isJSONSerializable(value, _type) {
|
|
||||||
if (value === null || value === void 0) return true;
|
|
||||||
if (_type !== "object") return _type === "boolean" || _type === "number" || _type === "string";
|
|
||||||
if (typeof value.toJSON === "function") return true;
|
|
||||||
if (Array.isArray(value)) return true;
|
|
||||||
if (typeof value.pipe === "function" || typeof value.pipeTo === "function") return false;
|
|
||||||
if (value instanceof NullProtoObj) return true;
|
|
||||||
const proto = Object.getPrototypeOf(value);
|
|
||||||
return proto === Object.prototype || proto === null;
|
|
||||||
}
|
|
||||||
var kNotFound = /* @__PURE__ */ Symbol.for("h3.notFound");
|
|
||||||
var kHandled = /* @__PURE__ */ Symbol.for("h3.handled");
|
|
||||||
function toResponse(val, event, config = {}) {
|
|
||||||
if (typeof val?.then === "function") return (val.catch?.((error) => error) || Promise.resolve(val)).then((resolvedVal) => toResponse(resolvedVal, event, config));
|
|
||||||
const response = prepareResponse(val, event, config);
|
|
||||||
if (typeof response?.then === "function") return toResponse(response, event, config);
|
|
||||||
const { onResponse } = config;
|
|
||||||
return onResponse ? Promise.resolve(onResponse(response, event)).then(() => response) : response;
|
|
||||||
}
|
|
||||||
var HTTPResponse = class {
|
|
||||||
#headers;
|
|
||||||
#init;
|
|
||||||
body;
|
|
||||||
constructor(body, init) {
|
|
||||||
this.body = body;
|
|
||||||
this.#init = init;
|
|
||||||
}
|
|
||||||
get status() {
|
|
||||||
return this.#init?.status || 200;
|
|
||||||
}
|
|
||||||
get statusText() {
|
|
||||||
return this.#init?.statusText || "OK";
|
|
||||||
}
|
|
||||||
get headers() {
|
|
||||||
return this.#headers ||= new Headers(this.#init?.headers);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
function prepareResponse(val, event, config, nested) {
|
|
||||||
if (val === kHandled) return new NodeResponse(null);
|
|
||||||
if (val === kNotFound) val = new HTTPError({
|
|
||||||
status: 404,
|
|
||||||
message: `Cannot find any route matching [${event.req.method}] ${event.url}`
|
|
||||||
});
|
|
||||||
if (val && val instanceof Error) {
|
|
||||||
const isHTTPError = HTTPError.isError(val);
|
|
||||||
const error = isHTTPError ? val : new HTTPError(val);
|
|
||||||
if (!isHTTPError) {
|
|
||||||
error.unhandled = true;
|
|
||||||
if (val?.stack) error.stack = val.stack;
|
|
||||||
}
|
|
||||||
if (error.unhandled && !config.silent) console.error(error);
|
|
||||||
const { onError } = config;
|
|
||||||
const errHeaders = event[kEventRes]?.[kEventResErrHeaders];
|
|
||||||
return onError && !nested ? Promise.resolve(onError(error, event)).catch((error) => error).then((newVal) => prepareResponse(newVal ?? val, event, config, true)) : errorResponse(error, config.debug, errHeaders);
|
|
||||||
}
|
|
||||||
const preparedRes = event[kEventRes];
|
|
||||||
const preparedHeaders = preparedRes?.[kEventResHeaders];
|
|
||||||
event[kEventRes] = void 0;
|
|
||||||
if (!(val instanceof Response)) {
|
|
||||||
const res = prepareResponseBody(val, event, config);
|
|
||||||
const status = res.status || preparedRes?.status;
|
|
||||||
return new NodeResponse(nullBody(event.req.method, status) ? null : res.body, {
|
|
||||||
status,
|
|
||||||
statusText: res.statusText || preparedRes?.statusText,
|
|
||||||
headers: res.headers && preparedHeaders ? mergeHeaders$1(res.headers, preparedHeaders) : res.headers || preparedHeaders
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (!preparedHeaders || nested || !val.ok) return val;
|
|
||||||
try {
|
|
||||||
mergeHeaders$1(val.headers, preparedHeaders, val.headers);
|
|
||||||
return val;
|
|
||||||
} catch {
|
|
||||||
return new NodeResponse(nullBody(event.req.method, val.status) ? null : val.body, {
|
|
||||||
status: val.status,
|
|
||||||
statusText: val.statusText,
|
|
||||||
headers: mergeHeaders$1(val.headers, preparedHeaders)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
function mergeHeaders$1(base, overrides, target = new Headers(base)) {
|
|
||||||
for (const [name, value] of overrides) if (name === "set-cookie") target.append(name, value);
|
|
||||||
else target.set(name, value);
|
|
||||||
return target;
|
|
||||||
}
|
|
||||||
var frozen = (name) => (...args) => {
|
|
||||||
throw new Error(`Headers are frozen (${name} ${args.join(", ")})`);
|
|
||||||
};
|
|
||||||
var FrozenHeaders = class extends Headers {
|
|
||||||
set = frozen("set");
|
|
||||||
append = frozen("append");
|
|
||||||
delete = frozen("delete");
|
|
||||||
};
|
|
||||||
var emptyHeaders = /* @__PURE__ */ new FrozenHeaders({ "content-length": "0" });
|
|
||||||
var jsonHeaders = /* @__PURE__ */ new FrozenHeaders({ "content-type": "application/json;charset=UTF-8" });
|
|
||||||
function prepareResponseBody(val, event, config) {
|
|
||||||
if (val === null || val === void 0) return {
|
|
||||||
body: "",
|
|
||||||
headers: emptyHeaders
|
|
||||||
};
|
|
||||||
const valType = typeof val;
|
|
||||||
if (valType === "string") return { body: val };
|
|
||||||
if (val instanceof Uint8Array) {
|
|
||||||
event.res.headers.set("content-length", val.byteLength.toString());
|
|
||||||
return { body: val };
|
|
||||||
}
|
|
||||||
if (val instanceof HTTPResponse || val?.constructor?.name === "HTTPResponse") return val;
|
|
||||||
if (isJSONSerializable(val, valType)) return {
|
|
||||||
body: JSON.stringify(val, void 0, config.debug ? 2 : void 0),
|
|
||||||
headers: jsonHeaders
|
|
||||||
};
|
|
||||||
if (valType === "bigint") return {
|
|
||||||
body: val.toString(),
|
|
||||||
headers: jsonHeaders
|
|
||||||
};
|
|
||||||
if (val instanceof Blob) {
|
|
||||||
const headers = new Headers({
|
|
||||||
"content-type": val.type,
|
|
||||||
"content-length": val.size.toString()
|
|
||||||
});
|
|
||||||
let filename = val.name;
|
|
||||||
if (filename) {
|
|
||||||
filename = encodeURIComponent(filename);
|
|
||||||
headers.set("content-disposition", `filename="${filename}"; filename*=UTF-8''${filename}`);
|
|
||||||
}
|
|
||||||
return {
|
|
||||||
body: val.stream(),
|
|
||||||
headers
|
|
||||||
};
|
|
||||||
}
|
|
||||||
if (valType === "symbol") return { body: val.toString() };
|
|
||||||
if (valType === "function") return { body: `${val.name}()` };
|
|
||||||
return { body: val };
|
|
||||||
}
|
|
||||||
function nullBody(method, status) {
|
|
||||||
return method === "HEAD" || status === 100 || status === 101 || status === 102 || status === 204 || status === 205 || status === 304;
|
|
||||||
}
|
|
||||||
function errorResponse(error, debug, errHeaders) {
|
|
||||||
let headers = error.headers ? mergeHeaders$1(jsonHeaders, error.headers) : new Headers(jsonHeaders);
|
|
||||||
if (errHeaders) headers = mergeHeaders$1(headers, errHeaders);
|
|
||||||
return new NodeResponse(JSON.stringify({
|
|
||||||
...error.toJSON(),
|
|
||||||
stack: debug && error.stack ? error.stack.split("\n").map((l) => l.trim()) : void 0
|
|
||||||
}, void 0, debug ? 2 : void 0), {
|
|
||||||
status: error.status,
|
|
||||||
statusText: error.statusText,
|
|
||||||
headers
|
|
||||||
});
|
|
||||||
}
|
|
||||||
//#endregion
|
|
||||||
export { toResponse as n, H3Event as t };
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue