@interware/content-generator 0.4.4 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (166) hide show
  1. package/README.md +21 -1
  2. package/dist/_chunks/{App-CfwvfmvL.js → App-CJxSC8yt.js} +32 -720
  3. package/dist/_chunks/{App-BQr5_g5u.mjs → App-qbgUXlOZ.mjs} +38 -726
  4. package/dist/_chunks/ImageStudioTabs-BLAH3KYv.mjs +5270 -0
  5. package/dist/_chunks/ImageStudioTabs-DtusqpQO.js +5271 -0
  6. package/dist/_chunks/PluginProviders-D79TeGSE.js +34 -0
  7. package/dist/_chunks/PluginProviders-DWMpcAIh.mjs +35 -0
  8. package/dist/_chunks/Settings-BQXxV3LO.js +242 -0
  9. package/dist/_chunks/Settings-o2GngLaW.mjs +242 -0
  10. package/dist/_chunks/StudioApp-BaySMwrk.js +18 -0
  11. package/dist/_chunks/StudioApp-C_znlQRo.mjs +18 -0
  12. package/dist/_chunks/{getTranslation-B9ND5RaH.mjs → getTranslation-B6Bsu-uq.mjs} +1 -1
  13. package/dist/_chunks/{getTranslation-DNhP1INv.js → getTranslation-BRVMWSf8.js} +1 -1
  14. package/dist/_chunks/{index-DGPqyrzz.js → index-BKhe-Jyx.js} +24 -6
  15. package/dist/_chunks/{index-Dyq8dxMX.mjs → index-BKigRXm3.mjs} +25 -7
  16. package/dist/admin/index.js +1 -1
  17. package/dist/admin/index.mjs +1 -1
  18. package/dist/admin/src/components/PluginIcon.d.ts +4 -2
  19. package/dist/admin/src/components/PluginProviders.d.ts +12 -0
  20. package/dist/admin/src/components/generate-video/Form.d.ts +1 -1
  21. package/dist/admin/src/components/settings/Form.d.ts +4 -5
  22. package/dist/admin/src/components/settings/VertexSettings.d.ts +18 -0
  23. package/dist/admin/src/containers/settings/index.d.ts +7 -7
  24. package/dist/admin/src/features/background-removal/RemoveBackgroundButton.d.ts +7 -0
  25. package/dist/admin/src/features/background-removal/RemoveBackgroundDialog.d.ts +15 -0
  26. package/dist/admin/src/features/background-removal/colorKey.d.ts +29 -0
  27. package/dist/admin/src/features/background-removal/imageCanvas.d.ts +20 -0
  28. package/dist/admin/src/features/background-removal/mask.d.ts +10 -0
  29. package/dist/admin/src/features/background-removal/runtime.d.ts +31 -0
  30. package/dist/admin/src/features/generator/EditEmpty.d.ts +13 -0
  31. package/dist/admin/src/features/generator/GeneratorTab.d.ts +7 -0
  32. package/dist/admin/src/features/generator/GroundingSources.d.ts +9 -0
  33. package/dist/admin/src/features/generator/ModeSwitch.d.ts +6 -0
  34. package/dist/admin/src/features/generator/PromptComposer.d.ts +25 -0
  35. package/dist/admin/src/features/generator/ReferencePicker.d.ts +26 -0
  36. package/dist/admin/src/features/generator/VersionHistory.d.ts +13 -0
  37. package/dist/admin/src/features/generator/generatorApi.d.ts +71 -0
  38. package/dist/admin/src/features/generator/model.d.ts +60 -0
  39. package/dist/admin/src/features/generator/useGeneratorApi.d.ts +21 -0
  40. package/dist/admin/src/features/image-studio/ImageStudioTabs.d.ts +26 -0
  41. package/dist/admin/src/features/image-studio/SegmentedSwitch.d.ts +18 -0
  42. package/dist/admin/src/features/image-studio/checkerboard.d.ts +5 -0
  43. package/dist/admin/src/features/library/FileCard.d.ts +17 -0
  44. package/dist/admin/src/features/library/FolderTree.d.ts +14 -0
  45. package/dist/admin/src/features/library/LibraryDialogs.d.ts +46 -0
  46. package/dist/admin/src/features/library/LibraryImagePicker.d.ts +15 -0
  47. package/dist/admin/src/features/library/LibraryTab.d.ts +2 -0
  48. package/dist/admin/src/features/library/SaveToLibraryDialog.d.ts +15 -0
  49. package/dist/admin/src/features/library/model.d.ts +40 -0
  50. package/dist/admin/src/features/library/studioRoot.d.ts +11 -0
  51. package/dist/admin/src/features/library/uploadApi.d.ts +77 -0
  52. package/dist/admin/src/features/library/useLibraryApi.d.ts +34 -0
  53. package/dist/admin/src/features/templates/editor/ColorField.d.ts +11 -0
  54. package/dist/admin/src/features/templates/editor/Editor.d.ts +19 -0
  55. package/dist/admin/src/features/templates/editor/EditorBar.d.ts +9 -0
  56. package/dist/admin/src/features/templates/editor/EditorMenuBar.d.ts +58 -0
  57. package/dist/admin/src/features/templates/editor/EditorToolbar.d.ts +20 -0
  58. package/dist/admin/src/features/templates/editor/ElementPalette.d.ts +10 -0
  59. package/dist/admin/src/features/templates/editor/FloatingPanel.d.ts +17 -0
  60. package/dist/admin/src/features/templates/editor/FullscreenView.d.ts +11 -0
  61. package/dist/admin/src/features/templates/editor/IconPicker.d.ts +9 -0
  62. package/dist/admin/src/features/templates/editor/Inspector.d.ts +17 -0
  63. package/dist/admin/src/features/templates/editor/LayersPanel.d.ts +12 -0
  64. package/dist/admin/src/features/templates/editor/Precision.d.ts +23 -0
  65. package/dist/admin/src/features/templates/editor/RangeField.d.ts +12 -0
  66. package/dist/admin/src/features/templates/editor/SaveTemplateDialog.d.ts +14 -0
  67. package/dist/admin/src/features/templates/editor/Stage.d.ts +29 -0
  68. package/dist/admin/src/features/templates/editor/TemplateFolderSelect.d.ts +9 -0
  69. package/dist/admin/src/features/templates/editor/TemplatePicker.d.ts +23 -0
  70. package/dist/admin/src/features/templates/editor/TemplatesTab.d.ts +5 -0
  71. package/dist/admin/src/features/templates/editor/TypographyControls.d.ts +24 -0
  72. package/dist/admin/src/features/templates/editor/icons.d.ts +7 -0
  73. package/dist/admin/src/features/templates/editor/overlays.d.ts +20 -0
  74. package/dist/admin/src/features/templates/editor/useCanvasNav.d.ts +25 -0
  75. package/dist/admin/src/features/templates/editor/useFitScale.d.ts +3 -0
  76. package/dist/admin/src/features/templates/export/fontEmbed.d.ts +22 -0
  77. package/dist/admin/src/features/templates/export/imageSource.d.ts +21 -0
  78. package/dist/admin/src/features/templates/export/pdf.d.ts +6 -0
  79. package/dist/admin/src/features/templates/export/render.d.ts +22 -0
  80. package/dist/admin/src/features/templates/export/useEditorIO.d.ts +18 -0
  81. package/dist/admin/src/features/templates/fonts/catalog.d.ts +47 -0
  82. package/dist/admin/src/features/templates/fonts/customFonts.d.ts +19 -0
  83. package/dist/admin/src/features/templates/fonts/useCustomFonts.d.ts +9 -0
  84. package/dist/admin/src/features/templates/fonts/useFonts.d.ts +2 -0
  85. package/dist/admin/src/features/templates/model/drag.d.ts +10 -0
  86. package/dist/admin/src/features/templates/model/editorReducer.d.ts +58 -0
  87. package/dist/admin/src/features/templates/model/layers.d.ts +42 -0
  88. package/dist/admin/src/features/templates/model/palette.d.ts +38 -0
  89. package/dist/admin/src/features/templates/model/presets.d.ts +17 -0
  90. package/dist/admin/src/features/templates/model/shortcuts.d.ts +19 -0
  91. package/dist/admin/src/features/templates/model/snap.d.ts +24 -0
  92. package/dist/admin/src/features/templates/model/templates.d.ts +8 -0
  93. package/dist/admin/src/features/templates/model/types.d.ts +154 -0
  94. package/dist/admin/src/features/templates/model/viewport.d.ts +36 -0
  95. package/dist/admin/src/features/templates/render/IWLogo.d.ts +7 -0
  96. package/dist/admin/src/features/templates/render/LayerCanvas.d.ts +13 -0
  97. package/dist/admin/src/features/templates/render/fonts.d.ts +5 -0
  98. package/dist/admin/src/features/templates/render/icons.d.ts +10 -0
  99. package/dist/admin/src/features/templates/render/renderLayer.d.ts +9 -0
  100. package/dist/admin/src/features/templates/store/persist.d.ts +41 -0
  101. package/dist/admin/src/features/templates/store/templatesApi.d.ts +49 -0
  102. package/dist/admin/src/features/templates/store/useMyTemplates.d.ts +19 -0
  103. package/dist/admin/src/features/templates/store/useTemplateSaving.d.ts +14 -0
  104. package/dist/admin/src/features/templates/store/useTemplatesApi.d.ts +23 -0
  105. package/dist/admin/src/hooks/useAdminTheme.d.ts +8 -0
  106. package/dist/admin/src/hooks/useThemeColors.d.ts +9 -0
  107. package/dist/admin/src/lib/dataUrl.d.ts +6 -0
  108. package/dist/admin/src/lib/promptRules.d.ts +23 -0
  109. package/dist/admin/src/lib/use-cases/articles/index.d.ts +12 -1
  110. package/dist/admin/src/lib/use-cases/categories/index.d.ts +12 -1
  111. package/dist/admin/src/lib/use-cases/facebook/index.d.ts +1 -1
  112. package/dist/admin/src/lib/use-cases/generate-content/index.d.ts +2 -2
  113. package/dist/admin/src/lib/use-cases/images/index.d.ts +1 -4
  114. package/dist/admin/src/lib/use-cases/linkedin/index.d.ts +1 -1
  115. package/dist/admin/src/lib/use-cases/settings/index.d.ts +14 -2
  116. package/dist/admin/src/lib/use-cases/users/index.d.ts +12 -1
  117. package/dist/admin/src/pages/ImageStudio.d.ts +3 -0
  118. package/dist/admin/src/pages/StudioApp.d.ts +3 -0
  119. package/dist/admin/src/pluginId.d.ts +6 -0
  120. package/dist/admin/src/test-setup.d.ts +1 -0
  121. package/dist/admin/src/test-utils.d.ts +5 -0
  122. package/dist/server/index.js +2494 -1279
  123. package/dist/server/index.mjs +2501 -1285
  124. package/dist/server/src/bootstrap.d.ts +1 -1
  125. package/dist/server/src/content-types/index.d.ts +66 -1
  126. package/dist/server/src/content-types/template/index.d.ts +65 -0
  127. package/dist/server/src/content-types/template/schema.d.ts +69 -0
  128. package/dist/server/src/controllers/config.d.ts +10 -0
  129. package/dist/server/src/controllers/controller.d.ts +0 -5
  130. package/dist/server/src/controllers/image-studio.d.ts +23 -0
  131. package/dist/server/src/controllers/index.d.ts +129 -5
  132. package/dist/server/src/controllers/templates.d.ts +26 -0
  133. package/dist/server/src/image-studio/geminiConfig.d.ts +40 -0
  134. package/dist/server/src/image-studio/models.d.ts +39 -0
  135. package/dist/server/src/image-studio/prompt.d.ts +7 -0
  136. package/dist/server/src/image-studio/validate.d.ts +41 -0
  137. package/dist/server/src/index.d.ts +233 -75
  138. package/dist/server/src/routes/admin.d.ts +6 -2
  139. package/dist/server/src/routes/content-api.d.ts +4 -9
  140. package/dist/server/src/routes/index.d.ts +7 -11
  141. package/dist/server/src/routes/policies.d.ts +14 -0
  142. package/dist/server/src/services/image-studio.d.ts +66 -0
  143. package/dist/server/src/services/index.d.ts +30 -57
  144. package/dist/server/src/services/service.d.ts +10 -57
  145. package/dist/server/src/services/templates.d.ts +81 -0
  146. package/dist/server/src/templates/folders.d.ts +14 -0
  147. package/dist/server/src/templates/validate.d.ts +23 -0
  148. package/dist/server/src/utils/folders.d.ts +15 -0
  149. package/dist/server/src/utils/geminiClient.d.ts +24 -0
  150. package/dist/server/src/utils/secrets.d.ts +9 -0
  151. package/dist/server/src/utils/serviceAccount.d.ts +29 -0
  152. package/package.json +23 -10
  153. package/static/background-worker.d.mts +15 -0
  154. package/static/background-worker.mjs +87 -0
  155. package/dist/_chunks/Settings-BrqTzJp-.js +0 -262
  156. package/dist/_chunks/Settings-CdZnYLLK.mjs +0 -244
  157. package/dist/admin/src/components/Navigation.d.ts +0 -2
  158. package/dist/admin/src/components/generate-image/Form.d.ts +0 -15
  159. package/dist/admin/src/components/generate-images/Image.d.ts +0 -5
  160. package/dist/admin/src/components/generate-images/Images.d.ts +0 -2
  161. package/dist/admin/src/components/generate-images/Modal.d.ts +0 -9
  162. package/dist/admin/src/containers/generate-image/index.d.ts +0 -2
  163. package/dist/admin/src/containers/generate-images/index.d.ts +0 -2
  164. package/dist/admin/src/hooks/generate-images/useImages.d.ts +0 -12
  165. package/dist/admin/src/pages/GenerateImage.d.ts +0 -2
  166. package/dist/admin/src/pages/GenerateImages.d.ts +0 -2
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ const jsxRuntime = require("react/jsx-runtime");
3
+ const reactTooltip = require("@radix-ui/react-tooltip");
4
+ const designSystem = require("@strapi/design-system");
5
+ const styledComponents = require("styled-components");
6
+ const react = require("react");
7
+ const THEME_KEY = "STRAPI_THEME";
8
+ const stored = () => {
9
+ try {
10
+ return localStorage.getItem(THEME_KEY);
11
+ } catch {
12
+ return null;
13
+ }
14
+ };
15
+ const systemDark = () => typeof window !== "undefined" && !!window.matchMedia?.("(prefers-color-scheme: dark)").matches;
16
+ const useAdminTheme = () => {
17
+ const choice = stored();
18
+ const [dark, setDark] = react.useState(systemDark);
19
+ react.useEffect(() => {
20
+ if (choice === "light" || choice === "dark") return;
21
+ const mq = window.matchMedia?.("(prefers-color-scheme: dark)");
22
+ if (!mq) return;
23
+ const onChange = (e) => setDark(e.matches);
24
+ mq.addEventListener("change", onChange);
25
+ return () => mq.removeEventListener("change", onChange);
26
+ }, [choice]);
27
+ if (choice === "light" || choice === "dark") return choice;
28
+ return dark ? "dark" : "light";
29
+ };
30
+ const PluginProviders = ({ children }) => {
31
+ const scheme = useAdminTheme();
32
+ return /* @__PURE__ */ jsxRuntime.jsx(styledComponents.ThemeProvider, { theme: scheme === "dark" ? designSystem.darkTheme : designSystem.lightTheme, children: /* @__PURE__ */ jsxRuntime.jsx(reactTooltip.Provider, { children }) });
33
+ };
34
+ exports.PluginProviders = PluginProviders;
@@ -0,0 +1,35 @@
1
+ import { jsx } from "react/jsx-runtime";
2
+ import { Provider } from "@radix-ui/react-tooltip";
3
+ import { darkTheme, lightTheme } from "@strapi/design-system";
4
+ import { ThemeProvider } from "styled-components";
5
+ import { useState, useEffect } from "react";
6
+ const THEME_KEY = "STRAPI_THEME";
7
+ const stored = () => {
8
+ try {
9
+ return localStorage.getItem(THEME_KEY);
10
+ } catch {
11
+ return null;
12
+ }
13
+ };
14
+ const systemDark = () => typeof window !== "undefined" && !!window.matchMedia?.("(prefers-color-scheme: dark)").matches;
15
+ const useAdminTheme = () => {
16
+ const choice = stored();
17
+ const [dark, setDark] = useState(systemDark);
18
+ useEffect(() => {
19
+ if (choice === "light" || choice === "dark") return;
20
+ const mq = window.matchMedia?.("(prefers-color-scheme: dark)");
21
+ if (!mq) return;
22
+ const onChange = (e) => setDark(e.matches);
23
+ mq.addEventListener("change", onChange);
24
+ return () => mq.removeEventListener("change", onChange);
25
+ }, [choice]);
26
+ if (choice === "light" || choice === "dark") return choice;
27
+ return dark ? "dark" : "light";
28
+ };
29
+ const PluginProviders = ({ children }) => {
30
+ const scheme = useAdminTheme();
31
+ return /* @__PURE__ */ jsx(ThemeProvider, { theme: scheme === "dark" ? darkTheme : lightTheme, children: /* @__PURE__ */ jsx(Provider, { children }) });
32
+ };
33
+ export {
34
+ PluginProviders as P
35
+ };
@@ -0,0 +1,242 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const admin = require("@strapi/strapi/admin");
5
+ const reactIntl = require("react-intl");
6
+ const react = require("react");
7
+ const designSystem = require("@strapi/design-system");
8
+ const formik = require("formik");
9
+ const PluginProviders = require("./PluginProviders-D79TeGSE.js");
10
+ const index = require("./index-BKhe-Jyx.js");
11
+ const getTranslation = require("./getTranslation-BRVMWSf8.js");
12
+ const useSettings = () => {
13
+ const { get, post, del } = admin.useFetchClient();
14
+ const getSettings = react.useCallback(
15
+ async (config) => {
16
+ return get("/strapi-content-generator-gemini/config", config);
17
+ },
18
+ [get]
19
+ );
20
+ const setSettings = react.useCallback(
21
+ async (data, config) => {
22
+ return post("/strapi-content-generator-gemini/config", data, config);
23
+ },
24
+ [post]
25
+ );
26
+ const removeVertex = react.useCallback(async () => del("/strapi-content-generator-gemini/config/vertex"), [del]);
27
+ return {
28
+ getSettings,
29
+ setSettings,
30
+ removeVertex
31
+ };
32
+ };
33
+ const FIELDS = [
34
+ { name: "googleGenAI", label: "API Key Gemini" },
35
+ { name: "linkedInAccessToken", label: "LinkedIn Access Token" },
36
+ { name: "linkedInOrganizationId", label: "LinkedIn Organization ID" },
37
+ { name: "facebookClientToken", label: "FACEBOOK CLIENT TOKEN" },
38
+ { name: "facebookPageId", label: "FACEBOOK PAGE ID" }
39
+ ];
40
+ const EMPTY = {
41
+ googleGenAI: "",
42
+ linkedInAccessToken: "",
43
+ linkedInOrganizationId: "",
44
+ facebookClientToken: "",
45
+ facebookPageId: ""
46
+ };
47
+ const hint = ({ configured, last4 }) => configured ? `Configurada ···${last4}` : "Sin configurar";
48
+ const filledOnly = (values) => Object.fromEntries(Object.entries(values).filter(([, value]) => value.trim() !== ""));
49
+ const Form = ({ status, handleSubmit }) => {
50
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 6, margin: 6, background: "neutral0", width: "100%", children: /* @__PURE__ */ jsxRuntime.jsx(
51
+ formik.Formik,
52
+ {
53
+ initialValues: EMPTY,
54
+ onSubmit: async (values, { resetForm }) => {
55
+ await handleSubmit(filledOnly(values));
56
+ resetForm();
57
+ },
58
+ children: ({ values, handleChange, handleBlur, handleSubmit: submit, isSubmitting }) => {
59
+ const hasChanges = Object.keys(filledOnly(values)).length > 0;
60
+ return /* @__PURE__ */ jsxRuntime.jsx("form", { onSubmit: submit, children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Grid.Root, { gap: 4, children: [
61
+ FIELDS.map(({ name, label }) => /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Field.Root, { id: name, width: "100%", hint: hint(status[name]), children: [
62
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: label }),
63
+ /* @__PURE__ */ jsxRuntime.jsx(
64
+ designSystem.Field.Input,
65
+ {
66
+ name,
67
+ value: values[name],
68
+ onChange: handleChange,
69
+ onBlur: handleBlur,
70
+ type: "password",
71
+ autoComplete: "off",
72
+ placeholder: "Escribe un valor nuevo para reemplazarla"
73
+ }
74
+ ),
75
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Hint, {})
76
+ ] }) }, name)),
77
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Flex, { justifyContent: "end", alignItems: "end", width: "100%", children: /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { type: "submit", disabled: !hasChanges || isSubmitting, children: "Guardar" }) }) })
78
+ ] }) });
79
+ }
80
+ }
81
+ ) });
82
+ };
83
+ const statusLine = ({ configured, projectId, clientEmail }) => configured ? `Configurada · proyecto ${projectId} · ${clientEmail}` : "Sin configurar: el plugin usa la llave de Gemini.";
84
+ const VertexSettings = ({ status, onSave, onRemove }) => {
85
+ const [text, setText] = react.useState("");
86
+ const [error, setError] = react.useState(null);
87
+ const [busy, setBusy] = react.useState(false);
88
+ const save = async () => {
89
+ setBusy(true);
90
+ setError(null);
91
+ try {
92
+ await onSave(text);
93
+ setText("");
94
+ } catch (err) {
95
+ setError(err instanceof Error ? err.message : "No se pudo guardar la cuenta de servicio.");
96
+ } finally {
97
+ setBusy(false);
98
+ }
99
+ };
100
+ const remove = async () => {
101
+ setBusy(true);
102
+ try {
103
+ await onRemove();
104
+ } finally {
105
+ setBusy(false);
106
+ }
107
+ };
108
+ return /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { padding: 6, margin: 6, background: "neutral0", width: "100%", children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
109
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "start", gap: 1, children: [
110
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "delta", tag: "h2", children: "Vertex AI" }),
111
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", textColor: "neutral600", children: statusLine(status) })
112
+ ] }),
113
+ /* @__PURE__ */ jsxRuntime.jsxs(
114
+ designSystem.Field.Root,
115
+ {
116
+ id: "vertexServiceAccount",
117
+ error: error ?? void 0,
118
+ hint: "Pega el contenido completo del archivo .json de la cuenta de servicio. La llave privada no vuelve a mostrarse.",
119
+ children: [
120
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Label, { children: "JSON de la cuenta de servicio" }),
121
+ /* @__PURE__ */ jsxRuntime.jsx(
122
+ designSystem.Textarea,
123
+ {
124
+ name: "vertexServiceAccount",
125
+ value: text,
126
+ onChange: (e) => setText(e.target.value),
127
+ placeholder: '{ "type": "service_account", … }'
128
+ }
129
+ ),
130
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Hint, {}),
131
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Field.Error, {})
132
+ ]
133
+ }
134
+ ),
135
+ /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { justifyContent: "end", gap: 2, children: [
136
+ status.configured && /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { variant: "danger-light", onClick: remove, disabled: busy, children: "Quitar cuenta de servicio" }),
137
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Button, { onClick: save, disabled: !text.trim() || busy, loading: busy, children: "Guardar cuenta de servicio" })
138
+ ] })
139
+ ] }) });
140
+ };
141
+ const NOT_CONFIGURED = { configured: false, last4: null };
142
+ const VERTEX_OFF = { configured: false, projectId: null, clientEmail: null };
143
+ const serverMessage = (error, fallback) => error?.response?.data?.error?.message ?? fallback;
144
+ const initialStatus = {
145
+ googleGenAI: NOT_CONFIGURED,
146
+ linkedInAccessToken: NOT_CONFIGURED,
147
+ linkedInOrganizationId: NOT_CONFIGURED,
148
+ facebookClientToken: NOT_CONFIGURED,
149
+ facebookPageId: NOT_CONFIGURED
150
+ };
151
+ const SettingsContainer = () => {
152
+ const [status, setStatus] = react.useState(initialStatus);
153
+ const [vertex, setVertex] = react.useState(VERTEX_OFF);
154
+ const { formatMessage } = reactIntl.useIntl();
155
+ const { getSettings, setSettings, removeVertex } = useSettings();
156
+ const { toggleNotification } = admin.useNotification();
157
+ const fetchSettings = react.useCallback(async () => {
158
+ let isMounted = true;
159
+ try {
160
+ const { data } = await getSettings();
161
+ if (isMounted) {
162
+ setStatus(data);
163
+ setVertex(data.vertex ?? VERTEX_OFF);
164
+ }
165
+ } catch (error) {
166
+ toggleNotification({
167
+ type: "danger",
168
+ message: formatMessage({
169
+ id: `${index.PLUGIN_ID}.config.load.error`,
170
+ defaultMessage: "Error cargando configuración"
171
+ })
172
+ });
173
+ }
174
+ return () => {
175
+ isMounted = false;
176
+ };
177
+ }, [getSettings]);
178
+ const handleSubmit = react.useCallback(
179
+ async (values) => {
180
+ try {
181
+ await setSettings(values);
182
+ await fetchSettings();
183
+ toggleNotification({
184
+ type: "success",
185
+ message: formatMessage({
186
+ id: `${index.PLUGIN_ID}.config.load.error`,
187
+ defaultMessage: "Configuración guardada con éxito"
188
+ })
189
+ });
190
+ } catch (error) {
191
+ toggleNotification({
192
+ type: "danger",
193
+ message: formatMessage({
194
+ id: `${index.PLUGIN_ID}.config.load.error`,
195
+ defaultMessage: "Error guardando configuración"
196
+ })
197
+ });
198
+ }
199
+ },
200
+ [setSettings, fetchSettings]
201
+ );
202
+ const saveVertex = react.useCallback(
203
+ async (json) => {
204
+ try {
205
+ await setSettings({ vertexServiceAccount: json });
206
+ } catch (error) {
207
+ throw new Error(serverMessage(error, "No se pudo guardar la cuenta de servicio."));
208
+ }
209
+ await fetchSettings();
210
+ toggleNotification({ type: "success", message: "Cuenta de servicio de Vertex AI guardada." });
211
+ },
212
+ [setSettings, fetchSettings]
213
+ );
214
+ const deleteVertex = react.useCallback(async () => {
215
+ try {
216
+ await removeVertex();
217
+ await fetchSettings();
218
+ toggleNotification({ type: "success", message: "Cuenta de servicio quitada: el plugin usa la llave de Gemini." });
219
+ } catch {
220
+ toggleNotification({ type: "danger", message: "No se pudo quitar la cuenta de servicio." });
221
+ }
222
+ }, [removeVertex, fetchSettings]);
223
+ react.useEffect(() => {
224
+ fetchSettings();
225
+ }, []);
226
+ return /* @__PURE__ */ jsxRuntime.jsx(PluginProviders.PluginProviders, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Grid.Root, { padding: 6, gap: 3, children: [
227
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { children: /* @__PURE__ */ jsxRuntime.jsxs(designSystem.Flex, { direction: "column", alignItems: "start", children: [
228
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "alpha", children: formatMessage({ id: getTranslation.getTranslation("plugin.name") }) }),
229
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Typography, { variant: "pi", children: "Para uso exclusivo de InterWare de México" })
230
+ ] }) }),
231
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(VertexSettings, { status: vertex, onSave: saveVertex, onRemove: deleteVertex }) }),
232
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Grid.Item, { children: /* @__PURE__ */ jsxRuntime.jsx(Form, { status, handleSubmit }) })
233
+ ] }) });
234
+ };
235
+ const SettingsPage = () => {
236
+ const { formatMessage } = reactIntl.useIntl();
237
+ return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: /* @__PURE__ */ jsxRuntime.jsxs(admin.Page.Main, { children: [
238
+ /* @__PURE__ */ jsxRuntime.jsx(admin.Page.Title, { children: `${formatMessage({ id: getTranslation.getTranslation("plugin.name") })} | Settings` }),
239
+ /* @__PURE__ */ jsxRuntime.jsx(SettingsContainer, {})
240
+ ] }) });
241
+ };
242
+ exports.default = SettingsPage;
@@ -0,0 +1,242 @@
1
+ import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
+ import { useFetchClient, useNotification, Page } from "@strapi/strapi/admin";
3
+ import { useIntl } from "react-intl";
4
+ import { useCallback, useState, useEffect } from "react";
5
+ import { Box, Grid, Field, Flex, Button, Typography, Textarea } from "@strapi/design-system";
6
+ import { Formik } from "formik";
7
+ import { P as PluginProviders } from "./PluginProviders-DWMpcAIh.mjs";
8
+ import { P as PLUGIN_ID } from "./index-BKigRXm3.mjs";
9
+ import { g as getTranslation } from "./getTranslation-B6Bsu-uq.mjs";
10
+ const useSettings = () => {
11
+ const { get, post, del } = useFetchClient();
12
+ const getSettings = useCallback(
13
+ async (config) => {
14
+ return get("/strapi-content-generator-gemini/config", config);
15
+ },
16
+ [get]
17
+ );
18
+ const setSettings = useCallback(
19
+ async (data, config) => {
20
+ return post("/strapi-content-generator-gemini/config", data, config);
21
+ },
22
+ [post]
23
+ );
24
+ const removeVertex = useCallback(async () => del("/strapi-content-generator-gemini/config/vertex"), [del]);
25
+ return {
26
+ getSettings,
27
+ setSettings,
28
+ removeVertex
29
+ };
30
+ };
31
+ const FIELDS = [
32
+ { name: "googleGenAI", label: "API Key Gemini" },
33
+ { name: "linkedInAccessToken", label: "LinkedIn Access Token" },
34
+ { name: "linkedInOrganizationId", label: "LinkedIn Organization ID" },
35
+ { name: "facebookClientToken", label: "FACEBOOK CLIENT TOKEN" },
36
+ { name: "facebookPageId", label: "FACEBOOK PAGE ID" }
37
+ ];
38
+ const EMPTY = {
39
+ googleGenAI: "",
40
+ linkedInAccessToken: "",
41
+ linkedInOrganizationId: "",
42
+ facebookClientToken: "",
43
+ facebookPageId: ""
44
+ };
45
+ const hint = ({ configured, last4 }) => configured ? `Configurada ···${last4}` : "Sin configurar";
46
+ const filledOnly = (values) => Object.fromEntries(Object.entries(values).filter(([, value]) => value.trim() !== ""));
47
+ const Form = ({ status, handleSubmit }) => {
48
+ return /* @__PURE__ */ jsx(Box, { padding: 6, margin: 6, background: "neutral0", width: "100%", children: /* @__PURE__ */ jsx(
49
+ Formik,
50
+ {
51
+ initialValues: EMPTY,
52
+ onSubmit: async (values, { resetForm }) => {
53
+ await handleSubmit(filledOnly(values));
54
+ resetForm();
55
+ },
56
+ children: ({ values, handleChange, handleBlur, handleSubmit: submit, isSubmitting }) => {
57
+ const hasChanges = Object.keys(filledOnly(values)).length > 0;
58
+ return /* @__PURE__ */ jsx("form", { onSubmit: submit, children: /* @__PURE__ */ jsxs(Grid.Root, { gap: 4, children: [
59
+ FIELDS.map(({ name, label }) => /* @__PURE__ */ jsx(Grid.Item, { children: /* @__PURE__ */ jsxs(Field.Root, { id: name, width: "100%", hint: hint(status[name]), children: [
60
+ /* @__PURE__ */ jsx(Field.Label, { children: label }),
61
+ /* @__PURE__ */ jsx(
62
+ Field.Input,
63
+ {
64
+ name,
65
+ value: values[name],
66
+ onChange: handleChange,
67
+ onBlur: handleBlur,
68
+ type: "password",
69
+ autoComplete: "off",
70
+ placeholder: "Escribe un valor nuevo para reemplazarla"
71
+ }
72
+ ),
73
+ /* @__PURE__ */ jsx(Field.Hint, {})
74
+ ] }) }, name)),
75
+ /* @__PURE__ */ jsx(Grid.Item, { children: /* @__PURE__ */ jsx(Flex, { justifyContent: "end", alignItems: "end", width: "100%", children: /* @__PURE__ */ jsx(Button, { type: "submit", disabled: !hasChanges || isSubmitting, children: "Guardar" }) }) })
76
+ ] }) });
77
+ }
78
+ }
79
+ ) });
80
+ };
81
+ const statusLine = ({ configured, projectId, clientEmail }) => configured ? `Configurada · proyecto ${projectId} · ${clientEmail}` : "Sin configurar: el plugin usa la llave de Gemini.";
82
+ const VertexSettings = ({ status, onSave, onRemove }) => {
83
+ const [text, setText] = useState("");
84
+ const [error, setError] = useState(null);
85
+ const [busy, setBusy] = useState(false);
86
+ const save = async () => {
87
+ setBusy(true);
88
+ setError(null);
89
+ try {
90
+ await onSave(text);
91
+ setText("");
92
+ } catch (err) {
93
+ setError(err instanceof Error ? err.message : "No se pudo guardar la cuenta de servicio.");
94
+ } finally {
95
+ setBusy(false);
96
+ }
97
+ };
98
+ const remove = async () => {
99
+ setBusy(true);
100
+ try {
101
+ await onRemove();
102
+ } finally {
103
+ setBusy(false);
104
+ }
105
+ };
106
+ return /* @__PURE__ */ jsx(Box, { padding: 6, margin: 6, background: "neutral0", width: "100%", children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "stretch", gap: 4, children: [
107
+ /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "start", gap: 1, children: [
108
+ /* @__PURE__ */ jsx(Typography, { variant: "delta", tag: "h2", children: "Vertex AI" }),
109
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", textColor: "neutral600", children: statusLine(status) })
110
+ ] }),
111
+ /* @__PURE__ */ jsxs(
112
+ Field.Root,
113
+ {
114
+ id: "vertexServiceAccount",
115
+ error: error ?? void 0,
116
+ hint: "Pega el contenido completo del archivo .json de la cuenta de servicio. La llave privada no vuelve a mostrarse.",
117
+ children: [
118
+ /* @__PURE__ */ jsx(Field.Label, { children: "JSON de la cuenta de servicio" }),
119
+ /* @__PURE__ */ jsx(
120
+ Textarea,
121
+ {
122
+ name: "vertexServiceAccount",
123
+ value: text,
124
+ onChange: (e) => setText(e.target.value),
125
+ placeholder: '{ "type": "service_account", … }'
126
+ }
127
+ ),
128
+ /* @__PURE__ */ jsx(Field.Hint, {}),
129
+ /* @__PURE__ */ jsx(Field.Error, {})
130
+ ]
131
+ }
132
+ ),
133
+ /* @__PURE__ */ jsxs(Flex, { justifyContent: "end", gap: 2, children: [
134
+ status.configured && /* @__PURE__ */ jsx(Button, { variant: "danger-light", onClick: remove, disabled: busy, children: "Quitar cuenta de servicio" }),
135
+ /* @__PURE__ */ jsx(Button, { onClick: save, disabled: !text.trim() || busy, loading: busy, children: "Guardar cuenta de servicio" })
136
+ ] })
137
+ ] }) });
138
+ };
139
+ const NOT_CONFIGURED = { configured: false, last4: null };
140
+ const VERTEX_OFF = { configured: false, projectId: null, clientEmail: null };
141
+ const serverMessage = (error, fallback) => error?.response?.data?.error?.message ?? fallback;
142
+ const initialStatus = {
143
+ googleGenAI: NOT_CONFIGURED,
144
+ linkedInAccessToken: NOT_CONFIGURED,
145
+ linkedInOrganizationId: NOT_CONFIGURED,
146
+ facebookClientToken: NOT_CONFIGURED,
147
+ facebookPageId: NOT_CONFIGURED
148
+ };
149
+ const SettingsContainer = () => {
150
+ const [status, setStatus] = useState(initialStatus);
151
+ const [vertex, setVertex] = useState(VERTEX_OFF);
152
+ const { formatMessage } = useIntl();
153
+ const { getSettings, setSettings, removeVertex } = useSettings();
154
+ const { toggleNotification } = useNotification();
155
+ const fetchSettings = useCallback(async () => {
156
+ let isMounted = true;
157
+ try {
158
+ const { data } = await getSettings();
159
+ if (isMounted) {
160
+ setStatus(data);
161
+ setVertex(data.vertex ?? VERTEX_OFF);
162
+ }
163
+ } catch (error) {
164
+ toggleNotification({
165
+ type: "danger",
166
+ message: formatMessage({
167
+ id: `${PLUGIN_ID}.config.load.error`,
168
+ defaultMessage: "Error cargando configuración"
169
+ })
170
+ });
171
+ }
172
+ return () => {
173
+ isMounted = false;
174
+ };
175
+ }, [getSettings]);
176
+ const handleSubmit = useCallback(
177
+ async (values) => {
178
+ try {
179
+ await setSettings(values);
180
+ await fetchSettings();
181
+ toggleNotification({
182
+ type: "success",
183
+ message: formatMessage({
184
+ id: `${PLUGIN_ID}.config.load.error`,
185
+ defaultMessage: "Configuración guardada con éxito"
186
+ })
187
+ });
188
+ } catch (error) {
189
+ toggleNotification({
190
+ type: "danger",
191
+ message: formatMessage({
192
+ id: `${PLUGIN_ID}.config.load.error`,
193
+ defaultMessage: "Error guardando configuración"
194
+ })
195
+ });
196
+ }
197
+ },
198
+ [setSettings, fetchSettings]
199
+ );
200
+ const saveVertex = useCallback(
201
+ async (json) => {
202
+ try {
203
+ await setSettings({ vertexServiceAccount: json });
204
+ } catch (error) {
205
+ throw new Error(serverMessage(error, "No se pudo guardar la cuenta de servicio."));
206
+ }
207
+ await fetchSettings();
208
+ toggleNotification({ type: "success", message: "Cuenta de servicio de Vertex AI guardada." });
209
+ },
210
+ [setSettings, fetchSettings]
211
+ );
212
+ const deleteVertex = useCallback(async () => {
213
+ try {
214
+ await removeVertex();
215
+ await fetchSettings();
216
+ toggleNotification({ type: "success", message: "Cuenta de servicio quitada: el plugin usa la llave de Gemini." });
217
+ } catch {
218
+ toggleNotification({ type: "danger", message: "No se pudo quitar la cuenta de servicio." });
219
+ }
220
+ }, [removeVertex, fetchSettings]);
221
+ useEffect(() => {
222
+ fetchSettings();
223
+ }, []);
224
+ return /* @__PURE__ */ jsx(PluginProviders, { children: /* @__PURE__ */ jsxs(Grid.Root, { padding: 6, gap: 3, children: [
225
+ /* @__PURE__ */ jsx(Grid.Item, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "start", children: [
226
+ /* @__PURE__ */ jsx(Typography, { variant: "alpha", children: formatMessage({ id: getTranslation("plugin.name") }) }),
227
+ /* @__PURE__ */ jsx(Typography, { variant: "pi", children: "Para uso exclusivo de InterWare de México" })
228
+ ] }) }),
229
+ /* @__PURE__ */ jsx(Grid.Item, { children: /* @__PURE__ */ jsx(VertexSettings, { status: vertex, onSave: saveVertex, onRemove: deleteVertex }) }),
230
+ /* @__PURE__ */ jsx(Grid.Item, { children: /* @__PURE__ */ jsx(Form, { status, handleSubmit }) })
231
+ ] }) });
232
+ };
233
+ const SettingsPage = () => {
234
+ const { formatMessage } = useIntl();
235
+ return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(Page.Main, { children: [
236
+ /* @__PURE__ */ jsx(Page.Title, { children: `${formatMessage({ id: getTranslation("plugin.name") })} | Settings` }),
237
+ /* @__PURE__ */ jsx(SettingsContainer, {})
238
+ ] }) });
239
+ };
240
+ export {
241
+ SettingsPage as default
242
+ };
@@ -0,0 +1,18 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
3
+ const jsxRuntime = require("react/jsx-runtime");
4
+ const admin = require("@strapi/strapi/admin");
5
+ const reactRouterDom = require("react-router-dom");
6
+ const PluginProviders = require("./PluginProviders-D79TeGSE.js");
7
+ const index = require("./index-BKhe-Jyx.js");
8
+ const designSystem = require("@strapi/design-system");
9
+ const ImageStudioTabs = require("./ImageStudioTabs-DtusqpQO.js");
10
+ const ImageStudio = () => /* @__PURE__ */ jsxRuntime.jsxs(admin.Page.Main, { children: [
11
+ /* @__PURE__ */ jsxRuntime.jsx(admin.Page.Title, { children: "Estudio de imágenes" }),
12
+ /* @__PURE__ */ jsxRuntime.jsx(designSystem.Box, { style: { height: "100vh" }, children: /* @__PURE__ */ jsxRuntime.jsx(ImageStudioTabs.ImageStudioTabs, {}) })
13
+ ] });
14
+ const StudioApp = () => /* @__PURE__ */ jsxRuntime.jsx(admin.Page.Protect, { permissions: [...index.pluginPermissions.access], children: /* @__PURE__ */ jsxRuntime.jsx(PluginProviders.PluginProviders, { children: /* @__PURE__ */ jsxRuntime.jsxs(reactRouterDom.Routes, { children: [
15
+ /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Route, { index: true, element: /* @__PURE__ */ jsxRuntime.jsx(ImageStudio, {}) }),
16
+ /* @__PURE__ */ jsxRuntime.jsx(reactRouterDom.Route, { path: "*", element: /* @__PURE__ */ jsxRuntime.jsx(admin.Page.Error, {}) })
17
+ ] }) }) });
18
+ exports.StudioApp = StudioApp;
@@ -0,0 +1,18 @@
1
+ import { jsxs, jsx } from "react/jsx-runtime";
2
+ import { Page } from "@strapi/strapi/admin";
3
+ import { Routes, Route } from "react-router-dom";
4
+ import { P as PluginProviders } from "./PluginProviders-DWMpcAIh.mjs";
5
+ import { p as pluginPermissions } from "./index-BKigRXm3.mjs";
6
+ import { Box } from "@strapi/design-system";
7
+ import { I as ImageStudioTabs } from "./ImageStudioTabs-BLAH3KYv.mjs";
8
+ const ImageStudio = () => /* @__PURE__ */ jsxs(Page.Main, { children: [
9
+ /* @__PURE__ */ jsx(Page.Title, { children: "Estudio de imágenes" }),
10
+ /* @__PURE__ */ jsx(Box, { style: { height: "100vh" }, children: /* @__PURE__ */ jsx(ImageStudioTabs, {}) })
11
+ ] });
12
+ const StudioApp = () => /* @__PURE__ */ jsx(Page.Protect, { permissions: [...pluginPermissions.access], children: /* @__PURE__ */ jsx(PluginProviders, { children: /* @__PURE__ */ jsxs(Routes, { children: [
13
+ /* @__PURE__ */ jsx(Route, { index: true, element: /* @__PURE__ */ jsx(ImageStudio, {}) }),
14
+ /* @__PURE__ */ jsx(Route, { path: "*", element: /* @__PURE__ */ jsx(Page.Error, {}) })
15
+ ] }) }) });
16
+ export {
17
+ StudioApp
18
+ };
@@ -1,4 +1,4 @@
1
- import { P as PLUGIN_ID } from "./index-Dyq8dxMX.mjs";
1
+ import { P as PLUGIN_ID } from "./index-BKigRXm3.mjs";
2
2
  const getTranslation = (id) => `${PLUGIN_ID}.${id}`;
3
3
  export {
4
4
  getTranslation as g
@@ -1,4 +1,4 @@
1
1
  "use strict";
2
- const index = require("./index-DGPqyrzz.js");
2
+ const index = require("./index-BKhe-Jyx.js");
3
3
  const getTranslation = (id) => `${index.PLUGIN_ID}.${id}`;
4
4
  exports.getTranslation = getTranslation;