@gallop.software/studio 0.1.82 → 0.1.84
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/{StudioUI-VJVOSOPD.mjs → StudioUI-EER6PAXH.mjs} +987 -509
- package/dist/StudioUI-EER6PAXH.mjs.map +1 -0
- package/dist/{StudioUI-YFDO5MGG.js → StudioUI-VNSW7JUI.js} +691 -213
- package/dist/StudioUI-VNSW7JUI.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
- package/dist/StudioUI-VJVOSOPD.mjs.map +0 -1
- package/dist/StudioUI-YFDO5MGG.js.map +0 -1
|
@@ -674,13 +674,389 @@ function StudioFolderPicker({ selectedItems, currentPath, onMove, onCancel }) {
|
|
|
674
674
|
] }) });
|
|
675
675
|
}
|
|
676
676
|
|
|
677
|
+
// src/components/R2SetupModal.tsx
|
|
678
|
+
|
|
679
|
+
|
|
680
|
+
|
|
681
|
+
var ENV_TEMPLATE = `CLOUDFLARE_R2_ACCOUNT_ID=your_account_id
|
|
682
|
+
CLOUDFLARE_R2_ACCESS_KEY_ID=your_access_key
|
|
683
|
+
CLOUDFLARE_R2_SECRET_ACCESS_KEY=your_secret_key
|
|
684
|
+
CLOUDFLARE_R2_BUCKET_NAME=your_bucket_name
|
|
685
|
+
CLOUDFLARE_R2_PUBLIC_URL=https://pub-xxx.r2.dev`;
|
|
686
|
+
var styles3 = {
|
|
687
|
+
overlay: _react3.css`
|
|
688
|
+
position: fixed;
|
|
689
|
+
inset: 0;
|
|
690
|
+
background: rgba(0, 0, 0, 0.6);
|
|
691
|
+
display: flex;
|
|
692
|
+
align-items: center;
|
|
693
|
+
justify-content: center;
|
|
694
|
+
z-index: 1100;
|
|
695
|
+
padding: 20px;
|
|
696
|
+
`,
|
|
697
|
+
modal: _react3.css`
|
|
698
|
+
background: ${_chunkUFCWGUAGjs.colors.surface};
|
|
699
|
+
border-radius: 12px;
|
|
700
|
+
max-width: 560px;
|
|
701
|
+
width: 100%;
|
|
702
|
+
max-height: 90vh;
|
|
703
|
+
overflow-y: auto;
|
|
704
|
+
box-shadow: 0 20px 40px rgba(0, 0, 0, 0.3);
|
|
705
|
+
`,
|
|
706
|
+
header: _react3.css`
|
|
707
|
+
display: flex;
|
|
708
|
+
align-items: center;
|
|
709
|
+
gap: 12px;
|
|
710
|
+
padding: 20px 24px;
|
|
711
|
+
border-bottom: 1px solid ${_chunkUFCWGUAGjs.colors.border};
|
|
712
|
+
`,
|
|
713
|
+
icon: _react3.css`
|
|
714
|
+
width: 32px;
|
|
715
|
+
height: 32px;
|
|
716
|
+
color: ${_chunkUFCWGUAGjs.colors.primary};
|
|
717
|
+
flex-shrink: 0;
|
|
718
|
+
`,
|
|
719
|
+
title: _react3.css`
|
|
720
|
+
font-size: ${_chunkUFCWGUAGjs.fontSize.xl};
|
|
721
|
+
font-weight: 600;
|
|
722
|
+
color: ${_chunkUFCWGUAGjs.colors.text};
|
|
723
|
+
margin: 0;
|
|
724
|
+
`,
|
|
725
|
+
closeBtn: _react3.css`
|
|
726
|
+
margin-left: auto;
|
|
727
|
+
background: none;
|
|
728
|
+
border: none;
|
|
729
|
+
padding: 4px;
|
|
730
|
+
cursor: pointer;
|
|
731
|
+
color: ${_chunkUFCWGUAGjs.colors.textMuted};
|
|
732
|
+
border-radius: 4px;
|
|
733
|
+
|
|
734
|
+
&:hover {
|
|
735
|
+
color: ${_chunkUFCWGUAGjs.colors.text};
|
|
736
|
+
background: ${_chunkUFCWGUAGjs.colors.surfaceHover};
|
|
737
|
+
}
|
|
738
|
+
`,
|
|
739
|
+
closeIcon: _react3.css`
|
|
740
|
+
width: 20px;
|
|
741
|
+
height: 20px;
|
|
742
|
+
`,
|
|
743
|
+
content: _react3.css`
|
|
744
|
+
padding: 24px;
|
|
745
|
+
`,
|
|
746
|
+
intro: _react3.css`
|
|
747
|
+
font-size: ${_chunkUFCWGUAGjs.fontSize.base};
|
|
748
|
+
color: ${_chunkUFCWGUAGjs.colors.textSecondary};
|
|
749
|
+
margin: 0 0 20px 0;
|
|
750
|
+
line-height: 1.6;
|
|
751
|
+
`,
|
|
752
|
+
steps: _react3.css`
|
|
753
|
+
list-style: none;
|
|
754
|
+
padding: 0;
|
|
755
|
+
margin: 0;
|
|
756
|
+
display: flex;
|
|
757
|
+
flex-direction: column;
|
|
758
|
+
gap: 16px;
|
|
759
|
+
`,
|
|
760
|
+
step: _react3.css`
|
|
761
|
+
display: flex;
|
|
762
|
+
gap: 12px;
|
|
763
|
+
`,
|
|
764
|
+
stepNumber: _react3.css`
|
|
765
|
+
width: 28px;
|
|
766
|
+
height: 28px;
|
|
767
|
+
border-radius: 50%;
|
|
768
|
+
background: ${_chunkUFCWGUAGjs.colors.primaryLight};
|
|
769
|
+
color: ${_chunkUFCWGUAGjs.colors.primary};
|
|
770
|
+
font-size: ${_chunkUFCWGUAGjs.fontSize.sm};
|
|
771
|
+
font-weight: 600;
|
|
772
|
+
display: flex;
|
|
773
|
+
align-items: center;
|
|
774
|
+
justify-content: center;
|
|
775
|
+
flex-shrink: 0;
|
|
776
|
+
`,
|
|
777
|
+
stepContent: _react3.css`
|
|
778
|
+
flex: 1;
|
|
779
|
+
padding-top: 3px;
|
|
780
|
+
`,
|
|
781
|
+
stepTitle: _react3.css`
|
|
782
|
+
font-size: ${_chunkUFCWGUAGjs.fontSize.base};
|
|
783
|
+
font-weight: 500;
|
|
784
|
+
color: ${_chunkUFCWGUAGjs.colors.text};
|
|
785
|
+
margin: 0 0 4px 0;
|
|
786
|
+
`,
|
|
787
|
+
stepDesc: _react3.css`
|
|
788
|
+
font-size: ${_chunkUFCWGUAGjs.fontSize.sm};
|
|
789
|
+
color: ${_chunkUFCWGUAGjs.colors.textSecondary};
|
|
790
|
+
margin: 0;
|
|
791
|
+
line-height: 1.5;
|
|
792
|
+
`,
|
|
793
|
+
link: _react3.css`
|
|
794
|
+
color: ${_chunkUFCWGUAGjs.colors.primary};
|
|
795
|
+
text-decoration: none;
|
|
796
|
+
font-weight: 500;
|
|
797
|
+
|
|
798
|
+
&:hover {
|
|
799
|
+
text-decoration: underline;
|
|
800
|
+
}
|
|
801
|
+
`,
|
|
802
|
+
envVarsWrapper: _react3.css`
|
|
803
|
+
position: relative;
|
|
804
|
+
margin-top: 20px;
|
|
805
|
+
`,
|
|
806
|
+
envVars: _react3.css`
|
|
807
|
+
background: ${_chunkUFCWGUAGjs.colors.background};
|
|
808
|
+
border: 1px solid ${_chunkUFCWGUAGjs.colors.border};
|
|
809
|
+
border-radius: 8px;
|
|
810
|
+
padding: 16px;
|
|
811
|
+
padding-right: 48px;
|
|
812
|
+
font-family: 'SF Mono', Monaco, 'Cascadia Code', monospace;
|
|
813
|
+
font-size: 13px;
|
|
814
|
+
line-height: 1.8;
|
|
815
|
+
color: ${_chunkUFCWGUAGjs.colors.text};
|
|
816
|
+
overflow-x: auto;
|
|
817
|
+
`,
|
|
818
|
+
envVar: _react3.css`
|
|
819
|
+
display: block;
|
|
820
|
+
`,
|
|
821
|
+
envKey: _react3.css`
|
|
822
|
+
color: ${_chunkUFCWGUAGjs.colors.primary};
|
|
823
|
+
`,
|
|
824
|
+
envValue: _react3.css`
|
|
825
|
+
color: ${_chunkUFCWGUAGjs.colors.textSecondary};
|
|
826
|
+
`,
|
|
827
|
+
copyBtn: _react3.css`
|
|
828
|
+
position: absolute;
|
|
829
|
+
top: 8px;
|
|
830
|
+
right: 8px;
|
|
831
|
+
width: 32px;
|
|
832
|
+
height: 32px;
|
|
833
|
+
display: flex;
|
|
834
|
+
align-items: center;
|
|
835
|
+
justify-content: center;
|
|
836
|
+
background: ${_chunkUFCWGUAGjs.colors.surface};
|
|
837
|
+
border: 1px solid ${_chunkUFCWGUAGjs.colors.border};
|
|
838
|
+
border-radius: 6px;
|
|
839
|
+
cursor: pointer;
|
|
840
|
+
color: ${_chunkUFCWGUAGjs.colors.textMuted};
|
|
841
|
+
transition: all 0.15s ease;
|
|
842
|
+
|
|
843
|
+
&:hover {
|
|
844
|
+
background: ${_chunkUFCWGUAGjs.colors.surfaceHover};
|
|
845
|
+
color: ${_chunkUFCWGUAGjs.colors.text};
|
|
846
|
+
border-color: #d0d5dd;
|
|
847
|
+
}
|
|
848
|
+
`,
|
|
849
|
+
copyIcon: _react3.css`
|
|
850
|
+
width: 16px;
|
|
851
|
+
height: 16px;
|
|
852
|
+
`,
|
|
853
|
+
copiedTooltip: _react3.css`
|
|
854
|
+
position: absolute;
|
|
855
|
+
top: 50%;
|
|
856
|
+
right: 100%;
|
|
857
|
+
transform: translateY(-50%);
|
|
858
|
+
background: #1a1f36;
|
|
859
|
+
color: white;
|
|
860
|
+
padding: 4px 8px;
|
|
861
|
+
border-radius: 4px;
|
|
862
|
+
font-size: 12px;
|
|
863
|
+
white-space: nowrap;
|
|
864
|
+
margin-right: 6px;
|
|
865
|
+
pointer-events: none;
|
|
866
|
+
|
|
867
|
+
&::before {
|
|
868
|
+
content: '';
|
|
869
|
+
position: absolute;
|
|
870
|
+
right: -4px;
|
|
871
|
+
top: 50%;
|
|
872
|
+
transform: translateY(-50%);
|
|
873
|
+
border-left: 4px solid #1a1f36;
|
|
874
|
+
border-top: 4px solid transparent;
|
|
875
|
+
border-bottom: 4px solid transparent;
|
|
876
|
+
}
|
|
877
|
+
`,
|
|
878
|
+
footer: _react3.css`
|
|
879
|
+
padding: 16px 24px;
|
|
880
|
+
border-top: 1px solid ${_chunkUFCWGUAGjs.colors.border};
|
|
881
|
+
display: flex;
|
|
882
|
+
justify-content: flex-end;
|
|
883
|
+
gap: 12px;
|
|
884
|
+
`,
|
|
885
|
+
docsBtn: _react3.css`
|
|
886
|
+
padding: 10px 16px;
|
|
887
|
+
border-radius: 6px;
|
|
888
|
+
font-size: ${_chunkUFCWGUAGjs.fontSize.base};
|
|
889
|
+
font-weight: 500;
|
|
890
|
+
border: 1px solid ${_chunkUFCWGUAGjs.colors.border};
|
|
891
|
+
background: ${_chunkUFCWGUAGjs.colors.surface};
|
|
892
|
+
color: ${_chunkUFCWGUAGjs.colors.text};
|
|
893
|
+
cursor: pointer;
|
|
894
|
+
text-decoration: none;
|
|
895
|
+
display: inline-flex;
|
|
896
|
+
align-items: center;
|
|
897
|
+
gap: 6px;
|
|
898
|
+
transition: all 0.15s ease;
|
|
899
|
+
|
|
900
|
+
&:hover {
|
|
901
|
+
background: ${_chunkUFCWGUAGjs.colors.surfaceHover};
|
|
902
|
+
border-color: #d0d5dd;
|
|
903
|
+
}
|
|
904
|
+
`,
|
|
905
|
+
doneBtn: _react3.css`
|
|
906
|
+
padding: 10px 20px;
|
|
907
|
+
border-radius: 6px;
|
|
908
|
+
font-size: ${_chunkUFCWGUAGjs.fontSize.base};
|
|
909
|
+
font-weight: 500;
|
|
910
|
+
border: none;
|
|
911
|
+
background: ${_chunkUFCWGUAGjs.colors.primary};
|
|
912
|
+
color: white;
|
|
913
|
+
cursor: pointer;
|
|
914
|
+
transition: background 0.15s ease;
|
|
915
|
+
|
|
916
|
+
&:hover {
|
|
917
|
+
background: ${_chunkUFCWGUAGjs.colors.primaryHover};
|
|
918
|
+
}
|
|
919
|
+
`,
|
|
920
|
+
externalIcon: _react3.css`
|
|
921
|
+
width: 14px;
|
|
922
|
+
height: 14px;
|
|
923
|
+
`
|
|
924
|
+
};
|
|
925
|
+
function R2SetupModal({ isOpen, onClose }) {
|
|
926
|
+
const [copied, setCopied] = _react.useState.call(void 0, false);
|
|
927
|
+
const handleCopy = async () => {
|
|
928
|
+
try {
|
|
929
|
+
await navigator.clipboard.writeText(ENV_TEMPLATE);
|
|
930
|
+
setCopied(true);
|
|
931
|
+
setTimeout(() => setCopied(false), 2e3);
|
|
932
|
+
} catch (error) {
|
|
933
|
+
console.error("Failed to copy:", error);
|
|
934
|
+
}
|
|
935
|
+
};
|
|
936
|
+
if (!isOpen) return null;
|
|
937
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles3.overlay, onClick: onClose, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles3.modal, onClick: (e) => e.stopPropagation(), children: [
|
|
938
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles3.header, children: [
|
|
939
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles3.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M3 15a4 4 0 004 4h9a5 5 0 10-.1-9.999 5.002 5.002 0 10-9.78 2.096A4.001 4.001 0 003 15z" }) }),
|
|
940
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { css: styles3.title, children: "Set Up CDN Storage" }),
|
|
941
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles3.closeBtn, onClick: onClose, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles3.closeIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })
|
|
942
|
+
] }),
|
|
943
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles3.content, children: [
|
|
944
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles3.intro, children: "Sync your images to Cloudflare R2 for faster global delivery. R2 offers generous free tier with no egress fees." }),
|
|
945
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "ol", { css: styles3.steps, children: [
|
|
946
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "li", { css: styles3.step, children: [
|
|
947
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles3.stepNumber, children: "1" }),
|
|
948
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles3.stepContent, children: [
|
|
949
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h4", { css: styles3.stepTitle, children: "Create a Cloudflare account" }),
|
|
950
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { css: styles3.stepDesc, children: [
|
|
951
|
+
"Sign up at",
|
|
952
|
+
" ",
|
|
953
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "a", { css: styles3.link, href: "https://dash.cloudflare.com/sign-up", target: "_blank", rel: "noopener noreferrer", children: "dash.cloudflare.com" }),
|
|
954
|
+
" ",
|
|
955
|
+
"if you don't have one already."
|
|
956
|
+
] })
|
|
957
|
+
] })
|
|
958
|
+
] }),
|
|
959
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "li", { css: styles3.step, children: [
|
|
960
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles3.stepNumber, children: "2" }),
|
|
961
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles3.stepContent, children: [
|
|
962
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h4", { css: styles3.stepTitle, children: "Create an R2 bucket" }),
|
|
963
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { css: styles3.stepDesc, children: [
|
|
964
|
+
"Go to R2 in your Cloudflare dashboard and create a new bucket. Choose a name like ",
|
|
965
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "code", { children: "my-images" }),
|
|
966
|
+
"."
|
|
967
|
+
] })
|
|
968
|
+
] })
|
|
969
|
+
] }),
|
|
970
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "li", { css: styles3.step, children: [
|
|
971
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles3.stepNumber, children: "3" }),
|
|
972
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles3.stepContent, children: [
|
|
973
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h4", { css: styles3.stepTitle, children: "Enable public access" }),
|
|
974
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { css: styles3.stepDesc, children: [
|
|
975
|
+
'In bucket settings, enable "Public Access" and copy the public URL (e.g., ',
|
|
976
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "code", { children: "https://pub-xxx.r2.dev" }),
|
|
977
|
+
")."
|
|
978
|
+
] })
|
|
979
|
+
] })
|
|
980
|
+
] }),
|
|
981
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "li", { css: styles3.step, children: [
|
|
982
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles3.stepNumber, children: "4" }),
|
|
983
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles3.stepContent, children: [
|
|
984
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h4", { css: styles3.stepTitle, children: "Create API token" }),
|
|
985
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles3.stepDesc, children: 'Go to R2 \u2192 Manage R2 API Tokens \u2192 Create API Token. Select "Object Read & Write" permissions for your bucket.' })
|
|
986
|
+
] })
|
|
987
|
+
] }),
|
|
988
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "li", { css: styles3.step, children: [
|
|
989
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles3.stepNumber, children: "5" }),
|
|
990
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles3.stepContent, children: [
|
|
991
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h4", { css: styles3.stepTitle, children: "Add environment variables" }),
|
|
992
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { css: styles3.stepDesc, children: [
|
|
993
|
+
"Add these to your ",
|
|
994
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "code", { children: ".env.local" }),
|
|
995
|
+
" file:"
|
|
996
|
+
] })
|
|
997
|
+
] })
|
|
998
|
+
] })
|
|
999
|
+
] }),
|
|
1000
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles3.envVarsWrapper, children: [
|
|
1001
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles3.envVars, children: [
|
|
1002
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { css: styles3.envVar, children: [
|
|
1003
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles3.envKey, children: "CLOUDFLARE_R2_ACCOUNT_ID" }),
|
|
1004
|
+
"=",
|
|
1005
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles3.envValue, children: "your_account_id" })
|
|
1006
|
+
] }),
|
|
1007
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { css: styles3.envVar, children: [
|
|
1008
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles3.envKey, children: "CLOUDFLARE_R2_ACCESS_KEY_ID" }),
|
|
1009
|
+
"=",
|
|
1010
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles3.envValue, children: "your_access_key" })
|
|
1011
|
+
] }),
|
|
1012
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { css: styles3.envVar, children: [
|
|
1013
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles3.envKey, children: "CLOUDFLARE_R2_SECRET_ACCESS_KEY" }),
|
|
1014
|
+
"=",
|
|
1015
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles3.envValue, children: "your_secret_key" })
|
|
1016
|
+
] }),
|
|
1017
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { css: styles3.envVar, children: [
|
|
1018
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles3.envKey, children: "CLOUDFLARE_R2_BUCKET_NAME" }),
|
|
1019
|
+
"=",
|
|
1020
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles3.envValue, children: "your_bucket_name" })
|
|
1021
|
+
] }),
|
|
1022
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { css: styles3.envVar, children: [
|
|
1023
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles3.envKey, children: "CLOUDFLARE_R2_PUBLIC_URL" }),
|
|
1024
|
+
"=",
|
|
1025
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles3.envValue, children: "https://pub-xxx.r2.dev" })
|
|
1026
|
+
] })
|
|
1027
|
+
] }),
|
|
1028
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles3.copyBtn, onClick: handleCopy, title: "Copy to clipboard", children: [
|
|
1029
|
+
copied && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles3.copiedTooltip, children: "Copied!" }),
|
|
1030
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles3.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 16H6a2 2 0 01-2-2V6a2 2 0 012-2h8a2 2 0 012 2v2m-6 12h8a2 2 0 002-2v-8a2 2 0 00-2-2h-8a2 2 0 00-2 2v8a2 2 0 002 2z" }) })
|
|
1031
|
+
] })
|
|
1032
|
+
] })
|
|
1033
|
+
] }),
|
|
1034
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles3.footer, children: [
|
|
1035
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
1036
|
+
"a",
|
|
1037
|
+
{
|
|
1038
|
+
css: styles3.docsBtn,
|
|
1039
|
+
href: "https://developers.cloudflare.com/r2/get-started/",
|
|
1040
|
+
target: "_blank",
|
|
1041
|
+
rel: "noopener noreferrer",
|
|
1042
|
+
children: [
|
|
1043
|
+
"R2 Documentation",
|
|
1044
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles3.externalIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" }) })
|
|
1045
|
+
]
|
|
1046
|
+
}
|
|
1047
|
+
),
|
|
1048
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles3.doneBtn, onClick: onClose, children: "Got it" })
|
|
1049
|
+
] })
|
|
1050
|
+
] }) });
|
|
1051
|
+
}
|
|
1052
|
+
|
|
677
1053
|
// src/components/StudioToolbar.tsx
|
|
678
1054
|
|
|
679
1055
|
var btnHeight = "36px";
|
|
680
1056
|
var spin = _react3.keyframes`
|
|
681
1057
|
to { transform: rotate(360deg); }
|
|
682
1058
|
`;
|
|
683
|
-
var
|
|
1059
|
+
var styles4 = {
|
|
684
1060
|
toolbar: _react3.css`
|
|
685
1061
|
display: flex;
|
|
686
1062
|
flex-wrap: nowrap;
|
|
@@ -898,6 +1274,8 @@ function StudioToolbar() {
|
|
|
898
1274
|
const [showNewFolderModal, setShowNewFolderModal] = _react.useState.call(void 0, false);
|
|
899
1275
|
const [showRenameFolderModal, setShowRenameFolderModal] = _react.useState.call(void 0, false);
|
|
900
1276
|
const [showMoveModal, setShowMoveModal] = _react.useState.call(void 0, false);
|
|
1277
|
+
const [showR2SetupModal, setShowR2SetupModal] = _react.useState.call(void 0, false);
|
|
1278
|
+
const [syncing, setSyncing] = _react.useState.call(void 0, false);
|
|
901
1279
|
const isInImagesFolder = currentPath === "public/images" || currentPath.startsWith("public/images/");
|
|
902
1280
|
const handleUpload = _react.useCallback.call(void 0, () => {
|
|
903
1281
|
_optionalChain([fileInputRef, 'access', _2 => _2.current, 'optionalAccess', _3 => _3.click, 'call', _4 => _4()]);
|
|
@@ -1194,9 +1572,60 @@ function StudioToolbar() {
|
|
|
1194
1572
|
});
|
|
1195
1573
|
}
|
|
1196
1574
|
}, [selectedItems, clearSelection, triggerRefresh]);
|
|
1197
|
-
const handleSyncCdn = _react.useCallback.call(void 0, () => {
|
|
1198
|
-
|
|
1199
|
-
|
|
1575
|
+
const handleSyncCdn = _react.useCallback.call(void 0, async () => {
|
|
1576
|
+
if (selectedItems.size === 0) return;
|
|
1577
|
+
const imageKeys = Array.from(selectedItems).filter((p) => !p.endsWith("/")).map((p) => "/" + p.replace(/^public\//, ""));
|
|
1578
|
+
if (imageKeys.length === 0) {
|
|
1579
|
+
setAlertMessage({
|
|
1580
|
+
title: "No Images Selected",
|
|
1581
|
+
message: "Please select image files to sync to CDN."
|
|
1582
|
+
});
|
|
1583
|
+
return;
|
|
1584
|
+
}
|
|
1585
|
+
setSyncing(true);
|
|
1586
|
+
try {
|
|
1587
|
+
const response = await fetch("/api/studio/sync", {
|
|
1588
|
+
method: "POST",
|
|
1589
|
+
headers: { "Content-Type": "application/json" },
|
|
1590
|
+
body: JSON.stringify({ imageKeys })
|
|
1591
|
+
});
|
|
1592
|
+
const data = await response.json();
|
|
1593
|
+
if (response.ok) {
|
|
1594
|
+
const syncedCount = _optionalChain([data, 'access', _19 => _19.synced, 'optionalAccess', _20 => _20.length]) || 0;
|
|
1595
|
+
const errorCount = _optionalChain([data, 'access', _21 => _21.errors, 'optionalAccess', _22 => _22.length]) || 0;
|
|
1596
|
+
if (errorCount > 0) {
|
|
1597
|
+
setAlertMessage({
|
|
1598
|
+
title: "Sync Partially Complete",
|
|
1599
|
+
message: `Synced ${syncedCount} images. ${errorCount} failed.`
|
|
1600
|
+
});
|
|
1601
|
+
} else {
|
|
1602
|
+
setAlertMessage({
|
|
1603
|
+
title: "Sync Complete",
|
|
1604
|
+
message: `Successfully synced ${syncedCount} images to CDN.`
|
|
1605
|
+
});
|
|
1606
|
+
}
|
|
1607
|
+
clearSelection();
|
|
1608
|
+
triggerRefresh();
|
|
1609
|
+
} else {
|
|
1610
|
+
if (_optionalChain([data, 'access', _23 => _23.error, 'optionalAccess', _24 => _24.includes, 'call', _25 => _25("R2 not configured")]) || _optionalChain([data, 'access', _26 => _26.error, 'optionalAccess', _27 => _27.includes, 'call', _28 => _28("CLOUDFLARE_R2")])) {
|
|
1611
|
+
setShowR2SetupModal(true);
|
|
1612
|
+
} else {
|
|
1613
|
+
setAlertMessage({
|
|
1614
|
+
title: "Sync Failed",
|
|
1615
|
+
message: data.error || "Failed to sync to CDN."
|
|
1616
|
+
});
|
|
1617
|
+
}
|
|
1618
|
+
}
|
|
1619
|
+
} catch (error) {
|
|
1620
|
+
console.error("Sync error:", error);
|
|
1621
|
+
setAlertMessage({
|
|
1622
|
+
title: "Sync Failed",
|
|
1623
|
+
message: "Failed to sync to CDN. Check console for details."
|
|
1624
|
+
});
|
|
1625
|
+
} finally {
|
|
1626
|
+
setSyncing(false);
|
|
1627
|
+
}
|
|
1628
|
+
}, [selectedItems, clearSelection, triggerRefresh]);
|
|
1200
1629
|
const handleCreateFolder = _react.useCallback.call(void 0, async (folderName) => {
|
|
1201
1630
|
setShowNewFolderModal(false);
|
|
1202
1631
|
try {
|
|
@@ -1375,7 +1804,14 @@ function StudioToolbar() {
|
|
|
1375
1804
|
onClose: () => setAlertMessage(null)
|
|
1376
1805
|
}
|
|
1377
1806
|
),
|
|
1378
|
-
/* @__PURE__ */ _jsxruntime.
|
|
1807
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1808
|
+
R2SetupModal,
|
|
1809
|
+
{
|
|
1810
|
+
isOpen: showR2SetupModal,
|
|
1811
|
+
onClose: () => setShowR2SetupModal(false)
|
|
1812
|
+
}
|
|
1813
|
+
),
|
|
1814
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles4.toolbar, children: [
|
|
1379
1815
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1380
1816
|
"input",
|
|
1381
1817
|
{
|
|
@@ -1387,11 +1823,11 @@ function StudioToolbar() {
|
|
|
1387
1823
|
style: { display: "none" }
|
|
1388
1824
|
}
|
|
1389
1825
|
),
|
|
1390
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
1826
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles4.left, children: [
|
|
1391
1827
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
1392
1828
|
"button",
|
|
1393
1829
|
{
|
|
1394
|
-
css: [
|
|
1830
|
+
css: [styles4.btn, styles4.btnPrimary],
|
|
1395
1831
|
onClick: handleUpload,
|
|
1396
1832
|
disabled: uploading || isInImagesFolder,
|
|
1397
1833
|
children: [
|
|
@@ -1403,7 +1839,7 @@ function StudioToolbar() {
|
|
|
1403
1839
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
1404
1840
|
"button",
|
|
1405
1841
|
{
|
|
1406
|
-
css:
|
|
1842
|
+
css: styles4.btn,
|
|
1407
1843
|
onClick: () => singleFolderSelected ? setShowRenameFolderModal(true) : setShowNewFolderModal(true),
|
|
1408
1844
|
disabled: isInImagesFolder && !singleFolderSelected,
|
|
1409
1845
|
title: isInImagesFolder && !singleFolderSelected ? "Cannot create folders in protected images folder" : void 0,
|
|
@@ -1413,11 +1849,11 @@ function StudioToolbar() {
|
|
|
1413
1849
|
]
|
|
1414
1850
|
}
|
|
1415
1851
|
),
|
|
1416
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css:
|
|
1852
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles4.divider }),
|
|
1417
1853
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
1418
1854
|
"button",
|
|
1419
1855
|
{
|
|
1420
|
-
css:
|
|
1856
|
+
css: styles4.btn,
|
|
1421
1857
|
onClick: handleProcessImages,
|
|
1422
1858
|
disabled: processing || isInImagesFolder,
|
|
1423
1859
|
title: isInImagesFolder ? "Cannot process images folder" : void 0,
|
|
@@ -1430,7 +1866,7 @@ function StudioToolbar() {
|
|
|
1430
1866
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
1431
1867
|
"button",
|
|
1432
1868
|
{
|
|
1433
|
-
css: [
|
|
1869
|
+
css: [styles4.btn, styles4.btnDanger],
|
|
1434
1870
|
onClick: handleDeleteClick,
|
|
1435
1871
|
disabled: !hasSelection,
|
|
1436
1872
|
children: [
|
|
@@ -1442,7 +1878,7 @@ function StudioToolbar() {
|
|
|
1442
1878
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
1443
1879
|
"button",
|
|
1444
1880
|
{
|
|
1445
|
-
css:
|
|
1881
|
+
css: styles4.btn,
|
|
1446
1882
|
onClick: handleMoveClick,
|
|
1447
1883
|
disabled: !hasSelection,
|
|
1448
1884
|
children: [
|
|
@@ -1454,20 +1890,20 @@ function StudioToolbar() {
|
|
|
1454
1890
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
1455
1891
|
"button",
|
|
1456
1892
|
{
|
|
1457
|
-
css:
|
|
1893
|
+
css: styles4.btn,
|
|
1458
1894
|
onClick: handleSyncCdn,
|
|
1459
|
-
disabled: !hasSelection,
|
|
1895
|
+
disabled: !hasSelection || syncing,
|
|
1460
1896
|
children: [
|
|
1461
1897
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, CloudIcon, {}),
|
|
1462
|
-
"Sync CDN"
|
|
1898
|
+
syncing ? "Syncing..." : "Sync CDN"
|
|
1463
1899
|
]
|
|
1464
1900
|
}
|
|
1465
1901
|
),
|
|
1466
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
1902
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles4.searchWrapper, children: [
|
|
1467
1903
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1468
1904
|
"input",
|
|
1469
1905
|
{
|
|
1470
|
-
css:
|
|
1906
|
+
css: styles4.searchInput,
|
|
1471
1907
|
type: "text",
|
|
1472
1908
|
placeholder: "Search images...",
|
|
1473
1909
|
value: searchQuery,
|
|
@@ -1478,7 +1914,7 @@ function StudioToolbar() {
|
|
|
1478
1914
|
searchQuery && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1479
1915
|
"button",
|
|
1480
1916
|
{
|
|
1481
|
-
css:
|
|
1917
|
+
css: styles4.searchClearBtn,
|
|
1482
1918
|
onClick: () => setSearchQuery(""),
|
|
1483
1919
|
title: "Clear search",
|
|
1484
1920
|
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { width: "14", height: "14", fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) })
|
|
@@ -1486,25 +1922,25 @@ function StudioToolbar() {
|
|
|
1486
1922
|
)
|
|
1487
1923
|
] })
|
|
1488
1924
|
] }),
|
|
1489
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
1490
|
-
hasSelection && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { css:
|
|
1925
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles4.right, children: [
|
|
1926
|
+
hasSelection && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { css: styles4.selectionCount, children: [
|
|
1491
1927
|
selectedItems.size,
|
|
1492
1928
|
" selected",
|
|
1493
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css:
|
|
1929
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles4.clearBtn, onClick: clearSelection, children: "Clear" })
|
|
1494
1930
|
] }),
|
|
1495
1931
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1496
1932
|
"button",
|
|
1497
1933
|
{
|
|
1498
|
-
css: [
|
|
1934
|
+
css: [styles4.btn, styles4.btnIconOnly],
|
|
1499
1935
|
onClick: handleRefresh,
|
|
1500
1936
|
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, RefreshIcon, { spinning: refreshing })
|
|
1501
1937
|
}
|
|
1502
1938
|
),
|
|
1503
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
1939
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles4.viewToggle, children: [
|
|
1504
1940
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1505
1941
|
"button",
|
|
1506
1942
|
{
|
|
1507
|
-
css: [
|
|
1943
|
+
css: [styles4.viewBtn, viewMode === "grid" && styles4.viewBtnActive],
|
|
1508
1944
|
onClick: () => setViewMode("grid"),
|
|
1509
1945
|
"aria-label": "Grid view",
|
|
1510
1946
|
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, GridIcon, {})
|
|
@@ -1513,7 +1949,7 @@ function StudioToolbar() {
|
|
|
1513
1949
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
1514
1950
|
"button",
|
|
1515
1951
|
{
|
|
1516
|
-
css: [
|
|
1952
|
+
css: [styles4.viewBtn, viewMode === "list" && styles4.viewBtnActive],
|
|
1517
1953
|
onClick: () => setViewMode("list"),
|
|
1518
1954
|
"aria-label": "List view",
|
|
1519
1955
|
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, ListIcon, {})
|
|
@@ -1525,34 +1961,34 @@ function StudioToolbar() {
|
|
|
1525
1961
|
] });
|
|
1526
1962
|
}
|
|
1527
1963
|
function UploadIcon() {
|
|
1528
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
1964
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12" }) });
|
|
1529
1965
|
}
|
|
1530
1966
|
function RefreshIcon({ spinning }) {
|
|
1531
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: [
|
|
1967
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: [styles4.icon, spinning && styles4.iconSpin], fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" }) });
|
|
1532
1968
|
}
|
|
1533
1969
|
function TrashIcon() {
|
|
1534
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
1970
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" }) });
|
|
1535
1971
|
}
|
|
1536
1972
|
function FolderPlusIcon() {
|
|
1537
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
1973
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 13h6m-3-3v6m-9 1V7a2 2 0 012-2h6l2 2h6a2 2 0 012 2v8a2 2 0 01-2 2H5a2 2 0 01-2-2z" }) });
|
|
1538
1974
|
}
|
|
1539
1975
|
function RenameIcon() {
|
|
1540
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
1976
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" }) });
|
|
1541
1977
|
}
|
|
1542
1978
|
function MoveIcon() {
|
|
1543
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
1979
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M8 7h12m0 0l-4-4m4 4l-4 4m0 6H4m0 0l4 4m-4-4l4-4" }) });
|
|
1544
1980
|
}
|
|
1545
1981
|
function CloudIcon() {
|
|
1546
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
1982
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" }) });
|
|
1547
1983
|
}
|
|
1548
1984
|
function GridIcon() {
|
|
1549
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
1985
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2V6zM14 6a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2V6zM4 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2H6a2 2 0 01-2-2v-2zM14 16a2 2 0 012-2h2a2 2 0 012 2v2a2 2 0 01-2 2h-2a2 2 0 01-2-2v-2z" }) });
|
|
1550
1986
|
}
|
|
1551
1987
|
function ListIcon() {
|
|
1552
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
1988
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 6h16M4 10h16M4 14h16M4 18h16" }) });
|
|
1553
1989
|
}
|
|
1554
1990
|
function ImageStackIcon() {
|
|
1555
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
1991
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles4.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) });
|
|
1556
1992
|
}
|
|
1557
1993
|
|
|
1558
1994
|
// src/components/StudioFileGrid.tsx
|
|
@@ -1750,7 +2186,7 @@ function useFileList() {
|
|
|
1750
2186
|
var spin2 = _react3.keyframes`
|
|
1751
2187
|
to { transform: rotate(360deg); }
|
|
1752
2188
|
`;
|
|
1753
|
-
var
|
|
2189
|
+
var styles5 = {
|
|
1754
2190
|
loading: _react3.css`
|
|
1755
2191
|
display: flex;
|
|
1756
2192
|
align-items: center;
|
|
@@ -2083,22 +2519,22 @@ function StudioFileGrid() {
|
|
|
2083
2519
|
handleSelectAll
|
|
2084
2520
|
} = useFileList();
|
|
2085
2521
|
if (loading) {
|
|
2086
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css:
|
|
2522
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles5.loading, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles5.spinner }) });
|
|
2087
2523
|
}
|
|
2088
2524
|
if (sortedItems.length === 0 && isAtRoot) {
|
|
2089
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
2090
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
2091
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css:
|
|
2092
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css:
|
|
2525
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.empty, children: [
|
|
2526
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.emptyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) }),
|
|
2527
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles5.emptyText, children: "No files in this folder" }),
|
|
2528
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles5.emptyText, children: "Upload images to get started" })
|
|
2093
2529
|
] });
|
|
2094
2530
|
}
|
|
2095
2531
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
|
|
2096
|
-
sortedItems.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css:
|
|
2532
|
+
sortedItems.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles5.selectAllRow, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "label", { css: styles5.selectAllLabel, children: [
|
|
2097
2533
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2098
2534
|
"input",
|
|
2099
2535
|
{
|
|
2100
2536
|
type: "checkbox",
|
|
2101
|
-
css:
|
|
2537
|
+
css: styles5.selectAllCheckbox,
|
|
2102
2538
|
checked: allItemsSelected,
|
|
2103
2539
|
ref: (el) => {
|
|
2104
2540
|
if (el) el.indeterminate = someItemsSelected && !allItemsSelected;
|
|
@@ -2110,17 +2546,17 @@ function StudioFileGrid() {
|
|
|
2110
2546
|
sortedItems.length,
|
|
2111
2547
|
")"
|
|
2112
2548
|
] }) }),
|
|
2113
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
2549
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.grid, children: [
|
|
2114
2550
|
!isAtRoot && !isSearching && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
2115
2551
|
"div",
|
|
2116
2552
|
{
|
|
2117
|
-
css: [
|
|
2553
|
+
css: [styles5.item, styles5.parentItem],
|
|
2118
2554
|
onClick: navigateUp,
|
|
2119
2555
|
children: [
|
|
2120
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css:
|
|
2121
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
2122
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css:
|
|
2123
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css:
|
|
2556
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles5.content, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.parentIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6" }) }) }),
|
|
2557
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.label, children: [
|
|
2558
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles5.name, children: ".." }),
|
|
2559
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles5.size, children: "Parent folder" })
|
|
2124
2560
|
] })
|
|
2125
2561
|
]
|
|
2126
2562
|
}
|
|
@@ -2154,43 +2590,43 @@ function GridItem({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
|
|
|
2154
2590
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
2155
2591
|
"div",
|
|
2156
2592
|
{
|
|
2157
|
-
css: [
|
|
2593
|
+
css: [styles5.item, isSelected && styles5.itemSelected],
|
|
2158
2594
|
onClick,
|
|
2159
2595
|
children: [
|
|
2160
2596
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2161
2597
|
"div",
|
|
2162
2598
|
{
|
|
2163
|
-
css:
|
|
2599
|
+
css: styles5.checkboxWrapper,
|
|
2164
2600
|
onClick: (e) => e.stopPropagation(),
|
|
2165
2601
|
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2166
2602
|
"input",
|
|
2167
2603
|
{
|
|
2168
2604
|
type: "checkbox",
|
|
2169
|
-
css:
|
|
2605
|
+
css: styles5.checkbox,
|
|
2170
2606
|
checked: isSelected,
|
|
2171
2607
|
onChange: () => onClick({})
|
|
2172
2608
|
}
|
|
2173
2609
|
)
|
|
2174
2610
|
}
|
|
2175
2611
|
),
|
|
2176
|
-
item.cdnSynced && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css:
|
|
2177
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
2612
|
+
item.cdnSynced && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles5.cdnBadge, children: "CDN" }),
|
|
2613
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.content, children: [
|
|
2178
2614
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
2179
2615
|
"button",
|
|
2180
2616
|
{
|
|
2181
|
-
css:
|
|
2617
|
+
css: styles5.copyBtn,
|
|
2182
2618
|
onClick: handleCopyPath,
|
|
2183
2619
|
title: "Copy file path",
|
|
2184
2620
|
children: [
|
|
2185
|
-
showCopied && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css:
|
|
2186
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
2621
|
+
showCopied && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles5.tooltip, children: "Copied!" }),
|
|
2622
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" }) })
|
|
2187
2623
|
]
|
|
2188
2624
|
}
|
|
2189
2625
|
),
|
|
2190
2626
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2191
2627
|
"button",
|
|
2192
2628
|
{
|
|
2193
|
-
css:
|
|
2629
|
+
css: styles5.openBtn,
|
|
2194
2630
|
onClick: (e) => {
|
|
2195
2631
|
e.stopPropagation();
|
|
2196
2632
|
onOpen();
|
|
@@ -2198,13 +2634,13 @@ function GridItem({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
|
|
|
2198
2634
|
children: "Open"
|
|
2199
2635
|
}
|
|
2200
2636
|
),
|
|
2201
|
-
isFolder ? isImagesFolder ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
2202
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
2203
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
2204
|
-
] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
2637
|
+
isFolder ? isImagesFolder ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.imagesFolderWrapper, children: [
|
|
2638
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.imagesFolderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M10 4H4a2 2 0 00-2 2v12a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2h-8l-2-2z" }) }),
|
|
2639
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.lockIcon, fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { fillRule: "evenodd", d: "M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z", clipRule: "evenodd" }) })
|
|
2640
|
+
] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.folderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M10 4H4a2 2 0 00-2 2v12a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2h-8l-2-2z" }) }) : isImage && item.hasThumbnail ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2205
2641
|
"img",
|
|
2206
2642
|
{
|
|
2207
|
-
css:
|
|
2643
|
+
css: styles5.image,
|
|
2208
2644
|
src: item.thumbnail,
|
|
2209
2645
|
alt: item.name,
|
|
2210
2646
|
loading: "lazy"
|
|
@@ -2212,26 +2648,26 @@ function GridItem({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
|
|
|
2212
2648
|
) : isImage && !item.hasThumbnail ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
2213
2649
|
"button",
|
|
2214
2650
|
{
|
|
2215
|
-
css:
|
|
2651
|
+
css: styles5.noThumbnail,
|
|
2216
2652
|
onClick: (e) => {
|
|
2217
2653
|
e.stopPropagation();
|
|
2218
2654
|
onGenerateThumbnail();
|
|
2219
2655
|
},
|
|
2220
2656
|
title: "Generate thumbnail",
|
|
2221
2657
|
children: [
|
|
2222
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
2223
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css:
|
|
2658
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.noThumbnailIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) }),
|
|
2659
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles5.noThumbnailText, children: "Generate" })
|
|
2224
2660
|
]
|
|
2225
2661
|
}
|
|
2226
|
-
) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
2662
|
+
) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles5.fileIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" }) })
|
|
2227
2663
|
] }),
|
|
2228
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css:
|
|
2229
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css:
|
|
2230
|
-
isFolder ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { css:
|
|
2664
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles5.label, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles5.labelRow, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles5.labelText, children: [
|
|
2665
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles5.name, title: item.name, children: truncateMiddle(item.name) }),
|
|
2666
|
+
isFolder ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "p", { css: styles5.size, children: [
|
|
2231
2667
|
item.fileCount !== void 0 ? `${item.fileCount} files` : "",
|
|
2232
2668
|
item.fileCount !== void 0 && item.totalSize !== void 0 ? " \xB7 " : "",
|
|
2233
2669
|
item.totalSize !== void 0 ? formatFileSize(item.totalSize) : ""
|
|
2234
|
-
] }) : item.size !== void 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css:
|
|
2670
|
+
] }) : item.size !== void 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles5.size, children: formatFileSize(item.size) })
|
|
2235
2671
|
] }) }) })
|
|
2236
2672
|
]
|
|
2237
2673
|
}
|
|
@@ -2263,7 +2699,7 @@ function truncateMiddle(str, maxLength = 24) {
|
|
|
2263
2699
|
var spin3 = _react3.keyframes`
|
|
2264
2700
|
to { transform: rotate(360deg); }
|
|
2265
2701
|
`;
|
|
2266
|
-
var
|
|
2702
|
+
var styles6 = {
|
|
2267
2703
|
loading: _react3.css`
|
|
2268
2704
|
display: flex;
|
|
2269
2705
|
align-items: center;
|
|
@@ -2584,18 +3020,18 @@ function StudioFileList() {
|
|
|
2584
3020
|
handleSelectAll
|
|
2585
3021
|
} = useFileList();
|
|
2586
3022
|
if (loading) {
|
|
2587
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css:
|
|
3023
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles6.loading, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles6.spinner }) });
|
|
2588
3024
|
}
|
|
2589
3025
|
if (sortedItems.length === 0 && isAtRoot) {
|
|
2590
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css:
|
|
3026
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles6.empty, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { children: "No files in this folder" }) });
|
|
2591
3027
|
}
|
|
2592
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css:
|
|
3028
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles6.tableWrapper, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "table", { css: styles6.table, children: [
|
|
2593
3029
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "thead", { children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "tr", { children: [
|
|
2594
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [
|
|
3030
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [styles6.th, styles6.thCheckbox], children: sortedItems.length > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2595
3031
|
"input",
|
|
2596
3032
|
{
|
|
2597
3033
|
type: "checkbox",
|
|
2598
|
-
css:
|
|
3034
|
+
css: styles6.checkbox,
|
|
2599
3035
|
checked: allItemsSelected,
|
|
2600
3036
|
ref: (el) => {
|
|
2601
3037
|
if (el) el.indeterminate = someItemsSelected && !allItemsSelected;
|
|
@@ -2603,21 +3039,21 @@ function StudioFileList() {
|
|
|
2603
3039
|
onChange: handleSelectAll
|
|
2604
3040
|
}
|
|
2605
3041
|
) }),
|
|
2606
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css:
|
|
2607
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [
|
|
2608
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [
|
|
2609
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [
|
|
3042
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: styles6.th, children: "Name" }),
|
|
3043
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [styles6.th, styles6.thSize], children: "Size" }),
|
|
3044
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [styles6.th, styles6.thDimensions], children: "Dimensions" }),
|
|
3045
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "th", { css: [styles6.th, styles6.thCdn], children: "CDN" })
|
|
2610
3046
|
] }) }),
|
|
2611
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "tbody", { css:
|
|
2612
|
-
!isAtRoot && !isSearching && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "tr", { css:
|
|
2613
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css:
|
|
2614
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css:
|
|
2615
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
2616
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css:
|
|
3047
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "tbody", { css: styles6.tbody, children: [
|
|
3048
|
+
!isAtRoot && !isSearching && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "tr", { css: styles6.parentRow, onClick: navigateUp, children: [
|
|
3049
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles6.td }),
|
|
3050
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles6.td, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.nameCell, children: [
|
|
3051
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles6.parentIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M3 10h10a8 8 0 018 8v2M3 10l6 6m-6-6l6-6" }) }),
|
|
3052
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles6.name, children: ".." })
|
|
2617
3053
|
] }) }),
|
|
2618
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: [
|
|
2619
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: [
|
|
2620
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css:
|
|
3054
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: [styles6.td, styles6.meta], children: "--" }),
|
|
3055
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: [styles6.td, styles6.meta], children: "Parent folder" }),
|
|
3056
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles6.td, children: "--" })
|
|
2621
3057
|
] }),
|
|
2622
3058
|
sortedItems.map((item) => /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2623
3059
|
ListRow,
|
|
@@ -2648,59 +3084,59 @@ function ListRow({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
|
|
|
2648
3084
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
2649
3085
|
"tr",
|
|
2650
3086
|
{
|
|
2651
|
-
css: [
|
|
3087
|
+
css: [styles6.row, isSelected && styles6.rowSelected],
|
|
2652
3088
|
onClick,
|
|
2653
3089
|
children: [
|
|
2654
3090
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2655
3091
|
"td",
|
|
2656
3092
|
{
|
|
2657
|
-
css: [
|
|
3093
|
+
css: [styles6.td, styles6.checkboxCell],
|
|
2658
3094
|
onClick: (e) => e.stopPropagation(),
|
|
2659
3095
|
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2660
3096
|
"input",
|
|
2661
3097
|
{
|
|
2662
3098
|
type: "checkbox",
|
|
2663
|
-
css:
|
|
3099
|
+
css: styles6.checkbox,
|
|
2664
3100
|
checked: isSelected,
|
|
2665
3101
|
onChange: () => onClick({})
|
|
2666
3102
|
}
|
|
2667
3103
|
)
|
|
2668
3104
|
}
|
|
2669
3105
|
),
|
|
2670
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css:
|
|
2671
|
-
isFolder ? isImagesFolder ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
2672
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
2673
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
2674
|
-
] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css:
|
|
3106
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles6.td, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.nameCell, children: [
|
|
3107
|
+
isFolder ? isImagesFolder ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.imagesFolderWrapper, children: [
|
|
3108
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles6.imagesFolderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M10 4H4a2 2 0 00-2 2v12a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2h-8l-2-2z" }) }),
|
|
3109
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles6.lockIcon, fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { fillRule: "evenodd", d: "M5 9V7a5 5 0 0110 0v2a2 2 0 012 2v5a2 2 0 01-2 2H5a2 2 0 01-2-2v-5a2 2 0 012-2zm8-2v2H7V7a3 3 0 016 0z", clipRule: "evenodd" }) })
|
|
3110
|
+
] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles6.folderIconWrapper, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles6.folderIcon, fill: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { d: "M10 4H4a2 2 0 00-2 2v12a2 2 0 002 2h16a2 2 0 002-2V8a2 2 0 00-2-2h-8l-2-2z" }) }) }) : isImage && item.hasThumbnail ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles6.thumbnailWrapper, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "img", { css: styles6.thumbnail, src: item.thumbnail, alt: item.name, loading: "lazy" }) }) : isImage && !item.hasThumbnail ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles6.thumbnailWrapper, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2675
3111
|
"button",
|
|
2676
3112
|
{
|
|
2677
|
-
css:
|
|
3113
|
+
css: styles6.noThumbnail,
|
|
2678
3114
|
onClick: (e) => {
|
|
2679
3115
|
e.stopPropagation();
|
|
2680
3116
|
onGenerateThumbnail();
|
|
2681
3117
|
},
|
|
2682
3118
|
title: "Generate thumbnail",
|
|
2683
|
-
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
3119
|
+
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles6.noThumbnailIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) })
|
|
2684
3120
|
}
|
|
2685
|
-
) }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css:
|
|
2686
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css:
|
|
2687
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
3121
|
+
) }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles6.thumbnailWrapper, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles6.fileIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" }) }) }),
|
|
3122
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles6.name, title: item.name, children: truncateMiddle2(item.name) }),
|
|
3123
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles6.actionsCell, children: [
|
|
2688
3124
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
2689
3125
|
"button",
|
|
2690
3126
|
{
|
|
2691
|
-
css:
|
|
3127
|
+
css: styles6.copyBtn,
|
|
2692
3128
|
onClick: handleCopyPath,
|
|
2693
3129
|
title: "Copy file path",
|
|
2694
3130
|
children: [
|
|
2695
|
-
showCopied && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css:
|
|
2696
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
3131
|
+
showCopied && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles6.tooltip, children: "Copied!" }),
|
|
3132
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles6.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" }) })
|
|
2697
3133
|
]
|
|
2698
3134
|
}
|
|
2699
3135
|
),
|
|
2700
3136
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
2701
3137
|
"button",
|
|
2702
3138
|
{
|
|
2703
|
-
css:
|
|
3139
|
+
css: styles6.openBtn,
|
|
2704
3140
|
onClick: (e) => {
|
|
2705
3141
|
e.stopPropagation();
|
|
2706
3142
|
onOpen();
|
|
@@ -2710,12 +3146,12 @@ function ListRow({ item, isSelected, onClick, onOpen, onGenerateThumbnail }) {
|
|
|
2710
3146
|
)
|
|
2711
3147
|
] })
|
|
2712
3148
|
] }) }),
|
|
2713
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: [
|
|
2714
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: [
|
|
2715
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css:
|
|
2716
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
3149
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: [styles6.td, styles6.meta], children: isFolder ? item.fileCount !== void 0 ? `${item.fileCount} files` : "--" : item.size !== void 0 ? formatFileSize2(item.size) : "--" }),
|
|
3150
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: [styles6.td, styles6.meta], children: isFolder ? item.totalSize !== void 0 ? formatFileSize2(item.totalSize) : "--" : item.dimensions ? `${item.dimensions.width}x${item.dimensions.height}` : "--" }),
|
|
3151
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "td", { css: styles6.td, children: item.cdnSynced ? /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { css: styles6.cdnBadge, children: [
|
|
3152
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles6.cdnIcon, fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { fillRule: "evenodd", d: "M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z", clipRule: "evenodd" }) }),
|
|
2717
3153
|
"Synced"
|
|
2718
|
-
] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css:
|
|
3154
|
+
] }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles6.cdnEmpty, children: "--" }) })
|
|
2719
3155
|
]
|
|
2720
3156
|
}
|
|
2721
3157
|
);
|
|
@@ -2753,7 +3189,7 @@ function isVideoFile(filename) {
|
|
|
2753
3189
|
const ext = filename.toLowerCase().substring(filename.lastIndexOf("."));
|
|
2754
3190
|
return VIDEO_EXTENSIONS.includes(ext);
|
|
2755
3191
|
}
|
|
2756
|
-
var
|
|
3192
|
+
var styles7 = {
|
|
2757
3193
|
overlay: _react3.css`
|
|
2758
3194
|
position: absolute;
|
|
2759
3195
|
top: 0;
|
|
@@ -3004,9 +3440,11 @@ function StudioDetailView() {
|
|
|
3004
3440
|
const [showDeleteConfirm, setShowDeleteConfirm] = _react.useState.call(void 0, false);
|
|
3005
3441
|
const [showRenameModal, setShowRenameModal] = _react.useState.call(void 0, false);
|
|
3006
3442
|
const [showProcessConfirm, setShowProcessConfirm] = _react.useState.call(void 0, false);
|
|
3443
|
+
const [showR2SetupModal, setShowR2SetupModal] = _react.useState.call(void 0, false);
|
|
3007
3444
|
const [processProgress, setProcessProgress] = _react.useState.call(void 0, null);
|
|
3008
3445
|
const [alertMessage, setAlertMessage] = _react.useState.call(void 0, null);
|
|
3009
3446
|
const [showCopied, setShowCopied] = _react.useState.call(void 0, false);
|
|
3447
|
+
const [syncing, setSyncing] = _react.useState.call(void 0, false);
|
|
3010
3448
|
if (!focusedItem) return null;
|
|
3011
3449
|
const isImage = isImageFile(focusedItem.name);
|
|
3012
3450
|
const isVideo = isVideoFile(focusedItem.name);
|
|
@@ -3078,8 +3516,41 @@ function StudioDetailView() {
|
|
|
3078
3516
|
});
|
|
3079
3517
|
}
|
|
3080
3518
|
};
|
|
3081
|
-
const handleSync = () => {
|
|
3082
|
-
|
|
3519
|
+
const handleSync = async () => {
|
|
3520
|
+
const imageKey = "/" + focusedItem.path.replace(/^public\//, "");
|
|
3521
|
+
setSyncing(true);
|
|
3522
|
+
try {
|
|
3523
|
+
const response = await fetch("/api/studio/sync", {
|
|
3524
|
+
method: "POST",
|
|
3525
|
+
headers: { "Content-Type": "application/json" },
|
|
3526
|
+
body: JSON.stringify({ imageKeys: [imageKey] })
|
|
3527
|
+
});
|
|
3528
|
+
const data = await response.json();
|
|
3529
|
+
if (response.ok) {
|
|
3530
|
+
setAlertMessage({
|
|
3531
|
+
title: "Sync Complete",
|
|
3532
|
+
message: "Successfully synced to CDN."
|
|
3533
|
+
});
|
|
3534
|
+
triggerRefresh();
|
|
3535
|
+
} else {
|
|
3536
|
+
if (_optionalChain([data, 'access', _29 => _29.error, 'optionalAccess', _30 => _30.includes, 'call', _31 => _31("R2 not configured")]) || _optionalChain([data, 'access', _32 => _32.error, 'optionalAccess', _33 => _33.includes, 'call', _34 => _34("CLOUDFLARE_R2")])) {
|
|
3537
|
+
setShowR2SetupModal(true);
|
|
3538
|
+
} else {
|
|
3539
|
+
setAlertMessage({
|
|
3540
|
+
title: "Sync Failed",
|
|
3541
|
+
message: data.error || "Failed to sync to CDN."
|
|
3542
|
+
});
|
|
3543
|
+
}
|
|
3544
|
+
}
|
|
3545
|
+
} catch (error) {
|
|
3546
|
+
console.error("Sync error:", error);
|
|
3547
|
+
setAlertMessage({
|
|
3548
|
+
title: "Sync Failed",
|
|
3549
|
+
message: "Failed to sync to CDN. Check console for details."
|
|
3550
|
+
});
|
|
3551
|
+
} finally {
|
|
3552
|
+
setSyncing(false);
|
|
3553
|
+
}
|
|
3083
3554
|
};
|
|
3084
3555
|
const handleProcessImage = async () => {
|
|
3085
3556
|
setShowProcessConfirm(false);
|
|
@@ -3101,7 +3572,7 @@ function StudioDetailView() {
|
|
|
3101
3572
|
if (!response.ok) {
|
|
3102
3573
|
throw new Error("Processing failed");
|
|
3103
3574
|
}
|
|
3104
|
-
const reader = _optionalChain([response, 'access',
|
|
3575
|
+
const reader = _optionalChain([response, 'access', _35 => _35.body, 'optionalAccess', _36 => _36.getReader, 'call', _37 => _37()]);
|
|
3105
3576
|
if (!reader) {
|
|
3106
3577
|
throw new Error("No response body");
|
|
3107
3578
|
}
|
|
@@ -3137,14 +3608,14 @@ function StudioDetailView() {
|
|
|
3137
3608
|
};
|
|
3138
3609
|
const renderMedia = () => {
|
|
3139
3610
|
if (isImage) {
|
|
3140
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "img", { css:
|
|
3611
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "img", { css: styles7.image, src: imageSrc, alt: focusedItem.name });
|
|
3141
3612
|
}
|
|
3142
3613
|
if (isVideo) {
|
|
3143
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "video", { css:
|
|
3614
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "video", { css: styles7.video, src: imageSrc, controls: true });
|
|
3144
3615
|
}
|
|
3145
|
-
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
3146
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
3147
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css:
|
|
3616
|
+
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.filePlaceholder, children: [
|
|
3617
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles7.fileIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 1.5, d: "M7 21h10a2 2 0 002-2V9.414a1 1 0 00-.293-.707l-5.414-5.414A1 1 0 0012.586 3H7a2 2 0 00-2 2v14a2 2 0 002 2z" }) }),
|
|
3618
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles7.fileName, children: focusedItem.name })
|
|
3148
3619
|
] });
|
|
3149
3620
|
};
|
|
3150
3621
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
@@ -3167,6 +3638,13 @@ function StudioDetailView() {
|
|
|
3167
3638
|
onClose: () => setAlertMessage(null)
|
|
3168
3639
|
}
|
|
3169
3640
|
),
|
|
3641
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3642
|
+
R2SetupModal,
|
|
3643
|
+
{
|
|
3644
|
+
isOpen: showR2SetupModal,
|
|
3645
|
+
onClose: () => setShowR2SetupModal(false)
|
|
3646
|
+
}
|
|
3647
|
+
),
|
|
3170
3648
|
showRenameModal && /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3171
3649
|
InputModal,
|
|
3172
3650
|
{
|
|
@@ -3197,61 +3675,61 @@ function StudioDetailView() {
|
|
|
3197
3675
|
onClose: () => setProcessProgress(null)
|
|
3198
3676
|
}
|
|
3199
3677
|
),
|
|
3200
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css:
|
|
3201
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
3202
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
3203
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css:
|
|
3204
|
-
showCopied && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css:
|
|
3205
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
3678
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles7.overlay, onClick: handleClose, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.container, onClick: (e) => e.stopPropagation(), children: [
|
|
3679
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.main, children: [
|
|
3680
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.headerButtons, children: [
|
|
3681
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles7.copyBtn, onClick: handleCopyPath, title: "Copy file path", children: [
|
|
3682
|
+
showCopied && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles7.tooltip, children: "Copied!" }),
|
|
3683
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles7.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" }) })
|
|
3206
3684
|
] }),
|
|
3207
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css:
|
|
3685
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles7.mainCloseBtn, onClick: handleClose, "aria-label": "Close", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles7.mainCloseIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })
|
|
3208
3686
|
] }),
|
|
3209
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css:
|
|
3687
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles7.mediaWrapper, children: renderMedia() })
|
|
3210
3688
|
] }),
|
|
3211
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
3212
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css:
|
|
3213
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
3214
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
3215
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
3216
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css:
|
|
3217
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css:
|
|
3689
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.sidebar, children: [
|
|
3690
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles7.sidebarHeader, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css: styles7.sidebarTitle, children: "Details" }) }),
|
|
3691
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.sidebarContent, children: [
|
|
3692
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.info, children: [
|
|
3693
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.infoRow, children: [
|
|
3694
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles7.infoLabel, children: "Name" }),
|
|
3695
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles7.infoValueWrap, children: focusedItem.name })
|
|
3218
3696
|
] }),
|
|
3219
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
3220
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css:
|
|
3221
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css:
|
|
3697
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.infoRow, children: [
|
|
3698
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles7.infoLabel, children: "Path" }),
|
|
3699
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles7.infoValueWrap, children: focusedItem.path.replace(/^public\//, "") })
|
|
3222
3700
|
] }),
|
|
3223
|
-
focusedItem.size !== void 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
3224
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css:
|
|
3225
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css:
|
|
3701
|
+
focusedItem.size !== void 0 && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.infoRow, children: [
|
|
3702
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles7.infoLabel, children: "Size" }),
|
|
3703
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles7.infoValue, children: formatFileSize3(focusedItem.size) })
|
|
3226
3704
|
] }),
|
|
3227
|
-
focusedItem.dimensions && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
3228
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css:
|
|
3229
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { css:
|
|
3705
|
+
focusedItem.dimensions && /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.infoRow, children: [
|
|
3706
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles7.infoLabel, children: "Dimensions" }),
|
|
3707
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { css: styles7.infoValue, children: [
|
|
3230
3708
|
focusedItem.dimensions.width,
|
|
3231
3709
|
" \xD7 ",
|
|
3232
3710
|
focusedItem.dimensions.height
|
|
3233
3711
|
] })
|
|
3234
3712
|
] }),
|
|
3235
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
3236
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css:
|
|
3237
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css:
|
|
3713
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.infoRow, children: [
|
|
3714
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles7.infoLabel, children: "CDN Status" }),
|
|
3715
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles7.infoValue, children: focusedItem.cdnSynced ? "Synced" : "Not synced" })
|
|
3238
3716
|
] })
|
|
3239
3717
|
] }),
|
|
3240
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
3241
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css:
|
|
3242
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
3718
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles7.actions, children: [
|
|
3719
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles7.actionBtn, onClick: () => setShowRenameModal(true), children: [
|
|
3720
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles7.actionIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M11 5H6a2 2 0 00-2 2v11a2 2 0 002 2h11a2 2 0 002-2v-5m-1.414-9.414a2 2 0 112.828 2.828L11.828 15H9v-2.828l8.586-8.586z" }) }),
|
|
3243
3721
|
"Rename"
|
|
3244
3722
|
] }),
|
|
3245
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css:
|
|
3246
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
3247
|
-
"Sync to CDN"
|
|
3723
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles7.actionBtn, onClick: handleSync, disabled: syncing, children: [
|
|
3724
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles7.actionIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M7 16a4 4 0 01-.88-7.903A5 5 0 1115.9 6L16 6a5 5 0 011 9.9M15 13l-3-3m0 0l-3 3m3-3v12" }) }),
|
|
3725
|
+
syncing ? "Syncing..." : "Sync to CDN"
|
|
3248
3726
|
] }),
|
|
3249
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css:
|
|
3250
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
3727
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles7.actionBtn, onClick: () => setShowProcessConfirm(true), children: [
|
|
3728
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles7.actionIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16l4.586-4.586a2 2 0 012.828 0L16 16m-2-2l1.586-1.586a2 2 0 012.828 0L20 14m-6-6h.01M6 20h12a2 2 0 002-2V6a2 2 0 00-2-2H6a2 2 0 00-2 2v12a2 2 0 002 2z" }) }),
|
|
3251
3729
|
"Process Image"
|
|
3252
3730
|
] }),
|
|
3253
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: [
|
|
3254
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
3731
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: [styles7.actionBtn, styles7.actionBtnDanger], onClick: () => setShowDeleteConfirm(true), children: [
|
|
3732
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles7.actionIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M19 7l-.867 12.142A2 2 0 0116.138 21H7.862a2 2 0 01-1.995-1.858L5 7m5 4v6m4-6v6m1-10V4a1 1 0 00-1-1h-4a1 1 0 00-1 1v3M4 7h16" }) }),
|
|
3255
3733
|
"Delete"
|
|
3256
3734
|
] })
|
|
3257
3735
|
] })
|
|
@@ -3271,7 +3749,7 @@ function formatFileSize3(bytes) {
|
|
|
3271
3749
|
|
|
3272
3750
|
|
|
3273
3751
|
var btnHeight2 = "36px";
|
|
3274
|
-
var
|
|
3752
|
+
var styles8 = {
|
|
3275
3753
|
btn: _react3.css`
|
|
3276
3754
|
height: ${btnHeight2};
|
|
3277
3755
|
padding: 0 12px;
|
|
@@ -3509,10 +3987,10 @@ var styles7 = {
|
|
|
3509
3987
|
function StudioSettings() {
|
|
3510
3988
|
const [isOpen, setIsOpen] = _react.useState.call(void 0, false);
|
|
3511
3989
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, _jsxruntime.Fragment, { children: [
|
|
3512
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css:
|
|
3990
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles8.btn, onClick: () => setIsOpen(true), "aria-label": "Settings", children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
3513
3991
|
"svg",
|
|
3514
3992
|
{
|
|
3515
|
-
css:
|
|
3993
|
+
css: styles8.icon,
|
|
3516
3994
|
xmlns: "http://www.w3.org/2000/svg",
|
|
3517
3995
|
viewBox: "0 0 24 24",
|
|
3518
3996
|
fill: "none",
|
|
@@ -3541,50 +4019,50 @@ function SettingsPanel({ onClose }) {
|
|
|
3541
4019
|
setCopied(true);
|
|
3542
4020
|
setTimeout(() => setCopied(false), 2e3);
|
|
3543
4021
|
};
|
|
3544
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css:
|
|
3545
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
3546
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { css:
|
|
3547
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css:
|
|
4022
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles8.overlay, onClick: onClose, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.panel, onClick: (e) => e.stopPropagation(), children: [
|
|
4023
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.header, children: [
|
|
4024
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h2", { css: styles8.title, children: "Settings" }),
|
|
4025
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles8.closeBtn, onClick: onClose, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles8.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M6 18L18 6M6 6l12 12" }) }) })
|
|
3548
4026
|
] }),
|
|
3549
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
4027
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.sections, children: [
|
|
3550
4028
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "section", { children: [
|
|
3551
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css:
|
|
3552
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css:
|
|
3553
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
3554
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css:
|
|
3555
|
-
copied && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css:
|
|
3556
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
4029
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css: styles8.sectionTitle, children: "Cloudflare R2" }),
|
|
4030
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles8.description, children: "Configure in .env.local file:" }),
|
|
4031
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.codeWrapper, children: [
|
|
4032
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "button", { css: styles8.copyBtn, onClick: handleCopy, title: "Copy to clipboard", children: [
|
|
4033
|
+
copied && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles8.tooltip, children: "Copied!" }),
|
|
4034
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles8.copyIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M9 5H7a2 2 0 00-2 2v12a2 2 0 002 2h10a2 2 0 002-2V7a2 2 0 00-2-2h-2M9 5a2 2 0 002 2h2a2 2 0 002-2M9 5a2 2 0 012-2h2a2 2 0 012 2" }) })
|
|
3557
4035
|
] }),
|
|
3558
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
3559
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css:
|
|
3560
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css:
|
|
3561
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css:
|
|
3562
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css:
|
|
3563
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css:
|
|
4036
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.code, children: [
|
|
4037
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles8.codeLine, children: "CLOUDFLARE_R2_ACCOUNT_ID=abc123def456ghi789" }),
|
|
4038
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles8.codeLine, children: "CLOUDFLARE_R2_ACCESS_KEY_ID=your_access_key_id_here" }),
|
|
4039
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles8.codeLine, children: "CLOUDFLARE_R2_SECRET_ACCESS_KEY=your_secret_access_key_here" }),
|
|
4040
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles8.codeLine, children: "CLOUDFLARE_R2_BUCKET_NAME=my-images-bucket" }),
|
|
4041
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles8.codeLine, children: "CLOUDFLARE_R2_PUBLIC_URL=https://cdn.yourdomain.com" })
|
|
3564
4042
|
] })
|
|
3565
4043
|
] })
|
|
3566
4044
|
] }),
|
|
3567
4045
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "section", { children: [
|
|
3568
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css:
|
|
3569
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
4046
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css: styles8.sectionTitle, children: "Thumbnail Sizes" }),
|
|
4047
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.grid, children: [
|
|
3570
4048
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
|
|
3571
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "label", { css:
|
|
3572
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { css:
|
|
4049
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "label", { css: styles8.label, children: "Small" }),
|
|
4050
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { css: styles8.input, type: "number", defaultValue: 300 })
|
|
3573
4051
|
] }),
|
|
3574
4052
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
|
|
3575
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "label", { css:
|
|
3576
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { css:
|
|
4053
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "label", { css: styles8.label, children: "Medium" }),
|
|
4054
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { css: styles8.input, type: "number", defaultValue: 700 })
|
|
3577
4055
|
] }),
|
|
3578
4056
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { children: [
|
|
3579
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "label", { css:
|
|
3580
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { css:
|
|
4057
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "label", { css: styles8.label, children: "Large" }),
|
|
4058
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "input", { css: styles8.input, type: "number", defaultValue: 1400 })
|
|
3581
4059
|
] })
|
|
3582
4060
|
] })
|
|
3583
4061
|
] })
|
|
3584
4062
|
] }),
|
|
3585
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
3586
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css:
|
|
3587
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css:
|
|
4063
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles8.footer, children: [
|
|
4064
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles8.cancelBtn, onClick: onClose, children: "Cancel" }),
|
|
4065
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles8.saveBtn, children: "Save Changes" })
|
|
3588
4066
|
] })
|
|
3589
4067
|
] }) });
|
|
3590
4068
|
}
|
|
@@ -3592,7 +4070,7 @@ function SettingsPanel({ onClose }) {
|
|
|
3592
4070
|
// src/components/ErrorModal.tsx
|
|
3593
4071
|
|
|
3594
4072
|
|
|
3595
|
-
var
|
|
4073
|
+
var styles9 = {
|
|
3596
4074
|
overlay: _react3.css`
|
|
3597
4075
|
position: fixed;
|
|
3598
4076
|
inset: 0;
|
|
@@ -3654,20 +4132,20 @@ var styles8 = {
|
|
|
3654
4132
|
function ErrorModal() {
|
|
3655
4133
|
const { error, clearError } = useStudio();
|
|
3656
4134
|
if (!error) return null;
|
|
3657
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css:
|
|
3658
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
3659
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
3660
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css:
|
|
4135
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles9.overlay, onClick: clearError, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles9.modal, onClick: (e) => e.stopPropagation(), children: [
|
|
4136
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles9.header, children: [
|
|
4137
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles9.icon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M12 9v2m0 4h.01m-6.938 4h13.856c1.54 0 2.502-1.667 1.732-3L13.732 4c-.77-1.333-2.694-1.333-3.464 0L3.34 16c-.77 1.333.192 3 1.732 3z" }) }),
|
|
4138
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h3", { css: styles9.title, children: error.title })
|
|
3661
4139
|
] }),
|
|
3662
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css:
|
|
3663
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css:
|
|
4140
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "p", { css: styles9.message, children: error.message }),
|
|
4141
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "button", { css: styles9.button, onClick: clearError, children: "OK" })
|
|
3664
4142
|
] }) });
|
|
3665
4143
|
}
|
|
3666
4144
|
|
|
3667
4145
|
// src/components/StudioUI.tsx
|
|
3668
4146
|
|
|
3669
4147
|
var btnHeight3 = "36px";
|
|
3670
|
-
var
|
|
4148
|
+
var styles10 = {
|
|
3671
4149
|
container: _react3.css`
|
|
3672
4150
|
${_chunkUFCWGUAGjs.baseReset}
|
|
3673
4151
|
display: flex;
|
|
@@ -3961,16 +4439,16 @@ function StudioUI({ onClose, isVisible = true }) {
|
|
|
3961
4439
|
showError,
|
|
3962
4440
|
clearError
|
|
3963
4441
|
};
|
|
3964
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StudioContext.Provider, { value: contextValue, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
3965
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
3966
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css:
|
|
3967
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css:
|
|
3968
|
-
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css:
|
|
4442
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StudioContext.Provider, { value: contextValue, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles10.container, children: [
|
|
4443
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles10.header, children: [
|
|
4444
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles10.headerLeft, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "h1", { css: styles10.title, children: "Studio" }) }),
|
|
4445
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles10.headerCenter, children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, Breadcrumbs, { currentPath, onNavigate: setCurrentPath }) }),
|
|
4446
|
+
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles10.headerActions, children: [
|
|
3969
4447
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, StudioSettings, {}),
|
|
3970
4448
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
3971
4449
|
"button",
|
|
3972
4450
|
{
|
|
3973
|
-
css:
|
|
4451
|
+
css: styles10.headerBtn,
|
|
3974
4452
|
onClick: onClose,
|
|
3975
4453
|
"aria-label": "Close Studio",
|
|
3976
4454
|
children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, CloseIcon, {})
|
|
@@ -3982,16 +4460,16 @@ function StudioUI({ onClose, isVisible = true }) {
|
|
|
3982
4460
|
/* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
3983
4461
|
"div",
|
|
3984
4462
|
{
|
|
3985
|
-
css:
|
|
4463
|
+
css: styles10.content,
|
|
3986
4464
|
onDragOver: handleDragOver,
|
|
3987
4465
|
onDragLeave: handleDragLeave,
|
|
3988
4466
|
onDrop: handleDrop,
|
|
3989
4467
|
children: [
|
|
3990
|
-
isDragging && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css:
|
|
3991
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css:
|
|
4468
|
+
isDragging && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles10.dropOverlay, children: /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "div", { css: styles10.dropMessage, children: [
|
|
4469
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "svg", { css: styles10.dropIcon, fill: "none", stroke: "currentColor", viewBox: "0 0 24 24", children: /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-8l-4-4m0 0L8 8m4-4v12" }) }),
|
|
3992
4470
|
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { children: "Drop files to upload" })
|
|
3993
4471
|
] }) }),
|
|
3994
|
-
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css:
|
|
4472
|
+
/* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles10.fileBrowser, children: viewMode === "grid" ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StudioFileGrid, {}) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0, StudioFileList, {}) })
|
|
3995
4473
|
]
|
|
3996
4474
|
}
|
|
3997
4475
|
),
|
|
@@ -4005,12 +4483,12 @@ function Breadcrumbs({ currentPath, onNavigate }) {
|
|
|
4005
4483
|
name: part,
|
|
4006
4484
|
path: parts.slice(0, index + 1).join("/")
|
|
4007
4485
|
}));
|
|
4008
|
-
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css:
|
|
4009
|
-
index > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css:
|
|
4010
|
-
index === breadcrumbs.length - 1 ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css:
|
|
4486
|
+
return /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "div", { css: styles10.breadcrumbs, children: breadcrumbs.map((crumb, index) => /* @__PURE__ */ _jsxruntime.jsxs.call(void 0, "span", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
|
|
4487
|
+
index > 0 && /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles10.breadcrumbSeparator, children: "/" }),
|
|
4488
|
+
index === breadcrumbs.length - 1 ? /* @__PURE__ */ _jsxruntime.jsx.call(void 0, "span", { css: styles10.breadcrumbCurrent, children: crumb.name }) : /* @__PURE__ */ _jsxruntime.jsx.call(void 0,
|
|
4011
4489
|
"span",
|
|
4012
4490
|
{
|
|
4013
|
-
css:
|
|
4491
|
+
css: styles10.breadcrumbItem,
|
|
4014
4492
|
onClick: () => onNavigate(crumb.path),
|
|
4015
4493
|
children: crumb.name
|
|
4016
4494
|
}
|
|
@@ -4021,7 +4499,7 @@ function CloseIcon() {
|
|
|
4021
4499
|
return /* @__PURE__ */ _jsxruntime.jsxs.call(void 0,
|
|
4022
4500
|
"svg",
|
|
4023
4501
|
{
|
|
4024
|
-
css:
|
|
4502
|
+
css: styles10.headerIcon,
|
|
4025
4503
|
xmlns: "http://www.w3.org/2000/svg",
|
|
4026
4504
|
viewBox: "0 0 24 24",
|
|
4027
4505
|
fill: "none",
|
|
@@ -4041,4 +4519,4 @@ var StudioUI_default = StudioUI;
|
|
|
4041
4519
|
|
|
4042
4520
|
|
|
4043
4521
|
exports.StudioUI = StudioUI; exports.default = StudioUI_default;
|
|
4044
|
-
//# sourceMappingURL=StudioUI-
|
|
4522
|
+
//# sourceMappingURL=StudioUI-VNSW7JUI.js.map
|