@interware/content-generator 0.6.1 → 0.7.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 (58) hide show
  1. package/dist/_chunks/App-Cwr5ra5m.js +1380 -0
  2. package/dist/_chunks/App-h4_txTsI.mjs +1362 -0
  3. package/dist/_chunks/{ImageStudioTabs-BLAH3KYv.mjs → ImageStudioTabs-B-mOwDfY.mjs} +687 -682
  4. package/dist/_chunks/{ImageStudioTabs-DtusqpQO.js → ImageStudioTabs-CG4KTn1S.js} +683 -678
  5. package/dist/_chunks/{Settings-o2GngLaW.mjs → Settings-BT-EqvXs.mjs} +2 -2
  6. package/dist/_chunks/{Settings-BQXxV3LO.js → Settings-D4NGBTk1.js} +4 -4
  7. package/dist/_chunks/{StudioApp-BaySMwrk.js → StudioApp-_ViSAwCm.js} +2 -2
  8. package/dist/_chunks/{StudioApp-C_znlQRo.mjs → StudioApp-xaEy-uIk.mjs} +2 -2
  9. package/dist/_chunks/{index-BKigRXm3.mjs → index-D67xWUPz.mjs} +3 -28
  10. package/dist/_chunks/{index-BKhe-Jyx.js → index-NA9OuMGs.js} +3 -28
  11. package/dist/admin/index.js +1 -1
  12. package/dist/admin/index.mjs +1 -1
  13. package/dist/admin/src/features/articles/ArticlePage.d.ts +5 -0
  14. package/dist/admin/src/features/articles/ArticlesPage.d.ts +7 -0
  15. package/dist/admin/src/features/articles/NewArticlePage.d.ts +6 -0
  16. package/dist/admin/src/features/articles/SharePreview.d.ts +19 -0
  17. package/dist/admin/src/features/articles/articlesApi.d.ts +94 -0
  18. package/dist/admin/src/features/articles/model.d.ts +24 -0
  19. package/dist/admin/src/features/articles/useArticlesApi.d.ts +19 -0
  20. package/dist/admin/src/features/library/LibraryImagePicker.d.ts +6 -1
  21. package/dist/admin/src/lib/postText.d.ts +25 -0
  22. package/dist/server/index.js +514 -320
  23. package/dist/server/index.mjs +514 -320
  24. package/dist/server/src/articles/generation.d.ts +135 -0
  25. package/dist/server/src/articles/schedule.d.ts +12 -0
  26. package/dist/server/src/articles/sources.d.ts +12 -0
  27. package/dist/server/src/bootstrap.d.ts +2 -0
  28. package/dist/server/src/controllers/articles.d.ts +30 -0
  29. package/dist/server/src/controllers/controller.d.ts +0 -4
  30. package/dist/server/src/controllers/index.d.ts +92 -4
  31. package/dist/server/src/index.d.ts +122 -67
  32. package/dist/server/src/services/articles.d.ts +126 -0
  33. package/dist/server/src/services/image-studio.d.ts +0 -10
  34. package/dist/server/src/services/index.d.ts +30 -63
  35. package/dist/server/src/services/service.d.ts +1 -62
  36. package/package.json +1 -1
  37. package/dist/_chunks/App-CJxSC8yt.js +0 -1105
  38. package/dist/_chunks/App-qbgUXlOZ.mjs +0 -1087
  39. package/dist/_chunks/getTranslation-B6Bsu-uq.mjs +0 -5
  40. package/dist/_chunks/getTranslation-BRVMWSf8.js +0 -4
  41. package/dist/admin/src/components/commons/dialog/index.d.ts +0 -12
  42. package/dist/admin/src/components/commons/generate-image-dialog/index.d.ts +0 -5
  43. package/dist/admin/src/components/generate-content/Form.d.ts +0 -15
  44. package/dist/admin/src/components/home/table.d.ts +0 -13
  45. package/dist/admin/src/components/index.d.ts +0 -12
  46. package/dist/admin/src/containers/generate-content/index.d.ts +0 -2
  47. package/dist/admin/src/containers/home/index.d.ts +0 -2
  48. package/dist/admin/src/hooks/useDialog.d.ts +0 -11
  49. package/dist/admin/src/lib/use-cases/articles/index.d.ts +0 -16
  50. package/dist/admin/src/lib/use-cases/categories/index.d.ts +0 -16
  51. package/dist/admin/src/lib/use-cases/facebook/index.d.ts +0 -5
  52. package/dist/admin/src/lib/use-cases/generate-content/index.d.ts +0 -6
  53. package/dist/admin/src/lib/use-cases/linkedin/index.d.ts +0 -5
  54. package/dist/admin/src/lib/use-cases/users/index.d.ts +0 -16
  55. package/dist/admin/src/pages/GenerateContent.d.ts +0 -2
  56. package/dist/admin/src/pages/HomePage.d.ts +0 -2
  57. package/dist/admin/src/reducers/dialog/index.d.ts +0 -6
  58. package/dist/admin/src/types/reducers.d.ts +0 -4
@@ -1,1087 +0,0 @@
1
- import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
- import { useFetchClient, useNotification, Page, useRBAC } from "@strapi/strapi/admin";
3
- import { useNavigate, Routes, Route } from "react-router-dom";
4
- import { P as PluginProviders } from "./PluginProviders-DWMpcAIh.mjs";
5
- import { useIntl } from "react-intl";
6
- import { useCallback, memo, useMemo, useState, useRef, useEffect } from "react";
7
- import { Box, Table, Thead, Tr, Th, Typography, Flex, Tbody, Td, Button, LinkButton, Dialog, Grid, Field, Textarea, TextInput, Combobox, ComboboxOption, IconButton } from "@strapi/design-system";
8
- import { useDispatch, useSelector } from "react-redux";
9
- import { c as closeDialog, o as openDialog, P as PLUGIN_ID, p as pluginPermissions } from "./index-BKigRXm3.mjs";
10
- import { Play, ExternalLink, Image, Trash, PlusCircle } from "@strapi/icons";
11
- import { g as getTranslation } from "./getTranslation-B6Bsu-uq.mjs";
12
- import { useFormik } from "formik";
13
- import * as Yup from "yup";
14
- import { L as LEGACY_ROUTES, S as StudioRedirect, l as legacyRedirect } from "./ImageStudioTabs-BLAH3KYv.mjs";
15
- const useDialog = (id) => {
16
- const dispatch = useDispatch();
17
- const state = useSelector((state2) => state2.content_generator_commonDialog.open[id] ?? false);
18
- return {
19
- open: state,
20
- openDialog: () => dispatch(openDialog(id)),
21
- closeDialog: () => dispatch(closeDialog(id))
22
- };
23
- };
24
- const useArticles = () => {
25
- const { get } = useFetchClient();
26
- const getArticles = useCallback(
27
- async (config) => {
28
- return get("/strapi-content-generator-gemini/posts", config);
29
- },
30
- [get]
31
- );
32
- return {
33
- getArticles
34
- };
35
- };
36
- const REQUEST_TIMEOUT = 12e4;
37
- const useGenerateContent = () => {
38
- const { post } = useFetchClient();
39
- const generateContent = useCallback(
40
- async (data, config) => {
41
- const controller = new AbortController();
42
- const timeoutId = setTimeout(() => {
43
- controller.abort();
44
- }, REQUEST_TIMEOUT);
45
- try {
46
- return await post(
47
- "/strapi-content-generator-gemini/generate-article",
48
- data,
49
- {
50
- ...config,
51
- signal: controller.signal
52
- }
53
- );
54
- } finally {
55
- clearTimeout(timeoutId);
56
- }
57
- },
58
- [post]
59
- );
60
- const generateImage = useCallback(
61
- async (data, config) => {
62
- const controller = new AbortController();
63
- const timeoutId = setTimeout(() => {
64
- controller.abort();
65
- }, REQUEST_TIMEOUT);
66
- try {
67
- return await post(
68
- "/strapi-content-generator-gemini/generate-image",
69
- data,
70
- {
71
- ...config,
72
- signal: controller.signal
73
- }
74
- );
75
- } finally {
76
- clearTimeout(timeoutId);
77
- }
78
- },
79
- [post]
80
- );
81
- return {
82
- generateContent,
83
- generateImage
84
- };
85
- };
86
- const usePublishLinkedIn = () => {
87
- const { post } = useFetchClient();
88
- const publishToLinkedIn = useCallback(
89
- async (data, config) => {
90
- return post("/strapi-content-generator-gemini/publish-linkedin", data, config);
91
- },
92
- [post]
93
- );
94
- return {
95
- publishToLinkedIn
96
- };
97
- };
98
- const usePublishFacebook = () => {
99
- const { post } = useFetchClient();
100
- const publishToFacebook = useCallback(
101
- async (data, config) => {
102
- return post("/strapi-content-generator-gemini/publish-facebook", data, config);
103
- },
104
- [post]
105
- );
106
- return {
107
- publishToFacebook
108
- };
109
- };
110
- const PublishingTableComponent = ({
111
- posts,
112
- currentPost,
113
- loadingImage,
114
- loadingPublishLinkedIn,
115
- loadingPublishingToFacebook,
116
- onClickAction
117
- }) => {
118
- const rows = useMemo(() => {
119
- const opciones = {
120
- day: "2-digit",
121
- month: "long",
122
- year: "numeric"
123
- };
124
- return posts.map((post) => {
125
- const fecha = post.fecha_publicacion ? new Date(post.fecha_publicacion).toLocaleDateString("es-ES", opciones) : "No definida";
126
- return {
127
- id: post.documentId,
128
- fecha,
129
- titulo: post.titulo && post.titulo.length > 30 ? `${post.titulo.slice(0, 30)}…` : post.titulo,
130
- linkedInURL: post.linkedInPostId ? `https://www.linkedin.com/feed/update/${post.linkedInPostId}` : "",
131
- facebookURL: post.facebookPostId ? `https://www.facebook.com/${post.facebookPostId}` : "",
132
- hasImage: Boolean(post.image)
133
- };
134
- });
135
- }, [posts]);
136
- return /* @__PURE__ */ jsx(Box, { padding: 6, width: "100%", children: /* @__PURE__ */ jsxs(Table, { colCount: 7, rowCount: rows.length + 1, children: [
137
- /* @__PURE__ */ jsx(Thead, { children: /* @__PURE__ */ jsxs(Tr, { children: [
138
- /* @__PURE__ */ jsx(Th, { children: /* @__PURE__ */ jsx(Typography, { variant: "sigma", textColor: "neutral600", children: "Fecha de publicación" }) }),
139
- /* @__PURE__ */ jsx(Th, { children: /* @__PURE__ */ jsx(Typography, { variant: "sigma", textColor: "neutral600", children: "Blog Title" }) }),
140
- /* @__PURE__ */ jsx(Th, { children: /* @__PURE__ */ jsxs(Flex, { gap: 1, alignItems: "center", justifyContent: "center", children: [
141
- /* @__PURE__ */ jsx("i", { className: "fa-brands fa-linkedin" }),
142
- /* @__PURE__ */ jsx(Typography, { variant: "sigma", textColor: "neutral600", children: "LinkedIn" })
143
- ] }) }),
144
- /* @__PURE__ */ jsx(Th, { children: /* @__PURE__ */ jsxs(Flex, { gap: 1, alignItems: "center", justifyContent: "center", children: [
145
- /* @__PURE__ */ jsx("i", { className: "fa-brands fa-facebook" }),
146
- /* @__PURE__ */ jsx(Typography, { variant: "sigma", textColor: "neutral600", children: "Facebook" })
147
- ] }) }),
148
- /* @__PURE__ */ jsx(Th, {}),
149
- /* @__PURE__ */ jsx(Th, {})
150
- ] }) }),
151
- /* @__PURE__ */ jsx(Tbody, { children: rows.map((row) => {
152
- const buttonLoadingImage = (loadingImage && currentPost.current) === row.id;
153
- const buttonLoadingPublishingLinkedIn = (loadingPublishLinkedIn && currentPost.current) === row.id;
154
- const buttonLoadingPublishingFacebook = (loadingPublishingToFacebook && currentPost.current) === row.id;
155
- return /* @__PURE__ */ jsxs(Tr, { children: [
156
- /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { textColor: "neutral800", children: row.fecha }) }),
157
- /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(Typography, { textColor: "neutral800", children: row.titulo }) }),
158
- /* @__PURE__ */ jsx(Td, { children: !row.linkedInURL ? /* @__PURE__ */ jsx(
159
- Button,
160
- {
161
- disabled: row.linkedInURL,
162
- onClick: () => onClickAction(row.id, "publish-to-linked-in-dialog"),
163
- loading: buttonLoadingPublishingLinkedIn,
164
- startIcon: /* @__PURE__ */ jsx(Play, {}),
165
- children: /* @__PURE__ */ jsx(Typography, { variant: "pi", children: buttonLoadingPublishingLinkedIn ? "publicando" : "publicar" })
166
- }
167
- ) : /* @__PURE__ */ jsx(
168
- LinkButton,
169
- {
170
- variant: "success-light",
171
- href: row.linkedInURL,
172
- isExternal: true,
173
- startIcon: /* @__PURE__ */ jsx(ExternalLink, {}),
174
- children: "visitar"
175
- }
176
- ) }),
177
- /* @__PURE__ */ jsx(Td, { children: !row.facebookURL ? /* @__PURE__ */ jsx(
178
- Button,
179
- {
180
- disabled: row.facebookURL,
181
- onClick: () => onClickAction(row.id, "publish-to-facebook-dialog"),
182
- loading: buttonLoadingPublishingFacebook,
183
- startIcon: /* @__PURE__ */ jsx(Play, {}),
184
- children: /* @__PURE__ */ jsx(Typography, { variant: "pi", children: buttonLoadingPublishingFacebook ? "publicando" : "publicar" })
185
- }
186
- ) : /* @__PURE__ */ jsx(
187
- LinkButton,
188
- {
189
- variant: "success-light",
190
- href: row.facebookURL,
191
- isExternal: true,
192
- startIcon: /* @__PURE__ */ jsx(ExternalLink, {}),
193
- children: "visitar"
194
- }
195
- ) }),
196
- /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(
197
- Button,
198
- {
199
- disabled: row.hasImage,
200
- onClick: () => onClickAction(row.id, "generate-image-dialog"),
201
- loading: buttonLoadingImage,
202
- startIcon: /* @__PURE__ */ jsx(Image, {}),
203
- children: /* @__PURE__ */ jsx(Typography, { variant: "pi", children: buttonLoadingImage ? "generando" : "generar" })
204
- }
205
- ) }),
206
- /* @__PURE__ */ jsx(Td, { children: /* @__PURE__ */ jsx(
207
- LinkButton,
208
- {
209
- href: `/admin/content-manager/collection-types/api::articulo.articulo/${row.id}`,
210
- children: /* @__PURE__ */ jsx(Typography, { variant: "pi", children: "ver" })
211
- }
212
- ) })
213
- ] }, row.id);
214
- }) })
215
- ] }) });
216
- };
217
- const PublishingTable = memo(PublishingTableComponent);
218
- const DialogCommon = ({
219
- id,
220
- title = "Confirmación",
221
- children,
222
- cancelText = "Cancelar",
223
- confirmText = "Confirmar",
224
- onCancelAction,
225
- onConfirmAction
226
- }) => {
227
- const { open } = useDialog(id);
228
- return /* @__PURE__ */ jsx(Dialog.Root, { open, children: /* @__PURE__ */ jsxs(Dialog.Content, { children: [
229
- /* @__PURE__ */ jsx(Dialog.Header, { children: title }),
230
- /* @__PURE__ */ jsx(Dialog.Body, { children }),
231
- /* @__PURE__ */ jsxs(Dialog.Footer, { children: [
232
- /* @__PURE__ */ jsx(Dialog.Cancel, { children: /* @__PURE__ */ jsx(Button, { fullWidth: true, variant: "tertiary", onClick: onCancelAction, children: cancelText }) }),
233
- /* @__PURE__ */ jsx(Dialog.Action, { children: /* @__PURE__ */ jsx(Button, { fullWidth: true, variant: "danger", onClick: onConfirmAction, children: confirmText }) })
234
- ] })
235
- ] }) });
236
- };
237
- const GenerateImageDialog = ({ onCancelAction, onConfirmAction }) => {
238
- const [imageInstructions, setImageInstructions] = useState("");
239
- return /* @__PURE__ */ jsx(
240
- DialogCommon,
241
- {
242
- id: "generate-image-dialog",
243
- title: "Generar imágen con Gemini",
244
- cancelText: "Cancelar",
245
- confirmText: "Confirmar",
246
- onCancelAction,
247
- onConfirmAction: () => {
248
- onConfirmAction(imageInstructions);
249
- },
250
- children: /* @__PURE__ */ jsxs(Grid.Root, { gap: 3, children: [
251
- /* @__PURE__ */ jsx(Grid.Item, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "center", justifyContent: "center", width: "100%", children: [
252
- /* @__PURE__ */ jsx(Typography, { variant: "omega", children: "¿Deseas generar la imágen para el artículo ahora?" }),
253
- /* @__PURE__ */ jsx(Typography, { variant: "pi", children: "No te preocupes, también puedes hacerlo más adelante." })
254
- ] }) }),
255
- /* @__PURE__ */ jsx(Grid.Item, { m: 12, children: /* @__PURE__ */ jsxs(
256
- Field.Root,
257
- {
258
- id: "image-instructions",
259
- width: "100%",
260
- children: [
261
- /* @__PURE__ */ jsx(Field.Label, { children: "Instrucciones adicionales" }),
262
- /* @__PURE__ */ jsx(
263
- Textarea,
264
- {
265
- name: "image-instructions",
266
- value: imageInstructions,
267
- placeholder: "Instrucciones adicionales para generar la imágen",
268
- onChange: (e) => {
269
- const { value } = e.target;
270
- setImageInstructions(value);
271
- },
272
- resizable: false,
273
- rows: 3
274
- }
275
- )
276
- ]
277
- }
278
- ) })
279
- ] })
280
- }
281
- );
282
- };
283
- const HomeContainer = () => {
284
- const [posts, setPosts] = useState([]);
285
- const [loadingImage, setIsLoadingImage] = useState(false);
286
- const [loadingPublishingToLinkedIn, setIsLoadingPublishingToLinkedIn] = useState(false);
287
- const [loadingPublishingToFacebook, setIsLoadingPublishingToFacebook] = useState(false);
288
- const currentPostRef = useRef("");
289
- const { formatMessage } = useIntl();
290
- const { openDialog: openImageGenerateDialog, closeDialog: closeImageGenerateDialog } = useDialog("generate-image-dialog");
291
- const { openDialog: openPublishToLinkedInDialog, closeDialog: closePublishToLinkedInDialog } = useDialog("publish-to-linked-in-dialog");
292
- const { openDialog: openPublishToFacebookDialog, closeDialog: closePublishToFacebookDialog } = useDialog("publish-to-facebook-dialog");
293
- const { getArticles } = useArticles();
294
- const { generateImage } = useGenerateContent();
295
- const { publishToLinkedIn } = usePublishLinkedIn();
296
- const { publishToFacebook } = usePublishFacebook();
297
- const { toggleNotification } = useNotification();
298
- const fetchPosts = useCallback(async () => {
299
- let isMounted = true;
300
- try {
301
- const { data } = await getArticles({
302
- params: {
303
- populate: {
304
- image: { fields: ["url", "caption", "alternativeText"] },
305
- autor: { fields: ["nombre", "apellidos"] }
306
- },
307
- sort: ["createdAt:desc"]
308
- }
309
- });
310
- if (isMounted) {
311
- setPosts(data);
312
- }
313
- } catch (error) {
314
- console.error("Error fetching posts:", error);
315
- }
316
- return () => {
317
- isMounted = false;
318
- };
319
- }, [getArticles]);
320
- useEffect(() => {
321
- fetchPosts();
322
- }, [fetchPosts]);
323
- const onConfirmGenerateImage = useCallback(
324
- async (imageInstructions) => {
325
- closeImageGenerateDialog();
326
- setIsLoadingImage(true);
327
- try {
328
- await generateImage({
329
- articleId: currentPostRef.current,
330
- imageInstructions
331
- });
332
- fetchPosts();
333
- toggleNotification({
334
- type: "success",
335
- message: formatMessage({
336
- id: `${PLUGIN_ID}.config.load.error`,
337
- defaultMessage: "Imagen generada con éxito"
338
- })
339
- });
340
- } catch (err) {
341
- toggleNotification({
342
- type: "danger",
343
- message: formatMessage({
344
- id: `${PLUGIN_ID}.config.load.error`,
345
- defaultMessage: "Ocurrió un error al generar la imagen"
346
- })
347
- });
348
- } finally {
349
- setIsLoadingImage(false);
350
- }
351
- },
352
- [generateImage, closeImageGenerateDialog, setIsLoadingImage]
353
- );
354
- const onConfirmPublish = useCallback(
355
- async (type) => {
356
- const isLinkedIn = type === "linkedin";
357
- const isFacebook = type === "facebook";
358
- if (isLinkedIn) {
359
- closePublishToLinkedInDialog();
360
- setIsLoadingPublishingToLinkedIn(true);
361
- }
362
- if (isFacebook) {
363
- closePublishToFacebookDialog();
364
- setIsLoadingPublishingToFacebook(true);
365
- }
366
- try {
367
- switch (type) {
368
- case "linkedin":
369
- await publishToLinkedIn({ articleId: currentPostRef.current });
370
- break;
371
- case "facebook":
372
- await publishToFacebook({ articleId: currentPostRef.current });
373
- break;
374
- default:
375
- return;
376
- }
377
- fetchPosts();
378
- toggleNotification({
379
- type: "success",
380
- message: formatMessage({
381
- id: `${PLUGIN_ID}.config.publish.success.${type}`,
382
- defaultMessage: type === "linkedin" ? "Artículo publicado en LinkedIn con éxito" : "Artículo publicado en Facebook con éxito"
383
- })
384
- });
385
- } catch (err) {
386
- toggleNotification({
387
- type: "danger",
388
- message: formatMessage({
389
- id: `${PLUGIN_ID}.config.publish.error.${type}`,
390
- defaultMessage: type === "linkedin" ? "Ocurrió un error al publicar el artículo en LinkedIn" : "Ocurrió un error al publicar el artículo en Facebook"
391
- })
392
- });
393
- } finally {
394
- if (isLinkedIn) {
395
- setIsLoadingPublishingToLinkedIn(false);
396
- }
397
- if (isFacebook) {
398
- setIsLoadingPublishingToFacebook(false);
399
- }
400
- }
401
- },
402
- [
403
- publishToLinkedIn,
404
- publishToFacebook,
405
- closePublishToLinkedInDialog,
406
- closePublishToFacebookDialog,
407
- setIsLoadingPublishingToLinkedIn,
408
- setIsLoadingPublishingToFacebook,
409
- fetchPosts,
410
- toggleNotification,
411
- formatMessage
412
- ]
413
- );
414
- const onCancel = useCallback((dialogId) => {
415
- currentPostRef.current = "";
416
- switch (dialogId) {
417
- case "generate-image-dialog":
418
- closeImageGenerateDialog();
419
- break;
420
- case "publish-to-linked-in-dialog":
421
- closePublishToLinkedInDialog();
422
- break;
423
- case "publish-to-facebook-dialog":
424
- closePublishToFacebookDialog();
425
- break;
426
- default:
427
- return;
428
- }
429
- }, [closeImageGenerateDialog, closePublishToLinkedInDialog, closePublishToFacebookDialog]);
430
- const onClickAction = useCallback(
431
- (postId, dialogId) => {
432
- currentPostRef.current = postId;
433
- switch (dialogId) {
434
- case "generate-image-dialog":
435
- openImageGenerateDialog();
436
- break;
437
- case "publish-to-linked-in-dialog":
438
- openPublishToLinkedInDialog();
439
- break;
440
- case "publish-to-facebook-dialog":
441
- openPublishToFacebookDialog();
442
- break;
443
- }
444
- },
445
- [openImageGenerateDialog, openPublishToLinkedInDialog, openPublishToFacebookDialog]
446
- );
447
- return /* @__PURE__ */ jsxs(Fragment, { children: [
448
- /* @__PURE__ */ jsx(
449
- DialogCommon,
450
- {
451
- id: "publish-to-linked-in-dialog",
452
- title: "Publicar en LinkedIn",
453
- confirmText: "Publicar",
454
- onCancelAction: () => onCancel("publish-to-linked-in-dialog"),
455
- onConfirmAction: () => onConfirmPublish("linkedin"),
456
- children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "center", children: [
457
- /* @__PURE__ */ jsx(Typography, { variant: "omega", children: "¿Seguro que deseas publicar este artículo en LinkedIn?" }),
458
- /* @__PURE__ */ jsx(Typography, { variant: "pi", children: "¡Esta acción es irreversible desde esta plataforma!" })
459
- ] })
460
- }
461
- ),
462
- /* @__PURE__ */ jsx(
463
- DialogCommon,
464
- {
465
- id: "publish-to-facebook-dialog",
466
- title: "Publicar en Facebook",
467
- confirmText: "Publicar",
468
- onCancelAction: () => onCancel("publish-to-facebook-dialog"),
469
- onConfirmAction: () => onConfirmPublish("facebook"),
470
- children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "center", children: [
471
- /* @__PURE__ */ jsx(Typography, { variant: "omega", children: "¿Seguro que deseas publicar este artículo en Facebook?" }),
472
- /* @__PURE__ */ jsx(Typography, { variant: "pi", children: "¡Esta acción es irreversible desde esta plataforma!" })
473
- ] })
474
- }
475
- ),
476
- /* @__PURE__ */ jsx(GenerateImageDialog, { onConfirmAction: onConfirmGenerateImage, onCancelAction: () => onCancel("generate-image-dialog") }),
477
- /* @__PURE__ */ jsxs(Grid.Root, { padding: 6, children: [
478
- /* @__PURE__ */ jsx(Grid.Item, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "start", children: [
479
- /* @__PURE__ */ jsx(Typography, { variant: "alpha", children: formatMessage({ id: getTranslation("plugin.name") }) }),
480
- /* @__PURE__ */ jsx(Typography, { variant: "pi", children: "Para uso exclusivo de InterWare de México" })
481
- ] }) }),
482
- /* @__PURE__ */ jsx(Grid.Item, { m: 12, children: /* @__PURE__ */ jsx(Flex, { justifyContent: "end", alignItems: "end", width: "100%", children: /* @__PURE__ */ jsx(LinkButton, { href: "/admin/plugins/strapi-content-generator-gemini/generate-content", children: "Generar nuevo artículo" }) }) }),
483
- /* @__PURE__ */ jsx(Grid.Item, { children: /* @__PURE__ */ jsx(
484
- PublishingTable,
485
- {
486
- posts,
487
- loadingImage,
488
- loadingPublishLinkedIn: loadingPublishingToLinkedIn,
489
- loadingPublishingToFacebook,
490
- currentPost: currentPostRef,
491
- onClickAction
492
- }
493
- ) })
494
- ] })
495
- ] });
496
- };
497
- const HomePage = () => {
498
- const { formatMessage } = useIntl();
499
- return /* @__PURE__ */ jsx(Fragment, { children: /* @__PURE__ */ jsxs(Page.Main, { children: [
500
- /* @__PURE__ */ jsx(Page.Title, { children: formatMessage({ id: getTranslation("plugin.name") }) }),
501
- /* @__PURE__ */ jsx(HomeContainer, {})
502
- ] }) });
503
- };
504
- const useCategories = () => {
505
- const { get } = useFetchClient();
506
- const getCategories = useCallback(
507
- async (config) => {
508
- return get("/strapi-content-generator-gemini/categories", config);
509
- },
510
- [get]
511
- );
512
- return {
513
- getCategories
514
- };
515
- };
516
- const useUsers = () => {
517
- const { get } = useFetchClient();
518
- const getUsers = useCallback(
519
- async (config) => {
520
- return get("/strapi-content-generator-gemini/users", config);
521
- },
522
- [get]
523
- );
524
- return {
525
- getUsers
526
- };
527
- };
528
- const validationSchema$1 = Yup.object().shape({
529
- titulo: Yup.string().notRequired(),
530
- autor: Yup.string().required("Este campo es obligatorio"),
531
- categoria: Yup.string().required("Este campo es obligatorio"),
532
- temperatura: Yup.string().notRequired(),
533
- instrucciones: Yup.string().notRequired()
534
- });
535
- const initialValues$1 = {
536
- titulo: "",
537
- autor: "",
538
- categoria: "",
539
- temperatura: "0.5",
540
- instrucciones: ""
541
- };
542
- const Form$1 = ({ onSubmit, categorias, users }) => {
543
- const formik = useFormik({
544
- initialValues: initialValues$1,
545
- validationSchema: validationSchema$1,
546
- onSubmit
547
- });
548
- const { values, errors, touched, isValid, dirty, isSubmitting, handleChange, setFieldValue, handleSubmit } = formik;
549
- return /* @__PURE__ */ jsx(Box, { background: "neutral0", padding: 6, margin: 6, width: "100%", children: /* @__PURE__ */ jsx("form", { onSubmit: handleSubmit, children: /* @__PURE__ */ jsxs(Grid.Root, { gap: 4, children: [
550
- /* @__PURE__ */ jsx(Grid.Item, { xs: 12, s: 12, m: 6, children: /* @__PURE__ */ jsxs(
551
- Field.Root,
552
- {
553
- id: "titulo",
554
- error: touched.titulo && errors.titulo ? errors.titulo : void 0,
555
- hint: "Ej: Las 10 mejores tendencias en IA para 2026",
556
- width: "100%",
557
- children: [
558
- /* @__PURE__ */ jsx(Field.Label, { children: "Título" }),
559
- /* @__PURE__ */ jsx(
560
- TextInput,
561
- {
562
- name: "titulo",
563
- label: "Título",
564
- placeholder: "Título sugerido para el blog",
565
- onChange: handleChange,
566
- type: "text",
567
- value: values.titulo
568
- }
569
- ),
570
- /* @__PURE__ */ jsx(Field.Error, {}),
571
- /* @__PURE__ */ jsx(Field.Hint, {})
572
- ]
573
- }
574
- ) }),
575
- /* @__PURE__ */ jsx(Grid.Item, { xs: 12, s: 12, m: 6, children: /* @__PURE__ */ jsxs(
576
- Field.Root,
577
- {
578
- id: "categoria",
579
- error: touched.categoria && errors.categoria ? errors.categoria : void 0,
580
- hint: "Puedes agregar más desde el Content Type: Categorías",
581
- width: "100%",
582
- required: true,
583
- children: [
584
- /* @__PURE__ */ jsx(Field.Label, { children: "Categoría" }),
585
- /* @__PURE__ */ jsx(
586
- Combobox,
587
- {
588
- name: "categoria",
589
- placeholder: "Selecciona o escribe una categoría",
590
- value: values.categoria,
591
- onChange: (v) => setFieldValue("categoria", v),
592
- onCreateOption: (v) => {
593
- setFieldValue("categoria", v);
594
- },
595
- required: true,
596
- children: categorias.map((c) => /* @__PURE__ */ jsx(ComboboxOption, { value: c.documentId, children: c.categoria }, c.documentId))
597
- }
598
- ),
599
- /* @__PURE__ */ jsx(Field.Hint, {})
600
- ]
601
- }
602
- ) }),
603
- /* @__PURE__ */ jsx(Grid.Item, { xs: 12, s: 12, m: 6, children: /* @__PURE__ */ jsxs(
604
- Field.Root,
605
- {
606
- id: "autor",
607
- error: touched.autor && errors.autor ? errors.autor : void 0,
608
- width: "100%",
609
- required: true,
610
- children: [
611
- /* @__PURE__ */ jsx(Field.Label, { children: "Autor" }),
612
- /* @__PURE__ */ jsx(
613
- Combobox,
614
- {
615
- name: "autor",
616
- placeholder: "Selecciona o escribe una categoría",
617
- value: values.autor,
618
- onChange: (v) => setFieldValue("autor", v),
619
- onCreateOption: (v) => {
620
- setFieldValue("autor", v);
621
- },
622
- required: true,
623
- children: users.map((c) => /* @__PURE__ */ jsx(ComboboxOption, { value: c.documentId, children: c.nombre_completo }, c.documentId))
624
- }
625
- ),
626
- /* @__PURE__ */ jsx(Field.Hint, {})
627
- ]
628
- }
629
- ) }),
630
- /* @__PURE__ */ jsx(Grid.Item, { xs: 12, s: 12, m: 6, children: /* @__PURE__ */ jsxs(
631
- Field.Root,
632
- {
633
- id: "temperatura",
634
- error: touched.temperatura && errors.temperatura ? errors.temperatura : void 0,
635
- width: "100%",
636
- children: [
637
- /* @__PURE__ */ jsx(Field.Label, { children: "Temperatura" }),
638
- /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", gap: 4, children: [
639
- /* @__PURE__ */ jsx(Box, { width: "100%", children: /* @__PURE__ */ jsx(
640
- "input",
641
- {
642
- name: "temperatura",
643
- value: values.temperatura,
644
- type: "range",
645
- min: "0",
646
- max: "2",
647
- step: "0.05",
648
- onChange: handleChange,
649
- style: { width: "100%" }
650
- }
651
- ) }),
652
- /* @__PURE__ */ jsx(Box, { width: "100px", children: /* @__PURE__ */ jsx(Field.Input, { value: values.temperatura, readOnly: true }) })
653
- ] }),
654
- /* @__PURE__ */ jsx(Field.Hint, {})
655
- ]
656
- }
657
- ) }),
658
- /* @__PURE__ */ jsx(Grid.Item, { children: /* @__PURE__ */ jsxs(
659
- Field.Root,
660
- {
661
- id: "instrucciones",
662
- error: touched.instrucciones && errors.instrucciones ? errors.instrucciones : void 0,
663
- width: "100%",
664
- children: [
665
- /* @__PURE__ */ jsx(Field.Label, { children: "Instrucciones adicionales" }),
666
- /* @__PURE__ */ jsx(
667
- Textarea,
668
- {
669
- name: "instrucciones",
670
- placeholder: "Escribe algunas instrucciones adicionales para el generador de contenido...",
671
- onChange: handleChange,
672
- value: values.instrucciones,
673
- resizable: false,
674
- rows: 10
675
- }
676
- )
677
- ]
678
- }
679
- ) }),
680
- /* @__PURE__ */ jsx(Grid.Item, { children: /* @__PURE__ */ jsx(Flex, { width: "100%", justifyContent: { initial: "end" }, alignItems: { initial: "end" }, children: /* @__PURE__ */ jsx(
681
- Button,
682
- {
683
- disabled: !(isValid && dirty) || isSubmitting,
684
- loading: isSubmitting,
685
- type: "submit",
686
- children: "Generar contenido"
687
- }
688
- ) }) })
689
- ] }) }) });
690
- };
691
- const GenerateContentContainer = () => {
692
- const [documentId, setDocumentId] = useState("");
693
- const [categorias, setCategorias] = useState([]);
694
- const [users, setUsers] = useState([]);
695
- const { getCategories } = useCategories();
696
- const { getUsers } = useUsers();
697
- const navigate = useNavigate();
698
- const { closeDialog: closeDialog2, openDialog: openDialog2 } = useDialog("generate-image-dialog");
699
- const { generateContent, generateImage } = useGenerateContent();
700
- const { formatMessage } = useIntl();
701
- const { toggleNotification } = useNotification();
702
- const onSubmit = useCallback(
703
- async (values, { setSubmitting }) => {
704
- try {
705
- const { data } = await generateContent(values);
706
- setDocumentId(data.documentId);
707
- openDialog2();
708
- toggleNotification({
709
- type: "success",
710
- message: formatMessage({
711
- id: `${PLUGIN_ID}.config.load.error`,
712
- defaultMessage: "Artículo generado con éxito"
713
- })
714
- });
715
- } catch (error) {
716
- console.error("Error generating content:", error);
717
- toggleNotification({
718
- type: "danger",
719
- message: formatMessage({
720
- id: `${PLUGIN_ID}.config.load.error`,
721
- defaultMessage: "Ocurrió un error al generar el artículo"
722
- })
723
- });
724
- } finally {
725
- setSubmitting(false);
726
- }
727
- },
728
- [generateContent, openDialog2]
729
- );
730
- const goToArticle = useCallback(() => {
731
- navigate(
732
- `/content-manager/collection-types/api::articulo.articulo/${documentId}`
733
- );
734
- }, [navigate, documentId]);
735
- const onConfirmGenerateImage = useCallback(
736
- async (imageInstructions) => {
737
- try {
738
- await generateImage({
739
- articleId: documentId,
740
- imageInstructions
741
- });
742
- goToArticle();
743
- } catch (err) {
744
- console.error("Error generating image:", err);
745
- } finally {
746
- closeDialog2();
747
- }
748
- },
749
- [generateImage, documentId, closeDialog2, goToArticle]
750
- );
751
- const onCancelGenerateImage = useCallback(() => {
752
- closeDialog2();
753
- goToArticle();
754
- }, [closeDialog2, goToArticle]);
755
- const fetchCategories = useCallback(async () => {
756
- let isMounted = true;
757
- try {
758
- const { data } = await getCategories();
759
- if (isMounted) {
760
- setCategorias(data);
761
- }
762
- } catch (error) {
763
- console.error("Error fetching posts:", error);
764
- }
765
- return () => {
766
- isMounted = false;
767
- };
768
- }, [getCategories]);
769
- const fetchUsers = useCallback(async () => {
770
- let isMounted = true;
771
- try {
772
- const { data } = await getUsers({
773
- params: {
774
- filters: {
775
- blocked: {
776
- $eq: false
777
- }
778
- }
779
- }
780
- });
781
- if (isMounted) {
782
- setUsers(data);
783
- }
784
- } catch (error) {
785
- console.error("Error fetching posts:", error);
786
- }
787
- return () => {
788
- isMounted = false;
789
- };
790
- }, [getUsers]);
791
- useEffect(() => {
792
- fetchCategories();
793
- fetchUsers();
794
- }, [fetchCategories]);
795
- return /* @__PURE__ */ jsxs(Fragment, { children: [
796
- /* @__PURE__ */ jsx(GenerateImageDialog, { onCancelAction: onCancelGenerateImage, onConfirmAction: onConfirmGenerateImage }),
797
- /* @__PURE__ */ jsxs(Grid.Root, { padding: 6, children: [
798
- /* @__PURE__ */ jsx(Grid.Item, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "start", children: [
799
- /* @__PURE__ */ jsx(Typography, { variant: "alpha", children: "Generar nuevo artículo" }),
800
- /* @__PURE__ */ jsx(Typography, { variant: "pi", children: "Para uso exclusivo de InterWare de México" })
801
- ] }) }),
802
- /* @__PURE__ */ jsx(Grid.Item, { m: 12, children: /* @__PURE__ */ jsx(Flex, { alignItems: "end", width: "100%", justifyContent: "end", children: /* @__PURE__ */ jsx(LinkButton, { href: "/admin/plugins/strapi-content-generator-gemini", children: "Regresar" }) }) }),
803
- /* @__PURE__ */ jsx(Grid.Item, { children: /* @__PURE__ */ jsx(Form$1, { categorias, users, onSubmit }) })
804
- ] })
805
- ] });
806
- };
807
- const GenerateContent = () => {
808
- return /* @__PURE__ */ jsxs(Page.Main, { children: [
809
- /* @__PURE__ */ jsx(Page.Title, { children: "Generar nuevo artículo" }),
810
- /* @__PURE__ */ jsx(GenerateContentContainer, {})
811
- ] });
812
- };
813
- const sceneSchema = Yup.object().shape({
814
- prompt: Yup.string().trim().required("El prompt es obligatorio para esta escena"),
815
- durationSeconds: Yup.number().min(1, "La duración mínima es 1 segundo").max(90, "La duración máxima es 90 segundos").required("La duración es obligatoria"),
816
- referenceImages: Yup.array().of(
817
- Yup.object().shape({
818
- id: Yup.number().required(),
819
- file: Yup.mixed().optional(),
820
- previewUrl: Yup.string().optional()
821
- })
822
- ).max(3, "Se permiten máximo 3 imágenes de referencia por escena").optional()
823
- });
824
- const validationSchema = Yup.object().shape({
825
- aspectRatio: Yup.string().oneOf(["16:9", "9:16", "1:1"], "Aspect ratio no válido").required("El aspect ratio es obligatorio"),
826
- scenes: Yup.array().of(sceneSchema).min(1, "Debe haber al menos una escena").max(20, "No se permiten más de 20 escenas")
827
- });
828
- const initialValues = {
829
- aspectRatio: "16:9",
830
- scenes: [
831
- {
832
- prompt: ``,
833
- durationSeconds: 8,
834
- narrationText: ``,
835
- referenceImages: []
836
- }
837
- ]
838
- };
839
- const Form = ({ onSubmit }) => {
840
- const formik = useFormik({
841
- initialValues,
842
- validationSchema,
843
- validateOnMount: true,
844
- onSubmit
845
- });
846
- console.log("🚀 ~ Form ~ formik:", formik.errors);
847
- return /* @__PURE__ */ jsx(Box, { background: "neutral0", padding: 6, hasRadius: true, width: "100%", children: /* @__PURE__ */ jsx("form", { onSubmit: formik.handleSubmit, children: /* @__PURE__ */ jsxs(Grid.Root, { gap: 4, children: [
848
- /* @__PURE__ */ jsx(Grid.Item, { m: 12, children: /* @__PURE__ */ jsxs(Field.Root, { id: "aspectRatio", width: "100%", required: true, children: [
849
- /* @__PURE__ */ jsx(Field.Label, { children: "Relación de aspecto" }),
850
- /* @__PURE__ */ jsxs(
851
- Combobox,
852
- {
853
- name: "aspectRatio",
854
- onChange: (value) => formik.setFieldValue("aspectRatio", value),
855
- onBlur: () => formik.setFieldTouched("aspectRatio", true),
856
- value: formik.values.aspectRatio,
857
- onClear: () => formik.setFieldValue("aspectRatio", ""),
858
- children: [
859
- /* @__PURE__ */ jsx(ComboboxOption, { value: "16:9", children: "16:9" }),
860
- /* @__PURE__ */ jsx(ComboboxOption, { value: "9:16", children: "9:16" }),
861
- /* @__PURE__ */ jsx(ComboboxOption, { value: "1:1", children: "1:1" })
862
- ]
863
- }
864
- ),
865
- /* @__PURE__ */ jsx(Field.Error, { children: formik.errors.aspectRatio })
866
- ] }) }),
867
- formik.values.scenes.map((scene, index) => /* @__PURE__ */ jsx(Grid.Item, { children: /* @__PURE__ */ jsxs(Box, { background: "neutral100", padding: 4, hasRadius: true, width: "100%", children: [
868
- /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", marginBottom: 3, children: [
869
- /* @__PURE__ */ jsxs("strong", { children: [
870
- "Escena ",
871
- index + 1
872
- ] }),
873
- formik.values.scenes.length > 1 && /* @__PURE__ */ jsx(
874
- Button,
875
- {
876
- variant: "danger-light",
877
- onClick: () => {
878
- const updatedScenes = [...formik.values.scenes];
879
- updatedScenes.splice(index, 1);
880
- formik.setFieldValue("scenes", updatedScenes);
881
- },
882
- children: "Eliminar Escena"
883
- }
884
- )
885
- ] }),
886
- /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 3, children: [
887
- /* @__PURE__ */ jsxs(Field.Root, { id: `scenes.${index}.prompt`, width: "100%", required: true, children: [
888
- /* @__PURE__ */ jsx(Field.Label, { children: "Prompt de la escena" }),
889
- /* @__PURE__ */ jsx(
890
- Textarea,
891
- {
892
- name: `scenes.${index}.prompt`,
893
- placeholder: "Describe visualmente esta escena",
894
- onChange: formik.handleChange,
895
- onBlur: formik.handleBlur,
896
- value: formik.values.scenes[index].prompt,
897
- rows: 6
898
- }
899
- )
900
- ] }),
901
- /* @__PURE__ */ jsxs(Field.Root, { id: `scenes.${index}.durationSeconds`, width: "100%", required: true, children: [
902
- /* @__PURE__ */ jsx(Field.Label, { children: "Duración (segundos)" }),
903
- /* @__PURE__ */ jsxs(
904
- Combobox,
905
- {
906
- name: `scenes.${index}.durationSeconds`,
907
- onChange: (value) => formik.setFieldValue(`scenes.${index}.durationSeconds`, value),
908
- onBlur: formik.handleBlur,
909
- value: formik.values.scenes[index].durationSeconds,
910
- onClear: () => formik.setFieldValue(`scenes.${index}.durationSeconds`, ""),
911
- children: [
912
- /* @__PURE__ */ jsx(ComboboxOption, { value: 4, children: "4" }),
913
- /* @__PURE__ */ jsx(ComboboxOption, { value: 6, children: "6" }),
914
- /* @__PURE__ */ jsx(ComboboxOption, { value: 8, children: "8" })
915
- ]
916
- }
917
- )
918
- ] }),
919
- /* @__PURE__ */ jsxs(Field.Root, { id: `scenes.${index}.referenceImages`, width: "100%", children: [
920
- /* @__PURE__ */ jsx(Field.Label, { children: "Imagen(es) de referencia" }),
921
- /* @__PURE__ */ jsxs(Flex, { direction: "column", gap: 3, width: "100%", children: [
922
- scene.referenceImages.map((image, imgIndex) => /* @__PURE__ */ jsx(Box, { background: "neutral200", padding: 2, hasRadius: true, width: "100%", children: /* @__PURE__ */ jsxs(Flex, { justifyContent: "space-between", alignItems: "center", children: [
923
- image.previewUrl ? /* @__PURE__ */ jsx("img", { src: image.previewUrl, alt: "preview", style: { width: 50, height: 50, objectFit: "cover" } }) : /* @__PURE__ */ jsx("div", { style: { width: 50, height: 50, backgroundColor: "#ccc" } }),
924
- /* @__PURE__ */ jsx(
925
- IconButton,
926
- {
927
- onClick: () => {
928
- const imageToRemove = scene.referenceImages[imgIndex];
929
- if (imageToRemove.previewUrl) {
930
- URL.revokeObjectURL(imageToRemove.previewUrl);
931
- }
932
- const updatedImages = [...scene.referenceImages];
933
- updatedImages.splice(imgIndex, 1);
934
- formik.setFieldValue(`scenes.${index}.referenceImages`, updatedImages);
935
- },
936
- label: "Eliminar imagen",
937
- children: /* @__PURE__ */ jsx(Trash, {})
938
- }
939
- )
940
- ] }) }, image.id)),
941
- /* @__PURE__ */ jsx(
942
- Button,
943
- {
944
- type: "button",
945
- startIcon: /* @__PURE__ */ jsx(PlusCircle, {}),
946
- variant: "secondary",
947
- fullWidth: true,
948
- onClick: () => {
949
- const input = document.createElement("input");
950
- input.type = "file";
951
- input.accept = "image/*";
952
- input.onchange = (e) => {
953
- const selectedFile = e.target.files?.[0];
954
- if (!selectedFile) return;
955
- const newImage = {
956
- id: Date.now(),
957
- file: selectedFile,
958
- previewUrl: URL.createObjectURL(selectedFile)
959
- };
960
- const newImages = [...scene.referenceImages, newImage];
961
- formik.setFieldValue(`scenes.${index}.referenceImages`, newImages.slice(0, 5));
962
- };
963
- input.click();
964
- },
965
- disabled: scene.referenceImages.length >= 5,
966
- children: "Añadir imagen de referencia"
967
- }
968
- )
969
- ] })
970
- ] })
971
- ] })
972
- ] }, index) }, `scene-${index}`)),
973
- /* @__PURE__ */ jsx(Grid.Item, { m: 12, children: /* @__PURE__ */ jsx(
974
- Button,
975
- {
976
- type: "button",
977
- startIcon: /* @__PURE__ */ jsx(PlusCircle, {}),
978
- variant: "secondary",
979
- onClick: () => {
980
- formik.setFieldValue("scenes", [
981
- ...formik.values.scenes,
982
- { prompt: "", durationSeconds: 6, narrationText: "", referenceImages: [] }
983
- ]);
984
- },
985
- fullWidth: true,
986
- children: "Añadir Escena"
987
- }
988
- ) }),
989
- /* @__PURE__ */ jsx(Grid.Item, { col: 12, children: /* @__PURE__ */ jsx(Flex, { width: "100%", justifyContent: "end", alignItems: "end", children: /* @__PURE__ */ jsx(
990
- Button,
991
- {
992
- type: "submit",
993
- fullWidth: true,
994
- disabled: !(formik.isValid && formik.dirty) || formik.isSubmitting,
995
- loading: formik.isSubmitting,
996
- children: "Generar Video"
997
- }
998
- ) }) })
999
- ] }) }) });
1000
- };
1001
- const useImages = () => {
1002
- const { post } = useFetchClient();
1003
- const generateVideoWithScenes = useCallback(
1004
- async (data, config) => {
1005
- return await post("/strapi-content-generator-gemini/generate-video-with-scenes", data, config);
1006
- },
1007
- [post]
1008
- );
1009
- return {
1010
- generateVideoWithScenes
1011
- };
1012
- };
1013
- const GenerateVideoContainer = () => {
1014
- const { toggleNotification } = useNotification();
1015
- const { generateVideoWithScenes } = useImages();
1016
- const { formatMessage } = useIntl();
1017
- const handleSubmit = async (values, { setSubmitting }) => {
1018
- try {
1019
- const formData = new FormData();
1020
- formData.append("aspectRatio", values.aspectRatio);
1021
- values.scenes.forEach((scene, index) => {
1022
- formData.append(`scenes[${index}][prompt]`, scene.prompt);
1023
- formData.append(`scenes[${index}][durationSeconds]`, scene.durationSeconds.toString());
1024
- formData.append(`scenes[${index}][narrationText]`, scene.narrationText || "");
1025
- scene.referenceImages.forEach((image, imgIndex) => {
1026
- if (image.file) {
1027
- formData.append(`scenes[${index}][referenceImages][${imgIndex}]`, image.file);
1028
- }
1029
- });
1030
- });
1031
- const response = await generateVideoWithScenes(formData);
1032
- console.log("🚀 ~ handleSubmit ~ response:", response);
1033
- toggleNotification({
1034
- type: "success",
1035
- message: formatMessage({
1036
- id: `${PLUGIN_ID}.config.load.success`,
1037
- defaultMessage: "Video generado con éxito"
1038
- })
1039
- });
1040
- } catch (error) {
1041
- toggleNotification({
1042
- type: "danger",
1043
- message: formatMessage({
1044
- id: `${PLUGIN_ID}.config.load.error`,
1045
- defaultMessage: "Ocurrió un error al generar el video"
1046
- })
1047
- });
1048
- } finally {
1049
- setSubmitting(false);
1050
- }
1051
- };
1052
- return /* @__PURE__ */ jsxs(Fragment, { children: [
1053
- /* @__PURE__ */ jsx(Grid.Root, { padding: 6, children: /* @__PURE__ */ jsx(Grid.Item, { children: /* @__PURE__ */ jsxs(Flex, { direction: "column", alignItems: "start", children: [
1054
- /* @__PURE__ */ jsx(Typography, { variant: "alpha", children: "Generar video con IA" }),
1055
- /* @__PURE__ */ jsx(Typography, { variant: "pi", children: "Para uso exclusivo de InterWare de México" })
1056
- ] }) }) }),
1057
- /* @__PURE__ */ jsxs(Grid.Root, { padding: 6, children: [
1058
- /* @__PURE__ */ jsx(Grid.Item, { m: 2 }),
1059
- /* @__PURE__ */ jsx(Grid.Item, { m: 8, children: /* @__PURE__ */ jsx(Form, { onSubmit: handleSubmit }) })
1060
- ] })
1061
- ] });
1062
- };
1063
- const GenerateVideo = () => {
1064
- return /* @__PURE__ */ jsxs(Page.Main, { children: [
1065
- /* @__PURE__ */ jsx(Page.Title, { children: "Generar video con IA" }),
1066
- /* @__PURE__ */ jsx(GenerateVideoContainer, {})
1067
- ] });
1068
- };
1069
- const App = () => {
1070
- const { allowedActions, isLoading } = useRBAC(pluginPermissions);
1071
- if (isLoading) {
1072
- return /* @__PURE__ */ jsx(Page.Loading, {});
1073
- }
1074
- return /* @__PURE__ */ jsx(Page.Protect, { permissions: [...pluginPermissions.access], children: /* @__PURE__ */ jsx(PluginProviders, { children: /* @__PURE__ */ jsxs(Routes, { children: [
1075
- allowedActions.canAccess && /* @__PURE__ */ jsx(Route, { index: true, element: /* @__PURE__ */ jsx(HomePage, {}) }),
1076
- allowedActions.canAccess && /* @__PURE__ */ jsx(Route, { path: "/generate-content", element: /* @__PURE__ */ jsx(GenerateContent, {}) }),
1077
- allowedActions.canAccess && /* @__PURE__ */ jsxs(Fragment, { children: [
1078
- /* @__PURE__ */ jsx(Route, { path: "/image-studio", element: /* @__PURE__ */ jsx(StudioRedirect, {}) }),
1079
- LEGACY_ROUTES.map((r) => /* @__PURE__ */ jsx(Route, { path: r.path, element: legacyRedirect(r.tab) }, r.path)),
1080
- /* @__PURE__ */ jsx(Route, { path: "/generate-video", element: /* @__PURE__ */ jsx(GenerateVideo, {}) })
1081
- ] }),
1082
- /* @__PURE__ */ jsx(Route, { path: "*", element: /* @__PURE__ */ jsx(Page.Error, {}) })
1083
- ] }) }) });
1084
- };
1085
- export {
1086
- App
1087
- };