Initial commit - Route Commerce platform

This commit is contained in:
2026-06-01 19:40:55 +00:00
commit 53a9671461
617 changed files with 106132 additions and 0 deletions
+262
View File
@@ -0,0 +1,262 @@
/**
* import-woo-to-route.ts - 2026 Season Import
*
* Reads Tuxedo_Corn_2026_Tour_Schedule-2.xlsx (Full Tour Schedule sheet) and produces:
* products.csv - 1 core pickup product
* stops.csv - 164 active stops
*
* Usage:
* npx tsx scripts/import-woo-to-route.ts \
* --xlsx "/path/to/Tuxedo_Corn_2026_Tour_Schedule-2.xlsx" \
* --brand 64294306-5f42-463d-a5e8-2ad6c81a96de \
* --output ./import-output
*/
import * as fs from "fs";
import * as path from "path";
import { parseArgs } from "util";
import ExcelJS from "exceljs";
// Types
interface ProductOutput {
name: string;
price: number;
type: "Pickup" | "Shipping" | "Pickup & Shipping";
description: string;
active: boolean;
image_url: string;
is_taxable: boolean;
}
interface StopOutput {
city: string;
state: string;
location: string;
date: string;
time: string;
address: string;
notes: string;
}
function slugify(s: string): string {
return s
.toLowerCase()
.replace(/[^a-z0-9]+/g, "-")
.replace(/^-|-$/g, "");
}
async function main() {
const args = parseArgs({
options: {
xlsx: { type: "string" },
brand: { type: "string" },
output: { type: "string", default: "./import-output" },
},
});
const xlsxPath = args.values.xlsx as string;
const brandId = args.values.brand as string;
const outputDir = args.values.output as string;
if (!xlsxPath || !brandId) {
console.error(
"Usage: npx tsx scripts/import-woo-to-route.ts --xlsx <path> --brand <uuid> [--output <dir>]"
);
process.exit(1);
}
if (!fs.existsSync(xlsxPath)) {
console.error("File not found: " + xlsxPath);
process.exit(1);
}
// Read Excel
// Row 0=title, Row1=subtitle, Row2=color-key, Row3=column-headers, Row4+=data
const wb = new ExcelJS.Workbook();
await wb.xlsx.readFile(xlsxPath);
const sheet = wb.getWorksheet(1);
if (!sheet) {
console.error("No worksheet found in file");
process.exit(1);
}
const allRows: (string | null | undefined)[][] = [];
sheet.eachRow((row) => {
allRows.push(row.values as (string | null | undefined)[]);
});
const colHeaders = (allRows[3] as string[]).map((h: unknown) => String(h ?? "").trim());
console.log("Column headers:", colHeaders);
const ci = (col: string) => colHeaders.indexOf(col);
const wkIdx = ci("Wk"), typeIdx = ci("Type"), datesIdx = ci("Dates"), dayIdx = ci("Day");
const cityIdx = ci("City / Location"), hostIdx = ci("Host / Venue");
const timeIdx = ci("Time"), truckIdx = ci("Truck"), statusIdx = ci("Status"), notesIdx = ci("Notes");
interface ScheduleRow {
wk: number; type: string; dates: string; day: string;
city: string; host: string; time: string; truck: string; status: string; notes: string;
}
const scheduleRows: ScheduleRow[] = [];
let currentWeek: { wk: number; type: string; dates: string; day: string } | null = null;
for (let i = 4; i < allRows.length; i++) {
const row = allRows[i] as (string | null | undefined)[];
if (!row) continue;
const wkVal = row[wkIdx];
const Day = String(row[dayIdx] ?? "").trim();
const City_Location = String(row[cityIdx] ?? "").trim();
const Status = String(row[statusIdx] ?? "").trim();
if (wkVal !== null && wkVal !== undefined && String(wkVal).trim() !== "") {
currentWeek = {
wk: Number(wkVal),
type: String(row[typeIdx] ?? "").trim(),
dates: String(row[datesIdx] ?? "").trim(),
day: Day,
};
}
if (!currentWeek) continue;
if (Status === "Off day") continue;
if (!City_Location) continue;
scheduleRows.push({
wk: currentWeek.wk, type: currentWeek.type, dates: currentWeek.dates,
day: Day || currentWeek.day,
city: City_Location,
host: String(row[hostIdx] ?? "").trim(),
time: String(row[timeIdx] ?? "").trim(),
truck: String(row[truckIdx] ?? "").trim(),
status: Status,
notes: String(row[notesIdx] ?? "").trim(),
});
}
const ACTIVE_STATUSES = ["✓ Confirmed", "🔴 Pre-sale live"];
const activeRows = scheduleRows.filter((r) => ACTIVE_STATUSES.includes(r.status));
console.log("\nSchedule rows: " + scheduleRows.length + " total | " + activeRows.length + " active\n");
// PRODUCTS -- one core product for all stops
const products: ProductOutput[] = [
{
name: "Olathe Sweet Corn -- 24 Ear Box",
price: 25,
type: "Pickup",
description:
"Fresh Olathe Sweet Corn pickup box. Add to cart, then choose your pickup stop at checkout. " +
"Available July-September 2026 at stops across Colorado, Wyoming, and New Mexico. " +
"See tuxedocorn.com for full schedule.",
active: true,
image_url:
"https://tuxedocorn.com/wp-content/uploads/2024/06/110260317_3494904527187819_6983832261179080791_n-1.jpg",
is_taxable: true,
},
];
console.log("[products] 1 core product: \"" + products[0].name + "\" at $" + products[0].price + "\n");
// STOPS -- one row per active schedule entry
const stops: StopOutput[] = [];
const seenStopKeys = new Set<string>();
for (const row of activeRows) {
if (!row.city) continue;
// Parse "City ST" or "City, ST" -> city + state
const cityRaw = row.city.replace(/--/g, "-").trim();
let city = cityRaw, state = "CO";
if (cityRaw.includes(",")) {
const parts = cityRaw.split(",").map((s: string) => s.trim());
const lastPart = parts[parts.length - 1] ?? "";
if (/^[A-Z]{2}$/.test(lastPart)) { city = parts.slice(0, -1).join(", ").trim(); state = lastPart; }
else city = parts.join(", ");
} else {
const tokens = cityRaw.split(/\s+/);
const lastToken = tokens[tokens.length - 1] ?? "";
if (/^[A-Z]{2}$/.test(lastToken)) { state = lastToken; city = tokens.slice(0, -1).join(" "); }
}
const stopKey = slugify(city + "-" + state + "-" + row.dates + "-" + row.time);
if (seenStopKeys.has(stopKey)) continue;
seenStopKeys.add(stopKey);
// Human-readable stop label = "Store (Time) | Truck T1"
const stopName = row.host + " (" + row.time + ")" + (row.truck ? " | Truck " + row.truck : "");
stops.push({
city,
state,
location: stopName,
date: row.dates, // week range -- set actual date in /admin/stops after import
time: row.time,
address: row.city + " | " + row.host,
notes: row.day + (row.notes ? " | " + row.notes : ""),
});
}
console.log("[stops] " + stops.length + " stops written\n");
// Show sample by week
const byWeek: Record<string, typeof stops> = {};
for (const s of stops) {
if (!byWeek[s.date]) byWeek[s.date] = [];
byWeek[s.date].push(s);
}
const weeks = Object.keys(byWeek).slice(0, 4);
for (const week of weeks) {
const ws = byWeek[week];
console.log(" " + week + " (" + ws.length + " stops):");
for (const s of ws.slice(0, 3)) {
console.log(" " + s.city + ", " + s.state + " | \"" + s.location + "\" | " + s.time);
}
}
// Write output CSVs
fs.mkdirSync(outputDir, { recursive: true });
function writeCSV(filename: string, header: string, rows: string[][]) {
const lines = rows.map((r) =>
r.map((c) => "\"" + String(c ?? "").replace(/\"/g, "\"\"") + "\"").join(",")
);
fs.writeFileSync(path.join(outputDir, filename), header + lines.join("\n"));
}
writeCSV(
"products.csv",
"name,price,type,description,active,image_url,is_taxable\n",
products.map((p) => [
p.name, String(p.price), p.type, p.description,
String(p.active), p.image_url, String(p.is_taxable),
])
);
writeCSV(
"stops.csv",
"city,state,location,date,time,address,notes\n",
stops.map((s) => [s.city, s.state, s.location, s.date, s.time, s.address, s.notes])
);
// Summary
console.log("\n============================================================");
console.log("IMPORT READY");
console.log("============================================================");
console.log("\nproducts.csv: 1 product (\"" + products[0].name + "\" @ $" + products[0].price + " Pickup)");
console.log("stops.csv: " + stops.length + " stops (confirmed + pre-sale only)");
console.log("\nOutput: " + outputDir + "/");
console.log("");
console.log(">>> NOTE: stops.csv 'date' field is a WEEK RANGE (e.g. Jul 22-28).");
console.log("After importing stops, visit /admin/stops to set the actual date for each stop.");
console.log("");
console.log("NEXT STEPS:");
console.log(" 1. Upload " + outputDir + "/products.csv via /admin/import -> type: products");
console.log(" 2. Upload " + outputDir + "/stops.csv via /admin/import -> type: stops");
console.log(" 3. Visit /admin/stops -- set each stop's actual date, verify address/time");
console.log(" 4. Visit /tuxedo -- verify product and stops appear\n");
console.log("Re-run: npx tsx scripts/import-woo-to-route.ts --xlsx \"" + xlsxPath + "\" --brand " + brandId + " --output " + outputDir + "\n");
}
main().catch(console.error);
+343
View File
@@ -0,0 +1,343 @@
#!/bin/bash
# Seed script for Route Commerce Platform
# Run with: bash scripts/seed.sh
set -e
# Use service role key for write operations during seeding
SUPABASE_URL="${SUPABASE_URL:-https://your-project.supabase.co}"
SERVICE_KEY="${SUPABASE_SERVICE_ROLE_KEY}"
ANON_KEY="${ANON_KEY:-$NEXT_PUBLIC_SUPABASE_ANON_KEY}"
AUTH_HEADER="apikey: $SERVICE_KEY"
CONTENT_TYPE="Content-Type: application/json"
echo "Fetching brands..."
BRANDS=$(curl -s "$SUPABASE_URL/rest/v1/brands?select=id,name" \
-H "$AUTH_HEADER")
echo "Brands: $BRANDS"
TUXEDO_ID=$(echo "$BRANDS" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)
IRD_ID=$(echo "$BRANDS" | grep -o '"id":"[^"]*"' | tail -1 | cut -d'"' -f4)
echo "Tuxedo: $TUXEDO_ID"
echo "IRD: $IRD_ID"
echo ""
echo "Creating stops..."
STOP1=$(curl -s -X POST "$SUPABASE_URL/rest/v1/stops" \
-H "$AUTH_HEADER" \
-H "$CONTENT_TYPE" \
-H "Prefer: return=representation" \
-d '{
"brand_id": "'"$TUXEDO_ID"'",
"city": "Burlington",
"state": "NC",
"date": "2026-05-15",
"time": "8:00 AM 2:00 PM",
"location": "102 W Front St, Burlington, NC",
"slug": "burlington-nc-2026-05-15",
"active": true
}')
echo "Stop 1: $STOP1"
STOP2=$(curl -s -X POST "$SUPABASE_URL/rest/v1/stops" \
-H "$AUTH_HEADER" \
-H "$CONTENT_TYPE" \
-H "Prefer: return=representation" \
-d '{
"brand_id": "'"$TUXEDO_ID"'",
"city": "Greensboro",
"state": "NC",
"date": "2026-05-16",
"time": "8:00 AM 2:00 PM",
"location": "200 S Elm St, Greensboro, NC",
"slug": "greensboro-nc-2026-05-16",
"active": true
}')
echo "Stop 2: $STOP2"
STOP3=$(curl -s -X POST "$SUPABASE_URL/rest/v1/stops" \
-H "$AUTH_HEADER" \
-H "$CONTENT_TYPE" \
-H "Prefer: return=representation" \
-d '{
"brand_id": "'"$IRD_ID"'",
"city": "Fort Pierce",
"state": "FL",
"date": "2026-05-15",
"time": "7:00 AM 1:00 PM",
"location": "1224 N US-1, Fort Pierce, FL",
"slug": "fort-pierce-fl-2026-05-15",
"active": true
}')
echo "Stop 3: $STOP3"
echo ""
echo "Creating products..."
PROD1=$(curl -s -X POST "$SUPABASE_URL/rest/v1/products" \
-H "$AUTH_HEADER" \
-H "$CONTENT_TYPE" \
-H "Prefer: return=representation" \
-d '{
"brand_id": "'"$TUXEDO_ID"'",
"name": "Sweet Corn",
"description": "Fresh picked white sweet corn, 8 ears per bag",
"price": 12,
"type": "Sweet Corn",
"active": true
}')
echo "Prod 1: $PROD1"
PROD2=$(curl -s -X POST "$SUPABASE_URL/rest/v1/products" \
-H "$AUTH_HEADER" \
-H "$CONTENT_TYPE" \
-H "Prefer: return=representation" \
-d '{
"brand_id": "'"$TUXEDO_ID"'",
"name": "Peaches",
"description": "Just-peeled freestone peaches, pint jar",
"price": 8,
"type": "Fruit",
"active": true
}')
echo "Prod 2: $PROD2"
PROD3=$(curl -s -X POST "$SUPABASE_URL/rest/v1/products" \
-H "$AUTH_HEADER" \
-H "$CONTENT_TYPE" \
-H "Prefer: return=representation" \
-d '{
"brand_id": "'"$TUXEDO_ID"'",
"name": "Corn & Peach Bundle",
"description": "Sweet corn + peaches combo, save $2",
"price": 18,
"type": "Bundle",
"active": true
}')
echo "Prod 3: $PROD3"
PROD4=$(curl -s -X POST "$SUPABASE_URL/rest/v1/products" \
-H "$AUTH_HEADER" \
-H "$CONTENT_TYPE" \
-H "Prefer: return=representation" \
-d '{
"brand_id": "'"$IRD_ID"'",
"name": "Navel Oranges",
"description": "Premium navel oranges, 4 lb bag",
"price": 15,
"type": "Citrus",
"active": true
}')
echo "Prod 4: $PROD4"
PROD5=$(curl -s -X POST "$SUPABASE_URL/rest/v1/products" \
-H "$AUTH_HEADER" \
-H "$CONTENT_TYPE" \
-H "Prefer: return=representation" \
-d '{
"brand_id": "'"$IRD_ID"'",
"name": "Grapefruit",
"description": "Ruby red grapefruit, 3 lb bag",
"price": 12,
"type": "Citrus",
"active": true
}')
echo "Prod 5: $PROD5"
PROD6=$(curl -s -X POST "$SUPABASE_URL/rest/v1/products" \
-H "$AUTH_HEADER" \
-H "$CONTENT_TYPE" \
-H "Prefer: return=representation" \
-d '{
"brand_id": "'"$IRD_ID"'",
"name": "Citrus Sampler",
"description": "Oranges, grapefruit & tangelos, 6 lb mix",
"price": 22,
"type": "Bundle",
"active": true
}')
echo "Prod 6: $PROD6"
P1_ID=$(echo "$PROD1" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)
P2_ID=$(echo "$PROD2" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)
P3_ID=$(echo "$PROD3" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)
P4_ID=$(echo "$PROD4" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)
P5_ID=$(echo "$PROD5" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)
P6_ID=$(echo "$PROD6" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)
S1_ID=$(echo "$STOP1" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)
S2_ID=$(echo "$STOP2" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)
S3_ID=$(echo "$STOP3" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)
echo ""
echo "Assigning products to stops..."
curl -s -X POST "$SUPABASE_URL/rest/v1/product_stops" \
-H "$AUTH_HEADER" -H "$CONTENT_TYPE" \
-d '{"stop_id": "'"$S1_ID"'", "product_id": "'"$P1_ID"'"}' > /dev/null
curl -s -X POST "$SUPABASE_URL/rest/v1/product_stops" \
-H "$AUTH_HEADER" -H "$CONTENT_TYPE" \
-d '{"stop_id": "'"$S1_ID"'", "product_id": "'"$P2_ID"'"}' > /dev/null
curl -s -X POST "$SUPABASE_URL/rest/v1/product_stops" \
-H "$AUTH_HEADER" -H "$CONTENT_TYPE" \
-d '{"stop_id": "'"$S1_ID"'", "product_id": "'"$P3_ID"'"}' > /dev/null
curl -s -X POST "$SUPABASE_URL/rest/v1/product_stops" \
-H "$AUTH_HEADER" -H "$CONTENT_TYPE" \
-d '{"stop_id": "'"$S2_ID"'", "product_id": "'"$P1_ID"'"}' > /dev/null
curl -s -X POST "$SUPABASE_URL/rest/v1/product_stops" \
-H "$AUTH_HEADER" -H "$CONTENT_TYPE" \
-d '{"stop_id": "'"$S2_ID"'", "product_id": "'"$P3_ID"'"}' > /dev/null
curl -s -X POST "$SUPABASE_URL/rest/v1/product_stops" \
-H "$AUTH_HEADER" -H "$CONTENT_TYPE" \
-d '{"stop_id": "'"$S3_ID"'", "product_id": "'"$P4_ID"'"}' > /dev/null
curl -s -X POST "$SUPABASE_URL/rest/v1/product_stops" \
-H "$AUTH_HEADER" -H "$CONTENT_TYPE" \
-d '{"stop_id": "'"$S3_ID"'", "product_id": "'"$P5_ID"'"}' > /dev/null
curl -s -X POST "$SUPABASE_URL/rest/v1/product_stops" \
-H "$AUTH_HEADER" -H "$CONTENT_TYPE" \
-d '{"stop_id": "'"$S3_ID"'", "product_id": "'"$P6_ID"'"}' > /dev/null
echo ""
echo "Creating orders..."
ORDER1=$(curl -s -X POST "$SUPABASE_URL/rest/v1/orders" \
-H "$AUTH_HEADER" \
-H "$CONTENT_TYPE" \
-H "Prefer: return=representation" \
-d '{
"customer_name": "Sarah Mitchell",
"customer_email": "sarah.m@email.com",
"customer_phone": "(336) 555-0142",
"stop_id": "'"$S1_ID"'",
"status": "pending",
"subtotal": 32,
"discount_amount": 0,
"pickup_complete": false,
"payment_processor": "manual",
"payment_status": "paid"
}')
echo "Order 1: $ORDER1"
ORDER2=$(curl -s -X POST "$SUPABASE_URL/rest/v1/orders" \
-H "$AUTH_HEADER" \
-H "$CONTENT_TYPE" \
-H "Prefer: return=representation" \
-d '{
"customer_name": "James Rivera",
"customer_email": "jrivera@email.com",
"customer_phone": "(336) 555-0298",
"stop_id": "'"$S1_ID"'",
"status": "confirmed",
"subtotal": 22,
"discount_amount": 2,
"discount_reason": "First-time customer",
"pickup_complete": true,
"payment_processor": "manual",
"payment_status": "paid"
}')
echo "Order 2: $ORDER2"
ORDER3=$(curl -s -X POST "$SUPABASE_URL/rest/v1/orders" \
-H "$AUTH_HEADER" \
-H "$CONTENT_TYPE" \
-H "Prefer: return=representation" \
-d '{
"customer_name": "Lisa Chen",
"customer_phone": "(919) 555-0763",
"stop_id": "'"$S2_ID"'",
"status": "pending",
"subtotal": 12,
"pickup_complete": false,
"payment_processor": "manual",
"payment_status": "pending"
}')
echo "Order 3: $ORDER3"
ORDER4=$(curl -s -X POST "$SUPABASE_URL/rest/v1/orders" \
-H "$AUTH_HEADER" \
-H "$CONTENT_TYPE" \
-H "Prefer: return=representation" \
-d '{
"customer_name": "Marcus Thompson",
"customer_email": "mthompson@email.com",
"customer_phone": "(772) 555-0119",
"stop_id": "'"$S3_ID"'",
"status": "confirmed",
"subtotal": 37,
"pickup_complete": false,
"payment_processor": "venmo",
"payment_status": "paid",
"payment_transaction_id": "VEN-88420"
}')
echo "Order 4: $ORDER4"
ORDER5=$(curl -s -X POST "$SUPABASE_URL/rest/v1/orders" \
-H "$AUTH_HEADER" \
-H "$CONTENT_TYPE" \
-H "Prefer: return=representation" \
-d '{
"customer_name": "Amanda Foster",
"customer_email": "afoster@email.com",
"stop_id": "'"$S3_ID"'",
"status": "cancelled",
"subtotal": 15,
"pickup_complete": false,
"internal_notes": "Customer cancelled after hours, no show next day",
"payment_processor": "manual",
"payment_status": "refunded",
"refunded_amount": 15,
"refund_reason": "Customer cancelled"
}')
echo "Order 5: $ORDER5"
O1_ID=$(echo "$ORDER1" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)
O2_ID=$(echo "$ORDER2" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)
O3_ID=$(echo "$ORDER3" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)
O4_ID=$(echo "$ORDER4" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)
O5_ID=$(echo "$ORDER5" | grep -o '"id":"[^"]*"' | head -1 | cut -d'"' -f4)
echo ""
echo "Creating order items..."
curl -s -X POST "$SUPABASE_URL/rest/v1/order_items" \
-H "$AUTH_HEADER" -H "$CONTENT_TYPE" \
-d '{"order_id": "'"$O1_ID"'", "product_id": "'"$P1_ID"'", "quantity": 2, "price": 12}' > /dev/null
curl -s -X POST "$SUPABASE_URL/rest/v1/order_items" \
-H "$AUTH_HEADER" -H "$CONTENT_TYPE" \
-d '{"order_id": "'"$O1_ID"'", "product_id": "'"$P2_ID"'", "quantity": 1, "price": 8}' > /dev/null
curl -s -X POST "$SUPABASE_URL/rest/v1/order_items" \
-H "$AUTH_HEADER" -H "$CONTENT_TYPE" \
-d '{"order_id": "'"$O2_ID"'", "product_id": "'"$P3_ID"'", "quantity": 1, "price": 18}' > /dev/null
curl -s -X POST "$SUPABASE_URL/rest/v1/order_items" \
-H "$AUTH_HEADER" -H "$CONTENT_TYPE" \
-d '{"order_id": "'"$O2_ID"'", "product_id": "'"$P1_ID"'", "quantity": 2, "price": 12}' > /dev/null
curl -s -X POST "$SUPABASE_URL/rest/v1/order_items" \
-H "$AUTH_HEADER" -H "$CONTENT_TYPE" \
-d '{"order_id": "'"$O3_ID"'", "product_id": "'"$P1_ID"'", "quantity": 1, "price": 12}' > /dev/null
curl -s -X POST "$SUPABASE_URL/rest/v1/order_items" \
-H "$AUTH_HEADER" -H "$CONTENT_TYPE" \
-d '{"order_id": "'"$O4_ID"'", "product_id": "'"$P4_ID"'", "quantity": 2, "price": 15}' > /dev/null
curl -s -X POST "$SUPABASE_URL/rest/v1/order_items" \
-H "$AUTH_HEADER" -H "$CONTENT_TYPE" \
-d '{"order_id": "'"$O4_ID"'", "product_id": "'"$P5_ID"'", "quantity": 1, "price": 12}' > /dev/null
curl -s -X POST "$SUPABASE_URL/rest/v1/order_items" \
-H "$AUTH_HEADER" -H "$CONTENT_TYPE" \
-d '{"order_id": "'"$O5_ID"'", "product_id": "'"$P4_ID"'", "quantity": 1, "price": 15}' > /dev/null
echo ""
echo "Done! Seed data created:"
echo " 3 stops (Burlington NC, Greensboro NC, Fort Pierce FL)"
echo " 6 products (3 Tuxedo Corn, 3 Indian River Direct)"
echo " 5 orders with items"
echo ""
echo "Quick test URLs:"
echo " /admin/orders"
echo " /admin/products"
echo " /admin/stops"
+74
View File
@@ -0,0 +1,74 @@
import { createClient } from "@supabase/supabase-js";
import { readFileSync } from "fs";
import { fileURLToPath } from "url";
import path from "path";
// Load .env.local manually
const __dirname = path.dirname(fileURLToPath(import.meta.url));
const envPath = path.join(__dirname, "..", ".env.local");
const envContent = readFileSync(envPath, "utf8");
envContent.split("\n").forEach((line) => {
const [key, ...rest] = line.split("=");
if (key && rest.length && key.trim() && !key.trim().startsWith("#")) {
process.env[key.trim()] = rest.join("=").trim().replace(/^"|"$/g, "");
}
});
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL;
const supabaseServiceKey = process.env.SUPABASE_SERVICE_ROLE_KEY;
if (!supabaseUrl || !supabaseServiceKey) {
console.error("Missing env vars");
process.exit(1);
}
const supabase = createClient(supabaseUrl, supabaseServiceKey);
async function uploadTuxedoHeroVideo() {
const filePath = "/Users/kylemartinez/Downloads/062624TuxedoCorn 001.mp4";
const fileBuffer = readFileSync(filePath);
const fileSizeMB = (fileBuffer.byteLength / 1024 / 1024).toFixed(2);
console.log(`File: ${filePath} (${fileSizeMB} MB)`);
// Ensure public videos bucket exists
const { data: buckets, error: listErr } = await supabase.storage.listBuckets();
if (listErr) { console.error("List buckets error:", listErr.message); process.exit(1); }
const existing = buckets?.find((b) => b.name === "videos");
if (!existing) {
console.log("Creating 'videos' bucket (public)...");
const { error: createErr } = await supabase.storage.createBucket("videos", { public: true });
if (createErr) { console.error("Create bucket error:", createErr.message); process.exit(1); }
console.log("Bucket 'videos' created.");
} else {
console.log(`'videos' bucket exists (public: ${existing.public}).`);
if (!existing.public) {
const { error: updErr } = await supabase.storage.updateBucket("videos", { public: true });
if (updErr) console.warn("Could not update bucket to public:", updErr.message);
else console.log("Bucket updated to public.");
}
}
// Upload
console.log("Uploading tuxedo-hero.mp4...");
const { data: uploadData, error: uploadErr } = await supabase.storage
.from("videos")
.upload("tuxedo-hero.mp4", fileBuffer, {
contentType: "video/mp4",
upsert: true,
});
if (uploadErr) {
console.error("Upload error:", uploadErr.message);
process.exit(1);
}
console.log("Upload OK:", JSON.stringify(uploadData));
// Public URL
const { data: urlData } = supabase.storage.from("videos").getPublicUrl("tuxedo-hero.mp4");
const url = urlData.publicUrl;
console.log(`\n✅ Public URL:\n${url}`);
}
uploadTuxedoHeroVideo().catch((e) => { console.error(e); process.exit(1); });