@webdevarif/dashui 0.2.5 → 0.3.0

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
@@ -96,6 +96,11 @@ __export(index_exports, {
96
96
  Popover: () => Popover,
97
97
  PopoverContent: () => PopoverContent,
98
98
  PopoverTrigger: () => PopoverTrigger,
99
+ PostEditorShell: () => PostEditorShell,
100
+ PostFiltersBar: () => PostFiltersBar,
101
+ PostListTable: () => PostListTable,
102
+ PostSidebarSection: () => PostSidebarSection,
103
+ PostStatusBadge: () => PostStatusBadge,
99
104
  SearchBar: () => SearchBar,
100
105
  Select: () => Select,
101
106
  SelectContent: () => SelectContent,
@@ -110,6 +115,7 @@ __export(index_exports, {
110
115
  Separator: () => Separator3,
111
116
  Sidebar: () => Sidebar,
112
117
  Skeleton: () => Skeleton2,
118
+ SlugInput: () => SlugInput,
113
119
  Stats: () => Stats,
114
120
  StorageBar: () => StorageBar,
115
121
  Switch: () => Switch,
@@ -2575,6 +2581,730 @@ function ConfirmDialog({
2575
2581
  ] }) });
2576
2582
  }
2577
2583
 
2584
+ // src/components/content/post-status-badge.tsx
2585
+ var import_jsx_runtime42 = require("react/jsx-runtime");
2586
+ var statusConfig = {
2587
+ DRAFT: {
2588
+ label: "Draft",
2589
+ container: "bg-muted text-muted-foreground",
2590
+ dot: "bg-gray-400"
2591
+ },
2592
+ PUBLISHED: {
2593
+ label: "Published",
2594
+ container: "bg-primary/10 text-primary",
2595
+ dot: "bg-primary animate-pulse"
2596
+ },
2597
+ SCHEDULED: {
2598
+ label: "Scheduled",
2599
+ container: "bg-blue-50 text-blue-600 dark:bg-blue-950 dark:text-blue-400",
2600
+ dot: "bg-blue-500 dark:bg-blue-400"
2601
+ },
2602
+ ARCHIVED: {
2603
+ label: "Archived",
2604
+ container: "bg-amber-50 text-amber-600 dark:bg-amber-950 dark:text-amber-400",
2605
+ dot: "bg-amber-500 dark:bg-amber-400"
2606
+ }
2607
+ };
2608
+ var sizeConfig = {
2609
+ sm: "text-[10px] px-1.5 py-0.5",
2610
+ md: "text-xs px-2 py-1"
2611
+ };
2612
+ function PostStatusBadge({
2613
+ status,
2614
+ size = "md",
2615
+ className
2616
+ }) {
2617
+ const config = statusConfig[status];
2618
+ return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
2619
+ "span",
2620
+ {
2621
+ className: cn(
2622
+ "inline-flex items-center gap-1.5 rounded-full font-medium",
2623
+ config.container,
2624
+ sizeConfig[size],
2625
+ className
2626
+ ),
2627
+ children: [
2628
+ /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
2629
+ "span",
2630
+ {
2631
+ className: cn("inline-block rounded-full", config.dot, {
2632
+ "w-1.5 h-1.5": size === "md",
2633
+ "w-1 h-1": size === "sm"
2634
+ })
2635
+ }
2636
+ ),
2637
+ config.label
2638
+ ]
2639
+ }
2640
+ );
2641
+ }
2642
+
2643
+ // src/components/content/post-list-table.tsx
2644
+ var React21 = __toESM(require("react"));
2645
+
2646
+ // src/components/Skeleton.tsx
2647
+ var import_jsx_runtime43 = require("react/jsx-runtime");
2648
+ function Skeleton2({ width = "100%", height = 16, rounded, style }) {
2649
+ return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
2650
+ "div",
2651
+ {
2652
+ style: {
2653
+ width,
2654
+ height,
2655
+ background: "var(--muted, #e5e7eb)",
2656
+ borderRadius: rounded ?? "var(--radius, 0.5rem)",
2657
+ overflow: "hidden",
2658
+ position: "relative",
2659
+ flexShrink: 0,
2660
+ ...style
2661
+ },
2662
+ children: /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
2663
+ "div",
2664
+ {
2665
+ style: {
2666
+ position: "absolute",
2667
+ inset: 0,
2668
+ background: "linear-gradient(90deg, transparent 0%, color-mix(in oklab, var(--background, #fff) 40%, transparent) 50%, transparent 100%)",
2669
+ animation: "dashui-shimmer 1.6s ease-in-out infinite"
2670
+ }
2671
+ }
2672
+ )
2673
+ }
2674
+ );
2675
+ }
2676
+
2677
+ // src/components/content/post-list-table.tsx
2678
+ var import_jsx_runtime44 = require("react/jsx-runtime");
2679
+ function IconEdit() {
2680
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2681
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("path", { d: "M11 4H4a2 2 0 0 0-2 2v14a2 2 0 0 0 2 2h14a2 2 0 0 0 2-2v-7" }),
2682
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("path", { d: "M18.5 2.5a2.121 2.121 0 0 1 3 3L12 15l-4 1 1-4 9.5-9.5z" })
2683
+ ] });
2684
+ }
2685
+ function IconTrash() {
2686
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2687
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("polyline", { points: "3 6 5 6 21 6" }),
2688
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("path", { d: "M19 6l-1 14a2 2 0 0 1-2 2H8a2 2 0 0 1-2-2L5 6" }),
2689
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("path", { d: "M10 11v6" }),
2690
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("path", { d: "M14 11v6" }),
2691
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("path", { d: "M9 6V4a1 1 0 0 1 1-1h4a1 1 0 0 1 1 1v2" })
2692
+ ] });
2693
+ }
2694
+ function IconCopy() {
2695
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2696
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2", ry: "2" }),
2697
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })
2698
+ ] });
2699
+ }
2700
+ function IconMoreHorizontal() {
2701
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("svg", { width: "16", height: "16", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2702
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("circle", { cx: "5", cy: "12", r: "1", fill: "currentColor" }),
2703
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("circle", { cx: "12", cy: "12", r: "1", fill: "currentColor" }),
2704
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("circle", { cx: "19", cy: "12", r: "1", fill: "currentColor" })
2705
+ ] });
2706
+ }
2707
+ function IconChevronRight() {
2708
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("svg", { width: "12", height: "12", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("polyline", { points: "9 18 15 12 9 6" }) });
2709
+ }
2710
+ function IconImage() {
2711
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
2712
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("rect", { x: "3", y: "3", width: "18", height: "18", rx: "2", ry: "2" }),
2713
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("circle", { cx: "8.5", cy: "8.5", r: "1.5" }),
2714
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("polyline", { points: "21 15 16 10 5 21" })
2715
+ ] });
2716
+ }
2717
+ function IconPlus() {
2718
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("svg", { width: "14", height: "14", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: [
2719
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("line", { x1: "12", y1: "5", x2: "12", y2: "19" }),
2720
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("line", { x1: "5", y1: "12", x2: "19", y2: "12" })
2721
+ ] });
2722
+ }
2723
+ function formatDate(date) {
2724
+ return new Date(date).toLocaleDateString("en-US", {
2725
+ year: "numeric",
2726
+ month: "short",
2727
+ day: "numeric"
2728
+ });
2729
+ }
2730
+ function getInitials(name) {
2731
+ return name.split(" ").slice(0, 2).map((w) => w[0]?.toUpperCase() ?? "").join("");
2732
+ }
2733
+ function RowActions({ post, onEdit, onDelete, onDuplicate, onStatusChange }) {
2734
+ const [open, setOpen] = React21.useState(false);
2735
+ const [statusOpen, setStatusOpen] = React21.useState(false);
2736
+ const ref = React21.useRef(null);
2737
+ React21.useEffect(() => {
2738
+ if (!open) return;
2739
+ function handleClick(e) {
2740
+ if (ref.current && !ref.current.contains(e.target)) {
2741
+ setOpen(false);
2742
+ setStatusOpen(false);
2743
+ }
2744
+ }
2745
+ document.addEventListener("mousedown", handleClick);
2746
+ return () => document.removeEventListener("mousedown", handleClick);
2747
+ }, [open]);
2748
+ const statusOptions = [
2749
+ { label: "Draft", value: "DRAFT" },
2750
+ { label: "Publish", value: "PUBLISHED" },
2751
+ { label: "Archive", value: "ARCHIVED" }
2752
+ ];
2753
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "relative flex items-center gap-1", ref, children: [
2754
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
2755
+ "button",
2756
+ {
2757
+ onClick: () => onEdit?.(post.id),
2758
+ className: "inline-flex items-center justify-center h-7 w-7 rounded-md text-muted-foreground hover:bg-accent hover:text-foreground transition-colors",
2759
+ title: "Edit",
2760
+ children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(IconEdit, {})
2761
+ }
2762
+ ),
2763
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
2764
+ "button",
2765
+ {
2766
+ onClick: () => {
2767
+ setOpen((v) => !v);
2768
+ setStatusOpen(false);
2769
+ },
2770
+ className: "inline-flex items-center justify-center h-7 w-7 rounded-md text-muted-foreground hover:bg-accent hover:text-foreground transition-colors",
2771
+ title: "More actions",
2772
+ children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(IconMoreHorizontal, {})
2773
+ }
2774
+ ),
2775
+ open && /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "absolute right-0 top-8 z-50 min-w-[160px] rounded-lg border border-border bg-card shadow-md py-1", children: [
2776
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
2777
+ "button",
2778
+ {
2779
+ onClick: () => {
2780
+ onDuplicate?.(post.id);
2781
+ setOpen(false);
2782
+ },
2783
+ className: "flex w-full items-center gap-2 px-3 py-1.5 text-sm hover:bg-accent transition-colors",
2784
+ children: [
2785
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(IconCopy, {}),
2786
+ "Duplicate"
2787
+ ]
2788
+ }
2789
+ ),
2790
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "relative", children: [
2791
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
2792
+ "button",
2793
+ {
2794
+ onMouseEnter: () => setStatusOpen(true),
2795
+ onMouseLeave: () => setStatusOpen(false),
2796
+ onClick: () => setStatusOpen((v) => !v),
2797
+ className: "flex w-full items-center justify-between gap-2 px-3 py-1.5 text-sm hover:bg-accent transition-colors",
2798
+ children: [
2799
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { children: "Change status" }),
2800
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(IconChevronRight, {})
2801
+ ]
2802
+ }
2803
+ ),
2804
+ statusOpen && /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
2805
+ "div",
2806
+ {
2807
+ className: "absolute left-full top-0 z-50 min-w-[130px] rounded-lg border border-border bg-card shadow-md py-1",
2808
+ onMouseEnter: () => setStatusOpen(true),
2809
+ onMouseLeave: () => setStatusOpen(false),
2810
+ children: statusOptions.map((opt) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
2811
+ "button",
2812
+ {
2813
+ onClick: () => {
2814
+ onStatusChange?.(post.id, opt.value);
2815
+ setOpen(false);
2816
+ setStatusOpen(false);
2817
+ },
2818
+ className: cn(
2819
+ "flex w-full items-center gap-2 px-3 py-1.5 text-sm hover:bg-accent transition-colors",
2820
+ post.status === opt.value && "text-primary font-medium"
2821
+ ),
2822
+ children: opt.label
2823
+ },
2824
+ opt.value
2825
+ ))
2826
+ }
2827
+ )
2828
+ ] }),
2829
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "my-1 border-t border-border" }),
2830
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
2831
+ "button",
2832
+ {
2833
+ onClick: () => {
2834
+ onDelete?.(post.id);
2835
+ setOpen(false);
2836
+ },
2837
+ className: "flex w-full items-center gap-2 px-3 py-1.5 text-sm text-destructive hover:bg-destructive/10 transition-colors",
2838
+ children: [
2839
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(IconTrash, {}),
2840
+ "Delete"
2841
+ ]
2842
+ }
2843
+ )
2844
+ ] })
2845
+ ] });
2846
+ }
2847
+ function SkeletonRow() {
2848
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("tr", { children: [
2849
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("td", { className: "px-4 py-3", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Skeleton2, { className: "w-10 h-10 rounded-lg" }) }),
2850
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("td", { className: "px-4 py-3", children: [
2851
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Skeleton2, { className: "h-4 w-40 mb-1.5" }),
2852
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Skeleton2, { className: "h-3 w-24" })
2853
+ ] }),
2854
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("td", { className: "px-4 py-3", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Skeleton2, { className: "h-5 w-20 rounded-full" }) }),
2855
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("td", { className: "px-4 py-3", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex items-center gap-2", children: [
2856
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Skeleton2, { className: "w-6 h-6 rounded-full" }),
2857
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Skeleton2, { className: "h-4 w-20" })
2858
+ ] }) }),
2859
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("td", { className: "px-4 py-3", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Skeleton2, { className: "h-4 w-24" }) }),
2860
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("td", { className: "px-4 py-3", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex gap-1", children: [
2861
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Skeleton2, { className: "w-7 h-7 rounded-md" }),
2862
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(Skeleton2, { className: "w-7 h-7 rounded-md" })
2863
+ ] }) })
2864
+ ] });
2865
+ }
2866
+ function PostListTable({
2867
+ posts,
2868
+ loading = false,
2869
+ singularLabel = "Post",
2870
+ onEdit,
2871
+ onDelete,
2872
+ onDuplicate,
2873
+ onStatusChange,
2874
+ emptyMessage,
2875
+ emptyIcon,
2876
+ onNewPost,
2877
+ newPostLabel,
2878
+ className
2879
+ }) {
2880
+ const isEmpty = !loading && posts.length === 0;
2881
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: cn("w-full overflow-x-auto rounded-lg border border-border bg-card", className), children: [
2882
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("table", { className: "w-full text-sm", children: [
2883
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("thead", { children: /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("tr", { className: "border-b border-border bg-muted/40", children: [
2884
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground w-14", children: "Image" }),
2885
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Title" }),
2886
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Status" }),
2887
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Author" }),
2888
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Date" }),
2889
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("th", { className: "px-4 py-2.5 text-right text-xs font-medium text-muted-foreground", children: "Actions" })
2890
+ ] }) }),
2891
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("tbody", { children: loading ? Array.from({ length: 5 }).map((_, i) => /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(SkeletonRow, {}, i)) : isEmpty ? null : posts.map((post) => {
2892
+ const date = post.status === "PUBLISHED" && post.publishedAt ? formatDate(post.publishedAt) : formatDate(post.createdAt);
2893
+ return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
2894
+ "tr",
2895
+ {
2896
+ className: "border-b border-border last:border-0 hover:bg-muted/30 transition-colors",
2897
+ children: [
2898
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("td", { className: "px-4 py-3", children: post.featuredImageUrl ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
2899
+ "img",
2900
+ {
2901
+ src: post.featuredImageUrl,
2902
+ alt: post.title,
2903
+ className: "w-10 h-10 rounded-lg object-cover"
2904
+ }
2905
+ ) : /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "w-10 h-10 rounded-lg bg-muted flex items-center justify-center text-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(IconImage, {}) }) }),
2906
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("td", { className: "px-4 py-3", children: [
2907
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "font-medium text-foreground leading-tight truncate max-w-[240px]", children: post.title }),
2908
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "text-xs text-muted-foreground mt-0.5 truncate max-w-[240px]", children: [
2909
+ "/",
2910
+ post.slug
2911
+ ] })
2912
+ ] }),
2913
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("td", { className: "px-4 py-3", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(PostStatusBadge, { status: post.status, size: "sm" }) }),
2914
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("td", { className: "px-4 py-3", children: post.author ? /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex items-center gap-2", children: [
2915
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "w-6 h-6 rounded-full bg-primary/20 text-primary flex items-center justify-center text-[10px] font-semibold shrink-0", children: getInitials(post.author) }),
2916
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "text-sm text-foreground truncate max-w-[100px]", children: post.author })
2917
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("span", { className: "text-muted-foreground text-xs", children: "\u2014" }) }),
2918
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("td", { className: "px-4 py-3 text-sm text-muted-foreground whitespace-nowrap", children: date }),
2919
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("td", { className: "px-4 py-3", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "flex justify-end", children: /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
2920
+ RowActions,
2921
+ {
2922
+ post,
2923
+ onEdit,
2924
+ onDelete,
2925
+ onDuplicate,
2926
+ onStatusChange
2927
+ }
2928
+ ) }) })
2929
+ ]
2930
+ },
2931
+ post.id
2932
+ );
2933
+ }) })
2934
+ ] }),
2935
+ isEmpty && /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { className: "flex flex-col items-center justify-center py-16 px-6 text-center", children: [
2936
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("div", { className: "text-muted-foreground mb-3", children: emptyIcon ?? /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("svg", { width: "40", height: "40", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.2", strokeLinecap: "round", strokeLinejoin: "round", className: "opacity-40", children: [
2937
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("path", { d: "M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z" }),
2938
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("polyline", { points: "14 2 14 8 20 8" }),
2939
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("line", { x1: "16", y1: "13", x2: "8", y2: "13" }),
2940
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("line", { x1: "16", y1: "17", x2: "8", y2: "17" }),
2941
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("polyline", { points: "10 9 9 9 8 9" })
2942
+ ] }) }),
2943
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)("p", { className: "text-sm text-muted-foreground mb-4", children: emptyMessage ?? `No ${singularLabel.toLowerCase()}s yet.` }),
2944
+ onNewPost && /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)(
2945
+ "button",
2946
+ {
2947
+ onClick: onNewPost,
2948
+ className: "inline-flex items-center gap-1.5 rounded-lg bg-primary px-3 py-1.5 text-sm font-medium text-primary-foreground hover:bg-primary/90 transition-colors",
2949
+ children: [
2950
+ /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(IconPlus, {}),
2951
+ newPostLabel ?? `New ${singularLabel}`
2952
+ ]
2953
+ }
2954
+ )
2955
+ ] })
2956
+ ] });
2957
+ }
2958
+
2959
+ // src/components/content/post-filters-bar.tsx
2960
+ var import_jsx_runtime45 = require("react/jsx-runtime");
2961
+ var STATUS_TABS = [
2962
+ { value: "all", label: "All" },
2963
+ { value: "DRAFT", label: "Draft" },
2964
+ { value: "PUBLISHED", label: "Published" },
2965
+ { value: "SCHEDULED", label: "Scheduled" },
2966
+ { value: "ARCHIVED", label: "Archived" }
2967
+ ];
2968
+ function IconSearch() {
2969
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
2970
+ "svg",
2971
+ {
2972
+ width: "14",
2973
+ height: "14",
2974
+ viewBox: "0 0 24 24",
2975
+ fill: "none",
2976
+ stroke: "currentColor",
2977
+ strokeWidth: "2",
2978
+ strokeLinecap: "round",
2979
+ strokeLinejoin: "round",
2980
+ children: [
2981
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("circle", { cx: "11", cy: "11", r: "8" }),
2982
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("line", { x1: "21", y1: "21", x2: "16.65", y2: "16.65" })
2983
+ ]
2984
+ }
2985
+ );
2986
+ }
2987
+ function IconPlus2() {
2988
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
2989
+ "svg",
2990
+ {
2991
+ width: "14",
2992
+ height: "14",
2993
+ viewBox: "0 0 24 24",
2994
+ fill: "none",
2995
+ stroke: "currentColor",
2996
+ strokeWidth: "2",
2997
+ strokeLinecap: "round",
2998
+ strokeLinejoin: "round",
2999
+ children: [
3000
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("line", { x1: "12", y1: "5", x2: "12", y2: "19" }),
3001
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("line", { x1: "5", y1: "12", x2: "19", y2: "12" })
3002
+ ]
3003
+ }
3004
+ );
3005
+ }
3006
+ function PostFiltersBar({
3007
+ search,
3008
+ onSearch,
3009
+ status,
3010
+ onStatusChange,
3011
+ onNew,
3012
+ newLabel = "New Post",
3013
+ total,
3014
+ typeLabel = "Posts",
3015
+ className
3016
+ }) {
3017
+ return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: cn("space-y-2", className), children: [
3018
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "flex flex-wrap items-center gap-3", children: [
3019
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { className: "relative flex items-center", children: [
3020
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("span", { className: "absolute left-2.5 text-muted-foreground pointer-events-none", children: /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(IconSearch, {}) }),
3021
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
3022
+ "input",
3023
+ {
3024
+ type: "text",
3025
+ value: search,
3026
+ onChange: (e) => onSearch(e.target.value),
3027
+ placeholder: `Search ${typeLabel}\u2026`,
3028
+ className: "h-8 pl-8 pr-3 rounded-lg border border-border bg-background text-sm placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary/30 focus:border-primary transition-colors w-56"
3029
+ }
3030
+ )
3031
+ ] }),
3032
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "flex items-center gap-1 rounded-lg bg-muted p-0.5", children: STATUS_TABS.map((tab) => /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
3033
+ "button",
3034
+ {
3035
+ onClick: () => onStatusChange(tab.value),
3036
+ className: cn(
3037
+ "rounded-md px-2.5 py-1 text-xs font-medium transition-colors",
3038
+ status === tab.value ? "bg-background text-foreground shadow-sm" : "text-muted-foreground hover:text-foreground"
3039
+ ),
3040
+ children: tab.label
3041
+ },
3042
+ tab.value
3043
+ )) }),
3044
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)("div", { className: "flex-1" }),
3045
+ onNew && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)(
3046
+ "button",
3047
+ {
3048
+ onClick: onNew,
3049
+ className: "inline-flex items-center gap-1.5 h-8 rounded-lg bg-primary px-3 text-sm font-medium text-primary-foreground hover:bg-primary/90 transition-colors",
3050
+ children: [
3051
+ /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(IconPlus2, {}),
3052
+ newLabel
3053
+ ]
3054
+ }
3055
+ )
3056
+ ] }),
3057
+ total !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("p", { className: "text-xs text-muted-foreground", children: [
3058
+ total,
3059
+ " ",
3060
+ total === 1 ? typeLabel.replace(/s$/, "") : typeLabel
3061
+ ] })
3062
+ ] });
3063
+ }
3064
+
3065
+ // src/components/content/post-editor-shell.tsx
3066
+ var import_jsx_runtime46 = require("react/jsx-runtime");
3067
+ function IconArrowLeft() {
3068
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
3069
+ "svg",
3070
+ {
3071
+ width: "14",
3072
+ height: "14",
3073
+ viewBox: "0 0 24 24",
3074
+ fill: "none",
3075
+ stroke: "currentColor",
3076
+ strokeWidth: "2",
3077
+ strokeLinecap: "round",
3078
+ strokeLinejoin: "round",
3079
+ children: [
3080
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("line", { x1: "19", y1: "12", x2: "5", y2: "12" }),
3081
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("polyline", { points: "12 19 5 12 12 5" })
3082
+ ]
3083
+ }
3084
+ );
3085
+ }
3086
+ function IconSpinner() {
3087
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
3088
+ "svg",
3089
+ {
3090
+ width: "14",
3091
+ height: "14",
3092
+ viewBox: "0 0 24 24",
3093
+ fill: "none",
3094
+ stroke: "currentColor",
3095
+ strokeWidth: "2",
3096
+ strokeLinecap: "round",
3097
+ strokeLinejoin: "round",
3098
+ className: "animate-spin",
3099
+ children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("path", { d: "M21 12a9 9 0 1 1-6.219-8.56" })
3100
+ }
3101
+ );
3102
+ }
3103
+ function IconMoreHorizontal2() {
3104
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
3105
+ "svg",
3106
+ {
3107
+ width: "16",
3108
+ height: "16",
3109
+ viewBox: "0 0 24 24",
3110
+ fill: "none",
3111
+ stroke: "currentColor",
3112
+ strokeWidth: "2",
3113
+ strokeLinecap: "round",
3114
+ strokeLinejoin: "round",
3115
+ children: [
3116
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("circle", { cx: "5", cy: "12", r: "1", fill: "currentColor" }),
3117
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("circle", { cx: "12", cy: "12", r: "1", fill: "currentColor" }),
3118
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("circle", { cx: "19", cy: "12", r: "1", fill: "currentColor" })
3119
+ ]
3120
+ }
3121
+ );
3122
+ }
3123
+ function PostEditorShell({
3124
+ title,
3125
+ backLabel = "Back",
3126
+ onBack,
3127
+ onSave,
3128
+ onPublish,
3129
+ saving = false,
3130
+ publishing = false,
3131
+ status,
3132
+ children,
3133
+ sidebar,
3134
+ className
3135
+ }) {
3136
+ return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: cn("flex flex-col h-screen bg-background overflow-hidden", className), children: [
3137
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex items-center gap-3 h-14 px-4 border-b border-border bg-card shrink-0", children: [
3138
+ onBack && /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
3139
+ "button",
3140
+ {
3141
+ onClick: onBack,
3142
+ className: "inline-flex items-center gap-1.5 rounded-lg px-2.5 py-1.5 text-sm text-muted-foreground hover:bg-accent hover:text-foreground transition-colors",
3143
+ children: [
3144
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(IconArrowLeft, {}),
3145
+ backLabel
3146
+ ]
3147
+ }
3148
+ ),
3149
+ onBack && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "h-5 w-px bg-border" }),
3150
+ title && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { className: "text-sm font-medium text-muted-foreground truncate max-w-xs", children: title }),
3151
+ status && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(PostStatusBadge, { status, size: "sm" }),
3152
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "flex-1" }),
3153
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("button", { className: "inline-flex items-center justify-center h-8 w-8 rounded-lg text-muted-foreground hover:bg-accent hover:text-foreground transition-colors", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(IconMoreHorizontal2, {}) }),
3154
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
3155
+ "button",
3156
+ {
3157
+ onClick: onSave,
3158
+ disabled: saving,
3159
+ className: "inline-flex items-center gap-1.5 h-8 rounded-lg border border-border bg-background px-3 text-sm font-medium hover:bg-accent transition-colors disabled:opacity-60",
3160
+ children: [
3161
+ saving && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(IconSpinner, {}),
3162
+ "Save Draft"
3163
+ ]
3164
+ }
3165
+ ),
3166
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)(
3167
+ "button",
3168
+ {
3169
+ onClick: onPublish,
3170
+ disabled: publishing,
3171
+ className: "inline-flex items-center gap-1.5 h-8 rounded-lg bg-primary px-3 text-sm font-medium text-primary-foreground hover:bg-primary/90 transition-colors disabled:opacity-60",
3172
+ children: [
3173
+ publishing && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(IconSpinner, {}),
3174
+ "Publish"
3175
+ ]
3176
+ }
3177
+ )
3178
+ ] }),
3179
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { className: "flex flex-1 overflow-hidden", children: [
3180
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "flex-1 overflow-y-auto p-6", children: /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "max-w-3xl mx-auto", children }) }),
3181
+ /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("div", { className: "w-72 shrink-0 border-l border-border overflow-y-auto p-4", children: sidebar })
3182
+ ] })
3183
+ ] });
3184
+ }
3185
+
3186
+ // src/components/content/slug-input.tsx
3187
+ var import_jsx_runtime47 = require("react/jsx-runtime");
3188
+ function IconRefresh() {
3189
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(
3190
+ "svg",
3191
+ {
3192
+ width: "13",
3193
+ height: "13",
3194
+ viewBox: "0 0 24 24",
3195
+ fill: "none",
3196
+ stroke: "currentColor",
3197
+ strokeWidth: "2",
3198
+ strokeLinecap: "round",
3199
+ strokeLinejoin: "round",
3200
+ children: [
3201
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("polyline", { points: "23 4 23 10 17 10" }),
3202
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("polyline", { points: "1 20 1 14 7 14" }),
3203
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("path", { d: "M3.51 9a9 9 0 0 1 14.85-3.36L23 10M1 14l4.64 4.36A9 9 0 0 0 20.49 15" })
3204
+ ]
3205
+ }
3206
+ );
3207
+ }
3208
+ function SlugInput({
3209
+ value,
3210
+ onChange,
3211
+ onGenerate,
3212
+ prefix,
3213
+ disabled = false,
3214
+ className
3215
+ }) {
3216
+ return /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: cn("space-y-1", className), children: [
3217
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)("div", { className: "flex items-center gap-1", children: [
3218
+ prefix && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("span", { className: "shrink-0 text-sm text-muted-foreground select-none", children: prefix }),
3219
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
3220
+ "input",
3221
+ {
3222
+ type: "text",
3223
+ value,
3224
+ onChange: (e) => onChange(e.target.value),
3225
+ disabled,
3226
+ className: cn(
3227
+ "flex-1 h-8 border-0 border-b border-input bg-transparent text-sm focus:outline-none focus:border-primary transition-colors",
3228
+ disabled && "opacity-60 cursor-not-allowed"
3229
+ ),
3230
+ placeholder: "your-slug-here"
3231
+ }
3232
+ ),
3233
+ onGenerate && /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
3234
+ "button",
3235
+ {
3236
+ onClick: onGenerate,
3237
+ disabled,
3238
+ title: "Generate slug",
3239
+ className: "inline-flex items-center justify-center h-7 w-7 rounded-md text-muted-foreground hover:bg-accent hover:text-foreground transition-colors disabled:opacity-60",
3240
+ children: /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(IconRefresh, {})
3241
+ }
3242
+ )
3243
+ ] }),
3244
+ /* @__PURE__ */ (0, import_jsx_runtime47.jsx)("p", { className: "text-[10px] text-muted-foreground", children: "Only lowercase letters, numbers, and hyphens" })
3245
+ ] });
3246
+ }
3247
+
3248
+ // src/components/content/post-sidebar-section.tsx
3249
+ var React22 = __toESM(require("react"));
3250
+ var import_jsx_runtime48 = require("react/jsx-runtime");
3251
+ function IconChevronDown() {
3252
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
3253
+ "svg",
3254
+ {
3255
+ width: "14",
3256
+ height: "14",
3257
+ viewBox: "0 0 24 24",
3258
+ fill: "none",
3259
+ stroke: "currentColor",
3260
+ strokeWidth: "2",
3261
+ strokeLinecap: "round",
3262
+ strokeLinejoin: "round",
3263
+ children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("polyline", { points: "6 9 12 15 18 9" })
3264
+ }
3265
+ );
3266
+ }
3267
+ function PostSidebarSection({
3268
+ title,
3269
+ children,
3270
+ defaultOpen = true,
3271
+ className
3272
+ }) {
3273
+ const [open, setOpen] = React22.useState(defaultOpen);
3274
+ return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { className: cn("border-b border-border", className), children: [
3275
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)(
3276
+ "button",
3277
+ {
3278
+ onClick: () => setOpen((v) => !v),
3279
+ className: "flex w-full items-center justify-between py-3 px-0 text-sm font-medium text-foreground hover:text-primary transition-colors",
3280
+ children: [
3281
+ title,
3282
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
3283
+ "span",
3284
+ {
3285
+ className: cn(
3286
+ "text-muted-foreground transition-transform duration-200",
3287
+ open ? "rotate-0" : "-rotate-90"
3288
+ ),
3289
+ children: /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(IconChevronDown, {})
3290
+ }
3291
+ )
3292
+ ]
3293
+ }
3294
+ ),
3295
+ /* @__PURE__ */ (0, import_jsx_runtime48.jsx)(
3296
+ "div",
3297
+ {
3298
+ className: cn(
3299
+ "overflow-hidden transition-all duration-200",
3300
+ open ? "max-h-[9999px] pb-4 opacity-100" : "max-h-0 opacity-0 pointer-events-none"
3301
+ ),
3302
+ children
3303
+ }
3304
+ )
3305
+ ] });
3306
+ }
3307
+
2578
3308
  // src/hooks/index.ts
2579
3309
  var import_react = require("react");
2580
3310
  function useDisclosure(initial = false) {
@@ -2594,9 +3324,9 @@ function usePagination(total, pageSize = 20) {
2594
3324
  }
2595
3325
 
2596
3326
  // src/components/auth/AuthShell.tsx
2597
- var import_jsx_runtime42 = require("react/jsx-runtime");
3327
+ var import_jsx_runtime49 = require("react/jsx-runtime");
2598
3328
  function AuthShell({ children, pattern = "dots", maxWidth = "520px" }) {
2599
- return /* @__PURE__ */ (0, import_jsx_runtime42.jsxs)(
3329
+ return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)(
2600
3330
  "div",
2601
3331
  {
2602
3332
  style: {
@@ -2611,7 +3341,7 @@ function AuthShell({ children, pattern = "dots", maxWidth = "520px" }) {
2611
3341
  overflow: "hidden"
2612
3342
  },
2613
3343
  children: [
2614
- pattern === "dots" && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
3344
+ pattern === "dots" && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
2615
3345
  "div",
2616
3346
  {
2617
3347
  "aria-hidden": true,
@@ -2625,7 +3355,7 @@ function AuthShell({ children, pattern = "dots", maxWidth = "520px" }) {
2625
3355
  }
2626
3356
  }
2627
3357
  ),
2628
- pattern === "grid" && /* @__PURE__ */ (0, import_jsx_runtime42.jsx)(
3358
+ pattern === "grid" && /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
2629
3359
  "div",
2630
3360
  {
2631
3361
  "aria-hidden": true,
@@ -2639,16 +3369,16 @@ function AuthShell({ children, pattern = "dots", maxWidth = "520px" }) {
2639
3369
  }
2640
3370
  }
2641
3371
  ),
2642
- /* @__PURE__ */ (0, import_jsx_runtime42.jsx)("div", { style: { position: "relative", zIndex: 1, width: "100%", maxWidth }, children })
3372
+ /* @__PURE__ */ (0, import_jsx_runtime49.jsx)("div", { style: { position: "relative", zIndex: 1, width: "100%", maxWidth }, children })
2643
3373
  ]
2644
3374
  }
2645
3375
  );
2646
3376
  }
2647
3377
 
2648
3378
  // src/components/auth/AuthCard.tsx
2649
- var import_jsx_runtime43 = require("react/jsx-runtime");
3379
+ var import_jsx_runtime50 = require("react/jsx-runtime");
2650
3380
  function AuthCard({ children, padding = "24px 28px" }) {
2651
- return /* @__PURE__ */ (0, import_jsx_runtime43.jsx)(
3381
+ return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
2652
3382
  "div",
2653
3383
  {
2654
3384
  style: {
@@ -2665,10 +3395,10 @@ function AuthCard({ children, padding = "24px 28px" }) {
2665
3395
  }
2666
3396
 
2667
3397
  // src/components/auth/AuthLogo.tsx
2668
- var import_jsx_runtime44 = require("react/jsx-runtime");
3398
+ var import_jsx_runtime51 = require("react/jsx-runtime");
2669
3399
  function AuthLogo({ appName = "Builify CMS", letter = "B", imageUrl, size = 36 }) {
2670
- return /* @__PURE__ */ (0, import_jsx_runtime44.jsxs)("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", gap: "10px", marginBottom: "28px" }, children: [
2671
- imageUrl ? /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
3400
+ return /* @__PURE__ */ (0, import_jsx_runtime51.jsxs)("div", { style: { display: "flex", alignItems: "center", justifyContent: "center", gap: "10px", marginBottom: "28px" }, children: [
3401
+ imageUrl ? /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
2672
3402
  "img",
2673
3403
  {
2674
3404
  src: imageUrl,
@@ -2677,7 +3407,7 @@ function AuthLogo({ appName = "Builify CMS", letter = "B", imageUrl, size = 36 }
2677
3407
  height: size,
2678
3408
  style: { borderRadius: "calc(var(--radius, 0.5rem) * 1.2)", flexShrink: 0, display: "block" }
2679
3409
  }
2680
- ) : /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
3410
+ ) : /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
2681
3411
  "div",
2682
3412
  {
2683
3413
  style: {
@@ -2696,7 +3426,7 @@ function AuthLogo({ appName = "Builify CMS", letter = "B", imageUrl, size = 36 }
2696
3426
  children: letter
2697
3427
  }
2698
3428
  ),
2699
- /* @__PURE__ */ (0, import_jsx_runtime44.jsx)(
3429
+ /* @__PURE__ */ (0, import_jsx_runtime51.jsx)(
2700
3430
  "span",
2701
3431
  {
2702
3432
  style: {
@@ -2712,10 +3442,10 @@ function AuthLogo({ appName = "Builify CMS", letter = "B", imageUrl, size = 36 }
2712
3442
  }
2713
3443
 
2714
3444
  // src/components/auth/AuthHeader.tsx
2715
- var import_jsx_runtime45 = require("react/jsx-runtime");
3445
+ var import_jsx_runtime52 = require("react/jsx-runtime");
2716
3446
  function AuthHeader({ title, description }) {
2717
- return /* @__PURE__ */ (0, import_jsx_runtime45.jsxs)("div", { style: { marginBottom: "24px", textAlign: "center" }, children: [
2718
- /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
3447
+ return /* @__PURE__ */ (0, import_jsx_runtime52.jsxs)("div", { style: { marginBottom: "24px", textAlign: "center" }, children: [
3448
+ /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
2719
3449
  "h1",
2720
3450
  {
2721
3451
  style: {
@@ -2728,7 +3458,7 @@ function AuthHeader({ title, description }) {
2728
3458
  children: title
2729
3459
  }
2730
3460
  ),
2731
- description && /* @__PURE__ */ (0, import_jsx_runtime45.jsx)(
3461
+ description && /* @__PURE__ */ (0, import_jsx_runtime52.jsx)(
2732
3462
  "p",
2733
3463
  {
2734
3464
  style: {
@@ -2744,12 +3474,12 @@ function AuthHeader({ title, description }) {
2744
3474
  }
2745
3475
 
2746
3476
  // src/components/auth/AuthField.tsx
2747
- var import_jsx_runtime46 = require("react/jsx-runtime");
3477
+ var import_jsx_runtime53 = require("react/jsx-runtime");
2748
3478
  function AuthField({ label, error, hint, rightLabel, id, ...props }) {
2749
3479
  const fieldId = id ?? label.toLowerCase().replace(/\s+/g, "-");
2750
- return /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "6px" }, children: [
2751
- /* @__PURE__ */ (0, import_jsx_runtime46.jsxs)("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
2752
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
3480
+ return /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "6px" }, children: [
3481
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsxs)("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
3482
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
2753
3483
  "label",
2754
3484
  {
2755
3485
  htmlFor: fieldId,
@@ -2761,9 +3491,9 @@ function AuthField({ label, error, hint, rightLabel, id, ...props }) {
2761
3491
  children: label
2762
3492
  }
2763
3493
  ),
2764
- rightLabel && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("span", { style: { fontSize: "0.8125rem" }, children: rightLabel })
3494
+ rightLabel && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("span", { style: { fontSize: "0.8125rem" }, children: rightLabel })
2765
3495
  ] }),
2766
- /* @__PURE__ */ (0, import_jsx_runtime46.jsx)(
3496
+ /* @__PURE__ */ (0, import_jsx_runtime53.jsx)(
2767
3497
  "input",
2768
3498
  {
2769
3499
  id: fieldId,
@@ -2793,13 +3523,13 @@ function AuthField({ label, error, hint, rightLabel, id, ...props }) {
2793
3523
  ...props
2794
3524
  }
2795
3525
  ),
2796
- error && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("p", { style: { fontSize: "0.8rem", color: "var(--destructive)", margin: 0 }, children: error }),
2797
- hint && !error && /* @__PURE__ */ (0, import_jsx_runtime46.jsx)("p", { style: { fontSize: "0.8rem", color: "var(--muted-foreground)", margin: 0 }, children: hint })
3526
+ error && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("p", { style: { fontSize: "0.8rem", color: "var(--destructive)", margin: 0 }, children: error }),
3527
+ hint && !error && /* @__PURE__ */ (0, import_jsx_runtime53.jsx)("p", { style: { fontSize: "0.8rem", color: "var(--muted-foreground)", margin: 0 }, children: hint })
2798
3528
  ] });
2799
3529
  }
2800
3530
 
2801
3531
  // src/components/auth/AuthButton.tsx
2802
- var import_jsx_runtime47 = require("react/jsx-runtime");
3532
+ var import_jsx_runtime54 = require("react/jsx-runtime");
2803
3533
  function AuthButton({
2804
3534
  loading,
2805
3535
  variant = "primary",
@@ -2842,7 +3572,7 @@ function AuthButton({
2842
3572
  color: "var(--foreground)"
2843
3573
  }
2844
3574
  };
2845
- return /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
3575
+ return /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
2846
3576
  "button",
2847
3577
  {
2848
3578
  disabled: loading || disabled,
@@ -2854,8 +3584,8 @@ function AuthButton({
2854
3584
  e.currentTarget.style.filter = "none";
2855
3585
  },
2856
3586
  ...props,
2857
- children: loading ? /* @__PURE__ */ (0, import_jsx_runtime47.jsxs)(import_jsx_runtime47.Fragment, { children: [
2858
- /* @__PURE__ */ (0, import_jsx_runtime47.jsx)(
3587
+ children: loading ? /* @__PURE__ */ (0, import_jsx_runtime54.jsxs)(import_jsx_runtime54.Fragment, { children: [
3588
+ /* @__PURE__ */ (0, import_jsx_runtime54.jsx)(
2859
3589
  "span",
2860
3590
  {
2861
3591
  style: {
@@ -2876,19 +3606,19 @@ function AuthButton({
2876
3606
  }
2877
3607
 
2878
3608
  // src/components/auth/AuthDivider.tsx
2879
- var import_jsx_runtime48 = require("react/jsx-runtime");
3609
+ var import_jsx_runtime55 = require("react/jsx-runtime");
2880
3610
  function AuthDivider({ label = "or" }) {
2881
- return /* @__PURE__ */ (0, import_jsx_runtime48.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "12px", margin: "20px 0" }, children: [
2882
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { style: { flex: 1, height: 1, background: "var(--border)" } }),
2883
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("span", { style: { fontSize: "0.75rem", color: "var(--muted-foreground)", userSelect: "none" }, children: label }),
2884
- /* @__PURE__ */ (0, import_jsx_runtime48.jsx)("div", { style: { flex: 1, height: 1, background: "var(--border)" } })
3611
+ return /* @__PURE__ */ (0, import_jsx_runtime55.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: "12px", margin: "20px 0" }, children: [
3612
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { style: { flex: 1, height: 1, background: "var(--border)" } }),
3613
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("span", { style: { fontSize: "0.75rem", color: "var(--muted-foreground)", userSelect: "none" }, children: label }),
3614
+ /* @__PURE__ */ (0, import_jsx_runtime55.jsx)("div", { style: { flex: 1, height: 1, background: "var(--border)" } })
2885
3615
  ] });
2886
3616
  }
2887
3617
 
2888
3618
  // src/components/auth/AuthFootnote.tsx
2889
- var import_jsx_runtime49 = require("react/jsx-runtime");
3619
+ var import_jsx_runtime56 = require("react/jsx-runtime");
2890
3620
  function AuthFootnote({ text, linkText, linkHref }) {
2891
- return /* @__PURE__ */ (0, import_jsx_runtime49.jsxs)("p", { style: {
3621
+ return /* @__PURE__ */ (0, import_jsx_runtime56.jsxs)("p", { style: {
2892
3622
  textAlign: "center",
2893
3623
  marginTop: "20px",
2894
3624
  fontSize: "0.8125rem",
@@ -2896,7 +3626,7 @@ function AuthFootnote({ text, linkText, linkHref }) {
2896
3626
  }, children: [
2897
3627
  text,
2898
3628
  " ",
2899
- /* @__PURE__ */ (0, import_jsx_runtime49.jsx)(
3629
+ /* @__PURE__ */ (0, import_jsx_runtime56.jsx)(
2900
3630
  "a",
2901
3631
  {
2902
3632
  href: linkHref,
@@ -2913,37 +3643,6 @@ function AuthFootnote({ text, linkText, linkHref }) {
2913
3643
  ] });
2914
3644
  }
2915
3645
 
2916
- // src/components/Skeleton.tsx
2917
- var import_jsx_runtime50 = require("react/jsx-runtime");
2918
- function Skeleton2({ width = "100%", height = 16, rounded, style }) {
2919
- return /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
2920
- "div",
2921
- {
2922
- style: {
2923
- width,
2924
- height,
2925
- background: "var(--muted, #e5e7eb)",
2926
- borderRadius: rounded ?? "var(--radius, 0.5rem)",
2927
- overflow: "hidden",
2928
- position: "relative",
2929
- flexShrink: 0,
2930
- ...style
2931
- },
2932
- children: /* @__PURE__ */ (0, import_jsx_runtime50.jsx)(
2933
- "div",
2934
- {
2935
- style: {
2936
- position: "absolute",
2937
- inset: 0,
2938
- background: "linear-gradient(90deg, transparent 0%, color-mix(in oklab, var(--background, #fff) 40%, transparent) 50%, transparent 100%)",
2939
- animation: "dashui-shimmer 1.6s ease-in-out infinite"
2940
- }
2941
- }
2942
- )
2943
- }
2944
- );
2945
- }
2946
-
2947
3646
  // src/index.ts
2948
3647
  var import_next_themes2 = require("next-themes");
2949
3648
  // Annotate the CommonJS export names for ESM import in node:
@@ -3014,6 +3713,11 @@ var import_next_themes2 = require("next-themes");
3014
3713
  Popover,
3015
3714
  PopoverContent,
3016
3715
  PopoverTrigger,
3716
+ PostEditorShell,
3717
+ PostFiltersBar,
3718
+ PostListTable,
3719
+ PostSidebarSection,
3720
+ PostStatusBadge,
3017
3721
  SearchBar,
3018
3722
  Select,
3019
3723
  SelectContent,
@@ -3028,6 +3732,7 @@ var import_next_themes2 = require("next-themes");
3028
3732
  Separator,
3029
3733
  Sidebar,
3030
3734
  Skeleton,
3735
+ SlugInput,
3031
3736
  Stats,
3032
3737
  StorageBar,
3033
3738
  Switch,