import React from 'react'; import superagent from 'superagent'; import cookie, { load } from 'react-cookies'; import constants, { DEFAULT_TIMEZONE } from '../CloudApi/Constants.js'; import { Segment, Form, Button, Icon, Pagination, Label, FormField, Grid, List, Header } from 'semantic-ui-react'; import { DateInput } from 'semantic-ui-calendar-react'; import * as ApiUtils from '../CloudApi/ApiUtils.js'; // Universal-Fit Light Seal (Halo Strap Substitute) variant ID // Note: All variant selections use exactShopifyVariantIds in the query string const UNIVERSAL_FIT_LIGHT_SEAL_PRODUCT_ID = "9131615977689"; const UNIVERSAL_FIT_LIGHT_SEAL_VARIANT_ID = "2222222222222"; const RECENTS_STORAGE_KEY = "bigorders_query_recents"; const MAX_RECENTS = 5; export default class BigOrdersQueryEnhanced extends React.Component { constructor(props) { super(props); this.state = { query: { origin: "Shopify" }, limit: props.limit || 50, offset: 0, loading: true, recents: [] }; } loadRecentsFromStorage() { try { const stored = localStorage.getItem(RECENTS_STORAGE_KEY); if (stored) { return JSON.parse(stored); } } catch (e) { console.log("Error loading recents from storage:", e); } return []; } saveRecentsToStorage(recents) { try { localStorage.setItem(RECENTS_STORAGE_KEY, JSON.stringify(recents)); } catch (e) { console.log("Error saving recents to storage:", e); } } getVariantNamesForIds(variantIds, shopifySchemas) { if (!variantIds || !shopifySchemas) return []; const allVariants = shopifySchemas.productVariants; return variantIds.map(id => { if (id === UNIVERSAL_FIT_LIGHT_SEAL_VARIANT_ID) { return "Universal-Fit Light Seal"; } const variant = allVariants.find(v => v.value === id); return variant ? variant.text : id; }); } generateRecentName(variantIds, shopifySchemas) { const names = this.getVariantNamesForIds(variantIds, shopifySchemas); if (names.length === 0) return "Empty selection"; if (names.length === 1) return names[0]; if (names.length === 2) return names.join(" & "); return `${names[0]} + ${names.length - 1} more`; } addToRecents(variantIds) { if (!variantIds || variantIds.length === 0) return; const name = this.generateRecentName(variantIds, this.state.shopifySchemas); const newRecent = { id: Date.now(), name, variantIds: [...variantIds], timestamp: new Date().toISOString() }; let recents = this.state.recents.filter(r => JSON.stringify(r.variantIds.sort()) !== JSON.stringify([...variantIds].sort()) ); recents.unshift(newRecent); recents = recents.slice(0, MAX_RECENTS); this.setState({ recents }); this.saveRecentsToStorage(recents); } removeFromRecents(recentId) { const recents = this.state.recents.filter(r => r.id !== recentId); this.setState({ recents }); this.saveRecentsToStorage(recents); } loadRecentSelection(recent) { const query = { ...this.state.query }; query.exactShopifyVariantIds = [...recent.variantIds]; delete query.exactShopifyProductIds; this.setState({ query }, () => { this.executeQuery(); }); } async componentDidMount() { try { const shopifySchemas = await ApiUtils.getShopifySchemas(); const recents = this.loadRecentsFromStorage(); const params = new URLSearchParams(window.location.search); const query = {}; let hasVariantIds = false; let hasProductIds = false; for (const [key, value] of params.entries()) { if (key === "limit") { this.setState({ limit: value }); } else if (key === "offset") { this.setState({ offset: value }); } else if (key === "exactShopifyVariantIds") { query[key] = value.split(","); hasVariantIds = true; } else if (key === "exactShopifyProductIds") { query[key] = value.split(","); hasProductIds = true; } else { query[key] = value; } } // If we have variant IDs from URL, use them directly if (hasVariantIds && query.exactShopifyVariantIds) { // Already have variant IDs, no conversion needed delete query.exactShopifyProductIds; } else if (hasProductIds && query.exactShopifyProductIds && shopifySchemas) { // Backwards compatibility: convert product IDs to variant IDs for display const productIds = query.exactShopifyProductIds; const variantIds = []; // Check for Universal-Fit Light Seal if (productIds.includes(UNIVERSAL_FIT_LIGHT_SEAL_PRODUCT_ID)) { variantIds.push(UNIVERSAL_FIT_LIGHT_SEAL_VARIANT_ID); } // Find matching variants for other product IDs shopifySchemas.productVariants.forEach(variant => { if (variant.key) { const variantProductId = variant.key.split(':')[0]; if (productIds.includes(variantProductId) && !variantIds.includes(variant.value)) { variantIds.push(variant.value); } } }); if (variantIds.length > 0) { query.exactShopifyVariantIds = variantIds; } delete query.exactShopifyProductIds; } console.log(query); this.setState({ query, shopifySchemas, recents, loading: false }, () => { // Auto-execute query if we have product variants from URL // Skip adding to recents since URL-based queries may have inflated variant counts if (query.exactShopifyVariantIds && query.exactShopifyVariantIds.length > 0) { this.executeQuery({ skipRecents: true }); } }); } catch (e) { console.log(e); } } getUrlSearchParams() { const queryString = new URLSearchParams(); if (this.state.query) { for (const [key, value] of Object.entries(this.state.query)) { if (value === "" || value === null) continue; // Send variant IDs directly if (key === "exactShopifyVariantIds" && Array.isArray(value) && value.length > 0) { queryString.append("exactShopifyVariantIds", value.join(",")); } else if (key === "exactShopifyProductIds" && Array.isArray(value)) { // Handle exactShopifyProductIds from URL parsing if (value.length > 0) { queryString.append(key, value.join(",")); } } else if (Array.isArray(value)) { // Handle other array parameters if (value.length > 0) { queryString.append(key, value.join(",")); } } else { queryString.append(key, value); } } } queryString.append("limit", this.state.limit); if (this.props.offset) { queryString.append("offset", this.props.offset); } return queryString; } updateUrlWithoutQuery() { const params = this.getUrlSearchParams(); const newPathQuery = `${window.location.pathname}?${params.toString()}`; window.history.pushState(null, '', newPathQuery); } async executeQuery(options = {}) { const { skipRecents = false } = options; const selectedVariantIds = this.state.query.exactShopifyVariantIds || []; if (selectedVariantIds.length === 0) { return; } // Save to recents (unless skipped, e.g., on initial page load) if (!skipRecents) { this.addToRecents(selectedVariantIds); } // Update URL and execute query const params = this.getUrlSearchParams(); const newPathQuery = `${window.location.pathname}?${params.toString()}`; window.history.pushState(null, '', newPathQuery); await this.props.onQueryUpdated(params); } onChange(e, { name, value }) { const query = this.state.query; if (value === "" || value === null) { console.log("delete", name, value); delete query[name]; } else { if (name === "state" && value === ApiUtils.ANY_VALUE) { delete query["state"]; } else if (name === "shopifyMinCreatedAt") { console.log(ApiUtils.CovertDateTimeToShopify(value)); query["shopifyMinCreatedAt"] = ApiUtils.CovertDateTimeToShopify(value); } else if (name === "shopifyMaxCreatedAt") { console.log(ApiUtils.CovertDateTimeToShopify(value)); query["shopifyMaxCreatedAt"] = ApiUtils.CovertDateTimeToShopify(value); } else if (name === "exactShopifyVariantIds") { const currentVariantIds = query["exactShopifyVariantIds"] || []; if (currentVariantIds.includes(value)) { currentVariantIds.splice(currentVariantIds.indexOf(value), 1); } else { currentVariantIds.push(value); } query["exactShopifyVariantIds"] = currentVariantIds; } else { query[name] = value; } } // For variant changes, just update state without triggering query if (name === "exactShopifyVariantIds") { this.setState({ query }, () => { this.updateUrlWithoutQuery(); }); } else { // For other fields, update URL but don't auto-query this.setState({ query }, () => { this.updateUrlWithoutQuery(); }); } } onClearValue(e, { name, value }) { const query = this.state.query; query[name] = ""; this.setState({ query }, () => { this.updateUrlWithoutQuery(); }); } toggleProductVariant(variant) { // All variants (including Universal-Fit Light Seal) use exactShopifyVariantIds internally // The conversion to exactShopifyProductIds happens in getUrlSearchParams this.onChange(null, { name: "exactShopifyVariantIds", value: variant.value }); } clearAllVariants() { const query = this.state.query; delete query["exactShopifyVariantIds"]; delete query["exactShopifyProductIds"]; this.setState({ query }, () => { this.updateUrlWithoutQuery(); }); } render() { if (!this.props.schemas) return null; if (this.state.loading) { return false; } const selectedVariantIds = this.state.query.exactShopifyVariantIds || []; const canExecuteQuery = selectedVariantIds.length > 0; // Define product categories to show const allowedCategories = [ "Bigscreen Beyond 2", "Audio Strap", "Cushion", "Accessories", "Light Seal", "Lens", "Cover Shell", "Halo", "Storage Can" ]; // Filter variants to only show those matching allowed categories const filteredVariants = this.state.shopifySchemas ? this.state.shopifySchemas.productVariants.filter(variant => allowedCategories.some(category => variant.text.toLowerCase().includes(category.toLowerCase()) ) ) : []; // Add custom Universal-Fit Light Seal variant filteredVariants.push({ key: `${UNIVERSAL_FIT_LIGHT_SEAL_PRODUCT_ID}:${UNIVERSAL_FIT_LIGHT_SEAL_VARIANT_ID}`, text: "Universal-Fit Light Seal (Halo Strap Substitute)", value: UNIVERSAL_FIT_LIGHT_SEAL_VARIANT_ID }); return ( {/* Main Query Form */}
} value={this.state.query.shopifyOrderName} onChange={this.onChange.bind(this)} /> } value={this.state.query.minPriority} onChange={this.onChange.bind(this)} /> {/* Product Variant Buttons */}
{filteredVariants.map((variant) => { const isSelected = selectedVariantIds.includes(variant.value); return ( ); })}
{/* Selection info and actions */}
{selectedVariantIds.length > 0 && ( )}
{/* Recents Sidebar */}
Recent Queries
{this.state.recents.length === 0 ? (

No recent queries

) : ( {this.state.recents.map(recent => ( this.removeFromRecents(recent.id)} title="Remove" /> this.loadRecentSelection(recent)} style={{ fontSize: '0.9em' }} > {recent.name} {recent.variantIds.length} variant{recent.variantIds.length !== 1 ? 's' : ''} ))} )}
); } }