Intended function: Projects names pulled from MySQL database that are listed in table column, will be a link to /projects page listing related unique information.
What is actually happening: Project names that are pulled from MySQL database that are listed in table column, are not links.
See pics for details: https://imgur.com/a/jp1JvV0
Dashboard.js
import React, { useState, useEffect } from "react";
import { DataTable } from "primereact/datatable";
import { Column } from "primereact/column";
import { Button } from "primereact/button";
// import ButtonDemo from './ButtonDemo';
import { Chart } from "primereact/chart";
import { InputText } from "primereact/inputtext";
import { InputTextarea } from "primereact/inputtextarea";
import { Modal, ModalFooter, ModalHeader } from "react-bootstrap";
import axios from "axios";
import { useHistory, Link } from "react-router-dom";
// import { Media } from "react-bootstrap/Media"
// import ProjectsTable from "./Tables/ProjectsTable";
// import TicketsPieChart from "./Tables/TicketsPieChart"
// import API from
//project table
//eslint-disable no-unused-vars
const TableDemo = () => {
// const toggle = () => {setShow(!show);}
const [project_name, setProjectName] = useState("");
const [description, setDescription] = useState("");
const [projects, setProjects] = useState([]);
const history = useHistory();
useEffect(() => {
getProjects();
}, []);
const getProjects = async () => {
const response = await axios.get("http://localhost:5002/bugtracker_table");
setProjects(response.data);
};
const saveProject = async (e) => {
e.preventDefault();
await axios.post("http://localhost:5002/bugtracker_table", {
project_name: project_name,
description: description,
});
history.push("/");
};
const [show, setShow] = useState(false);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
return (
<>
<div className="grid table-demo">
<div className="col-12">
<div className="card">
<h5>Projects</h5>
<div>
<Button label="New Project" className="p-button-rounded mr-2 mb-2 npbutton" onClick={handleShow} />
</div>
<Modal className="modal" show={show} onHide={handleClose}>
<form onSubmit={saveProject}>
<div className="grid p-fluid">
<div className="col-12 md:col-6">
<div className="card">
<ModalHeader>
<h5>Projects</h5>
</ModalHeader>
<div className="grid formgrid">
<div className="col-12 mb-2 lg:col-4 lg:mb-0">
<InputText value={project_name} onChange={(e) => setProjectName(e.target.value)} type="text" placeholder="Enter project name"></InputText>
</div>
</div>
<h5>Project Description</h5>
<InputTextarea value={description} onChange={(e) => setDescription(e.target.value)} type="text" placeholder="Enter project description" autoResize rows="3" cols="30" />
<ModalFooter>
<Button label="Submit" className="p-button-rounded p-button-success mr-2 mb-2" />
<Button onClick={handleClose}>Close</Button>
</ModalFooter>
</div>
</div>
</div>
</form>
</Modal>
{/* // <Link to="/ticketlist" className="col-12"> */}
<div>
{/* // className="card"></Link> */}
<DataTable
// sortMode="single" sortField="representative.name"
value={projects}
sortOrder={1}
scrollable
scrollHeight="400px"
responsiveLayout="scroll"
>
<Column field="project_name" header="Project Name" style={{ minWidth: "200px" }}></Column>
{/* <Column field="ticket_title" header="Ticket Title" style={{ minWidth: "200px" }}></Column> */}
<Column field="description" header="Description" style={{ minWidth: "350px" }}></Column>
<Column field="status" header="Status" style={{ minWidth: "200" }}></Column>
<Column field="createdAt" header="Date" style={{ minWidth: "200px" }}></Column>
{projects.map((project, index) => (
<tr key={project.id}>
<td>{index + 1}</td>
<td>
<Link to={`/projects/${project.id}`}>{project.project_name}</Link>
</td>
<td>{project.description}</td>
<td>{project.createdAt}</td>\{" "}
</tr>
))}
</DataTable>
</div>
</div>
</div>
<div className="grid p-fluid">
<div className="col-12 lg:col-6">
<div className="card flex flex-column align-items-center">
<h5>Tickets by Type</h5>
<Chart type="pie" focus={"type"} />
</div>
</div>
</div>
<div className="grid p-fluid">
<div className="col-12 lg:col-6">
<div className="card flex flex-column align-items-center">
<h5>Tickets by Priority</h5>
<Chart type="pie" focus={"priority"} />
</div>
</div>
</div>
<div className="grid p-fluid">
<div className="col-12 lg:col-6">
<div className="card flex flex-column align-items-center">
<h5>Tickets by Status</h5>
<Chart type="pie" focus={"status"} />
</div>
</div>
</div>
</div>
</>
);
};
export default React.memo(TableDemo);
You could do a map to the projects array into a new variable before passing it to the Datatable value parameter
const projectsToShow = projects.map(project => {
return {
...project,
project_name: <Link to={`/projects/${project.id}`}>{project.project_name}</Link>
}
})
then the DataTable can handle the display with projectsToShow instead of project
<DataTable
...
value={projectsToShow}
...
>
Related
I have a popup that opens when the Add New Device button in the navbar is pressed. I'm printing the devices saved from this popup in produtcs page. However, popup lags behind the cards created for each product. I want you to appear first. How can I fix?
App.js
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
<React.StrictMode>
<App />
</React.StrictMode>
);
Navbar.js
import React, { useState } from 'react'
import AddProducts from './AddProduct';
import './components.css'
import 'reactjs-popup/dist/index.css';
function Navbar() {
const [openPopup, setOpenPopup] = useState(false);
return (
<div>
<nav className="navbar bg-light">
<div className="container-fluid">
<div className='justify-content-start'>
<a className="navbar-brand">Products</a>
<button className="btn btn-outline-danger btn-sm" onClick={() => setOpenPopup(true)}>+ Add New</button>
<AddProducts trigger={openPopup} setTrigger={setOpenPopup}></AddProducts>
</div>
<form className="d-flex" role="search">
<input className="form-control me-2" type="search" placeholder="Search" aria-label="Search" />
<button className="btn btn-outline-success" type="submit">Search</button>
</form>
</div>
</nav>
</div >
)
}
export default Navbar
AddProducts.js (popup)
import React, { useState } from 'react'
import './components.css';
import { BiX } from "react-icons/bi";
import { addDoc, collection } from "firebase/firestore"
import { db } from "../firebase-config";
import 'reactjs-popup/dist/index.css';
const AddProducts = (props) => {
const [name, setName] = useState("");
const [coordinates, setCoordinates] = useState("");
const [format, setFormat] = useState();
const productsCollectionRef = collection(db, "products");
const add = async (e) => {
e.preventDefault();
await addDoc(productsCollectionRef, { name: name, coordinates: coordinates, format: format });
};
return (props.trigger) ? (
<div className="popup">
<div className="popupTop ">
<div className="row">
<p className='col-md-10'>Add New Device</p>
<p className=" col-md-2 closeBtn" onClick={() => props.setTrigger(false)}>
<BiX size="20" color="black"></BiX>
</p>
{props.children}
</div>
</div>
<div className="popupContent">
<form autoComplete='off' className="form-group"
onSubmit={add}>
<div className="mb-3 inputAP">
<label className="form-label">Name *</label>
<input className="form-control"
required
onChange={(e) => setName(e.target.value)} value={name} />
</div>
<div className="mb-3 inputAP">
<label className="form-label">Coordinates *</label>
<input className="form-control"
required
onChange={(e) => setCoordinates(e.target.value)} value={coordinates} />
</div>
<div className="mb-3">
<label className="form-label">Format *</label>
<div className="form-check">
<input className="form-check-input" type="radio" name="format" value={"16:9"}
onChange={(e) => setFormat(e.target.value)} /> 16:9
</div>
<div className="form-check">
<input className="form-check-input" type="radio" name="format" value={"4:3"}
onChange={(e) => setFormat(e.target.value)} /> 4:3
</div>
</div>
</form>
<div className="mb-3">
<button className="btn btn-success" onClick={add}>Submit</button>
</div>
</div>
</div>
) : "";
}
export default AddProducts;
Products.js
import React, { useEffect, useState } from 'react'
import { getDocs, collection, doc, deleteDoc } from 'firebase/firestore'
import { db } from '../firebase-config';
import './components.css';
import { BiTrash, BiDesktop } from "react-icons/bi";
function Products() {
const [listProducts, setListProducts] = useState([]);
const productsCollectionRef = collection(db, "products");
useEffect(() => {
const getProducts = async () => {
const data = await getDocs(productsCollectionRef);
setListProducts(data.docs.map((doc) => ({ ...doc.data(), id: doc.id })));
};
getProducts();
});
const deleteProduct = async (id) => {
const productDoc = doc(db, "products", id)
await deleteDoc(productDoc);
};
return (
<div className="container productList ">
<div className="row productRow">
{listProducts.map((product) => {
return (
<div class="card col-md-3 mb-3 mx-2 border-secondary ">
<div class="card-header bg-transparent border-secondary">{product.name}</div>
<div class="card-body text-secondary">
<p class="card-text">Coordinates: {product.coordinates}</p>
</div>
<div class="card-footer bg-transparent border-secondary">
<div className="formatProduct">
<p className='formatIcon formatItem mx-2'><BiDesktop size="20" color="black"></BiDesktop></p>
<p className="card-text formatItem">{product.format}</p>
</div>
<div className="deleteProduct">
<p onClick={() => { deleteProduct(product.id) }}><BiTrash size="20" color="red"></BiTrash></p>
</div>
</div>
</div>
);
})}
</div>
</div >
);
}
export default Products
This is how it looks now on the back of the cards.
This question expands on my problem which got partially solved here. I have two components, ApplicationOverview.js and ApplicationModal.jsx and I want to dynamically add div panels to the ApplicationOverview.js Component from the Modal. In the Modal I have two input fields and I can add an image, which will be displayed on the div after I clicked on the 'Add' button. This is what the Modal looks like and this is what I am trying to achieve with n number of panels. (Note that the first 3 panels are hard coded)
So far, I can add a single div panel to my page, but whenever I try to add another one, it just changes the text of the panel that I just added. I am currently just toggling the visibility of that single div I am adding with a boolean (as you can see on the bottom of ApplicationOverview.js), but I can't figure out how I'd add multiple divs from my Modal to the page. Also, when I close the Modal but type something into the input fields, the text on the added div will still change without clicking on 'Add' beforehand.
ApplicationModal.jsx:
import React from "react";
var name = "";
var comment = "";
var filename = "";
const ApplicationModal = ({
setOpen,
setState,
setStateComment,
setFile,
file,
setBool,
}) => {
React.useEffect(() => {
function handleEscapeKey(event) {
if (event.code === "Escape") {
setOpen(false);
}
}
document.addEventListener("keydown", handleEscapeKey);
return () => document.removeEventListener("keydown", handleEscapeKey);
});
const handleComment = (e) => {
setStateComment(e.target.value);
};
const handleChange = (e) => {
setState(e.target.value);
};
const addNewApplication = () => {
setBool(true);
setOpen(false);
};
function openDialog() {
document.getElementById("inputUpload").click();
}
function loadFile(e) {
console.log(e.target.files);
setFile(URL.createObjectURL(e.target.files[0]));
}
document.addEventListener("click", function (e) {});
return (
<React.Fragment>
<div className="modalDark" style={{ paddingRight: "250px" }}>
<div class="modal-dialog">
<div class="modal-content" style={{ width: "800px" }}>
<div class="modal-close">
<div class="module-button" style={{ left: "750px" }}>
<button
class="btn btn-link "
onClick={() => setOpen(false)}
></button>
<div class="button-animation"></div>
<div class="button-content new">
<i class="icon icon-dc_close"></i>
</div>
</div>
</div>
<div class="modal-header">
<h3>Add new Application</h3>
</div>
<div class="modal-body">
<div
class="module-input form-group has-placeholder"
data-plugin="moduleInput"
style={{ bottom: "60px", width: "350px" }}
>
<label for="demo-default">Customer Name</label>
<div class="input-animation-wrapper">
<input
type="text"
id="demo-default"
class="form-control "
maxLength="42"
placeholder="[Application Name]"
onChange={(e) => handleChange(e)}
/>
<div class="input-animation"></div>
</div>
</div>
<div
class="module-textarea form-group floating-label has-placeholder"
data-plugin="moduleInput"
style={{ bottom: "60px" }}
>
<label for="demo-3">Customer Short text</label>
<div class="input-animation-wrapper" style={{ width: "350px" }}>
<textarea
id="demo-3"
class="form-control"
rows="9"
placeholder="Short description of Customer; max. 280 characters"
maxLength={180}
onChange={(e) => handleComment(e)}
style={{ width: "350px" }}
></textarea>
<div class="label-area"></div>
<div class="input-animation"></div>
</div>
</div>
<img
class="image"
alt="Customer Logo"
id="logo"
src={file}
style={{
left: "420px",
bottom: "280px",
position: "absolute",
height: "250px",
}}
/>
<div
class="module-button"
style={{
left: "500px",
bottom: "200px",
position: "absolute",
zIndex: "1",
}}
>
<button
type="file"
class="btn btn-light"
onClick={() => openDialog()}
id="fileUpload"
>
<input
type="file"
hidden={true}
accept="image/*"
id="inputUpload"
onChange={(e) => loadFile(e)}
></input>
</button>
<div class="button-animation"> </div>
<div class="button-content">
<span class="content-text">Upload Logo</span>
</div>
</div>
<div
class="module-button"
style={{ bottom: "50px", width: "100px", textAlign: "center" }}
>
<button
type="button"
class="btn btn-secondary btn"
onClick={() => addNewApplication()}
id="adding"
></button>
<div class="button-animation"></div>
<div class="button-content">
<span class="content-text">Add</span>
</div>
</div>
</div>
</div>
</div>
</div>
</React.Fragment>
);
};
export default ApplicationModal;
export { name, comment, filename };
ApplicationOverview.js:
import React from "react";
import "../Overview.css";
import ApplicationModal from "../components/ApplicationModal.jsx";
var id = 0;
const ApplicationOverview = () => {
const [open, setOpen] = React.useState(false);
const [state, setState] = React.useState("");
const [stateComment, setStateComment] = React.useState("");
const [file, setFile] = React.useState("https://upload.wikimedia.org/wikipedia/commons/thumb/3/3f/Placeholder_view_vector.svg/681px-Placeholder_view_vector.svg.png");
const [bool, setBool] = React.useState(false);
function addID()
{
id++;
console.log(id)
return id;
}
return (
<div id="wrapper">
{open && <ApplicationModal setOpen={setOpen} setState={setState} file={file} setBool={setBool} setFile={setFile} setStateComment={setStateComment} />}
<div class="component-headline">
<h4 style={{ color: "gray", display: "inline" }}>
Application overview
</h4>
<div
class="module-button"
style={{
backgroundColor: "rgb(18,205,212,255)",
borderRadius: "12px",
marginLeft: "1032px",
}}
onClick={() => setOpen(true)}
>
<button type="button" class="btn btn-secondary"></button>
<div class="button-animation"></div>
<div
class="button-content"
style={{
backgroundColor: "rgb(18,205,212,255)",
borderRadius: "12px",
}}
>
<span class="content-text" style={{ color: "black" }}>
Add Application
</span>
</div>
</div>
</div>
<hr style={{ marginTop: "-20px" }} />
<div class="center-content" id="center">
<div class="overview-box">
<img
class="image"
src="https://st.depositphotos.com/1968353/2535/i/600/depositphotos_25357041-stock-photo-close-up-of-machine-gears.jpg"
alt="car"
/>
<div class="box-content">
<h3 class="overview-h3">Press</h3>
<p class="overview-p">This Application is used for maintenance</p>
<h3 class="overview-h3-second">Connected Products</h3>
<h1 class="overview-h1-second">
?/?
<p class="overview-p-second">Online</p>
</h1>
<div class="module-button" id="configure">
<button type="button" class="btn btn-secondary"></button>
<div class="button-animation"></div>
<div class="button-content">
<span class="content-text">Configure</span>
</div>
</div>
</div>
</div>
<div class="overview-box">
<img
class="image"
src="https://st.depositphotos.com/1968353/2535/i/600/depositphotos_25357041-stock-photo-close-up-of-machine-gears.jpg"
alt="car"
/>
<div class="box-content">
<h3 class="overview-h3">Tooling Machine</h3>
<p class="overview-p">
This Application is used for drilling records
</p>
<h3 class="overview-h3-second">Connected Products</h3>
<h1 class="overview-h1-second">
?/?
<p class="overview-p-second">Online</p>
</h1>
<div class="module-button" id="configure">
<button type="button" class="btn btn-secondary"></button>
<div class="button-animation"></div>
<div class="button-content">
<span class="content-text">Configure</span>
</div>
</div>
</div>
</div>
<div class="overview-box">
<img
class="image"
src="https://st.depositphotos.com/1968353/2535/i/600/depositphotos_25357041-stock-photo-close-up-of-machine-gears.jpg"
alt="car"
/>
<div class="box-content">
<h3 class="overview-h3">Storing Unit</h3>
<p class="overview-p">
This Application is used for store parameters
</p>
<h3 class="overview-h3-second">Connected Products</h3>
<h1 class="overview-h1-second">
?/?
<p class="overview-p-second">Online</p>
</h1>
<div class="module-button" id="configure">
<button type="button" class="btn btn-secondary"></button>
<div class="button-animation"></div>
<div class="button-content">
<span class="content-text">Configure</span>
</div>
</div>
</div>
</div>
{(stateComment || state) && bool && <div class='overview-box' id={addID()}> <img class='image' src={file} alt='car'/> <div class='box-content'><h3 class='overview-h3' id='new-headline'>{state}</h3> <p class='overview-p'>{stateComment}</p><h3 class='overview-h3-second'>Connected Products</h3><h1 class='overview-h1-second'> ?/? <p class='overview-p-second'>Online</p> </h1> <div class='module-button' id='configure'> <button type='button' class='btn btn-secondary'></button> <div class='button-animation'></div> <div class='button-content'> <span class='content-text'>Configure</span> </div> </div> </div> </div> }
</div>
</div>
);
};
export default ApplicationOverview;
So if I understand your problem is that you have a modal and when you fill the modal and send add it will add the text and images to ApplicationOverview. I think you want to be able to do that several times. You want your users to be able to complete the modal again and again so it keep adding at the bottom of the ApplicationOverview.
So you need your ApplicationModal to have its own state.
const [modalState, setModalState] = useState("");
const [modalCommentState, setCommentModalState] = useState("");
const [modalFile, setModalFile] = useState("");
so your handler function should be
const handleComment = (e) => {
setCommentModalState(e.target.value);
};
const handleChange = (e) => {
setModalState(e.target.value);
};
function loadFile(e) {
setModalFile(URL.createObjectURL(e.target.files[0]));
}
Your submit function
const addNewApplication = () => {
setOpen(false);
setStates( oldArray => [...oldArray, {
state:modalState,
stateComment:modalCommentState,
file: modalFile } ]);
};
in the ApplicationOverview.js
const [states, setStates] = useState([]);
in your HTML section you loop through the state with a map
{ states.map((state)=> {
return (
<div class='overview-box' id={addID()}>
<img class='image' src={state.file} alt='car'/>
<div class='box-content'>
<h3 class='overview-h3' id='new-headline'>{state.state}</h3>
<p class='overview-p'>{state.stateComment}</p>
<h3 class='overview-h3-second'>Connected Products</h3>
<h1 class='overview-h1-second'> ?/? <p class='overview-p-second'>Online</p></h1>
<div class='module-button' id='configure'>
<button type='button' class='btn btn-secondary'></button>
<div class='button-animation'></div>
<div class='button-content'>
<span class='content-text'>Configure</span>
</div>
</div>
</div>
</div>
})}
So everytime the user submit the modal it will get added to the array of states and it will be display in the ApplicationOverview
I want to bind height of two blocks;
const [blockHeight, setBlockHeight] = useState(0);
const inputCommandsRef = useRef(null);
useEffect(() => {
setBlockHeight(inputCommandsRef.current?.clientHeight)
}, [inputCommandsRef])
<div className="row" ref={inputCommandsRef}>
<div style={{padding: '20px'}} className="col-xxl-9">
<textarea name="" id="" cols="30" rows="10"></textarea>
</div>
<div className="flex-line d-flex justify-content-start col-xxl-3"
style={{ maxHeight: `${maxHeight}px` }}>
<h1>maxHeight ${maxHeight}</h1>
<table>
....
</table>
</div>
</div>
Problem that when I change size of textArea the height of second block is not change (and value in h1 tag also), I just get once height and that is all.
You should not use useRef variables inside depsArray, they work in different way. You just need a ResizeObserver.
function Block() {
const [blockSize, setBlockSize] = useState({
width: 0,
height: 0
});
const inputCommandsRef = useRef(null);
useEffect(() => {
const { current } = inputCommandsRef;
if (!current) return;
const setSizes = () => {
setBlockSize({
width: current.clientWidth,
height: current.clientHeight
});
};
setSizes();
const obs = new ResizeObserver(setSizes);
obs.observe(current);
return () => {
obs.unobserve(current);
};
}, []);
return (
<div className="row" ref={inputCommandsRef}>
<div style={{ padding: "20px" }} className="col-xxl-9">
<textarea name="" id="" cols="30" rows="10"></textarea>
</div>
<div
className="flex-line d-flex justify-content-start col-xxl-3"
style={{ maxHeight: `${blockSize.height}px` }}
>
<h1>maxHeight ${blockSize.height}</h1>
</div>
</div>
);
}
How can I get a flex container on a same line rather than taking up a whole new row like when I have a logo on the left end of the page and wants to add a flex container to its right but even when I use inline-flex it still takes up a whole new row and I'm not very sure how I can implement the way Ive in my mind. I've attached a pic for reference regarding the same. Also I"m using tailwind css to style in a react based project so my code has elements that require other routings and paths to be viewed properly but the html part of the code is what I have attached below along with the styling I used.
How I intend to implement but instead how its being implemented
<div>
<body class="box-border m-0 p-0">
<header>
{user?(
<div>
<Link to="/main"><img class="ml-4 mt-8 w-48 bg-yellow-600" src={WorxaImg} alt="logo" /></Link>
<div class="inline-flex bg-red-700 flex-wrap w-[320px] gap-5">
<div class="self-start ">
<input class="bg-green-600 ml-4 w-[10vw] " type="text" placeholder="Search" value={value} onChange={onChange}/> {/* <label>Location {location}</label> */} {/* <button onClick={()=> onSearch(value)} className="ui primary button">search</button> */}
</div>
<div>
<select class="ml-6 mr-20" type="text" placeholder="Location" name='location' id='location' value={location} onChange={onChangeLocation}>
<option value="">Select your option</option>
{ locations.map((location,i)=>{ return(
<option>{location.city}</option>
) }) }
</select>
</div>
{jobs .filter((item) => { const searchTerm = value.toLowerCase(); const fullName = item.catogory.toLowerCase(); return ( searchTerm && fullName.startsWith(searchTerm) && fullName !== searchTerm ); }) .slice(0, 10) .map((item) => (
<Link to={ '/main/'+item.catogory}> {item.catogory}
<div onClick={()=> onSearch(item.catogory)} key={item.catogory}>
<Link to={ '/main/'+item.catogory}> {item.catogory}</Link>
</div>
</Link>
))} {worker .filter((item) => { const searchTerm = value.toLowerCase(); const fullName = item.name.toLowerCase(); return ( searchTerm && fullName.startsWith(searchTerm) && fullName !== searchTerm ); }) .slice(0, 10) .map((item) => (
<Link to={ '/main/'+item.job+ '/'+item._id}>
<div onClick={()=> onSearch(item.name)} key={item.name}>
<Link to={ '/main/'+item.job+ '/'+item._id}> {item.name},{item.job}{item.sjob!=='none'?','+item.sjob:''}</Link>
</div>
</Link>
))}
<div>
<Link to='/registerworker'><i>{(user.type==="employee")?(<div >Update Worker</div>):(<div class="bg-pink-700"> Test</div>)}</i></Link>
</div>
<div>
<button class="bg-yellow-600" onClick={onLogout}>
<i>Sign out</i>
</button>
</div>
<div>
<Link to='/profile'><i class="bg-green-700">Profile</i></Link>
</div>
</div>
</div>
Try to use flex flex-row to outermost div but inside of <body>.
Below is the code, see whether it works or not for you.
<div>
<body class="box-border m-0 p-0">
<header>
{user?(
<div class="flex flex-row space-x-5">
<Link to="/main"><img class="ml-4 mt-8 w-48 bg-yellow-600" src="http://commondatastorage.googleapis.com/codeskulptor-aets/week5-triangle.png" alt="logo" /></Link>
<div class="flex bg-red-700 flex-wrap w-[320px] gap-5">
<div class="self-start">
<input class="bg-green-600 ml-4 w-[10vw] " type="text" placeholder="Search" value={value} onChange={onChange}/> {/* <label>Location {location}</label> */} {/* <button onClick={()=> onSearch(value)} className="ui primary button">search</button> */}
</div>
<div>
<select class="ml-6 mr-20" type="text" placeholder="Location" name='location' id='location' value={location} onChange={onChangeLocation}>
<option value="">Select your option</option>
{ locations.map((location,i)=>{ return(
<option>{location.city}</option>
) }) }
</select>
</div>
{jobs .filter((item) => { const searchTerm = value.toLowerCase(); const fullName = item.catogory.toLowerCase(); return ( searchTerm && fullName.startsWith(searchTerm) && fullName !== searchTerm ); }) .slice(0, 10) .map((item) => (
<Link to={ '/main/'+item.catogory}> {item.catogory}
<div onClick={()=> onSearch(item.catogory)} key={item.catogory}>
<Link to={ '/main/'+item.catogory}> {item.catogory}</Link>
</div>
</Link>
))} {worker .filter((item) => { const searchTerm = value.toLowerCase(); const fullName = item.name.toLowerCase(); return ( searchTerm && fullName.startsWith(searchTerm) && fullName !== searchTerm ); }) .slice(0, 10) .map((item) => (
<Link to={ '/main/'+item.job+ '/'+item._id}>
<div onClick={()=> onSearch(item.name)} key={item.name}>
<Link to={ '/main/'+item.job+ '/'+item._id}> {item.name},{item.job}{item.sjob!=='none'?','+item.sjob:''}</Link>
</div>
</Link>
))}
<div>
<Link to='/registerworker'><i>{(user.type==="employee")?(<div >Update Worker</div>):(<div class="bg-pink-700"> Test</div>)}</i></Link>
</div>
<div>
<button class="bg-yellow-600" onClick={onLogout}>
<i>Sign out</i>
</button>
</div>
<div>
<Link to='/profile'><i class="bg-green-700">Profile</i></Link>
</div>
</div>
</div>
</header>
</body>
</div>
The issue: My first table bugtracker_table on dashboard.js works fine when I submit data to it but my second table ticket_table on projects.js do not submit values even though it's pretty much the same code.
I even have the terminal that says: Executing (default): INSERT INTO ticket_table (id,ticket_title,ticket_description,type_menu,priority_menu,status_menu,createdAt,updatedAt) VALUES (DEFAULT,?,?,?,?,?,?,?);
But there is no data in table.
Dashboard.js
import React, { useState, useEffect } from "react";
import { DataTable } from "primereact/datatable";
import { Column } from "primereact/column";
import { Button } from "primereact/button";
// import ButtonDemo from './ButtonDemo';
import { Chart } from "primereact/chart";
import { InputText } from "primereact/inputtext";
import { InputTextarea } from "primereact/inputtextarea";
import { Modal, ModalFooter, ModalHeader } from "react-bootstrap";
import axios from "axios";
import { useHistory, Link } from "react-router-dom";
// import { Media } from "react-bootstrap/Media"
// import ProjectsTable from "./Tables/ProjectsTable";
// import TicketsPieChart from "./Tables/TicketsPieChart"
// import API from
//project table
//eslint-disable no-unused-vars
const TableDemo = () => {
// const toggle = () => {setShow(!show);}
const [project_name, setProjectName] = useState("");
const [description, setDescription] = useState("");
const [projects, setProjects] = useState([]);
const history = useHistory();
const projectsToShow = projects.map((project) => {
return {
...project,
project_name: <Link to={`/projects/${project.id}`}>{project.project_name}</Link>,
};
});
useEffect(() => {
getProjects();
}, []);
const getProjects = async () => {
const response = await axios.get("http://localhost:5002/bugtracker_table");
setProjects(response.data);
};
const saveProject = async (e) => {
e.preventDefault();
await axios.post("http://localhost:5002/bugtracker_table", {
project_name: project_name,
description: description,
});
history.push("/");
};
const [show, setShow] = useState(false);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
return (
<>
<div className="grid table-demo">
<div className="col-12">
<div className="card">
<h5>Projects</h5>
<div>
<Button label="New Project" className="p-button-rounded mr-2 mb-2 npbutton" onClick={handleShow} />
</div>
<Modal className="modal" show={show} onHide={handleClose}>
<form onSubmit={saveProject}>
<div className="grid p-fluid">
<div className="col-12 md:col-6">
<div className="card">
<Button icon="pi pi-times" className="p-button-rounded p-button-danger p-button-text mr-2 mb-2 x-button" onClick={handleClose}></Button>
<ModalHeader>
<h5>Projects</h5>
</ModalHeader>
<div className="grid formgrid">
<div className="col-12 mb-2 lg:col-4 lg:mb-0">
<InputText value={project_name} onChange={(e) => setProjectName(e.target.value)} type="text" placeholder="Enter project name"></InputText>
</div>
</div>
<h5>Project Description</h5>
<InputTextarea value={description} onChange={(e) => setDescription(e.target.value)} type="text" placeholder="Enter project description" autoResize rows="3" cols="30" />
<ModalFooter>
<Button label="Submit" className="p-button-rounded p-button-success mr-2 mb-2 success" />
{/* <Button onClick={handleClose}>Close</Button> */}
</ModalFooter>
</div>
</div>
</div>
</form>
</Modal>
{/* // <Link to="/ticketlist" className="col-12"> */}
<div>
{/* // className="card"></Link> */}
<DataTable
// sortMode="single" sortField="representative.name"
value={projectsToShow}
sortOrder={1}
scrollable
scrollHeight="400px"
responsiveLayout="scroll"
>
<Column field="project_name" header="Project Name" style={{ minWidth: "200px" }}></Column>
<Column field="description" header="Description" style={{ minWidth: "350px" }}></Column>
<Column field="createdAt" header="Created On" style={{ minWidth: "150px" }}></Column>
{projects.map((project, index) => (
<tr key={project.id}>
<td>{index + 1}</td>
<td>{project.description}</td>
<td>{project.createdAt}</td>
</tr>
))}
</DataTable>
</div>
</div>
</div>
<div className="grid p-fluid">
<div className="col-12 lg:col-6">
<div className="card flex flex-column align-items-center">
<h5>Tickets by Type</h5>
<Chart type="pie" focus={"type"} />
</div>
</div>
</div>
<div className="grid p-fluid">
<div className="col-12 lg:col-6">
<div className="card flex flex-column align-items-center">
<h5>Tickets by Priority</h5>
<Chart type="pie" focus={"priority"} />
</div>
</div>
</div>
<div className="grid p-fluid">
<div className="col-12 lg:col-6">
<div className="card flex flex-column align-items-center">
<h5>Tickets by Status</h5>
<Chart type="pie" focus={"status"} />
</div>
</div>
</div>
</div>
</>
);
};
export default React.memo(TableDemo);
Projects.js
import React, { useState, useEffect } from "react";
import { Column } from "primereact/column";
import { DataTable } from "primereact/datatable";
import { Button } from "primereact/button";
import { Modal, ModalFooter, ModalHeader } from "react-bootstrap";
import { InputText } from "primereact/inputtext";
import { InputTextarea } from "primereact/inputtextarea";
// import { InputNumber } from "primereact/inputnumber";
import { Dropdown } from "primereact/dropdown";
import axios from "axios";
const Projectz = () => {
const [ticket_title, setTicketTitle] = useState("");
const [ticket_description, setTicketDescription] = useState("");
// const [time_takes, setTimeTakes] = useState("");
const [type_menu, setTypeMenu] = useState("");
const [priority_menu, setPriorityMenu] = useState("");
const [status_menu, setStatusMenu] = useState("");
const [projects, setProjects] = useState([]);
useEffect(() => {
getProjects();
}, []);
const getProjects = async () => {
const response = await axios.get("http://localhost:5002/ticket_table");
setProjects(response.data);
};
const saveProject = async (e) => {
e.preventDefault();
await axios.post("http://localhost:5002/ticket_table", {
ticket_title: ticket_title,
ticket_description: ticket_description,
// time_takes: time_takes,
type_menu: type_menu,
priority_menu: priority_menu,
status_menu: status_menu,
});
};
const dropdownValues1 = [
{ name: "Issue", code: "ISS" },
{ name: "Bug", code: "BUG" },
{ name: "Error", code: "ERR" },
{ name: "Other", code: "OTH" },
];
const dropdownValues2 = [
{ name: "Low", code: "LOW" },
{ name: "Medium", code: "MED" },
{ name: "High", code: "HI" },
{ name: "Immediate", code: "IMM" },
];
const dropdownValues3 = [
{ name: "New", code: "NEW" },
{ name: "Open", code: "OP" },
{ name: "In Progress", code: "IP" },
{ name: "Resolved", code: "RES" },
{ name: "Additional Info Required", code: "AIR" },
];
const [show, setShow] = useState(false);
const handleClose = () => setShow(false);
const handleShow = () => setShow(true);
return (
<>
<div className="grid table-demo">
<div className="col-12">
<div className="card">
<h5>Tickets</h5>
<div>
<Button label="New Ticket" className="p-button-rounded mr-2 mb-2 npbutton" onClick={handleShow} />
</div>
<Modal className="modal" show={show} onHide={handleClose}>
<form onSubmit={saveProject}>
<div className="grid p-fluid">
<div className="col-12 md:col-6">
<div className="card">
<ModalHeader>
<h5>Create Ticket</h5>
</ModalHeader>
<div className="grid formgrid">
<div className="col-12 mb-2 lg:col-4 lg:mb-0">
<InputText value={ticket_title} onChange={(e) => setTicketTitle(e.target.value)} type="text" placeholder="Enter ticket title"></InputText>
</div>
</div>
<h5>Ticket Description</h5>
<InputTextarea value={ticket_description} onChange={(e) => setTicketDescription(e.target.value)} type="text" placeholder="Enter ticket description" autoResize rows="3" cols="30" />
{/* <h5>Time Estimate (Hours)</h5> */}
{/* <InputNumber value={time_takes} onValueChange={(e) => setTimeTakes(e.value)} showButtons mode="decimal"></InputNumber> */}
<h5>Type</h5>
<Dropdown value={type_menu} onChange={(e) => setTypeMenu(e.value)} options={dropdownValues1} optionLabel="name" placeholder="Select" />
<h5>Priority</h5>
<Dropdown value={priority_menu} onChange={(e) => setPriorityMenu(e.value)} options={dropdownValues2} optionLabel="name" placeholder="Select" />
<h5>Status</h5>
<Dropdown value={status_menu} onChange={(e) => setStatusMenu(e.value)} options={dropdownValues3} optionLabel="name" placeholder="Select" />
<ModalFooter>
<Button label="Submit" className="p-button-rounded p-button-success mr-2 mb-2 success" />
<Button onClick={handleClose}>Close</Button>
</ModalFooter>
</div>
</div>
</div>
</form>
</Modal>
<div>
<DataTable
// sortMode="single" sortField="representative.name"
sortOrder={1}
scrollable
scrollHeight="400px"
responsiveLayout="scroll"
>
<Column field="ticket_title" header="Ticket Title" style={{ minWidth: "200px" }}></Column>
<Column field="description" header="Description" style={{ minWidth: "350px" }}></Column>
<Column field="status" header="Status" style={{ minWidth: "200" }}></Column>
<Column field="createdAt" header="Date" style={{ minWidth: "200px" }}></Column>
</DataTable>
</div>
</div>
</div>
</div>
<div className="grid table-demo">
<div className="col-12">
<div className="card">
<h5>Ticket Info</h5>
<div>
<DataTable
// value={projects}
// sortMode="single" sortField="representative.name"
// sortOrder={1}
// scrollable
// scrollHeight="400px"
// responsiveLayout="scroll"
>
{projects.map((project, index) => (
<tr key={project.id}>
<td>{index + 1}</td>
<td>{project.ticket_title}</td>
<td>{project.ticket_description}</td>
{/* <td>{ticket.time_takes}</td> */}
<td>{project.type_menu}</td>
<td>{project.priority_menu}</td>
<td>{project.status_menu}</td>
</tr>
))}
</DataTable>
</div>
</div>
</div>
</div>
</>
);
};
export default React.memo(Projectz);