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
.