@jiggai/kitchen-plugin-marketing 0.5.3 → 0.5.5

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.
@@ -2,6 +2,7 @@
2
2
  // src/tabs/content-calendar.tsx
3
3
  (function() {
4
4
  const R = window.React;
5
+ const RD = window.ReactDOM;
5
6
  if (!R) return;
6
7
  const h = R.createElement;
7
8
  const useState = R.useState;
@@ -9,6 +10,25 @@
9
10
  const useMemo = R.useMemo;
10
11
  const useCallback = R.useCallback;
11
12
  const useRef = R.useRef;
13
+ function Portal({ children }) {
14
+ const rd = RD || typeof window !== "undefined" && window.ReactDOM;
15
+ const [container] = useState(() => {
16
+ if (typeof document === "undefined") return null;
17
+ const el = document.createElement("div");
18
+ el.setAttribute("data-ck-portal", "marketing");
19
+ return el;
20
+ });
21
+ useEffect(() => {
22
+ if (!container) return;
23
+ document.body.appendChild(container);
24
+ return () => {
25
+ document.body.removeChild(container);
26
+ };
27
+ }, [container]);
28
+ if (rd?.createPortal && container) return rd.createPortal(children, container);
29
+ if (container) return rd?.createPortal ? rd.createPortal(children, container) : children;
30
+ return children;
31
+ }
12
32
  const s = {
13
33
  // layout
14
34
  container: { color: "var(--ck-text-primary)" },
@@ -728,74 +748,78 @@
728
748
  const p = previewPost;
729
749
  const d = p.scheduledAt ? new Date(p.scheduledAt) : new Date(p.createdAt);
730
750
  return h(
731
- "div",
732
- { style: s.overlay, onClick: () => setPreviewPost(null) },
751
+ Portal,
752
+ null,
733
753
  h(
734
754
  "div",
735
- {
736
- style: { ...s.modal, maxWidth: "550px" },
737
- onClick: (e) => e.stopPropagation()
738
- },
755
+ { style: s.overlay, onClick: () => setPreviewPost(null) },
739
756
  h(
740
757
  "div",
741
- { style: s.modalHeader },
742
- h("div", { style: { fontWeight: 700, fontSize: "1rem", color: "var(--ck-text-primary)" } }, "Preview Post"),
743
- h("button", { style: s.closeBtn, onClick: () => setPreviewPost(null) }, "\xD7")
744
- ),
745
- h(
746
- "div",
747
- { style: { padding: "1.25rem" } },
758
+ {
759
+ style: { ...s.modal, maxWidth: "550px" },
760
+ onClick: (e) => e.stopPropagation()
761
+ },
748
762
  h(
749
763
  "div",
750
- { style: { display: "flex", alignItems: "center", gap: "0.5rem", marginBottom: "0.75rem" } },
751
- h("div", { style: s.statusDot(p.status) }),
752
- h("span", { style: { fontSize: "0.8rem", fontWeight: 600, color: "var(--ck-text-secondary)", textTransform: "capitalize" } }, p.status),
753
- h("span", { style: { fontSize: "0.75rem", color: "var(--ck-text-tertiary)" } }, d.toLocaleString())
764
+ { style: s.modalHeader },
765
+ h("div", { style: { fontWeight: 700, fontSize: "1rem", color: "var(--ck-text-primary)" } }, "Preview Post"),
766
+ h("button", { style: s.closeBtn, onClick: () => setPreviewPost(null) }, "\xD7")
754
767
  ),
755
- // Platforms
756
- p.platforms?.length > 0 && h(
757
- "div",
758
- { style: { display: "flex", gap: "0.4rem", marginBottom: "0.75rem", flexWrap: "wrap" } },
759
- ...p.platforms.map((pl) => {
760
- const drv = drivers.find((x) => x.platform === pl);
761
- return h("span", {
762
- key: pl,
763
- style: {
764
- background: "rgba(127,90,240,0.15)",
765
- border: "1px solid rgba(127,90,240,0.3)",
766
- borderRadius: "999px",
767
- padding: "0.15rem 0.5rem",
768
- fontSize: "0.75rem",
769
- color: "var(--ck-text-secondary)"
770
- }
771
- }, drv ? `${drv.icon} ${drv.label}` : pl);
772
- })
773
- ),
774
- // Content
775
- h("div", {
776
- style: {
777
- ...s.previewPanel,
778
- whiteSpace: "pre-wrap",
779
- fontSize: "0.9rem",
780
- color: "var(--ck-text-primary)",
781
- lineHeight: "1.5"
782
- }
783
- }, p.content),
784
- // Actions
785
768
  h(
786
769
  "div",
787
- { style: { display: "flex", gap: "0.5rem", marginTop: "1rem" } },
788
- h("button", {
789
- style: s.btnGhost,
790
- onClick: () => copyPost(p.content)
791
- }, "\u{1F4CB} Copy"),
792
- h("button", {
793
- style: { ...s.btnGhost, color: "rgba(248,113,113,0.9)" },
794
- onClick: () => {
795
- deletePost(p.id);
796
- setPreviewPost(null);
770
+ { style: { padding: "1.25rem" } },
771
+ h(
772
+ "div",
773
+ { style: { display: "flex", alignItems: "center", gap: "0.5rem", marginBottom: "0.75rem" } },
774
+ h("div", { style: s.statusDot(p.status) }),
775
+ h("span", { style: { fontSize: "0.8rem", fontWeight: 600, color: "var(--ck-text-secondary)", textTransform: "capitalize" } }, p.status),
776
+ h("span", { style: { fontSize: "0.75rem", color: "var(--ck-text-tertiary)" } }, d.toLocaleString())
777
+ ),
778
+ // Platforms
779
+ p.platforms?.length > 0 && h(
780
+ "div",
781
+ { style: { display: "flex", gap: "0.4rem", marginBottom: "0.75rem", flexWrap: "wrap" } },
782
+ ...p.platforms.map((pl) => {
783
+ const drv = drivers.find((x) => x.platform === pl);
784
+ return h("span", {
785
+ key: pl,
786
+ style: {
787
+ background: "rgba(127,90,240,0.15)",
788
+ border: "1px solid rgba(127,90,240,0.3)",
789
+ borderRadius: "999px",
790
+ padding: "0.15rem 0.5rem",
791
+ fontSize: "0.75rem",
792
+ color: "var(--ck-text-secondary)"
793
+ }
794
+ }, drv ? `${drv.icon} ${drv.label}` : pl);
795
+ })
796
+ ),
797
+ // Content
798
+ h("div", {
799
+ style: {
800
+ ...s.previewPanel,
801
+ whiteSpace: "pre-wrap",
802
+ fontSize: "0.9rem",
803
+ color: "var(--ck-text-primary)",
804
+ lineHeight: "1.5"
797
805
  }
798
- }, "\u{1F5D1} Delete")
806
+ }, p.content),
807
+ // Actions
808
+ h(
809
+ "div",
810
+ { style: { display: "flex", gap: "0.5rem", marginTop: "1rem" } },
811
+ h("button", {
812
+ style: s.btnGhost,
813
+ onClick: () => copyPost(p.content)
814
+ }, "\u{1F4CB} Copy"),
815
+ h("button", {
816
+ style: { ...s.btnGhost, color: "rgba(248,113,113,0.9)" },
817
+ onClick: () => {
818
+ deletePost(p.id);
819
+ setPreviewPost(null);
820
+ }
821
+ }, "\u{1F5D1} Delete")
822
+ )
799
823
  )
800
824
  )
801
825
  )
@@ -809,396 +833,400 @@
809
833
  return limits.length > 0 ? Math.min(...limits) : void 0;
810
834
  }, [modalPlatforms, drivers]);
811
835
  return h(
812
- "div",
813
- { style: s.overlay, onClick: () => setModalOpen(false) },
836
+ Portal,
837
+ null,
814
838
  h(
815
839
  "div",
816
- {
817
- style: s.modal,
818
- onClick: (e) => e.stopPropagation()
819
- },
820
- // Header
840
+ { style: s.overlay, onClick: () => setModalOpen(false) },
821
841
  h(
822
842
  "div",
823
- { style: s.modalHeader },
824
- h("div", { style: { fontWeight: 700, fontSize: "1.1rem", color: "var(--ck-text-primary)" } }, "Create Post"),
825
- h("button", { style: s.closeBtn, onClick: () => setModalOpen(false) }, "\xD7")
826
- ),
827
- // Body — two columns
828
- h(
829
- "div",
830
- { style: s.modalBody },
831
- // Left — compose
843
+ {
844
+ style: s.modal,
845
+ onClick: (e) => e.stopPropagation()
846
+ },
847
+ // Header
832
848
  h(
833
849
  "div",
834
- { style: s.modalLeft },
835
- // Platform circles
836
- h(
837
- "div",
838
- { style: { display: "flex", gap: "0.5rem", flexWrap: "wrap" } },
839
- ...drivers.map(
840
- (d) => h("div", {
841
- key: d.platform,
842
- style: s.platformCircle(modalPlatforms.includes(d.platform), d.connected),
843
- onClick: () => {
844
- if (!d.connected) return;
845
- setModalPlatforms(
846
- (prev) => prev.includes(d.platform) ? prev.filter((x) => x !== d.platform) : [...prev, d.platform]
847
- );
848
- },
849
- title: `${d.label}${d.connected ? "" : " (not connected)"}`
850
- }, d.icon)
851
- )
852
- ),
853
- // Textarea
854
- h("textarea", {
855
- style: s.textarea,
856
- dir: "ltr",
857
- value: modalContent,
858
- onChange: (e) => setModalContent(e.target.value),
859
- placeholder: "Write something \u2026",
860
- autoFocus: true
861
- }),
862
- // Toolbar
850
+ { style: s.modalHeader },
851
+ h("div", { style: { fontWeight: 700, fontSize: "1.1rem", color: "var(--ck-text-primary)" } }, "Create Post"),
852
+ h("button", { style: s.closeBtn, onClick: () => setModalOpen(false) }, "\xD7")
853
+ ),
854
+ // Body two columns
855
+ h(
856
+ "div",
857
+ { style: s.modalBody },
858
+ // Left — compose
863
859
  h(
864
860
  "div",
865
- { style: { display: "flex", gap: "0.5rem", alignItems: "center", flexWrap: "wrap" } },
866
- h("button", {
867
- type: "button",
868
- style: { ...s.btnGhost, padding: "0.3rem 0.6rem", fontSize: "0.75rem" },
869
- onClick: async () => {
870
- const next = !modalShowMedia;
871
- setModalShowMedia(next);
872
- if (next) await loadMedia();
873
- }
874
- }, "\u{1F5BC} Insert Media"),
875
- charLimit && h("span", {
876
- style: {
877
- fontSize: "0.75rem",
878
- marginLeft: "auto",
879
- color: modalContent.length > charLimit ? "rgba(248,113,113,0.95)" : "var(--ck-text-tertiary)"
880
- }
881
- }, `${modalContent.length}/${charLimit}`)
882
- ),
883
- // Media panel (upload + library + URL)
884
- modalShowMedia && h(
885
- "div",
886
- {
887
- style: {
888
- background: "rgba(255,255,255,0.02)",
889
- border: "1px solid var(--ck-border-subtle)",
890
- borderRadius: "10px",
891
- padding: "0.75rem"
892
- }
893
- },
861
+ { style: s.modalLeft },
862
+ // Platform circles
894
863
  h(
895
864
  "div",
896
- { style: { display: "flex", gap: "0.5rem", alignItems: "center", marginBottom: "0.5rem", flexWrap: "wrap" } },
897
- h("input", {
898
- ref: modalFileInputRef,
899
- type: "file",
900
- accept: "image/*,video/*",
901
- multiple: true,
902
- style: { display: "none" },
903
- onChange: (e) => void handleModalFileUpload(e.target.files)
904
- }),
905
- h("button", {
906
- type: "button",
907
- style: { ...s.btnGhost, padding: "0.35rem 0.6rem", fontSize: "0.75rem", opacity: modalUploading ? 0.7 : 1 },
908
- onClick: () => modalFileInputRef.current?.click(),
909
- disabled: modalUploading
910
- }, modalUploading ? "\u23F3 Uploading\u2026" : "\u{1F4C1} Upload"),
911
- h("button", {
912
- type: "button",
913
- style: { ...s.btnGhost, padding: "0.35rem 0.6rem", fontSize: "0.75rem" },
914
- onClick: () => setModalShowMedia(false)
915
- }, "Done")
865
+ { style: { display: "flex", gap: "0.5rem", flexWrap: "wrap" } },
866
+ ...drivers.map(
867
+ (d) => h("div", {
868
+ key: d.platform,
869
+ style: s.platformCircle(modalPlatforms.includes(d.platform), d.connected),
870
+ onClick: () => {
871
+ if (!d.connected) return;
872
+ setModalPlatforms(
873
+ (prev) => prev.includes(d.platform) ? prev.filter((x) => x !== d.platform) : [...prev, d.platform]
874
+ );
875
+ },
876
+ title: `${d.label}${d.connected ? "" : " (not connected)"}`
877
+ }, d.icon)
878
+ )
916
879
  ),
917
- h("input", {
918
- style: s.input,
919
- type: "url",
920
- value: modalMediaUrl,
921
- onChange: (e) => setModalMediaUrl(e.target.value),
922
- placeholder: "Paste a public image/video URL (needed for Postiz)\u2026"
880
+ // Textarea
881
+ h("textarea", {
882
+ style: s.textarea,
883
+ dir: "ltr",
884
+ value: modalContent,
885
+ onChange: (e) => setModalContent(e.target.value),
886
+ placeholder: "Write something \u2026",
887
+ autoFocus: true
923
888
  }),
924
- // Selected media strip
925
- modalSelectedMediaIds.length > 0 && h(
889
+ // Toolbar
890
+ h(
926
891
  "div",
927
- { style: { display: "flex", flexWrap: "wrap", gap: "0.5rem", marginTop: "0.65rem" } },
928
- ...modalSelectedMediaIds.map((id) => {
929
- const item = modalMediaLibrary.find((m) => m.id === id);
930
- if (!item) return null;
931
- return h(
932
- "div",
933
- {
934
- key: id,
935
- style: {
936
- position: "relative",
937
- width: "64px",
938
- height: "64px",
939
- borderRadius: "8px",
940
- overflow: "hidden",
941
- border: "2px solid rgba(127,90,240,0.55)"
942
- }
943
- },
944
- item.mimeType?.startsWith("video/") ? h("div", {
945
- style: { width: "100%", height: "100%", background: "rgba(0,0,0,0.35)", display: "flex", alignItems: "center", justifyContent: "center", color: "white" }
946
- }, "\u{1F3A5}") : h("img", { src: item.thumbnailDataUrl, style: { width: "100%", height: "100%", objectFit: "cover" } }),
947
- h("button", {
948
- type: "button",
949
- onClick: () => toggleModalMedia(id),
950
- style: {
951
- position: "absolute",
952
- top: "2px",
953
- right: "2px",
954
- background: "rgba(0,0,0,0.6)",
955
- border: "none",
956
- borderRadius: "50%",
957
- width: "18px",
958
- height: "18px",
959
- color: "white",
960
- fontSize: "0.65rem",
961
- cursor: "pointer",
962
- display: "flex",
963
- alignItems: "center",
964
- justifyContent: "center"
965
- }
966
- }, "\u2715")
967
- );
968
- })
892
+ { style: { display: "flex", gap: "0.5rem", alignItems: "center", flexWrap: "wrap" } },
893
+ h("button", {
894
+ type: "button",
895
+ style: { ...s.btnGhost, padding: "0.3rem 0.6rem", fontSize: "0.75rem" },
896
+ onClick: async () => {
897
+ const next = !modalShowMedia;
898
+ setModalShowMedia(next);
899
+ if (next) await loadMedia();
900
+ }
901
+ }, "\u{1F5BC} Insert Media"),
902
+ charLimit && h("span", {
903
+ style: {
904
+ fontSize: "0.75rem",
905
+ marginLeft: "auto",
906
+ color: modalContent.length > charLimit ? "rgba(248,113,113,0.95)" : "var(--ck-text-tertiary)"
907
+ }
908
+ }, `${modalContent.length}/${charLimit}`)
969
909
  ),
970
- // Library grid
971
- h(
910
+ // Media panel (upload + library + URL)
911
+ modalShowMedia && h(
972
912
  "div",
973
- { style: { marginTop: "0.65rem" } },
974
- h("div", { style: { fontSize: "0.75rem", fontWeight: 600, color: "var(--ck-text-secondary)", marginBottom: "0.4rem" } }, "Media Library"),
975
- modalMediaLibrary.length === 0 ? h("div", { style: { fontSize: "0.75rem", color: "var(--ck-text-tertiary)", padding: "0.5rem 0" } }, "No media yet \u2014 upload something.") : h(
913
+ {
914
+ style: {
915
+ background: "rgba(255,255,255,0.02)",
916
+ border: "1px solid var(--ck-border-subtle)",
917
+ borderRadius: "10px",
918
+ padding: "0.75rem"
919
+ }
920
+ },
921
+ h(
976
922
  "div",
977
- {
978
- style: {
979
- display: "grid",
980
- gridTemplateColumns: "repeat(auto-fill, minmax(86px, 1fr))",
981
- gap: "0.5rem",
982
- maxHeight: "220px",
983
- overflowY: "auto",
984
- paddingRight: "4px"
985
- }
986
- },
987
- ...modalMediaLibrary.map((item) => {
988
- const selected = modalSelectedMediaIds.includes(item.id);
989
- const thumb = item.thumbnailDataUrl;
923
+ { style: { display: "flex", gap: "0.5rem", alignItems: "center", marginBottom: "0.5rem", flexWrap: "wrap" } },
924
+ h("input", {
925
+ ref: modalFileInputRef,
926
+ type: "file",
927
+ accept: "image/*,video/*",
928
+ multiple: true,
929
+ style: { display: "none" },
930
+ onChange: (e) => void handleModalFileUpload(e.target.files)
931
+ }),
932
+ h("button", {
933
+ type: "button",
934
+ style: { ...s.btnGhost, padding: "0.35rem 0.6rem", fontSize: "0.75rem", opacity: modalUploading ? 0.7 : 1 },
935
+ onClick: () => modalFileInputRef.current?.click(),
936
+ disabled: modalUploading
937
+ }, modalUploading ? "\u23F3 Uploading\u2026" : "\u{1F4C1} Upload"),
938
+ h("button", {
939
+ type: "button",
940
+ style: { ...s.btnGhost, padding: "0.35rem 0.6rem", fontSize: "0.75rem" },
941
+ onClick: () => setModalShowMedia(false)
942
+ }, "Done")
943
+ ),
944
+ h("input", {
945
+ style: s.input,
946
+ type: "url",
947
+ value: modalMediaUrl,
948
+ onChange: (e) => setModalMediaUrl(e.target.value),
949
+ placeholder: "Paste a public image/video URL (needed for Postiz)\u2026"
950
+ }),
951
+ // Selected media strip
952
+ modalSelectedMediaIds.length > 0 && h(
953
+ "div",
954
+ { style: { display: "flex", flexWrap: "wrap", gap: "0.5rem", marginTop: "0.65rem" } },
955
+ ...modalSelectedMediaIds.map((id) => {
956
+ const item = modalMediaLibrary.find((m) => m.id === id);
957
+ if (!item) return null;
990
958
  return h(
991
959
  "div",
992
960
  {
993
- key: item.id,
994
- onClick: () => toggleModalMedia(item.id),
961
+ key: id,
995
962
  style: {
996
963
  position: "relative",
997
- width: "100%",
998
- paddingTop: "100%",
999
- borderRadius: "10px",
964
+ width: "64px",
965
+ height: "64px",
966
+ borderRadius: "8px",
1000
967
  overflow: "hidden",
1001
- cursor: "pointer",
1002
- border: selected ? "2px solid rgba(127,90,240,0.75)" : "1px solid var(--ck-border-subtle)",
1003
- boxShadow: selected ? "0 0 10px rgba(127,90,240,0.25)" : "none",
1004
- background: "rgba(0,0,0,0.25)"
968
+ border: "2px solid rgba(127,90,240,0.55)"
1005
969
  }
1006
970
  },
1007
971
  item.mimeType?.startsWith("video/") ? h("div", {
1008
- style: { position: "absolute", inset: 0, display: "flex", alignItems: "center", justifyContent: "center", color: "white", fontSize: "1.4rem" }
1009
- }, "\u{1F3A5}") : h("img", {
1010
- src: thumb,
1011
- style: { position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover" }
1012
- }),
1013
- selected && h("div", {
972
+ style: { width: "100%", height: "100%", background: "rgba(0,0,0,0.35)", display: "flex", alignItems: "center", justifyContent: "center", color: "white" }
973
+ }, "\u{1F3A5}") : h("img", { src: item.thumbnailDataUrl, style: { width: "100%", height: "100%", objectFit: "cover" } }),
974
+ h("button", {
975
+ type: "button",
976
+ onClick: () => toggleModalMedia(id),
1014
977
  style: {
1015
978
  position: "absolute",
1016
- top: "6px",
1017
- right: "6px",
1018
- width: "20px",
1019
- height: "20px",
979
+ top: "2px",
980
+ right: "2px",
981
+ background: "rgba(0,0,0,0.6)",
982
+ border: "none",
1020
983
  borderRadius: "50%",
1021
- background: "rgba(127,90,240,0.9)",
984
+ width: "18px",
985
+ height: "18px",
986
+ color: "white",
987
+ fontSize: "0.65rem",
988
+ cursor: "pointer",
1022
989
  display: "flex",
1023
990
  alignItems: "center",
1024
- justifyContent: "center",
1025
- color: "white",
1026
- fontSize: "0.75rem",
1027
- fontWeight: 800
991
+ justifyContent: "center"
1028
992
  }
1029
- }, "\u2713")
993
+ }, "\u2715")
1030
994
  );
1031
995
  })
996
+ ),
997
+ // Library grid
998
+ h(
999
+ "div",
1000
+ { style: { marginTop: "0.65rem" } },
1001
+ h("div", { style: { fontSize: "0.75rem", fontWeight: 600, color: "var(--ck-text-secondary)", marginBottom: "0.4rem" } }, "Media Library"),
1002
+ modalMediaLibrary.length === 0 ? h("div", { style: { fontSize: "0.75rem", color: "var(--ck-text-tertiary)", padding: "0.5rem 0" } }, "No media yet \u2014 upload something.") : h(
1003
+ "div",
1004
+ {
1005
+ style: {
1006
+ display: "grid",
1007
+ gridTemplateColumns: "repeat(auto-fill, minmax(86px, 1fr))",
1008
+ gap: "0.5rem",
1009
+ maxHeight: "220px",
1010
+ overflowY: "auto",
1011
+ paddingRight: "4px"
1012
+ }
1013
+ },
1014
+ ...modalMediaLibrary.map((item) => {
1015
+ const selected = modalSelectedMediaIds.includes(item.id);
1016
+ const thumb = item.thumbnailDataUrl;
1017
+ return h(
1018
+ "div",
1019
+ {
1020
+ key: item.id,
1021
+ onClick: () => toggleModalMedia(item.id),
1022
+ style: {
1023
+ position: "relative",
1024
+ width: "100%",
1025
+ paddingTop: "100%",
1026
+ borderRadius: "10px",
1027
+ overflow: "hidden",
1028
+ cursor: "pointer",
1029
+ border: selected ? "2px solid rgba(127,90,240,0.75)" : "1px solid var(--ck-border-subtle)",
1030
+ boxShadow: selected ? "0 0 10px rgba(127,90,240,0.25)" : "none",
1031
+ background: "rgba(0,0,0,0.25)"
1032
+ }
1033
+ },
1034
+ item.mimeType?.startsWith("video/") ? h("div", {
1035
+ style: { position: "absolute", inset: 0, display: "flex", alignItems: "center", justifyContent: "center", color: "white", fontSize: "1.4rem" }
1036
+ }, "\u{1F3A5}") : h("img", {
1037
+ src: thumb,
1038
+ style: { position: "absolute", inset: 0, width: "100%", height: "100%", objectFit: "cover" }
1039
+ }),
1040
+ selected && h("div", {
1041
+ style: {
1042
+ position: "absolute",
1043
+ top: "6px",
1044
+ right: "6px",
1045
+ width: "20px",
1046
+ height: "20px",
1047
+ borderRadius: "50%",
1048
+ background: "rgba(127,90,240,0.9)",
1049
+ display: "flex",
1050
+ alignItems: "center",
1051
+ justifyContent: "center",
1052
+ color: "white",
1053
+ fontSize: "0.75rem",
1054
+ fontWeight: 800
1055
+ }
1056
+ }, "\u2713")
1057
+ );
1058
+ })
1059
+ )
1032
1060
  )
1033
1061
  )
1034
- )
1035
- ),
1036
- // Right — social-post-style preview
1037
- h(
1038
- "div",
1039
- { style: s.modalRight },
1040
- h("div", { style: { fontWeight: 600, fontSize: "0.85rem", color: "var(--ck-text-secondary)", marginBottom: "0.75rem" } }, "Post Preview"),
1062
+ ),
1063
+ // Right — social-post-style preview
1041
1064
  h(
1042
1065
  "div",
1043
- {
1044
- style: {
1045
- background: "rgba(22,22,28,0.95)",
1046
- borderRadius: "12px",
1047
- border: "1px solid rgba(255,255,255,0.08)",
1048
- overflow: "hidden"
1049
- }
1050
- },
1051
- // Header
1066
+ { style: s.modalRight },
1067
+ h("div", { style: { fontWeight: 600, fontSize: "0.85rem", color: "var(--ck-text-secondary)", marginBottom: "0.75rem" } }, "Post Preview"),
1052
1068
  h(
1053
1069
  "div",
1054
- { style: { display: "flex", alignItems: "center", gap: "0.65rem", padding: "0.85rem 1rem 0" } },
1055
- h("div", {
1070
+ {
1056
1071
  style: {
1057
- width: "40px",
1058
- height: "40px",
1059
- borderRadius: "50%",
1060
- background: "rgba(127,90,240,0.25)",
1061
- display: "flex",
1062
- alignItems: "center",
1063
- justifyContent: "center",
1064
- fontSize: "1.1rem",
1065
- color: "rgba(127,90,240,0.9)",
1066
- flexShrink: 0
1072
+ background: "rgba(22,22,28,0.95)",
1073
+ borderRadius: "12px",
1074
+ border: "1px solid rgba(255,255,255,0.08)",
1075
+ overflow: "hidden"
1067
1076
  }
1068
- }, "\u{1F464}"),
1077
+ },
1078
+ // Header
1069
1079
  h(
1070
1080
  "div",
1071
- null,
1072
- h(
1073
- "div",
1074
- { style: { display: "flex", alignItems: "center", gap: "0.3rem" } },
1075
- h("span", { style: { fontWeight: 700, fontSize: "0.9rem", color: "var(--ck-text-primary)" } }, "Your Brand"),
1076
- h("span", { style: { color: "rgba(99,179,237,0.9)", fontSize: "0.85rem" } }, "\u2713")
1077
- ),
1081
+ { style: { display: "flex", alignItems: "center", gap: "0.65rem", padding: "0.85rem 1rem 0" } },
1082
+ h("div", {
1083
+ style: {
1084
+ width: "40px",
1085
+ height: "40px",
1086
+ borderRadius: "50%",
1087
+ background: "rgba(127,90,240,0.25)",
1088
+ display: "flex",
1089
+ alignItems: "center",
1090
+ justifyContent: "center",
1091
+ fontSize: "1.1rem",
1092
+ color: "rgba(127,90,240,0.9)",
1093
+ flexShrink: 0
1094
+ }
1095
+ }, "\u{1F464}"),
1078
1096
  h(
1079
1097
  "div",
1080
- { style: { fontSize: "0.75rem", color: "var(--ck-text-tertiary)" } },
1081
- modalDate ? new Date(modalDate).toLocaleDateString(void 0, { month: "short", day: "numeric", hour: "2-digit", minute: "2-digit" }) : "Just now"
1098
+ null,
1099
+ h(
1100
+ "div",
1101
+ { style: { display: "flex", alignItems: "center", gap: "0.3rem" } },
1102
+ h("span", { style: { fontWeight: 700, fontSize: "0.9rem", color: "var(--ck-text-primary)" } }, "Your Brand"),
1103
+ h("span", { style: { color: "rgba(99,179,237,0.9)", fontSize: "0.85rem" } }, "\u2713")
1104
+ ),
1105
+ h(
1106
+ "div",
1107
+ { style: { fontSize: "0.75rem", color: "var(--ck-text-tertiary)" } },
1108
+ modalDate ? new Date(modalDate).toLocaleDateString(void 0, { month: "short", day: "numeric", hour: "2-digit", minute: "2-digit" }) : "Just now"
1109
+ )
1082
1110
  )
1111
+ ),
1112
+ // Body
1113
+ h(
1114
+ "div",
1115
+ { style: { padding: "0.65rem 1rem 0.75rem" } },
1116
+ modalContent.trim() ? h("div", {
1117
+ style: {
1118
+ whiteSpace: "pre-wrap",
1119
+ fontSize: "0.9rem",
1120
+ color: "var(--ck-text-primary)",
1121
+ lineHeight: "1.5",
1122
+ maxHeight: "300px",
1123
+ overflowY: "auto",
1124
+ wordBreak: "break-word"
1125
+ }
1126
+ }, modalContent) : h("div", {
1127
+ style: { color: "var(--ck-text-tertiary)", fontSize: "0.85rem", fontStyle: "italic", padding: "1.5rem 0", textAlign: "center" }
1128
+ }, "Start writing to see a preview")
1129
+ ),
1130
+ // Media preview (selected library media first, then URL)
1131
+ (modalSelectedMediaIds.length > 0 || modalMediaUrl) && h(
1132
+ "div",
1133
+ null,
1134
+ ...modalSelectedMediaIds.slice(0, 1).map((id) => {
1135
+ const item = modalMediaLibrary.find((m) => m.id === id);
1136
+ if (!item) return null;
1137
+ return item.mimeType?.startsWith("video/") ? h("div", {
1138
+ key: id,
1139
+ style: { background: "rgba(0,0,0,0.4)", padding: "1.25rem", textAlign: "center", color: "var(--ck-text-secondary)" }
1140
+ }, "\u{1F3A5} Video") : h("img", { key: id, src: item.thumbnailDataUrl, style: { width: "100%", display: "block" } });
1141
+ }),
1142
+ modalMediaUrl && h("img", {
1143
+ src: modalMediaUrl,
1144
+ style: { width: "100%", display: "block" },
1145
+ onError: (e) => {
1146
+ e.target.style.display = "none";
1147
+ }
1148
+ })
1149
+ ),
1150
+ // Engagement bar
1151
+ h(
1152
+ "div",
1153
+ {
1154
+ style: {
1155
+ display: "flex",
1156
+ justifyContent: "space-around",
1157
+ padding: "0.6rem 1rem",
1158
+ borderTop: "1px solid rgba(255,255,255,0.06)",
1159
+ fontSize: "0.8rem",
1160
+ color: "var(--ck-text-tertiary)"
1161
+ }
1162
+ },
1163
+ h("span", null, "\u2764\uFE0F 0"),
1164
+ h("span", null, "\u{1F4AC} 0"),
1165
+ h("span", null, "\u{1F501} 0"),
1166
+ h("span", null, "\u{1F4CA} 0")
1083
1167
  )
1084
1168
  ),
1085
- // Body
1086
- h(
1087
- "div",
1088
- { style: { padding: "0.65rem 1rem 0.75rem" } },
1089
- modalContent.trim() ? h("div", {
1090
- style: {
1091
- whiteSpace: "pre-wrap",
1092
- fontSize: "0.9rem",
1093
- color: "var(--ck-text-primary)",
1094
- lineHeight: "1.5",
1095
- maxHeight: "300px",
1096
- overflowY: "auto",
1097
- wordBreak: "break-word"
1098
- }
1099
- }, modalContent) : h("div", {
1100
- style: { color: "var(--ck-text-tertiary)", fontSize: "0.85rem", fontStyle: "italic", padding: "1.5rem 0", textAlign: "center" }
1101
- }, "Start writing to see a preview")
1102
- ),
1103
- // Media preview (selected library media first, then URL)
1104
- (modalSelectedMediaIds.length > 0 || modalMediaUrl) && h(
1105
- "div",
1106
- null,
1107
- ...modalSelectedMediaIds.slice(0, 1).map((id) => {
1108
- const item = modalMediaLibrary.find((m) => m.id === id);
1109
- if (!item) return null;
1110
- return item.mimeType?.startsWith("video/") ? h("div", {
1111
- key: id,
1112
- style: { background: "rgba(0,0,0,0.4)", padding: "1.25rem", textAlign: "center", color: "var(--ck-text-secondary)" }
1113
- }, "\u{1F3A5} Video") : h("img", { key: id, src: item.thumbnailDataUrl, style: { width: "100%", display: "block" } });
1114
- }),
1115
- modalMediaUrl && h("img", {
1116
- src: modalMediaUrl,
1117
- style: { width: "100%", display: "block" },
1118
- onError: (e) => {
1119
- e.target.style.display = "none";
1120
- }
1121
- })
1122
- ),
1123
- // Engagement bar
1124
- h(
1169
+ // Platform pills
1170
+ modalPlatforms.length > 0 && h(
1125
1171
  "div",
1126
1172
  {
1173
+ style: { display: "flex", flexWrap: "wrap", gap: "0.35rem", marginTop: "0.65rem" }
1174
+ },
1175
+ ...modalPlatforms.map((pl) => h("span", {
1176
+ key: pl,
1127
1177
  style: {
1128
- display: "flex",
1129
- justifyContent: "space-around",
1130
- padding: "0.6rem 1rem",
1131
- borderTop: "1px solid rgba(255,255,255,0.06)",
1132
- fontSize: "0.8rem",
1133
- color: "var(--ck-text-tertiary)"
1178
+ background: "rgba(127,90,240,0.12)",
1179
+ border: "1px solid rgba(127,90,240,0.25)",
1180
+ borderRadius: "999px",
1181
+ padding: "0.1rem 0.4rem",
1182
+ fontSize: "0.7rem",
1183
+ color: "var(--ck-text-secondary)"
1134
1184
  }
1135
- },
1136
- h("span", null, "\u2764\uFE0F 0"),
1137
- h("span", null, "\u{1F4AC} 0"),
1138
- h("span", null, "\u{1F501} 0"),
1139
- h("span", null, "\u{1F4CA} 0")
1185
+ }, pl))
1140
1186
  )
1141
- ),
1142
- // Platform pills
1143
- modalPlatforms.length > 0 && h(
1144
- "div",
1145
- {
1146
- style: { display: "flex", flexWrap: "wrap", gap: "0.35rem", marginTop: "0.65rem" }
1147
- },
1148
- ...modalPlatforms.map((pl) => h("span", {
1149
- key: pl,
1150
- style: {
1151
- background: "rgba(127,90,240,0.12)",
1152
- border: "1px solid rgba(127,90,240,0.25)",
1153
- borderRadius: "999px",
1154
- padding: "0.1rem 0.4rem",
1155
- fontSize: "0.7rem",
1156
- color: "var(--ck-text-secondary)"
1157
- }
1158
- }, pl))
1159
1187
  )
1160
- )
1161
- ),
1162
- // Footer
1163
- h(
1164
- "div",
1165
- { style: s.modalFooter },
1166
- // Left — date
1167
- h(
1168
- "div",
1169
- { style: { display: "flex", alignItems: "center", gap: "0.5rem" } },
1170
- h("span", { style: { fontSize: "0.8rem", color: "var(--ck-text-tertiary)" } }, "\u{1F4C5}"),
1171
- h("input", {
1172
- style: { ...s.input, width: "220px" },
1173
- type: "datetime-local",
1174
- value: modalDate,
1175
- onChange: (e) => setModalDate(e.target.value)
1176
- })
1177
1188
  ),
1178
- // Right — buttons
1189
+ // Footer
1179
1190
  h(
1180
1191
  "div",
1181
- { style: { display: "flex", gap: "0.5rem" } },
1182
- h("button", {
1183
- style: { ...s.btnGhost, opacity: modalSaving ? 0.6 : 1 },
1184
- onClick: () => void modalSaveDraft(),
1185
- disabled: modalSaving || !modalContent.trim()
1186
- }, modalSaving ? "Saving\u2026" : "Save as draft"),
1187
- connectedDrivers.length > 0 && modalPlatforms.length > 0 && h("button", {
1188
- style: { ...s.btnPrimary, opacity: modalPublishing ? 0.6 : 1 },
1189
- onClick: () => void modalPublish(),
1190
- disabled: modalPublishing || !modalContent.trim()
1191
- }, modalPublishing ? "Publishing\u2026" : modalDate ? "\u23F1 Schedule" : "\u{1F4E4} Publish")
1192
- )
1193
- ),
1194
- // Error / success
1195
- (modalError || modalSuccess) && h("div", {
1196
- style: {
1197
- padding: "0.5rem 1.25rem",
1198
- fontSize: "0.8rem",
1199
- color: modalError ? "rgba(248,113,113,0.95)" : "rgba(74,222,128,0.9)"
1200
- }
1201
- }, modalError || modalSuccess)
1192
+ { style: s.modalFooter },
1193
+ // Left — date
1194
+ h(
1195
+ "div",
1196
+ { style: { display: "flex", alignItems: "center", gap: "0.5rem" } },
1197
+ h("span", { style: { fontSize: "0.8rem", color: "var(--ck-text-tertiary)" } }, "\u{1F4C5}"),
1198
+ h("input", {
1199
+ style: { ...s.input, width: "220px" },
1200
+ type: "datetime-local",
1201
+ value: modalDate,
1202
+ onChange: (e) => setModalDate(e.target.value)
1203
+ })
1204
+ ),
1205
+ // Right buttons
1206
+ h(
1207
+ "div",
1208
+ { style: { display: "flex", gap: "0.5rem" } },
1209
+ h("button", {
1210
+ style: { ...s.btnGhost, opacity: modalSaving ? 0.6 : 1 },
1211
+ onClick: () => void modalSaveDraft(),
1212
+ disabled: modalSaving || !modalContent.trim()
1213
+ }, modalSaving ? "Saving\u2026" : "Save as draft"),
1214
+ connectedDrivers.length > 0 && modalPlatforms.length > 0 && h("button", {
1215
+ style: { ...s.btnPrimary, opacity: modalPublishing ? 0.6 : 1 },
1216
+ onClick: () => void modalPublish(),
1217
+ disabled: modalPublishing || !modalContent.trim()
1218
+ }, modalPublishing ? "Publishing\u2026" : modalDate ? "\u23F1 Schedule" : "\u{1F4E4} Publish")
1219
+ )
1220
+ ),
1221
+ // Error / success
1222
+ (modalError || modalSuccess) && h("div", {
1223
+ style: {
1224
+ padding: "0.5rem 1.25rem",
1225
+ fontSize: "0.8rem",
1226
+ color: modalError ? "rgba(248,113,113,0.95)" : "rgba(74,222,128,0.9)"
1227
+ }
1228
+ }, modalError || modalSuccess)
1229
+ )
1202
1230
  )
1203
1231
  );
1204
1232
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jiggai/kitchen-plugin-marketing",
3
- "version": "0.5.3",
3
+ "version": "0.5.5",
4
4
  "description": "Marketing Suite plugin for ClawKitchen",
5
5
  "main": "dist/index.js",
6
6
  "files": [