rosh
4 years ago
8 changed files with 442 additions and 0 deletions
@ -0,0 +1,11 @@ |
|||
|
|||
|
|||
@import url('https://fonts.googleapis.com/css?family=Josefin+Sans'); |
|||
|
|||
body { |
|||
font-family: 'Inter'; |
|||
} |
|||
|
|||
:root { |
|||
font-family: 'Inter'; |
|||
} |
@ -0,0 +1,239 @@ |
|||
import React from 'react'; |
|||
import { css } from "emotion"; |
|||
import { useState } from 'react'; |
|||
import './App.css'; |
|||
|
|||
|
|||
const wrapper = css` |
|||
display: flex; |
|||
width:100%; |
|||
|
|||
`;
|
|||
const leftpane = css` |
|||
width:50% |
|||
|
|||
`;
|
|||
|
|||
const input1 = css` |
|||
|
|||
|
|||
`;
|
|||
|
|||
const imageupload = css` |
|||
|
|||
|
|||
`;
|
|||
|
|||
const textarea1 = css` |
|||
|
|||
|
|||
`;
|
|||
|
|||
const fieldarea = css` |
|||
|
|||
|
|||
`;
|
|||
|
|||
const buttontextarea = css` |
|||
|
|||
`;
|
|||
|
|||
const rightpane = css` |
|||
padding-left:20px; |
|||
width:50%; |
|||
|
|||
`;
|
|||
|
|||
const imageright = css` |
|||
width: 100%; |
|||
height:600px; |
|||
overflow: hidden; |
|||
|
|||
`;
|
|||
|
|||
const imageright1 = css` |
|||
width: 100%; |
|||
height:600px; |
|||
overflow: hidden; |
|||
|
|||
`;
|
|||
|
|||
const image = css` |
|||
width: 100%; |
|||
|
|||
|
|||
`;
|
|||
|
|||
const titleinput0 = css` |
|||
|
|||
|
|||
`;
|
|||
|
|||
const textarearight0 = css` |
|||
|
|||
|
|||
`;
|
|||
|
|||
|
|||
const titleinput = css` |
|||
|
|||
|
|||
`;
|
|||
|
|||
const textarearight = css` |
|||
|
|||
|
|||
`;
|
|||
|
|||
function App() { |
|||
const [file, setFile] = React.useState(null); |
|||
const [fields, setFields] = useState([{ value: null }]); |
|||
const [input, setInput] = useState(""); |
|||
const [textarea, setTextarea] = useState(""); |
|||
const [fields1, setFields1] = useState([{ value: null }]); |
|||
const [selectb, setSelectb] = useState('InputField'); |
|||
|
|||
const addFields = e =>{ |
|||
const values = [...fields]; |
|||
values.push({ value: null, type:selectb }); |
|||
setFields(values); |
|||
}; |
|||
|
|||
const handleRemove = i => { |
|||
const values = [...fields]; |
|||
values.splice(i, 1); |
|||
setFields(values); |
|||
}; |
|||
|
|||
const updateInputChanged = idx => e => { |
|||
|
|||
|
|||
let newArr = [...fields]; |
|||
newArr[idx].value = e.target.value; |
|||
|
|||
setFields(newArr); |
|||
}; |
|||
|
|||
const updateFieldChanged = idx => e => { |
|||
|
|||
|
|||
let newArr = [...fields1]; |
|||
newArr[idx].value = e.target.value; |
|||
|
|||
setFields1(newArr); |
|||
}; |
|||
|
|||
function handleChange(e) { |
|||
setSelectb(e.target.value); |
|||
} |
|||
|
|||
|
|||
return ( |
|||
|
|||
<div className={wrapper}> |
|||
|
|||
<div className={leftpane}> |
|||
|
|||
<div className={input1}> |
|||
|
|||
<input type="text" id="title" onChange={e => setInput(e.target.value)} name="title"/> |
|||
</div><br></br> |
|||
<div className={imageupload}> |
|||
<input type="file" id="img" onChange={e => setFile(e.target.files[0])} name="img" accept="image/*"/> |
|||
</div><br></br> |
|||
<div className={textarea1}> |
|||
<textarea |
|||
id="textarea1" |
|||
name="textarea1" |
|||
rows="10" |
|||
cols="90" |
|||
onChange={e =>setTextarea(e.target.value)}/> |
|||
</div><br></br> |
|||
<div className={fieldarea}> |
|||
{fields.map((field, idx) => { |
|||
return ( |
|||
|
|||
<div key={`${field}-${idx}`}> |
|||
|
|||
{field.type ==="InputField"? <div> <input type="text" id="title" onChange={updateInputChanged(idx)} name="title"/><button type="button" onClick={() => handleRemove(idx)}> |
|||
Delete |
|||
</button></div> |
|||
:field.type ==="ImgUpload"? <div> <input type="file" id="img" onChange={updateFieldChanged(idx)} name="img" accept="image/*"/><button type="button" onClick={() => handleRemove(idx)}> |
|||
Delete |
|||
</button> </div> |
|||
:field.type === "Textarea"? <div><textarea |
|||
id="textarea2" |
|||
name="textarea2" |
|||
rows="10" |
|||
cols="90" |
|||
onChange={updateFieldChanged(idx)} |
|||
/><button type="button" onClick={() => handleRemove(idx)}> |
|||
Delete |
|||
</button></div>:"" |
|||
} |
|||
|
|||
</div> |
|||
); |
|||
})} |
|||
</div> |
|||
<div className={buttontextarea}> |
|||
<select value={selectb} onChange={handleChange}> |
|||
<option value="InputField">Input Field</option> |
|||
<option value="ImgUpload">Image upload</option> |
|||
<option value="Textarea">Textarea</option> |
|||
</select> |
|||
<button type="button" onClick={addFields}>Add</button> |
|||
</div> |
|||
|
|||
|
|||
|
|||
</div> |
|||
|
|||
<div className={rightpane}> |
|||
<div className={imageright}> |
|||
<img src={file? URL.createObjectURL(file) : null} className={image} ></img> |
|||
</div> |
|||
<div className={imageright1}> |
|||
{fields.map((field, idx) => { |
|||
return ( |
|||
<div key={`${field}-${idx}`}> |
|||
<img src={field.value? URL.createObjectURL(field.value) : null} className={image} ></img> |
|||
</div> |
|||
|
|||
); |
|||
})} </div> |
|||
<div className={titleinput0}> |
|||
<h1>{input}</h1> |
|||
</div> |
|||
|
|||
<div className={titleinput}> |
|||
{fields.map((field, idx) => { |
|||
return ( |
|||
<div key={`${field}-${idx}`}> |
|||
|
|||
<h1>{field.value}</h1> |
|||
</div> |
|||
|
|||
); |
|||
})} |
|||
</div> |
|||
<div className={textarearight0}> |
|||
{textarea} |
|||
</div> |
|||
<div className={textarearight}> |
|||
{fields1.map((field1, idx) => { |
|||
return ( |
|||
<div key={`${field1}-${idx}`}> |
|||
|
|||
{field1.value} |
|||
</div> |
|||
|
|||
); |
|||
})} |
|||
</div> |
|||
</div> |
|||
</div> |
|||
); |
|||
} |
|||
|
|||
export default App; |
@ -0,0 +1,9 @@ |
|||
import React from 'react'; |
|||
import { render } from '@testing-library/react'; |
|||
import App from './App'; |
|||
|
|||
test('renders learn react link', () => { |
|||
const { getByText } = render(<App />); |
|||
const linkElement = getByText(/learn react/i); |
|||
expect(linkElement).toBeInTheDocument(); |
|||
}); |
@ -0,0 +1,13 @@ |
|||
body { |
|||
margin: 0; |
|||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen', |
|||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue', |
|||
sans-serif; |
|||
-webkit-font-smoothing: antialiased; |
|||
-moz-osx-font-smoothing: grayscale; |
|||
} |
|||
|
|||
code { |
|||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New', |
|||
monospace; |
|||
} |
@ -0,0 +1,17 @@ |
|||
import React from 'react'; |
|||
import ReactDOM from 'react-dom'; |
|||
import './index.css'; |
|||
import App from './App'; |
|||
import * as serviceWorker from './serviceWorker'; |
|||
|
|||
ReactDOM.render( |
|||
<React.StrictMode> |
|||
<App /> |
|||
</React.StrictMode>, |
|||
document.getElementById('root') |
|||
); |
|||
|
|||
// If you want your app to work offline and load faster, you can change
|
|||
// unregister() to register() below. Note this comes with some pitfalls.
|
|||
// Learn more about service workers: https://bit.ly/CRA-PWA
|
|||
serviceWorker.unregister(); |
After Width: | Height: | Size: 2.6 KiB |
@ -0,0 +1,141 @@ |
|||
// This optional code is used to register a service worker.
|
|||
// register() is not called by default.
|
|||
|
|||
// This lets the app load faster on subsequent visits in production, and gives
|
|||
// it offline capabilities. However, it also means that developers (and users)
|
|||
// will only see deployed updates on subsequent visits to a page, after all the
|
|||
// existing tabs open on the page have been closed, since previously cached
|
|||
// resources are updated in the background.
|
|||
|
|||
// To learn more about the benefits of this model and instructions on how to
|
|||
// opt-in, read https://bit.ly/CRA-PWA
|
|||
|
|||
const isLocalhost = Boolean( |
|||
window.location.hostname === 'localhost' || |
|||
// [::1] is the IPv6 localhost address.
|
|||
window.location.hostname === '[::1]' || |
|||
// 127.0.0.0/8 are considered localhost for IPv4.
|
|||
window.location.hostname.match( |
|||
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/ |
|||
) |
|||
); |
|||
|
|||
export function register(config) { |
|||
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) { |
|||
// The URL constructor is available in all browsers that support SW.
|
|||
const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href); |
|||
if (publicUrl.origin !== window.location.origin) { |
|||
// Our service worker won't work if PUBLIC_URL is on a different origin
|
|||
// from what our page is served on. This might happen if a CDN is used to
|
|||
// serve assets; see https://github.com/facebook/create-react-app/issues/2374
|
|||
return; |
|||
} |
|||
|
|||
window.addEventListener('load', () => { |
|||
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`; |
|||
|
|||
if (isLocalhost) { |
|||
// This is running on localhost. Let's check if a service worker still exists or not.
|
|||
checkValidServiceWorker(swUrl, config); |
|||
|
|||
// Add some additional logging to localhost, pointing developers to the
|
|||
// service worker/PWA documentation.
|
|||
navigator.serviceWorker.ready.then(() => { |
|||
console.log( |
|||
'This web app is being served cache-first by a service ' + |
|||
'worker. To learn more, visit https://bit.ly/CRA-PWA' |
|||
); |
|||
}); |
|||
} else { |
|||
// Is not localhost. Just register service worker
|
|||
registerValidSW(swUrl, config); |
|||
} |
|||
}); |
|||
} |
|||
} |
|||
|
|||
function registerValidSW(swUrl, config) { |
|||
navigator.serviceWorker |
|||
.register(swUrl) |
|||
.then(registration => { |
|||
registration.onupdatefound = () => { |
|||
const installingWorker = registration.installing; |
|||
if (installingWorker == null) { |
|||
return; |
|||
} |
|||
installingWorker.onstatechange = () => { |
|||
if (installingWorker.state === 'installed') { |
|||
if (navigator.serviceWorker.controller) { |
|||
// At this point, the updated precached content has been fetched,
|
|||
// but the previous service worker will still serve the older
|
|||
// content until all client tabs are closed.
|
|||
console.log( |
|||
'New content is available and will be used when all ' + |
|||
'tabs for this page are closed. See https://bit.ly/CRA-PWA.' |
|||
); |
|||
|
|||
// Execute callback
|
|||
if (config && config.onUpdate) { |
|||
config.onUpdate(registration); |
|||
} |
|||
} else { |
|||
// At this point, everything has been precached.
|
|||
// It's the perfect time to display a
|
|||
// "Content is cached for offline use." message.
|
|||
console.log('Content is cached for offline use.'); |
|||
|
|||
// Execute callback
|
|||
if (config && config.onSuccess) { |
|||
config.onSuccess(registration); |
|||
} |
|||
} |
|||
} |
|||
}; |
|||
}; |
|||
}) |
|||
.catch(error => { |
|||
console.error('Error during service worker registration:', error); |
|||
}); |
|||
} |
|||
|
|||
function checkValidServiceWorker(swUrl, config) { |
|||
// Check if the service worker can be found. If it can't reload the page.
|
|||
fetch(swUrl, { |
|||
headers: { 'Service-Worker': 'script' }, |
|||
}) |
|||
.then(response => { |
|||
// Ensure service worker exists, and that we really are getting a JS file.
|
|||
const contentType = response.headers.get('content-type'); |
|||
if ( |
|||
response.status === 404 || |
|||
(contentType != null && contentType.indexOf('javascript') === -1) |
|||
) { |
|||
// No service worker found. Probably a different app. Reload the page.
|
|||
navigator.serviceWorker.ready.then(registration => { |
|||
registration.unregister().then(() => { |
|||
window.location.reload(); |
|||
}); |
|||
}); |
|||
} else { |
|||
// Service worker found. Proceed as normal.
|
|||
registerValidSW(swUrl, config); |
|||
} |
|||
}) |
|||
.catch(() => { |
|||
console.log( |
|||
'No internet connection found. App is running in offline mode.' |
|||
); |
|||
}); |
|||
} |
|||
|
|||
export function unregister() { |
|||
if ('serviceWorker' in navigator) { |
|||
navigator.serviceWorker.ready |
|||
.then(registration => { |
|||
registration.unregister(); |
|||
}) |
|||
.catch(error => { |
|||
console.error(error.message); |
|||
}); |
|||
} |
|||
} |
@ -0,0 +1,5 @@ |
|||
// jest-dom adds custom jest matchers for asserting on DOM nodes.
|
|||
// allows you to do things like:
|
|||
// expect(element).toHaveTextContent(/react/i)
|
|||
// learn more: https://github.com/testing-library/jest-dom
|
|||
import '@testing-library/jest-dom/extend-expect'; |
Loading…
Reference in new issue