diff --git a/frontend/package-lock.json b/frontend/package-lock.json
index 0d36402..0295583 100644
--- a/frontend/package-lock.json
+++ b/frontend/package-lock.json
@@ -19,6 +19,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
+ "react-svg": "^16.1.19",
"web-vitals": "^2.1.4"
}
},
@@ -4000,6 +4001,16 @@
"url": "https://github.com/sponsors/gregberge"
}
},
+ "node_modules/@tanem/svg-injector": {
+ "version": "10.1.60",
+ "resolved": "https://registry.npmjs.org/@tanem/svg-injector/-/svg-injector-10.1.60.tgz",
+ "integrity": "sha512-yzdF0f7TZI7MrMieJLu5VYEJuL0WneFCabLvBfpNWDoWikzQPW8V9tpEqHa2A4kKJDiXUzsIoqtPEvGj9xsPgQ==",
+ "dependencies": {
+ "@babel/runtime": "^7.22.5",
+ "content-type": "^1.0.5",
+ "tslib": "^2.6.0"
+ }
+ },
"node_modules/@testing-library/dom": {
"version": "9.3.1",
"resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-9.3.1.tgz",
@@ -15092,6 +15103,21 @@
}
}
},
+ "node_modules/react-svg": {
+ "version": "16.1.19",
+ "resolved": "https://registry.npmjs.org/react-svg/-/react-svg-16.1.19.tgz",
+ "integrity": "sha512-WchBqQ8LooWpEp3JM7F9cJxPzrMLmd2fTD5NbzkDHeJAMuqUeD9QtOEDNPgRstPeh0aMEV2j8WwNXSXFRMuy3g==",
+ "dependencies": {
+ "@babel/runtime": "^7.22.6",
+ "@tanem/svg-injector": "^10.1.60",
+ "@types/prop-types": "^15.7.5",
+ "prop-types": "^15.8.1"
+ },
+ "peerDependencies": {
+ "react": "^16.0.0 || ^17.0.0 || ^18.0.0",
+ "react-dom": "^16.0.0 || ^17.0.0 || ^18.0.0"
+ }
+ },
"node_modules/react-transition-group": {
"version": "4.4.5",
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
diff --git a/frontend/package.json b/frontend/package.json
index ce67c8d..f314d7e 100644
--- a/frontend/package.json
+++ b/frontend/package.json
@@ -14,6 +14,7 @@
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-scripts": "5.0.1",
+ "react-svg": "^16.1.19",
"web-vitals": "^2.1.4"
},
"scripts": {
diff --git a/frontend/src/App.js b/frontend/src/App.js
index 7e778bb..065cad3 100644
--- a/frontend/src/App.js
+++ b/frontend/src/App.js
@@ -1,4 +1,6 @@
-import React, { useState } from 'react';
+import React, { useRef, useState } from 'react';
+import { renderToString } from 'react-dom/server';
+import { ReactSVG } from 'react-svg';
import { Button, TextField, Box, CircularProgress, AppBar, Toolbar, Typography, Container, Grid, Paper, Link, IconButton } from '@mui/material';
import LinkedInIcon from '@mui/icons-material/LinkedIn';
import TwitterIcon from '@mui/icons-material/Twitter';
@@ -41,17 +43,18 @@ function App() {
const [description, setDescription] = useState('');
const [isLoading, setIsLoading] = useState(false);
const [svgData, setSvgData] = useState(null);
+ const svgRef = useRef(null);
const handleDesignClick = async () => {
setIsLoading(true);
try {
- const response = await axios.post('/call_prompt',
+ const response = await axios.post('/call_prompt',
{
input: description,
},
{
- headers: {"Content-Type": "application/json"},
+ headers: { "Content-Type": "application/json" },
redirect: 'follow'
}
);
@@ -66,9 +69,28 @@ function App() {
};
// Creating a Blob from SVG data
- const svgBlob = new Blob([svgData], {type: 'image/svg+xml;charset=utf-8'});
+ const svgBlob = new Blob([svgData], { type: 'image/svg+xml;charset=utf-8' });
const svgUrl = URL.createObjectURL(svgBlob);
+ const downloadPNG = () => {
+ const svgString = renderToString(svgRef.current);
+ const canvas = document.createElement('canvas');
+ const ctx = canvas.getContext('2d');
+ const img = new Image();
+
+ img.src = `data:image/svg+xml;base64,${btoa(svgString)}`;
+ img.onload = () => {
+ canvas.width = img.width;
+ canvas.height = img.height;
+ ctx.drawImage(img, 0, 0);
+ const pngUrl = canvas.toDataURL();
+ const link = document.createElement('a');
+ link.href = pngUrl;
+ link.download = 'diagram.png';
+ link.click();
+ };
+ };
+
return (
- {isLoading ? : }
+ {isLoading ? : }
@@ -121,9 +143,14 @@ function App() {
{!isLoading && svgData && (
-
- Download Diagram
-
+ <>
+
+ Download Diagram (SVG)
+
+
+ >
)}