can you please help me? i read that in routes the components need to change to elements but it still doesn't
render.
the page will not render the root path at localhost:3000/.
error message
react-dom.development.js:26091 Uncaught Error: Target container is not a DOM element.
App.js
import { render } from "react-dom";
import {
BrowserRouter,
Routes,
Route,
} from "react-router-dom";
import App from "./App";
import CreateBook from "./components/CreateBook";
import ShowBookDetails from "./components/ShowBookDetails";
import UpdateBookInfo from "./components/UpdateBookInfo";
const rootElement = document.getElementById("/");
render(
<BrowserRouter>
<Routes>
<Route path="/" element={<ShowBookDetails />} />
<Route path="create-book" element={<CreateBook />} />
<Route path="edit-book" element={<UpdateBookInfo />} />
</Routes>
</BrowserRouter>,
rootElement
);
export default App;
components/ShowBookDetails.js
import React, { Component } from 'react';
import { Link } from 'react-router-dom';
import '../App.css';
import axios from 'axios';
class showBookDetails extends Component {
constructor(props) {
super(props);
this.state = {
book: {}
};
}
componentDidMount() {
// console.log("Print id: " + this.props.match.params.id);
axios
.get('http://localhost:8082/api/books/'+this.props.match.params.id)
.then(res => {
// console.log("Print-showBookDetails-API-response: " + res.data);
this.setState({
book: res.data
})
})
.catch(err => {
console.log("Error from ShowBookDetails");
})
};
onDeleteClick (id) {
axios
.delete('http://localhost:8082/api/books/'+id)
.then(res => {
this.props.history.push("/");
})
.catch(err => {
console.log("Error form ShowBookDetails_deleteClick");
})
};
render() {
const book = this.state.book;
let BookItem = <div>
<table className="table table-hover table-dark">
{/* <thead>
<tr>
<th scope="col">#</th>
<th scope="col">First</th>
<th scope="col">Last</th>
<th scope="col">Handle</th>
</tr>
</thead> */}
<tbody>
<tr>
<th scope="row">1</th>
<td>Title</td>
<td>{ book.title }</td>
</tr>
<tr>
<th scope="row">2</th>
<td>Author</td>
<td>{ book.author }</td>
</tr>
<tr>
<th scope="row">3</th>
<td>ISBN</td>
<td>{ book.isbn }</td>
</tr>
<tr>
<th scope="row">4</th>
<td>Publisher</td>
<td>{ book.publisher }</td>
</tr>
<tr>
<th scope="row">5</th>
<td>Published Date</td>
<td>{ book.published_date }</td>
</tr>
<tr>
<th scope="row">6</th>
<td>Description</td>
<td>{ book.description }</td>
</tr>
</tbody>
</table>
</div>
return (
<div className="ShowBookDetails">
<div className="container">
<div className="row">
<div className="col-md-10 m-auto">
<br /> <br />
<Link to="/" className="btn btn-outline-warning float-left">
Show Book List
</Link>
</div>
<br />
<div className="col-md-8 m-auto">
<h1 className="display-4 text-center">Book's Record</h1>
<p className="lead text-center">
View Book's Info
</p>
<hr /> <br />
</div>
</div>
<div>
{ BookItem }
</div>
<div className="row">
<div className="col-md-6">
<button type="button" className="btn btn-outline-danger btn-lg btn-block" onClick={this.onDeleteClick.bind(this,book._id)}>Delete Book</button><br />
</div>
<div className="col-md-6">
<Link to={`/edit-book/${book._id}`} className="btn btn-outline-info btn-lg btn-block">
Edit Book
</Link>
<br />
</div>
</div>
{/* <br />
<button type="button" class="btn btn-outline-info btn-lg btn-block">Edit Book</button>
<button type="button" class="btn btn-outline-danger btn-lg btn-block">Delete Book</button> */}
</div>
</div>
);
}
}
export default showBookDetails;
you should write components name with uppercase:
class showBookDetails extends Component - class ShowBookDetails extends Component
Related
I have a project and in this project I have several salaries and I am trying to delete a salary, but no action has taken place, and I have no effect on the network,
How can I solve the problem?
I think the error is in the receipt file below
This file contains the delete function of Salary
receipt.js:
import { createSlice, createAsyncThunk } from "#reduxjs/toolkit";
import axios from "axios";
export const getReceipt = createAsyncThunk(
"Receipts/getReceipt",
async (params) => {
console.log("idddd: ", params);
const response = await axios.get(`/financial/receipts/${params}`);
console.log("url: ", "/financial/receipts/", params);
console.log("resss: ", response);
const data = response.data.data;
console.log("reddddd: ", data);
// return data === undefined ? null : data;
return data;
}
);
export const removeDeduction = createAsyncThunk(
"Receipts/removeDeduction",
async (receiptId, id, { dispatch, getState }) => {
console.log("receipt Id: ", receiptId);
console.log("deduction Id: ", id);
const response = await axios.delete(
`/financial/receipts/${receiptId}/deductions/${id}`
);
dispatch(getReceipt());
return response.data;
}
);
export const removeSalary = createAsyncThunk(
"Receipts/removeSalary",
async (receiptId, id, { dispatch, getState }) => {
console.log("receipt Id: ", receiptId);
console.log("deduction Id: ", id);
const response = await axios.delete(
`/financial/receipts/${receiptId}/salaries/${id}`
);
dispatch(getReceipt());
console.log("response delete: ", response.data);
return response.data;
}
);
const receiptSlice = createSlice({
name: "eCommerceApp/receipt",
initialState: null,
reducers: {},
extraReducers: {
[getReceipt.fulfilled]: (state, action) => action.payload,
[removeDeduction.fulfilled]: (state, action) => null,
[removeSalary.fulfilled]: (state, action) => null,
},
});
export default receiptSlice.reducer;
This file contains the entire code, and inside it, the function to delete a salary was called
ReceiptDetails.js:
import Avatar from "#material-ui/core/Avatar";
import Icon from "#material-ui/core/Icon";
import Tooltip from "#material-ui/core/Tooltip";
import Typography from "#material-ui/core/Typography";
import { useState } from "react";
import { useSelector } from "react-redux";
import IconButton from "#material-ui/core/IconButton";
import { removeDeduction, removeSalary } from "../../store/receiptSlice";
import { useDispatch } from "react-redux";
import { Link, useHistory } from "react-router-dom";
function ReceiptDetailsTab() {
const order = useSelector(({ eCommerceApp }) => eCommerceApp.receipt);
const dispatch = useDispatch();
const [map, setMap] = useState("shipping");
const history = useHistory();
function handleRemoveDeduction() {
dispatch(removeDeduction()).then(() => {
history.push("/apps/e-commerce/orders/1");
});
}
function handleRemoveSalary() {
dispatch(removeSalary());
}
return (
<div>
<div className="pb-48">
<div className="pb-16 flex items-center">
<Icon color="action">account_circle</Icon>
<Typography className="h2 mx-12 font-medium" color="textSecondary">
User
</Typography>
</div>
<div className="mb-24">
<div className="table-responsive mb-48">
<table className="simple">
<thead>
<tr>
<th>
<Typography className="font-semibold">Name</Typography>
</th>
<th>
<Typography className="font-semibold">Email</Typography>
</th>
<th>
<Typography className="font-semibold">Phone</Typography>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<div className="flex items-center">
{/* <Avatar src={order.user.avatar} /> */}
<Avatar src="assets/images/avatars/Lily.jpg" />
<Typography className="truncate mx-8">
{/* {`${order.customer.firstName} ${order.customer.lastName}`} */}
Samara Kamal
</Typography>
</div>
</td>
<td>
<Typography className="truncate">
{/* {order.customer.email} */}
samara#gmail.com
</Typography>
</td>
<td>
<Typography className="truncate">
{/* {order.customer.phone} */}
0947483381
</Typography>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</div>
<div className="pb-48">
<div className="pb-16 flex items-center">
<Icon color="action">attach_money</Icon>
<Typography className="h2 mx-12 font-medium" color="textSecondary">
Salary
</Typography>
</div>
<div className="table-responsive">
<table className="simple">
<thead>
<tr>
<th>
<Typography className="font-semibold">Amount</Typography>
</th>
<th>
<Typography className="font-semibold">
Work Start Date
</Typography>
</th>
<th>
<Typography className="font-semibold">
Work End Date
</Typography>
</th>
<th>
<Typography className="font-semibold">Bonus</Typography>
</th>
</tr>
</thead>
<tbody>
<tr>
<td>
<span>£</span>
<span className="truncate">{order.salary.amount}</span>
</td>
<td>
<span className="truncate">{order.salary.workStartDate}</span>
</td>
<td>
<span className="truncate">{order.salary.workEndDate}</span>
</td>
<td>
<span>£</span>
<span className="truncate">{order.salary.bonus}</span>
</td>
<td>
<IconButton
onClick={handleRemoveSalary}
style={{
color: "red",
border: "none",
marginLeft: "5rem",
}}
>
<Icon>delete</Icon>
</IconButton>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div className="pb-48">
<div className="pb-16 flex items-center">
<Icon color="action">moneyOff</Icon>
<Typography className="h2 mx-12 font-medium" color="textSecondary">
Deductions
</Typography>
</div>
<div className="table-responsive">
<table className="simple">
<thead>
<tr>
<th>
<Typography className="font-semibold">Amount</Typography>
</th>
<th>
<Typography className="font-semibold">Type</Typography>
</th>
<th>
<Typography className="font-semibold">Reason</Typography>
</th>
</tr>
</thead>
<tbody>
{order.deductions.map((deduction) => (
<tr key={deduction.id}>
<td>
<span>£</span>
<span className="truncate">{deduction.amount}</span>
</td>
<td>
<span className="truncate">{deduction.type}</span>
</td>
<td>
<span className="truncate">{deduction.reason}</span>
</td>
<td>
<IconButton
onClick={handleRemoveDeduction}
style={{ color: "red", border: "none" }}
>
<Icon>delete</Icon>
</IconButton>
</td>
</tr>
))}
</tbody>
</table>
</div>
</div>
</div>
);
}
export default ReceiptDetailsTab;
Issue
You don't have parameters in the function when you call it
Solve
export const removeDeduction = createAsyncThunk(
"Receipts/removeDeduction",
async (params, { dispatch, getState }) => {
console.log("receipt Id: ", params.receiptId);
console.log("deduction Id: ", params.id);
const response = await axios.delete(
`/financial/receipts/${params.receiptId}/deductions/${params.id}`
);
dispatch(getReceipt());
return response.data;
}
);
function handleRemoveDeduction() {
const params = {
receiptId: '',
id: ''
}
dispatch(removeDeduction(params)).then(() => {
history.push("/apps/e-commerce/orders/1");
});
}
TableItem component added without any data in UI. Could somebody help on this. On refereshing the UI, added data is shown with details in TableItem component.
Table Component Code
import TableItem from "./TableItem";
function Table({ searchWord }) {
const dispatch = useDispatch();
const dictData = useSelector((state) => state.dictionary);
useEffect(() => {
dispatch(getDictionaryAsync());
}, [dispatch]);
return (
<table className="table table-striped">
<thead>
<tr>
<th scope="col">Word</th>
<th scope="col">Description</th>
<th scope="col"></th>
</tr>
</thead>
<tbody>
{dictData &&
dictData
.filter((e) =>
searchWord === ""
? e
: e.word &&
e.word.toLowerCase().includes(searchWord.toLowerCase())
)
.map((item) => (
<TableItem item={item} key={item.id} searchWord={searchWord} />
))}
</tbody>
</table>
);
}
export default Table;
Below is the TableItem Component Code which i am trying to update,
When i add a word to dictionary it will fetch the details from the server and display it in the React app.
function TableItem({ item }) {
const [modal, setModal] = useState(false);
const openModal = () => {
setModal(true);
};
return (
<>
<tr key={item.id}>
<td style={{ textTransform: "capitalize" }}>{item.word}</td>
<td>
<b style={{ textTransform: "capitalize" }}>
{item.items && item.items[0].category} -{" "}
</b>
{item.items && truncate(item.items[0].definitions[0])}
</td>
<td>
<button className="btn btn-danger btn-sm " onClick={openModal}>
View
</button>
</td>
</tr>
<Modal isOpen={modal} ariaHideApp={true}>
<div className="modal-header">
<h3 className="modal-word-header">
{item.word && item.word.toUpperCase()}
</h3>
<button
className="btn btn-danger btn-sm"
onClick={() => setModal(false)}
>
<i class="fa fa-times" aria-hidden="true"></i>
</button>
</div>
<div className="model-content">
<p>
{item.items &&
item.items.map((e) => {
return (
<>
<i>{e.category}</i>
<ul>
{e.definitions.map((def) => {
return <li>{def}</li>;
})}
</ul>
</>
);
})}
</p>
</div>
</Modal>
</>
);
}
Better add your TableItem component code!
Below code works fine and updated the UI on change in the Data in TableItem,
useEffect(() => {
dispatch(getDictionaryAsync());
}, [dispatch, dictData]); *<--updated code*
I am new to react,
i am trying to use async function but i have facing the following error
"Error: Objects are not valid as a React child (found: [object Promise]). If you meant to render a collection of children, use an array instead."
import {
Badge,
Card,
CardHeader,
CardFooter,
DropdownMenu,
DropdownItem,
UncontrolledDropdown,
DropdownToggle,
Media,
Pagination,
PaginationItem,
PaginationLink,
Table,
Container,
Row,
UncontrolledTooltip,
} from "reactstrap";
// core components
import Header from "components/Headers/Header.js";
import 'react-toastify/dist/ReactToastify.css';
import { Link } from "react-router-dom";
import axios from "axios";
import data from "./data";
var apitoken= localStorage.getItem('apitoken');
const api=axios.create({baseURL:"https://IP/DeAPI/api/v1/account"})
const options = {
headers: {'Authorization': apitoken}
}
const asynchronousFunction = async () => {
const response = await api.get("/",options)
window.input=response.data.response
}
const mainFunction = async () => {
const result = await asynchronousFunction()
return result
}
const state = { students:window.input}
//console.log(window.input);
const renderTableData=async ()=> {
console.log("test"+await mainFunction())
if(state.students) {
return state.students.map((student, index) => {
const { id, name, age, email } = student //destructuring
return (
<tr key={id}>
<th scope="row">
<Media className="align-items-center">
<a
className="avatar rounded-circle mr-3"
href="#pablo"
onClick={(e) => e.preventDefault()}
>
<img
alt="..."
src={
require("../../assets/img/theme/bootstrap.jpg")
.default
}
/>
</a>
<Media>
<span className="mb-0 text-sm">{id} </span>
</Media>
</Media>
</th>
<td>
<Badge color="" className="badge-dot mr-4">{name}</Badge>
</td>
<td>
<Badge color="" className="badge-dot mr-4">{age}</Badge>
</td>
<td>
<Badge color="" className="badge-dot mr-4">{email}</Badge>
</td>
</tr>
)
})
}
else
{
console.log("Something went wrong")
}
}
const Accounts = () => {
return (
<>
<Header />
{/* Page content */}
<Container className="mt--7" fluid>
{/* Table */}
<Row>
<div className="col">
<Card className="shadow">
<CardHeader className="border-0">
<h3 className="mb-0">All Account</h3>
</CardHeader>
<div>
</div>
<Table className="align-items-center table-flush" responsive>
<thead className="thead-light">
<tr>
<th scope="col">Account Name</th>
<th scope="col">Phone</th>
<th scope="col">Email</th>
<th scope="col">Account Owner</th>
{/* <th scope="col">Pincode</th> */}
<th scope="col" />
</tr>
</thead>
<tbody>
{renderTableData()}
</tbody>
</Table>
</Card>
</div>
</Row>
</Container>
</>
);
};
export default Accounts;
What have i done wrong here;
I am trying to get the student data from api and render it in the component dynamically.
The issue is with
<tbody>
{renderTableData()}
</tbody>
If i removed it its working,
Thanks in advance
You should not put anything except JSX into JSX. The problem is that async function returns Promise instead of JSX. You should rather use React.useEffect and React.useState to solve the loading problem. Let me show you.
Acutally another problem might be returning an array. Try wrapping it into <>...</> as I did.
import * as React from "react";
import {
Badge,
Card,
CardHeader,
CardFooter,
DropdownMenu,
DropdownItem,
UncontrolledDropdown,
DropdownToggle,
Media,
Pagination,
PaginationItem,
PaginationLink,
Table,
Container,
Row,
UncontrolledTooltip,
} from "reactstrap";
// core components
import Header from "components/Headers/Header.js";
import 'react-toastify/dist/ReactToastify.css';
import { Link } from "react-router-dom";
import axios from "axios";
import data from "./data";
var apitoken= localStorage.getItem('apitoken');
const api=axios.create({baseURL:"https://IP/DeAPI/api/v1/account"})
const options = {
headers: {'Authorization': apitoken}
}
const TableData = () => {
const [students, setStudents] = React.useState([]);
const [loading, setLoading] = React.useState(true);
React.useEffect(async () => {
const response = await api.get("/",options);
setStudents(response.data.response);
setLoading(false);
}, []);
if (loading) {
return <>Loading...</>;
}
return (
<>
{students.map((student, index) => {
const { id, name, age, email } = student //destructuring
return (
<tr key={id}>
<th scope="row">
<Media className="align-items-center">
<a
className="avatar rounded-circle mr-3"
href="#pablo"
onClick={(e) => e.preventDefault()}
>
<img
alt="..."
src={
require("../../assets/img/theme/bootstrap.jpg")
.default
}
/>
</a>
<Media>
<span className="mb-0 text-sm">{id} </span>
</Media>
</Media>
</th>
<td>
<Badge color="" className="badge-dot mr-4">{name}</Badge>
</td>
<td>
<Badge color="" className="badge-dot mr-4">{age}</Badge>
</td>
<td>
<Badge color="" className="badge-dot mr-4">{email}</Badge>
</td>
</tr>
)
})}
</>
)
}
const Accounts = () => {
return (
<>
<Header />
{/* Page content */}
<Container className="mt--7" fluid>
{/* Table */}
<Row>
<div className="col">
<Card className="shadow">
<CardHeader className="border-0">
<h3 className="mb-0">All Account</h3>
</CardHeader>
<div>
</div>
<Table className="align-items-center table-flush" responsive>
<thead className="thead-light">
<tr>
<th scope="col">Account Name</th>
<th scope="col">Phone</th>
<th scope="col">Email</th>
<th scope="col">Account Owner</th>
{/* <th scope="col">Pincode</th> */}
<th scope="col" />
</tr>
</thead>
<tbody>
<TableData />
</tbody>
</Table>
</Card>
</div>
</Row>
</Container>
</>
);
};
export default Accounts;
You should use the lifecycle hook useEffect to fetch async data (when working with functional components).
you also want to save your data in state. This is the default way to work with apis in react. Simply storing it in a variable will not work due to React's async behaviour.
Your error here is that you are trying to render a promise, which is not valid JSX
you can use the hook like this
const [state, setState] = useState({})
...
useEffect(() =>{
async(() =>{
const data = await mainFunction()
setState(data)
})()
}, []) //empty array means to only run once
<tbody>
{state.students?.map((student, index) => {
const { id, name, age, email } = student //destructuring
return (
<tr key={id}>
<th scope="row">
<Media className="align-items-center">
<a
className="avatar rounded-circle mr-3"
href="#pablo"
onClick={(e) => e.preventDefault()}
>
<img
alt="..."
src={
require("../../assets/img/theme/bootstrap.jpg")
.default
}
/>
</a>
<Media>
<span className="mb-0 text-sm">{id} </span>
</Media>
</Media>
</th>
<td>
<Badge color="" className="badge-dot mr-4">{name}</Badge>
</td>
<td>
<Badge color="" className="badge-dot mr-4">{age}</Badge>
</td>
<td>
<Badge color="" className="badge-dot mr-4">{email}</Badge>
</td>
</tr>
)
})
}
</tbody>
Try this one instead
I'm new in React and I have to create a CRUD table for my DB.
I created a simple table as you can see:
class ListPromoCatalog extends React.Component {
constructor(props) {
super(props);
this.state = {
promos: [],
message: null
};
this.refreshPromo = this.refreshPromo.bind(this)
}
componentDidMount() { //React defines a component lifecycle
this.refreshPromo();
}
refreshPromo() {
PromoCatalogService.retrieveAllPromo(PRIZES)//this would make the call to the REST API.
.then(
response => {
console.log(response);
this.setState({promos: response.data.viaggio})
}
)
}
PromoOffClicked(id) {
PromoCatalogService.promoOff(PRIZES, id)
.then(
response => {
console.log(response);
this.setState({message: `Promo ${id} OFF Successful`});
this.refreshPromo();
}
)
}
updatePromoClicked(id) {
console.log('update ' + id);
this.props.history.push(`/promos/${id}`);
}
addCourseClicked() {
this.props.history.push(`/promos/-1`);
}
render() {
return (
<div className="container">
<h3>All Promo</h3>
<div className="row">
<FileUploader/>
</div>
{this.state.message && <div className="alert alert-success">{this.state.message}</div>}
<div className="container">
<table className="table">
<thead>
<tr>
<th>Id</th>
<th>Item</th>
<th>Title</th>
<th>Description</th>
<th>Delete</th>
<th>Update</th>
</tr>
</thead>
<tbody>
{
this.state.promos.map(
promo =>
<tr key={promo.promoId}>
<td>{promo.promoId}</td>
<td>{promo.ijCod}</td>
<td>{promo.title}</td>
<td>{promo.description}</td>
<td>
<button className="btn btn-warning"
onClick={() => this.PromoOffClicked(promo.promoId)}>OFF
</button>
</td>
<td>
<button className="btn btn-success"
onClick={() => this.updatePromoClicked(promo.promoId)}>Update
</button>
</td>
</tr>
)
}
</tbody>
</table>
<div className="row">
<button className="btn btn-success" onClick={this.addCourseClicked}>Add</button>
</div>
</div>
</div>
)
}
}
export default ListPromoCatalog
I would like to do the same thing with a Material Table but I don't know how to put data and methods in my new class.
I would like to do the same thing with a Material Table but I don't know how to put data and methods in my new class.
render() {
return (
<>
<PanelHeader size="sm"/>
<div className="content">
<Row>
<Col xs={12}>
<Card>
<CardHeader>
<CardTitle tag="h4">Simple Table</CardTitle>
</CardHeader>
<CardBody>
<MDBDataTable
striped
bordered
small
data={data} //DATA SHOULD CONTAIN HEADERS AND COLUMNS
/>
</CardBody>
</Card>
</Col>
</Row>
</div>
</>
);
}
There is a 'Print' button on SaleInvoice.js which shows the Modal containing Report.js.
Report.js is created only to describe how and what should be displayed in the printed page.
Report.js has a button 'Print' which opens the Print Preview in the browser.
How do I make the 'Print' button on SaleInvoice.js directly open the Print Preview in the browser?
SaleInvoice.js
...
<button
style={{marginRight: '200px'}}
onClick={() => this.setState({printView: true})}>
Print
</button>
{this.state.printView ? (
<Modal
type="Print"
{...this.props}
show={this.state.printView}
modalClosed={() => this.setState({printView: false})}
/>
) : null}
...
Report.js
import React from 'react';
import styles from './SaleInvoice.module.css';
const SaleInvoice = props => {
const {customerName} = props;
const rows = props.lineItems;
const alignRightMarginRight = [styles.alignRight, styles.marginRight].join(
' ',
);
const {amountBeforeFreight, freight, amountAfterFreight} = props;
const reverseDateString = date => {
let [yyyy, mm, dd] = date.split('-');
return dd + '-' + mm + '-' + yyyy;
};
const renderContent = () => {
let i = 0;
let contentRows = (i, d) => {
return (
<React.Fragment>
<td className={styles.serialNumber}>{i}</td>
<td className={styles.productName}>{d.product_name}</td>
<td className={alignRightMarginRight}>{d.product_qty}</td>
<td className={alignRightMarginRight}>{d.product_unit}</td>
<td className={alignRightMarginRight}>{d.product_rate}</td>
<td className={alignRightMarginRight}>{d.product_disc}</td>
<td className={alignRightMarginRight}>{d.sub_total}</td>
</React.Fragment>
);
};
return rows.map(d => {
i++;
if (i === rows.length) {
return null;
}
if (i % 10 === 0) {
return (
<tr key={i} className={styles.pagebreak}>
{contentRows(i, d)}
</tr>
);
} else {
return <tr key={i}>{contentRows(i, d)}</tr>;
}
});
};
return (
<React.Fragment>
<div className={styles.all}>
<div className={[styles.header].join(' ')}>
<button className={styles.hideInPrint} onClick={window.print}>
Print
</button>
<button className={styles.hideInPrint} onClick={props.modalClosed}>
Close
</button>
<h5 className={styles.docTitle}>Estimate</h5>
<h6 className={styles.customerName}>
{customerName}
<span className={styles.date}>
{reverseDateString(props.date.split('T')[0])}
</span>
</h6>
</div>
<table className={styles.content}>
<thead>
<tr>
<td>No</td>
<td>Name</td>
<td className={alignRightMarginRight}>Qty</td>
<td className={alignRightMarginRight}>Unit</td>
<td className={alignRightMarginRight}>Rate</td>
<td className={alignRightMarginRight}>Disc</td>
<td className={alignRightMarginRight}>Total</td>
</tr>
</thead>
<tbody className={styles.content}>{renderContent()}</tbody>
</table>
<div className={styles.footer}>
<div className={styles.foot}>
<label>Amount:</label>
<label className={styles.amount}>
{amountBeforeFreight.toFixed(2)}
</label>
</div>
<div className={styles.foot}>
<label>Freight:</label>
<label className={styles.amount}>
{freight ? freight.toFixed(2) : 0}
</label>
</div>
<div className={styles.foot}>
<label>Final Amount:</label>
<label className={styles.amount}>
{amountAfterFreight.toFixed(2)}
</label>
</div>
</div>
</div>
</React.Fragment>
);
};
export default SaleInvoice;
in your file SalesInvoice.js, we would be changing the event onClick, instead of what action does(setting modal view to true in your state) we want it to open the print window in the browser.
as follows
<button
style={{marginRight: '200px'}}
onClick={window.print} >
Print
</button>
you will not need this part I guess?
{this.state.printView ? (
<Modal
type="Print"
{...this.props}
show={this.state.printView}
modalClosed={() => this.setState({printView: false})}
/>
) : null}