I have 2 Components "TableCard" et "TableGrouping". I have a component inside "TableCard" called "Grouping".
When I hover the button with my mouse it is flickering/flashing on my screen. The 2 components are separated in 2 files because I need to modify the content of "TableGrouping" in "TableCard" (when I put directly the content of grouping into "TableGrouping" it's working fine but it's not my objective.
Here is my code:
export function TableGrouping(props) {
return (
<div className="form">
<div className="row align-items-center form-group-actions margin-top-20 margin-bottom-20">
<div className="col-xl-12">
<div className="form-group form-group-inline">
<div className="form-label form-label-no-wrap">
{props.children}
</div>
</div>
</div>
</div>
</div>
);
}
export function TableCard() {
const Grouping = () => {
function BtnSupprimer(props) {
return <Button>test</Button>;
}
return (
<>
<BtnSupprimer/>
</>
);
};
return (
<TableGrouping>
<Grouping />
</TableGrouping>
);
}
Link of what it's doing : here
Do some of you have an Idea ? Thank you :)
Related
Using React.JS and BootStrap grid system, I'm aiming to build the following page.
However, with the code linked at the bottom, the page looks like this (the alignment of the elements is wrong in multiple places. For example, the banner and search bar aren't aligned with the rest of the elements.
What am I doing wrong in using the BootStrap Grid System?
Before that, I'd like to specify that all the 4 MinWidget.jsx components are wrapped inside a MinWidgetCollection.jsx component. And all the elements encompased by the red border are wrapped inside a PageInformation.jsx component. The MiniWidgetCollection must take 7/12 of the page width while the BigWidget one the rest of 5/12 (with BootStrap grid having a maximum of 12 columns per row). Similarly, the first chart below must have 7/12 of width while the second chart only 5/12.
This is the current code which produces errors in alignment.
function App() {
return (
<div className='container'>
<Searchbar/>
<Banner/>
<PageInformation/>
</div>
)
}
export const Searchbar = (props) => {
return (
<div className='row mb-5' style={{border: "1px solid green"}}>
<div className='card-header p-7 w-50'>
</div>
)
export const Banner = (props) => {
return (
<div className='row'>
<div className='card mb-5 mb-xl-10'>
</div>
</div>
)
export const PageInformation = (props) => {
return (
<div style={{border: "1px solid red"}}>
<div className='row'>
<MinWidgetCollection />
<BigWidget />
</div>
<div className='row'>
<Chart newClassname='col-md-7 col-xs-12' />
<Chart newClassname='col-md-5 col-xs-12' />
</div>
</div>
)
}
export const MinWidgetCollection = (props) => {
return (
<div className='row col-md-7 col-xs-12'>
<MinWidget />
<MinWidget />
<MinWidget />
<MinWidget />
</div>
)
}
export const MinWidget = (props) => {
return (
<div className='col-md-6 col-xs-12'>
<div className='card card-md-6 card-xs-12 mb-xl-8'>
</div>
</div>
)
}
export const BigWidget = (props) => {
return (
<div className='col-md-5 col-xs-12'>
<div className="card card-xl-stretch mb-5 mb-xl-8 h-100">
</div>
</div>
)
}
export const Chart = (props) => {
<div className={props.newClassname}>
<div className={`card mt-5 `}>
</div>
</div>
}
I'm trying to load a pdf file for the user in another tab once they click a button but it's not working and I'm not sure how to make it work. Could I have some help in doing this?
I defined a function PdfViewer() and I call it when a button is clicked using onClick(), but once the button is clicked I get this error:
Uncaught Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
Here's my code:
import "../styles/ProjectDetails.css";
import React, { useState } from 'react'
import { Document, Page } from 'react-pdf/dist/esm/entry.webpack'
function PdfViewer() {
const [numPage, setNumPages] = useState(null);
const [pageNumber, setPageNumber] = useState(1);
function onDocumentLoadSuccess({numPages}) {
setNumPages(numPage);
setPageNumber(1);
}
return (
<div>
<header>
<Document file="../pdfs/Mini_Case_Study_15.pdf" onLoadSuccess={onDocumentLoadSuccess}>
<Page height="600" pageNumber={pageNumber}></Page>
</Document>
</header>
</div>
)
}
const ProjectDetails = ({ project }) => {
return (
<div className="card-grid">
<div className="card">
<div className="card-header card-image">
<img src="https://c4.wallpaperflare.com/wallpaper/672/357/220/road-background-color-hd-wallpaper-thumb.jpg"/>
</div>
<div className="card-title"><strong>{project.sdg}</strong></div>
<div className="card-body">
<strong>Goal:</strong> {project.goal}
</div>
<div className="card-themes">
<strong>Themes:</strong> {project.theme.map((theme)=>{return theme + ', '})}
</div>
<div className="card-assignment">
<strong>Assignment Type:</strong> {project.assignment_type}
</div>
<div className="card-footer">
<button className="btn">Details</button>
{project.assignment_type === 'Mini Case Studies' &&
<>
<button className="btn btn-outline">Download</button>
{/* <button onClick={PdfViewer} className="btn">Preview</button> */}
</>
}
</div>
</div>
</div>
)
}
export default ProjectDetails
How do I make it so that once the user clicks the button, it takes them to another page with the pdf file shown?
You could try this approach here, inserting the Preview as a Component.
const ProjectDetails = ({ project }) => {
const [preview, setPreview] = useState(false)
const onClickToPreviewPDF = () => {
setPreview(preview ? false : true);
}
return (
<>
<div className="card-grid">
<div className="card">
<div className="card-header card-image">
<img src="https://c4.wallpaperflare.com/wallpaper/672/357/220/road-background-color-hd-wallpaper-thumb.jpg"/>
</div>
<div className="card-title"><strong>{project.sdg}</strong></div>
<div className="card-body">
<strong>Goal:</strong> {project.goal}
</div>
<div className="card-themes">
<strong>Themes:</strong> {project.theme.map((theme)=>{return theme + ', '})}
</div>
<div className="card-assignment">
<strong>Assignment Type:</strong> {project.assignment_type}
</div>
<div className="card-footer">
<button className="btn">Details</button>
{project.assignment_type === 'Mini Case Studies' &&
<>
<button className="btn btn-outline">Download</button>
<button onClick={onClickToPreviewPDF} className="btn">Preview</button>
</>
}
</div>
</div>
</div>
{preview && <PdfViewer />}
</>
)
}
I'm new in next js and I'm working on project using NextJS. I have some lots in my items page that shows lots currently(pagination/items.tsx) and I also have lotDetails page that I want it to show details of each lot using dynamic route(lotDetails\id\index.tsx).
This is the folder structure:
Now when I click the Link in Items.tsx I expect it to go to lotDetails page and pass the props, but nothing happens! (It stays on Items page!). here is Items.tsx:
import React from 'react'
import Link from "next/link"
const Items = ({currentItems}:{currentItems:any}) => {
console.log(currentItems)
// const ids=currentItems.map((el:any)=>el.id)
// const paths=ids.map((el:any)=>{params:{id:el.toString()}})
// console.log(paths)
return (
<>
<div className="container">
<div className="row">
{currentItems.map((el:any)=><div className="col-md-3 ">
//this should be linked to lotDetails page!
<Link href={{pathname:"../lotDetails/[id]",query:{id:JSON.stringify(el.id),title:el.title,image:el.image,description:el.description.toString(),rate:el.rating.rate,count:el.rating.count,price:el.price},}} as={`/lotDetails/${el.id.toString()}`}>
<div className="lot">
<div className="img-container">
<img src={el.image}/>
</div>
<div className="title">
{el.title}
</div>
<div className="price">
<span className="price-title">Price:</span>
<span>{el.price}</span>
</div>
</div>
</Link>
</div>)}
</div>
</div>
</>
)
}
export default Items;
I'm using getStaticProps and GetStaticPaths in lotDetails:
const LotDetails = (props:any) => {
const dispatch=useDispatch();
console.log(props)
const lotCount=1;
const addLots=()=>{
dispatch(AddCustomerLot({...props,lotCount:lotCount}))
}
return (
<>
<div className='container lot-details'>
<div className="row" >
<div className="col-md-6">
<div className="detail-container">
<div className="title-details"><h3>{props.title}</h3></div>
<div className="badge"><FontAwesomeIcon icon={faStar}/><span>{props.rate}</span></div>
<div className="inventory">
Inventory: <span className="count">{props.count}</span>
</div>
<div className="description-details">{props.description}</div>
<div className="price">Price: <span className="price-number">{props.price}$</span> </div>
<button className="btn btn-regist" onClick={addLots}>Add to shopping basket</button>
</div>
</div>
<div className="col-md-6"><img src={props.image} alt="" /></div>
</div>
</div>
</>
)
}
export const getStaticPaths:GetStaticPaths=async(context:any)=>{
const response= await axios.get("https://fakestoreapi.com/products")
const paths=response.data.map((el:any)=>({params:{id:el.id.toString()}}))
console.log(paths)
return{
paths,
fallback:'blocking'
}
}
export const getStaticProps:GetStaticProps=async(context:any)=>{
return{
props:
{
//recieve props
id:context.query.id,
title:context.query.title,
image:context.query.image,
description:context.query.description,
rate:context.query.rate,
count:context.query.count,
price:context.query.price
}
}
}
export default LotDetails;
when I deleted getStaticProps and getStaticPaths, the link worked! So I receive that link works perfectly and the problem is in getStaticProps and getStaticPaths. Of course I don't want to use getServerSideProps.
Update
According to julio's suggestion I changed pathName, and I also changed context.query to context.params.id:
Items:
<Link href={{pathname:`/lotDetails/${el.id}`,query:{id:JSON.stringify(el.id),title:el.title,image:el.image,description:el.description.toString(),rate:el.rating.rate,count:el.rating.count,price:el.price},}} as={`/lotDetails/${el.id.toString()}`}>
<div className="lot">
<div className="img-container">
<img src={el.image}/>
</div>
<div className="title">
{el.title}
</div>
<div className="price">
<span className="price-title">Price:</span>
<span>{el.price}</span>
</div>
</div>
</Link>
lotDetails:
return (
<>
<div className='container lot-details'>
<div className="row" >
<div className="col-md-6">
//I removed all section which used props and querys using comments
{/* <div className="detail-container">
<div className="title-details"><h3>{props.title}</h3></div>
<div className="badge"><FontAwesomeIcon icon={faStar}/><span>{props.rate}</span></div>
<div className="inventory">
Inventory: <span className="count">{props.count}</span>
</div>
<div className="description-details">{props.description}</div>
<div className="price">Price: <span className="price-number">{props.price}$</span> </div>
<button className="btn btn-regist" onClick={addLots}>Add to shopping basket</button>
</div> */}
</div>
{/* <div className="col-md-6"><img src={props.image} alt="" /></div> */}
</div>
</div>
</>
)
}
export const getStaticPaths:GetStaticPaths=async(context:any)=>{
const response= await axios.get("https://fakestoreapi.com/products")
const paths=response.data.map((el:any)=>({params:{id:el.id.toString()}}))
console.log(paths)
return{
paths,
fallback:'blocking'
}
}
export const getStaticProps:GetStaticProps=async(context:any)=>{
return{
props:
{
id:context.params.id,
// title:context.query.title,
// image:context.query.image,
// description:context.query.description,
// rate:context.query.rate,
// count:context.query.count,
// price:context.query.price
}
}
}
Finally, I solved problem in two steps:
1-I'm using google chrome browser, so I configured chrome and added my localhost port:
I used this link: chrome://inspect/, clicked configure button and added my localhost port(in my case localhost:3000)
2-I added this code to lotDetails page(the page which I used axios)
axios.defaults.httpsAgent=new https.Agent({
rejectUnauthorized:false,
})
don't forget to import:
import https from "https"
Now It's working.
Could you tell me why my offer content is always empty ?
The "toto" is not displayed and my data are displayed because of the line "console.log(offers").
const ListProduct = (offers : any) => {
console.log(offers);
const offersDisplay = offers ? (
<div>
{ () => {
console.log("test");
offers.map((shop :any) => {
shop.offers.map((offer:any) => {
return(
<div className="card border-secondary mb-3 listMaxWidth">
<div className="card-header">{shop.name}</div>
<div className="card-body">
<img src={offer.picture} className="imgOffer"/>
<h4 className="card-title">{offer.name}</h4>
<p className="card-text">{shop.description}</p>
</div>
</div>
);
});
})
}
}
</div>
):'toto';
return(
<div>
{offersDisplay }
</div>
)
}
export default ListProduct;
I tried so many different way to write it, unfortunately can't find the right way ...
Could you help me please ?
Thanks in advance
You don't need to pass a callback function in your code
const offersDisplay = offers ? (
<div>
//this callback
{ () => {
And also you don't return from your first map.
And the last thing is that you need to include the code in your return that way it gets executed every time the offers data is changed.
You need to change your code like this
const ListProduct = (offers : any) => {
return(
<div>
{
offers && offers.length && offers.map((shop :any) => {
return shop.offers.map((offer:any) => {
return(
<div className="card border-secondary mb-3 listMaxWidth">
<div className="card-header">{shop.name}</div>
<div className="card-body">
<img src={offer.picture} className="imgOffer"/>
<h4 className="card-title">{offer.name}</h4>
<p className="card-text">{shop.description}</p>
</div>
</div>
);
});
})
}
</div>
)
}
export default ListProduct;
On calling API I got multiple JSON objects (it could be 2,3,6 or some other count) which contains the array of string with the length of more than 6000 records in each object. I need to display these records in a bootstrap card.
For example, if I got 2 JSON object then 2 cards should be displayed and each bootstrap card contains the records' name with the checkboxes.
So, how can I manage the state of these checkboxes let say if I click on cardb apply button then only cardb checked checkboxes and the name of the card i.e., "cardb" should be captured somewhere so that I can use this info for further API calling.
Can someone please help me out in this?
Main.JSX
render() {
return (
<main
role="main"
className="flex-shrink-0">
<div className="container">
<form onSubmit={this.handleWidgetsCardFormSubmit}>
<div className="row flex-row flex-nowrap wc-main-div-scroll">
{this.displayWidgetsCard()}
</div>
</form>
</div>
</main>
);
}
displayWidgetsCard() {
if (this.state.displayWidgetsCard === true) {
console.log("Total widgets card to show: ",this.state.cardCount.length);
let t = [];
for (let i = 0; i < this.state.cardCount.length; i++) {
t.push(
<Card
key={this.state.cardCount[i].cardname}
cardName={this.state.cardCount[i].cardname}
recordCount={this.state.cardCount[i].count}
createCheckboxes={this.createCheckboxes3(this.state.cardCount[i].recordsArr)}
/>
);
}
return t;
} else {
return null;
}
}
componentWillMount = () => {
this.selectedCheckboxes3 = new Set();
};
toggleCheckbox3 = label => {
if (this.selectedCheckboxes3.has(label)) {
this.selectedCheckboxes3.delete(label);
} else {
this.selectedCheckboxes3.add(label);
}
};
createCheckbox3 = label => (
<Checkbox
label={label}
handleCheckboxChange={this.toggleCheckbox3}
key={label}
/>
);
createCheckboxes3 = array1 => array1.map(this.createCheckbox3);
Card.JSX
import React, { Component } from "react";
import "./styles.css";
class Card extends Component {
render() {
const { cardName, createCheckboxes, recordCount } = this.props;
return (
<div className="col-4">
<div className="card wc-dim border-dark sh">
<div className="card-header">
<b>
{cardName}
{" (" + recordCount + ")"}
</b>
<div className="input-group mt-2">
<input
type="text"
className="form-control search-form"
placeholder="Search"
/>
</div>
</div>
<div className="card-body wc-scroll">
<div className="card-text">{createCheckboxes}</div>
</div>
<div className="card-footer bg-transparent">
<button className="btn btn-primary" type="submit" id="btn-right">
Apply
</button>
</div>
</div>
</div>
);
}
}
export default Card;