@orion-studios/payload-studio 0.6.0-beta.119 → 0.6.0-beta.120

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.
@@ -9,7 +9,7 @@ import {
9
9
  SiteFooterPreview,
10
10
  adminNavIcons,
11
11
  buildAdminPageLinkOptions
12
- } from "../chunk-KOBQX2HL.mjs";
12
+ } from "../chunk-NF37A575.mjs";
13
13
  import "../chunk-ROTPP5CU.mjs";
14
14
  import {
15
15
  BlockPicker,
@@ -8,7 +8,7 @@ import {
8
8
  MediaUploadForm,
9
9
  SiteFooterPreview,
10
10
  SiteHeaderPreview
11
- } from "../chunk-KOBQX2HL.mjs";
11
+ } from "../chunk-NF37A575.mjs";
12
12
  import "../chunk-ROTPP5CU.mjs";
13
13
 
14
14
  // src/admin-app/components/PageEditorFrame.tsx
@@ -823,6 +823,22 @@ var updateJsonListAttribute = ({
823
823
  [listAttr]: JSON.stringify(list)
824
824
  });
825
825
  };
826
+ var snapshotModel = (model) => ({
827
+ attributes: { ...model.getAttributes?.() || {} },
828
+ style: { ...model.getStyle?.() || {} }
829
+ });
830
+ var pushModelHistory = ({
831
+ after,
832
+ before,
833
+ editor,
834
+ model
835
+ }) => {
836
+ editor?.trigger?.("orion:component-history", {
837
+ after,
838
+ before,
839
+ component: model
840
+ });
841
+ };
826
842
  var addJsonListItem = ({
827
843
  listAttr,
828
844
  model,
@@ -940,11 +956,26 @@ var bindEditablePreview = (view, editor) => {
940
956
  if (!listAttr) {
941
957
  return;
942
958
  }
959
+ const before = snapshotModel(view.model);
960
+ const runListMutation = (callback) => {
961
+ withoutUndoTracking(editor, callback);
962
+ const after = snapshotModel(view.model);
963
+ if (JSON.stringify(before) !== JSON.stringify(after)) {
964
+ pushModelHistory({
965
+ after,
966
+ before,
967
+ editor,
968
+ model: view.model
969
+ });
970
+ }
971
+ };
943
972
  if (action === "add-list-item") {
944
- addJsonListItem({
945
- listAttr,
946
- model: view.model,
947
- template: parseTemplateAttribute(element.dataset.orionItemTemplate)
973
+ runListMutation(() => {
974
+ addJsonListItem({
975
+ listAttr,
976
+ model: view.model,
977
+ template: parseTemplateAttribute(element.dataset.orionItemTemplate)
978
+ });
948
979
  });
949
980
  return;
950
981
  }
@@ -952,18 +983,22 @@ var bindEditablePreview = (view, editor) => {
952
983
  return;
953
984
  }
954
985
  if (action === "duplicate-list-item") {
955
- duplicateJsonListItem({
956
- index: listIndex,
957
- listAttr,
958
- model: view.model
986
+ runListMutation(() => {
987
+ duplicateJsonListItem({
988
+ index: listIndex,
989
+ listAttr,
990
+ model: view.model
991
+ });
959
992
  });
960
993
  return;
961
994
  }
962
995
  if (action === "remove-list-item") {
963
- removeJsonListItem({
964
- index: listIndex,
965
- listAttr,
966
- model: view.model
996
+ runListMutation(() => {
997
+ removeJsonListItem({
998
+ index: listIndex,
999
+ listAttr,
1000
+ model: view.model
1001
+ });
967
1002
  });
968
1003
  }
969
1004
  };
@@ -2876,6 +2911,27 @@ function GrapesPageEditor({
2876
2911
  }
2877
2912
  }, autosaveIntervalMs);
2878
2913
  });
2914
+ editor.on("orion:component-history", (entry) => {
2915
+ if (!entry || typeof entry !== "object" || !("component" in entry) || !("before" in entry) || !("after" in entry)) {
2916
+ return;
2917
+ }
2918
+ const typedEntry = entry;
2919
+ if (!typedEntry.component || !typedEntry.before || !typedEntry.after) {
2920
+ return;
2921
+ }
2922
+ pushCustomHistoryEntry(
2923
+ {
2924
+ attributes: { ...typedEntry.before.attributes || {} },
2925
+ component: typedEntry.component,
2926
+ style: { ...typedEntry.before.style || {} }
2927
+ },
2928
+ {
2929
+ attributes: { ...typedEntry.after.attributes || {} },
2930
+ component: typedEntry.component,
2931
+ style: { ...typedEntry.after.style || {} }
2932
+ }
2933
+ );
2934
+ });
2879
2935
  editor.on("component:selected", (component) => {
2880
2936
  const typed = component;
2881
2937
  const target = getCurrentOrionBlockTarget(typed) || typed;
@@ -699,6 +699,22 @@ var updateJsonListAttribute = ({
699
699
  [listAttr]: JSON.stringify(list)
700
700
  });
701
701
  };
702
+ var snapshotModel = (model) => ({
703
+ attributes: { ...model.getAttributes?.() || {} },
704
+ style: { ...model.getStyle?.() || {} }
705
+ });
706
+ var pushModelHistory = ({
707
+ after,
708
+ before,
709
+ editor,
710
+ model
711
+ }) => {
712
+ editor?.trigger?.("orion:component-history", {
713
+ after,
714
+ before,
715
+ component: model
716
+ });
717
+ };
702
718
  var addJsonListItem = ({
703
719
  listAttr,
704
720
  model,
@@ -816,11 +832,26 @@ var bindEditablePreview = (view, editor) => {
816
832
  if (!listAttr) {
817
833
  return;
818
834
  }
835
+ const before = snapshotModel(view.model);
836
+ const runListMutation = (callback) => {
837
+ withoutUndoTracking(editor, callback);
838
+ const after = snapshotModel(view.model);
839
+ if (JSON.stringify(before) !== JSON.stringify(after)) {
840
+ pushModelHistory({
841
+ after,
842
+ before,
843
+ editor,
844
+ model: view.model
845
+ });
846
+ }
847
+ };
819
848
  if (action === "add-list-item") {
820
- addJsonListItem({
821
- listAttr,
822
- model: view.model,
823
- template: parseTemplateAttribute(element.dataset.orionItemTemplate)
849
+ runListMutation(() => {
850
+ addJsonListItem({
851
+ listAttr,
852
+ model: view.model,
853
+ template: parseTemplateAttribute(element.dataset.orionItemTemplate)
854
+ });
824
855
  });
825
856
  return;
826
857
  }
@@ -828,18 +859,22 @@ var bindEditablePreview = (view, editor) => {
828
859
  return;
829
860
  }
830
861
  if (action === "duplicate-list-item") {
831
- duplicateJsonListItem({
832
- index: listIndex,
833
- listAttr,
834
- model: view.model
862
+ runListMutation(() => {
863
+ duplicateJsonListItem({
864
+ index: listIndex,
865
+ listAttr,
866
+ model: view.model
867
+ });
835
868
  });
836
869
  return;
837
870
  }
838
871
  if (action === "remove-list-item") {
839
- removeJsonListItem({
840
- index: listIndex,
841
- listAttr,
842
- model: view.model
872
+ runListMutation(() => {
873
+ removeJsonListItem({
874
+ index: listIndex,
875
+ listAttr,
876
+ model: view.model
877
+ });
843
878
  });
844
879
  }
845
880
  };
@@ -2752,6 +2787,27 @@ function GrapesPageEditor({
2752
2787
  }
2753
2788
  }, autosaveIntervalMs);
2754
2789
  });
2790
+ editor.on("orion:component-history", (entry) => {
2791
+ if (!entry || typeof entry !== "object" || !("component" in entry) || !("before" in entry) || !("after" in entry)) {
2792
+ return;
2793
+ }
2794
+ const typedEntry = entry;
2795
+ if (!typedEntry.component || !typedEntry.before || !typedEntry.after) {
2796
+ return;
2797
+ }
2798
+ pushCustomHistoryEntry(
2799
+ {
2800
+ attributes: { ...typedEntry.before.attributes || {} },
2801
+ component: typedEntry.component,
2802
+ style: { ...typedEntry.before.style || {} }
2803
+ },
2804
+ {
2805
+ attributes: { ...typedEntry.after.attributes || {} },
2806
+ component: typedEntry.component,
2807
+ style: { ...typedEntry.after.style || {} }
2808
+ }
2809
+ );
2810
+ });
2755
2811
  editor.on("component:selected", (component) => {
2756
2812
  const typed = component;
2757
2813
  const target = getCurrentOrionBlockTarget(typed) || typed;
@@ -734,124 +734,13 @@ function HeaderNavEditorWithPreview({
734
734
  ] });
735
735
  }
736
736
 
737
- // src/admin-app/components/MediaDetailPanel.tsx
738
- import { useState as useState4 } from "react";
737
+ // src/admin-app/components/MediaListItem.tsx
739
738
  import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
740
739
  function formatFileSize(bytes) {
741
740
  if (bytes < 1024) return `${bytes} B`;
742
741
  if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
743
742
  return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
744
743
  }
745
- function MediaDetailPanel({
746
- id,
747
- filename,
748
- alt,
749
- url,
750
- filesize,
751
- width,
752
- height,
753
- mimeType,
754
- createdAt,
755
- updateAction,
756
- deleteAction
757
- }) {
758
- const [copied, setCopied] = useState4(false);
759
- const [confirmDelete, setConfirmDelete] = useState4(false);
760
- const copyUrl = async () => {
761
- if (!url) return;
762
- try {
763
- await navigator.clipboard.writeText(url);
764
- setCopied(true);
765
- setTimeout(() => setCopied(false), 2e3);
766
- } catch {
767
- const input = document.createElement("input");
768
- input.value = url;
769
- document.body.appendChild(input);
770
- input.select();
771
- document.execCommand("copy");
772
- document.body.removeChild(input);
773
- setCopied(true);
774
- setTimeout(() => setCopied(false), 2e3);
775
- }
776
- };
777
- const metaRows = [];
778
- if (filename) metaRows.push({ label: "Filename", value: filename });
779
- if (typeof filesize === "number") metaRows.push({ label: "File size", value: formatFileSize(filesize) });
780
- if (typeof width === "number" && typeof height === "number") metaRows.push({ label: "Dimensions", value: `${width} \xD7 ${height} px` });
781
- if (mimeType) metaRows.push({ label: "Type", value: mimeType });
782
- if (createdAt) {
783
- try {
784
- metaRows.push({ label: "Uploaded", value: new Date(createdAt).toLocaleDateString() });
785
- } catch {
786
- metaRows.push({ label: "Uploaded", value: createdAt });
787
- }
788
- }
789
- return /* @__PURE__ */ jsxs5("div", { className: "orion-admin-grid", style: { alignItems: "start" }, children: [
790
- /* @__PURE__ */ jsxs5("div", { children: [
791
- /* @__PURE__ */ jsx5("div", { className: "orion-admin-card", children: url ? /* @__PURE__ */ jsx5("img", { alt: alt || filename || "Media", src: url, style: { borderRadius: 12, width: "100%" } }) : /* @__PURE__ */ jsx5("span", { children: "No preview available." }) }),
792
- url ? /* @__PURE__ */ jsx5(
793
- "button",
794
- {
795
- className: "orion-admin-action-button",
796
- onClick: copyUrl,
797
- style: { marginTop: "0.6rem", width: "100%" },
798
- type: "button",
799
- children: copied ? "Copied!" : "Copy URL"
800
- }
801
- ) : null
802
- ] }),
803
- /* @__PURE__ */ jsxs5("div", { style: { display: "grid", gap: "0.8rem" }, children: [
804
- metaRows.length > 0 ? /* @__PURE__ */ jsx5("div", { className: "orion-admin-card orion-admin-meta-table", children: metaRows.map((row) => /* @__PURE__ */ jsxs5("div", { className: "orion-admin-meta-row", children: [
805
- /* @__PURE__ */ jsx5("span", { className: "orion-admin-meta-label", children: row.label }),
806
- /* @__PURE__ */ jsx5("span", { className: "orion-admin-meta-value", children: row.value })
807
- ] }, row.label)) }) : null,
808
- /* @__PURE__ */ jsxs5("form", { action: updateAction, className: "orion-admin-form", children: [
809
- /* @__PURE__ */ jsx5("input", { name: "id", type: "hidden", value: id }),
810
- /* @__PURE__ */ jsxs5("label", { children: [
811
- "Alt text",
812
- /* @__PURE__ */ jsx5("input", { defaultValue: alt || "", name: "alt", required: true, type: "text" })
813
- ] }),
814
- /* @__PURE__ */ jsx5("button", { type: "submit", children: "Save" })
815
- ] }),
816
- confirmDelete ? /* @__PURE__ */ jsxs5("div", { className: "orion-admin-form", style: { borderColor: "#b42318" }, children: [
817
- /* @__PURE__ */ jsx5("p", { style: { fontWeight: 700, margin: 0 }, children: "Are you sure you want to delete this asset?" }),
818
- /* @__PURE__ */ jsx5("p", { style: { color: "var(--orion-admin-muted)", fontSize: "0.9rem", margin: 0 }, children: "This action cannot be undone." }),
819
- /* @__PURE__ */ jsxs5("div", { style: { display: "flex", gap: "0.5rem" }, children: [
820
- /* @__PURE__ */ jsxs5("form", { action: deleteAction, style: { flex: 1 }, children: [
821
- /* @__PURE__ */ jsx5("input", { name: "id", type: "hidden", value: id }),
822
- /* @__PURE__ */ jsx5("button", { style: { background: "#b42318", border: 0, borderRadius: 10, color: "#fff", cursor: "pointer", fontWeight: 800, padding: "0.55rem 0.8rem", width: "100%" }, type: "submit", children: "Yes, Delete" })
823
- ] }),
824
- /* @__PURE__ */ jsx5(
825
- "button",
826
- {
827
- onClick: () => setConfirmDelete(false),
828
- style: { background: "transparent", border: "1px solid var(--orion-admin-border)", borderRadius: 10, cursor: "pointer", flex: 1, fontWeight: 700, padding: "0.55rem 0.8rem" },
829
- type: "button",
830
- children: "Cancel"
831
- }
832
- )
833
- ] })
834
- ] }) : /* @__PURE__ */ jsx5(
835
- "button",
836
- {
837
- className: "orion-admin-action-button",
838
- onClick: () => setConfirmDelete(true),
839
- style: { background: "#b42318" },
840
- type: "button",
841
- children: "Delete Asset"
842
- }
843
- )
844
- ] })
845
- ] });
846
- }
847
-
848
- // src/admin-app/components/MediaListItem.tsx
849
- import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
850
- function formatFileSize2(bytes) {
851
- if (bytes < 1024) return `${bytes} B`;
852
- if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
853
- return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
854
- }
855
744
  function MediaListItem({
856
745
  id,
857
746
  filename,
@@ -866,26 +755,26 @@ function MediaListItem({
866
755
  const label = filename || `Media ${id}`;
867
756
  const altText = alt || "";
868
757
  const metaParts = [];
869
- if (typeof filesize === "number") metaParts.push(formatFileSize2(filesize));
758
+ if (typeof filesize === "number") metaParts.push(formatFileSize(filesize));
870
759
  if (typeof width === "number" && typeof height === "number") metaParts.push(`${width}\xD7${height}`);
871
760
  if (typeof mimeType === "string") metaParts.push(mimeType);
872
- return /* @__PURE__ */ jsxs6("a", { className: "orion-admin-list-item", href, children: [
873
- /* @__PURE__ */ jsxs6("div", { style: { alignItems: "center", display: "flex", gap: "0.8rem" }, children: [
874
- url ? /* @__PURE__ */ jsx6("img", { alt: altText || label, className: "orion-admin-media-preview", src: url }) : null,
875
- /* @__PURE__ */ jsxs6("div", { children: [
876
- /* @__PURE__ */ jsx6("strong", { children: label }),
877
- /* @__PURE__ */ jsx6("div", { className: "orion-admin-list-meta", children: altText || "No alt text" }),
878
- metaParts.length > 0 ? /* @__PURE__ */ jsx6("div", { className: "orion-admin-list-meta", style: { marginTop: "0.15rem" }, children: metaParts.join(" \xB7 ") }) : null
761
+ return /* @__PURE__ */ jsxs5("a", { className: "orion-admin-list-item", href, children: [
762
+ /* @__PURE__ */ jsxs5("div", { style: { alignItems: "center", display: "flex", gap: "0.8rem" }, children: [
763
+ url ? /* @__PURE__ */ jsx5("img", { alt: altText || label, className: "orion-admin-media-preview", src: url }) : null,
764
+ /* @__PURE__ */ jsxs5("div", { children: [
765
+ /* @__PURE__ */ jsx5("strong", { children: label }),
766
+ /* @__PURE__ */ jsx5("div", { className: "orion-admin-list-meta", children: altText || "No alt text" }),
767
+ metaParts.length > 0 ? /* @__PURE__ */ jsx5("div", { className: "orion-admin-list-meta", style: { marginTop: "0.15rem" }, children: metaParts.join(" \xB7 ") }) : null
879
768
  ] })
880
769
  ] }),
881
- /* @__PURE__ */ jsx6("span", { className: "orion-admin-list-meta", children: "Edit" })
770
+ /* @__PURE__ */ jsx5("span", { className: "orion-admin-list-meta", children: "Edit" })
882
771
  ] });
883
772
  }
884
773
 
885
774
  // src/admin-app/components/MediaUploadForm.tsx
886
- import { useState as useState5, useRef, useCallback } from "react";
775
+ import { useState as useState4, useRef, useCallback } from "react";
887
776
  import { useRouter } from "next/navigation";
888
- import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
777
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
889
778
  var MEDIA_LIBRARY_SYNC_EVENT = "orion-media-library-updated";
890
779
  var notifyMediaLibraryUpdated = () => {
891
780
  if (typeof window === "undefined") {
@@ -926,12 +815,12 @@ var parseUploadError = async (response) => {
926
815
  function MediaUploadForm() {
927
816
  const router = useRouter();
928
817
  const fileInputRef = useRef(null);
929
- const [alt, setAlt] = useState5("");
930
- const [file, setFile] = useState5(null);
931
- const [preview, setPreview] = useState5(null);
932
- const [dragging, setDragging] = useState5(false);
933
- const [submitting, setSubmitting] = useState5(false);
934
- const [error, setError] = useState5(null);
818
+ const [alt, setAlt] = useState4("");
819
+ const [file, setFile] = useState4(null);
820
+ const [preview, setPreview] = useState4(null);
821
+ const [dragging, setDragging] = useState4(false);
822
+ const [submitting, setSubmitting] = useState4(false);
823
+ const [error, setError] = useState4(null);
935
824
  const handleFile = useCallback((selectedFile) => {
936
825
  setFile(selectedFile);
937
826
  if (preview) {
@@ -999,10 +888,10 @@ function MediaUploadForm() {
999
888
  setSubmitting(false);
1000
889
  }
1001
890
  };
1002
- return /* @__PURE__ */ jsxs7("form", { className: "orion-admin-upload-form", onSubmit: upload, children: [
1003
- /* @__PURE__ */ jsxs7("label", { children: [
891
+ return /* @__PURE__ */ jsxs6("form", { className: "orion-admin-upload-form", onSubmit: upload, children: [
892
+ /* @__PURE__ */ jsxs6("label", { children: [
1004
893
  "Alt text",
1005
- /* @__PURE__ */ jsx7(
894
+ /* @__PURE__ */ jsx6(
1006
895
  "input",
1007
896
  {
1008
897
  onChange: (event) => setAlt(event.target.value),
@@ -1012,7 +901,7 @@ function MediaUploadForm() {
1012
901
  }
1013
902
  )
1014
903
  ] }),
1015
- /* @__PURE__ */ jsxs7(
904
+ /* @__PURE__ */ jsxs6(
1016
905
  "div",
1017
906
  {
1018
907
  className: `orion-admin-dropzone${dragging ? " is-dragging" : ""}${file ? " has-file" : ""}`,
@@ -1021,14 +910,14 @@ function MediaUploadForm() {
1021
910
  onDragOver,
1022
911
  onDrop,
1023
912
  children: [
1024
- preview ? /* @__PURE__ */ jsxs7("div", { className: "orion-admin-dropzone-preview", children: [
1025
- /* @__PURE__ */ jsx7("img", { alt: "Upload preview", src: preview }),
1026
- /* @__PURE__ */ jsx7("span", { children: file?.name })
1027
- ] }) : /* @__PURE__ */ jsxs7("div", { className: "orion-admin-dropzone-label", children: [
1028
- /* @__PURE__ */ jsx7("strong", { children: "Drop an image here" }),
1029
- /* @__PURE__ */ jsx7("span", { children: "or click to browse" })
913
+ preview ? /* @__PURE__ */ jsxs6("div", { className: "orion-admin-dropzone-preview", children: [
914
+ /* @__PURE__ */ jsx6("img", { alt: "Upload preview", src: preview }),
915
+ /* @__PURE__ */ jsx6("span", { children: file?.name })
916
+ ] }) : /* @__PURE__ */ jsxs6("div", { className: "orion-admin-dropzone-label", children: [
917
+ /* @__PURE__ */ jsx6("strong", { children: "Drop an image here" }),
918
+ /* @__PURE__ */ jsx6("span", { children: "or click to browse" })
1030
919
  ] }),
1031
- /* @__PURE__ */ jsx7(
920
+ /* @__PURE__ */ jsx6(
1032
921
  "input",
1033
922
  {
1034
923
  accept: "image/*",
@@ -1041,8 +930,119 @@ function MediaUploadForm() {
1041
930
  ]
1042
931
  }
1043
932
  ),
1044
- error ? /* @__PURE__ */ jsx7("div", { className: "orion-admin-upload-error", children: error }) : null,
1045
- /* @__PURE__ */ jsx7("button", { disabled: submitting, type: "submit", children: submitting ? "Uploading..." : "Upload" })
933
+ error ? /* @__PURE__ */ jsx6("div", { className: "orion-admin-upload-error", children: error }) : null,
934
+ /* @__PURE__ */ jsx6("button", { disabled: submitting, type: "submit", children: submitting ? "Uploading..." : "Upload" })
935
+ ] });
936
+ }
937
+
938
+ // src/admin-app/components/MediaDetailPanel.tsx
939
+ import { useState as useState5 } from "react";
940
+ import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
941
+ function formatFileSize2(bytes) {
942
+ if (bytes < 1024) return `${bytes} B`;
943
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
944
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
945
+ }
946
+ function MediaDetailPanel({
947
+ id,
948
+ filename,
949
+ alt,
950
+ url,
951
+ filesize,
952
+ width,
953
+ height,
954
+ mimeType,
955
+ createdAt,
956
+ updateAction,
957
+ deleteAction
958
+ }) {
959
+ const [copied, setCopied] = useState5(false);
960
+ const [confirmDelete, setConfirmDelete] = useState5(false);
961
+ const copyUrl = async () => {
962
+ if (!url) return;
963
+ try {
964
+ await navigator.clipboard.writeText(url);
965
+ setCopied(true);
966
+ setTimeout(() => setCopied(false), 2e3);
967
+ } catch {
968
+ const input = document.createElement("input");
969
+ input.value = url;
970
+ document.body.appendChild(input);
971
+ input.select();
972
+ document.execCommand("copy");
973
+ document.body.removeChild(input);
974
+ setCopied(true);
975
+ setTimeout(() => setCopied(false), 2e3);
976
+ }
977
+ };
978
+ const metaRows = [];
979
+ if (filename) metaRows.push({ label: "Filename", value: filename });
980
+ if (typeof filesize === "number") metaRows.push({ label: "File size", value: formatFileSize2(filesize) });
981
+ if (typeof width === "number" && typeof height === "number") metaRows.push({ label: "Dimensions", value: `${width} \xD7 ${height} px` });
982
+ if (mimeType) metaRows.push({ label: "Type", value: mimeType });
983
+ if (createdAt) {
984
+ try {
985
+ metaRows.push({ label: "Uploaded", value: new Date(createdAt).toLocaleDateString() });
986
+ } catch {
987
+ metaRows.push({ label: "Uploaded", value: createdAt });
988
+ }
989
+ }
990
+ return /* @__PURE__ */ jsxs7("div", { className: "orion-admin-grid", style: { alignItems: "start" }, children: [
991
+ /* @__PURE__ */ jsxs7("div", { children: [
992
+ /* @__PURE__ */ jsx7("div", { className: "orion-admin-card", children: url ? /* @__PURE__ */ jsx7("img", { alt: alt || filename || "Media", src: url, style: { borderRadius: 12, width: "100%" } }) : /* @__PURE__ */ jsx7("span", { children: "No preview available." }) }),
993
+ url ? /* @__PURE__ */ jsx7(
994
+ "button",
995
+ {
996
+ className: "orion-admin-action-button",
997
+ onClick: copyUrl,
998
+ style: { marginTop: "0.6rem", width: "100%" },
999
+ type: "button",
1000
+ children: copied ? "Copied!" : "Copy URL"
1001
+ }
1002
+ ) : null
1003
+ ] }),
1004
+ /* @__PURE__ */ jsxs7("div", { style: { display: "grid", gap: "0.8rem" }, children: [
1005
+ metaRows.length > 0 ? /* @__PURE__ */ jsx7("div", { className: "orion-admin-card orion-admin-meta-table", children: metaRows.map((row) => /* @__PURE__ */ jsxs7("div", { className: "orion-admin-meta-row", children: [
1006
+ /* @__PURE__ */ jsx7("span", { className: "orion-admin-meta-label", children: row.label }),
1007
+ /* @__PURE__ */ jsx7("span", { className: "orion-admin-meta-value", children: row.value })
1008
+ ] }, row.label)) }) : null,
1009
+ /* @__PURE__ */ jsxs7("form", { action: updateAction, className: "orion-admin-form", children: [
1010
+ /* @__PURE__ */ jsx7("input", { name: "id", type: "hidden", value: id }),
1011
+ /* @__PURE__ */ jsxs7("label", { children: [
1012
+ "Alt text",
1013
+ /* @__PURE__ */ jsx7("input", { defaultValue: alt || "", name: "alt", required: true, type: "text" })
1014
+ ] }),
1015
+ /* @__PURE__ */ jsx7("button", { type: "submit", children: "Save" })
1016
+ ] }),
1017
+ confirmDelete ? /* @__PURE__ */ jsxs7("div", { className: "orion-admin-form", style: { borderColor: "#b42318" }, children: [
1018
+ /* @__PURE__ */ jsx7("p", { style: { fontWeight: 700, margin: 0 }, children: "Are you sure you want to delete this asset?" }),
1019
+ /* @__PURE__ */ jsx7("p", { style: { color: "var(--orion-admin-muted)", fontSize: "0.9rem", margin: 0 }, children: "This action cannot be undone." }),
1020
+ /* @__PURE__ */ jsxs7("div", { style: { display: "flex", gap: "0.5rem" }, children: [
1021
+ /* @__PURE__ */ jsxs7("form", { action: deleteAction, style: { flex: 1 }, children: [
1022
+ /* @__PURE__ */ jsx7("input", { name: "id", type: "hidden", value: id }),
1023
+ /* @__PURE__ */ jsx7("button", { style: { background: "#b42318", border: 0, borderRadius: 10, color: "#fff", cursor: "pointer", fontWeight: 800, padding: "0.55rem 0.8rem", width: "100%" }, type: "submit", children: "Yes, Delete" })
1024
+ ] }),
1025
+ /* @__PURE__ */ jsx7(
1026
+ "button",
1027
+ {
1028
+ onClick: () => setConfirmDelete(false),
1029
+ style: { background: "transparent", border: "1px solid var(--orion-admin-border)", borderRadius: 10, cursor: "pointer", flex: 1, fontWeight: 700, padding: "0.55rem 0.8rem" },
1030
+ type: "button",
1031
+ children: "Cancel"
1032
+ }
1033
+ )
1034
+ ] })
1035
+ ] }) : /* @__PURE__ */ jsx7(
1036
+ "button",
1037
+ {
1038
+ className: "orion-admin-action-button",
1039
+ onClick: () => setConfirmDelete(true),
1040
+ style: { background: "#b42318" },
1041
+ type: "button",
1042
+ children: "Delete Asset"
1043
+ }
1044
+ )
1045
+ ] })
1046
1046
  ] });
1047
1047
  }
1048
1048
 
@@ -1054,7 +1054,7 @@ export {
1054
1054
  SiteHeaderPreview,
1055
1055
  SiteFooterPreview,
1056
1056
  HeaderNavEditorWithPreview,
1057
- MediaDetailPanel,
1058
1057
  MediaListItem,
1059
- MediaUploadForm
1058
+ MediaUploadForm,
1059
+ MediaDetailPanel
1060
1060
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@orion-studios/payload-studio",
3
- "version": "0.6.0-beta.119",
3
+ "version": "0.6.0-beta.120",
4
4
  "description": "Base CMS, builder, and custom admin toolkit for Orion Studios websites",
5
5
  "types": "./dist/index.d.ts",
6
6
  "main": "./dist/index.js",