- Introduced a new Separator component for visual separation in UI. - Added Sheet component for modal-like functionality with triggers and overlays. - Implemented Toaster component for notifications using Sonner library. - Created Switch component for toggle functionality. - Developed Table component with headers, body, footer, and rows for structured data display. - Added Tabs component for organizing content into tabbed interfaces. - Implemented Textarea component for multi-line text input. - Created Tooltip component for displaying additional information on hover. feat: add PocketBase helpers and types - Implemented various helper functions for interacting with PocketBase collections (customers, companies, suppliers, quotes, orders). - Added type definitions for entities such as Customer, Company, Supplier, Quote, Order, and their respective items. - Included utility functions for generating unique identifiers for quotes, orders, and purchase orders. - Added functions for calculating totals and formatting currency and dates. chore: add TypeScript configuration - Added tsconfig.json for TypeScript support with strict type checking and module resolution.
94 lines
3 KiB
TypeScript
94 lines
3 KiB
TypeScript
import PocketBase from "pocketbase";
|
|
import { readFileSync } from "fs";
|
|
import { resolve } from "path";
|
|
|
|
const PB_URL = "http://127.0.0.1:8090";
|
|
const ADMIN_EMAIL = "david.els1@outlook.com";
|
|
const ADMIN_PASSWORD = "1234567890";
|
|
|
|
const CUSTOMERS_FILE = "/Volumes/KIOXIA/Downloads/WFDASH - wfdash_customers (wfdash_customers) 2026-05-24_12-58.json";
|
|
const COMPANIES_FILE = "/Volumes/KIOXIA/Downloads/WFDASH - wfdash_company (wfdash_company) 2026-05-24_12-58.json";
|
|
|
|
function normalizeDate(val: string | null): string | null {
|
|
if (!val) return null;
|
|
return val.replace(" ", "T");
|
|
}
|
|
|
|
function parseJson(path: string): Record<string, unknown>[] {
|
|
const raw = readFileSync(resolve(path), "utf-8");
|
|
return JSON.parse(raw);
|
|
}
|
|
|
|
function chunks<T>(arr: T[], size: number): T[][] {
|
|
const result: T[][] = [];
|
|
for (let i = 0; i < arr.length; i += size) {
|
|
result.push(arr.slice(i, i + size));
|
|
}
|
|
return result;
|
|
}
|
|
|
|
async function importCollection<T extends Record<string, unknown>>(
|
|
pb: PocketBase,
|
|
collectionName: string,
|
|
records: T[],
|
|
mapper: (r: T) => Record<string, unknown>,
|
|
) {
|
|
console.log(`\nImporting ${records.length} records into "${collectionName}"...`);
|
|
let success = 0;
|
|
let errors = 0;
|
|
|
|
for (let i = 0; i < records.length; i++) {
|
|
try {
|
|
await pb.collection(collectionName).create(mapper(records[i]), { $autoCancel: false });
|
|
success++;
|
|
} catch (err: unknown) {
|
|
errors++;
|
|
if (errors <= 3) {
|
|
const msg = err instanceof Error ? err.message : String(err);
|
|
console.error(` Error on record ${i}: ${msg}`);
|
|
}
|
|
}
|
|
if ((i + 1) % 20 === 0 || i === records.length - 1) {
|
|
const pct = Math.round(((i + 1) / records.length) * 100);
|
|
process.stdout.write(`\r Progress: ${success + errors}/${records.length} (${pct}%) | OK: ${success} | Err: ${errors}`);
|
|
}
|
|
}
|
|
console.log(`\n Done: ${success} created, ${errors} failed`);
|
|
}
|
|
|
|
async function main() {
|
|
const pb = new PocketBase(PB_URL);
|
|
console.log("Authenticating as admin...");
|
|
await pb.collection("_superusers").authWithPassword(ADMIN_EMAIL, ADMIN_PASSWORD);
|
|
|
|
// --- Import companies ---
|
|
const companyRecords = parseJson(COMPANIES_FILE);
|
|
await importCollection(pb, "companies", companyRecords, (r) => ({
|
|
company: r.company ?? "",
|
|
address: r.address ?? "",
|
|
vendor: r.vendor ?? "",
|
|
}));
|
|
|
|
// --- Import customers ---
|
|
const customerRecords = parseJson(CUSTOMERS_FILE);
|
|
await importCollection(pb, "customers", customerRecords, (r) => ({
|
|
customer: r.customer ?? "",
|
|
email: r.email ?? "",
|
|
alternative_email: r.alternative_email ?? null,
|
|
buyer_email: r.buyer_email ?? null,
|
|
number: r.number ?? "",
|
|
company: r.company ?? "",
|
|
dateadded: normalizeDate(r.dateadded as string | null),
|
|
lastvisiteddate: normalizeDate(r.lastvisiteddate as string | null),
|
|
rep: r.rep ?? null,
|
|
coordinates: r.coordinates ?? null,
|
|
description: r.description ?? null,
|
|
}));
|
|
|
|
console.log("\n\n✅ Import complete!");
|
|
}
|
|
|
|
main().catch((err) => {
|
|
console.error("Import failed:", err);
|
|
process.exit(1);
|
|
});
|