- {contentType === 'image' && contentPosition !== 'background'
- ? imageBlock(illustrationImage)
- : null}
- {contentType === 'video' && contentPosition !== 'background'
- ? videoBlock(illustrationVideo)
- : null}
-
-
-
-
-
-
This is a React.js/Node.js app generated by the Flatlogic Web App Generator
-
For guides and documentation please check
- your local README.md and the Flatlogic documentation
+
+
+
+
+
+
+
+
+
+ 🤖 SaaS de contenido dark para monetizar sin aparecer
+
+
+ Crea videos que pueden generar dinero{' '}
+
+ {}sin mostrar tu rostro.
+
+
+
+ DarkFactory.ai usa inteligencia artificial para generar ideas, guiones, títulos,
+ CTAs, prompts MGX y paquetes de publicación para YouTube, TikTok y Reels en minutos.
+
+
+
+ Comenzar ahora
+
+
+ Probar gratis
+
+
+
+ Plan Pro desde R$29/mes · login incluido · historial de creaciones.
+
-
-
-
-
-
+
+
+
+
+
Factory Output
+
Pack viral listo
+
+
Activo
+
+
+ {scriptExamples.map((item) => (
+
+ {item.label}
+ {item.title}
+ {item.copy}
+
+ ))}
+
+
+
+
+
+
+
+
+
+
Suite de herramientas
+
De un tema a un paquete de publicación.
+
+ Ideas, guiones cortos y largos, títulos, CTAs, prompts para MGX, thumbnails y voz IA en una sola experiencia.
+
+
+
+ {['🧠 Ideas de videos', '✍️ Guiones cortos/largos', '🎯 Títulos + CTAs', '🎬 Shorts automáticos', '🖼️ Thumbnails', '💬 Prompts MGX', '🔊 Voz IA', '📦 Packs semanales'].map((tool) => (
+
+ {tool}
+
+ ))}
+
+
+ Abrir página de herramientas
+
+
+
+
+
+
+ {creatorResults.map(([value, label]) => (
+
+ ))}
+
+
+
+
+
+
+
Monetización por suscripción
+
Elige tu plan y empieza a producir.
+
+
+ {plans.map((plan) => (
+
+
+
{plan.name}
+ {plan.badge}
+
+ {plan.price}
+
+ {plan.benefits.map((benefit) => (
+
+ ✓
+ {benefit}
+
+ ))}
+
+
+ {plan.name === 'Free' ? 'Crear cuenta gratis' : 'Suscribirme ahora'}
+
+
+ ))}
+
+
+
+
+
+
+
Sobre el proyecto
+
DarkFactory.ai convierte constancia en sistema.
+
+ Creamos una fábrica digital para creadores que quieren publicar más, probar más nichos y monetizar más rápido sin depender de cámara, edición pesada o bloqueo creativo.
+
+
+
+
+
+
-
-
-
© 2026 {title} . All rights reserved
-
- Privacy Policy
-
-
-
+
);
}
@@ -163,4 +255,3 @@ export default function Starter() {
Starter.getLayout = function getLayout(page: ReactElement) {
return
{page} ;
};
-
diff --git a/frontend/src/pages/tools-studio.tsx b/frontend/src/pages/tools-studio.tsx
new file mode 100644
index 0000000..7fa7b5c
--- /dev/null
+++ b/frontend/src/pages/tools-studio.tsx
@@ -0,0 +1,420 @@
+import * as icon from '@mdi/js';
+import Head from 'next/head';
+import React, { ReactElement } from 'react';
+import axios from 'axios';
+import BaseButton from '../components/BaseButton';
+import CardBox from '../components/CardBox';
+import LayoutAuthenticated from '../layouts/Authenticated';
+import SectionMain from '../components/SectionMain';
+import SectionTitleLineWithButton from '../components/SectionTitleLineWithButton';
+import { getPageTitle } from '../config';
+import { useAppDispatch, useAppSelector } from '../stores/hooks';
+import { aiResponse } from '../stores/openAiSlice';
+
+type ToolId = 'ideas' | 'scripts' | 'titles' | 'shorts' | 'thumbnails' | 'mgx' | 'voice';
+
+type GeneratedRun = {
+ id: string;
+ toolId: ToolId;
+ toolName: string;
+ topic: string;
+ platform: string;
+ style: string;
+ language: string;
+ result: string;
+ createdAt: string;
+ savedToApi: boolean;
+};
+
+const tools: Array<{ id: ToolId; icon: string; name: string; description: string; instruction: string }> = [
+ {
+ id: 'ideas',
+ icon: '🧠',
+ name: 'Gerador de Ideias de Vídeos',
+ description: 'Ángulos virales y series de contenido para canales dark.',
+ instruction: 'Genera 10 ideas de videos dark con gancho, promesa, público objetivo y formato recomendado.',
+ },
+ {
+ id: 'scripts',
+ icon: '✍️',
+ name: 'Gerador de Roteiros',
+ description: 'Guiones cortos y largos con hook, desarrollo, CTA y retención.',
+ instruction: 'Crea un guion completo para video dark con hook de 3 segundos, narrativa, escenas sugeridas y CTA final.',
+ },
+ {
+ id: 'titles',
+ icon: '🎯',
+ name: 'Gerador de Títulos + CTAs',
+ description: 'Títulos magnéticos, CTAs y descripciones listas para publicar.',
+ instruction: 'Genera 12 títulos virales, 5 CTAs y 3 descripciones cortas optimizadas para conversión.',
+ },
+ {
+ id: 'shorts',
+ icon: '🎬',
+ name: 'Gerador de Shorts Automáticos',
+ description: 'Estructuras rápidas para TikTok, Reels y YouTube Shorts.',
+ instruction: 'Diseña un short de 45 segundos con escenas, texto en pantalla, narración y ritmo de edición.',
+ },
+ {
+ id: 'thumbnails',
+ icon: '🖼️',
+ name: 'Gerador de Thumbnails',
+ description: 'Conceptos visuales con copy, composición y contraste.',
+ instruction: 'Propón 6 ideas de thumbnails con texto corto, colores, foco visual y emoción dominante.',
+ },
+ {
+ id: 'mgx',
+ icon: '💬',
+ name: 'Gerador de Prompts para MGX',
+ description: 'Prompts visuales para assets, escenas y B-roll generativo.',
+ instruction: 'Escribe prompts MGX detallados para generar escenas visuales coherentes con un canal dark.',
+ },
+ {
+ id: 'voice',
+ icon: '🔊',
+ name: 'Sugestões de Voz IA',
+ description: 'Dirección de voz, ritmo, emoción y estilo de narración.',
+ instruction: 'Recomienda estilos de voz IA, ritmo, emoción, pausas y ejemplo de narración para el tema.',
+ },
+];
+
+const styles = [
+ { value: 'storytelling', label: 'Storytelling' },
+ { value: 'listicle', label: 'Lista viral' },
+ { value: 'tutorial', label: 'Tutorial' },
+ { value: 'facts', label: 'Curiosidades' },
+ { value: 'finance', label: 'Finanzas' },
+ { value: 'motivational', label: 'Motivacional' },
+ { value: 'horror', label: 'Horror / misterio' },
+];
+
+const extractResponseText = (payload: any) => {
+ const output = payload?.output;
+ if (Array.isArray(output)) {
+ const message = output.find((item) => item?.type === 'message');
+ const content = message?.content;
+ if (Array.isArray(content)) {
+ const textItem = content.find((item) => item?.type === 'output_text');
+ if (textItem?.text) return textItem.text;
+ }
+ }
+ if (typeof payload?.text === 'string') return payload.text;
+ if (typeof payload?.data === 'string') return payload.data;
+ return JSON.stringify(payload, null, 2);
+};
+
+const buildPrompt = (toolName: string, instruction: string, topic: string, platform: string, style: string, language: string) => `
+Herramienta: ${toolName}
+Tema: ${topic}
+Plataforma: ${platform}
+Estilo de contenido: ${style}
+Idioma de salida: ${language}
+
+Instrucciones:
+${instruction}
+
+Devuelve el resultado en formato práctico, con secciones claras, bullets accionables y texto listo para copiar/pegar. Mantén un tono directo, persuasivo y orientado a creadores que quieren monetizar canales dark sin mostrar el rostro.
+`;
+
+const localStorageKey = 'darkfactory_tool_runs';
+
+const ToolsStudio = () => {
+ const dispatch = useAppDispatch();
+ const { isAskingResponse, errorMessage } = useAppSelector((state) => state.openAi);
+ const [activeToolId, setActiveToolId] = React.useState
('ideas');
+ const [topic, setTopic] = React.useState('Finanzas personales para jóvenes que quieren ganar dinero con IA');
+ const [platform, setPlatform] = React.useState('multi');
+ const [style, setStyle] = React.useState('storytelling');
+ const [language, setLanguage] = React.useState('es');
+ const [validationError, setValidationError] = React.useState('');
+ const [saveNotice, setSaveNotice] = React.useState('');
+ const [runs, setRuns] = React.useState([]);
+ const [selectedRunId, setSelectedRunId] = React.useState('');
+
+ const activeTool = tools.find((tool) => tool.id === activeToolId) || tools[0];
+ const selectedRun = runs.find((run) => run.id === selectedRunId) || runs[0];
+
+ React.useEffect(() => {
+ try {
+ const storedRuns = window.localStorage.getItem(localStorageKey);
+ if (storedRuns) {
+ const parsedRuns = JSON.parse(storedRuns);
+ if (Array.isArray(parsedRuns)) {
+ setRuns(parsedRuns);
+ setSelectedRunId(parsedRuns[0]?.id || '');
+ }
+ }
+ } catch (error) {
+ console.error('Failed to load DarkFactory local history', error);
+ setSaveNotice('No se pudo cargar el historial local. Revisa la consola para más detalles.');
+ }
+ }, []);
+
+ const persistRuns = (nextRuns: GeneratedRun[]) => {
+ window.localStorage.setItem(localStorageKey, JSON.stringify(nextRuns.slice(0, 12)));
+ setRuns(nextRuns.slice(0, 12));
+ };
+
+ const generate = async () => {
+ const cleanTopic = topic.trim();
+ setValidationError('');
+ setSaveNotice('');
+
+ if (cleanTopic.length < 5) {
+ setValidationError('Escribe un tema con al menos 5 caracteres para generar un resultado útil.');
+ return;
+ }
+
+ const prompt = buildPrompt(activeTool.name, activeTool.instruction, cleanTopic, platform, style, language);
+ const response = await dispatch(
+ aiResponse({
+ input: [
+ {
+ role: 'system',
+ content: 'Eres DarkFactory.ai, un asistente experto en contenido dark, retención, monetización y guiones para YouTube, TikTok y Reels.',
+ },
+ { role: 'user', content: prompt },
+ ],
+ options: { poll_interval: 5, poll_timeout: 300 },
+ }),
+ ).unwrap();
+
+ const resultText = extractResponseText(response);
+ let savedToApi = false;
+
+ try {
+ await axios.post('/tool_runs', {
+ data: {
+ platform,
+ content_style: style,
+ language,
+ topic: cleanTopic,
+ audience: 'Creadores de canales dark que quieren monetizar con contenido sin rostro',
+ tone: 'Directo, persuasivo y accionable',
+ desired_length_seconds: activeToolId === 'shorts' ? 45 : 120,
+ prompt_text: prompt,
+ result_text: resultText,
+ status: 'succeeded',
+ requested_at: new Date().toISOString(),
+ completed_at: new Date().toISOString(),
+ estimated_cost: 0,
+ },
+ });
+ savedToApi = true;
+ setSaveNotice('Resultado generado y guardado en Tool runs.');
+ } catch (error) {
+ console.error('DarkFactory result generated but API history save failed', error);
+ setSaveNotice('Resultado generado. No se pudo guardar en la base de datos; quedó guardado en este navegador.');
+ }
+
+ const nextRun: GeneratedRun = {
+ id: `${Date.now()}`,
+ toolId: activeTool.id,
+ toolName: activeTool.name,
+ topic: cleanTopic,
+ platform,
+ style,
+ language,
+ result: resultText,
+ createdAt: new Date().toISOString(),
+ savedToApi,
+ };
+ const nextRuns = [nextRun, ...runs];
+ persistRuns(nextRuns);
+ setSelectedRunId(nextRun.id);
+ };
+
+ const downloadSelected = () => {
+ if (!selectedRun) return;
+ const blob = new Blob([selectedRun.result], { type: 'text/plain;charset=utf-8' });
+ const url = URL.createObjectURL(blob);
+ const anchor = document.createElement('a');
+ anchor.href = url;
+ anchor.download = `darkfactory-${selectedRun.toolId}-${selectedRun.id}.txt`;
+ anchor.click();
+ URL.revokeObjectURL(url);
+ };
+
+ return (
+ <>
+
+ {getPageTitle('DarkFactory Tools Studio')}
+
+
+
+
+
+
+
+
+
+
+
+
+
Generación con IA
+
+ Escribe un tema. Recibe un paquete listo para publicar.
+
+
+ Elige una herramienta, define plataforma y estilo, genera contenido y guarda el historial para descargar paquetes después.
+
+
+
+ {tools.map((tool) => (
+ setActiveToolId(tool.id)}
+ className={`rounded-2xl border p-4 text-left transition hover:-translate-y-0.5 ${activeToolId === tool.id ? 'border-cyan-300 bg-cyan-300 text-[#07101c]' : 'border-white/10 bg-white/[0.05] text-white hover:bg-white/[0.08]'}`}
+ >
+ {tool.icon}
+ {tool.name}
+ {tool.description}
+
+ ))}
+
+
+
+
+
+
+
+
+
{activeTool.icon}
+
+
{activeTool.name}
+
{activeTool.description}
+
+
+
+
+ Tema o nicho
+
+
+
+
+
+
+
+
+
+
+
+
Historial de creaciones
+
Últimos paquetes generados en este navegador.
+
+
{runs.length}
+
+
+ {!runs.length && (
+
+
Aún no hay resultados.
+
Genera tu primer paquete para ver el detalle y descargarlo.
+
+ )}
+
+
+ {runs.map((run) => (
+
setSelectedRunId(run.id)}
+ className={`w-full rounded-2xl border p-4 text-left transition hover:-translate-y-0.5 ${selectedRun?.id === run.id ? 'border-cyan-400 bg-cyan-50 dark:bg-cyan-400/10' : 'border-gray-200 dark:border-dark-700'}`}
+ >
+
+
+
{run.toolName}
+
{run.topic}
+
+
+ {run.savedToApi ? 'DB' : 'Local'}
+
+
+
+ ))}
+
+
+
+
+ {selectedRun ? (
+
+
+
+
Resultado
+
{selectedRun.toolName}
+
+ {new Date(selectedRun.createdAt).toLocaleString()} · {selectedRun.platform} · {selectedRun.language}
+
+
+
+
+
+ {selectedRun.result}
+
+
+ ) : (
+
+
+
📦
+
Tu paquete aparecerá aquí
+
Genera contenido para ver el detalle, copiarlo o descargarlo.
+
+
+ )}
+
+
+
+ >
+ );
+};
+
+ToolsStudio.getLayout = function getLayout(page: ReactElement) {
+ return {page} ;
+};
+
+export default ToolsStudio;