Lab #7
Customer Segmentation- front end
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="CustomerSegmentation.aspx.vb" Inherits="CustomerSegmentation" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Customer Segmentation</title>
<style>
body {
font-family: Arial, sans-serif;
}
asp\:Table, table {
width: 100%;
}
td, th {
border: 1px solid black;
padding: 8px;
text-align: center;
}
.UpperPanel {
display: flex;
align-items: flex-start;
gap: 10px;
margin-bottom: 5px;
}
.leftPanel {
width: 50%;
}
.rightPanel {
width: 25%;
}
.btn {
background-color: darkslategray;
color: white;
border: none;
padding: 10px 10px;
margin: 1px;
border-radius: 6px;
cursor: pointer;
font-weight: bolder;
}
.filter-box {
display: flex;
flex-direction: column;
margin-bottom: 10px;
text-align: left;
}
.filter-box label {
font-weight: bold;
margin-bottom: 1px;
}
.LowerPanel {
width: 98%;
margin: auto;
background-color: ghostwhite;
padding: 15px;
border-radius: 10px;
text-align: left;
/*display: grid;
grid-template-columns: 1fr 1fr;*/
gap: 15px;
display:flex;
flex-direction:row;
}
</style>
</head>
<body>
<form id="form1" runat="server">
<h2 style="margin-left:40% ; font-weight: bold;">Customer Segmentation</h2>
<hr /><hr />
<div class="UpperPanel">
<div class="leftPanel">
<div class="definitionBox">
<h3>Customer Segmentation Rules</h3>
<ul>
<li><b>Premium Customers:</b> Total spending exceeds threshold (Fro10,000).</li>
<li><b>Frequent Customers:</b> High number of orders in a period.</li>
<li><b>Bulk Buyers:</b> Large quantity purchases in orders.</li>
<li><b>Low Customers:</b> Low total spending below threshold.</li>
</ul>
</div>
</div>
<div class="rightPanel">
<div class ="filter-box">
<label>No of Records to Show:</label>
<asp:TextBox ID="noOfRecordsT" runat="server" Text="5" CssClass="btn"></asp:TextBox>
</div>
<div class="filter-box">
<label>Premium Threshold (Total Spending):</label>
<asp:TextBox ID="prmThresholdT" runat="server" Text="10000" CssClass="btn"></asp:TextBox>
</div>
<div class="filter-box">
<label>Bulk Buyer Threshold (Quantity):</label>
<asp:TextBox ID="blkThresholdT" runat="server" Text="20" CssClass="btn"></asp:TextBox>
</div>
<asp:Button ID="applyBtn" runat="server" Text="Apply Filters" OnClick="applyBtn_Click" CssClass="btn"/>
</div>
</div>
<hr />
<hr />
<table class="MiddlePanel">
<tr>
<td>
<h3>Premium Customers</h3>
<asp:Table ID="tblPremium" runat="server"></asp:Table>
</td>
<td>
<h3>Frequent Customers</h3>
<asp:Table ID="tblFrequent" runat="server"></asp:Table>
</td>
</tr>
<tr>
<td>
<h3>Bulk Buyers</h3>
<asp:Table ID="tblBulk" runat="server"></asp:Table>
</td>
<td>
<h3>Low Customers</h3>
<asp:Table ID="tblLow" runat="server"></asp:Table>
</td>
</tr>
</table>
<hr />
<div class="LowerPanel">
<div>
<h3>Segment Control</h3>
<label>Select Segment</label>
<asp:RadioButtonList ID="rblSegment" runat="server">
<asp:ListItem Text="Premium" Value="Premium" selected="true"/>
<asp:ListItem Text="Frequent" Value="Frequent" />
<asp:ListItem Text="Bulk" Value="Bulk" />
<asp:ListItem Text="Low" Value="Low" />
</asp:RadioButtonList>
<br />
<label>Action Type</label>
<asp:RadioButtonList ID="actionType" runat="server">
<asp:ListItem Text="Message" Value="MessageAction" Selected="True" />
<asp:ListItem Text="Discount" Value="DiscountAction" />
</asp:RadioButtonList>
<br />
</div>
<div>
<asp:TextBox ID="msgInput" runat="server"
TextMode="MultiLine"
Rows="4" Columns="80" placeholder="Write Message or Reason for Discount"></asp:TextBox>
<h3>Discount Settings</h3>
<label>Discount %</label>
<asp:TextBox ID="discoutInput" runat="server"></asp:TextBox>
<br />
<label>Start Date</label>
<asp:TextBox ID="startDate" runat="server" TextMode="Date"></asp:TextBox>
<br />
<label>End Date</label>
<asp:TextBox ID="endDate" runat="server" TextMode="Date"></asp:TextBox>
<br /><br />
<asp:Button ID="actionBtn" runat="server" Text="Send Message/Discount" CssClass="btn" />
<br /><br />
<asp:Label ID="actionResultL" runat="server" Color="Green"></asp:Label>
</div>
</div>
</form>
</body>
</html>

Lab #7
Test case no of records 10
// as before

Lab #7
Premimu Threshold 50,000 No Customer with this uptil now
// code as before

Lab #7
Sending Discount
// code same

Lab #7
Sending Discount
DB DAta

Lab #7
When no customer of a particular segment
...

Lab #7
Customer Sementation Code behind
Imports System.Data.SqlClient
Partial Class CustomerSegmentation
' Inherits System.Web.UI.Page
Inherits BasePage
'Hosted Db con string
' Dim conStr As String = "Data Source=FurnitureDB.mssql.somee.com;Initial Catalog=FurnitureDB;User id=aftabmehdi514_SQLLogin_1;Password=2czuxl4oz4;TrustServerCertificate=True;"
'Local Db con string
Dim conStr As String = "Data Source=MEHTABPC\SQLEXPRESS;Initial Catalog=FurnitureDB;Persist Security Info=True;User ID=mehtab;Password=aftab"
Private Sub CustomerSegmentation_Load(sender As Object, e As EventArgs) Handles Me.Load
CheckPermission("ViewSegmentation")
If Not IsPostBack Then
LoadAll()
msgInput.Text = ""
discoutInput.Text = ""
startDate.Text = ""
endDate.Text = ""
actionResultL.Text = ""
End If
End Sub
Protected Sub applyBtn_Click(sender As Object, e As EventArgs)
LoadAll()
End Sub
Private Sub LoadAll()
' we need to wrok here so that the ids dont' get duplicated ... makeing sure to clear ... giving wired output...
If Session("PremiumIDs") Is Nothing Then
Session("PremiumIDs") = New List(Of Integer)
Else
CType(Session("PremiumIDs"), List(Of Integer)).Clear()
End If
If Session("FrequentIDs") Is Nothing Then
Session("FrequentIDs") = New List(Of Integer)
Else
CType(Session("FrequentIDs"), List(Of Integer)).Clear()
End If
If Session("BulkIDs") Is Nothing Then
Session("BulkIDs") = New List(Of Integer)
Else
CType(Session("BulkIDs"), List(Of Integer)).Clear()
End If
If Session("LowIDs") Is Nothing Then
Session("LowIDs") = New List(Of Integer)
Else
CType(Session("LowIDs"), List(Of Integer)).Clear()
End If
' Session("FrequentIDs") = New List(Of Integer)
'Session("BulkIDs") = New List(Of Integer)
'Session("LowIDs") = New List(Of Integer)
LoadPremium()
LoadFrequent()
LoadBulk()
LoadLow()
End Sub
Private Sub FillTable(query As String, tbl As Table)
tbl.Rows.Clear()
Dim conn As New SqlConnection(conStr)
Dim cmd As New SqlCommand(query, conn)
Try
conn.Open()
Dim reader As SqlDataReader = cmd.ExecuteReader()
Dim header As New TableRow()
header.BackColor = Drawing.Color.Black
header.ForeColor = Drawing.Color.White
Dim h1 As New TableCell()
h1.Text = "ID"
Dim h2 As New TableCell()
h2.Text = "Name"
Dim h3 As New TableCell()
h3.Text = "Value"
header.Cells.Add(h1)
header.Cells.Add(h2)
header.Cells.Add(h3)
tbl.Rows.Add(header)
While reader.Read()
Dim row As New TableRow()
Dim cell1 As New TableCell()
cell1.Text = reader(0).ToString()
Dim cell2 As New TableCell()
cell2.Text = reader(1).ToString()
Dim cell3 As New TableCell()
cell3.Text = reader(2).ToString()
row.Cells.Add(cell1)
row.Cells.Add(cell2)
row.Cells.Add(cell3)
tbl.Rows.Add(row)
'here we will fill of our ids list so that we can later send messages
Dim id As Integer = Convert.ToInt32(reader(0))
If tbl.ID = "tblPremium" Then
CType(Session("PremiumIDs"), List(Of Integer)).Add(id)
ElseIf tbl.ID = "tblFrequent" Then
CType(Session("FrequentIDs"), List(Of Integer)).Add(id)
ElseIf tbl.ID = "tblBulk" Then
CType(Session("BulkIDs"), List(Of Integer)).Add(id)
ElseIf tbl.ID = "tblLow" Then
CType(Session("LowIDs"), List(Of Integer)).Add(id)
End If
'----------------------------------
End While
reader.Close()
Catch ex As Exception
Response.Write(ex.Message)
Finally
conn.Close()
End Try
End Sub
Private Sub LoadPremium()
' also this part needed to make safe using math.max fucntion lets mke it crash safe
Dim noOfRecords As Integer = Math.Max(1, Val(noOfRecordsT.Text))
Dim thr As Integer = Math.Max(0, Val(prmThresholdT.Text))
Dim query As String = ""
query &= "SELECT TOP " & noOfRecords & " C.Customer_Id, C.Customer_Name, "
query &= "SUM(P.Standard_Price * OL.Ordered_Quantity) "
query &= "FROM Customer_t C "
query &= "JOIN Order_t O ON C.Customer_Id = O.Customer_Id "
query &= "JOIN Order_line_t OL ON O.Order_Id = OL.Order_Id "
query &= "JOIN Product_t P ON OL.Product_Id = P.Product_Id "
query &= "GROUP BY C.Customer_Id, C.Customer_Name "
query &= "HAVING SUM(P.Standard_Price * OL.Ordered_Quantity) >= " & thr & " "
query &= "ORDER BY SUM(P.Standard_Price * OL.Ordered_Quantity) DESC"
FillTable(query, tblPremium)
End Sub
Private Sub LoadFrequent()
Dim noOfRecords As Integer = Math.Max(1, Val(noOfRecordsT.Text))
Dim query As String = ""
query &= "SELECT TOP " & noOfRecords & " C.Customer_Id, C.Customer_Name, "
query &= "COUNT(O.Order_Id) "
query &= "FROM Customer_t C "
query &= "JOIN Order_t O ON C.Customer_Id = O.Customer_Id "
query &= "GROUP BY C.Customer_Id, C.Customer_Name "
query &= "ORDER BY COUNT(O.Order_Id) DESC"
FillTable(query, tblFrequent)
End Sub
Private Sub LoadBulk()
Dim noOfRecords As Integer = Math.Max(1, Val(noOfRecordsT.Text)) ' can be made safe form sql injection but now sufficient
Dim thr As Integer = Math.Max(0, Val(blkThresholdT.Text))
Dim query As String = ""
query &= "SELECT TOP " & noOfRecords & " C.Customer_Id, C.Customer_Name, "
query &= "SUM(OL.Ordered_Quantity) "
query &= "FROM Customer_t C "
query &= "JOIN Order_t O ON C.Customer_Id = O.Customer_Id "
query &= "JOIN Order_line_t OL ON O.Order_Id = OL.Order_Id "
query &= "GROUP BY C.Customer_Id, C.Customer_Name "
query &= "HAVING SUM(OL.Ordered_Quantity) >= " & thr & " "
query &= "ORDER BY SUM(OL.Ordered_Quantity) DESC"
FillTable(query, tblBulk)
End Sub
Private Sub LoadLow()
Dim noOfRecords As Integer = Math.Max(1, Val(noOfRecordsT.Text))
Dim query As String = ""
query &= "SELECT TOP " & noOfRecords & " C.Customer_Id, C.Customer_Name, "
query &= "SUM(P.Standard_Price * OL.Ordered_Quantity) "
query &= "FROM Customer_t C "
query &= "JOIN Order_t O ON C.Customer_Id = O.Customer_Id "
query &= "JOIN Order_line_t OL ON O.Order_Id = OL.Order_Id "
query &= "JOIN Product_t P ON OL.Product_Id = P.Product_Id "
query &= "GROUP BY C.Customer_Id, C.Customer_Name "
query &= "ORDER BY SUM(P.Standard_Price * OL.Ordered_Quantity) ASC"
FillTable(query, tblLow)
End Sub
' ok so lets implement Message or Discout System
' Made two tables in db segmentmessage and CustomerDiscounts
' For administation Actions lets make a button event handler
Protected Sub actionBtn_Click(sender As Object, e As EventArgs) Handles actionBtn.Click
actionResultL.Text = ""
' Firt of all , lets get the ids of custoemr in a parituclar segment in a list ....!
Dim list As List(Of Integer)
If rblSegment.SelectedValue = "Premium" Then
list = CType(Session("PremiumIDs"), List(Of Integer))
ElseIf rblSegment.SelectedValue = "Frequent" Then
list = CType(Session("FrequentIDs"), List(Of Integer))
ElseIf rblSegment.SelectedValue = "Bulk" Then
list = CType(Session("BulkIDs"), List(Of Integer))
Else
list = CType(Session("LowIDs"), List(Of Integer))
End If
Dim conn As New SqlConnection(conStr)
Dim cmd As New SqlCommand
cmd.Connection = conn
' One last thing if no reocrd in particular segment ...
If list Is Nothing OrElse list.Count = 0 Then
actionResultL.Text = "No customers found in selected segment."
LoadAll()
Exit Sub
End If
Try
conn.Open()
actionResultL.Text = ""
' First of all lets do validaiton for discount
Dim discountValue As Integer
If actionType.SelectedValue = "DiscountAction" Then
If Not Integer.TryParse(discoutInput.Text, discountValue) Then
actionResultL.Text = "Please enter a valid number."
LoadAll()
Exit Sub
End If
If discountValue < 0 Or discountValue > 100 Then
actionResultL.Text = "Discount must be between 0 and 100."
LoadAll()
Exit Sub
End If
If startDate.Text = "" Then
actionResultL.Text = "Please enter a valid start date."
LoadAll()
Exit Sub
End If
If endDate.Text = "" Then
actionResultL.Text = "Please enter a valid end date."
LoadAll()
Exit Sub
End If
End If
If actionType.SelectedValue = "MessageAction" Then
If msgInput.Text = "" Then
actionResultL.Text = "Please Enter a message to send."
LoadAll()
Exit Sub
End If
End If
For Each id As Integer In list
' as we are doing two queires so we should clear the parameter
cmd.Parameters.Clear()
'IF the admin selects to send messge
actionResultL.Text &= "apply aciton on : " & id & "<br>"
If actionType.SelectedValue = "MessageAction" Then
Dim query As String = "INSERT INTO SegmentMessages (CustomerId, MessageText, CreatedDate) VALUES (@id, @msg, GETDATE())"
cmd.CommandText = query
cmd.Parameters.AddWithValue("@id", id)
cmd.Parameters.AddWithValue("@msg", msgInput.Text)
Dim rowsAffected As Integer = cmd.ExecuteNonQuery()
actionResultL.Text &= "Rows inserted: " & rowsAffected & "<br>"
' Response.Write("command made : " & cmd.CommandText & "<br>")
'for 2nd choice
ElseIf actionType.SelectedValue = "DiscountAction" Then
' One thing that we missed earlier is causing probme is not to delete teh previosu discounts :
Dim delCmd As New SqlCommand("DELETE FROM CustomerDiscounts WHERE CustomerId=@id", conn)
delCmd.Parameters.AddWithValue("@id", id)
delCmd.ExecuteNonQuery()
Dim query As String = "INSERT INTO CustomerDiscounts (CustomerId, DiscountPercent, Reason, StartDate, EndDate) VALUES (@id, @d, @r, @s, @e)"
cmd.CommandText = query
cmd.Parameters.AddWithValue("@id", id)
cmd.Parameters.AddWithValue("@d", discountValue)
cmd.Parameters.AddWithValue("@r", msgInput.Text)
cmd.Parameters.AddWithValue("@s", Convert.ToDateTime(startDate.Text))
cmd.Parameters.AddWithValue("@e", Convert.ToDateTime(endDate.Text))
' Response.Write("sent discout to customer :" & id & " with discount percent : " & Val(discoutInput.Text))
' actionResultL.Text &= "Sent discount to customer :" & id & " with discount percent : " & Val(discoutInput.Text) & "<br>"
Dim rowsAffected As Integer = cmd.ExecuteNonQuery()
actionResultL.Text &= "Rows inserted: " & rowsAffected & "<br>"
End If
Next
actionResultL.Text = "Action applied successfully to " & list.Count & " customers!"
LoadAll()
Catch ex As Exception
actionResultL.Text = ex.Message
Finally
conn.Close()
End Try
' lets clear so that it don;t creat mess after action applied
msgInput.Text = ""
discoutInput.Text = ""
startDate.Text = ""
endDate.Text = ""
End Sub
End Class
' Here is summary fo validadation and Database changes we have done so far
' VALIDATIONS
' MESSAGE VALIDATION
' Check if message textbox is empty
' If empty show error "Please enter a message"
' Stop execution using Exit Sub
' Prevents inserting blank messages in database
' DISCOUNT VALIDATIONS
' Discount must be numeric using Integer.TryParse()
' Discount must be between 0 and 100
' Start Date validation
' Check if empty to avoid DateTime conversion error
' End Date validation
' Check if empty
' Better approach
' Use DateTime.TryParse instead of Convert.ToDateTime
' GENERAL VALIDATIONS
' Check if selected segment has customers
' If no customers found show message and stop execution
' IMPORTANT
' Clear actionResultL.Text at start to remove old messages
' Use Exit Sub after validation failure so no database query runs
' DATABASE TABLES FOR THIS FEATURE
' SegmentMessages
' Stores messages sent to customers
' Fields
' CustomerId
' MessageText
' CreatedDate
' CustomerDiscounts
' Stores discount information
' Fields
' CustomerId
' DiscountPercent
' Reason
' StartDate
' EndDate
' Before inserting new discount old discount is deleted to avoid duplicates
Lab #7
Update to Customer Dashboard - We are displaying both message and Discounts to make sure everything is working
Imports System.Data.SqlClient
Partial Class CustomerDashboard
'Inherits System.Web.UI.Page
Inherits BasePage
Dim customerId As Integer = -1
Private Sub CustomerDashboard_Load(sender As Object, e As EventArgs) Handles Me.Load
'When session will expire it will return the control to login page...
If Session("UserId") Is Nothing Then
Response.Redirect("LogIn.aspx")
Exit Sub
End If
'Hosted DB connection String
'Dim conStr As String = "Data Source=FurnitureDB.mssql.somee.com;Initial Catalog=FurnitureDB;User id=aftabmehdi514_SQLLogin_1;Password=2czuxl4oz4;TrustServerCertificate=True;"
' Local DB connection string
Dim conStr As String = "Data Source=MEHTABPC\SQLEXPRESS;Initial Catalog=FurnitureDB;Persist Security Info=True;User ID=mehtab;Password=aftab"
CheckPermission("ViewCustomerDashboard")
' Retriving ID and Messages '
Using conn As New SqlConnection(conStr)
conn.Open()
customerId = GetCustomerId(Session("UserId"), conn)
ShowCustomerMessages(customerId, conn)
ShowCustomerDiscounts(customerId, conn)
End Using
End Sub
Protected Sub LogOutButton_Click(sender As Object, e As EventArgs) Handles LogOutButton.Click
Session.Abandon()
Response.Redirect("LogIn.aspx")
End Sub
' we have userid in session storage that we will use to access customer informaiton from custoemr table
' but lets do some work to complete the work of message recieve on behalff of custoemr segmentaion
'that we have developed so far
Private Function GetCustomerId(userId As Integer, conn As SqlConnection) As Integer
' Response.Write("Custoemr Dashboard recevied user id : " & userId)
' we used isnull a better approach crash free..!
Dim cmd As New SqlCommand("SELECT ISNULL(Customer_Id, -1) FROM Customer_t WHERE UserId = @uid", conn)
cmd.Parameters.AddWithValue("@uid", userId)
' making the resutl crash free....
Dim result As Integer = -1
Try
result =cmd.ExecuteScalar()
Catch
result = -1
End Try
' Response.Write("<br> found customer id " & result)
idLabel.Text = result
Return result
End Function
Protected Sub ShowCustomerMessages(customerId As Integer, conn As SqlConnection)
Dim cmd As New SqlCommand("SELECT MessageText, CreatedDate FROM SegmentMessages WHERE CustomerId = @customerId ORDER BY CreatedDate DESC", conn)
cmd.Parameters.AddWithValue("@customerId", customerId)
Dim reader As SqlDataReader = cmd.ExecuteReader()
While reader.Read()
' Response.Write("<b><p>" & reader("MessageText").ToString() & "</P></b><br>" & reader("CreatedDate").ToString() & "<hr>")
messagesDiv.InnerHtml &= "<b>" & reader("MessageText").ToString() & "</b><br>" & "<p>" & reader("CreatedDate").ToString() & "</p><hr>"
End While
'Dim reader As SqlDataReader = cmd.ExecuteReader()
' While reader.Read()
'Response.Write("<p>" & reader("Message").ToString() & "</p>")
'End While
reader.Close()
End Sub
Private Sub ShowCustomerDiscounts(customerId As Integer, conn As SqlConnection)
' Response.Write("show discouts received customer id as : " & customerId)
Dim query As String = "Select DiscountPercent, Reason, StartDate, EndDate From CustomerDiscounts WHERE CustomerId = @cid ORDER BY StartDate DESC"
Dim cmd As New SqlCommand(query, conn)
cmd.Parameters.AddWithValue("@cid", customerId)
Dim reader As SqlDataReader = cmd.ExecuteReader()
While reader.Read()
Dim percent As Integer = reader("DiscountPercent")
Dim reason As String = reader("Reason").ToString()
Dim startD As Date = Convert.ToDateTime(reader("StartDate"))
Dim endD As Date = Convert.ToDateTime(reader("EndDate"))
Dim today As Date = Date.Now
Dim status As String = ""
Dim daysLeft As String = ""
If today < startD Then
status = "Upcoming"
daysLeft = "Starts In " & (startD - today).Days & " days"
ElseIf today >= startD And today <= endD Then
status = "Active"
daysLeft = "Expires In " & (endD - today).Days & " days"
Else
status = "Expired"
daysLeft = "Expired"
End If
discountDiv.InnerHtml &= "<div style='border:1px solid gray; padding:10px; margin:5px; border-radius:6px;'>"
discountDiv.InnerHtml &= "<b>" & percent & "% OFF</b><br>"
discountDiv.InnerHtml &= "Reason: " & reason & "<br>"
discountDiv.InnerHtml &= "<b>" & status & "</b> | " & daysLeft
discountDiv.InnerHtml &= "</div>"
End While
reader.Close()
End Sub
End Class

Lab #7
Customer Dashboard aspx code
<%@ Page Language="VB" AutoEventWireup="false" CodeFile="CustomerDashboard.aspx.vb" Inherits="CustomerDashboard" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title>Customer Dashboard</title>
<style>
body {
font-family: Arial, sans-serif;
}
.header {
background: black;
color: white;
padding: 10px;
text-align: center;
}
.header a {
color: white;
}
.main {
display: flex;
gap: 20px;
margin-top: 20px;
}
.ItemButtons {
display: flex;
gap: 10px;
margin-left:40px;
}
.p1, .p2, .p3 {
background-color: lightgrey;
width: 250px;
padding: 15px;
text-align: center;
border-radius: 5px;
}
#messagesDiv {
margin-top: 20px;
padding: 15px;
border: 1px solid;
border-radius: 8px;
}
#msgDiscDiv {
display: flex;
gap: 20px;
margin-top: 20px;
}
#discountDiv {
margin-top: 20px;
padding: 15px;
border: 1px solid;
border-radius: 8px;
}
</style>
</head>
<body>
<form id="form1" runat="server">
<div>
<div class="header">
Pine Valley Furniture |
<a href="Search.aspx">Search </a> |
<a href="About.aspx">About </a> |
<a href="Help.aspx">Help </a> |
<asp:Button id="LogOutButton" runat="server" Text="LogOut" OnClick="LogOutButton_Click" />
</div>
<h2>Welcome Back Dear Customer </h2>
<asp:label id="idLabel" runat="server" Text=""></asp:Label>
<h2>Products</h2>
<div class="main">
<div class="p1">
<img src="Assets/p1.jpg" height="100px" width="100px">
<p>Arm Chair</p>
<p>Product Description</p>
<div>
<div class="ItemButtons">
<a href="Order.aspx" style="padding:8px 15px; background:black; color:white; text-decoration:none; border-radius:4px;">
Add to cart </a>
<a href="Order.aspx" style="padding:8px 15px; background:white; color:black; margin-right="2px"; text-decoration:none; border-radius:4px;">
Buy </a>
</div>
</div>
</div>
<div class="p2">
<img src="Assets/p2.jpg" height="100px" width="100px">
<p>Chair</p>
<p>Product Description...</p>
<div class="ItemButtons">
<a href="Order.aspx" style="padding:8px 15px; background:black; color:white; text-decoration:none; border-radius:4px;">
Add to cart </a>
<a href="Order.aspx" style="padding:8px 15px; background:white; color:black; margin-right="2px"; text-decoration:none; border-radius:4px;">
Buy </a>
</div>
</div>
<div class="p2">
<img src="Assets/p3.jpg" height="100px" width="100px">
<p>Sofa</p>
<p>Product Description...</p>
<div class="ItemButtons">
<a href="Order.aspx" style="padding:8px 15px; background:black; color:white; text-decoration:none; border-radius:4px;">
Add to cart </a>
<a href="Order.aspx" style="padding:8px 15px; background:white; color:black; margin-right="2px"; text-decoration:none; border-radius:4px;">
Buy </a>
</div>
</div>
</div>
<div id="msgDiscDiv" runat="server">
<div id="messagesDiv" runat="server">
<h4 style="margin:2% 30%">Message Panel</h4>
</div>
<div id="discountDiv" runat="server">
<h4 style="margin:2% 30%">Your Discounts</h4>
</div>
</div>
</div>
</form>
</body>
</html>