enh
This commit is contained in:
parent
496faffe0a
commit
fbbda2fe58
7 changed files with 144 additions and 21 deletions
|
|
@ -38,6 +38,7 @@ interface Product {
|
||||||
productTags: string[]
|
productTags: string[]
|
||||||
productType: string
|
productType: string
|
||||||
isComboOnly: boolean
|
isComboOnly: boolean
|
||||||
|
isOffer: boolean
|
||||||
comboItems: Array<{
|
comboItems: Array<{
|
||||||
skuId: number
|
skuId: number
|
||||||
skuName: string | null
|
skuName: string | null
|
||||||
|
|
@ -287,6 +288,7 @@ export async function getAllProducts(): Promise<Product[]> {
|
||||||
productTags: productTags,
|
productTags: productTags,
|
||||||
productType: product.productType || 'item',
|
productType: product.productType || 'item',
|
||||||
isComboOnly: product.isComboOnly,
|
isComboOnly: product.isComboOnly,
|
||||||
|
isOffer: product.isOffer,
|
||||||
comboItems: comboItems,
|
comboItems: comboItems,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,6 +58,7 @@ export async function scaffoldProducts() {
|
||||||
images: product.images,
|
images: product.images,
|
||||||
productType: product.productType || 'item',
|
productType: product.productType || 'item',
|
||||||
isComboOnly: product.isComboOnly,
|
isComboOnly: product.isComboOnly,
|
||||||
|
isOffer: product.isOffer,
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ import {
|
||||||
} from "common-ui";
|
} from "common-ui";
|
||||||
import MaterialIcons from "@expo/vector-icons/MaterialIcons";
|
import MaterialIcons from "@expo/vector-icons/MaterialIcons";
|
||||||
import ProductCard from "@/components/ProductCard";
|
import ProductCard from "@/components/ProductCard";
|
||||||
import { trpc } from "@/src/trpc-client";
|
import { useAllProducts } from "@/src/hooks/prominent-api-hooks";
|
||||||
import FloatingCartBar from "@/components/floating-cart-bar";
|
import FloatingCartBar from "@/components/floating-cart-bar";
|
||||||
import TabLayoutWrapper from "@/components/TabLayoutWrapper";
|
import TabLayoutWrapper from "@/components/TabLayoutWrapper";
|
||||||
|
|
||||||
|
|
@ -97,11 +97,11 @@ export default function Offers() {
|
||||||
const [expandedOffers, setExpandedOffers] = useState(false);
|
const [expandedOffers, setExpandedOffers] = useState(false);
|
||||||
const [expandedCombos, setExpandedCombos] = useState(false);
|
const [expandedCombos, setExpandedCombos] = useState(false);
|
||||||
|
|
||||||
const { data, isLoading, error, refetch } =
|
const { data, isLoading, error, refetch } = useAllProducts();
|
||||||
trpc.user.product.getOffersPage.useQuery();
|
|
||||||
|
|
||||||
const combos = data?.combos || [];
|
const allProducts = data?.products || [];
|
||||||
const offers = data?.offers || [];
|
const combos = allProducts.filter((p) => p.productType === 'combo');
|
||||||
|
const offers = allProducts.filter((p) => p.isOffer);
|
||||||
|
|
||||||
useManualRefresh(() => {
|
useManualRefresh(() => {
|
||||||
refetch();
|
refetch();
|
||||||
|
|
|
||||||
|
|
@ -60,11 +60,11 @@ export default function Layout() {
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Tabs.Screen
|
<Tabs.Screen
|
||||||
name="(tabs)/stores"
|
name="(tabs)/order-again"
|
||||||
options={{
|
options={{
|
||||||
tabBarLabel: 'Stores',
|
tabBarLabel: 'Offers',
|
||||||
tabBarIcon: ({ color, size, focused }) => (
|
tabBarIcon: ({ color, size, focused }) => (
|
||||||
<StoresIcon focused={focused} size={size} color={color} />
|
<OffersIcon focused={focused} size={size} color={color} />
|
||||||
),
|
),
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
@ -95,11 +95,11 @@ export default function Layout() {
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
<Tabs.Screen
|
<Tabs.Screen
|
||||||
name="(tabs)/order-again"
|
name="(tabs)/stores"
|
||||||
options={{
|
options={{
|
||||||
tabBarLabel: 'Offers',
|
tabBarLabel: 'Stores',
|
||||||
tabBarIcon: ({ color, size, focused }) => (
|
tabBarIcon: ({ color, size, focused }) => (
|
||||||
<OffersIcon focused={focused} size={size} color={color} />
|
<StoresIcon focused={focused} size={size} color={color} />
|
||||||
),
|
),
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
|
||||||
|
|
@ -460,17 +460,40 @@ export default function CartPage({ isFlashDelivery = false }: CartPageProps) {
|
||||||
<View key={item.id}>
|
<View key={item.id}>
|
||||||
<View style={tw`p-4`}>
|
<View style={tw`p-4`}>
|
||||||
<View style={tw`flex-row items-center mb-2`}>
|
<View style={tw`flex-row items-center mb-2`}>
|
||||||
<Image
|
<MyTouchableOpacity
|
||||||
source={{ uri: product?.images?.[0] }}
|
onPress={() =>
|
||||||
style={tw`w-8 h-8 rounded-lg bg-gray-100 mr-3`}
|
router.push(
|
||||||
/>
|
isFlashDelivery
|
||||||
|
? `/(drawer)/(tabs)/flash-delivery/product-detail/${item.skuId}` as any
|
||||||
<MyText
|
: `/(drawer)/(tabs)/home/product-detail/${item.skuId}` as any
|
||||||
style={tw`text-sm text-gray-900 flex-1 mr-3`}
|
)
|
||||||
numberOfLines={2}
|
}
|
||||||
|
activeOpacity={0.7}
|
||||||
>
|
>
|
||||||
{product?.name}
|
<Image
|
||||||
</MyText>
|
source={{ uri: product?.images?.[0] }}
|
||||||
|
style={tw`w-8 h-8 rounded-lg bg-gray-100 mr-3`}
|
||||||
|
/>
|
||||||
|
</MyTouchableOpacity>
|
||||||
|
|
||||||
|
<MyTouchableOpacity
|
||||||
|
onPress={() =>
|
||||||
|
router.push(
|
||||||
|
isFlashDelivery
|
||||||
|
? `/(drawer)/(tabs)/flash-delivery/product-detail/${item.skuId}` as any
|
||||||
|
: `/(drawer)/(tabs)/home/product-detail/${item.skuId}` as any
|
||||||
|
)
|
||||||
|
}
|
||||||
|
activeOpacity={0.7}
|
||||||
|
style={tw`flex-1 mr-3`}
|
||||||
|
>
|
||||||
|
<MyText
|
||||||
|
style={tw`text-sm text-gray-900`}
|
||||||
|
numberOfLines={2}
|
||||||
|
>
|
||||||
|
{product?.name}
|
||||||
|
</MyText>
|
||||||
|
</MyTouchableOpacity>
|
||||||
<MyText style={tw`text-xs text-gray-500 mr-2`}>
|
<MyText style={tw`text-xs text-gray-500 mr-2`}>
|
||||||
{product?.productType !== 'combo' ? (product?.unitNotation || '') : ''}
|
{product?.productType !== 'combo' ? (product?.unitNotation || '') : ''}
|
||||||
</MyText>
|
</MyText>
|
||||||
|
|
|
||||||
|
|
@ -61,6 +61,7 @@ export interface ProductBasicData {
|
||||||
flashPrice: string | null
|
flashPrice: string | null
|
||||||
productType: string
|
productType: string
|
||||||
isComboOnly: boolean
|
isComboOnly: boolean
|
||||||
|
isOffer: boolean
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AvailabilityCacheData {
|
export interface AvailabilityCacheData {
|
||||||
|
|
@ -150,6 +151,7 @@ export async function getAllProductsForCache(): Promise<ProductBasicData[]> {
|
||||||
flashPrice: marketStats?.flashPrice ? String(marketStats.flashPrice) : null,
|
flashPrice: marketStats?.flashPrice ? String(marketStats.flashPrice) : null,
|
||||||
productType: sku.product?.productType ?? 'item',
|
productType: sku.product?.productType ?? 'item',
|
||||||
isComboOnly: sku.isComboOnly ?? false,
|
isComboOnly: sku.isComboOnly ?? false,
|
||||||
|
isOffer: sku.isOffer ?? false,
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
|
||||||
95
scripts/clear-db-old.sql
Normal file
95
scripts/clear-db-old.sql
Normal file
|
|
@ -0,0 +1,95 @@
|
||||||
|
-- ============================================================
|
||||||
|
-- clear-db-old.sql — DROP ALL TABLES of the PRE-SKU-SPLIT database
|
||||||
|
--
|
||||||
|
-- This targets a database migrated only up to:
|
||||||
|
-- 0000_nifty_sauron.sql
|
||||||
|
-- 0001_migrate_product_slots.sql
|
||||||
|
-- (i.e. 0002_sku_split.sql has NOT been applied)
|
||||||
|
--
|
||||||
|
-- In this state there are NO product_skus / sku_features /
|
||||||
|
-- product_market_stats / product_combos tables, and product_slots
|
||||||
|
-- has already been dropped by 0001 (hence its IF EXISTS below).
|
||||||
|
--
|
||||||
|
-- Usage:
|
||||||
|
-- sqlite3 <your.db> < scripts/clear-db-old.sql
|
||||||
|
-- wrangler d1 execute <db-name> --local --file scripts/clear-db-old.sql
|
||||||
|
-- wrangler d1 execute <db-name> --remote --file scripts/clear-db-old.sql
|
||||||
|
--
|
||||||
|
-- WARNING: This DROPS every table in the database. There is no undo.
|
||||||
|
-- ============================================================
|
||||||
|
|
||||||
|
-- Don't enforce FK constraints while dropping (ordering below is
|
||||||
|
-- child-first anyway, so this is belt-and-braces).
|
||||||
|
PRAGMA defer_foreign_keys = on;
|
||||||
|
PRAGMA foreign_keys = OFF;
|
||||||
|
|
||||||
|
-- ---- leaf tables (no inbound references) ----
|
||||||
|
DROP TABLE IF EXISTS order_items;
|
||||||
|
DROP TABLE IF EXISTS cart_items;
|
||||||
|
DROP TABLE IF EXISTS special_deals;
|
||||||
|
DROP TABLE IF EXISTS coupon_applicable_products;
|
||||||
|
DROP TABLE IF EXISTS product_reviews;
|
||||||
|
DROP TABLE IF EXISTS product_tags;
|
||||||
|
DROP TABLE IF EXISTS product_group_membership;
|
||||||
|
|
||||||
|
-- ---- product hierarchy (old flat product_info) ----
|
||||||
|
DROP TABLE IF EXISTS product_slots;
|
||||||
|
DROP TABLE IF EXISTS product_info;
|
||||||
|
DROP TABLE IF EXISTS store_info;
|
||||||
|
|
||||||
|
-- ---- orders & dependents ----
|
||||||
|
DROP TABLE IF EXISTS coupon_usage;
|
||||||
|
DROP TABLE IF EXISTS order_status;
|
||||||
|
DROP TABLE IF EXISTS payments;
|
||||||
|
DROP TABLE IF EXISTS refunds;
|
||||||
|
DROP TABLE IF EXISTS complaints;
|
||||||
|
DROP TABLE IF EXISTS user_incidents;
|
||||||
|
DROP TABLE IF EXISTS orders;
|
||||||
|
DROP TABLE IF EXISTS payment_info;
|
||||||
|
DROP TABLE IF EXISTS coupon_applicable_users;
|
||||||
|
|
||||||
|
-- ---- coupons & snippets ----
|
||||||
|
DROP TABLE IF EXISTS coupons;
|
||||||
|
DROP TABLE IF EXISTS reserved_coupons;
|
||||||
|
DROP TABLE IF EXISTS vendor_snippets;
|
||||||
|
DROP TABLE IF EXISTS delivery_slot_info;
|
||||||
|
|
||||||
|
-- ---- content/catalog ----
|
||||||
|
DROP TABLE IF EXISTS home_banners;
|
||||||
|
DROP TABLE IF EXISTS product_group_info;
|
||||||
|
DROP TABLE IF EXISTS product_tag_info;
|
||||||
|
DROP TABLE IF EXISTS product_categories;
|
||||||
|
DROP TABLE IF EXISTS units;
|
||||||
|
DROP TABLE IF EXISTS upload_url_status;
|
||||||
|
|
||||||
|
-- ---- notifications / misc ----
|
||||||
|
DROP TABLE IF EXISTS user_notifications;
|
||||||
|
DROP TABLE IF EXISTS notifications;
|
||||||
|
DROP TABLE IF EXISTS notif_creds;
|
||||||
|
DROP TABLE IF EXISTS key_val_store;
|
||||||
|
|
||||||
|
-- ---- addresses ----
|
||||||
|
DROP TABLE IF EXISTS addresses;
|
||||||
|
DROP TABLE IF EXISTS address_areas;
|
||||||
|
DROP TABLE IF EXISTS address_zones;
|
||||||
|
|
||||||
|
-- ---- users ----
|
||||||
|
DROP TABLE IF EXISTS unlogged_user_tokens;
|
||||||
|
DROP TABLE IF EXISTS user_creds;
|
||||||
|
DROP TABLE IF EXISTS user_details;
|
||||||
|
DROP TABLE IF EXISTS users;
|
||||||
|
|
||||||
|
-- ---- staff ----
|
||||||
|
DROP TABLE IF EXISTS staff_role_permissions;
|
||||||
|
DROP TABLE IF EXISTS staff_users;
|
||||||
|
DROP TABLE IF EXISTS staff_roles;
|
||||||
|
DROP TABLE IF EXISTS staff_permissions;
|
||||||
|
|
||||||
|
-- (sqlite_sequence is internal; SQLite drops it automatically once the last
|
||||||
|
-- AUTOINCREMENT table is gone)
|
||||||
|
|
||||||
|
PRAGMA foreign_keys = ON;
|
||||||
|
PRAGMA defer_foreign_keys = off;
|
||||||
|
|
||||||
|
-- Optionally reclaim disk space (sqlite3 CLI only; not supported in D1):
|
||||||
|
-- VACUUM;
|
||||||
Loading…
Add table
Reference in a new issue