Google Authentication With React-Google-Login issue when redirecting - node.js

I am having an issue with the npm package react-google-login. The issue is that I have a redirectUri passed into the component but when I try to redirect with the popup nothing happens , but when I add uxMode='redirect' it works but it gives me an awfully long url which is something I do not like. Is there a way to make the popup version of the redirect work?
Here is my code below, the clientID is removed:
import React from 'react';
import GoogleLogin from 'react-google-login';
import ChatRoom from './ChatRoom';
import { FontAwesomeIcon } from '#fortawesome/react-fontawesome';
import { faGoogle } from '#fortawesome/free-brands-svg-icons';
import { faQuestionCircle } from '#fortawesome/free-solid-svg-icons';
import {Link} from 'react-router-dom';
const responseGoogle = (res) => {
console.log('Failed');
}
const successLogin = () => {
console.log('success');
}
const Authentication = () => {
return (
<div className='auth-wrapper'>
<div className="auth-container">
<h1 className="auth-header">Choose Your Sign in Method</h1>
<div className="btn-container2">
<GoogleLogin
clientId="none"
buttonText="Sign in with Google"
onSuccess={successLogin}
onFailure={responseGoogle}
cookiePolicy={'single_host_origin'}
uxMode='popup'
redirectUri='http://localhost:3000/ChatRoom'
render={renderProps => (
<button className="btn2 btn-primary2 animate shake" onClick={renderProps.onClick} disabled={renderProps.disabled}><FontAwesomeIcon size='lg' icon={faGoogle} /> Sign in with Google</button>
)}
/>
<Link to='/ChatRoom'>
<button className="space btn2 btn-primary2 animate shake">
<FontAwesomeIcon size='lg' icon={faQuestionCircle} /> Continue as Guest
</button>
</Link>
</div>
</div>
</div>
)
}
export default Authentication

Essentially all I had to do was use useHistory from react-router-dom and utilize history.push('/page'); to navigate to the page whenever the user gets authenticated.
let history = useHistory();
// Redirects user after authentication to the ChatRoom
const successLogin = () => {
history.push('/ChatRoom');
}

Related

What is console.error in react testing and is it okay to ignore?

I am on the way to learning Jest and React Testing Library.
When I run the test below, it is 'passed' but I see the console.error message.
[sectionIntro.spec.js]
import React from "react";
import { fireEvent, render, screen } from "#testing-library/react";
import SectionIntro from "../../components/home/SectionIntro.jsx";
import { CV_URL } from "../../lib/socials";
describe("SectionIntroComponent", () => {
it("Should open the CV link when CV button is clicked", () => {
render(<SectionIntro />);
const cv_link = screen.getByText(/Check My CV/i);
expect(cv_link.href).toBe(CV_URL);
});
});
// Also a mock file is used for an image file.
[SectionIntro.jsx]
import * as React from "react";
import Image from "next/image";
import profilePic from "../../public/me.png";
import styles from "../../styles/SectionIntro.module.css";
import { CV_URL } from "../../lib/socials";
const SectionIntro = () => {
return (
<>
<div>
<div>
<Image
className="rounded-full"
src={profilePic}
alt="The author of the website"
objectFit="cover"
sizes="30vw"
/>
</div>
</div>
<div>
<button
className={`${styles.btnCV}`}
>
<a
href={CV_URL}
aria-label="CV"
target="_blank"
rel="noopener noreferrer"
>
Check My CV
</a>
</button>
</div>
</>
);
};
export default SectionIntro;
[mocks/mockFile.js]
export default "";
My question is if the test result is passed why the console.error is shown?
Would it be okay to ignore console.error?
If it is not a good idea to hide the console, why is it so?
Thanks alot in advance!

Using express js I can't render items on screen. It goes blank. Full stack

I am using express nodejs to create a fullstack app, this page has to show users and products but it is rendering a blank page. If I delete the {} of user, it renders the page but with no results.
import React, { useContext, useState } from 'react';
import CoffeeContext from '../contexts/CoffeeContext';
import { Link } from "react-router-dom";
import '../App.css'
import UserContext from '../contexts/UserContext';
function CoffeeList(props) {
let { deleteCoffee } = useContext(CoffeeContext);
let { user } = useContext(UserContext)
return (
<CoffeeContext.Consumer>
{
({ coffee }) => {
return <div>
<h1>Posts</h1>
<h4>Hello <span> {user.username}'Insert user's name here' Thanks for visiting our website!</span></h4>
<button>Add New Post</button>
<div>
{coffee.map((c) => {
console.log(coffee)
return (
<div key={c._id}>
<h2>{c.name}</h2>
<Link to={`/edit/${c._id}`}>
<button>Edit</button>
</Link>
<button onClick={() => { deleteCoffee(c._id)}}>Delete</button>
<h6>{user.username}</h6>
</div>
)
})}
</div>
</div>
}
}
</CoffeeContext.Consumer>
);
}
export default CoffeeList;

React component data not saved when submit

Below is my code, the React app is connected to Node js and the data of comment are saved when submit but it's not working for StarRating component.
The comment data is saved in the db table but not the rating
Please pass setRating in starComponent as props
Like below:
<StarRating rating={rating1} updateRating={(e) => setRating1(e)}
onChange={e => setRating1(e.target.value)}></StarRating>
Now you will get updateRating as props in starComponent. So update rating form star component like below:
import React, { useState} from "react";
import { FaStar } from 'react-icons/fa';
const StarRating = ({rating, updateRating}) =>{ // Here you will get setRating state(State of app component) in props
// const [rating, setRating] = useState(null); // not needed this state here. Update rating value in state which comes form props
const [hover, setHover] = useState(null);
return <div>
<p>Rate your experience from 0 to 5 stars</p>
{[... Array(5)].map((star, i)=>{
const ratingValue= i + 1;
return (
<label>
<input
type="radio"
name="rating"
value={rating}
onClick={() =>updateRating(ratingValue)} /> // Update `updateRating` state which comes from app component.
<FaStar
className="star"
color={ratingValue <= (hover || rating) ? "#11C4B0" : "#D3D3D3"}
size={40}
onMouseEnter={() =>setHover(ratingValue)}
onMouseLeave={() =>setHover(null)}
/>
</label>
);
})}
</div>
}
export default StarRating;
You will get updated state in rating1 in app component if any changes occurred from starComponent.
I think the Problem is that you are accessing the rating state in App component but the real state with the value is the rating state of StarRating component. Also, you have passed the props onChange and value to StarRating component but The Props concept is different than the HTML Attributes concept so you definitely need to look into that. Anyway, the possible Solution can be...
import * as React from 'react';
import './App.css';
import StarRating from './StarRating';
import StarRating2 from './StarRating2';
import StarRating3 from './StarRating3';
import { TextArea } from 'semantic-ui-react';
import AlertDialogSlide from './confirmation';
import Dialog from '#mui/material/Dialog';
import DialogActions from '#mui/material/DialogActions';
import DialogContent from '#mui/material/DialogContent';
import DialogContentText from '#mui/material/DialogContentText';
import Slide from '#mui/material/Slide';
import Button from '#mui/material/Button';
import { useState } from "react";
const Transition = React.forwardRef(function Transition(props, ref) {
return <Slide direction="up" ref={ref} {...props} />;
});
function App() {
const [open, setOpen] = React.useState(false);
const [comment, setComment] = useState("");
const [rating1, setRating1] = useState("");
const handleClickOpen = () => {
setOpen(true);
};
const handleClose = () => {
setOpen(false);
};
const onSubmitForm = async e => {
e.preventDefault();
try {
const body = { rating1, comment };
const response = await fetch("http://localhost:5000/feedback", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body)
});
window.location = "/";
} catch (err) {
console.error(err.message);
}
};
return (
<form onSubmit={onSubmitForm} >
<div className="App">
<img src='solavievelogo.png'></img>
<hr/>
<h2>Leave a feedback!</h2>
<StarRating setRating={setRating1} />
<hr2/>
<StarRating2></StarRating2>
<hr2/>
<StarRating3></StarRating3>
<hr2/>
<p>Please leave a comment about your experience below:</p>
<TextArea placeholder=' Type your comment here...'
value={comment}
onChange={e => setComment(e.target.value)}
></TextArea>
<br/>
<button class="Button" type='submit' variant="outlined" onClick={handleClickOpen}><span class="Button-inner">SEND FEEDBACK</span> </button>
<Dialog
open={open}
TransitionComponent={Transition}
keepMounted
onClose={handleClose}
aria-describedby="alert-dialog-slide-description"
>
<DialogContent>
<img src='confirm.png'></img>
<DialogContentText id="alert-dialog-slide-description">
<p>Thank you for your message!</p>
<p> We will be in contact soon..</p>
</DialogContentText>
</DialogContent>
<DialogActions >
<button class="Button" type='submit' onClick={handleClose} ><span class="Button-inner">Close</span> </button>
</DialogActions>
</Dialog>
</div>
</form>
);
}
export default App;
StarRating Component
import React, { useState} from "react";
import { FaStar } from 'react-icons/fa';
const StarRating = ({setRating}) =>{
const [hover, setHover] = useState(null);
return <div>
<p>Rate your experience from 0 to 5 stars</p>
{[... Array(5)].map((star, i)=>{
const ratingValue= i + 1;
return (
<label>
<input
type="radio"
name="rating"
value={ratingValue}
onClick={() =>setRating(ratingValue)} />
<FaStar
className="star"
color={ratingValue <= (hover || rating) ? "#11C4B0" : "#D3D3D3"}
size={40}
onMouseEnter={() =>setHover(ratingValue)}
onMouseLeave={() =>setHover(null)}
/>
</label>
);
})}
</div>
}
export default StarRating;

Monitoring multiple server stats in React JS

I have multiple pods running on my Kubernetes cluster and I have a "core app" built with react from which I want to get CPU & Memory usage stats.
Right now I am testing using a very simple setup where I have a local node app using socket.io to stream the time (based on this tutorial)
However, with one component which looks like the following, I am able to get real time updates from the server.
import React, { useState, useEffect } from "react";
import socketIOClient from "socket.io-client";
import {StatsCPUWrapper} from './statsCPU.style'
const ENDPOINT = process.env.STATS_ENDPOINT || "http://127.0.0.1:4001";
function StatsCPUComp() {
const [cpustats, setCPUstats] = useState("");
useEffect(() => {
const socket = socketIOClient(ENDPOINT);
socket.on("FromAPI", data => {
setCPUstats(data);
});
// Clean up the effect
return () => socket.disconnect();
}, []);
return (
<StatsCPUWrapper>
<p>
It's <time dateTime={cpustats}>{cpustats}</time>
</p>
</StatsCPUWrapper>
);
}
export default StatsCPUComp;
What I am now trying to do is have 3 or more of those components (depends on the list I get from my backend) to "subscribe" to multiple servers at the same time.
Here's my "projects list" component which gets the stats from the initial state and renders all the details:
import React from 'react'
import {useSelector, useDispatch} from 'react-redux'
import {Link} from 'react-router-dom'
import PropTypes from 'prop-types'
import {create, remove} from '../../features/projects/projectSlice'
import {ProjectWrapper} from './project.style'
import StatsCPUComp from './stats/statsCPU'
export function ProjectComp() {
const dispatch = useDispatch()
const projects = useSelector((state) => state.projects)
const handleSubmit = (e) => {
e.preventDefault()
}
const handleAction = (e) => {
e.preventDefault()
}
return (
<ProjectWrapper>
<div className="projects">
<div className="row">
{projects.map((projects) => (
<div className="col-12">
<div class="card project-card">
<div className="card-body">
<div className="row">
<div className="col-4 project-text">
<h5 class="card-title">
{' '}
<Link to={`/projects/` + projects.id}>{projects.name}</Link>
</h5>
<p class="card-text">Owner: {projects.owner}</p>
<p class="card-text">{projects.email}</p>
</div>
<div className="col-4 projects-stats">
<StatsCPUComp />
</div>
<div className="col-4 projects-stats"></div>
<div className="col-4 projects-stats"></div>
</div>
</div>
</div>
<br></br>
</div>
))}
</div>
</div>
</ProjectWrapper>
)
}
Right now the "time" from the stats component is being added on my last project component (makes sense since I did not implement any approach yet to map that too).
Any ideas on how I can have a different stats component for each of my "projects" where each one connects to a provided endpoint ? (I can pass all of the endpoints as env variables)
Any help would be highly appreciated.
So here's the implementation I did to make it work. (Not sure if it's ideal so please feel free to make any suggestions)
I added "endpoint" to state.projects which holds the data I get from my backend.
Then in my "projects list" component mentioned shown in the question, I pass projects (from state.projects) as props
<StatsCPUComp props={projects}/>
I then destructure it and pass it to my useEffect() in the stats component as follows:
import React, {useState, useEffect} from 'react'
import socketIOClient from 'socket.io-client'
import {StatsCPUWrapper} from './statsCPU.style'
import {useSelector, useDispatch} from 'react-redux'
let ENDPOINTS = []
let PROJECTS = []
function StatsCPUComp(...props) {
const [cpustats, setCPUstats] = useState('')
let endpoints = {...props}
let endpoints_2 = {...endpoints[0]}
useEffect(() => {
let socketlist = []
console.log(endpoints[0].props.endpoint)
const socket = socketIOClient(endpoints[0].props.endpoint);
socket.on("FromAPI", data => {
setCPUstats(data);
});
return () => socket.disconnect();
}, [cpustats])
return (
<>
<StatsCPUWrapper>
<p>
It's <time dateTime={cpustats}>{cpustats}</time>
</p>
</StatsCPUWrapper>
</>
)
}
export default StatsCPUComp
It seems to be working fine, however please do provide any suggestions since I might not be following an optimal approach (Performance and scalability wise)

How to display images in Bootstrap carousel using React

So I have a component(Posts) in which a loop through all the posts from the Database. In the component, I 'embedded' another component(PostItem) so I dont have to create a different component for viewing individual entries. Now inside the PostItem component I have another component with the name of 'PostGallery'.
This is the current code that I have in PostItem.js file:
import React from 'react';
import PropTypes from 'prop-types';
import { Link } from 'react-router-dom';
import { connect } from 'react-redux';
import PostGallery from '../posts/PostGallery';
const PostItem = ({
post: { _id, text, name, files, avatar, user, likes, comments, date },
}) => (
<article className={_id}>
<Link to={`/posts/${_id}`}>
<div id="carouselExampleIndicators" className="carousel slide" data-ride="carousel">
<div className="carousel-inner">
{files.slice(0, 5).map((file, index) => (
<PostGallery key={index} post={file} />
))}
</div>
</div>
</Link>
</article>
);
PostItem.propTypes = {
post: PropTypes.object.isRequired,
};
export default connect(
null, null
)(PostItem);
When posting an entry the user can post URL from images separated by comma which is working just fine. The problem comes when displaying it in the front-end.
This is what I have in my PostGallery component:
import React from 'react';
import PropTypes from 'prop-types';
const PostGallery = ({
post: { files }
}) => {
return (
<div className="">
{post.files.length > 0 ? (
post.files.map(file => (
<img key={file} src={file} alt="" />
))) : (
<p>No images found</p>
)
}
</div>
);
};
PostGallery.propTypes = {
post: PropTypes.object.isRequired,
};
export default PostGallery;
I believe this should be easy but somehow its just now working and the console it's not trowing me any errors related to it. So if you guys can help...
Thanks!

Resources