reactJS copy to clipboard - javascript

I wonder if something like this is doable in reactjs (i'm new).
In this example, when user hovers over the email address (at the bottom), it says: copy to clipboard, once clicked, email is copied.
https://shapefarm.net/contact/
I have the styling, once hovered, the text appears, but I really don't know how to implement the functionality, any ideas? Thank you!
const Footer = () => {
return (
<>
<FooterContainer>
<FooterBg>
<div className="footer-wrapper">
<div className="info">
<div className="hovertext-container">
<p className="hovertext-p1">
mymail#test.com
</p>
<p className="hovertext-p2">copy to clipboard</p>
</div>
</div>
<div>
<SocialMedia />
</div>
</div>
</FooterBg>
</FooterContainer>
</>
)
}
export default Footer

A simple
onClick={() => {navigator.clipboard.writeText(this.state.textToCopy)}}
is going to do the job, you can also try out this npm package.

const Footer = () => {
let email = "mymail#test.com";
return (
<>
<FooterContainer>
<FooterBg>
<div className="footer-wrapper">
<div className="info">
<div className="hovertext-container">
<p className="hovertext-p1">
mymail#test.com
</p>
<p onClick={async () => {
await navigator.clipboard.writeText(email)
alert("Copied text!")
}}
className="hovertext-p2">copy to clipboard</p>
</div>
</div>
<div>
<SocialMedia />
</div>
</div>
</FooterBg>
</FooterContainer>
</>
)
}
export default Footer

Related

render specific text based on Conditional statement

I have the following JSON
{"location":"2034","type":"Residential","price":400000,"address":"123 Fake Street","suburb":"Maroubra","historical_DAs":0,"description":"Residential","property_ID":1},
{"location":"2036","type":"Commercial","price":475000,"address":"123 Fake Street","suburb":"Coogee","historical_DAs":10,"description":"Government","property_ID":2},
{"location":"2035","type":"Food & Bev","price":56000,"address":"123 Fake Street","suburb":"Clovelly","historical_DAs":3,"description":"Residential","property_ID":3},
{"location":"2031","type":"Education","price":69070,"address":"123 Fake Street","suburb":"Randwick","historical_DAs":7,"description":"Government","property_ID":4},
{"location":"2036","type":"Education","price":69070,"address":"123 Fake Street","suburb":"Randwick","historical_DAs":7,"description":"Government","property_ID":5}
I want to render different images based upon the description field (currently trying to just get text to render correctly atm.)
What I have tried so far:
function TypeImages({ description }) {
function Residential(props) {
return <div>
<h1>Image 1</h1>
</div>;
}
function Government(props) {
return <div>
<h1>Image 2 </h1>
</div>;
}
function TypeImage(props) {
if (description === 'Residential') {
return <Residential />;
} else
return <Commercial />;
}
return (
<div>
<div>
<div className="hidden lg:inline-flex mb-1 px-9">
<TypeImage/>
<div>
</div>
</div>
</div>
</div>
);
}
export default TypeImages;
This isn't working as what is rendered is all 'Image 2' even though there should be some 'Image 1'
Any suggestions on the most efficient way to achieve this?
Thanks!
You can do by many ways,
You need to make sure or check if description has value, if not you probably get unexpected behaviors
Sandbox Example: https://codesandbox.io/s/stupefied-water-sc4o5h?file=/src/App.js
Using ternary conditional statements
return (
<div>
<div>
<div className="hidden lg:inline-flex mb-1 px-9">
{/* Doing this */}
{description === "Residential" ? <Residential /> : <Government /> }
<div>
</div>
</div>
</div>
</div>
);
Doing the way that you was working
function TypeImage() {
if (description === 'Residential') {
return <Residential />;
}
return <Government/>;
}
return (
<div>
<div>
<div className="hidden lg:inline-flex mb-1 px-9">
<TypeImage/>
<div>
</div>
</div>
</div>
</div>
);
Doing this another way using conditional inline
return (
<div>
<div>
<div className="hidden lg:inline-flex mb-1 px-9">
{description === "Residential" && <Residential /> }
{description === "Government" && <Government/> }
<div>
</div>
</div>
</div>
</div>
);

React infinite/max-level comment for each news post

I have a News feature where user can post their status. However, so far, I cannot make it display all comments of the news as my current solution only allows two-level only. Here are my codes:
News.js (for all)
function News() {
const {userId, setUserId} = useContext(UserContext);
const {type, isUserType} = useContext(UserTypeContext);
const [newsList, setNewsList] = useState([]);
const rootNews = newsList.filter(
(newList) => newList.reply_of === null
);
const getReplies = commentId => {
return newsList.filter(newList => newList.reply_of === commentId);
}
useEffect(()=>{
Axios.get('http://localhost:3001/news',{
})
.then((response) => {
if(response.data.length > 0){
setNewsList(response.data);
}
})
},[]);
return (
<div className = "news p-5">
<h3 className="news-title">News</h3>
<div className = "comments-container">
{rootNews.map((rootNew) => (
<div>
<Comment key={rootNew.news_id}
comment={rootNew}
replies={getReplies(rootNew.news_id)}/>
</div>
))}
</div>
</div>
)
}
Comment.js (for rendering the comments and replies)
function Comment({comment, replies}) {
return (
<div className="comment">
<div className="comment-image-container">
<img src = "/user-icon.png" />
</div>
<div className="comment-right-part">
<div className="comment-content">
<div className="comment-author">
{comment.user_name}
</div>
<div>{comment.day}, {moment(comment.date).format('DD-MM-YYYY')} at {comment.time}</div>
</div>
<div className="comment-text">{comment.news_title}</div>
{replies.length > 0 && (
<div className="replies">
{replies.map(reply => (
<Comment comment={reply} key={reply.news_id} replies={[]}/>
))}
</div>
)}
</div>
</div>
)
}
This is an example on how the comment structure would look like:
Comment 1
Reply 1.1
Reply 1.1.1
Reply 1.1.1.1
Reply 1.2
Comment 2
An idea on how I could render infinite replies, or possibly set the maximum level of replies allowed? Thank you
You just need a little change to the Comment component to recursively render the already nested data structure:
function Comment({ comment, newsList }) {
const replies = newsList.filter((newList) => newList.reply_of === comment.news_id);
return (
<div className="comment">
<div className="comment-image-container">
<img src="/user-icon.png" />
</div>
<div className="comment-right-part">
<div className="comment-content">
<div className="comment-author">{comment.user_name}</div>
<div>
{comment.day}, {moment(comment.date).format("DD-MM-YYYY")} at{" "}
{comment.time}
</div>
</div>
<div className="comment-text">{comment.news_title}</div>
{replies.length > 0 && (
<div className="replies">
{replies.map((reply) => (
<Comment key={reply.news_id} comment={reply} newsList={newsList} />
))}
</div>
)}
</div>
</div>
);
}
Basically, you just move the code that gets the direct replies to a comment into the Comment component.
When you render the root Comment component, all direct replies to the root comment will be identified and will cause the rendering of nested Comment components, which will in turn identify the replies to the reply, render a nested Comment component and so on.

Next js component doesn't show without reload

Basically, I have a nested component that I want to render with the parent component and it's working fine when the server starts.
But the problem arises when I switch back from another page. Some of the nested components get disappeared. If I made a refresh then again everything ok.
How can I solve this issue?
Normal:
Image-1
Component disappeared:
Image-2
Index.js:
import BannerBaseLine from "./../components/HOME/Banner/BannerBaseLine";
import SubSection1 from "./../components/ABOUT/subSection1";
import CoursesList from "../components/HOME/MOSTTRENDING/CoursesList/courseslist";
import ShortOverview from "./../components/HOME/CourseOverviewSection/Section1/shortoverview";
import Testimonial from "./../components/HOME/Testimonial/testimonial";
import ClientItem from "./../components/HOME/Client-area/all-client-item";
export default function HomeMain({categories}) {
return (
<>
<br></br>
<br></br>
<br></br>
<BannerBaseLine categories = {categories} />
<CoursesList />
{/* <SubSection1 /> */}
<ShortOverview />
<CoursesList />
<Testimonial />
<ClientItem />
</>
);
}
export async function getStaticProps(){
const response = await fetch('http://localhost:8000/api/data/categories')
const data = await response.json()
console.log(data)
return {
props:{
categories : data,
}
}
}
BannerBaseLine component:
import BannerBlock from './BannerBlock';
export default function BannerBaseLine({ categories }) {
return (
<>
<section
className="banner-area"
style={{ backgroundImage: "url(assets/img/banner/0.jpg)" }}
>
<div className="container">
<div className="row">
<div className="col-lg-6 col-md-8 align-self-center">
<div className="banner-inner text-md-start text-center">
<h1>
Find the Best <span>Courses</span> & Upgrade{" "}
<span>Your Skills.</span>
</h1>
<div className="banner-content">
<p>
Edufie offers professional training classes and special
features to help you improve your skills.
</p>
</div>
<div className="single-input-wrap">
<input type="text" placeholder="Search your best courses" />
<button>
<i className="fa fa-search"></i>
</button>
</div>
</div>
</div>
</div>
</div>
</section>
<br></br>
<br></br>
<div className="container">
<div className="intro-area-2">
<div className="row justify-content-center">
<div className="col-lg-12">
<div className="intro-slider owl-carousel">
{categories.map((category) => {
return (
<>
<BannerBlock category={category} key={category.id} />
</>
);
})}
</div>
</div>
</div>
</div>
</div>
</>
);
}
BannerBlock component:
export default function BannerBlock({category}) {
console.log(category);
return (
<div className="item">
<div className="single-intro-wrap">
<div className="thumb">
<img src={category.image} alt="img" />
</div>
<div className="wrap-details">
<h6>
{category.Base_Category_Title}
</h6>
<p>236 Course Available</p>
</div>
</div>
</div>
);
}
From https://nextjs.org/docs/basic-features/data-fetching#getstaticprops-static-generation
Note: You should not use fetch() to call an API route in
getStaticProps. Instead, directly import the logic used inside your
API route. You may need to slightly refactor your code for this
approach.
Fetching from an external API is fine!
you should check if categories exist
export default function HomeMain({categories}) {
if(categories){
return <Loading Component />
}
rest of the code...
}

Cards inside the grid-container: each child in a list should have a unique "key" prop

What I`m doing wrong?It also says: "Check the render method of Card" , which is here:
<div className="grid-container">
{pokemonData.map((pokemon, i) => {
console.log(pokemon.id) // unique numbers are here
return <Card key={pokemon.id} pokemon={pokemon} />
})}
</div>
Card component itself:
function Card({ pokemon }) {
return (
<div className="card">
<div className="card__image">
<img src={pokemon.sprites.front_default} alt="Pokemon" />
</div>
<div className="card__name">
{pokemon.name}
</div>
<div className="card__types">
{
pokemon.types.map(type => {
return (
<div className="card__type" style={{backgroundColor: typeColors[type.type.name]}}>
{type.type.name}
</div>
)
})
}
</div>
<div className="card__info">
<div className="card__data card__data--weight">
<p className="title">Weight:</p>
<p>{pokemon.weight}</p>
</div>
<div className="card__data card__data--height">
<p className="title">Height:</p>
<p>{pokemon.height}</p>
</div>
<div className="card__data card__data--ability">
<p className="title">Abilities:</p>
{/* {console.log(pokemon.abilities)} Temporary for dev puprose */}
{pokemon.abilities.map(ability => <p>{ability.ability.name}</p>
)}
</div>
</div>
</div>
);
}
export default Card;
You can use the index of the array may be your data is having some kind of duplicate. It is recommended that you pass a key prop whenever you are returning a list.
<div className="grid-container">
{pokemonData.map((pokemon, i) => {
console.log(pokemon.id) // unique numbers are here
return <Card key={i} pokemon={pokemon} />
})}
</div>
Equally, check this segment of card components.
{
pokemon.types.map((type,i) => {
return (
<div key={i} className="card__type" style={{backgroundColor:
typeColors[type.type.name]}}>
{type.type.name}
/div>
)
})
}
And
<div className="card__data card__data--ability">
<p className="title">Abilities:</p>
{/* {console.log(pokemon.abilities)} }
{pokemon.abilities.map((ability, i) => <p key={i}>{ability.ability.name}
</p>
)}
</div>
Previous answer will solve your problem. However, for your info, I would also like to add here.
For React a key attribute is like an identity of a node/element/tag which helps React to identify each item in the list and apply reconciliation correctlyon each item. Without a key React will render your component but may cause issue when you re-order your list.
React recommends to use id of the data instead of index number. However, if your list does not re-orders/ sorts or do not have id then you can use index.
You can read more here:
https://reactjs.org/docs/lists-and-keys.html
Change this:
<div className="card__types">
{
pokemon.types.map(type => {
return (
<div className="card__type"
style={{backgroundColor:typeColors[type.type.name]}}
>
{type.type.name}
</div>
)
})
}
</div>
to:
<div className="card__types">
{
pokemon.types.map((type, key) => {
return (
<div key={key} className="card__type"
style={{backgroundColor:typeColors[type.type.name]}}
>
{type.type.name}
</div>
)
})
}
</div>
and:
{pokemon.abilities.map(ability => <p>{ability.ability.name}</p>
to:
{pokemon.abilities.map((ability,key) => <p key={key} >{ability.ability.name}</p>

How to blur out an entire webpage when a button is clicked

I'm setting up a one-page website with react.js, html, and scss. I am struggling to have the entire website have a blur effect or fade when a button is clicked (this will be later used for loading animations). What commands can I use to get this blur when a button is pressed?
render() {
return (
<div className="App">
<div className="top-bar">
<div className="title">poem</div>
<img className="logo" src="./logo.png" />
</div>
<div className="container">
<div className="sloganLineOne">Poem Theme</div>
<div className="sloganLineTwo">Detector</div>
<textarea
className="inputField"
placeholder="Please Enter Your Poem Here..."
/>
<button className="button" onClick={this.fadeOut}>
Enter
</button>
<img className="leftTriangle" src="./leftSideTriangle.png" />
<img className="rightTriangle" src="./rightSideTriangle.png" />
</div>
</div>
)
}
fadeOut = () => this.setState({ fadingOut: true })
}
I expect the entire page to be blurred or look like it when the button is clicked.
All you have to do is apply the style to your parent div and you should be good to go! Give this a shot
class App extends React.Component {
state = { fadingOut: false }
fadeOut = () => this.setState({fadingOut: true});
render() {
return (
<div className="App" style={this.state.fadingOut ? {filter: 'blur(2px)'} : undefined }>
<div className="top-bar">
<div className="title">
poem
</div>
</div>
<div className="container">
<div className="sloganLineOne">Poem Theme</div>
<div className="sloganLineTwo">Detector</div>
<textarea className="inputField" placeholder="Please Enter
Your Poem Here..."></textarea>
<button className="button" onClick={this.fadeOut}>Enter</button>
<img className="leftTriangle" src="./leftSideTriangle.png"/>
<img className="rightTriangle" src="./rightSideTriangle.png"/>
</div>
</div>
);
}
}
See it in action!

Categories

Resources