Refactoring, create component OpenInCodepenio

This commit is contained in:
dialmedu 2023-11-26 23:36:20 -05:00
parent 101dcc4bb5
commit 3a6a5f8632
2 changed files with 121 additions and 42 deletions

View File

@ -31,6 +31,7 @@ import { UrlInputSection } from "./components/UrlInputSection";
import TermsOfServiceDialog from "./components/TermsOfServiceDialog"; import TermsOfServiceDialog from "./components/TermsOfServiceDialog";
import html2canvas from "html2canvas"; import html2canvas from "html2canvas";
import { USER_CLOSE_WEB_SOCKET_CODE } from "./constants"; import { USER_CLOSE_WEB_SOCKET_CODE } from "./constants";
import OpenInCodepenio from "./components/OpenInCodepenio";
function App() { function App() {
const [appState, setAppState] = useState<AppState>(AppState.INITIAL); const [appState, setAppState] = useState<AppState>(AppState.INITIAL);
@ -97,45 +98,6 @@ function App() {
setAppState(AppState.CODE_READY); setAppState(AppState.CODE_READY);
}; };
function doOpenInCodepenio(){
const code = generatedCode
var form = document.createElement('form');
form.setAttribute('method', 'POST');
form.setAttribute('action', 'https://codepen.io/pen/define');
form.setAttribute('target', '_blank'); // open in new window
const data = {
html: code,
editors: "100", // 1:Open html, 0:close CSS, 0:Close Js
layout: "left",
css_external: "https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css"
+ (generatedCode.includes('<ion-') ? ',https://cdn.jsdelivr.net/npm/@ionic/core/css/ionic.bundle.css': '')
,
js_external: "https://cdn.tailwindcss.com "
+ (generatedCode.includes('<ion-') ? ',https://cdn.jsdelivr.net/npm/@ionic/core/dist/ionic/ionic.esm.js,https://cdn.jsdelivr.net/npm/@ionic/core/dist/ionic/ionic.js': '')
,
}
// test have html to json
try {
JSON.stringify(data)
} catch (error) {
data.html = "<!-- Copy your code here -->"
}
// Crear un input tipo hidden
var input = document.createElement('input');
input.setAttribute('type', 'hidden');
input.setAttribute('name', 'data');
input.setAttribute('value', JSON.stringify(data));
// Agregar el input al formulario
form.appendChild(input);
// Agregar el formulario al documento y enviarlo automáticamente
document.body.appendChild(form);
form.submit();
}
function doGenerateCode(params: CodeGenerationParams) { function doGenerateCode(params: CodeGenerationParams) {
setExecutionConsole([]); setExecutionConsole([]);
setAppState(AppState.CODING); setAppState(AppState.CODING);
@ -361,9 +323,7 @@ function App() {
> >
Copy Code <FaCopy className="ml-2" /> Copy Code <FaCopy className="ml-2" />
</span> </span>
<Button onClick={doOpenInCodepenio} className="bg-gray-100 text-black ml-2 py-2 px-4 border border-black rounded-md hover:bg-gray-400 focus:outline-none"> <OpenInCodepenio code={generatedCode} ></OpenInCodepenio>
Open in <img src="https://assets.codepen.io/t-1/codepen-logo.svg" alt="codepen.io" className="h-4 ml-1" />
</Button>
</div> </div>
<CodeMirror <CodeMirror
code={generatedCode} code={generatedCode}

View File

@ -0,0 +1,119 @@
import { Component } from 'react';
import { Button } from './ui/button';
enum SupportType {
HTML = 'html',
IONIC = 'ionic'
}
enum LibraryType {
css = 'css',
js = 'js',
}
interface OpenInCodepenioProps {
code: string;
support?: SupportType;
onDoOpen?: () => void;
}
interface Library {
[LibraryType.css]: string[],
[LibraryType.js]: string[],
validate: (support: SupportType, code: String) => Boolean
}
/**
* Component show button do open in new windows to CodePen Editor, this component add support
* of diferrent tecnologies do use `libraries` property.
* @component
* Redirect to codepen.io
* @param { OpenInCodepenioProps } props
* @property {string} code - this generated code.
* @property {Function} onDoOpen - handle after open and redirect to Codepen Editor
* @property {Record} libraries - add support diferent tecnologies adding css, js libraries
* to css_external and js_external atributte of Codepen Editor.
*/
class OpenInCodepenio extends Component<OpenInCodepenioProps> {
libraries: Record<string, Library> = {
[SupportType.HTML] : {
css: ['https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css'],
js: ['https://cdn.tailwindcss.com'],
validate: (support) => {
return support == SupportType.HTML
}
},
[SupportType.IONIC] : {
css: [
'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/5.15.3/css/all.min.css',
'https://cdn.jsdelivr.net/npm/@ionic/core/css/ionic.bundle.css'],
js: [
'https://cdn.tailwindcss.com',
'https://cdn.jsdelivr.net/npm/@ionic/core/dist/ionic/ionic.esm.js',
'https://cdn.jsdelivr.net/npm/@ionic/core/dist/ionic/ionic.js'
],
validate: (support, code) => {
return support == SupportType.IONIC || code.includes('<ion-')
}
},
}
getExternalLibraries = (type: LibraryType): string => {
let library: string[] = []
const { code, support = SupportType.HTML } = this.props;
debugger
Object.values(this.libraries).forEach((value: Library) => {
if( value.validate(support, code)){
library = value[type]
}
});
return library.join(',');
}
doOpenInCodepenio = () => {
const { code, onDoOpen } = this.props;
var form = document.createElement('form');
form.setAttribute('method', 'POST');
form.setAttribute('action', 'https://codepen.io/pen/define');
form.setAttribute('target', '_blank'); // open in new window
const data = {
html: code,
editors: "100", // 1:Open html, 0:close CSS, 0:Close Js
layout: "left",
css_external: this.getExternalLibraries(LibraryType.css),
js_external: this.getExternalLibraries(LibraryType.js),
}
// test have html to json
try {
JSON.stringify({ html: data.html })
} catch (error) {
data.html = "<!-- Copy your code here -->"
}
var input = document.createElement('input');
input.setAttribute('type', 'hidden');
input.setAttribute('name', 'data');
input.setAttribute('value', JSON.stringify(data));
form.appendChild(input);
document.body.appendChild(form);
form.submit();
if (onDoOpen) {
onDoOpen();
}
}
render() {
return (
<div>
<Button onClick={this.doOpenInCodepenio} className="bg-gray-100 text-black ml-2 py-2 px-4 border border-black rounded-md hover:bg-gray-400 focus:outline-none">
Open in <img src="https://assets.codepen.io/t-1/codepen-logo.svg" alt="codepen.io" className="h-4 ml-1" />
</Button>
</div>
);
}
}
export default OpenInCodepenio;