Allow uses to adjust the position of their profile pictures - javascript

I am building a website and want to include the feature that allows users to adjust the position of their profile picture when uploading (which part of the picture gets displayed by the "img" element). LinkedIn, for example, has this feature. I searched about how to implement the feature but did not find anything helpful. The code below is what I have right now: After the user selects a image file, it will be uploaded to firebase storage, then the web page will be re-rendered and the new image will be displayed on the web page. I am wondering whether anyone can give me a clue about how to add the feature to my existing code. Thanks!
Client-side code that lets users upload profile images
state = {
image: "",
edit: false
}
componentDidMount() {
const { profile } = this.props;
this.setState({
image: profile.image
})
}
......
handleUpload = (e) => {
e.preventDefault();
const image = e.target.files[0];
const { auth } = this.props;
this.props.uploadImage(image, auth.uid);
}
openFiles = (e) => {
e.preventDefault();
const input = document.getElementById("imageinput");
input.click();
}
......
render() {
return (
......
<img src={this.state.image ? this.state.image : ditto}></img>
<input type="file" id="imageinput" hidden="hidden" onChange={this.handleUpload}></input>
<button onClick={this.openFiles}>Upload Profile Image</button>
......
Redux uploadImage action object
export const uploadImage = ( image, userid ) => (dispatch) => {
firebase.storage().ref('images/'+userid).put(image)
.then(() => {
return firebase.storage().ref(`images/`+userid).getDownloadURL()
})
.then((image) => {
firebase.firestore().collection("users").doc(userid).update({
image: image
})
}).then(() => {
dispatch({ type: EDIT_SUCCESS });
})
}

Related

Link upload image with content with strapi api in reactjs

I try to use strapi for the first time with react and I can't understand how I can link upload (in strapi) image to my content, I know how upload, I know how post something but I don't know how link this. I readed a lot of times strapi documentation but I can't understand.
My code
function ProductCreateApi({ evtId }) {
const [image, setImage] = useState(null)
const [posts, setPosts] = useState([])
const [updatesData, setUpdatesData] = useState({
titleproductgroup: "",
})
function updateEdit(e) {
const newupdate = { ...updatesData }
newupdate[e.target.id] = e.target.value
setUpdatesData(newupdate)
console.log(newupdate)
}
const handleSubmit = async (e) => {
console.log('handleSubmit')
e.preventDefault()
const formData = new FormData()
formData.append('files', image) // the pic
formData.append('ref', 'api::product-group.product-group') // link with my table
formData.append('refId', evtId)
formData.append('field', 'picproductgroup') // the row
axios.post('http://localhost:1337/api/upload/', formData)
e.preventDefault()
const res = axios.post(`http://localhost:1337/api/product-groups/`, {
"data": {
titleproductgroup: updatesData.titleproductgroup
}
})
if (res.ok) {
console.log('res.ok')
console.log('res', res)
// imageUploaded()
}
}
const handleFileChange = (e) => {
console.log('handleFileChange')
console.log(e.target.files[0]) //this will give us an array and we want the first wone so we add 0
setImage(e.target.files[0])
}
return (
<div>
<h1> Upload Event Image</h1>
<form onSubmit={handleSubmit}>
<input onChange={(e) => updateEdit(e)} id="titleproductgroup" value={updatesData.titleproductgroup} type="text" placeholder={posts.titleproductgroup} />
<div>
<input type='file' onChange={handleFileChange} />
</div>
<input type='submit' value='Upload' className='btn' />
</form>
</div>
)
}
export default ProductCreateApi
In the comment I wrote what I understand from attributes
and here my "table"
Thanks for your help. I hope I can improve myself thanks to you
I find solution, I just change that
const handleSubmit = async (e) => {
console.log('handleSubmit')
e.preventDefault()
const formData = new FormData()
formData.append('files', image) // the pic
formData.append('ref', 'api::product-group.product-group') // link with my table
formData.append('refId', evtId)
//formData.append('field', 'picproductgroup') // the row
axios.post('http://localhost:1337/api/upload/', formData).then(res => {
console.log(res.data[0].id);
const res2 = axios.post(`http://localhost:1337/api/product-groups/`, {
"data": {
titleproductgroup: updatesData.titleproductgroup,
picproductgroup: res.data[0].id,
}
})
if (res2.ok) {
console.log('res.ok')
console.log('res', res2)
// imageUploaded()
}
}).catch(error => {
console.log(error.message);
});
//e.preventDefault()
}
const handleFileChange = (e) => {
console.log('handleFileChange')
console.log(e.target.files[0]) //this will give us an array and we want the first wone so we add 0
setImage(e.target.files[0])
}
return (

Manipulating Local Data in React JS, Can Not Get It To Work For My Quiz Application

I'm new to coding (it's been around three months) and I have a problem with React JS.
I took freecodecamp's eleven hour REact JS Course on YouTube and in the end of the video, there is a quiz application challenge called quizzy.
You can go to my github project file and check it out
I came to a point where I can't get the answer options selected.
I want to toggle between a different colored background whenever I click on an answer button, and I wanted it to stay as long as that button is clicked. As far as I checked, there seems to be a problem with the App.js file where I try to manipulate the data's isSelected key inside toggle function. I kindly ask anyone for help. I just don't know what I am doing wrong and it's driving me crazy.
My App.js file looks like this:
import { nanoid } from 'nanoid';
import React from 'react';
import data from '../data';
import QuestionsAndAnswers from './QuestionsAndAnswers';
function Quiz() {
const [quiz, setQuiz] = React.useState(data);
// const [isSelected, setIsSelected] = React.useState(false);
React.useEffect(() => {
const newData = data.map((data) => ({
...data,
answerOptions: data.answerOptions.map(answerOptions => ({
...answerOptions,
optionsID: nanoid()
}))
}))
setQuiz(newData);
}, [])
const handleSubmit = (event) => {
event.preventDefault();
console.log("completed")
}
function toggle(id, value) {
console.log(id, value)
setQuiz((oldState) => oldState.map((data) => {
return data.id === id
? {
...data,
answerOptions: data.answerOptions.map(answerOptions => {
return answerOptions.answerText === value
? {
...answerOptions,
isSelected: !answerOptions.isSelected
}
: {
...answerOptions,
isSelected: false
}
})
}
: data
}))
}
const selectedOptions = data.map(data => {
return (data.answerOptions.isSelected ? data : null)
})
console.log(selectedOptions)
const questions = quiz.map((quiz, index) => {
return (
<QuestionsAndAnswers
key={index}
quiz={quiz}
setQuiz={setQuiz}
toggle={toggle}
/>
)
})
// main function
return (
<main>
<form className="form-container" onSubmit={handleSubmit}>
<h2 className='header'>QuizCript</h2>
{questions}
<button className="complete-quiz-button" type='submit'>Complete the Quiz</button>
</form>
</main>
)
}
export default Quiz;

How do I display all of the images from my Firebase Storage in React Native without needing image names?

Hello i am trying to figure out how to display all of the images in a folder i have in Firebase Storage called "VerifiedPhotos". I don't want to reference them by image name like I did below because I have multiple images. How do I grab all the list of image URLS and display them to my screen in React Native? Please help I have spent all week looking up how to use listAll() and I also am not sure how to display the multiple images in the return statement. Please help.
const Photos = () => {
const [imageUrl, setImageUrl] = useState(undefined);
useEffect(() => {
firebase.storage()
.ref('VerifiedPhotos/' + '3.png') //name in storage in firebase console
.getDownloadURL()
.then((url) => {
setImageUrl(url);
})
.catch((e) => console.log('Errors while downloading => ', e));
}, []);
return (
<Image style={{height: 200, width: 200}} source={{uri: imageUrl}} />
);
}
export default Photos;
As the documentation said about .listAll() here, you need to iterate through results :
const Photos = () => {
const [imageTab, setImageTab] = useState([]);
useEffect(() => {
firebase.storage()
.ref('VerifiedPhotos/')
.listAll()
.then(function(result) {
result.items.forEach(function(imageRef) {
imageRef.getDownloadURL().then(function(url) {
imageTab.push(url);
setImageTab(imageTab);
}).catch(function(error) {
// Handle any errors
});
});
})
.catch((e) => console.log('Errors while downloading => ', e));
}, []);
return (<View>
{imageTab.map(i => (<Image style={{height: 200, width: 200}} source={{uri: i}} />))}
</View>);
}
export default Photos;
Let me know if it worked :)

FileReader result brings me to a blank page with "about:blank#blocked" in the address bar

I'm trying to build a UI that allows users to download files from their computer to display in a playlist. So far all I did was display the name of the file in the list like so
Just currently I just started to get the links for each li to display different (before they were all the same). But now my functionality is slow and when I click on the link it brings to me to a blank page that has "about:blank#blocked" in the address bar when I want bring up the and play the audio. This is what my state looks like (The links are different):
Here's my code:
class DownloadTest extends React.Component {
constructor(props) {
super(props);
this.handleClick = this.handleClick.bind(this);
this.inputRef = React.createRef();
this.state = {
files: []
};
}
handleClick = event => {
// Helper code to read file and return promise
const readFile = (file) => {
const fileList = [];
const fileReader = new FileReader();
// create the promise and return it
return new Promise((resolve, reject) => {
// if file reader has an error, report it
fileReader.onerror = (error) => {
reject({ error })
}
// if success, resolve the promise
fileReader.onload = (e) => {
resolve({
name: file.name,
link: fileReader.result
})
}
// start reading the file
fileReader.readAsText(file);
})
}
// create all the file reader promises
// create an array from the files list and use map to generate
// an array of promises
const allReaders = Array.from(event.target.files).map(readFile)
// Now handle the array of promises we just created
Promise.all(allReaders)
.then(fileList => {
console.log(fileList)
// set the state that we have all the files
this.setState({ files: fileList });
})
.catch(error => {
console.error(error)
});
}
render() {
console.log(this.state);
return (
<div className="input">
<input
onChange={this.handleClick}
id="upload-file"
className="inputName"
type="file"
multiple
ref={this.inputRef}
/>
<div>
<ul ref={this.ulRef}>
{this.state.files.map((file, index) => (
<li key={index}>
<a href={file.link} download>{file.name}</a>
</li>
))}
</ul>
</div>
</div>
);
}
}
export default DownloadTest;

react-admin refresh dataGrid by custom form

First, i want to say that i'm beginner in react (and i hate front development but, you know, sometimes we don't choose in the job's life)....
So, i create a custom form with react-admin without use the REST connexion from react-admin (it's a specific form).
After the form's validation, a value named processingStatut of several data change and need to show this new value in the
<List><Datagrid> mapped by react-admin.
So i follow the documentation for create a reducer action for change a boolean value named processingStatut in my dataGrid like this:
epassesReceived.js
export const EPASSES_RECEIVED = 'EPASSES_RECEIVED';
export const epassesReceived = (data) => ({
type: EPASSES_RECEIVED,
payload: { data },
});
my customForm.js
import { epassesReceived as epassesReceivedAction } from './epassesReceived';
handleSubmit(event) {
this.setState({
post: this.post
});
const { fetchJson } = fetchUtils;
const {
showNotification,
history,
push,
epassesReceived,
fetchStart, fetchEnd
} = this.props;
const url = `${API_URL}/ePasses/update`;
const datas = JSON.stringify(this.state);
const options = {
method: 'POST',
body: datas
};
fetchStart();
fetchJson(url, options)
.then( response => epassesReceived(response.json) )
.then(() => {
showNotification('ra.notification.epasseRecorded');
history.goBack();
})
.catch( error => {
console.error(error);
var message = error.message.replace(/ /g, '');
showNotification(`ra.notification.${message}`, 'warning');
})
.finally(fetchEnd);
event.preventDefault();
}
...
const mapStateToProps = state => ({
customReducer: state.customReducer
});
export const EpassesUpdate = connect(mapStateToProps, {
epassesReceived: epassesReceivedAction,
showNotification,
push,fetchStart, fetchEnd
})(translate(withStyles(formStyle)(EpassesUpdateView)));
and in my app.js
import { EPASSES_RECEIVED } from './epassesReceived';
const customReducer = (previousState = 0, { type, payload }) => {
console.log(payload, type);
if (type == EPASSES_RECEIVED) {
// console.log('modif');
// payload.data[0].processingStatut=1; this is the purpose of the script. To show de modification changed after form's validation
return payload;
}
return previousState;
}
and the viewDataGrid.js
<List
classes={props.classes}
{...props}
exporter={exporter}
title='ePass.pageTitle'
perPage={15}
pagination={<PostPagination />}
filters={<EPassFilter businessunit={businessUnit} />}
bulkActions={<EPassBulkActions businessunit={businessUnit} />}
actions={<PostActions businessUnit={businessUnit} />}
>
<Datagrid classes={props.classes}>
{ businessUnit === undefined || !businessUnit.companyName &&
<TextField source="businessUnitName" label="ePass.businessUnitName" />
}
<StateField source="processingStatut" label="" translate={props.translate} />
.....
But in my console log my value doesn't change and i don't now why... Of course it's works if i refresh my web page by F5 because the value is changed in my database. But not in react's dataGrid... I'm lost...
maybe the log output can be helpfull:
We can see the type "EPASSES_RECEIVED" and the data changed
i think your problem comes from your fetch. Try this :
fetch(url, options)
.then( response => response.json() )
.then(data => {
epassesReceived(data);
showNotification('ra.notification.epasseRecorded');
history.goBack();
})
.catch( error => {
console.error(error);
var message = error.message.replace(/ /g, '');
showNotification(`ra.notification.${message}`, 'warning');
})
.finally(fetchEnd);

Categories