Skip to the content.

Integration Planning

My Feature

Get Student Details Feature

It takes the student’s name and returns all their Github details, allowing Mr. Mortenson and others to quickly and seamlessly check the analytics of specific students.

Backend Work

  • Gets the details, which contain the GitHub username, of one specific student
@RestController
@RequestMapping("/api/students")
public class StudentApiController {
    @Getter
    public static class CriteriaDto {
        private String name;
        private String course;
        private int trimester;
        private int period; 
    }

    @PostMapping("/find")
    public ResponseEntity<Student> getStudentByCriteria(
            @RequestBody CriteriaDto criteriaDto) {
        
        List<Student> students = studentJPARepository.findByNameCourseTrimesterPeriod(criteriaDto.getName(), criteriaDto.getCourse(), criteriaDto.getTrimester(), criteriaDto.getPeriod());
        
        if (students.isEmpty()) {
            return ResponseEntity.notFound().build();
        } else {
            return ResponseEntity.ok(students.get(0));
        }
    }
}
  • JPA that connects to SQL database to person query
    public interface StudentJPARepository extends JpaRepository<Student, Long> {
      @Query(
          value = "SELECT * FROM students WHERE name = :name AND course = :course AND trimester = :trimester AND period = :period",
          nativeQuery = true
      )
      List<Student> findByNameCourseTrimesterPeriod(
          @Param("name") String name, 
          @Param("course") String course, 
          @Param("trimester") int trimester, 
          @Param("period") int period
      );
    }
    

Frontend Work

  • One section in the homepage page contains input box
<body>
  <!-- Search Bar -->
  <div class="search-container">
    <input type="text" id="searchName" placeholder="Enter student name">
    <button onclick="searchStudent()">Search</button>
  </div>
<script>
    function searchStudent() {
      const name = document.getElementById("searchName").value;

      const criteriaDto = {
        name: name,
        course: "CSA",
        trimester: 1,
        period: 3
      };

      fetch("http://localhost:8181/api/students/find", {
        method: "POST",
        headers: {
          "Content-Type": "application/json"
        },
        body: JSON.stringify(criteriaDto)
      })
      .then(response => {
        if (!response.ok) {
          throw new Error("Network response was not ok");
        }
        return response.json();
      })
      .then(data => {
        const params = new URLSearchParams({
          name: data.name,
          course: data.course,
          trimester: data.trimester,
          period: data.period
        });
        window.location.href = "/student_2025/student-info?" + params.toString();
      })
      .catch(error => {
        console.error("There was a problem with the fetch operation:", error);
        alert("Student not found.");
      });
    }
  </script>
</body>
  • Page to display student details
<body>

<div id="details-container">
  <img id="profile-pic" src="" alt="Profile Picture">
  <div class="details-content">
    <p><strong>Username:</strong> <span id="githubUsername"></span></p>
    <p><strong>Profile URL:</strong> <a id="githubProfile" href="" target="_blank"></a></p>
    <p><strong>Issues:</strong> <span id="githubIssues"></span></p>
    <p><strong>Pull Requests:</strong> <span id="githubPulls"></span></p>
    <p><strong>Commits:</strong> <span id="githubCommits"></span></p>
    <p><strong>Public Repos:</strong> <span id="githubRepos"></span></p>
    <p><strong>Public Gists:</strong> <span id="githubGists"></span></p>
    <p><strong>Followers:</strong> <span id="githubFollowers"></span></p>
  </div>
</div>

<script>
  async function fetchStudentDetails() {
    const urlParams = new URLSearchParams(window.location.search);
    const name = urlParams.get("name");
    const course = urlParams.get("course");
    const trimester = urlParams.get("trimester");
    const period = urlParams.get("period");

    const criteriaDto = {
      name: name,
      course: course,
      trimester: parseInt(trimester),
      period: parseInt(period)
    };

    try {
      // Fetch student data from your backend
      const studentResponse = await fetch("http://localhost:8181/api/students/find", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify(criteriaDto)
      });

      if (!studentResponse.ok) throw new Error("Student not found");

      const student = await studentResponse.json();
      const githubUsername = student.username;

      // Fetch GitHub user profile
      const githubResponse = await fetch(`https://api.github.com/users/${githubUsername}`);
      if (!githubResponse.ok) throw new Error("GitHub profile not found");
      const githubData = await githubResponse.json();

      // Fetch GitHub user events for issues, PRs, and commits data
      const eventsResponse = await fetch(`https://api.github.com/users/${githubUsername}/events`);
      if (!eventsResponse.ok) throw new Error("GitHub events not found");
      const eventsData = await eventsResponse.json();

      // Define the start date for filtering events
      const startDate = new Date("2024-08-01T00:00:00Z");

      // Count events occurring after the start date
      const commitsCount = eventsData.filter(event => 
        event.type === "PushEvent" && new Date(event.created_at) >= startDate
      ).length;

      const prsCount = eventsData.filter(event => 
        event.type === "PullRequestEvent" && new Date(event.created_at) >= startDate
      ).length;

      const issuesCount = eventsData.filter(event => 
        event.type === "IssuesEvent" && new Date(event.created_at) >= startDate
      ).length;

      // Populate the details on the page
      document.getElementById("profile-pic").src = githubData.avatar_url;
      document.getElementById("githubUsername").innerText = githubData.login;
      document.getElementById("githubProfile").href = githubData.html_url;
      document.getElementById("githubProfile").innerText = githubData.html_url;
      document.getElementById("githubRepos").innerText = githubData.public_repos;
      document.getElementById("githubGists").innerText = githubData.public_gists;
      document.getElementById("githubFollowers").innerText = githubData.followers;

      // Display the filtered event data
      document.getElementById("githubIssues").innerText = issuesCount;
      document.getElementById("githubPulls").innerText = prsCount;
      document.getElementById("githubCommits").innerText = commitsCount;

    } catch (error) {
      console.error("Error:", error);
      alert(error.message);
    }
  }

  window.onload = fetchStudentDetails;
</script>

</body>

UML Design

Field Name Data Type Description
id Long Unique identifier for each student.
name String Full name of the student.
username String Unique username for the student.
tableNumber int Assigned table number in the classroom.
course String The course the student is enrolled in (e.g., CSSE, CSP, CSA).
tasks ArrayList<String> List of tasks or assignments assigned to the student.
trimester int Trimester during which the student is enrolled.
period int Class period for the student.

What needs to be done

I have files both in the frontend and in the backend. I must first combine this all with my teammates’ code into a combined backend and frontend. I then must put all this code onto our branch of the CSA-Coders-2025 backend and frontend. From there, I can then make a pull request to be accepted onto the main CSA 2025 repository. Regarding my collaboration with other teams, specifically CSA Synergy and AI grader, we must make a feature to assign grades to a table. We must also use Person class rather than hardcoding students and only retrieve students using the role ROLE_STUDENT.

Image