virtual-ui-lib 1.0.68 → 1.0.70

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -32,9 +32,11 @@ __export(index_exports, {
32
32
  AvatarCard: () => AvatarCard,
33
33
  BackgoundImageSlider: () => BackgoundImageSlider,
34
34
  Charts: () => Charts,
35
+ FileUpload: () => FileUpload,
35
36
  Footer: () => Footer,
36
37
  ImageCard: () => ImageCard,
37
38
  ImageSlider: () => ImageSlider,
39
+ InvoiceCard: () => InvoiceCard,
38
40
  Loader: () => Loader,
39
41
  Navbar: () => Navbar,
40
42
  NotificationToast: () => NotificationToast,
@@ -2272,14 +2274,500 @@ var OTPInput = ({
2272
2274
  resendTimer > 0 ? `${resendText} (${resendTimer}s)` : resendText
2273
2275
  )));
2274
2276
  };
2277
+
2278
+ // src/components/InvoiceCard/InvoiceCard.jsx
2279
+ var import_react14 = __toESM(require("react"));
2280
+ var InvoiceCard = ({
2281
+ invoiceNumber = "INV-2024-001",
2282
+ date = "21 March 2024",
2283
+ dueDate = "31 March 2024",
2284
+ from = {
2285
+ name: "VirtualAI Inc.",
2286
+ email: "billing@virtualai.com",
2287
+ address: "123 Tech Street, San Francisco, CA"
2288
+ },
2289
+ to = {
2290
+ name: "Aryan Sharma",
2291
+ email: "aryan@example.com",
2292
+ address: "456 Dev Lane, Mumbai, India"
2293
+ },
2294
+ items = [
2295
+ { name: "Pro Plan Subscription", qty: 1, price: 29 },
2296
+ { name: "Extra AI Credits (500)", qty: 2, price: 9 },
2297
+ { name: "Custom Domain Setup", qty: 1, price: 15 }
2298
+ ],
2299
+ taxRate = 18,
2300
+ currency = "$",
2301
+ accent = "#6366f1",
2302
+ bg = "#0f172a",
2303
+ radius = "20px",
2304
+ status = "unpaid",
2305
+ onPayClick = () => {
2306
+ },
2307
+ onDownloadClick = () => {
2308
+ }
2309
+ }) => {
2310
+ const [paid, setPaid] = (0, import_react14.useState)(status === "paid");
2311
+ const alpha = (hex, op) => {
2312
+ const r = parseInt(hex.slice(1, 3), 16);
2313
+ const g = parseInt(hex.slice(3, 5), 16);
2314
+ const b = parseInt(hex.slice(5, 7), 16);
2315
+ return `rgba(${r},${g},${b},${op})`;
2316
+ };
2317
+ const subtotal = items.reduce((s, i) => s + i.qty * i.price, 0);
2318
+ const tax = parseFloat((subtotal * taxRate / 100).toFixed(2));
2319
+ const total = parseFloat((subtotal + tax).toFixed(2));
2320
+ const statusConfig = {
2321
+ paid: { label: "Paid", bg: "rgba(16,185,129,0.15)", color: "#34d399", border: "rgba(16,185,129,0.3)" },
2322
+ unpaid: { label: "Unpaid", bg: "rgba(239,68,68,0.12)", color: "#f87171", border: "rgba(239,68,68,0.3)" },
2323
+ pending: { label: "Pending", bg: "rgba(245,158,11,0.12)", color: "#fbbf24", border: "rgba(245,158,11,0.3)" }
2324
+ };
2325
+ const sc = statusConfig[paid ? "paid" : status] || statusConfig.unpaid;
2326
+ const Row = ({ label, value, bold, large, accentColor }) => /* @__PURE__ */ import_react14.default.createElement("div", { style: {
2327
+ display: "flex",
2328
+ justifyContent: "space-between",
2329
+ alignItems: "center",
2330
+ padding: "5px 0"
2331
+ } }, /* @__PURE__ */ import_react14.default.createElement("span", { style: {
2332
+ fontSize: large ? "14px" : "12px",
2333
+ fontWeight: bold ? "700" : "400",
2334
+ color: large ? "#fff" : "rgba(255,255,255,0.45)"
2335
+ } }, label), /* @__PURE__ */ import_react14.default.createElement("span", { style: {
2336
+ fontSize: large ? "16px" : "13px",
2337
+ fontWeight: bold ? "800" : "600",
2338
+ color: accentColor || (large ? "#fff" : "rgba(255,255,255,0.85)")
2339
+ } }, currency, typeof value === "number" ? value.toFixed(2) : value));
2340
+ return /* @__PURE__ */ import_react14.default.createElement("div", { style: {
2341
+ background: bg,
2342
+ borderRadius: radius,
2343
+ padding: "24px",
2344
+ width: "340px",
2345
+ fontFamily: "system-ui, sans-serif",
2346
+ border: "1px solid rgba(255,255,255,0.07)",
2347
+ boxShadow: "0 10px 40px rgba(0,0,0,0.4)",
2348
+ color: "#fff"
2349
+ } }, /* @__PURE__ */ import_react14.default.createElement("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: "20px" } }, /* @__PURE__ */ import_react14.default.createElement("div", null, /* @__PURE__ */ import_react14.default.createElement("div", { style: { display: "flex", alignItems: "center", gap: "7px", marginBottom: "4px" } }, /* @__PURE__ */ import_react14.default.createElement("div", { style: {
2350
+ width: "24px",
2351
+ height: "24px",
2352
+ borderRadius: "6px",
2353
+ background: `linear-gradient(135deg, ${accent}, ${alpha(accent, 0.6)})`,
2354
+ display: "flex",
2355
+ alignItems: "center",
2356
+ justifyContent: "center",
2357
+ fontSize: "11px",
2358
+ fontWeight: "800",
2359
+ color: "#fff"
2360
+ } }, "V"), /* @__PURE__ */ import_react14.default.createElement("span", { style: { fontSize: "14px", fontWeight: "800" } }, from.name)), /* @__PURE__ */ import_react14.default.createElement("p", { style: { fontSize: "11px", color: "rgba(255,255,255,0.3)", margin: 0 } }, invoiceNumber)), /* @__PURE__ */ import_react14.default.createElement("div", { style: {
2361
+ padding: "4px 12px",
2362
+ borderRadius: "20px",
2363
+ fontSize: "11px",
2364
+ fontWeight: "700",
2365
+ background: sc.bg,
2366
+ color: sc.color,
2367
+ border: `1px solid ${sc.border}`,
2368
+ textTransform: "uppercase",
2369
+ letterSpacing: "0.5px"
2370
+ } }, sc.label)), /* @__PURE__ */ import_react14.default.createElement("div", { style: {
2371
+ display: "grid",
2372
+ gridTemplateColumns: "1fr 1fr",
2373
+ gap: "12px",
2374
+ background: "rgba(255,255,255,0.03)",
2375
+ border: "1px solid rgba(255,255,255,0.06)",
2376
+ borderRadius: "12px",
2377
+ padding: "14px",
2378
+ marginBottom: "20px"
2379
+ } }, [{ label: "From", info: from }, { label: "To", info: to }].map(({ label, info }) => /* @__PURE__ */ import_react14.default.createElement("div", { key: label }, /* @__PURE__ */ import_react14.default.createElement("p", { style: { fontSize: "10px", fontWeight: "700", color: "rgba(255,255,255,0.25)", textTransform: "uppercase", letterSpacing: "0.8px", marginBottom: "5px" } }, label), /* @__PURE__ */ import_react14.default.createElement("p", { style: { fontSize: "12px", fontWeight: "700", color: "#fff", margin: "0 0 2px" } }, info.name), /* @__PURE__ */ import_react14.default.createElement("p", { style: { fontSize: "11px", color: "rgba(255,255,255,0.35)", margin: "0 0 2px" } }, info.email), /* @__PURE__ */ import_react14.default.createElement("p", { style: { fontSize: "10px", color: "rgba(255,255,255,0.25)", margin: 0, lineHeight: 1.4 } }, info.address)))), /* @__PURE__ */ import_react14.default.createElement("div", { style: { display: "flex", gap: "10px", marginBottom: "20px" } }, [{ label: "Issue Date", val: date }, { label: "Due Date", val: dueDate }].map(({ label, val }) => /* @__PURE__ */ import_react14.default.createElement("div", { key: label, style: {
2380
+ flex: 1,
2381
+ background: "rgba(255,255,255,0.03)",
2382
+ border: "1px solid rgba(255,255,255,0.06)",
2383
+ borderRadius: "10px",
2384
+ padding: "10px 12px"
2385
+ } }, /* @__PURE__ */ import_react14.default.createElement("p", { style: { fontSize: "10px", color: "rgba(255,255,255,0.25)", textTransform: "uppercase", letterSpacing: "0.8px", margin: "0 0 3px", fontWeight: "700" } }, label), /* @__PURE__ */ import_react14.default.createElement("p", { style: { fontSize: "12px", fontWeight: "700", color: "#fff", margin: 0 } }, val)))), /* @__PURE__ */ import_react14.default.createElement("div", { style: { marginBottom: "16px" } }, /* @__PURE__ */ import_react14.default.createElement("div", { style: {
2386
+ display: "grid",
2387
+ gridTemplateColumns: "1fr auto auto",
2388
+ gap: "8px",
2389
+ padding: "6px 8px",
2390
+ borderBottom: "1px solid rgba(255,255,255,0.06)",
2391
+ marginBottom: "4px"
2392
+ } }, ["Item", "Qty", "Amount"].map((h) => /* @__PURE__ */ import_react14.default.createElement("span", { key: h, style: { fontSize: "10px", fontWeight: "700", color: "rgba(255,255,255,0.25)", textTransform: "uppercase", letterSpacing: "0.8px", textAlign: h !== "Item" ? "right" : "left" } }, h))), items.map((item, i) => /* @__PURE__ */ import_react14.default.createElement("div", { key: i, style: {
2393
+ display: "grid",
2394
+ gridTemplateColumns: "1fr auto auto",
2395
+ gap: "8px",
2396
+ padding: "8px",
2397
+ borderRadius: "8px",
2398
+ background: i % 2 === 0 ? "rgba(255,255,255,0.02)" : "transparent"
2399
+ } }, /* @__PURE__ */ import_react14.default.createElement("span", { style: { fontSize: "12px", color: "rgba(255,255,255,0.75)" } }, item.name), /* @__PURE__ */ import_react14.default.createElement("span", { style: { fontSize: "12px", color: "rgba(255,255,255,0.35)", textAlign: "right" } }, "\xD7", item.qty), /* @__PURE__ */ import_react14.default.createElement("span", { style: { fontSize: "12px", fontWeight: "600", color: "#fff", textAlign: "right" } }, currency, (item.qty * item.price).toFixed(2))))), /* @__PURE__ */ import_react14.default.createElement("div", { style: {
2400
+ background: "rgba(255,255,255,0.03)",
2401
+ border: "1px solid rgba(255,255,255,0.06)",
2402
+ borderRadius: "12px",
2403
+ padding: "12px 14px",
2404
+ marginBottom: "20px"
2405
+ } }, /* @__PURE__ */ import_react14.default.createElement(Row, { label: "Subtotal", value: subtotal }), /* @__PURE__ */ import_react14.default.createElement(Row, { label: `Tax (${taxRate}%)`, value: tax }), /* @__PURE__ */ import_react14.default.createElement("div", { style: { height: "1px", background: "rgba(255,255,255,0.07)", margin: "8px 0" } }), /* @__PURE__ */ import_react14.default.createElement(Row, { label: "Total", value: total, bold: true, large: true, accentColor: accent })), /* @__PURE__ */ import_react14.default.createElement("div", { style: { display: "flex", gap: "8px" } }, !paid && /* @__PURE__ */ import_react14.default.createElement(
2406
+ "button",
2407
+ {
2408
+ onClick: () => {
2409
+ setPaid(true);
2410
+ onPayClick();
2411
+ },
2412
+ style: {
2413
+ flex: 1,
2414
+ padding: "11px",
2415
+ borderRadius: "12px",
2416
+ border: "none",
2417
+ background: `linear-gradient(135deg, ${accent}, ${alpha(accent, 0.7)})`,
2418
+ color: "#fff",
2419
+ fontSize: "13px",
2420
+ fontWeight: "700",
2421
+ cursor: "pointer",
2422
+ fontFamily: "inherit",
2423
+ transition: "opacity 0.2s"
2424
+ },
2425
+ onMouseEnter: (e) => e.currentTarget.style.opacity = "0.85",
2426
+ onMouseLeave: (e) => e.currentTarget.style.opacity = "1"
2427
+ },
2428
+ "Pay ",
2429
+ currency,
2430
+ total.toFixed(2)
2431
+ ), paid && /* @__PURE__ */ import_react14.default.createElement("div", { style: {
2432
+ flex: 1,
2433
+ padding: "11px",
2434
+ borderRadius: "12px",
2435
+ background: "rgba(16,185,129,0.1)",
2436
+ border: "1px solid rgba(16,185,129,0.25)",
2437
+ display: "flex",
2438
+ alignItems: "center",
2439
+ justifyContent: "center",
2440
+ gap: "6px",
2441
+ fontSize: "13px",
2442
+ fontWeight: "700",
2443
+ color: "#34d399"
2444
+ } }, /* @__PURE__ */ import_react14.default.createElement(
2445
+ "svg",
2446
+ {
2447
+ width: "14",
2448
+ height: "14",
2449
+ viewBox: "0 0 24 24",
2450
+ fill: "none",
2451
+ stroke: "currentColor",
2452
+ strokeWidth: "2.5",
2453
+ strokeLinecap: "round"
2454
+ },
2455
+ /* @__PURE__ */ import_react14.default.createElement("polyline", { points: "20 6 9 17 4 12" })
2456
+ ), "Payment Done"), /* @__PURE__ */ import_react14.default.createElement(
2457
+ "button",
2458
+ {
2459
+ onClick: onDownloadClick,
2460
+ style: {
2461
+ width: "42px",
2462
+ padding: "11px",
2463
+ borderRadius: "12px",
2464
+ background: "rgba(255,255,255,0.05)",
2465
+ border: "1px solid rgba(255,255,255,0.1)",
2466
+ color: "rgba(255,255,255,0.5)",
2467
+ cursor: "pointer",
2468
+ display: "flex",
2469
+ alignItems: "center",
2470
+ justifyContent: "center",
2471
+ transition: "all 0.2s"
2472
+ },
2473
+ onMouseEnter: (e) => {
2474
+ e.currentTarget.style.color = "#fff";
2475
+ e.currentTarget.style.borderColor = "rgba(255,255,255,0.25)";
2476
+ },
2477
+ onMouseLeave: (e) => {
2478
+ e.currentTarget.style.color = "rgba(255,255,255,0.5)";
2479
+ e.currentTarget.style.borderColor = "rgba(255,255,255,0.1)";
2480
+ }
2481
+ },
2482
+ /* @__PURE__ */ import_react14.default.createElement(
2483
+ "svg",
2484
+ {
2485
+ width: "15",
2486
+ height: "15",
2487
+ viewBox: "0 0 24 24",
2488
+ fill: "none",
2489
+ stroke: "currentColor",
2490
+ strokeWidth: "2",
2491
+ strokeLinecap: "round",
2492
+ strokeLinejoin: "round"
2493
+ },
2494
+ /* @__PURE__ */ import_react14.default.createElement("path", { d: "M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4M7 10l5 5 5-5M12 15V3" })
2495
+ )
2496
+ )));
2497
+ };
2498
+
2499
+ // src/components/FileUpload/FileUpload.jsx
2500
+ var import_react15 = __toESM(require("react"));
2501
+ var FileUpload = ({
2502
+ accept = "*",
2503
+ multiple = true,
2504
+ maxSizeMB = 5,
2505
+ accent = "#6366f1",
2506
+ bg = "#0f172a",
2507
+ radius = "16px",
2508
+ label = "Drop files here or click to upload",
2509
+ subLabel = "Supports any file up to",
2510
+ onUpload = () => {
2511
+ }
2512
+ }) => {
2513
+ const [files, setFiles] = (0, import_react15.useState)([]);
2514
+ const [dragging, setDragging] = (0, import_react15.useState)(false);
2515
+ const [error, setError] = (0, import_react15.useState)("");
2516
+ const inputRef = (0, import_react15.useRef)(null);
2517
+ const alpha = (hex, op) => {
2518
+ const r = parseInt(hex.slice(1, 3), 16);
2519
+ const g = parseInt(hex.slice(3, 5), 16);
2520
+ const b = parseInt(hex.slice(5, 7), 16);
2521
+ return `rgba(${r},${g},${b},${op})`;
2522
+ };
2523
+ const formatSize = (bytes) => {
2524
+ if (bytes < 1024) return bytes + " B";
2525
+ if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + " KB";
2526
+ return (bytes / (1024 * 1024)).toFixed(1) + " MB";
2527
+ };
2528
+ const getIcon = (type) => {
2529
+ if (type.startsWith("image/")) return { path: "M21 19V5a2 2 0 00-2-2H5a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2zM8.5 13.5l2.5 3 3.5-4.5 4.5 6H5l3.5-4.5z", color: "#a78bfa" };
2530
+ if (type.includes("pdf")) return { path: "M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8zM14 2v6h6M16 13H8M16 17H8M10 9H8", color: "#f87171" };
2531
+ if (type.includes("video")) return { path: "M23 7l-7 5 7 5V7zM1 5h15a2 2 0 012 2v10a2 2 0 01-2 2H1a2 2 0 01-2-2V7a2 2 0 012-2z", color: "#34d399" };
2532
+ if (type.includes("audio")) return { path: "M9 18V5l12-2v13M9 18c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2zm12-2c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2z", color: "#fbbf24" };
2533
+ return { path: "M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8zM14 2v6h6", color: "#94a3b8" };
2534
+ };
2535
+ const processFiles = (incoming) => {
2536
+ setError("");
2537
+ const valid = [];
2538
+ for (const f of incoming) {
2539
+ if (f.size > maxSizeMB * 1024 * 1024) {
2540
+ setError(`"${f.name}" exceeds ${maxSizeMB}MB limit.`);
2541
+ continue;
2542
+ }
2543
+ valid.push({ file: f, id: Math.random().toString(36).slice(2), progress: 0, done: false });
2544
+ }
2545
+ if (!valid.length) return;
2546
+ const newFiles = multiple ? [...files, ...valid] : valid;
2547
+ setFiles(newFiles);
2548
+ valid.forEach(({ id }) => {
2549
+ let p = 0;
2550
+ const t = setInterval(() => {
2551
+ p += Math.floor(Math.random() * 15) + 5;
2552
+ if (p >= 100) {
2553
+ p = 100;
2554
+ clearInterval(t);
2555
+ setFiles((prev) => prev.map((f) => f.id === id ? { ...f, progress: 100, done: true } : f));
2556
+ onUpload(id);
2557
+ } else {
2558
+ setFiles((prev) => prev.map((f) => f.id === id ? { ...f, progress: p } : f));
2559
+ }
2560
+ }, 200);
2561
+ });
2562
+ };
2563
+ const handleDrop = (e) => {
2564
+ e.preventDefault();
2565
+ setDragging(false);
2566
+ processFiles(Array.from(e.dataTransfer.files));
2567
+ };
2568
+ const removeFile = (id) => setFiles((prev) => prev.filter((f) => f.id !== id));
2569
+ return /* @__PURE__ */ import_react15.default.createElement("div", { style: { width: "320px", fontFamily: "system-ui, sans-serif" } }, /* @__PURE__ */ import_react15.default.createElement(
2570
+ "div",
2571
+ {
2572
+ onClick: () => {
2573
+ var _a;
2574
+ return (_a = inputRef.current) == null ? void 0 : _a.click();
2575
+ },
2576
+ onDragOver: (e) => {
2577
+ e.preventDefault();
2578
+ setDragging(true);
2579
+ },
2580
+ onDragLeave: () => setDragging(false),
2581
+ onDrop: handleDrop,
2582
+ style: {
2583
+ background: dragging ? alpha(accent, 0.1) : "rgba(255,255,255,0.03)",
2584
+ border: `2px dashed ${dragging ? accent : "rgba(255,255,255,0.1)"}`,
2585
+ borderRadius: radius,
2586
+ padding: "32px 20px",
2587
+ textAlign: "center",
2588
+ cursor: "pointer",
2589
+ transition: "all 0.2s"
2590
+ }
2591
+ },
2592
+ /* @__PURE__ */ import_react15.default.createElement(
2593
+ "input",
2594
+ {
2595
+ ref: inputRef,
2596
+ type: "file",
2597
+ accept,
2598
+ multiple,
2599
+ style: { display: "none" },
2600
+ onChange: (e) => processFiles(Array.from(e.target.files))
2601
+ }
2602
+ ),
2603
+ /* @__PURE__ */ import_react15.default.createElement("div", { style: {
2604
+ width: "48px",
2605
+ height: "48px",
2606
+ borderRadius: "14px",
2607
+ background: alpha(accent, 0.12),
2608
+ border: `1px solid ${alpha(accent, 0.25)}`,
2609
+ display: "flex",
2610
+ alignItems: "center",
2611
+ justifyContent: "center",
2612
+ margin: "0 auto 14px",
2613
+ transition: "all 0.2s",
2614
+ transform: dragging ? "scale(1.1)" : "scale(1)"
2615
+ } }, /* @__PURE__ */ import_react15.default.createElement(
2616
+ "svg",
2617
+ {
2618
+ width: "22",
2619
+ height: "22",
2620
+ viewBox: "0 0 24 24",
2621
+ fill: "none",
2622
+ stroke: accent,
2623
+ strokeWidth: "2",
2624
+ strokeLinecap: "round",
2625
+ strokeLinejoin: "round"
2626
+ },
2627
+ /* @__PURE__ */ import_react15.default.createElement("path", { d: "M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4M17 8l-5-5-5 5M12 3v12" })
2628
+ )),
2629
+ /* @__PURE__ */ import_react15.default.createElement("p", { style: { fontSize: "13px", fontWeight: "600", color: "#fff", margin: "0 0 4px" } }, label),
2630
+ /* @__PURE__ */ import_react15.default.createElement("p", { style: { fontSize: "11px", color: "rgba(255,255,255,0.3)", margin: 0 } }, subLabel, " ", maxSizeMB, "MB")
2631
+ ), error && /* @__PURE__ */ import_react15.default.createElement("div", { style: {
2632
+ marginTop: "10px",
2633
+ padding: "9px 12px",
2634
+ borderRadius: "10px",
2635
+ background: "rgba(239,68,68,0.08)",
2636
+ border: "1px solid rgba(239,68,68,0.2)",
2637
+ display: "flex",
2638
+ alignItems: "center",
2639
+ gap: "8px"
2640
+ } }, /* @__PURE__ */ import_react15.default.createElement(
2641
+ "svg",
2642
+ {
2643
+ width: "13",
2644
+ height: "13",
2645
+ viewBox: "0 0 24 24",
2646
+ fill: "none",
2647
+ stroke: "#f87171",
2648
+ strokeWidth: "2.5",
2649
+ strokeLinecap: "round"
2650
+ },
2651
+ /* @__PURE__ */ import_react15.default.createElement("circle", { cx: "12", cy: "12", r: "10" }),
2652
+ /* @__PURE__ */ import_react15.default.createElement("line", { x1: "12", y1: "8", x2: "12", y2: "12" }),
2653
+ /* @__PURE__ */ import_react15.default.createElement("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })
2654
+ ), /* @__PURE__ */ import_react15.default.createElement("span", { style: { fontSize: "11px", color: "#f87171" } }, error)), files.length > 0 && /* @__PURE__ */ import_react15.default.createElement("div", { style: { marginTop: "12px", display: "flex", flexDirection: "column", gap: "8px" } }, files.map(({ file, id, progress, done }) => {
2655
+ const icon = getIcon(file.type);
2656
+ const preview = file.type.startsWith("image/") ? URL.createObjectURL(file) : null;
2657
+ return /* @__PURE__ */ import_react15.default.createElement("div", { key: id, style: {
2658
+ background: "rgba(255,255,255,0.03)",
2659
+ border: `1px solid ${done ? alpha(accent, 0.2) : "rgba(255,255,255,0.07)"}`,
2660
+ borderRadius: "12px",
2661
+ padding: "10px 12px",
2662
+ transition: "border-color 0.3s"
2663
+ } }, /* @__PURE__ */ import_react15.default.createElement("div", { style: { display: "flex", alignItems: "center", gap: "10px" } }, /* @__PURE__ */ import_react15.default.createElement("div", { style: {
2664
+ width: "36px",
2665
+ height: "36px",
2666
+ borderRadius: "8px",
2667
+ flexShrink: 0,
2668
+ background: preview ? `url(${preview}) center/cover` : alpha(icon.color, 0.12),
2669
+ border: `1px solid ${alpha(icon.color, 0.2)}`,
2670
+ display: "flex",
2671
+ alignItems: "center",
2672
+ justifyContent: "center",
2673
+ overflow: "hidden"
2674
+ } }, !preview && /* @__PURE__ */ import_react15.default.createElement(
2675
+ "svg",
2676
+ {
2677
+ width: "16",
2678
+ height: "16",
2679
+ viewBox: "0 0 24 24",
2680
+ fill: "none",
2681
+ stroke: icon.color,
2682
+ strokeWidth: "2",
2683
+ strokeLinecap: "round",
2684
+ strokeLinejoin: "round"
2685
+ },
2686
+ /* @__PURE__ */ import_react15.default.createElement("path", { d: icon.path })
2687
+ )), /* @__PURE__ */ import_react15.default.createElement("div", { style: { flex: 1, minWidth: 0 } }, /* @__PURE__ */ import_react15.default.createElement("p", { style: {
2688
+ fontSize: "12px",
2689
+ fontWeight: "600",
2690
+ color: "#fff",
2691
+ margin: "0 0 2px",
2692
+ overflow: "hidden",
2693
+ textOverflow: "ellipsis",
2694
+ whiteSpace: "nowrap"
2695
+ } }, file.name), /* @__PURE__ */ import_react15.default.createElement("p", { style: { fontSize: "10px", color: "rgba(255,255,255,0.3)", margin: 0 } }, formatSize(file.size))), done ? /* @__PURE__ */ import_react15.default.createElement("div", { style: {
2696
+ width: "22px",
2697
+ height: "22px",
2698
+ borderRadius: "50%",
2699
+ background: "rgba(16,185,129,0.15)",
2700
+ border: "1px solid rgba(16,185,129,0.3)",
2701
+ display: "flex",
2702
+ alignItems: "center",
2703
+ justifyContent: "center",
2704
+ flexShrink: 0
2705
+ } }, /* @__PURE__ */ import_react15.default.createElement(
2706
+ "svg",
2707
+ {
2708
+ width: "10",
2709
+ height: "10",
2710
+ viewBox: "0 0 24 24",
2711
+ fill: "none",
2712
+ stroke: "#34d399",
2713
+ strokeWidth: "3",
2714
+ strokeLinecap: "round"
2715
+ },
2716
+ /* @__PURE__ */ import_react15.default.createElement("polyline", { points: "20 6 9 17 4 12" })
2717
+ )) : /* @__PURE__ */ import_react15.default.createElement(
2718
+ "button",
2719
+ {
2720
+ onClick: () => removeFile(id),
2721
+ style: {
2722
+ background: "transparent",
2723
+ border: "none",
2724
+ padding: "2px",
2725
+ cursor: "pointer",
2726
+ color: "rgba(255,255,255,0.25)",
2727
+ flexShrink: 0,
2728
+ transition: "color 0.2s"
2729
+ },
2730
+ onMouseEnter: (e) => e.currentTarget.style.color = "#f87171",
2731
+ onMouseLeave: (e) => e.currentTarget.style.color = "rgba(255,255,255,0.25)"
2732
+ },
2733
+ /* @__PURE__ */ import_react15.default.createElement(
2734
+ "svg",
2735
+ {
2736
+ width: "14",
2737
+ height: "14",
2738
+ viewBox: "0 0 24 24",
2739
+ fill: "none",
2740
+ stroke: "currentColor",
2741
+ strokeWidth: "2.5",
2742
+ strokeLinecap: "round"
2743
+ },
2744
+ /* @__PURE__ */ import_react15.default.createElement("path", { d: "M18 6L6 18M6 6l12 12" })
2745
+ )
2746
+ )), !done && /* @__PURE__ */ import_react15.default.createElement("div", { style: {
2747
+ marginTop: "8px",
2748
+ height: "3px",
2749
+ background: "rgba(255,255,255,0.06)",
2750
+ borderRadius: "2px",
2751
+ overflow: "hidden"
2752
+ } }, /* @__PURE__ */ import_react15.default.createElement("div", { style: {
2753
+ height: "100%",
2754
+ borderRadius: "2px",
2755
+ width: `${progress}%`,
2756
+ background: `linear-gradient(90deg, ${accent}, ${alpha(accent, 0.6)})`,
2757
+ transition: "width 0.2s ease"
2758
+ } })));
2759
+ })));
2760
+ };
2275
2761
  // Annotate the CommonJS export names for ESM import in node:
2276
2762
  0 && (module.exports = {
2277
2763
  AvatarCard,
2278
2764
  BackgoundImageSlider,
2279
2765
  Charts,
2766
+ FileUpload,
2280
2767
  Footer,
2281
2768
  ImageCard,
2282
2769
  ImageSlider,
2770
+ InvoiceCard,
2283
2771
  Loader,
2284
2772
  Navbar,
2285
2773
  NotificationToast,
package/dist/index.mjs CHANGED
@@ -2225,13 +2225,499 @@ var OTPInput = ({
2225
2225
  resendTimer > 0 ? `${resendText} (${resendTimer}s)` : resendText
2226
2226
  )));
2227
2227
  };
2228
+
2229
+ // src/components/InvoiceCard/InvoiceCard.jsx
2230
+ import React14, { useState as useState12 } from "react";
2231
+ var InvoiceCard = ({
2232
+ invoiceNumber = "INV-2024-001",
2233
+ date = "21 March 2024",
2234
+ dueDate = "31 March 2024",
2235
+ from = {
2236
+ name: "VirtualAI Inc.",
2237
+ email: "billing@virtualai.com",
2238
+ address: "123 Tech Street, San Francisco, CA"
2239
+ },
2240
+ to = {
2241
+ name: "Aryan Sharma",
2242
+ email: "aryan@example.com",
2243
+ address: "456 Dev Lane, Mumbai, India"
2244
+ },
2245
+ items = [
2246
+ { name: "Pro Plan Subscription", qty: 1, price: 29 },
2247
+ { name: "Extra AI Credits (500)", qty: 2, price: 9 },
2248
+ { name: "Custom Domain Setup", qty: 1, price: 15 }
2249
+ ],
2250
+ taxRate = 18,
2251
+ currency = "$",
2252
+ accent = "#6366f1",
2253
+ bg = "#0f172a",
2254
+ radius = "20px",
2255
+ status = "unpaid",
2256
+ onPayClick = () => {
2257
+ },
2258
+ onDownloadClick = () => {
2259
+ }
2260
+ }) => {
2261
+ const [paid, setPaid] = useState12(status === "paid");
2262
+ const alpha = (hex, op) => {
2263
+ const r = parseInt(hex.slice(1, 3), 16);
2264
+ const g = parseInt(hex.slice(3, 5), 16);
2265
+ const b = parseInt(hex.slice(5, 7), 16);
2266
+ return `rgba(${r},${g},${b},${op})`;
2267
+ };
2268
+ const subtotal = items.reduce((s, i) => s + i.qty * i.price, 0);
2269
+ const tax = parseFloat((subtotal * taxRate / 100).toFixed(2));
2270
+ const total = parseFloat((subtotal + tax).toFixed(2));
2271
+ const statusConfig = {
2272
+ paid: { label: "Paid", bg: "rgba(16,185,129,0.15)", color: "#34d399", border: "rgba(16,185,129,0.3)" },
2273
+ unpaid: { label: "Unpaid", bg: "rgba(239,68,68,0.12)", color: "#f87171", border: "rgba(239,68,68,0.3)" },
2274
+ pending: { label: "Pending", bg: "rgba(245,158,11,0.12)", color: "#fbbf24", border: "rgba(245,158,11,0.3)" }
2275
+ };
2276
+ const sc = statusConfig[paid ? "paid" : status] || statusConfig.unpaid;
2277
+ const Row = ({ label, value, bold, large, accentColor }) => /* @__PURE__ */ React14.createElement("div", { style: {
2278
+ display: "flex",
2279
+ justifyContent: "space-between",
2280
+ alignItems: "center",
2281
+ padding: "5px 0"
2282
+ } }, /* @__PURE__ */ React14.createElement("span", { style: {
2283
+ fontSize: large ? "14px" : "12px",
2284
+ fontWeight: bold ? "700" : "400",
2285
+ color: large ? "#fff" : "rgba(255,255,255,0.45)"
2286
+ } }, label), /* @__PURE__ */ React14.createElement("span", { style: {
2287
+ fontSize: large ? "16px" : "13px",
2288
+ fontWeight: bold ? "800" : "600",
2289
+ color: accentColor || (large ? "#fff" : "rgba(255,255,255,0.85)")
2290
+ } }, currency, typeof value === "number" ? value.toFixed(2) : value));
2291
+ return /* @__PURE__ */ React14.createElement("div", { style: {
2292
+ background: bg,
2293
+ borderRadius: radius,
2294
+ padding: "24px",
2295
+ width: "340px",
2296
+ fontFamily: "system-ui, sans-serif",
2297
+ border: "1px solid rgba(255,255,255,0.07)",
2298
+ boxShadow: "0 10px 40px rgba(0,0,0,0.4)",
2299
+ color: "#fff"
2300
+ } }, /* @__PURE__ */ React14.createElement("div", { style: { display: "flex", justifyContent: "space-between", alignItems: "flex-start", marginBottom: "20px" } }, /* @__PURE__ */ React14.createElement("div", null, /* @__PURE__ */ React14.createElement("div", { style: { display: "flex", alignItems: "center", gap: "7px", marginBottom: "4px" } }, /* @__PURE__ */ React14.createElement("div", { style: {
2301
+ width: "24px",
2302
+ height: "24px",
2303
+ borderRadius: "6px",
2304
+ background: `linear-gradient(135deg, ${accent}, ${alpha(accent, 0.6)})`,
2305
+ display: "flex",
2306
+ alignItems: "center",
2307
+ justifyContent: "center",
2308
+ fontSize: "11px",
2309
+ fontWeight: "800",
2310
+ color: "#fff"
2311
+ } }, "V"), /* @__PURE__ */ React14.createElement("span", { style: { fontSize: "14px", fontWeight: "800" } }, from.name)), /* @__PURE__ */ React14.createElement("p", { style: { fontSize: "11px", color: "rgba(255,255,255,0.3)", margin: 0 } }, invoiceNumber)), /* @__PURE__ */ React14.createElement("div", { style: {
2312
+ padding: "4px 12px",
2313
+ borderRadius: "20px",
2314
+ fontSize: "11px",
2315
+ fontWeight: "700",
2316
+ background: sc.bg,
2317
+ color: sc.color,
2318
+ border: `1px solid ${sc.border}`,
2319
+ textTransform: "uppercase",
2320
+ letterSpacing: "0.5px"
2321
+ } }, sc.label)), /* @__PURE__ */ React14.createElement("div", { style: {
2322
+ display: "grid",
2323
+ gridTemplateColumns: "1fr 1fr",
2324
+ gap: "12px",
2325
+ background: "rgba(255,255,255,0.03)",
2326
+ border: "1px solid rgba(255,255,255,0.06)",
2327
+ borderRadius: "12px",
2328
+ padding: "14px",
2329
+ marginBottom: "20px"
2330
+ } }, [{ label: "From", info: from }, { label: "To", info: to }].map(({ label, info }) => /* @__PURE__ */ React14.createElement("div", { key: label }, /* @__PURE__ */ React14.createElement("p", { style: { fontSize: "10px", fontWeight: "700", color: "rgba(255,255,255,0.25)", textTransform: "uppercase", letterSpacing: "0.8px", marginBottom: "5px" } }, label), /* @__PURE__ */ React14.createElement("p", { style: { fontSize: "12px", fontWeight: "700", color: "#fff", margin: "0 0 2px" } }, info.name), /* @__PURE__ */ React14.createElement("p", { style: { fontSize: "11px", color: "rgba(255,255,255,0.35)", margin: "0 0 2px" } }, info.email), /* @__PURE__ */ React14.createElement("p", { style: { fontSize: "10px", color: "rgba(255,255,255,0.25)", margin: 0, lineHeight: 1.4 } }, info.address)))), /* @__PURE__ */ React14.createElement("div", { style: { display: "flex", gap: "10px", marginBottom: "20px" } }, [{ label: "Issue Date", val: date }, { label: "Due Date", val: dueDate }].map(({ label, val }) => /* @__PURE__ */ React14.createElement("div", { key: label, style: {
2331
+ flex: 1,
2332
+ background: "rgba(255,255,255,0.03)",
2333
+ border: "1px solid rgba(255,255,255,0.06)",
2334
+ borderRadius: "10px",
2335
+ padding: "10px 12px"
2336
+ } }, /* @__PURE__ */ React14.createElement("p", { style: { fontSize: "10px", color: "rgba(255,255,255,0.25)", textTransform: "uppercase", letterSpacing: "0.8px", margin: "0 0 3px", fontWeight: "700" } }, label), /* @__PURE__ */ React14.createElement("p", { style: { fontSize: "12px", fontWeight: "700", color: "#fff", margin: 0 } }, val)))), /* @__PURE__ */ React14.createElement("div", { style: { marginBottom: "16px" } }, /* @__PURE__ */ React14.createElement("div", { style: {
2337
+ display: "grid",
2338
+ gridTemplateColumns: "1fr auto auto",
2339
+ gap: "8px",
2340
+ padding: "6px 8px",
2341
+ borderBottom: "1px solid rgba(255,255,255,0.06)",
2342
+ marginBottom: "4px"
2343
+ } }, ["Item", "Qty", "Amount"].map((h) => /* @__PURE__ */ React14.createElement("span", { key: h, style: { fontSize: "10px", fontWeight: "700", color: "rgba(255,255,255,0.25)", textTransform: "uppercase", letterSpacing: "0.8px", textAlign: h !== "Item" ? "right" : "left" } }, h))), items.map((item, i) => /* @__PURE__ */ React14.createElement("div", { key: i, style: {
2344
+ display: "grid",
2345
+ gridTemplateColumns: "1fr auto auto",
2346
+ gap: "8px",
2347
+ padding: "8px",
2348
+ borderRadius: "8px",
2349
+ background: i % 2 === 0 ? "rgba(255,255,255,0.02)" : "transparent"
2350
+ } }, /* @__PURE__ */ React14.createElement("span", { style: { fontSize: "12px", color: "rgba(255,255,255,0.75)" } }, item.name), /* @__PURE__ */ React14.createElement("span", { style: { fontSize: "12px", color: "rgba(255,255,255,0.35)", textAlign: "right" } }, "\xD7", item.qty), /* @__PURE__ */ React14.createElement("span", { style: { fontSize: "12px", fontWeight: "600", color: "#fff", textAlign: "right" } }, currency, (item.qty * item.price).toFixed(2))))), /* @__PURE__ */ React14.createElement("div", { style: {
2351
+ background: "rgba(255,255,255,0.03)",
2352
+ border: "1px solid rgba(255,255,255,0.06)",
2353
+ borderRadius: "12px",
2354
+ padding: "12px 14px",
2355
+ marginBottom: "20px"
2356
+ } }, /* @__PURE__ */ React14.createElement(Row, { label: "Subtotal", value: subtotal }), /* @__PURE__ */ React14.createElement(Row, { label: `Tax (${taxRate}%)`, value: tax }), /* @__PURE__ */ React14.createElement("div", { style: { height: "1px", background: "rgba(255,255,255,0.07)", margin: "8px 0" } }), /* @__PURE__ */ React14.createElement(Row, { label: "Total", value: total, bold: true, large: true, accentColor: accent })), /* @__PURE__ */ React14.createElement("div", { style: { display: "flex", gap: "8px" } }, !paid && /* @__PURE__ */ React14.createElement(
2357
+ "button",
2358
+ {
2359
+ onClick: () => {
2360
+ setPaid(true);
2361
+ onPayClick();
2362
+ },
2363
+ style: {
2364
+ flex: 1,
2365
+ padding: "11px",
2366
+ borderRadius: "12px",
2367
+ border: "none",
2368
+ background: `linear-gradient(135deg, ${accent}, ${alpha(accent, 0.7)})`,
2369
+ color: "#fff",
2370
+ fontSize: "13px",
2371
+ fontWeight: "700",
2372
+ cursor: "pointer",
2373
+ fontFamily: "inherit",
2374
+ transition: "opacity 0.2s"
2375
+ },
2376
+ onMouseEnter: (e) => e.currentTarget.style.opacity = "0.85",
2377
+ onMouseLeave: (e) => e.currentTarget.style.opacity = "1"
2378
+ },
2379
+ "Pay ",
2380
+ currency,
2381
+ total.toFixed(2)
2382
+ ), paid && /* @__PURE__ */ React14.createElement("div", { style: {
2383
+ flex: 1,
2384
+ padding: "11px",
2385
+ borderRadius: "12px",
2386
+ background: "rgba(16,185,129,0.1)",
2387
+ border: "1px solid rgba(16,185,129,0.25)",
2388
+ display: "flex",
2389
+ alignItems: "center",
2390
+ justifyContent: "center",
2391
+ gap: "6px",
2392
+ fontSize: "13px",
2393
+ fontWeight: "700",
2394
+ color: "#34d399"
2395
+ } }, /* @__PURE__ */ React14.createElement(
2396
+ "svg",
2397
+ {
2398
+ width: "14",
2399
+ height: "14",
2400
+ viewBox: "0 0 24 24",
2401
+ fill: "none",
2402
+ stroke: "currentColor",
2403
+ strokeWidth: "2.5",
2404
+ strokeLinecap: "round"
2405
+ },
2406
+ /* @__PURE__ */ React14.createElement("polyline", { points: "20 6 9 17 4 12" })
2407
+ ), "Payment Done"), /* @__PURE__ */ React14.createElement(
2408
+ "button",
2409
+ {
2410
+ onClick: onDownloadClick,
2411
+ style: {
2412
+ width: "42px",
2413
+ padding: "11px",
2414
+ borderRadius: "12px",
2415
+ background: "rgba(255,255,255,0.05)",
2416
+ border: "1px solid rgba(255,255,255,0.1)",
2417
+ color: "rgba(255,255,255,0.5)",
2418
+ cursor: "pointer",
2419
+ display: "flex",
2420
+ alignItems: "center",
2421
+ justifyContent: "center",
2422
+ transition: "all 0.2s"
2423
+ },
2424
+ onMouseEnter: (e) => {
2425
+ e.currentTarget.style.color = "#fff";
2426
+ e.currentTarget.style.borderColor = "rgba(255,255,255,0.25)";
2427
+ },
2428
+ onMouseLeave: (e) => {
2429
+ e.currentTarget.style.color = "rgba(255,255,255,0.5)";
2430
+ e.currentTarget.style.borderColor = "rgba(255,255,255,0.1)";
2431
+ }
2432
+ },
2433
+ /* @__PURE__ */ React14.createElement(
2434
+ "svg",
2435
+ {
2436
+ width: "15",
2437
+ height: "15",
2438
+ viewBox: "0 0 24 24",
2439
+ fill: "none",
2440
+ stroke: "currentColor",
2441
+ strokeWidth: "2",
2442
+ strokeLinecap: "round",
2443
+ strokeLinejoin: "round"
2444
+ },
2445
+ /* @__PURE__ */ React14.createElement("path", { d: "M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4M7 10l5 5 5-5M12 15V3" })
2446
+ )
2447
+ )));
2448
+ };
2449
+
2450
+ // src/components/FileUpload/FileUpload.jsx
2451
+ import React15, { useState as useState13, useRef as useRef2 } from "react";
2452
+ var FileUpload = ({
2453
+ accept = "*",
2454
+ multiple = true,
2455
+ maxSizeMB = 5,
2456
+ accent = "#6366f1",
2457
+ bg = "#0f172a",
2458
+ radius = "16px",
2459
+ label = "Drop files here or click to upload",
2460
+ subLabel = "Supports any file up to",
2461
+ onUpload = () => {
2462
+ }
2463
+ }) => {
2464
+ const [files, setFiles] = useState13([]);
2465
+ const [dragging, setDragging] = useState13(false);
2466
+ const [error, setError] = useState13("");
2467
+ const inputRef = useRef2(null);
2468
+ const alpha = (hex, op) => {
2469
+ const r = parseInt(hex.slice(1, 3), 16);
2470
+ const g = parseInt(hex.slice(3, 5), 16);
2471
+ const b = parseInt(hex.slice(5, 7), 16);
2472
+ return `rgba(${r},${g},${b},${op})`;
2473
+ };
2474
+ const formatSize = (bytes) => {
2475
+ if (bytes < 1024) return bytes + " B";
2476
+ if (bytes < 1024 * 1024) return (bytes / 1024).toFixed(1) + " KB";
2477
+ return (bytes / (1024 * 1024)).toFixed(1) + " MB";
2478
+ };
2479
+ const getIcon = (type) => {
2480
+ if (type.startsWith("image/")) return { path: "M21 19V5a2 2 0 00-2-2H5a2 2 0 00-2 2v14a2 2 0 002 2h14a2 2 0 002-2zM8.5 13.5l2.5 3 3.5-4.5 4.5 6H5l3.5-4.5z", color: "#a78bfa" };
2481
+ if (type.includes("pdf")) return { path: "M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8zM14 2v6h6M16 13H8M16 17H8M10 9H8", color: "#f87171" };
2482
+ if (type.includes("video")) return { path: "M23 7l-7 5 7 5V7zM1 5h15a2 2 0 012 2v10a2 2 0 01-2 2H1a2 2 0 01-2-2V7a2 2 0 012-2z", color: "#34d399" };
2483
+ if (type.includes("audio")) return { path: "M9 18V5l12-2v13M9 18c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2zm12-2c0 1.1-.9 2-2 2s-2-.9-2-2 .9-2 2-2 2 .9 2 2z", color: "#fbbf24" };
2484
+ return { path: "M14 2H6a2 2 0 00-2 2v16a2 2 0 002 2h12a2 2 0 002-2V8zM14 2v6h6", color: "#94a3b8" };
2485
+ };
2486
+ const processFiles = (incoming) => {
2487
+ setError("");
2488
+ const valid = [];
2489
+ for (const f of incoming) {
2490
+ if (f.size > maxSizeMB * 1024 * 1024) {
2491
+ setError(`"${f.name}" exceeds ${maxSizeMB}MB limit.`);
2492
+ continue;
2493
+ }
2494
+ valid.push({ file: f, id: Math.random().toString(36).slice(2), progress: 0, done: false });
2495
+ }
2496
+ if (!valid.length) return;
2497
+ const newFiles = multiple ? [...files, ...valid] : valid;
2498
+ setFiles(newFiles);
2499
+ valid.forEach(({ id }) => {
2500
+ let p = 0;
2501
+ const t = setInterval(() => {
2502
+ p += Math.floor(Math.random() * 15) + 5;
2503
+ if (p >= 100) {
2504
+ p = 100;
2505
+ clearInterval(t);
2506
+ setFiles((prev) => prev.map((f) => f.id === id ? { ...f, progress: 100, done: true } : f));
2507
+ onUpload(id);
2508
+ } else {
2509
+ setFiles((prev) => prev.map((f) => f.id === id ? { ...f, progress: p } : f));
2510
+ }
2511
+ }, 200);
2512
+ });
2513
+ };
2514
+ const handleDrop = (e) => {
2515
+ e.preventDefault();
2516
+ setDragging(false);
2517
+ processFiles(Array.from(e.dataTransfer.files));
2518
+ };
2519
+ const removeFile = (id) => setFiles((prev) => prev.filter((f) => f.id !== id));
2520
+ return /* @__PURE__ */ React15.createElement("div", { style: { width: "320px", fontFamily: "system-ui, sans-serif" } }, /* @__PURE__ */ React15.createElement(
2521
+ "div",
2522
+ {
2523
+ onClick: () => {
2524
+ var _a;
2525
+ return (_a = inputRef.current) == null ? void 0 : _a.click();
2526
+ },
2527
+ onDragOver: (e) => {
2528
+ e.preventDefault();
2529
+ setDragging(true);
2530
+ },
2531
+ onDragLeave: () => setDragging(false),
2532
+ onDrop: handleDrop,
2533
+ style: {
2534
+ background: dragging ? alpha(accent, 0.1) : "rgba(255,255,255,0.03)",
2535
+ border: `2px dashed ${dragging ? accent : "rgba(255,255,255,0.1)"}`,
2536
+ borderRadius: radius,
2537
+ padding: "32px 20px",
2538
+ textAlign: "center",
2539
+ cursor: "pointer",
2540
+ transition: "all 0.2s"
2541
+ }
2542
+ },
2543
+ /* @__PURE__ */ React15.createElement(
2544
+ "input",
2545
+ {
2546
+ ref: inputRef,
2547
+ type: "file",
2548
+ accept,
2549
+ multiple,
2550
+ style: { display: "none" },
2551
+ onChange: (e) => processFiles(Array.from(e.target.files))
2552
+ }
2553
+ ),
2554
+ /* @__PURE__ */ React15.createElement("div", { style: {
2555
+ width: "48px",
2556
+ height: "48px",
2557
+ borderRadius: "14px",
2558
+ background: alpha(accent, 0.12),
2559
+ border: `1px solid ${alpha(accent, 0.25)}`,
2560
+ display: "flex",
2561
+ alignItems: "center",
2562
+ justifyContent: "center",
2563
+ margin: "0 auto 14px",
2564
+ transition: "all 0.2s",
2565
+ transform: dragging ? "scale(1.1)" : "scale(1)"
2566
+ } }, /* @__PURE__ */ React15.createElement(
2567
+ "svg",
2568
+ {
2569
+ width: "22",
2570
+ height: "22",
2571
+ viewBox: "0 0 24 24",
2572
+ fill: "none",
2573
+ stroke: accent,
2574
+ strokeWidth: "2",
2575
+ strokeLinecap: "round",
2576
+ strokeLinejoin: "round"
2577
+ },
2578
+ /* @__PURE__ */ React15.createElement("path", { d: "M21 15v4a2 2 0 01-2 2H5a2 2 0 01-2-2v-4M17 8l-5-5-5 5M12 3v12" })
2579
+ )),
2580
+ /* @__PURE__ */ React15.createElement("p", { style: { fontSize: "13px", fontWeight: "600", color: "#fff", margin: "0 0 4px" } }, label),
2581
+ /* @__PURE__ */ React15.createElement("p", { style: { fontSize: "11px", color: "rgba(255,255,255,0.3)", margin: 0 } }, subLabel, " ", maxSizeMB, "MB")
2582
+ ), error && /* @__PURE__ */ React15.createElement("div", { style: {
2583
+ marginTop: "10px",
2584
+ padding: "9px 12px",
2585
+ borderRadius: "10px",
2586
+ background: "rgba(239,68,68,0.08)",
2587
+ border: "1px solid rgba(239,68,68,0.2)",
2588
+ display: "flex",
2589
+ alignItems: "center",
2590
+ gap: "8px"
2591
+ } }, /* @__PURE__ */ React15.createElement(
2592
+ "svg",
2593
+ {
2594
+ width: "13",
2595
+ height: "13",
2596
+ viewBox: "0 0 24 24",
2597
+ fill: "none",
2598
+ stroke: "#f87171",
2599
+ strokeWidth: "2.5",
2600
+ strokeLinecap: "round"
2601
+ },
2602
+ /* @__PURE__ */ React15.createElement("circle", { cx: "12", cy: "12", r: "10" }),
2603
+ /* @__PURE__ */ React15.createElement("line", { x1: "12", y1: "8", x2: "12", y2: "12" }),
2604
+ /* @__PURE__ */ React15.createElement("line", { x1: "12", y1: "16", x2: "12.01", y2: "16" })
2605
+ ), /* @__PURE__ */ React15.createElement("span", { style: { fontSize: "11px", color: "#f87171" } }, error)), files.length > 0 && /* @__PURE__ */ React15.createElement("div", { style: { marginTop: "12px", display: "flex", flexDirection: "column", gap: "8px" } }, files.map(({ file, id, progress, done }) => {
2606
+ const icon = getIcon(file.type);
2607
+ const preview = file.type.startsWith("image/") ? URL.createObjectURL(file) : null;
2608
+ return /* @__PURE__ */ React15.createElement("div", { key: id, style: {
2609
+ background: "rgba(255,255,255,0.03)",
2610
+ border: `1px solid ${done ? alpha(accent, 0.2) : "rgba(255,255,255,0.07)"}`,
2611
+ borderRadius: "12px",
2612
+ padding: "10px 12px",
2613
+ transition: "border-color 0.3s"
2614
+ } }, /* @__PURE__ */ React15.createElement("div", { style: { display: "flex", alignItems: "center", gap: "10px" } }, /* @__PURE__ */ React15.createElement("div", { style: {
2615
+ width: "36px",
2616
+ height: "36px",
2617
+ borderRadius: "8px",
2618
+ flexShrink: 0,
2619
+ background: preview ? `url(${preview}) center/cover` : alpha(icon.color, 0.12),
2620
+ border: `1px solid ${alpha(icon.color, 0.2)}`,
2621
+ display: "flex",
2622
+ alignItems: "center",
2623
+ justifyContent: "center",
2624
+ overflow: "hidden"
2625
+ } }, !preview && /* @__PURE__ */ React15.createElement(
2626
+ "svg",
2627
+ {
2628
+ width: "16",
2629
+ height: "16",
2630
+ viewBox: "0 0 24 24",
2631
+ fill: "none",
2632
+ stroke: icon.color,
2633
+ strokeWidth: "2",
2634
+ strokeLinecap: "round",
2635
+ strokeLinejoin: "round"
2636
+ },
2637
+ /* @__PURE__ */ React15.createElement("path", { d: icon.path })
2638
+ )), /* @__PURE__ */ React15.createElement("div", { style: { flex: 1, minWidth: 0 } }, /* @__PURE__ */ React15.createElement("p", { style: {
2639
+ fontSize: "12px",
2640
+ fontWeight: "600",
2641
+ color: "#fff",
2642
+ margin: "0 0 2px",
2643
+ overflow: "hidden",
2644
+ textOverflow: "ellipsis",
2645
+ whiteSpace: "nowrap"
2646
+ } }, file.name), /* @__PURE__ */ React15.createElement("p", { style: { fontSize: "10px", color: "rgba(255,255,255,0.3)", margin: 0 } }, formatSize(file.size))), done ? /* @__PURE__ */ React15.createElement("div", { style: {
2647
+ width: "22px",
2648
+ height: "22px",
2649
+ borderRadius: "50%",
2650
+ background: "rgba(16,185,129,0.15)",
2651
+ border: "1px solid rgba(16,185,129,0.3)",
2652
+ display: "flex",
2653
+ alignItems: "center",
2654
+ justifyContent: "center",
2655
+ flexShrink: 0
2656
+ } }, /* @__PURE__ */ React15.createElement(
2657
+ "svg",
2658
+ {
2659
+ width: "10",
2660
+ height: "10",
2661
+ viewBox: "0 0 24 24",
2662
+ fill: "none",
2663
+ stroke: "#34d399",
2664
+ strokeWidth: "3",
2665
+ strokeLinecap: "round"
2666
+ },
2667
+ /* @__PURE__ */ React15.createElement("polyline", { points: "20 6 9 17 4 12" })
2668
+ )) : /* @__PURE__ */ React15.createElement(
2669
+ "button",
2670
+ {
2671
+ onClick: () => removeFile(id),
2672
+ style: {
2673
+ background: "transparent",
2674
+ border: "none",
2675
+ padding: "2px",
2676
+ cursor: "pointer",
2677
+ color: "rgba(255,255,255,0.25)",
2678
+ flexShrink: 0,
2679
+ transition: "color 0.2s"
2680
+ },
2681
+ onMouseEnter: (e) => e.currentTarget.style.color = "#f87171",
2682
+ onMouseLeave: (e) => e.currentTarget.style.color = "rgba(255,255,255,0.25)"
2683
+ },
2684
+ /* @__PURE__ */ React15.createElement(
2685
+ "svg",
2686
+ {
2687
+ width: "14",
2688
+ height: "14",
2689
+ viewBox: "0 0 24 24",
2690
+ fill: "none",
2691
+ stroke: "currentColor",
2692
+ strokeWidth: "2.5",
2693
+ strokeLinecap: "round"
2694
+ },
2695
+ /* @__PURE__ */ React15.createElement("path", { d: "M18 6L6 18M6 6l12 12" })
2696
+ )
2697
+ )), !done && /* @__PURE__ */ React15.createElement("div", { style: {
2698
+ marginTop: "8px",
2699
+ height: "3px",
2700
+ background: "rgba(255,255,255,0.06)",
2701
+ borderRadius: "2px",
2702
+ overflow: "hidden"
2703
+ } }, /* @__PURE__ */ React15.createElement("div", { style: {
2704
+ height: "100%",
2705
+ borderRadius: "2px",
2706
+ width: `${progress}%`,
2707
+ background: `linear-gradient(90deg, ${accent}, ${alpha(accent, 0.6)})`,
2708
+ transition: "width 0.2s ease"
2709
+ } })));
2710
+ })));
2711
+ };
2228
2712
  export {
2229
2713
  AvatarCard,
2230
2714
  BackgoundImageSlider,
2231
2715
  Charts,
2716
+ FileUpload,
2232
2717
  Footer,
2233
2718
  ImageCard,
2234
2719
  ImageSlider,
2720
+ InvoiceCard,
2235
2721
  Loader,
2236
2722
  Navbar,
2237
2723
  NotificationToast,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "virtual-ui-lib",
3
- "version": "1.0.68",
3
+ "version": "1.0.70",
4
4
  "description": "Virtual UI React Component Library",
5
5
  "author": "Ankush",
6
6
  "license": "ISC",