Redirecting to external link using ReactJS - javascript

I want to add button property which will redirect to external link when it is clicked. prop which should be added to button is siteURL .Button should be in class = "project-item-details-container". Do I have to install any external package?
sample button: Visit site
code which I have written -
const ProjectItem = props => {
const {projectDetails} = props
const {projectId, imageURL, description, title, siteURL} = projectDetails
return (
<>
<li className="project-item-container">
<img
className="project-item-image"
src={imageURL}
alt={`project-item${projectId}`}
/>
<div className="project-item-details-container">
<h1 className="project-item-title">{title}</h1>
<p className="project-item-description">{description}</p>
</div>
</li>
</>
)
}

const ProjectItem = props => {
const {projectDetails} = props
const {projectId, imageURL, description, title, siteURL} = projectDetails
return (
<>
<li className="project-item-container">
<img
className="project-item-image"
src={imageURL}
alt={`project-item${projectId}`}
/>
<div className="project-item-details-container">
<h1 className="project-item-title">{title}</h1>
<p className="project-item-description">{description}</p>
</div>
<a href={siteUrl}>{title}</a>
</li>
</>
)
}

you can do something like this
const ProjectItem = props => {
const {projectDetails} = props
const {projectId, imageURL, description, title, siteURL} = projectDetails
return (
<>
<li className="project-item-container">
<img
className="project-item-image"
src={imageURL}
alt={`project-item${projectId}`}
/>
<div className="project-item-details-container">
<h1 className="project-item-title">{title}</h1>
<p className="project-item-description">{description}</p>
<button onClick={()=>window.location.href=siteURL}>{title}</button>
</div>
</li>
</>
)
}

Well, I solved this.
I have used attribute in button element.
const ProjectItem = props => {
const {projectDetails} = props
const {projectId, imageURL, description, title, siteURL} = projectDetails
return (
<>
<li className="project-item-container">
<img
className="project-item-image"
src={imageURL}
alt={`project-item${projectId}`}
/>
<div className="project-item-details-container">
<h1 className="project-item-title">{title}</h1>
<p className="project-item-description">{description}</p>
<button type="button" className="project-redirect-button">
<a href={siteURL} alt="Broken Link">
Visit Site
</a>
</button>
</div>
</li>
</>
)
}

Related

Show post content in the same page ReactJS

i'm creating a blog. in my index.js i have a left sidebar that shows the article links.
What I'm trying to do is when I click on the link the post content should be shown in the right sidebar of my index.js
At the moment it's been opened in a new page.
index.js
const IndexPage = ({
data: {
allMarkdownRemark: { edges },
},
}) => {
const PostData = edges[0]
const Posts = edges
.filter(edge => !!edge.node.frontmatter.date) // You can filter your posts based on some criteria
.map(edge => <PostLink key={edge.node.id} post={edge.node} />)
return (
<div className='html-container'>
<div className='main-container'>
<div className='row'>
<div className='left-sidebar'>
<div className='logo'>
<p>logo</p>
</div>
<div className='menu'>
{Posts}
</div>
<div className='social'>
<img src={twitch} />
<img src={discord} />
<img src={twitter} />
<img src={email} />
</div>
</div>
<div className='right-sidebar'>
</div>
</div>
</div>
</div>
)
}
post-link.js
import React from "react"
import { Link } from "gatsby"
const PostLink = ({ post }) => (
<div>
<Link to={"/blog"+post.frontmatter.slug}>
{post.frontmatter.title}
{/* {post.frontmatter.title} ({post.frontmatter.date}) */}
</Link>
</div>
)
export default PostLink
Check the API of the Link and if it has an equivalent of target attribute.

my react.js app is coming blank trying to seed with an external js file

I just started studying react, so I picked up the book Fullstack react by Anthony Accomozzio et al, with the latest version on January 13, 2020. I created the react app with npx create-react-app I am stuck on the part of 'making product data driven', I'm trying to seed data from an external file seed.js using props, but it returns a blank screen. But runs if data is hard encoded.
App.js:
import logo from './logo.svg';
import './App.css';
import './seed';
function App() {
const product = window.Seed.products[1];
return (
<div className="App">
<Product
id = {product.id}
title = {product.title}
decription = {product.description}
url = {product.url}
votes = {product.votes}
submitterAvatarUrl = {product.submitterAvatarUrl}
productImageUrl = {product.productImageUrl}
/>
</div>
);
}
const Product = () => {
return (
<div className = 'item'>
<div className = 'image'>
<img src = {this.props.productImageUrl} />
</div>
<div className = 'middle aligned content'>
<div className = 'header'>
<a>
<i className = 'large caret up icon' />
</a>
{this.props.votes}
</div>
<div className = 'description'>
<a href = {this.props.url}>
{this.props.title}
</a>
<p>
{this.props.description}
</p>
</div>
<div className='extra'>
<span>Submitted by:</span>
<img
className='ui avatar image'
src = {this.props.submitterAvatarUrl}
/>
</div>
</div>
</div>
);
}
export default App;
The seed.js that has the data:
window.Seed = (function (){
function generateVoteCount() {
return Math.floor((Math.random() * 50) + 15);
}
const products = [
{
id: 1,
title: 'Yellow Pail',
description: 'On-demand sand castle construction expertise.',
url: '#',
votes: generateVoteCount(),
submitterAvatarUrl: 'images/avatars/daniel.jpg',
productImageUrl: 'images/products/image-aqua.png',
},
...
];
return { products: products };
}());
Is the codes deprecated for the react version?
Your Product component is a functional component which means there is no this.props.
You'll need to take in the props as an argument and then you can use prop.xxx to access the values.
const Product = (props) => {
return (
<div className="item">
<div className="image">
<img src={props.productImageUrl} />
</div>
<div className="middle aligned content">
<div className="header">
<a>
<i className="large caret up icon" />
</a>
{props.votes}
</div>
<div className="description">
<a href={props.url}>{props.title}</a>
<p>{props.description}</p>
</div>
<div className="extra">
<span>Submitted by:</span>
<img className="ui avatar image" src={props.submitterAvatarUrl} />
</div>
</div>
</div>
);
};

Tailwind CSS Grid Spacing Messed Up

I am trying to make a blog website with two columns for the posts. The first column displays one large-format post while the second displays 3 small-format posts (pictured below). However, when i do this to small-format posts seem to respect the spacing of the large-format post, even though they are in different columns. Here is a picture:
As you can see, I want the posts on the right side to be spaced evenly, but the second post starts at the end of the large-format post on the first column.
Here is my code:
import React, { useEffect, useState } from 'react'
import client from '../client'
import BlockContent from '#sanity/block-content-to-react'
import { Link } from 'react-router-dom'
function Main() {
const [posts, setPosts] = useState([])
useEffect(() => {
client.fetch(
`*[_type == "post"] {
title,
slug,
body,
author,
mainImage {
asset -> {
_id,
url
},
alt
},
publishedAt
}`
).then((data) => setPosts(data))
.catch(console.error)
}, [])
return (
<div className='grid lg:grid-cols-3 md:grid-cols-2 gap-8 m-4 '>
{posts.slice(0, 1).map((p, i) => (
<Link to = {`/blog/${p.slug.current}`} className=''>
<article key = {p.slug.current} className=''>
<img src = {p.mainImage.asset.url} alt = {p.title} className='' />
<div>
<p className='font-bold text-xl text-secondary'>{p.title}</p>
<p className='text-sm'>By Brandon Pyle | {new Date(p.publishedAt).toLocaleDateString()}</p>
</div>
</article>
</Link>
))}
{posts.slice(1, 4).map((p, i) => (
<Link to = {`/blog/${p.slug.current}`} className='col-start-2 h-16'>
<article key = {p.slug.current} className='flex'>
<img src = {p.mainImage.asset.url} alt = {p.title} className='w-auto h-auto max-h-[80px]' />
<div>
<p className='font-bold text-xl text-secondary'>{p.title}</p>
<p className='text-sm'>By Brandon Pyle | {new Date(p.publishedAt).toLocaleDateString()}</p>
</div>
</article>
</Link>
))}
</div>
)
}
export default Main
Please let me know if you have any ideas on how to fix this issue! Thanks.
try build your cols with this code with the size you want to
grid-cols-[80px_400px_1fr_250px]=grid-cols-[first_second_therd]
and check this too Try build layout with tailwind CSS
I figured out what was causing the issue. All I had to do was wrap each of the map functions in a div, like so:
import React, { useEffect, useState } from 'react'
import client from '../client'
import BlockContent from '#sanity/block-content-to-react'
import { Link } from 'react-router-dom'
function Main() {
const [posts, setPosts] = useState([])
useEffect(() => {
client.fetch(
`*[_type == "post"] {
title,
slug,
body,
author,
mainImage {
asset -> {
_id,
url
},
alt
},
publishedAt
}`
).then((data) => setPosts(data))
.catch(console.error)
}, [])
return (
<div className='grid lg:grid-cols-3 md:grid-cols-2 gap-8 m-4 '>
<div>
{posts.slice(0, 1).map((p, i) => (
<Link to = {`/blog/${p.slug.current}`} className=''>
<article key = {p.slug.current} className=''>
<img src = {p.mainImage.asset.url} alt = {p.title} className='' />
<div>
<p className='font-bold text-xl text-secondary'>{p.title}</p>
<p className='text-sm'>By Brandon Pyle | {new Date(p.publishedAt).toLocaleDateString()}</p>
</div>
</article>
</Link>
))}
</div>
<div className='my-[-16px]'>
{posts.slice(1, 4).map((p, i) => (
<Link to = {`/blog/${p.slug.current}`} className='col-start-2'>
<article key = {p.slug.current} className='flex my-4'>
<img src = {p.mainImage.asset.url} alt = {p.title} className='w-auto h-auto max-h-[80px]' />
<div>
<p className='font-bold text-xl text-secondary'>{p.title}</p>
<p className='text-sm'>By Brandon Pyle | {new Date(p.publishedAt).toLocaleDateString()}</p>
</div>
</article>
</Link>
))}
</div>
</div>
)
}
export default Main

excluding missing data when mapping through JSON in React/Js

I have a React component set up to map through a JSON file of projects and display the information in a card. However some of projects have less information that others. Namely my wordpress website does not need a link to the code. However I have it set up like:
Code:
<p>{project.code}</p>
How can I change this to an if statement, saying if Code is a property then return that block of code or else do not display 'code:' at all.
Here is my two files for reference.
Projects.js:
import React from "react";
import ReactCardFlip from "react-card-flip";
import Data from "../../ProjectData.json";
import './Projects.scss'
import '../MediaQueries/Projects.scss'
const CardStyle = {
padding: "30px",
margin: "30px",
width: "250px",
height: "300px",
};
const Card = ({ project }) => {
const [isFlipped, setIsFlipped] = React.useState(false);
// console.log(project);
return (
<div className="Card-wrapper">
<ReactCardFlip isFlipped={isFlipped} flipDirection="horizontal">
<div
style={CardStyle}
onMouseEnter={() => setIsFlipped((prev) => !prev)}
className="CardFront"
>
<div className="CardFront-div1">
<h3 className="CardFront-div1-title">{project.title}</h3>
<img width="250" src={project.gif} alt="" className="CardFront-div1-gif"/>
<div className="CardFront-div1-list">
<p>{project.html}</p>
<p>{project.css}</p>
<p>{project.javascript}</p>
<p>{project.react}</p>
</div>
</div>
</div>
<div
style={CardStyle}
onMouseLeave={() => setIsFlipped((prev) => !prev)}
className="CardBack"
>
<div>
<p>{project.description}</p>
<span>
Project:
<p>{project.link}</p>
</span>
<span>
Code:
<p>{project.code}</p>
</span>
</div>
</div>
</ReactCardFlip>
<button onClick={() => setIsFlipped((prev) => !prev)} className="cardflip-button">Flip</button>
</div>
);
};
const Projects = () => {
return (
<>
<h1>Projects</h1>
<div className="Projects" id="Projects">
{Data.map((item, index) => (
<Card project={item} key={`card-${index}`} />
))}
</div>
</>
);
};
export default Projects;
{
project.code ? (
<span>
Code:
<p>{project.code}</p>
</span>
) : null
}
Post got deleted by the user but the code is what I was looking for:
{!!project.code && (
<span >
Code:
<p>{project.code}</p>
</span>
)}

HTML - ReactJS: How to shown an image inside a <div>

I am using Contentful as external container for my images.
I am building a boat visualizer using AISHub. All the vessels I am interested are injected into a table. When I click on the table I locate the marker (vessel) on the map and the image of that vessel pops up on a sidebar on the right of the map.
The problem I have is that I should also visualize the image of the vessel, but unfortunately I only visualize a weird icon as shown below:
Below the code I have so far:
import React from 'react';
import { Card, CardTitle, CardSubtitle, CardText, CardBody, CardImg } from 'reactstrap';
import '../components/SideBar.css';
import { Link } from 'react-router-dom';
import Client from '../Contentful';
class Sidebar extends React.Component {
state = {
ships: []
};
async componentDidMount() {
let response = await Client.getEntries({
content_type: 'cashmanCards'
});
const ships = response.items.map((item) => {
const { name, slug, type, company, description, images, companylogo } = item.fields;
return {
name,
slug,
type,
company,
description,
images,
companylogo
};
});
this.setState({
ships
});
}
getFilteredShips = () => {
if (!this.props.activeShip) {
return this.state.ships;
}
return this.state.ships.filter((ship) => this.props.activeShip.name.toLowerCase() === ship.name.toLowerCase());
};
render() {
return (
<div className="map-sidebar">
{this.props.activeShipTypes}
<pre>
{this.getFilteredShips().map((ship) => (
<Card className="mb-2">
<CardImg />
<CardBody>
<div className="row">
{/* <div className="column"> */}
<img className="image-sizing-primary" src={ship.companylogo} alt="shipImage" />
</div>
<div>
<img className="image-sizing-secondary" src={ship.images} alt="shipImage" />
</div>
<CardTitle>
<h3 className="thick">{ship.name}</h3>
</CardTitle>
<CardSubtitle>{ship.type}</CardSubtitle>
<CardText>
<br />
<h6>Project Details</h6>
<p>For a description of the project view the specification included</p>
</CardText>
<div class="btn-toolbar">
<SpecsButton />
<Link to="/vessels/Atchafalaya" className="btn btn-primary">
Go to vessel
</Link>
</div>
</CardBody>
</Card>
))}
</pre>
</div>
);
}
}
export default Sidebar;
EDITS:
class Sidebar extends React.Component {
state = {
ships: []
};
async componentDidMount() {
let response = await Client.getEntries({
content_type: 'cashmanCards'
});
const ships = response.items.map((item) => {
const { name, slug, type, company, description, images, companylogo } = item.fields;
return {
name,
slug,
type,
company,
description,
images,
companylogo
};
});
this.setState({
ships
});
}
getFilteredShips = () => {
if (!this.props.activeShip) {
return this.state.ships;
}
return this.state.ships.filter((ship) => this.props.activeShip.name.toLowerCase() === ship.name.toLowerCase());
};
{this.getFilteredShips().map((ship) => (
console.log(ship);
return (
<div className="map-sidebar">
<Card className="mb-2">
<CardImg />
<CardBody>
<div className="row">
<img className="image-sizing-primary" src={ship.companylogo} alt="shipImage" />
</div>
<div>
<img className="image-sizing-secondary" src={ship.images} alt="shipImage" />
</div>
<CardTitle>
<h3 className="thick">{ship.name}</h3>
</CardTitle>
<CardSubtitle>{ship.type}</CardSubtitle>
<CardText>
<br />
<h6>Project Details</h6>
<p>For a description of the project view the specification included</p>
</CardText>
<div class="btn-toolbar">
<SpecsButton />
<Link to="/vessels/Atchafalaya" className="btn btn-primary">
Go to vessel
</Link>
</div>
</CardBody>
</Card>
</div>
)))}
}
export default Sidebar;
EDITS 2:
class Sidebar extends React.Component {
state = {
ships: []
};
async componentDidMount() {
let response = await Client.getEntries({
content_type: 'cashmanCards'
});
const ships = response.items.map((item) => {
const { name, slug, type, company, description, images, companylogo } = item.fields;
return {
name,
slug,
type,
company,
description,
images,
companylogo
};
});
this.setState({
ships
});
}
getFilteredShips = () => {
if (!this.props.activeShip) {
return this.state.ships;
}
return this.state.ships.filter((ship) => this.props.activeShip.name.toLowerCase() === ship.name.toLowerCase());
};
{this.getFilteredShips().map((ship) => {
console.log(ship);
render() {
return (
<Card className="mb-2">
<CardImg />
<CardBody>
<div className="row">
{/* <div className="column"> */}
<img className="image-sizing-primary" src={ship.companylogo} alt="shipImage" />
</div>
<div>
<img className="image-sizing-secondary" src={ship.images} alt="shipImage" />
</div>
<CardTitle>
<h3 className="thick">{ship.name}</h3>
</CardTitle>
<CardSubtitle>{ship.type}</CardSubtitle>
<CardText>
<br />
<h6>Project Details</h6>
<p>For a description of the project view the specification included</p>
</CardText>
<div class="btn-toolbar">
<SpecsButton />
<Link to="/vessels/Atchafalaya" className="btn btn-primary">
Go to vessel
</Link>
</div>
</CardBody>
</Card>
)
}
})}
}
export default Sidebar;
Below a print screen on how Contentful is structured:
What I have done so far:
1) I was able to implement the table click event as well as finding the marker (vessel) and show its card on the right of a sidebar, and thought that it would have been easy to finally show the vessel image. Unfortunately the implementation does not show the image.
I should mention that I used reactstrap Cards.
Maybe there is an error in how Contentful is reading the image?
2) After researching more this problem I came across this post which was useful. The problem was that the image uploaded was local, I have an image that is external on an external container.
Thanks for pointing in the right direction.
here you go
import React from 'react';
import { Card, CardTitle, CardSubtitle, CardText, CardBody, CardImg } from 'reactstrap';
import '../components/SideBar.css';
import { Link } from 'react-router-dom';
import Client from '../Contentful';
class Sidebar extends React.Component {
state = {
ships: []
};
async componentDidMount() {
let response = await Client.getEntries({
content_type: 'cashmanCards'
});
const ships = response.items.map((item) => {
const { name, slug, type, company, description, images, companylogo } = item.fields;
return {
name,
slug,
type,
company,
description,
images,
companylogo
};
});
this.setState({
ships
});
}
getFilteredShips = () => {
if (!this.props.activeShip) {
return this.state.ships;
}
return this.state.ships.filter((ship) => this.props.activeShip.name.toLowerCase() === ship.name.toLowerCase());
};
render() {
return (
<div className="map-sidebar">
{this.props.activeShipTypes}
<pre>
{this.getFilteredShips().map((ship) => {
console.log(ship);
return (
<Card className="mb-2">
<CardImg />
<CardBody>
<div className="row">
{/* <div className="column"> */}
<img className="image-sizing-primary" src={ship.companylogo} alt="shipImage" />
</div>
<div>
<img className="image-sizing-secondary" src={ship.images} alt="shipImage" />
</div>
<CardTitle>
<h3 className="thick">{ship.name}</h3>
</CardTitle>
<CardSubtitle>{ship.type}</CardSubtitle>
<CardText>
<br />
<h6>Project Details</h6>
<p>For a description of the project view the specification included</p>
</CardText>
<div class="btn-toolbar">
<SpecsButton />
<Link to="/vessels/Atchafalaya" className="btn btn-primary">
Go to vessel
</Link>
</div>
</CardBody>
</Card>
)
})}
</pre>
</div>
);
}
}
export default Sidebar;

Categories

Resources