@webdevarif/dashui 0.2.5 → 0.3.1

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