@burdenoff/website-sdk 2026.516.13 → 2026.516.15

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.
@@ -1,5 +1,6 @@
1
1
  import { createContext, useState, useCallback, useEffect, useContext } from 'react';
2
- import { jsx } from 'react/jsx-runtime';
2
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
3
+ import { Helmet } from 'react-helmet-async';
3
4
 
4
5
  var __defProp = Object.defineProperty;
5
6
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
@@ -204,6 +205,15 @@ var PUBLIC_CONTENT_PAGES_QUERY = `
204
205
  title
205
206
  slug
206
207
  lastUpdated
208
+ tags
209
+ excerpt
210
+ thumbnail
211
+ author
212
+ publishedAt
213
+ readingTime
214
+ featured
215
+ category
216
+ seoDescription
207
217
  }
208
218
  total
209
219
  hasMore
@@ -301,7 +311,399 @@ function ContentRenderer({
301
311
  }
302
312
  return /* @__PURE__ */ jsx("div", { className, children: /* @__PURE__ */ jsx("pre", { style: { whiteSpace: "pre-wrap", fontFamily: "inherit" }, children: content }) });
303
313
  }
314
+ function PageHead({
315
+ title,
316
+ description,
317
+ productName,
318
+ keywords,
319
+ image,
320
+ url,
321
+ favicon,
322
+ robots = "index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1",
323
+ locale = "en_US",
324
+ twitterHandle,
325
+ themeColor = "#000000",
326
+ structuredData,
327
+ additionalMeta
328
+ }) {
329
+ const fullTitle = productName && !title.includes(productName) ? `${title} | ${productName}` : title;
330
+ const fullImageUrl = image && !image.startsWith("http") && url ? `${url.replace(/\/$/, "")}${image}` : image;
331
+ const structuredDataItems = structuredData ? Array.isArray(structuredData) ? structuredData : [structuredData] : [];
332
+ return /* @__PURE__ */ jsxs(Helmet, { children: [
333
+ /* @__PURE__ */ jsx("title", { children: fullTitle }),
334
+ /* @__PURE__ */ jsx("meta", { name: "title", content: fullTitle }),
335
+ description && /* @__PURE__ */ jsx("meta", { name: "description", content: description }),
336
+ keywords && /* @__PURE__ */ jsx("meta", { name: "keywords", content: keywords }),
337
+ /* @__PURE__ */ jsx("meta", { name: "author", content: "Burdenoff Consultancy Services Pvt Ltd" }),
338
+ /* @__PURE__ */ jsx("meta", { name: "robots", content: robots }),
339
+ url && /* @__PURE__ */ jsx("link", { rel: "canonical", href: url }),
340
+ favicon && /* @__PURE__ */ jsx("link", { rel: "icon", href: favicon }),
341
+ /* @__PURE__ */ jsx("meta", { property: "og:type", content: "website" }),
342
+ /* @__PURE__ */ jsx("meta", { property: "og:title", content: fullTitle }),
343
+ description && /* @__PURE__ */ jsx("meta", { property: "og:description", content: description }),
344
+ fullImageUrl && /* @__PURE__ */ jsx("meta", { property: "og:image", content: fullImageUrl }),
345
+ url && /* @__PURE__ */ jsx("meta", { property: "og:url", content: url }),
346
+ /* @__PURE__ */ jsx("meta", { property: "og:locale", content: locale }),
347
+ productName && /* @__PURE__ */ jsx("meta", { property: "og:site_name", content: productName }),
348
+ /* @__PURE__ */ jsx("meta", { name: "twitter:card", content: "summary_large_image" }),
349
+ /* @__PURE__ */ jsx("meta", { name: "twitter:title", content: fullTitle }),
350
+ description && /* @__PURE__ */ jsx("meta", { name: "twitter:description", content: description }),
351
+ fullImageUrl && /* @__PURE__ */ jsx("meta", { name: "twitter:image", content: fullImageUrl }),
352
+ twitterHandle && /* @__PURE__ */ jsx("meta", { name: "twitter:creator", content: twitterHandle }),
353
+ /* @__PURE__ */ jsx("meta", { name: "theme-color", content: themeColor }),
354
+ structuredDataItems.map((data, index) => /* @__PURE__ */ jsx("script", { type: "application/ld+json", children: JSON.stringify(data) }, `ld-${index}`)),
355
+ additionalMeta?.map((meta, index) => /* @__PURE__ */ jsx(
356
+ "meta",
357
+ {
358
+ ...meta.name ? { name: meta.name } : {},
359
+ ...meta.property ? { property: meta.property } : {},
360
+ content: meta.content
361
+ },
362
+ `meta-${index}`
363
+ ))
364
+ ] });
365
+ }
366
+ var BLOG_POSTS_QUERY = `
367
+ query BlogPosts($productId: String!, $limit: Int, $offset: Int) {
368
+ publicContentPages(productId: $productId, limit: $limit, offset: $offset) {
369
+ items {
370
+ id
371
+ title
372
+ slug
373
+ lastUpdated
374
+ tags
375
+ excerpt
376
+ thumbnail
377
+ author
378
+ publishedAt
379
+ readingTime
380
+ featured
381
+ category
382
+ seoDescription
383
+ }
384
+ total
385
+ hasMore
386
+ }
387
+ }
388
+ `;
389
+ var BLOG_POST_QUERY = `
390
+ query BlogPost($slug: String!, $productId: String) {
391
+ publicContentPage(slug: $slug, productId: $productId) {
392
+ id
393
+ title
394
+ slug
395
+ content
396
+ contentFormat
397
+ seoTitle
398
+ seoDescription
399
+ seoKeywords
400
+ lastUpdated
401
+ tags
402
+ excerpt
403
+ thumbnail
404
+ author
405
+ publishedAt
406
+ readingTime
407
+ category
408
+ }
409
+ }
410
+ `;
411
+ function BlogCard({
412
+ post,
413
+ basePath = "/blog"
414
+ }) {
415
+ const date = post.publishedAt || post.lastUpdated;
416
+ const formattedDate = date ? new Date(date).toLocaleDateString("en-US", {
417
+ year: "numeric",
418
+ month: "long",
419
+ day: "numeric"
420
+ }) : "";
421
+ return /* @__PURE__ */ jsxs(
422
+ "a",
423
+ {
424
+ href: `${basePath}/${post.slug}`,
425
+ className: "group block bg-card border rounded-xl overflow-hidden hover:shadow-lg hover:border-primary/30 transition-all duration-300",
426
+ children: [
427
+ post.thumbnail ? /* @__PURE__ */ jsx("div", { className: "aspect-[16/9] overflow-hidden", children: /* @__PURE__ */ jsx(
428
+ "img",
429
+ {
430
+ src: post.thumbnail,
431
+ alt: post.title,
432
+ className: "w-full h-full object-cover group-hover:scale-105 transition-transform duration-300",
433
+ loading: "lazy"
434
+ }
435
+ ) }) : /* @__PURE__ */ jsx("div", { className: "aspect-[16/9] bg-muted/50 flex items-center justify-center", children: /* @__PURE__ */ jsx(
436
+ "svg",
437
+ {
438
+ className: "w-12 h-12 text-muted-foreground/20",
439
+ fill: "none",
440
+ viewBox: "0 0 24 24",
441
+ stroke: "currentColor",
442
+ children: /* @__PURE__ */ jsx(
443
+ "path",
444
+ {
445
+ strokeLinecap: "round",
446
+ strokeLinejoin: "round",
447
+ strokeWidth: 1.5,
448
+ d: "M12 6.253v13m0-13C10.832 5.477 9.246 5 7.5 5S4.168 5.477 3 6.253v13C4.168 18.477 5.754 18 7.5 18s3.332.477 4.5 1.253m0-13C13.168 5.477 14.754 5 16.5 5c1.747 0 3.332.477 4.5 1.253v13C19.832 18.477 18.247 18 16.5 18c-1.746 0-3.332.477-4.5 1.253"
449
+ }
450
+ )
451
+ }
452
+ ) }),
453
+ /* @__PURE__ */ jsxs("div", { className: "p-5 sm:p-6", children: [
454
+ post.category && /* @__PURE__ */ jsx("span", { className: "inline-block text-xs font-medium text-primary bg-primary/10 px-2.5 py-1 rounded-full mb-3", children: post.category }),
455
+ /* @__PURE__ */ jsx("h3", { className: "text-lg font-semibold text-foreground mb-2 group-hover:text-primary transition-colors line-clamp-2", children: post.title }),
456
+ /* @__PURE__ */ jsx("p", { className: "text-sm text-muted-foreground mb-4 line-clamp-3", children: post.excerpt || post.seoDescription || "" }),
457
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 text-xs text-muted-foreground", children: [
458
+ post.author && /* @__PURE__ */ jsx("span", { className: "font-medium", children: post.author }),
459
+ post.author && formattedDate && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground/40", children: "\xB7" }),
460
+ formattedDate && /* @__PURE__ */ jsx("span", { children: formattedDate }),
461
+ post.readingTime && /* @__PURE__ */ jsxs(Fragment, { children: [
462
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground/40", children: "\xB7" }),
463
+ /* @__PURE__ */ jsxs("span", { children: [
464
+ post.readingTime,
465
+ " min read"
466
+ ] })
467
+ ] })
468
+ ] })
469
+ ] })
470
+ ]
471
+ }
472
+ );
473
+ }
474
+ function BlogListPage(props) {
475
+ const {
476
+ productName,
477
+ heroTitle = "Blog",
478
+ heroSubtitle = "Latest updates, engineering insights, and product news",
479
+ blogPostBasePath = "/blog",
480
+ className = "",
481
+ seoTitle,
482
+ seoDescription,
483
+ seoKeywords
484
+ } = props;
485
+ const client = useWebSDK();
486
+ const config = useWebSDKConfig();
487
+ const { product } = useProduct();
488
+ const resolvedProductId = product?.id || config.productId;
489
+ const [posts, setPosts] = useState([]);
490
+ const [total, setTotal] = useState(0);
491
+ const [loading, setLoading] = useState(true);
492
+ const [error, setError] = useState(null);
493
+ const [offset, setOffset] = useState(0);
494
+ const limit = 12;
495
+ const fetchPosts = useCallback(async () => {
496
+ if (!resolvedProductId) return;
497
+ setLoading(true);
498
+ try {
499
+ const result = await client.query(BLOG_POSTS_QUERY, {
500
+ productId: resolvedProductId,
501
+ limit,
502
+ offset
503
+ });
504
+ if (result.errors?.length) {
505
+ setError(result.errors[0]?.message ?? "Failed to load posts");
506
+ return;
507
+ }
508
+ const blogPosts = (result.data?.publicContentPages?.items || []).filter(
509
+ (p) => p.tags?.includes("blog")
510
+ );
511
+ setPosts(blogPosts);
512
+ setTotal(result.data?.publicContentPages?.total || 0);
513
+ setError(null);
514
+ } catch {
515
+ setError("Failed to load blog posts");
516
+ } finally {
517
+ setLoading(false);
518
+ }
519
+ }, [client, resolvedProductId, offset]);
520
+ useEffect(() => {
521
+ fetchPosts();
522
+ }, [fetchPosts]);
523
+ const featuredPosts = posts.filter((p) => p.featured);
524
+ const regularPosts = posts.filter((p) => !p.featured);
525
+ return /* @__PURE__ */ jsxs("div", { className: `w-full ${className}`, children: [
526
+ seoTitle && /* @__PURE__ */ jsx(
527
+ PageHead,
528
+ {
529
+ title: seoTitle,
530
+ description: seoDescription || heroSubtitle,
531
+ productName,
532
+ keywords: seoKeywords
533
+ }
534
+ ),
535
+ /* @__PURE__ */ jsx("section", { className: "py-16 sm:py-20 md:py-24", children: /* @__PURE__ */ jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: /* @__PURE__ */ jsxs("div", { className: "text-center max-w-3xl mx-auto", children: [
536
+ /* @__PURE__ */ jsx("h1", { className: "text-3xl sm:text-4xl md:text-5xl font-bold tracking-tight text-foreground", children: heroTitle }),
537
+ /* @__PURE__ */ jsx("p", { className: "mt-4 text-lg text-muted-foreground", children: heroSubtitle })
538
+ ] }) }) }),
539
+ /* @__PURE__ */ jsx("section", { className: "pb-16 sm:pb-20", children: /* @__PURE__ */ jsx("div", { className: "max-w-7xl mx-auto px-4 sm:px-6 lg:px-8", children: loading ? /* @__PURE__ */ jsx("div", { className: "grid md:grid-cols-2 lg:grid-cols-3 gap-6 sm:gap-8", children: [1, 2, 3].map((i) => /* @__PURE__ */ jsxs(
540
+ "div",
541
+ {
542
+ className: "bg-card border rounded-xl overflow-hidden animate-pulse",
543
+ children: [
544
+ /* @__PURE__ */ jsx("div", { className: "aspect-[16/9] bg-muted" }),
545
+ /* @__PURE__ */ jsxs("div", { className: "p-6 space-y-3", children: [
546
+ /* @__PURE__ */ jsx("div", { className: "h-4 bg-muted rounded w-1/4" }),
547
+ /* @__PURE__ */ jsx("div", { className: "h-6 bg-muted rounded w-3/4" }),
548
+ /* @__PURE__ */ jsx("div", { className: "h-4 bg-muted rounded" }),
549
+ /* @__PURE__ */ jsx("div", { className: "h-4 bg-muted rounded w-1/2" })
550
+ ] })
551
+ ]
552
+ },
553
+ i
554
+ )) }) : error ? /* @__PURE__ */ jsx("div", { className: "text-center py-12", children: /* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: error }) }) : posts.length === 0 ? /* @__PURE__ */ jsx("div", { className: "text-center py-12", children: /* @__PURE__ */ jsx("p", { className: "text-muted-foreground", children: "No blog posts yet. Check back soon!" }) }) : /* @__PURE__ */ jsxs(Fragment, { children: [
555
+ featuredPosts.length > 0 && /* @__PURE__ */ jsx("div", { className: "grid md:grid-cols-2 gap-6 sm:gap-8 mb-8", children: featuredPosts.map((post) => /* @__PURE__ */ jsx(
556
+ BlogCard,
557
+ {
558
+ post,
559
+ basePath: blogPostBasePath
560
+ },
561
+ post.id
562
+ )) }),
563
+ /* @__PURE__ */ jsx("div", { className: "grid md:grid-cols-2 lg:grid-cols-3 gap-6 sm:gap-8", children: regularPosts.map((post) => /* @__PURE__ */ jsx(
564
+ BlogCard,
565
+ {
566
+ post,
567
+ basePath: blogPostBasePath
568
+ },
569
+ post.id
570
+ )) }),
571
+ total > limit && /* @__PURE__ */ jsxs("div", { className: "flex justify-center gap-4 mt-12", children: [
572
+ /* @__PURE__ */ jsx(
573
+ "button",
574
+ {
575
+ onClick: () => setOffset(Math.max(0, offset - limit)),
576
+ disabled: offset === 0,
577
+ className: "px-5 py-2.5 text-sm font-medium border rounded-lg disabled:opacity-40 hover:bg-muted transition-colors",
578
+ children: "Previous"
579
+ }
580
+ ),
581
+ /* @__PURE__ */ jsx(
582
+ "button",
583
+ {
584
+ onClick: () => setOffset(offset + limit),
585
+ disabled: offset + limit >= total,
586
+ className: "px-5 py-2.5 text-sm font-medium border rounded-lg disabled:opacity-40 hover:bg-muted transition-colors",
587
+ children: "Next"
588
+ }
589
+ )
590
+ ] })
591
+ ] }) }) })
592
+ ] });
593
+ }
594
+ function BlogPostPage(props) {
595
+ const { productName, blogListUrl = "/blog", className = "" } = props;
596
+ const client = useWebSDK();
597
+ const config = useWebSDKConfig();
598
+ const { product } = useProduct();
599
+ const resolvedProductId = product?.id || config.productId;
600
+ const [post, setPost] = useState(null);
601
+ const [loading, setLoading] = useState(true);
602
+ const [error, setError] = useState(null);
603
+ const slug = typeof window !== "undefined" ? window.location.pathname.split("/").pop() || "" : "";
604
+ useEffect(() => {
605
+ if (!slug || !resolvedProductId) return;
606
+ async function fetchPost() {
607
+ setLoading(true);
608
+ try {
609
+ const result = await client.query(BLOG_POST_QUERY, {
610
+ slug,
611
+ productId: resolvedProductId
612
+ });
613
+ if (result.errors?.length) {
614
+ setError(result.errors[0]?.message ?? "Failed to load post");
615
+ return;
616
+ }
617
+ setPost(result.data?.publicContentPage ?? null);
618
+ setError(null);
619
+ } catch {
620
+ setError("Failed to load blog post");
621
+ } finally {
622
+ setLoading(false);
623
+ }
624
+ }
625
+ fetchPost();
626
+ }, [client, slug, resolvedProductId]);
627
+ if (loading) {
628
+ return /* @__PURE__ */ jsx("div", { className: `w-full ${className}`, children: /* @__PURE__ */ jsx("div", { className: "max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-24", children: /* @__PURE__ */ jsxs("div", { className: "animate-pulse space-y-6", children: [
629
+ /* @__PURE__ */ jsx("div", { className: "h-8 bg-muted rounded w-2/3" }),
630
+ /* @__PURE__ */ jsx("div", { className: "h-4 bg-muted rounded w-1/3" }),
631
+ /* @__PURE__ */ jsx("div", { className: "aspect-[16/9] bg-muted rounded-xl" }),
632
+ /* @__PURE__ */ jsx("div", { className: "space-y-3", children: [1, 2, 3, 4, 5].map((i) => /* @__PURE__ */ jsx("div", { className: "h-4 bg-muted rounded" }, i)) })
633
+ ] }) }) });
634
+ }
635
+ if (error || !post) {
636
+ return /* @__PURE__ */ jsx("div", { className: `w-full ${className}`, children: /* @__PURE__ */ jsxs("div", { className: "max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-24 text-center", children: [
637
+ /* @__PURE__ */ jsx("h1", { className: "text-2xl font-bold mb-4", children: "Post not found" }),
638
+ /* @__PURE__ */ jsx("p", { className: "text-muted-foreground mb-6", children: error || "This blog post doesn't exist or has been removed." }),
639
+ /* @__PURE__ */ jsx(
640
+ "a",
641
+ {
642
+ href: blogListUrl,
643
+ className: "text-primary hover:underline font-medium",
644
+ children: "\u2190 Back to Blog"
645
+ }
646
+ )
647
+ ] }) });
648
+ }
649
+ const date = post.publishedAt || post.lastUpdated;
650
+ const formattedDate = date ? new Date(date).toLocaleDateString("en-US", {
651
+ year: "numeric",
652
+ month: "long",
653
+ day: "numeric"
654
+ }) : "";
655
+ return /* @__PURE__ */ jsxs("div", { className: `w-full ${className}`, children: [
656
+ /* @__PURE__ */ jsx(
657
+ PageHead,
658
+ {
659
+ title: post.seoTitle || post.title,
660
+ description: post.seoDescription || post.excerpt || "",
661
+ productName,
662
+ keywords: post.seoKeywords || ""
663
+ }
664
+ ),
665
+ /* @__PURE__ */ jsxs("article", { className: "max-w-4xl mx-auto px-4 sm:px-6 lg:px-8 py-16 sm:py-20", children: [
666
+ /* @__PURE__ */ jsx(
667
+ "a",
668
+ {
669
+ href: blogListUrl,
670
+ className: "inline-flex items-center gap-1 text-sm text-muted-foreground hover:text-foreground mb-8 transition-colors",
671
+ children: "\u2190 Back to Blog"
672
+ }
673
+ ),
674
+ post.category && /* @__PURE__ */ jsx("span", { className: "inline-block text-xs font-medium text-primary bg-primary/10 px-2.5 py-1 rounded-full mb-4", children: post.category }),
675
+ /* @__PURE__ */ jsx("h1", { className: "text-3xl sm:text-4xl md:text-5xl font-bold tracking-tight text-foreground mb-4", children: post.title }),
676
+ /* @__PURE__ */ jsxs("div", { className: "flex items-center gap-3 text-sm text-muted-foreground mb-8", children: [
677
+ post.author && /* @__PURE__ */ jsx("span", { className: "font-medium text-foreground", children: post.author }),
678
+ post.author && formattedDate && /* @__PURE__ */ jsx("span", { className: "text-muted-foreground/40", children: "\xB7" }),
679
+ formattedDate && /* @__PURE__ */ jsx("span", { children: formattedDate }),
680
+ post.readingTime && /* @__PURE__ */ jsxs(Fragment, { children: [
681
+ /* @__PURE__ */ jsx("span", { className: "text-muted-foreground/40", children: "\xB7" }),
682
+ /* @__PURE__ */ jsxs("span", { children: [
683
+ post.readingTime,
684
+ " min read"
685
+ ] })
686
+ ] })
687
+ ] }),
688
+ post.thumbnail && /* @__PURE__ */ jsx("div", { className: "aspect-[16/9] rounded-xl overflow-hidden mb-10", children: /* @__PURE__ */ jsx(
689
+ "img",
690
+ {
691
+ src: post.thumbnail,
692
+ alt: post.title,
693
+ className: "w-full h-full object-cover"
694
+ }
695
+ ) }),
696
+ /* @__PURE__ */ jsx("div", { className: "prose prose-gray dark:prose-invert max-w-none", children: /* @__PURE__ */ jsx(
697
+ ContentRenderer,
698
+ {
699
+ content: post.content,
700
+ format: post.contentFormat
701
+ }
702
+ ) })
703
+ ] })
704
+ ] });
705
+ }
304
706
 
305
- export { ContentRenderer, useContentPage, useContentPages };
707
+ export { BlogListPage, BlogPostPage, ContentRenderer, useContentPage, useContentPages };
306
708
  //# sourceMappingURL=index.mjs.map
307
709
  //# sourceMappingURL=index.mjs.map