Login.aspx

<%@ Page Language="VB" AutoEventWireup="true" CodeFile="Login.aspx.vb" Inherits="Login" %>

<!DOCTYPE html>
<html>
<head runat="server">
<title>Login</title>
<link rel="stylesheet" href="StyleSheet.css" />
</head>

<body>
<form id="form1" runat="server">

<div class="main-container">

<div class="sidebar">
<div class="logo">QuizApp</div>
<div class="nav-item active">Login</div>
</div>

<div class="content-area">
<div class="card">

<h2>Login</h2>

<div class="input-group">
<label>Email:</label>
<asp:TextBox ID="txtEmail" runat="server" CssClass="form-control"></asp:TextBox>
</div>

<div class="input-group">
<label>Password:</label>
<asp:TextBox ID="txtPassword" runat="server" TextMode="Password" CssClass="form-control"></asp:TextBox>
</div>

<asp:Button ID="btnLogin" runat="server" Text="Login" OnClick="btnLogin_Click" CssClass="btn-primary" />
<asp:Label ID="lblMsg" runat="server" CssClass="message"></asp:Label>

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

</form>
</body>
</html>

Login.aspx.vb

Imports System.Data.SqlClient
Imports System.Configuration

Partial Class Login
    Inherits System.Web.UI.Page

    Protected Sub btnLogin_Click(sender As Object, e As EventArgs)

        Using con As New SqlConnection(ConfigurationManager.ConnectionStrings("QuizDB").ConnectionString)

            Dim query As String = "SELECT UserID, Role FROM Users WHERE Email=@e AND Password=@p"

            Using cmd As New SqlCommand(query, con)
                cmd.Parameters.AddWithValue("@e", txtEmail.Text.Trim())
                cmd.Parameters.AddWithValue("@p", txtPassword.Text.Trim())

                con.Open()

                Using dr As SqlDataReader = cmd.ExecuteReader()

                    If dr.Read() Then
                        Session("UserID") = dr("UserID")
                        Dim role As String = dr("Role").ToString()
                        Session("Role") = role

                        Select Case role
                            Case "Teacher"
                                Response.Redirect("TeacherDashboard.aspx")
                            Case "Student"
                                Response.Redirect("StudentDashboard.aspx")
                            Case "Admin"
                                Response.Redirect("AdminDashboard.aspx")
                            Case Else
                                lblMsg.Text = "Role not recognized"
                        End Select

                    Else
                        lblMsg.Text = "Invalid Email or Password"
                    End If

                End Using
            End Using
        End Using

    End Sub
End Class

AdminDashboard.aspx

<%@ Page Language="VB" AutoEventWireup="true" CodeFile="AdminDashboard.aspx.vb" Inherits="AdminDashboard" %>

<!DOCTYPE html>
<html>
<head runat="server">
<title>Admin Dashboard</title>
<link rel="stylesheet" href="StyleSheet.css" />
</head>

<body>
<form id="form1" runat="server">

<div class="main-container">

<div class="sidebar">
<div class="logo">QuizApp</div>
<div class="nav-item active">Dashboard</div>
</div>

<div class="content-area">
<div class="card">

<h1>Admin Dashboard</h1>

<asp:Label ID="lblWelcome" runat="server"></asp:Label>

<asp:Button ID="btnScheduleQuiz" runat="server" Text="Schedule Quiz" OnClick="btnScheduleQuiz_Click" CssClass="btn-primary" />
<br /><br />

<asp:Button ID="btnLogout" runat="server" Text="Logout" OnClick="btnLogout_Click" CssClass="btn-primary" />

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

</form>
</body>
</html>

AdminDashboard.aspx.vb

Partial Class AdminDashboard
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load

        If Session("Role") <> "Admin" Then
            Response.Redirect("Login.aspx")
        End If

        If Not IsPostBack Then
            lblWelcome.Text = "Welcome Admin"
        End If

    End Sub

    Protected Sub btnScheduleQuiz_Click(sender As Object, e As EventArgs)
        Response.Redirect("ScheduleQuiz.aspx")
    End Sub

    Protected Sub btnLogout_Click(sender As Object, e As EventArgs)
        Session.Abandon()
        Response.Redirect("Login.aspx")
    End Sub

End Class

ScheduleQuiz.aspx

<%@ Page Language="VB" AutoEventWireup="true" CodeFile="ScheduleQuiz.aspx.vb" Inherits="ScheduleQuiz" %>

<!DOCTYPE html>
<html>
<head runat="server">
<title>Schedule Quiz</title>
<link rel="stylesheet" href="StyleSheet.css" />
</head>

<body>
<form id="form1" runat="server">

<div class="main-container">

<div class="sidebar">
<div class="logo">QuizApp</div>
<div class="nav-item active">Schedule</div>
</div>

<div class="content-area">
<div class="card">

<h2>Schedule Quiz</h2>

<asp:DropDownList ID="ddlQuiz" runat="server" CssClass="form-control"></asp:DropDownList>

<asp:TextBox ID="txtStart" runat="server" CssClass="form-control"></asp:TextBox>
<asp:TextBox ID="txtEnd" runat="server" CssClass="form-control"></asp:TextBox>

<asp:Button ID="btnSchedule" runat="server" Text="Schedule" OnClick="btnSchedule_Click" CssClass="btn-primary" />

<asp:Label ID="lblMsg" runat="server" CssClass="message"></asp:Label>

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

</form>
</body>
</html>

ScheduleQuiz.aspx.vb

Imports System.Data.SqlClient
Imports System.Configuration

Partial Class ScheduleQuiz
    Inherits System.Web.UI.Page

    Dim connStr As String = ConfigurationManager.ConnectionStrings("QuizDB").ConnectionString

    Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
        If Session("Role") <> "Admin" Then
            Response.Redirect("Login.aspx")
        End If

        If Not IsPostBack Then
            LoadQuizzes()
        End If
    End Sub

    Sub LoadQuizzes()
        Using con As New SqlConnection(connStr)
            Dim cmd As New SqlCommand("SELECT QuizID, Title FROM Quiz", con)
            con.Open()

            ddlQuiz.DataSource = cmd.ExecuteReader()
            ddlQuiz.DataTextField = "Title"
            ddlQuiz.DataValueField = "QuizID"
            ddlQuiz.DataBind()

            ddlQuiz.Items.Insert(0, New ListItem("-- Select Quiz --", "0"))
        End Using
    End Sub

    Protected Sub btnSchedule_Click(sender As Object, e As EventArgs)
        Using con As New SqlConnection(connStr)

            Dim sql As String = "UPDATE Quiz SET StartTime=@s, EndTime=@e WHERE QuizID=@id"

            Dim cmd As New SqlCommand(sql, con)

            cmd.Parameters.AddWithValue("@s", txtStart.Text)
            cmd.Parameters.AddWithValue("@e", txtEnd.Text)
            cmd.Parameters.AddWithValue("@id", ddlQuiz.SelectedValue)

            con.Open()
            cmd.ExecuteNonQuery()

        End Using

        lblMsg.Text = "Quiz Scheduled Successfully"
    End Sub

End Class

Student_Results.aspx

<%@ Page Language="VB" AutoEventWireup="true" CodeFile="Student_Results.aspx.vb" Inherits="Student_Results" %>

<!DOCTYPE html>
<html>
<head runat="server">
<title>My Results</title>
<link rel="stylesheet" href="StyleSheet.css" />
</head>

<body>
<form id="form1" runat="server">

<div class="main-container">

<div class="sidebar">
<div class="logo">QuizApp</div>
<div class="nav-item active">My Results</div>
</div>

<div class="content-area">
<div class="card">

<h2>My Quiz Results</h2>

<asp:GridView ID="gvResults" runat="server" CssClass="grid-view"></asp:GridView>

</div>
</div>

</div>

</form>
</body>
</html>

Student_Results.aspx.vb

Imports System.Data
Imports System.Data.SqlClient
Imports System.Configuration

Partial Class Student_Results
    Inherits System.Web.UI.Page

    Dim con As New SqlConnection(ConfigurationManager.ConnectionStrings("QuizDB").ConnectionString)

    Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load

        If Session("Role") Is Nothing OrElse Session("Role").ToString() <> "Student" Then
            Response.Redirect("Login.aspx")
        End If

        If Not IsPostBack Then
            LoadResults()
        End If

    End Sub

    Private Sub LoadResults()

        Dim query As String = "SELECT q.Title, " & _
                              "ISNULL(qa.Score, 0) AS Score, " & _
                              "qa.StartTime, " & _
                              "qa.EndTime, " & _
                              "ISNULL(qa.Status, 'Pending') AS Status " & _
                              "FROM QuizAttempts qa " & _
                              "INNER JOIN Quiz q ON qa.QuizID = q.QuizID " & _
                              "WHERE qa.StudentID = @SID " & _
                              "ORDER BY qa.StartTime DESC"

        Dim cmd As New SqlCommand(query, con)
        cmd.Parameters.AddWithValue("@SID", Session("UserID"))

        Dim da As New SqlDataAdapter(cmd)
        Dim dt As New DataTable()

        da.Fill(dt)

        gvResults.DataSource = dt
        gvResults.DataBind()

    End Sub

End Class

Student_TakeQuiz.aspx

<%@ Page Language="VB" AutoEventWireup="true" CodeFile="Student_TakeQuiz.aspx.vb" Inherits="Student_TakeQuiz" %>

<!DOCTYPE html>
<html>
<head runat="server">
    <title>Take Quiz</title>
    <link rel="stylesheet" href="StyleSheet.css" />
</head>

<body>

<form id="form1" runat="server">

<div class="main-container">
    
    <div class="sidebar">
        <div class="logo">QuizApp</div>
        <div class="nav-item active">Take Quiz</div>
    </div>

    <div class="content-area">
        <div class="card">

            <asp:Label ID="lblQuestion" runat="server" Font-Bold="True"></asp:Label>

            <br /><br />

            <asp:RadioButtonList ID="rblOptions" runat="server"></asp:RadioButtonList>

            <br />

            <asp:Button ID="btnNext" runat="server" Text="Next"
                OnClick="btnNext_Click" CssClass="btn-primary" />

            <asp:Button ID="btnSubmit" runat="server" Text="Submit Quiz"
                OnClick="btnSubmit_Click" CssClass="btn-primary" />

        </div>
    </div>

</div>

</form>
</body>
</html>

Student_TakeQuiz.aspx.vb

Imports System.Data
Imports System.Data.SqlClient
Imports System.Configuration

Partial Class Student_TakeQuiz
    Inherits System.Web.UI.Page

    Dim con As New SqlConnection(ConfigurationManager.ConnectionStrings("QuizDB").ConnectionString)

    Private Property QuestionIndex As Integer
        Get
            If Session("qIndex") Is Nothing Then Return 0
            Return Convert.ToInt32(Session("qIndex"))
        End Get
        Set(value As Integer)
            Session("qIndex") = value
        End Set
    End Property

    Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load

        If Session("Role") Is Nothing OrElse Session("Role").ToString() <> "Student" Then
            Response.Redirect("Login.aspx")
            Return
        End If

        If Not IsPostBack Then

            If Request.QueryString("QuizID") Is Nothing Then
                Response.Redirect("StudentDashboard.aspx")
                Return
            End If

            Session("QuizID") = Convert.ToInt32(Request.QueryString("QuizID"))

            If AlreadyAttempted() Then
                Response.Redirect("StudentDashboard.aspx")
                Return
            End If

            Dim existingAttemptID As Integer = GetStartedAttemptID()

            If existingAttemptID > 0 Then
                Session("AttemptID") = existingAttemptID
                Session("ShuffledQuestions") = GetAnsweredAndRemainingQuestions(existingAttemptID)
                QuestionIndex = GetAnsweredCount(existingAttemptID)
            Else
                QuestionIndex = 0
                CreateAttempt()
                Session("ShuffledQuestions") = GetShuffledQuestions()
            End If

            LoadQuestion()
        End If

    End Sub

    Private Sub LoadQuestion()

        If Session("ShuffledQuestions") Is Nothing Then
            Response.Redirect("StudentDashboard.aspx")
            Return
        End If

        Dim questions = CType(Session("ShuffledQuestions"), List(Of Integer))

        If questions.Count = 0 OrElse QuestionIndex >= questions.Count Then
            SubmitQuiz()
            Return
        End If

        Dim qID As Integer = questions(QuestionIndex)

        Dim cmd As New SqlCommand(
            "SELECT QuestionText FROM Questions WHERE QuestionID=@Q", con)

        cmd.Parameters.AddWithValue("@Q", qID)

        con.Open()
        lblQuestion.Text = Convert.ToString(cmd.ExecuteScalar())
        con.Close()

        Session("CurrentQID") = qID

        LoadOptions(qID)

    End Sub

    Protected Sub btnNext_Click(sender As Object, e As EventArgs)

        SaveAnswer()
        QuestionIndex += 1
        LoadQuestion()

    End Sub

    Private Sub SaveAnswer()

        If Session("AttemptID") Is Nothing Then Exit Sub
        If Session("CurrentQID") Is Nothing Then Exit Sub
        If rblOptions.SelectedValue = "" Then Exit Sub

        Dim query As String =
            "IF EXISTS (SELECT 1 FROM Answers WHERE AttemptID=@A AND QuestionID=@Q) " &
            "UPDATE Answers SET OptionID=@O WHERE AttemptID=@A AND QuestionID=@Q " &
            "ELSE INSERT INTO Answers (AttemptID, QuestionID, OptionID) VALUES (@A,@Q,@O)"

        Using cmd As New SqlCommand(query, con)
            cmd.Parameters.AddWithValue("@A", Session("AttemptID"))
            cmd.Parameters.AddWithValue("@Q", Session("CurrentQID"))
            cmd.Parameters.AddWithValue("@O", rblOptions.SelectedValue)

            con.Open()
            cmd.ExecuteNonQuery()
            con.Close()
        End Using

    End Sub

    Private Sub CreateAttempt()

        Dim query As String =
            "INSERT INTO QuizAttempts (QuizID, StudentID, StartTime, Status) " &
            "VALUES (@Q, @S, GETDATE(), 'Started'); SELECT SCOPE_IDENTITY();"

        Dim cmd As New SqlCommand(query, con)
        cmd.Parameters.AddWithValue("@Q", Session("QuizID"))
        cmd.Parameters.AddWithValue("@S", Session("UserID"))

        con.Open()
        Dim attemptID As Integer = Convert.ToInt32(cmd.ExecuteScalar())
        con.Close()

        Session("AttemptID") = attemptID

    End Sub

    Private Function GetStartedAttemptID() As Integer
        Dim cmd As New SqlCommand(
            "SELECT AttemptID FROM QuizAttempts WHERE QuizID=@Q AND StudentID=@S AND Status='Started'", con)

        cmd.Parameters.AddWithValue("@Q", Session("QuizID"))
        cmd.Parameters.AddWithValue("@S", Session("UserID"))

        con.Open()
        Dim r = cmd.ExecuteScalar()
        con.Close()

        If r Is Nothing Then Return 0
        Return Convert.ToInt32(r)
    End Function

    Private Function AlreadyAttempted() As Boolean

        Dim cmd As New SqlCommand(
            "SELECT AttemptID FROM QuizAttempts WHERE QuizID=@Q AND StudentID=@S AND Status='Completed'", con)

        cmd.Parameters.AddWithValue("@Q", Session("QuizID"))
        cmd.Parameters.AddWithValue("@S", Session("UserID"))

        con.Open()
        Dim r = cmd.ExecuteScalar()
        con.Close()

        Return r IsNot Nothing

    End Function

    Private Function GetAnsweredCount(attemptID As Integer) As Integer

        Dim cmd As New SqlCommand(
            "SELECT COUNT(*) FROM Answers WHERE AttemptID=@A", con)

        cmd.Parameters.AddWithValue("@A", attemptID)

        con.Open()
        Dim count As Integer = Convert.ToInt32(cmd.ExecuteScalar())
        con.Close()

        Return count

    End Function

    Private Function GetAnsweredAndRemainingQuestions(attemptID As Integer) As List(Of Integer)

        Dim answered As New List(Of Integer)

        Dim cmd1 As New SqlCommand(
            "SELECT QuestionID FROM Answers WHERE AttemptID=@A", con)

        cmd1.Parameters.AddWithValue("@A", attemptID)

        con.Open()
        Dim r1 = cmd1.ExecuteReader()
        While r1.Read()
            answered.Add(Convert.ToInt32(r1("QuestionID")))
        End While
        con.Close()

        Dim remaining As New List(Of Integer)

        Dim cmd2 As New SqlCommand(
            "SELECT QuestionID FROM QuizQuestions WHERE QuizID=@Q", con)

        cmd2.Parameters.AddWithValue("@Q", Session("QuizID"))

        con.Open()
        Dim r2 = cmd2.ExecuteReader()
        While r2.Read()
            Dim id = Convert.ToInt32(r2("QuestionID"))
            If Not answered.Contains(id) Then remaining.Add(id)
        End While
        con.Close()

        Dim rnd As New Random()
        For i = remaining.Count - 1 To 1 Step -1
            Dim j = rnd.Next(0, i + 1)
            Dim tmp = remaining(i)
            remaining(i) = remaining(j)
            remaining(j) = tmp
        Next

        answered.AddRange(remaining)
        Return answered

    End Function

    Private Function GetShuffledQuestions() As List(Of Integer)

        Dim list As New List(Of Integer)

        Dim cmd As New SqlCommand(
            "SELECT QuestionID FROM QuizQuestions WHERE QuizID=@Q", con)

        cmd.Parameters.AddWithValue("@Q", Session("QuizID"))

        con.Open()
        Dim r = cmd.ExecuteReader()
        While r.Read()
            list.Add(Convert.ToInt32(r("QuestionID")))
        End While
        con.Close()

        Dim rnd As New Random()
        For i = list.Count - 1 To 1 Step -1
            Dim j = rnd.Next(0, i + 1)
            Dim tmp = list(i)
            list(i) = list(j)
            list(j) = tmp
        Next

        Return list

    End Function

    Private Sub LoadOptions(questionID As Integer)

        Dim cmd As New SqlCommand(
            "SELECT OptionID, OptionText FROM QuestionOptions WHERE QuestionID=@Q ORDER BY NEWID()", con)

        cmd.Parameters.AddWithValue("@Q", questionID)

        Dim dt As New DataTable()
        Dim da As New SqlDataAdapter(cmd)
        da.Fill(dt)

        rblOptions.DataSource = dt
        rblOptions.DataTextField = "OptionText"
        rblOptions.DataValueField = "OptionID"
        rblOptions.DataBind()

    End Sub

    Protected Sub btnSubmit_Click(sender As Object, e As EventArgs)
        SubmitQuiz()
    End Sub

    Private Sub SubmitQuiz()

        SaveAnswer()

        Dim query As String =
            "UPDATE QuizAttempts SET EndTime=GETDATE(), Status='Completed', " &
            "Score=(SELECT COUNT(*) FROM Answers a INNER JOIN QuestionOptions o " &
            "ON a.OptionID=o.OptionID WHERE a.AttemptID=@A AND o.IsCorrect=1) " &
            "WHERE AttemptID=@A"

        Dim cmd As New SqlCommand(query, con)
        cmd.Parameters.AddWithValue("@A", Session("AttemptID"))

        con.Open()
        cmd.ExecuteNonQuery()
        con.Close()

        Dim attemptID As Integer = Convert.ToInt32(Session("AttemptID"))

        Session.Remove("QuizID")
        Session.Remove("AttemptID")
        Session.Remove("ShuffledQuestions")
        Session.Remove("CurrentQID")
        Session.Remove("qIndex")

        Response.Redirect("Student_Results.aspx?AttemptID=" & attemptID)

    End Sub

End Class

StudentDashboard.aspx

<%@ Page Language="VB" AutoEventWireup="true" CodeFile="StudentDashboard.aspx.vb" Inherits="StudentDashboard" %>

<!DOCTYPE html>
<html>
<head runat="server">
<title>Student Dashboard</title>
<link rel="stylesheet" href="StyleSheet.css" />
</head>

<body>

<form id="form1" runat="server">

<div class="main-container">

    <div class="sidebar">
        <div class="logo">QuizApp</div>
        <div class="nav-item active">Dashboard</div>
    </div>

    <div class="content-area">

        <div class="card">

            <h1>Student Dashboard</h1>

            <asp:Label ID="lblWelcome" runat="server"></asp:Label>

            <hr />

            <h3>Available Subjects</h3>

            <asp:GridView ID="gvSubjects" runat="server" AutoGenerateColumns="False" CssClass="grid-view">
                <Columns>
                    <asp:BoundField DataField="SubjectName" HeaderText="Subject" />
                </Columns>
            </asp:GridView>

            <br />

            <h3>Available Quizzes</h3>

            <asp:Label ID="lblNoQuiz" runat="server" ForeColor="Gray" Font-Italic="True"></asp:Label>

            <asp:GridView ID="gvQuizzes" runat="server" AutoGenerateColumns="False"
                OnRowCommand="gvQuizzes_RowCommand"
                OnRowDataBound="gvQuizzes_RowDataBound"
                CssClass="grid-view">

                <Columns>

                    <asp:BoundField DataField="SubjectName" HeaderText="Subject" />
                    <asp:BoundField DataField="Title" HeaderText="Quiz Title" />
                    <asp:BoundField DataField="TotalQuestions" HeaderText="Questions" />
                    <asp:BoundField DataField="TotalTime" HeaderText="Time (min)" />

                    <asp:TemplateField HeaderText="Schedule">
                        <ItemTemplate>

                            <b>From:</b>
                            <%# If(IsDBNull(Eval("StartTime")), "Not Scheduled",
                                Convert.ToDateTime(Eval("StartTime")).ToString("dd MMM hh:mm tt")) %>

                            <br />

                            <b>To:</b>
                            <%# If(IsDBNull(Eval("EndTime")), "Not Scheduled",
                                Convert.ToDateTime(Eval("EndTime")).ToString("dd MMM hh:mm tt")) %>

                        </ItemTemplate>
                    </asp:TemplateField>

                    <asp:TemplateField HeaderText="Status">
                        <ItemTemplate>
                            <asp:Label ID="lblStatus" runat="server"></asp:Label>
                        </ItemTemplate>
                    </asp:TemplateField>

                    <asp:TemplateField>
                        <ItemTemplate>
                            <asp:Button ID="btnAttempt" runat="server"
                                Text="Attempt"
                                CommandName="AttemptQuiz"
                                CommandArgument='<%# Eval("QuizID") %>' />
                        </ItemTemplate>
                    </asp:TemplateField>

                </Columns>

            </asp:GridView>

            <br />

            <asp:Button ID="btnViewResults" runat="server"
                Text="View My Results"
                OnClick="btnViewResults_Click"
                CssClass="btn-primary" />

            <br /><br />

            <asp:Button ID="btnLogout" runat="server"
                Text="Logout"
                OnClick="btnLogout_Click"
                CssClass="btn-primary" />

        </div>

    </div>

</div>

</form>

</body>
</html>

StudentDashboard.aspx.vb

Imports System.Data
Imports System.Data.SqlClient
Imports System.Configuration

Partial Class StudentDashboard
    Inherits System.Web.UI.Page

    Dim con As New SqlConnection(ConfigurationManager.ConnectionStrings("QuizDB").ConnectionString)

    Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load

        If Session("Role") <> "Student" Then
            Response.Redirect("Login.aspx")
        End If

        If Not IsPostBack Then
            lblWelcome.Text = "Welcome Student ID: " & Session("UserID")
            LoadSubjects()
            LoadQuizzes()
        End If

    End Sub

    Private Sub LoadSubjects()

        Dim cmd As New SqlCommand("SELECT SubjectID, SubjectName FROM Subjects", con)
        Dim da As New SqlDataAdapter(cmd)
        Dim dt As New DataTable()

        da.Fill(dt)

        gvSubjects.DataSource = dt
        gvSubjects.DataBind()

    End Sub

    Private Sub LoadQuizzes()

        Dim query As String =
            "SELECT q.QuizID, q.Title, q.TotalQuestions, q.TotalTime, " & _
            "q.StartTime, q.EndTime, s.SubjectName " & _
            "FROM Quiz q " & _
            "INNER JOIN Subjects s ON q.SubjectID = s.SubjectID " & _
            "WHERE q.QuizID NOT IN (SELECT QuizID FROM QuizAttempts WHERE StudentID = @SID)"

        Dim cmd As New SqlCommand(query, con)
        cmd.Parameters.AddWithValue("@SID", Session("UserID"))

        Dim da As New SqlDataAdapter(cmd)
        Dim dt As New DataTable()

        da.Fill(dt)

        gvQuizzes.DataSource = dt
        gvQuizzes.DataBind()

        lblNoQuiz.Text = If(dt.Rows.Count = 0, "No quizzes available.", "")

    End Sub

    Protected Sub gvQuizzes_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles gvQuizzes.RowDataBound

        If e.Row.RowType = DataControlRowType.DataRow Then

            Dim btn As Button = CType(e.Row.FindControl("btnAttempt"), Button)
            Dim lbl As Label = CType(e.Row.FindControl("lblStatus"), Label)

            Dim startObj = DataBinder.Eval(e.Row.DataItem, "StartTime")
            Dim endObj = DataBinder.Eval(e.Row.DataItem, "EndTime")

            If IsDBNull(startObj) Or IsDBNull(endObj) Then
                btn.Enabled = False
                btn.Text = "Not Scheduled"
                lbl.Text = "Pending"
                Return
            End If

            Dim startTime As DateTime = Convert.ToDateTime(startObj)
            Dim endTime As DateTime = Convert.ToDateTime(endObj)

            If DateTime.Now < startTime Then
                btn.Enabled = False
                btn.Text = "Starts Soon"
                lbl.Text = "Upcoming"

            ElseIf DateTime.Now > endTime Then
                btn.Enabled = False
                btn.Text = "Expired"
                lbl.Text = "Closed"

            Else
                btn.Enabled = True
                btn.Text = "Attempt"
                lbl.Text = "Active"
            End If

        End If

    End Sub

    Protected Sub gvQuizzes_RowCommand(sender As Object, e As GridViewCommandEventArgs)

        If e.CommandName = "AttemptQuiz" Then

            Dim quizID As Integer = Convert.ToInt32(e.CommandArgument)

            Session("QuizID") = quizID

            Response.Redirect("Student_TakeQuiz.aspx?QuizID=" & quizID)

        End If

    End Sub

    Protected Sub btnViewResults_Click(sender As Object, e As EventArgs)
        Response.Redirect("Student_Results.aspx")
    End Sub

    Protected Sub btnLogout_Click(sender As Object, e As EventArgs)
        Session.Abandon()
        Response.Redirect("Login.aspx")
    End Sub

End Class

Teacher_AddQuestions.aspx

<%@ Page Language="VB" AutoEventWireup="true" CodeFile="Teacher_AddQuestions.aspx.vb" Inherits="Teacher_AddQuestions" %>

<!DOCTYPE html>
<html>
<head runat="server">
<title>Teacher - Add Questions</title>
<link rel="stylesheet" href="StyleSheet.css" />
</head>

<body>
<form id="form1" runat="server">

<div class="main-container">
<div class="sidebar">
<div class="logo">QuizApp</div>
<div class="nav-item active">Add Questions</div>
</div>

<div class="content-area">
<div class="card">

<h2>Create New Question</h2>

<asp:Label ID="lblMsg" runat="server" Visible="false"></asp:Label>

<asp:DropDownList ID="ddlSubject" runat="server"></asp:DropDownList>
<asp:DropDownList ID="ddlType" runat="server"></asp:DropDownList>

<asp:TextBox ID="txtQ" runat="server" TextMode="MultiLine"></asp:TextBox>

<asp:TextBox ID="txtA" runat="server"></asp:TextBox>
<asp:TextBox ID="txtB" runat="server"></asp:TextBox>
<asp:TextBox ID="txtC" runat="server"></asp:TextBox>
<asp:TextBox ID="txtD" runat="server"></asp:TextBox>

<asp:DropDownList ID="ddlCorrect" runat="server"></asp:DropDownList>

<asp:Button ID="btnAdd" runat="server" Text="Save Question" />

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

</form>
</body>
</html>

Teacher_AddQuestions.aspx.vb

Imports System.Data
Imports System.Data.SqlClient
Imports System.Web.Configuration

Partial Class Teacher_AddQuestions
    Inherits System.Web.UI.Page

    Dim connStr As String = WebConfigurationManager.ConnectionStrings("QuizDB").ConnectionString

    Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load

        If Session("UserID") Is Nothing Then
            Response.Redirect("Login.aspx")
        End If

        If Not IsPostBack Then
            LoadSubjects()
        End If

    End Sub

    Sub LoadSubjects()

        Using con As New SqlConnection(connStr)

            Dim cmd As New SqlCommand("SELECT SubjectID, SubjectName FROM Subjects", con)

            con.Open()

            ddlSubject.DataSource = cmd.ExecuteReader()
            ddlSubject.DataTextField = "SubjectName"
            ddlSubject.DataValueField = "SubjectID"
            ddlSubject.DataBind()

        End Using

    End Sub

    Protected Sub ddlType_SelectedIndexChanged(sender As Object, e As EventArgs)

        lblMsg.Visible = False

        If ddlType.SelectedValue = "TF" Then

            pnlExtraOptions.Visible = False
            liC.Enabled = False
            liD.Enabled = False

            txtA.Text = "True"
            txtB.Text = "False"

            lblA.InnerText = "Option A (True):"
            lblB.InnerText = "Option B (False):"

        Else

            pnlExtraOptions.Visible = True
            liC.Enabled = True
            liD.Enabled = True

            txtA.Text = ""
            txtB.Text = ""

            lblA.InnerText = "Option A:"
            lblB.InnerText = "Option B:"

        End If

    End Sub

    Protected Sub btnAdd_Click(sender As Object, e As EventArgs)

        Try

            Using con As New SqlConnection(connStr)

                con.Open()

                Dim sqlQ As String =
                    "INSERT INTO Questions (SubjectID, TeacherID, QuestionText, DifficultyLevel)
                     VALUES (@sid, @tid, @q, @diff);
                     SELECT SCOPE_IDENTITY();"

                Dim qid As Integer

                Using cmd As New SqlCommand(sqlQ, con)

                    cmd.Parameters.AddWithValue("@sid", ddlSubject.SelectedValue)
                    cmd.Parameters.AddWithValue("@tid", Session("UserID"))
                    cmd.Parameters.AddWithValue("@q", txtQ.Text.Trim())
                    cmd.Parameters.AddWithValue("@diff", ddlDifficulty.SelectedValue)

                    qid = Convert.ToInt32(cmd.ExecuteScalar())

                End Using

                InsertOption(con, qid, txtA.Text.Trim(), ddlCorrect.SelectedValue = "A")
                InsertOption(con, qid, txtB.Text.Trim(), ddlCorrect.SelectedValue = "B")

                If ddlType.SelectedValue = "MCQ" Then
                    InsertOption(con, qid, txtC.Text.Trim(), ddlCorrect.SelectedValue = "C")
                    InsertOption(con, qid, txtD.Text.Trim(), ddlCorrect.SelectedValue = "D")
                End If

            End Using

            lblMsg.Text = "Question added successfully!"
            lblMsg.CssClass = "success-msg"
            lblMsg.Visible = True

            ClearFields()

        Catch ex As Exception

            lblMsg.Text = "Error: " & ex.Message
            lblMsg.CssClass = "error-msg"
            lblMsg.Visible = True

        End Try

    End Sub

    Sub InsertOption(con As SqlConnection, qid As Integer, text As String, isCorrect As Boolean)

        Dim sqlOpt As String =
            "INSERT INTO QuestionOptions (QuestionID, OptionText, IsCorrect)
             VALUES (@qid, @text, @correct)"

        Using cmd As New SqlCommand(sqlOpt, con)

            cmd.Parameters.AddWithValue("@qid", qid)
            cmd.Parameters.AddWithValue("@text", text)
            cmd.Parameters.AddWithValue("@correct", If(isCorrect, 1, 0))

            cmd.ExecuteNonQuery()

        End Using

    End Sub

    Sub ClearFields()

        txtQ.Text = ""

        If ddlType.SelectedValue = "MCQ" Then
            txtA.Text = ""
            txtB.Text = ""
        End If

        txtC.Text = ""
        txtD.Text = ""

    End Sub

End Class

Teacher_CreateQuiz.aspx

<%@ Page Language="VB" AutoEventWireup="true" CodeFile="Teacher_CreateQuiz.aspx.vb" Inherits="Teacher_CreateQuiz" %>

<!DOCTYPE html>
<html>
<head runat="server">
<title>Create Quiz</title>
<link rel="stylesheet" href="StyleSheet.css" />
</head>

<body>
<form id="form1" runat="server">

<div class="main-container">

<div class="sidebar">
<div class="logo">QuizApp</div>
<div class="nav-item active">Create Quiz</div>
</div>

<div class="content-area">
<div class="card">

<h2>Create Quiz</h2>

<asp:DropDownList ID="ddlSubject" runat="server"></asp:DropDownList>

<asp:TextBox ID="txtTitle" runat="server"></asp:TextBox>
<asp:TextBox ID="txtTime" runat="server"></asp:TextBox>

<asp:CheckBoxList ID="cblQuestions" runat="server"></asp:CheckBoxList>

<asp:Button ID="btnCreate" runat="server" Text="Create Quiz" />

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

</form>
</body>
</html>

Teacher_CreateQuiz.aspx.vb

Imports System.Data.SqlClient
Imports System.Configuration

Partial Class Teacher_CreateQuiz
    Inherits System.Web.UI.Page

    Dim connStr As String = ConfigurationManager.ConnectionStrings("QuizDB").ConnectionString

    Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load

        If Session("UserID") Is Nothing OrElse Session("Role").ToString() <> "Teacher" Then
            Response.Redirect("Login.aspx")
        End If

        If Not IsPostBack Then
            LoadSubjects()
        End If

    End Sub

    Sub LoadSubjects()

        Using con As New SqlConnection(connStr)

            Dim cmd As New SqlCommand("SELECT SubjectID, SubjectName FROM Subjects", con)

            con.Open()

            ddlSubject.DataSource = cmd.ExecuteReader()
            ddlSubject.DataTextField = "SubjectName"
            ddlSubject.DataValueField = "SubjectID"
            ddlSubject.DataBind()

            ddlSubject.Items.Insert(0, New ListItem("-- Select Subject --", "0"))

        End Using

    End Sub

    Protected Sub ddlSubject_SelectedIndexChanged(sender As Object, e As EventArgs) Handles ddlSubject.SelectedIndexChanged

        Using con As New SqlConnection(connStr)

            Dim sql As String = "SELECT QuestionID, QuestionText FROM Questions WHERE SubjectID=@sid"

            Dim cmd As New SqlCommand(sql, con)
            cmd.Parameters.AddWithValue("@sid", ddlSubject.SelectedValue)

            con.Open()

            cblQuestions.DataSource = cmd.ExecuteReader()
            cblQuestions.DataTextField = "QuestionText"
            cblQuestions.DataValueField = "QuestionID"
            cblQuestions.DataBind()

        End Using

    End Sub

    Protected Sub btnCreate_Click(sender As Object, e As EventArgs)

        Dim quizId As Integer
        Dim selectedCount As Integer = 0

        For Each item As ListItem In cblQuestions.Items
            If item.Selected Then selectedCount += 1
        Next

        If selectedCount = 0 Then
            lblMsg.Text = "Please select at least one question."
            lblMsg.ForeColor = Drawing.Color.Red
            Return
        End If

        Using con As New SqlConnection(connStr)

            con.Open()

            Dim sqlQuiz As String =
                "INSERT INTO Quiz (SubjectID, TeacherID, Title, TotalQuestions, TotalTime, RandomizeQuestions, ShuffleOptions)
                 VALUES (@sid, @tid, @title, @totalQ, @time, 1, 1);
                 SELECT SCOPE_IDENTITY();"

            Dim cmd As New SqlCommand(sqlQuiz, con)

            cmd.Parameters.AddWithValue("@sid", ddlSubject.SelectedValue)
            cmd.Parameters.AddWithValue("@tid", Session("UserID"))
            cmd.Parameters.AddWithValue("@title", txtTitle.Text)
            cmd.Parameters.AddWithValue("@totalQ", selectedCount)
            cmd.Parameters.AddWithValue("@time", txtTime.Text)

            quizId = Convert.ToInt32(cmd.ExecuteScalar())

            Dim order As Integer = 1

            For Each item As ListItem In cblQuestions.Items

                If item.Selected Then

                    Dim sqlMapping As String =
                        "INSERT INTO QuizQuestions (QuizID, QuestionID, QuestionOrder)
                         VALUES (@qid, @qid2, @ord)"

                    Using qCmd As New SqlCommand(sqlMapping, con)

                        qCmd.Parameters.AddWithValue("@qid", quizId)
                        qCmd.Parameters.AddWithValue("@qid2", item.Value)
                        qCmd.Parameters.AddWithValue("@ord", order)

                        qCmd.ExecuteNonQuery()

                    End Using

                    order += 1

                End If

            Next

        End Using

        lblMsg.Text = "Quiz Created Successfully!"
        lblMsg.ForeColor = Drawing.Color.Green

    End Sub

End Class

TeacherDashboard.aspx

<%@ Page Language="VB" AutoEventWireup="true" CodeFile="TeacherDashboard.aspx.vb" Inherits="TeacherDashboard" %>

<!DOCTYPE html>
<html>
<head runat="server">
<title>Teacher Dashboard</title>
<link rel="stylesheet" href="StyleSheet.css" />
</head>

<body>
<form id="form1" runat="server">

<div class="main-container">

<div class="sidebar">
<div class="logo">QuizApp</div>
<div class="nav-item active">Dashboard</div>
</div>

<div class="content-area">
<div class="card">

<h1>Teacher Dashboard</h1>

<asp:Label ID="lblWelcome" runat="server"></asp:Label>

<asp:Button ID="btnAddQuestion" runat="server" Text="Add Questions" />
<asp:Button ID="btnCreateQuiz" runat="server" Text="Create Quiz" />
<asp:Button ID="btnLogout" runat="server" Text="Logout" />

</div>
</div>

</div>

</form>
</body>
</html>

TeacherDashboard.aspx.vb

Partial Class TeacherDashboard
    Inherits System.Web.UI.Page

    Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load

        If Session("Role") <> "Teacher" Then
            Response.Redirect("Login.aspx")
        End If

        If Not IsPostBack Then
            lblWelcome.Text = "Welcome Teacher ID: " & Session("UserID")
        End If

    End Sub

    Protected Sub btnAddQuestion_Click(sender As Object, e As EventArgs)
        Response.Redirect("Teacher_AddQuestions.aspx")
    End Sub

    Protected Sub btnCreateQuiz_Click(sender As Object, e As EventArgs)
        Response.Redirect("Teacher_CreateQuiz.aspx")
    End Sub

    Protected Sub btnLogout_Click(sender As Object, e As EventArgs)
        Session.Abandon()
        Response.Redirect("Login.aspx")
    End Sub

End Class

StyleSheet.css

body {
    margin: 0;
    padding: 0;
    font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
    background-color: #6a5acd;
    height: 100vh;
    display: flex;
    justify-content: center;
    align-items: center;
}

.main-container {
    display: flex;
    width: 95%;
    max-width: 1200px;
    height: 80vh;
    background-color: #f8f9fa;
    border-radius: 20px;
    overflow: hidden;
    box-shadow: 0 10px 30px rgba(0,0,0,0.2);
}

.sidebar {
    width: 250px;
    background-color: #ffffff;
    border-right: 1px solid #eee;
    padding: 40px 20px;
}

.logo {
    color: #6a5acd;
    font-size: 24px;
    margin-bottom: 40px;
}

.nav-item {
    padding: 12px 15px;
    margin-bottom: 10px;
    border-radius: 8px;
    color: #555;
    cursor: pointer;
}

.nav-item.active {
    background-color: #6a5acd;
    color: white;
}

.content-area {
    flex-grow: 1;
    padding: 40px;
    background-color: #f4f7fe;
    overflow-y: auto;
}

.card {
    background: white;
    padding: 30px;
    border-radius: 15px;
    border: 1px solid #e0e0e0;
}

h2 {
    margin-top: 0;
    color: #333;
}

.input-group {
    margin-bottom: 20px;
}

.input-group label {
    display: block;
    margin-bottom: 5px;
    font-weight: 600;
    color: #666;
}

.form-control {
    width: 100%;
    padding: 10px;
    border: 1px solid #ddd;
    border-radius: 8px;
    box-sizing: border-box;
}

.btn-primary {
    background-color: #6a5acd;
    color: white;
    border: none;
    padding: 12px 25px;
    border-radius: 8px;
    cursor: pointer;
    font-weight: bold;
    width: 100%;
}

.btn-primary:hover {
    background-color: #5a4db8;
}

.message {
    margin-top: 15px;
    color: #d9534f;
    font-size: 14px;
}

fieldset {
    border: 1px solid #ddd;
    border-radius: 8px;
    padding: 15px;
    margin-bottom: 20px;
}

legend {
    font-weight: bold;
    color: #6a5acd;
    padding: 0 10px;
}

.grid-view {
    width: 100%;
    border-collapse: collapse;
    background: white;
    border-radius: 8px;
    overflow: hidden;
}

.grid-view th {
    background-color: #6a5acd;
    color: white;
    padding: 10px;
    text-align: left;
}

.grid-view td {
    padding: 10px;
    border-bottom: 1px solid #eee;
    color: #333;
}

.grid-view tr:hover {
    background-color: #f1f1f1;
}