From 3ac68b8b59f150e08731a62026ce3ac825655614 Mon Sep 17 00:00:00 2001 From: Daniel Hader Date: Thu, 4 Jun 2026 18:29:34 -0500 Subject: viewing submissions logic --- src/database/database.rs | 23 +++++++++++++++++++++++ src/main.rs | 5 +++-- src/routes/submission.rs | 11 +++++++++++ static/default.css | 4 ++++ static/main.js | 5 +++-- static/submission.html | 40 ++++++++++++++++++++++++++++++++++++++++ static/submission.js | 35 +++++++++++++++++++++++++++++++++++ static/submit.html | 3 ++- 8 files changed, 121 insertions(+), 5 deletions(-) create mode 100644 static/submission.html create mode 100644 static/submission.js diff --git a/src/database/database.rs b/src/database/database.rs index 961c39c..95c8bf6 100644 --- a/src/database/database.rs +++ b/src/database/database.rs @@ -244,6 +244,29 @@ impl Database { .map_err(|e| DatabaseError::Query(e.to_string()))? ) } + + pub fn fetch_display_submission(&self, submission_id: i64) -> Result, DatabaseError> { + static QUERY: &str = include_str!("sql/fetch_display_submissions.sql"); + let conn = self.pool + .get() + .map_err(|e| DatabaseError::Connection(e.to_string()))?; + let mut statement = conn.prepare(QUERY) + .map_err(|e| DatabaseError::Query(e.to_string()))?; + + Ok(statement + .query_one([submission_id], |row| { + Ok(DisplaySubmission { + id: row.get("id")?, + username: row.get("username")?, + language: row.get("language")?, + details: row.get("details")?, + code: row.get("code")?, + }) + }) + .optional() + .map_err(|e| DatabaseError::Query(e.to_string()))? + ) + } pub fn initialize(&self) -> Result<(), DatabaseError> { static QUERY: &str = include_str!("sql/initialize.sql"); diff --git a/src/main.rs b/src/main.rs index 9659af3..afa9821 100644 --- a/src/main.rs +++ b/src/main.rs @@ -14,7 +14,7 @@ use routes::user::{create_user, me}; use routes::auth::{login, logout}; use tower_http::services::ServeDir; -use crate::{database::Database, routes::submission::{create_submission, get_display_submissions, get_submissions_by_problem_id}, utils::register_admin}; +use crate::{database::Database, routes::submission::{create_submission, get_display_submission, get_display_submissions, get_submissions_by_problem_id}, utils::register_admin}; #[derive(Clone)] struct AppState { @@ -62,10 +62,11 @@ async fn main() { .route("/login", post(login)) .route("/logout", post(logout)) .route("/problem/{problem_id}", get(get_problem)) + .route("/problem/{problem_id}/submission", get(get_display_submissions)) .route("/problem", get(get_problems)) .route("/problem", post(create_problem)) .route("/submission", post(create_submission)) - .route("/submission/{problem_id}", get(get_display_submissions)) + .route("/submission/{submission_id}", get(get_display_submission)) .route("/user", post(create_user)) .route("/me", get(me)) .nest_service("/static", static_files) diff --git a/src/routes/submission.rs b/src/routes/submission.rs index 4cfad5c..b3cf2b9 100644 --- a/src/routes/submission.rs +++ b/src/routes/submission.rs @@ -48,3 +48,14 @@ pub async fn get_display_submissions( Ok(Json(submissions)) } +pub async fn get_display_submission( + State(state): State, + Path(submission_id): Path +) -> Result { + match state.database.fetch_display_submission(submission_id) { + Ok(None) => Err(RouteError::NotFound("submission".into())), + Ok(Some(submission)) => Ok(Json(submission)), + Err(e) => Err(RouteError::Internal(format!("unable to fetch submission: {e:?}"))) + } +} + diff --git a/static/default.css b/static/default.css index 8f24f39..b137fca 100644 --- a/static/default.css +++ b/static/default.css @@ -26,6 +26,10 @@ h3 { margin-bottom: 2px; } +code { + border: 1px solid black; +} + #container { width: 640px; margin: auto; diff --git a/static/main.js b/static/main.js index b070ccb..b3bf50f 100644 --- a/static/main.js +++ b/static/main.js @@ -88,7 +88,8 @@ function create_problem_element(problem, submissions) { const sub_subm = document.createElement("td"); const sub_anch = document.createElement("a"); - sub_anch.href = "submission.html?id=5"; + + sub_anch.href = `submission.html?problem_id=${problem.id}&submission_id=${submission.id}`; sub_anch.innerText = "view submission"; sub_subm.appendChild(sub_anch); sub_row.appendChild(sub_subm); @@ -99,7 +100,7 @@ function create_problem_element(problem, submissions) { } async function fetch_submissions(problem_id) { - const response = await fetch(`/submission/${problem_id}`) + const response = await fetch(`/problem/${problem_id}/submission`) const result = await response.json(); return result; } diff --git a/static/submission.html b/static/submission.html new file mode 100644 index 0000000..0789c12 --- /dev/null +++ b/static/submission.html @@ -0,0 +1,40 @@ + + + + + + Code Golf Login + + + + + + + + + + +
+
+
+ Home +

C&! Code Golf Leaderboard

+
+ +

Submission

+
+

+

+

+

Additional Details

+

+
+
© 2026 Daniel Hader
+
+
+
+ + diff --git a/static/submission.js b/static/submission.js new file mode 100644 index 0000000..bbe4075 --- /dev/null +++ b/static/submission.js @@ -0,0 +1,35 @@ +async function get_problem() { + const url_params = new URLSearchParams(window.location.search); + const problem_id = parseInt(url_params.get("problem_id")); + const response = await fetch(`/problem/${problem_id}`) + return await response.json(); +} + +async function get_submission() { + const url_params = new URLSearchParams(window.location.search); + const submission_id = parseInt(url_params.get("submission_id")); + const response = await fetch(`/submission/${submission_id}`) + return await response.json(); +} + +async function init() { + const problem = await get_problem(); + const submission = await get_submission(); + + const problem_div = document.getElementById("submission-problem"); + + const title = document.createElement("h2"); + title.innerHTML = `Problem: ${problem.title}`; + problem_div.appendChild(title); + + const description = document.createElement("p"); + description.innerHTML = problem.description; + problem_div.appendChild(description); + + document.getElementById("submission-author").innerHTML = `by ${submission.username}`; + document.getElementById("submission-size").innerHTML = `${new Blob([submission.code]).size} bytes`; + document.getElementById("submission-details").innerHTML = submission.details; + document.getElementById("submission-code").innerHTML = submission.code; + + hljs.highlightAll(); +} diff --git a/static/submit.html b/static/submit.html index 151fba5..43a1dbf 100644 --- a/static/submit.html +++ b/static/submit.html @@ -25,7 +25,8 @@