project.js 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155
  1. import { useEffect } from "react";
  2. import { useState } from "react";
  3. import { connect } from "react-redux";
  4. import { Redirect } from "react-router";
  5. import { Link } from "react-router-dom";
  6. import { actionSnippetById } from "../actions/actionSnippetById";
  7. import Editor from "../components/editor";
  8. import { actionSnippetAdd } from "../actions/actionSnippetAdd";
  9. import {sortableContainer, sortableElement, arrayMove} from 'react-sortable-hoc';
  10. const ProjectSnippet = ({onSave, getSnippet, match:{params:{id},}, titleText, descriptionText, filesArr, nameText,}) => {
  11. useEffect(() => {
  12. getSnippet(id);
  13. }, []);
  14. const [files, setFiles] = useState([]);
  15. const [name, setName] = useState("");
  16. const [title, setTitle] = useState("");
  17. const [description, setDescription] = useState("");
  18. useEffect(() => {
  19. setFiles(filesArr);
  20. setTitle(titleText);
  21. setDescription(descriptionText);
  22. }, [filesArr, titleText, descriptionText]);
  23. const [srcDoc, setSrcDoc] = useState("");
  24. const html = files?.filter((el) => {
  25. return el?.type === "html";
  26. })[0]?.text;
  27. const css = files?.filter((el) => {
  28. return el?.type === "css";
  29. })[0]?.text;
  30. const js = files?.filter((el) => {
  31. return el?.type === "javascript";
  32. })[0]?.text;
  33. console.log(files);
  34. useEffect(() => {
  35. const timeout = setTimeout(() => {
  36. setSrcDoc(`
  37. <html>
  38. <body>${html || ""}</body>
  39. <style>${css}</style>
  40. <script>${js}</script>
  41. </html>
  42. `);
  43. }, 250);
  44. return () => clearTimeout(timeout);
  45. }, [html, css, js]);
  46. const SortableItem = sortableElement(({value, index}) => {
  47. console.log(value);
  48. return (
  49. <span>{value.name || "new edit"}&nbsp; </span>
  50. )
  51. })
  52. const SortableList = sortableContainer(({items})=>{
  53. //console.log(items)
  54. return(
  55. <div>
  56. {items?.map((value, index) => (
  57. <SortableItem value={value} index={index} />
  58. ))
  59. }
  60. </div>
  61. )
  62. })
  63. const onSortEnd = ({oldIndex, newIndex}) => {
  64. let arr = arrayMove(filesArr, oldIndex, newIndex);
  65. setFiles(arr)
  66. }
  67. return (
  68. <div>
  69. <Link to="/">
  70. <button className="float-left btn-secondary d-inline-block mt-2 ml-2">
  71. <span>&#8617;</span> Back to Main Page
  72. </button>
  73. </Link>
  74. <Link to="/projects" style={{}}>
  75. <button className="float-right btn btn-outline-info border-info mt-2 mr-2">
  76. All projects
  77. </button>
  78. </Link>
  79. <br/>
  80. <div>
  81. <h3 style={{marginTop:'30px', marginLeft: "20px"}}><u>Name of this project:</u> &nbsp; <i>{title}</i></h3>
  82. <iframe srcDoc={srcDoc} title="output" sandbox="allow-scripts" frameBorder="0" width="95%" height="100%"
  83. style={{height: "280px", marginLeft: "2%",marginTop: "40px", border: "5px solid green"}}/>
  84. <div style={{marginTop:"20px", textAlign:'center'}}>
  85. <p onClick={()=>console.log(files)}><b>Click here </b><span>to reverse the snippets</span></p>
  86. <SortableList items={files} onSortEnd={onSortEnd} />
  87. </div>
  88. {files?.map((data, index) => (
  89. <>
  90. <Editor onDelete={() => setFiles(files?.filter((item) => item !== data))} data={data}
  91. onChange={({type, name, text}) => setFiles([...files.slice(0, index), {type, name, text}, ...files.slice(index + 1),])}
  92. />
  93. </>
  94. ))}
  95. </div>
  96. <br />
  97. <div style={{alignItems: "center", textAlign: "center", marginBottom: "10px"}}>
  98. <div>
  99. <button className="btn btn-primary" onClick={() => setFiles([...files, {type: "html"}])} key={files}>
  100. Add editor
  101. </button>
  102. </div>
  103. <div className="input-group mb-3 mt-5 ml-auto mr-auto w-50">
  104. <div className="input-group-prepend">
  105. <span className="input-group-text" id="basic-addon1">
  106. Name of your project
  107. </span>
  108. </div>
  109. <input value={title} onChange={(e) => setTitle(e.target.value)} type="text" className="form-control"
  110. placeholder="Name of project" aria-label="Name of project" aria-describedby="basic-addon1"/>
  111. </div>
  112. <div className="input-group ml-auto mr-auto w-50">
  113. <div className="input-group-prepend">
  114. <span className="input-group-text ">Description</span>
  115. </div>
  116. <textarea value={description} onChange={(e) => setDescription(e.target.value)} className="form-control "
  117. aria-label="With textarea" placeholder="Your description"></textarea>
  118. </div>
  119. <button className="btn btn-success float-center mt-5 mb-5" onClick={() => onSave(title, description, files, id)}>
  120. Save project
  121. </button>
  122. </div>
  123. </div>
  124. );
  125. };
  126. const ConnectedProject = connect(
  127. (state) => ({
  128. titleText: state?.promise?.findSnippetById?.payload?.data?.SnippetFind?.[0]?.title,
  129. descriptionText: state?.promise?.findSnippetById?.payload?.data?.SnippetFind?.[0]?.description,
  130. nameText: state?.promise?.findSnippetById?.payload?.data?.SnippetFind?.[0]?.name,
  131. filesArr: state?.promise?.findSnippetById?.payload?.data?.SnippetFind?.[0]?.files,
  132. }),
  133. {getSnippet: actionSnippetById, onSave: actionSnippetAdd}
  134. )(ProjectSnippet);
  135. export default ConnectedProject;