How to make Admin Dashboard

In modern e-commerce architectures, a dedicated Producer Dashboard is essential for allowing vendors or creators to manage their inventory and track incoming sales. This article breaks down how to build a functional React dashboard that handles data fetching, form management, and conditional rendering.
Core Functionalities

The ProducerDashboard component serves two primary purposes:

Inventory Management: A dynamic form to add new products to the database.

Order Tracking: A live view of customer orders specific to the logged-in producer.

Key Technical Concepts

  1. Authentication Guarding

Before the component renders its main content, it checks for a user object. If the user isn’t logged in, it uses the useNavigate hook from react-router-dom to redirect them to the login page. This ensures that sensitive data and producer tools remain protected.

  1. Managing Complex State

The component utilizes the useState hook to manage several different types of data:

Orders: An array to store data fetched from the API.

Form Data: An object used to track multiple input fields simultaneously.

Feedback UI: State variables for error and message to provide real-time updates to the user.
  1. Data Fetching with useEffect

The component uses useEffect to trigger an asynchronous fetch call. By including [user] in the dependency array, the dashboard automatically refreshes or loads data whenever the user context changes.
The Implementation

Below is the complete React code for the ProducerDashboard.
JavaScript

import { useState, useEffect } from ‘react’
import { useNavigate } from ‘react-router-dom’
import ‘./ProducerDashboard.css’

function ProducerDashboard({ user }) {
const navigate = useNavigate()
const [orders, setOrders] = useState([])
const [form, setForm] = useState({
product_name: ”,
product_price: ”,
product_stock: ”,
product_description: ”
})
const [message, setMessage] = useState(”)
const [error, setError] = useState(”)

useEffect(() => {
// Redirect if user is not authenticated
if (!user) {
navigate(‘/login’);
return
}

const load = async () => {
  try {
    const res  = await fetch(`/api/producer/orders/${user.producerID}`)
    const data = await res.json()
    setOrders(data)
  } catch (err) {
    console.error("Failed to load orders", err)
  }
}
load()

}, [user, navigate])

const handleChange = (e) => {
// Dynamically update form state based on input name
setForm({ …form, [e.target.name]: e.target.value })
}

const addProduct = async () => {
// Basic Validation
if (!form.product_name) { setError(‘Please enter a product name’); return }
if (!form.product_price) { setError(‘Please enter a price’); return }
if (!form.product_stock) { setError(‘Please enter stock level’); return }

const res = await fetch('/api/products', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    ...form,
    producerID: user.producerID
  })
})

if (res.ok) {
  setMessage('Product added!')
  setError('')
  // Reset form after successful submission
  setForm({
    product_name: '',
    product_price: '',
    product_stock: '',
    product_description: ''
  })
} else {
  setError('Failed to add product. Please try again.')
}

}

if (!user) return

Please log in as a producer.

return (

Producer Dashboard

  {/* Section 1: Product Entry */}
  <div className="dashboard-section">
    <h2>Add New Product</h2>

    <input
      name="product_name"
      placeholder="Product name"
      value={form.product_name}
      onChange={handleChange}
    />
    <input
      name="product_price"
      placeholder="Price"
      value={form.product_price}
      onChange={handleChange}
    />
    <input
      name="product_stock"
      placeholder="Stock"
      value={form.product_stock}
      onChange={handleChange}
    />
    <textarea
      name="product_description"
      placeholder="Description"
      value={form.product_description}
      onChange={handleChange}
    />

    {error   && <p className="error">{error}</p>}
    {message && <p className="success">{message}</p>}

    <button onClick={addProduct}>Add Product</button>
  </div>

  {/* Section 2: Order Management */}
  <div className="dashboard-section">
    <h2>Customer Orders</h2>
    {orders.length === 0 && <p>No orders yet.</p>}
    {orders.map(order => (
      <div key={order.orderID} className="order-card">
        <p className="order-product"><strong>{order.product_name}</strong></p>
        <p>Customer: {order.first_name} {order.last_name}</p>
        <p>Quantity: {order.product_quantity}</p>
        <p>Date: {new Date(order.order_date).toLocaleDateString()}</p>
      </div>
    ))}
  </div>
</div>

)
}

export default ProducerDashboard

Best Practices Observed

Controlled Components: All inputs are linked to the React state via the value and onChange attributes, making the UI the "single source of truth."

RESTful Interaction: The code uses standard HTTP methods (GET for retrieving orders and POST for creating products).

User Feedback: It provides immediate visual feedback (success/error messages) which is vital for a good user experience.

Scalable Formatting: By using .map() to render orders, the dashboard can handle any number of sales entries dynamically.