auto-component 0.0.33 → 0.0.35

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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "auto-component",
3
- "version": "0.0.33",
3
+ "version": "0.0.35",
4
4
  "main": "src/index.jsx",
5
5
  "peerDependencies": {
6
6
  "react": "^18.2.0",
@@ -1,28 +1,22 @@
1
- #auto-component {
1
+ #content-creator {
2
+ position: relative;
2
3
  width: 100%;
3
4
  display: flex;
4
5
  flex-direction: column;
5
6
  align-items: center;
7
+ margin: 40px 0;
6
8
  font-family: Arial, Helvetica, sans-serif
7
9
  }
8
- #auto-component-entry {
9
- position: fixed;
10
- bottom: 100px;
11
- left: 50%;
12
- transform: translateX(-50%);
13
- width: 90%;
14
- max-width: 700px;
10
+ #content-creator div {
11
+ width: 100%;
15
12
  display: flex;
16
13
  flex-direction: row;
17
14
  justify-content: center;
18
15
  align-items: center;
19
- padding: 0 20px;
20
- background: #222;
21
- border-radius: 10px;
22
- border: 2px solid rgb(108, 108, 246);
16
+
23
17
  }
24
- #auto-component input {
25
- width: 100%;
18
+ #content-creator input {
19
+ width: 60%;
26
20
  height: 40px;
27
21
  border-radius: 5px;
28
22
  color: #444;
@@ -30,7 +24,7 @@
30
24
  border: 3px solid #ddd;
31
25
  padding-left: 10px;
32
26
  }
33
- #auto-component button {
27
+ #content-creator button {
34
28
  padding: 10px;
35
29
  margin: 20px;
36
30
  background: rgb(184, 230, 184);
@@ -38,36 +32,29 @@
38
32
  border-radius: 5px;
39
33
  box-shadow: 0px 0px 5px #fff;
40
34
  }
41
- #auto-component button:nth-child(3) {
35
+ #content-creator button:nth-child(3) {
42
36
  padding: 10px 20px;
43
37
  margin-left: 0px;
44
38
  margin-right: 0px;
45
39
  background: #db9d9d;
46
40
  }
47
- #auto-component button:hover {
41
+ #content-creator button:hover {
48
42
  background: green;
49
43
  color: #eee;
50
44
  }
51
- #auto-component button:nth-child(3):hover {
45
+ #content-creator button:nth-child(3):hover {
52
46
  background: #dc3c3c;
53
47
  }
54
- #auto-component-tabs {
55
- position: fixed;
56
- bottom: 68px;
57
- left: 50%;
58
- transform: translateX(-50%);
48
+ #content-creator div:nth-child(2) {
59
49
  display: flex;
60
- flex-direction: row;
61
- width: 100%;
62
- max-width: 700px;
50
+ flex-direction: column;
63
51
  }
64
52
  .tab {
65
- width: 30%;
66
53
  margin: 0 10%;
67
54
  padding: 4px 0;
68
- background: #c6c7d3;
69
- color: #fff;
70
- border-radius: 0 0 5px 5px;
55
+ background: #444;
56
+ color: #aaa;
57
+ border-radius: 5px 5px 0 0;
71
58
  cursor: pointer;
72
59
  }
73
60
  .tab:hover {
@@ -75,20 +62,17 @@
75
62
  color: #eee;
76
63
  }
77
64
  .selected {
78
- background: #444;
79
- color: #aaa;
65
+ background: #c6c7d3;
66
+ color: #fff;
80
67
  font-size: 1.2rem;
68
+ pointer-events: none;
81
69
  }
82
- #auto-component-code {
83
- position: fixed;
84
- bottom: 180px;
85
- left: 50%;
86
- transform: translateX(-50%);
70
+ #content-creator pre {
71
+ position: relative;
87
72
  text-align: left;
88
- max-width: 600px;
89
- width: 80%;
90
- max-height: 300px;
91
- min-height: 300px;
73
+ max-width: 90%;
74
+ min-width: 90%;
75
+ max-height: 60vh;
92
76
  background: #cdd1d9;
93
77
  color: #111;
94
78
  padding: 40px 10px 40px 10px;
@@ -98,7 +82,7 @@
98
82
  box-shadow: 0px 0px 5px #fff;
99
83
  white-space: pre-wrap;
100
84
  }
101
- .auto-component-copy {
85
+ .copy-btn {
102
86
  position: absolute;
103
87
  top: 130px;
104
88
  right: 7%;
@@ -111,9 +95,6 @@
111
95
  color: #fff;
112
96
  }
113
97
 
114
- .auto-component-copy:hover {
98
+ .copy-btn:hover {
115
99
  background: #666;
116
- }
117
- .hidden {
118
- display: none;
119
100
  }
package/src/index.jsx CHANGED
@@ -1,66 +1,243 @@
1
- import {useState, useEffect} from 'react'
2
- import { Link } from 'react-router-dom'
3
- import { getPeople } from '../../utilities/people-service'
4
- import './People.css'
5
- import NewPersonForm from './NewPersonForm'
6
- import AutoComponent from '../../components/Componenter'
1
+ import { useState, useEffect } from 'react'
2
+ // import beautify from 'js-beautify';
3
+ import './auto-component.css'
7
4
 
8
- const People = () => {
9
- const [isLoading, setIsLoading] = useState(true)
10
- const [people, setPeople] = useState([])
5
+ const AutoComponent = ({ exclusions }) => {
11
6
 
7
+ //**-----------**/
8
+ // ** State ** //
9
+ //**---------**/
10
+ const [ currentHtml, setHtml ] = useState('')
11
+ const [ currentStyle, setStyles ] = useState('')
12
+ const [ currentRequest, setRequest ] = useState('')
13
+ const [ user, setUser ] = useState('')
14
+
15
+ const [ responseData, setResponseData ] = useState(null)
16
+ const [ requestData, setRequestData ] = useState(null)
17
+
18
+ const [ activeTab, setActiveTab ] = useState('request')
19
+ const [ history, setHistory ] = useState(["No History"])
20
+
21
+ //**-------------------------**/
22
+ // ** HTML/CSS Formatting ** //
23
+ //**-----------------------**/
24
+ // get the html/style for the current page and set state
25
+ const htmlContent = () => {
26
+ const body = document.querySelector('body')
27
+ const htmlContent = body ? body.innerHTML : ''
28
+ const cssStyles = document.documentElement.innerHTML
29
+
30
+ const cleanedHtml = cleanExclusions(htmlContent, exclusions)
31
+ const cleanedStyles = cleanStyles(cssStyles)
32
+
33
+ setHtml(cleanedHtml)
34
+ setStyles(cleanedStyles)
35
+ }
36
+
37
+ // format html for display (breaks/indentation)
38
+ // const formatHtml = (html) => {
39
+ // return beautify.html(html, {
40
+ // indent_size: 2,
41
+ // wrap_line_length: 80,
42
+ // max_preserve_newlines: 1,
43
+ // })
44
+ // }
45
+
46
+ // clean html of exclusions:
47
+ // if an element className includes 'exclude'
48
+ // (partial) the element wrapper remains, but contents removed
49
+ // OR, (full) the element and it's content are excluded from output
50
+
51
+ // partial exclusion
52
+ const cleanExclusions = (html) => {
53
+ const regexExcludeClass = /(<[^>]*\sclass\s*=\s*['"]([^'"]*exclude[^'"]*)['"][^>]*>)[\s\S]*?(<\/[^>]*>)/g;
54
+ const cleanedHtml = html.replace(regexExcludeClass, '$1$3');
55
+ const scriptIndex = cleanedHtml.lastIndexOf('<script');
56
+
57
+ // return formatHtml(cleanedHtml.substring(0, scriptIndex));
58
+ return cleanedHtml.substring(0, scriptIndex);
59
+ };
60
+
61
+ // full exclusion
62
+ // const cleanExclusionsFull = (html) => {
63
+ // const regexExcludeClass = /<[^>]*\sclass\s*=\s*['"]([^'"]*exclude[^'"]*)['"][^>]*>[\s\S]*?<\/[^>]*>/g
64
+ // const cleanedHtml = html.replace(regexExcludeClass, '')
65
+ // const scriptIndex = cleanedHtml.lastIndexOf('<script')
66
+ //
67
+ // return formatHtml(cleanedHtml.substring(0, scriptIndex))
68
+ // }
69
+
70
+ // exclude non <style> data and remove comments
71
+ const cleanStyles = (css) => {
72
+ const styleRegex = /<style\b[^>]*>(.*?)<\/style>/gs
73
+ const matches = css.match(styleRegex)
74
+
75
+ if (matches) {
76
+ const cleanedMatches = matches.map(match => match.replace(/\/\*[\s\S]*?\*\//g, ''))
77
+ return cleanedMatches
78
+ }
79
+ return null
80
+ }
81
+
82
+ const randomUser = () => {
83
+ setUser(Math.floor(Math.random()*100000))
84
+ }
85
+
86
+ useEffect(() => {
87
+ htmlContent()
88
+ randomUser()
89
+ }, [])
90
+
91
+ //**---------------------------**/
92
+ // ** API Requests/Response ** //
93
+ //**-------------------------**/
94
+
95
+ // TEMP FUNCTION FOR TESTING
96
+ // const sendRequest = (data) => {
97
+ // return(response)
98
+ // }
99
+
100
+ const sendRequest = async () => {
101
+ const url = "https://server-auto-component-46830ff262f8.herokuapp.com/api";
102
+
103
+ try {
104
+ const res = await fetch(url, {
105
+ method: 'POST',
106
+ headers: {
107
+ 'Content-Type': 'application/json',
108
+ },
109
+ body: JSON.stringify(requestData),
110
+ });
111
+
112
+ if (res.ok) {
113
+ const jsonData = await res.json();
114
+ return jsonData;
115
+ } else {
116
+ throw new Error("Invalid request!");
117
+ }
118
+ } catch (err) {
119
+ console.log(err.message);
120
+ }
121
+ };
122
+
123
+ // make API request with updated state data
12
124
  const handleRequest = async () => {
13
125
  try {
14
- const peopleData = await getPeople()
15
- if (peopleData) setPeople(peopleData)
126
+ const resData = await sendRequest();
127
+
128
+ if (resData) {
129
+ setHistory(resData.history)
130
+ // setResponseData(formatHtml(resData.response.content));
131
+ setResponseData(resData.response.content);
132
+ setActiveTab('response');
133
+ }
16
134
  } catch (err) {
17
- console.log(err)
135
+ console.log(err);
18
136
  }
19
- setIsLoading(false)
137
+ // setIsLoading(false);
138
+ };
139
+
140
+ //**------------------------**/
141
+ // ** UI/Button Handling ** //
142
+ //**----------------------**/
143
+
144
+ const handleChange = (e) => {
145
+ e.preventDefault()
146
+ setRequest(e.target.value)
147
+ }
148
+
149
+ const handleGenerate = async (e) => {
150
+ await setRequestData({
151
+ "userId": user,
152
+ "request": currentRequest,
153
+ "html": currentHtml
154
+ })
20
155
  }
21
156
 
22
157
  useEffect(() => {
23
- handleRequest()
24
- }, [])
158
+ if (requestData !== null) {
159
+ handleRequest();
160
+ }
161
+ },[requestData])
162
+
163
+ const handleReset = () => {
164
+ setRequest('')
165
+ setResponseData('')
166
+ randomUser()
167
+ setHistory([])
168
+ }
25
169
 
170
+ const handleRequestTab = () => {
171
+ setActiveTab('request')
172
+ }
173
+ const handleResponseTab = () => {
174
+ setActiveTab('response')
175
+ }
26
176
 
27
- if (isLoading) {
28
- return <h1>Loading...</h1>;
29
- } else {
177
+ const copyToClipboard = async () => {
178
+ const text = activeTab === 'response' ? responseData : requestData
179
+ await navigator.clipboard.writeText(text)
180
+ }
181
+
182
+ //**---------------**/
183
+ // ** Rendering ** //
184
+ //**-------------**/
185
+
186
+ const getLog = () => {
30
187
  return (
31
- <section>
32
- {/* <NewPersonForm handleRequest={handleRequest} /> */}
188
+ history.map((entry, index) => (
189
+
190
+ index !== 0 && entry.content.split('HTML Context:')[0] + (entry.content.includes("User Request") ? '\n' : '\n\n\n')
191
+ )
192
+ ))
193
+ }
33
194
 
34
- <div id="secret-element" className='secret secret-element'>
35
- this is the excluded text
36
- <div className='something'>
37
- and this is the excluded element
38
- </div>
39
- </div>
195
+ const requestHTML = currentHtml ? (
196
+ `Review the details below for accuracy and privacy concerns.
197
+ If the contents of an element should be excluded, add the 'exclude' class to the element.
198
+ Click Generate to send the request and receive the auto component AI generated code.
40
199
 
41
- <div id="not-secret-element" className=''>
42
- included
43
- </div>
200
+ User ID:\n `
201
+ + user
202
+ + "\n\nUser Request:\n"
203
+ + currentRequest
204
+ + "\n\nUser HTML:\n"
205
+ + currentHtml
206
+ ) : 'There was an error collecting your HTML. Ensure no top level elements are assigned the class "exclude"'
207
+
208
+ const responseHtml = responseData ? (
209
+ responseData
210
+ ) : 'No response has been generated'
44
211
 
45
- <div className="people-list">
46
- {people.map((p) => (
47
- <Link to={"/people/" + p._id}>
48
- <div key={p._id}>
49
- <h3>{p.name}</h3>
50
- <img
51
- className="profile-image"
52
- src={p.image}
53
- alt={`Image of ${p.name}`}
54
- />
55
- <p>{p.title}</p>
56
- </div>
57
- </Link>
58
- ))}
212
+
213
+ return (
214
+ <>
215
+ {/* create the display window */}
216
+ <div id="auto-component">
217
+ <div>
218
+ <input type="text" value={currentRequest} onChange={handleChange} placeholder="Enter a request"></input>
219
+ <button onClick={handleGenerate}>Generate</button>
220
+ <button onClick={handleReset}>X</button>
59
221
  </div>
60
- <AutoComponent />
61
- </section>
62
- );
63
- }
222
+ <div>
223
+ <div>
224
+ <div className={`${activeTab === 'request' ? 'selected' : ''} tab`} onClick={handleRequestTab}>
225
+ Request
226
+ </div>
227
+ <div className={`${activeTab === 'response' ? 'selected' : ''} tab`} onClick={handleResponseTab}>
228
+ Response
229
+ </div>
230
+ </div>
231
+ <pre>
232
+ {activeTab === 'request' ? getLog() : responseHtml}
233
+ </pre>
234
+ </div>
235
+ <div className="copy-btn" onClick={copyToClipboard} style={activeTab !== 'response' ? { display: 'none' } : null}>
236
+ copy
237
+ </div>
238
+ </div>
239
+ </>
240
+ )
64
241
  }
65
242
 
66
- export default People
243
+ export default AutoComponent