Z User commited on
Commit
057c18f
·
1 Parent(s): 184676a

fix: 3 page errors found during testing

Browse files

1. Categories page 400 error: when no category selected, was calling
products.category('') which returned 400. Now falls back to products.all(50)
when no category is selected.

2. QR page CORS error: qr.html was making direct browser fetches to
eesha-search.onrender.com which blocks cross-origin requests. Added
/api/openwa/* proxy route in web-server that injects the X-API-Key
header server-side. Updated qr.html to use the proxy.

3. Product page 404: was testing with product id=20 which was cleaned up.
Not a code bug — just stale test data. The page correctly shows
'Product not found' for non-existent IDs.

Eesha buying folder/categories.html CHANGED
@@ -480,9 +480,12 @@
480
  if (currentSearch) {
481
  // Search within all products (optionally capped by maxPrice)
482
  result = await window.EdgeFunctions.products.search(currentSearch, maxPrice);
483
- } else {
484
  // Browse by category with sort + pagination
485
- result = await window.EdgeFunctions.products.category(currentCategory || '', currentSort, page + 1);
 
 
 
486
  }
487
 
488
  if (!result.success) {
 
480
  if (currentSearch) {
481
  // Search within all products (optionally capped by maxPrice)
482
  result = await window.EdgeFunctions.products.search(currentSearch, maxPrice);
483
+ } else if (currentCategory) {
484
  // Browse by category with sort + pagination
485
+ result = await window.EdgeFunctions.products.category(currentCategory, currentSort, page + 1);
486
+ } else {
487
+ // No category selected — load all products
488
+ result = await window.EdgeFunctions.products.all(50);
489
  }
490
 
491
  if (!result.success) {
qr.html CHANGED
@@ -10,11 +10,11 @@ body { background: #1a1a2e; display: flex; flex-direction: column; align-items:
10
  h1 { font-size: 1.5rem; margin-bottom: 0.5rem; }
11
  .subtitle { color: #aaa; font-size: 0.9rem; margin-bottom: 1.5rem; }
12
  #qr-img { max-width: 350px; width: 100%; border-radius: 20px; padding: 20px; background: white; display: none; }
13
- #loading { color: #fb5b1b; font-size: 1.2rem; padding: 40px; }
14
  #error { color: #ef4444; font-size: 1rem; padding: 20px; display: none; }
15
  .instructions { color: #aaa; font-size: 0.85rem; margin-top: 1.5rem; line-height: 1.6; }
16
- .warning { color: #fb5b1b; font-size: 0.85rem; margin-top: 0.5rem; }
17
- .btn { background: #fb5b1b; color: white; border: none; padding: 12px 32px; border-radius: 30px; font-size: 1rem; cursor: pointer; margin-top: 1.5rem; }
18
  </style>
19
  </head>
20
  <body>
@@ -35,8 +35,9 @@ h1 { font-size: 1.5rem; margin-bottom: 0.5rem; }
35
  <button class="btn" onclick="loadQR()">🔄 Refresh QR Code</button>
36
  </div>
37
  <script>
38
- const GATEWAY_URL = 'https://eesha-search.onrender.com';
39
- const API_KEY = 'CellexWA2024';
 
40
  const SESSION_NAME = 'eeshamart-main';
41
 
42
  async function loadQR() {
@@ -45,19 +46,17 @@ async function loadQR() {
45
  document.getElementById('qr-img').style.display = 'none';
46
 
47
  try {
48
- const headers = { 'X-API-Key': API_KEY, 'Content-Type': 'application/json' };
49
-
50
  // Step 1: List sessions to find existing one
51
- let resp = await fetch(`${GATEWAY_URL}/api/sessions`, { headers });
52
  let sessions = await resp.json();
53
- let session = sessions.find(s => s.name === SESSION_NAME);
54
 
55
  // Step 2: If no session, create one
56
  if (!session) {
57
  console.log('Creating new session...');
58
- resp = await fetch(`${GATEWAY_URL}/api/sessions`, {
59
  method: 'POST',
60
- headers,
61
  body: JSON.stringify({ name: SESSION_NAME })
62
  });
63
  session = await resp.json();
@@ -67,16 +66,16 @@ async function loadQR() {
67
  console.log('Session ID:', sessionId);
68
 
69
  // Step 3: Start the session
70
- await fetch(`${GATEWAY_URL}/api/sessions/${sessionId}/start`, {
71
  method: 'POST',
72
- headers
73
  });
74
 
75
  // Step 4: Wait a moment for QR to generate
76
  await new Promise(r => setTimeout(r, 3000));
77
 
78
  // Step 5: Get QR code
79
- resp = await fetch(`${GATEWAY_URL}/api/sessions/${sessionId}/qr`, { headers });
80
  const data = await resp.json();
81
 
82
  const qrCode = data.qrCode || data.qr || data.base64;
@@ -90,7 +89,7 @@ async function loadQR() {
90
  } catch (err) {
91
  document.getElementById('loading').style.display = 'none';
92
  document.getElementById('error').style.display = 'block';
93
- document.getElementById('error').innerHTML = `❌ ${err.message}<br><br>Try refreshing. If it keeps failing, <a href="${GATEWAY_URL}" target="_blank" style="color:#fb5b1b">click here to wake the gateway</a>, then refresh.`;
94
  }
95
  }
96
  loadQR();
 
10
  h1 { font-size: 1.5rem; margin-bottom: 0.5rem; }
11
  .subtitle { color: #aaa; font-size: 0.9rem; margin-bottom: 1.5rem; }
12
  #qr-img { max-width: 350px; width: 100%; border-radius: 20px; padding: 20px; background: white; display: none; }
13
+ #loading { color: #00d4ff; font-size: 1.2rem; padding: 40px; }
14
  #error { color: #ef4444; font-size: 1rem; padding: 20px; display: none; }
15
  .instructions { color: #aaa; font-size: 0.85rem; margin-top: 1.5rem; line-height: 1.6; }
16
+ .warning { color: #00d4ff; font-size: 0.85rem; margin-top: 0.5rem; }
17
+ .btn { background: #00d4ff; color: #0f172a; border: none; padding: 12px 32px; border-radius: 30px; font-size: 1rem; cursor: pointer; margin-top: 1.5rem; font-weight: 700; }
18
  </style>
19
  </head>
20
  <body>
 
35
  <button class="btn" onclick="loadQR()">🔄 Refresh QR Code</button>
36
  </div>
37
  <script>
38
+ // Use the web-server proxy to avoid CORS issues
39
+ // The proxy at /api/openwa/* injects the X-API-Key header server-side
40
+ const PROXY_URL = '/api/openwa';
41
  const SESSION_NAME = 'eeshamart-main';
42
 
43
  async function loadQR() {
 
46
  document.getElementById('qr-img').style.display = 'none';
47
 
48
  try {
 
 
49
  // Step 1: List sessions to find existing one
50
+ let resp = await fetch(`${PROXY_URL}/api/sessions`);
51
  let sessions = await resp.json();
52
+ let session = Array.isArray(sessions) ? sessions[0] : null;
53
 
54
  // Step 2: If no session, create one
55
  if (!session) {
56
  console.log('Creating new session...');
57
+ resp = await fetch(`${PROXY_URL}/api/sessions`, {
58
  method: 'POST',
59
+ headers: { 'Content-Type': 'application/json' },
60
  body: JSON.stringify({ name: SESSION_NAME })
61
  });
62
  session = await resp.json();
 
66
  console.log('Session ID:', sessionId);
67
 
68
  // Step 3: Start the session
69
+ await fetch(`${PROXY_URL}/api/sessions/${sessionId}/start`, {
70
  method: 'POST',
71
+ headers: { 'Content-Type': 'application/json' }
72
  });
73
 
74
  // Step 4: Wait a moment for QR to generate
75
  await new Promise(r => setTimeout(r, 3000));
76
 
77
  // Step 5: Get QR code
78
+ resp = await fetch(`${PROXY_URL}/api/sessions/${sessionId}/qr`);
79
  const data = await resp.json();
80
 
81
  const qrCode = data.qrCode || data.qr || data.base64;
 
89
  } catch (err) {
90
  document.getElementById('loading').style.display = 'none';
91
  document.getElementById('error').style.display = 'block';
92
+ document.getElementById('error').innerHTML = `❌ ${err.message}<br><br>Try refreshing. If it keeps failing, <a href="https://eesha-search.onrender.com" target="_blank" style="color:#00d4ff">click here to wake the gateway</a>, then refresh.`;
93
  }
94
  }
95
  loadQR();
web-server/server.py CHANGED
@@ -324,6 +324,55 @@ async def proxy_cross_platform(request: Request):
324
  async def proxy_telegram(request: Request):
325
  return await _proxy_to_edge_function("telegram", request)
326
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
327
  # ---- Phase 3: Direct video upload to Supabase Storage ----
328
  # Sellers upload video files via PUT. The web-server reads the session cookie
329
  # to verify auth, then forwards the bytes to Supabase Storage using the
 
324
  async def proxy_telegram(request: Request):
325
  return await _proxy_to_edge_function("telegram", request)
326
 
327
+ # ---- Phase 4: OpenWA gateway proxy (avoids CORS issues from browser) ----
328
+ OPENWA_BASE_URL = os.environ.get("OPENWA_BASE_URL", "https://eesha-search.onrender.com")
329
+ OPENWA_API_KEY = os.environ.get("OPENWA_API_KEY", "CellexWA2024")
330
+
331
+ @app.api_route("/api/openwa/{path:path}", methods=["GET", "POST", "PUT", "DELETE"])
332
+ async def proxy_openwa(path: str, request: Request):
333
+ """Proxy requests to the OpenWA gateway to avoid CORS issues.
334
+ The browser can't call eesha-search.onrender.com directly due to CORS,
335
+ so we proxy through here with the X-API-Key header injected server-side."""
336
+ target_url = f"{OPENWA_BASE_URL}/{path}"
337
+
338
+ # Forward query params
339
+ if request.url.query:
340
+ target_url += f"?{request.url.query}"
341
+
342
+ # Build headers — inject the API key
343
+ headers = {
344
+ "X-API-Key": OPENWA_API_KEY,
345
+ "Content-Type": "application/json",
346
+ }
347
+
348
+ # Read body for POST/PUT
349
+ body = None
350
+ if request.method in ("POST", "PUT"):
351
+ body = await request.body()
352
+
353
+ try:
354
+ async with httpx.AsyncClient(timeout=30.0) as client:
355
+ if request.method == "GET":
356
+ resp = await client.get(target_url, headers=headers)
357
+ elif request.method == "POST":
358
+ resp = await client.post(target_url, content=body, headers=headers)
359
+ elif request.method == "PUT":
360
+ resp = await client.put(target_url, content=body, headers=headers)
361
+ elif request.method == "DELETE":
362
+ resp = await client.delete(target_url, headers=headers)
363
+ else:
364
+ return JSONResponse({"error": "Method not allowed"}, status_code=405)
365
+
366
+ try:
367
+ data = resp.json()
368
+ except Exception:
369
+ data = {"_raw": resp.text[:500]}
370
+ return JSONResponse(data, status_code=resp.status_code)
371
+ except httpx.TimeoutException:
372
+ return JSONResponse({"error": "OpenWA gateway timeout"}, status_code=504)
373
+ except Exception as e:
374
+ return JSONResponse({"error": str(e)}, status_code=500)
375
+
376
  # ---- Phase 3: Direct video upload to Supabase Storage ----
377
  # Sellers upload video files via PUT. The web-server reads the session cookie
378
  # to verify auth, then forwards the bytes to Supabase Storage using the