Thursday 30 November 2023

ASP.NET Core Web API with Angular and React Example

 1. We will do below Web API



Folder Structure


I. In DairyOrderController.cs file

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using DairyAPI.Models;
using Microsoft.AspNetCore.Http.HttpResults;

namespace DairyAPI.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class DairyOrderController : ControllerBase
    {
        private readonly DairyOrderContext _context;

        public DairyOrderController(DairyOrderContext context)
        {
            _context = context;
        }

        // GET: api/DairyOrder
        [HttpGet]
        public async Task<ActionResult<IEnumerable<DairyOrder>>> GetDairyOrders()
        {
          if (_context.DairyOrders == null)
          {
              return NotFound();
          }
            return await _context.DairyOrders.ToListAsync();
        }

        // GET: api/DairyOrder/5
        [HttpGet("{id}")]
        public async Task<ActionResult<DairyOrder>> GetDairyOrder(int id)
        {
          if (_context.DairyOrders == null)
          {
              return NotFound();
          }
            var dairyOrder = await _context.DairyOrders.FindAsync(id);

            if (dairyOrder == null)
            {
                return NotFound();
            }

            return dairyOrder;
        }

        // PUT: api/DairyOrder/5
        // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
        [HttpPut("{id}")]
        public async Task<IActionResult> PutDairyOrder(int id, DairyOrder dairyOrder)
        {
            if (id != dairyOrder.OrderId)
            {
                return BadRequest();
            }

            _context.Entry(dairyOrder).State = EntityState.Modified;

            try
            {
                await _context.SaveChangesAsync();
            }
            catch (DbUpdateConcurrencyException)
            {
                if (!DairyOrderExists(id))
                {
                    return NotFound();
                }
                else
                {
                    throw;
                }
            }

            //return NoContent();
            return Ok(await _context.DairyOrders.ToListAsync());
        }

        // POST: api/DairyOrder
        // To protect from overposting attacks, see https://go.microsoft.com/fwlink/?linkid=2123754
        [HttpPost]
        public async Task<ActionResult<DairyOrder>> PostDairyOrder(DairyOrder dairyOrder)
        {
          if (_context.DairyOrders == null)
          {
              return Problem("Entity set 'DairyOrderContext.DairyOrders'  is null.");
          }
            _context.DairyOrders.Add(dairyOrder);
            await _context.SaveChangesAsync();

            //return CreatedAtAction("GetDairyOrder", new { id = dairyOrder.OrderId }, dairyOrder);
            return Ok(await _context.DairyOrders.ToListAsync());
        }

        // DELETE: api/DairyOrder/5
        [HttpDelete("{id}")]
        public async Task<IActionResult> DeleteDairyOrder(int id)
        {
            if (_context.DairyOrders == null)
            {
                return NotFound();
            }
            var dairyOrder = await _context.DairyOrders.FindAsync(id);
            if (dairyOrder == null)
            {
                return NotFound();
            }

            _context.DairyOrders.Remove(dairyOrder);
            await _context.SaveChangesAsync();

            //return NoContent();
            return Ok(await _context.DairyOrders.ToListAsync());
        }

        private bool DairyOrderExists(int id)
        {
            return (_context.DairyOrders?.Any(e => e.OrderId == id)).GetValueOrDefault();
        }
    }
}

II. In Models>>DairyOrder.cs file
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;

namespace DairyAPI.Models
{
    public class DairyOrder
    {
        [Key]
        public int OrderId { get; set; }
        [Column(TypeName = "nvarchar(100)")]
        public string OrderItem { get; set; } = "";
        public float Quantity { get; set; }
        public float Price { get; set; }
        [Column(TypeName = "nvarchar(20)")]
        public string OrderDate { get; set; } = "";
        [Column(TypeName = "nvarchar(20)")]
        public string OrderStatus { get; set; } = "";
        public long PhoneNumber { get; set; }
        [Column(TypeName = "nvarchar(50)")]
        public string Email { get; set; } = "";
        [Column(TypeName = "nvarchar(100)")]
        public string Address { get; set; } = "";
    }
}

III. In Models>>DairyOrderContext.cs file
using Microsoft.EntityFrameworkCore;

namespace DairyAPI.Models
{
    public class DairyOrderContext:DbContext
    {
        public DairyOrderContext(DbContextOptions options):base(options)
        {
            
        }
        public DbSet<DairyOrder> DairyOrders { get; set; }

    }
}

IV. In appsettings.json file
{
  "Logging": {
    "LogLevel": {
      "Default": "Information",
      "Microsoft.AspNetCore": "Warning"
    }
  },
  "AllowedHosts": "*",
  "ConnectionStrings": {
    "MyDevConnection": "Server=(localdb)\\MSSQLLocalDB;Database=DairyOrderDB;Trusted_Connection=True;TrustServerCertificate=True;MultipleActiveResultSets=True;"
  }
 }

V. In Program.cs file
using DairyAPI.Models;
using Microsoft.EntityFrameworkCore;

var builder = WebApplication.CreateBuilder(args);

// Add services to the container.

builder.Services.AddControllers();
// Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle
builder.Services.AddEndpointsApiExplorer();
builder.Services.AddSwaggerGen();

builder.Services.AddDbContext<DairyOrderContext>(options =>
options.UseSqlServer(builder.Configuration.GetConnectionString("MyDevConnection")));

var app = builder.Build();


// Configure the HTTP request pipeline.
if (app.Environment.IsDevelopment())
{
    app.UseSwagger();
    app.UseSwaggerUI();
}

app.UseCors(options=>
options.WithOrigins("http://localhost:3000")
.AllowAnyMethod()
.AllowAnyHeader());

app.UseAuthorization();

app.MapControllers();

app.Run();


----Open Package Console:
--Build Project
>add-migration
>update-database

--Check DB and Table is created

2. Now consume above API in Angular

Folder Structure

Dependencies

Now we will start step by step
>ng new DairyOrderApp
>cd DairyOrderApp
>code .

I. In Dairy-Order-Details>>dairy-order-details.html file
<div class="bg-body-secondary text-center py-5 rounded-2">
    <h1 class="display-6 fw-bold">
        Dairy Order Details
    </h1>
</div>
<div class="row mt-5">
    <div class="col-6">
        <app-dairy-order-detail-form/>
    </div>
    <div class="col-6">
        <ul class="list-group">
            <li class="list-group-item d-flex justify-content-between
            align-items-start mb-2 border px-4 py-3 rounded-3"
            *ngFor="let dol of service.list">
        <div class="flex-grow-1 mouse-hover" (click)="populateForm(dol)">
            <div class="fw-bold">{{dol.orderItem}}</div>
            <div class="fw-bold">{{dol.quantity + "ltr"}} </div>
            <div class="fw-bold">{{dol.orderStatus}}</div>
            <div class="fw-bold">{{dol.orderDate}}</div>
        </div>
        <span class="text-secondary">
            <i class="fa-solid fa-trash-can fa-lg mouse-hover"
            (click)="onDelete(dol.orderId)"></i>
        </span>
               
            </li>
        </ul>
    </div>
</div>

II. In Dairy-Order-Details>>dairy-order-details.ts file
import { Component, OnInit } from '@angular/core';
import { DairyOrderDetailService } from '../shared/dairy-order-detail.service';
import { DairyOrderDetail } from '../shared/dairy-order-detail.model';
import { ToastrService } from 'ngx-toastr';

@Component({
  selector: 'app-dairy-order-details',
  templateUrl: './dairy-order-details.component.html',
  styles: [
  ]
})
export class DairyOrderDetailsComponent implements OnInit {

  constructor(public service:DairyOrderDetailService,private toastr:ToastrService){}

  ngOnInit(): void {
      this.service.getDairyOrderList();
  }

  populateForm(selectedRecord:DairyOrderDetail){
    this.service.formData=Object.assign({},selectedRecord);
  }

  onDelete(id:number){
    if (confirm('Are you sure to delete this record?'))
    this.service.deleteDairyOrder(id).subscribe({
      next:res=>{
        console.log(res);
        this.service.list=res as DairyOrderDetail[];
        this.toastr.error('Deleted Successfully','Dairy Order Details');
      },
      error:err=>{console.log(err)}
    })
  }

}

III. In Dairy-Order-Details>>dairy-order-detail-form>>dairy-order-detail-form.html file
<form #form="ngForm" (submit)="onSubmit(form)"
[class.submitted]="service.formSubmitted" novalidate autocomplete="off">
    <input type="hidden" name="orderId" [value]="service.formData.orderId"/>
    <div class="row">
    <div class="mb-3 col-6 ">
        <label>Select Item</label>
        <select class="form-control form-control-lg" placeholder="Select Item"
        #orderItem="ngModel" name="orderItem"
        [(ngModel)]="service.formData.orderItem">
            <option></option>
            <option>Milk</option>
            <option>Curd</option>
        </select>

        <!-- <input class="form-control form-control-lg" placeholder="Item Name"
        #orderItem="ngModel" name="orderItem"
        [(ngModel)]="service.formData.orderItem"
        required minlength="5" maxlength="5"/> -->
    </div>
    <div class="mb-3 col-3">
        <label>Quantity</label>
        <input class="form-control form-control-lg" placeholder="Quantity(in ltr/kg)"
        #quantity="ngModel" name="quantity"
        [(ngModel)]="service.formData.quantity"
        required (change)="calcPrice()"/>
    </div>
    <div class="mb-3 col-3">
        <label>Price</label>
        <p><strong>{{service.formData.price}}</strong></p>
    </div>
</div>
<div class="row">
    <div class="mb-3 col-6">
        <label>Order Date</label>
        <input class="form-control form-control-lg" placeholder="dd/mm/yyyy"
        #orderDate="ngModel" name="orderDate"
        [(ngModel)]=service.formData.orderDate/>
    </div>
    <div class="mb-3 col-6">
        <label>Select Order Status</label>
        <select class="form-control form-control-lg" placeholder="Order Status"
        #orderItem="ngModel" name="orderStatus"
        [(ngModel)]="service.formData.orderStatus">
            <option></option>
            <option>Ordered</option>
            <option>Delivered</option>
        </select>


        <!-- <input class="form-control form-control-lg" placeholder="Order Status"
        #orderStatus="ngModel" name="orderStatus"
        [(ngModel)]="service.formData.orderStatus"/> -->
    </div>
</div>
<div class="row">
    <div class="mb-3 col-6">
        <label>Phone Number</label>
        <input class="form-control form-control-lg" placeholder="Phone Number"
        #phoneNumber="ngModel" name="phoneNumber"
        [(ngModel)]="service.formData.phoneNumber"
        required/>
    </div>
    <div class="mb-3 col-6">
        <label>Email</label>
        <input class="form-control form-control-lg" placeholder="Email"
        #email="ngModel" name="email"
        [(ngModel)]="service.formData.email"/>
    </div>
</div>
<div class="row">
    <div class="mb-3 col-6">
        <label>Address</label>
        <textarea class="form-control form-control-lg" placeholder="Address"
        #address="ngModel" name="address"
        [(ngModel)]="service.formData.address"
        required></textarea>
    </div>
    <div class="mb-3 col-6">
        <button class="btn btn-lg btn-success" type="submit">Submit</button>
    </div>
</div>
    <!-- <div class="d-grid">
        <button class="btn btn-lg btn-success" type="submit">Submit</button>
    </div> -->
</form>

IV. In Dairy-Order-Details>>dairy-order-detail-form>>dairy-order-detail-form.ts file
import { Component } from '@angular/core';
import { DairyOrderDetailService } from 'src/app/shared/dairy-order-detail.service';
import {NgForm} from '@angular/forms';
import { DairyOrderDetail } from 'src/app/shared/dairy-order-detail.model';
import { ToastrService } from 'ngx-toastr';

@Component({
  selector: 'app-dairy-order-detail-form',
  templateUrl: './dairy-order-detail-form.component.html',
  styles: [
  ]
})
export class DairyOrderDetailFormComponent {
  price:number=0;

  constructor(public service:DairyOrderDetailService,private toastr:ToastrService){}

  onSubmit(form:NgForm){
    this.service.formSubmitted=true;
    if(form.valid){
      if(this.service.formData.orderId==0)
        this.insertRecord(form);
      else
      this.updateRecord(form);
    }
  }

  insertRecord(form:NgForm){
    this.service.postDairyOrder()
    .subscribe({
      next:res=>{
        console.log(res);
        this.service.list=res as DairyOrderDetail[];
        this.service.resetForm(form);
        this.toastr.success('Inserted Successfully','Dairy Order Details');
      },
      error:err=>{console.log(err)}
    })
  }

  updateRecord(form:NgForm){
    this.service.putDairyOrder()
    .subscribe({
      next:res=>{
        console.log(res);
        this.service.list=res as DairyOrderDetail[];
        this.service.resetForm(form);
        this.toastr.info('Updated Successfully','Dairy Order Details');
      },
      error:err=>{console.log(err)}
    })
  }

  calcPrice(){
    if(this.service.formData.quantity!=0){
      this.service.formData.price=60*this.service.formData.quantity;
    }
  }

}

V. In Shared>>dairy-order-detail.model.ts file
export class DairyOrderDetail {
  orderId: number=0
  orderItem: string=""
  quantity: number=0
  orderDate: string=""
  orderStatus: string=""
  phoneNumber: string=""
  email: string=""
  address: string=""
  price:number=0
}

VI. In Shared>>dairy-order-detail.service.ts file
import { Injectable } from '@angular/core';
import {HttpClient} from '@angular/common/http';
import { DairyOrderDetail } from './dairy-order-detail.model';
import { NgForm } from '@angular/forms';

@Injectable({
  providedIn: 'root'
})
export class DairyOrderDetailService {
  url:string="http://localhost:5202/api/DairyOrder";
  list:DairyOrderDetail[]=[];
  formData:DairyOrderDetail=new DairyOrderDetail();
  formSubmitted:boolean=false;

  constructor(private http:HttpClient) { }

  getDairyOrderList(){
    this.http.get(this.url)
    .subscribe({
      next:res=>{
        this.list=res as DairyOrderDetail[]
        console.log(res);
      },
      error:err=>{
        console.log(err);
      }
    });
  }

  postDairyOrder(){
    console.log(this.formData);
    return this.http.post(this.url,this.formData)
  }

  putDairyOrder(){
    console.log(this.formData);
    return this.http.put(this.url+'/'+this.formData.orderId,this.formData)
  }

  deleteDairyOrder(id:number){
    console.log(this.formData);
    return this.http.delete(this.url+'/'+id)
  }

  resetForm(form:NgForm){
    form.form.reset();
    this.formData=new DairyOrderDetail();
    this.formSubmitted=false;
  }
}

VII. In app.component.html file
<div class="container">
  <div class="row">
    <div class="col-8 offset-2">
      <app-dairy-order-details/>

    </div>
  </div>
</div>

VIII. In app.component.ts file
import { Component } from '@angular/core';

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styles: []
})
export class AppComponent {
  title = 'DairyOrderApp';
}

IX. In app.module.ts file
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { BrowserAnimationsModule } from '@angular/platform-browser/animations';
import { ToastrModule } from 'ngx-toastr';

import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';
import { DairyOrderDetailsComponent } from './dairy-order-details/dairy-order-details.component';
import { DairyOrderDetailFormComponent } from './dairy-order-details/dairy-order-detail-form/dairy-order-detail-form.component';
import { HttpClientModule } from '@angular/common/http';
import { FormsModule } from '@angular/forms';


@NgModule({
  declarations: [
    AppComponent,
    DairyOrderDetailsComponent,
    DairyOrderDetailFormComponent
  ],
  imports: [
    BrowserModule,
    AppRoutingModule,
    HttpClientModule,
    FormsModule,
    BrowserAnimationsModule,
    ToastrModule.forRoot(),
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule { }

X. In index.html file
<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <title>DairyOrderApp</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
  <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-T3c6CoIi6uLrA9TneNEoa7RxnatzjcDSCmG1MXxSR1GAsXEV/Dwwykc2MPK8M2HN" crossorigin="anonymous">
  <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" integrity="sha512-z3gLpd7yknf1YoNbCzqRKc4qyor8gaKU1qmn+CShxbuBusANI9QpRohGBreCFkKxLhei6S9CQXFEbbKuqLg0DA==" crossorigin="anonymous" referrerpolicy="no-referrer" />
</head>
<body>
  <app-root/>
</body>
</html>

--Now Run
>ng serve --port 3000 --open

3. Now consume above API in React
Folder Structure
Dependencies

Now we will start step by step
>npx create-react-app react-diary-order
>cd react-diary-order
>code .

I. In Redux>>Action.jsx file
import axios from "axios";
import { ADD_ORDER, DELETE_ORDER, FAIL_REQUEST, GET_ORDER_LIST, MAKE_REQUEST } from "./ActionType";
import { toast } from "react-toastify";

export const makeRequest = () => {
    return {
      type: MAKE_REQUEST,
    };
  };
 
  export const failRequest = (err) => {
    return {
      type: FAIL_REQUEST,
      payload: err,
    };
  };
 
  export const getOrderList = (data) => {
    return {
      type: GET_ORDER_LIST,
      payload: data,
    };
  };

  export const addOrder = () => {
    return {
      type: ADD_ORDER,
    };
  };

  export const deleteOrder = () => {
    return {
      type: DELETE_ORDER,
    };
  };

  export const FetchOrderList = () => {
    return (dispatch) => {
      dispatch(makeRequest());
      //setTimeout(()=>{
 
      axios
        .get("http://localhost:5202/api/DairyOrder")
        .then((res) => {
          const userlist = res.data;
          dispatch(getOrderList(userlist));
        })
        .catch((err) => {
          dispatch(failRequest(err.message));
        })
 
      //},2000)
    };
  };

  export const AddOrder = (data) => {
    return (dispatch) => {
      dispatch(makeRequest());
      //setTimeout(()=>{
 
      axios
        .post("http://localhost:5202/api/DairyOrder/",data)
        .then((res) => {
          dispatch(addOrder());
          toast.success("Order added successfully");
        })
        .catch((err) => {
          dispatch(failRequest(err.message));
        })
 
      //},2000)
    };
  };

  export const DeleteOrder = (id) => {
    return (dispatch) => {
      dispatch(makeRequest());
      //setTimeout(()=>{
 
      axios
        .delete("http://localhost:5202/api/DairyOrder/"+id)
        .then((res) => {
          dispatch(deleteOrder());
          toast.error("Order deleted successfully");
        })
        .catch((err) => {
          dispatch(failRequest(err.message));
        })
 
      //},2000)
    };
  };

II. In Redux>>ActionType.jsx file
export const MAKE_REQUEST='MAKE_REQUEST'
export const FAIL_REQUEST='FAIL_REQUEST'
export const GET_ORDER_LIST='GET_ORDER_LIST'
export const ADD_ORDER='ADD_ORDER'
export const DELETE_ORDER='DELETE_ORDER'

III. In Redux>>Reducer.jsx file
import { ADD_ORDER, DELETE_ORDER, FAIL_REQUEST, GET_ORDER_LIST, MAKE_REQUEST } from "./ActionType"

const initialstate={
    loading:true,
    orderlist:[],
    userobj:{},
    errmessage:''
}

export const Reducer=(state=initialstate,action)=>{
    switch(action.type){
        case MAKE_REQUEST:
            return{
                ...state,
                loading:true
            }
        case FAIL_REQUEST:
            return{
                ...state,
                loading:false,
                errmessage:action.payload
            }
        case GET_ORDER_LIST:
                return{
                    loading:false,
                    errmessage:'',
                    orderlist:action.payload,
                    userobj:{}
                }
        case ADD_ORDER:
                        return{
                            ...state,
                            loading:false
                        }
        case DELETE_ORDER:
                    return{
                        ...state,
                        loading:false
                    }
        // case UPDATE_USER:
        //                     return{
        //                         ...state,
        //                         loading:false
        //                     }
        // case GET_USER_OBJ:
        //                     return{
        //                         ...state,
        //                         loading:false,
        //                         userobj:action.payload
        //                     }
        default:return state
    }
}

IV. In Redux>>Store.jsx file
import { combineReducers, configureStore } from "@reduxjs/toolkit";
import { Reducer } from "./Reducer";
import thunk from "redux-thunk";
import logger from "redux-logger";

const rootreducer=combineReducers({dairyorder:Reducer});
const Store=configureStore({reducer:rootreducer,middleware:[thunk,logger]});
export default Store;

V. In Component>>DairyOrderDetailForm.jsx file
import React, { useState } from "react";
import { useDispatch } from "react-redux";
import { useNavigate } from "react-router-dom";
import { AddOrder } from "../Redux/Action";

function DairyOrderDetailForm() {
  const [orderItem, setOrderItem] = useState("0");
  const [orderStatus, setOrderStatus] = useState("delivered");
  const [orderDate, setOrderDate] = useState("");
  const [quantity, setQuantity] = useState("");
  const [price, setPrice] = useState("0");
  const [phoneNumber, setPhoneNumber] = useState("");
  const [address, setAddress] = useState("");
  const [email, setEmail] = useState("");
  const dispatch = useDispatch();
  const navigate = useNavigate();

  const handleSubmit = (e) => {
    e.preventDefault();
    const orderobj={orderItem,orderStatus,orderDate,quantity,price,phoneNumber,address,email};
    console.log(orderobj);
    dispatch(AddOrder(orderobj));
    //navigate('/orderdiary');
  };

 const handleChange=(e)=>{
    setQuantity(e.target.value);
    const constPrice=60;
    setPrice(constPrice*quantity);
    console.log(quantity);
    console.log(price);
  }

  return (
    <div>
      <form onSubmit={handleSubmit}>
        <div className="row">
          <div className="mb-3 col-6 ">
            <label>Select Item</label>
            <select
              className="form-control form-control-lg"
              placeholder="Select Item"
              value={orderItem}
              onChange={(e) => setOrderItem(e.target.value)}
            >
              <option></option>
              <option>Milk</option>
              <option>Curd</option>
            </select>
          </div>
          <div className="mb-3 col-3">
            <label>Quantity</label>
            <input
              className="form-control form-control-lg"
              placeholder="Quantity(in ltr/kg)"
              value={quantity}
              onChange={(e)=>setQuantity(e.target.value)}
            />
          </div>
          <div className="mb-3 col-3">
            <label>Price</label>
            <p>
              <strong>{price}</strong>
            </p>
          </div>
        </div>
        <div className="row">
          <div className="mb-3 col-6">
            <label>Order Date</label>
            <input
              className="form-control form-control-lg"
              placeholder="dd/mm/yyyy"
              value={orderDate}
              onChange={(e) => setOrderDate(e.target.value)}
            />
          </div>
          <div className="mb-3 col-6">
            <label>Select Order Status</label>
            <select
              className="form-control form-control-lg"
              placeholder="Order Status"
              value={orderStatus}
              onChange={(e) => setOrderStatus(e.target.value)}
            >
              <option></option>
              <option>Ordered</option>
              <option>Delivered</option>
            </select>
          </div>
        </div>
        <div className="row">
          <div className="mb-3 col-6">
            <label>Phone Number</label>
            <input
              className="form-control form-control-lg"
              placeholder="Phone Number"
              value={phoneNumber}
              onChange={(e) => setPhoneNumber(e.target.value)}
            />
          </div>
          <div className="mb-3 col-6">
            <label>Email</label>
            <input
              className="form-control form-control-lg"
              placeholder="Email"
              value={email}
              onChange={(e) => setEmail(e.target.value)}
            />
          </div>
        </div>
        <div className="row">
          <div className="mb-3 col-6">
            <label>Address</label>
            <textarea
              className="form-control form-control-lg"
              placeholder="Address"
              value={address}
              onChange={(e) => setAddress(e.target.value)}
            ></textarea>
          </div>
          <div className="mb-3 col-6">
            <button className="btn btn-lg btn-success" type="submit">
              Submit
            </button>
          </div>
        </div>
      </form>
    </div>
  );
}

export default DairyOrderDetailForm;

VI. In Component>>DairyOrderDetails.jsx file
import React, { useEffect } from "react";
import DairyOrderDetailForm from "./DairyOrderDetailForm";
import { connect } from "react-redux";
import { DeleteOrder, FetchOrderList } from "../Redux/Action";

function DairyOrderDetails(props) {
  const orderobj={orderItem:"",orderStatus:"",orderDate:"",quantity:0,price:0,
  phoneNumber:"",address:"",email:""};

  useEffect(() => {
    props.loadorder();
  }, []);

  const onDelete=(id)=>{
    if(window.confirm('Do you want to Delete user?')){
      props.deleteuser(id);
      props.loaduser();
      //toast.success("User deleted successfully");
    }

  }

  return (
    <div>
      <div className="bg-body-secondary text-center py-2 rounded-2">
        <h1 className="display-6 fw-bold">Dairy Order Details</h1>
      </div>
      <div className="row mt-5">
        <div className="col-6">
          <DairyOrderDetailForm />
        </div>
        <div className="col-6">
          {props.order.orderlist &&
            props.order.orderlist.map((item) => (
              <ul className="list-group" key={item.orderId}>
                <li className="list-group-item d-flex justify-content-between
            align-items-start mb-2 border px-4 py-3 rounded-3" >

                <div className="flex-grow-1 mouse-hover">
                  <div className="fw-bold">{item.orderItem} </div>
                  <div className="fw-bold">{item.quantity + "ltr"} </div>
                  <div className="fw-bold">{item.orderStatus}</div>
                  <div className="fw-bold">{item.orderDate}</div>
                  <i className="fa-solid fa-trash-can fa-lg mouse-hover"></i>
                </div>
                {/* <span className="text-secondary">
                <FontAwesomeIcon icon="fa-solid fa-trash-arrow-up" />
                </span> */}
                <button className="btn btn-danger" onClick={()=>onDelete(item.orderId)}>Delete</button>
                </li>
              </ul>
            ))}
        </div>
      </div>
    </div>
  );
}

const mapStateToProps = (state) => {
  return {
    order: state.dairyorder,
  };
};

const mapDispatchToProps = (dispatch) => {
  return {
    loadorder: () => dispatch(FetchOrderList()),
    deleteuser:(id)=>dispatch(DeleteOrder(id))
  };
};

export default connect(mapStateToProps, mapDispatchToProps)(DairyOrderDetails);

VII. In Component>>Home.jsx file
import React from 'react'

function Home() {
  return (
    <div>Home</div>
  )
}

export default Home

VIII. In App.css file
.header{
  width: 100%;
  background-color: blue;
  color: #fff;
  padding: 1%;
  text-align: left;
}
a{
  text-decoration: none!important;
  color: white!important;
  padding: 2px;
}
.card-header{
  text-align: right;
}

IX. In App.js file
import logo from './logo.svg';
import './App.css';
import { BrowserRouter, Link, Route, Routes } from 'react-router-dom';
import Home from './Component/Home';
import DairyOrderDetails from './Component/DairyOrderDetails';
import { ToastContainer } from 'react-toastify';
import { Provider } from 'react-redux';
import Store from './Redux/Store';

function App() {
  return (
    <Provider store={Store}>
    <div className="App">
      <BrowserRouter>
      <div className='header'>
        <Link to={'/'}>Home</Link>
        <Link to={'/orderdiary'}>DairyOrderDetails</Link>
      </div>
      <Routes>
        <Route path='/' element={<Home></Home>}></Route>
        <Route path='/orderdiary' element={<DairyOrderDetails></DairyOrderDetails>}></Route>
      </Routes>
      </BrowserRouter>
      <ToastContainer position='bottom-right'></ToastContainer>
    </div>
    </Provider>
  );
}

export default App;

X. In index.js file
import React from 'react';
import ReactDOM from 'react-dom/client';
import './index.css';
import App from './App';
import reportWebVitals from './reportWebVitals';
import '../node_modules/bootstrap/dist/css/bootstrap.min.css';
import '../node_modules/react-toastify/dist/ReactToastify.css';
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.2/css/all.min.css" integrity="sha512-z3gLpd7yknf1YoNbCzqRKc4qyor8gaKU1qmn+CShxbuBusANI9QpRohGBreCFkKxLhei6S9CQXFEbbKuqLg0DA==" crossorigin="anonymous" referrerpolicy="no-referrer" />

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

// If you want to start measuring performance in your app, pass a function
// to log results (for example: reportWebVitals(console.log))
// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals
reportWebVitals();


--Now Run
>npm start --p 3000