Improved leaderboard functionality and documentation
This commit is contained in:
parent
a611ab02ef
commit
caa177571b
@ -1,3 +1,4 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
@ -21,11 +22,11 @@
|
|||||||
</style>
|
</style>
|
||||||
<div class="markdown-heading"><h1 class="heading-element">Links</h1><a id="user-content-links" class="anchor" aria-label="Permalink: Links" href="#links"><span aria-hidden="true" class="octicon octicon-link"></span></a></div>
|
<div class="markdown-heading"><h1 class="heading-element">Links</h1><a id="user-content-links" class="anchor" aria-label="Permalink: Links" href="#links"><span aria-hidden="true" class="octicon octicon-link"></span></a></div>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="./create_user.html">Create User</a></li>
|
<li><a href="./create_user.html">POST <code>/api/Create_User</code></a></li>
|
||||||
<li><a href="./get_user_tests.html">Get User Tests</a></li>
|
<li><a href="./create_test.html">POST <code>/api/Post Test</code></a></li>
|
||||||
<li><a href="./leaderboard.html">Leaderboard</a></li>
|
<li><a href="./get_user_tests.html">GET <code>/api/Get_User_Tests</code></a></li>
|
||||||
<li><a href="./login.html">Login</a></li>
|
<li><a href="./leaderboard.html">GET <code>/api/Leaderboard</code></a></li>
|
||||||
<li><a href="./create_test.html">Post Test</a></li>
|
<li><a href="./login.html">GET <code>/api/Login</code></a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@ -1,7 +1,7 @@
|
|||||||
# Links
|
# Links
|
||||||
|
|
||||||
- [Create User](./create_user.md)
|
- [POST `/api/Create_User`](./create_user.md)
|
||||||
- [Get User Tests](./get_user_tests.md)
|
- [POST `/api/Post_Test`](./create_test.md)
|
||||||
- [Leaderboard](./leaderboard.md)
|
- [GET `/api/Get_User_Tests`](./get_user_tests.md)
|
||||||
- [Login](./login.md)
|
- [GET `/api/Leaderboard`](./leaderboard.md)
|
||||||
- [Post Test](./create_test.md)
|
- [GET `/api/Login`](./login.md)
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head>
|
<head>
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||||
@ -19,29 +20,48 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<div class="markdown-heading"><h1 class="heading-element">Leaderboard</h1><a id="user-content-leaderboard" class="anchor" aria-label="Permalink: Leaderboard" href="#leaderboard"><span aria-hidden="true" class="octicon octicon-link"></span></a></div>
|
<div class="markdown-heading"><h1 class="heading-element">Leaderboard API Endpoint</h1><a id="user-content-leaderboard-api-endpoint" class="anchor" aria-label="Permalink: Leaderboard API Endpoint" href="#leaderboard-api-endpoint"><span aria-hidden="true" class="octicon octicon-link"></span></a></div>
|
||||||
<p>This API endpoint retrieves the highest test data from each user and returns it as a JSON array.</p>
|
<div class="markdown-heading"><h2 class="heading-element">GET <code>/api/leaderboard</code>
|
||||||
<div class="markdown-heading"><h2 class="heading-element">Endpoint</h2><a id="user-content-endpoint" class="anchor" aria-label="Permalink: Endpoint" href="#endpoint"><span aria-hidden="true" class="octicon octicon-link"></span></a></div>
|
</h2><a id="user-content-get-apileaderboard" class="anchor" aria-label="Permalink: GET /api/leaderboard" href="#get-apileaderboard"><span aria-hidden="true" class="octicon octicon-link"></span></a></div>
|
||||||
<pre><code>GET /api/leaderboard
|
<p>Returns the highest test data from each user as a JSON array. The data includes metrics such as username, words per minute (WPM), accuracy percentage, the time taken for the test, and the length of the test for a comprehensive overview of user performance.</p>
|
||||||
</code></pre>
|
<div class="markdown-heading"><h2 class="heading-element">Responses</h2><a id="user-content-responses" class="anchor" aria-label="Permalink: Responses" href="#responses"><span aria-hidden="true" class="octicon octicon-link"></span></a></div>
|
||||||
<div class="markdown-heading"><h2 class="heading-element">Request Parameters</h2><a id="user-content-request-parameters" class="anchor" aria-label="Permalink: Request Parameters" href="#request-parameters"><span aria-hidden="true" class="octicon octicon-link"></span></a></div>
|
<ul>
|
||||||
<p>This endpoint does not require any request parameters.</p>
|
<li>
|
||||||
<div class="markdown-heading"><h2 class="heading-element">Example Request</h2><a id="user-content-example-request" class="anchor" aria-label="Permalink: Example Request" href="#example-request"><span aria-hidden="true" class="octicon octicon-link"></span></a></div>
|
<code>200 OK</code>: Successfully retrieves the leaderboard data.</li>
|
||||||
<div class="highlight highlight-source-shell"><pre>curl -X GET <span class="pl-s"><span class="pl-pds">"</span>https://example.com/api/leaderboard<span class="pl-pds">"</span></span></pre></div>
|
<li>
|
||||||
<div class="markdown-heading"><h2 class="heading-element">Response</h2><a id="user-content-response" class="anchor" aria-label="Permalink: Response" href="#response"><span aria-hidden="true" class="octicon octicon-link"></span></a></div>
|
<code>404 Not Found</code>: Indicates that the leaderboard was not found.</li>
|
||||||
|
<li>
|
||||||
|
<code>500 Internal Server Error</code>: Indicates an issue with accessing the database.</li>
|
||||||
|
</ul>
|
||||||
|
<div class="markdown-heading"><h2 class="heading-element">Example Response</h2><a id="user-content-example-response" class="anchor" aria-label="Permalink: Example Response" href="#example-response"><span aria-hidden="true" class="octicon octicon-link"></span></a></div>
|
||||||
<div class="highlight highlight-source-json"><pre>[
|
<div class="highlight highlight-source-json"><pre>[
|
||||||
{
|
{
|
||||||
<span class="pl-ent">"userName"</span>: <span class="pl-s"><span class="pl-pds">"</span>user_1<span class="pl-pds">"</span></span>,
|
<span class="pl-ent">"username"</span>: <span class="pl-s"><span class="pl-pds">"</span>user1<span class="pl-pds">"</span></span>,
|
||||||
<span class="pl-ent">"wpm"</span>: <span class="pl-c1">85</span>,
|
<span class="pl-ent">"wpm"</span>: <span class="pl-c1">75</span>,
|
||||||
|
<span class="pl-ent">"accuracy"</span>: <span class="pl-c1">97</span>,
|
||||||
|
<span class="pl-ent">"test_time"</span>: <span class="pl-c1">120</span>,
|
||||||
|
<span class="pl-ent">"test_length"</span>: <span class="pl-c1">250</span>
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
<span class="pl-ent">"userName"</span>: <span class="pl-s"><span class="pl-pds">"</span>user_2<span class="pl-pds">"</span></span>,
|
<span class="pl-ent">"username"</span>: <span class="pl-s"><span class="pl-pds">"</span>user2<span class="pl-pds">"</span></span>,
|
||||||
<span class="pl-ent">"score"</span>: <span class="pl-c1">80</span>,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
<span class="pl-ent">"userName"</span>: <span class="pl-s"><span class="pl-pds">"</span>user_3<span class="pl-pds">"</span></span>,
|
|
||||||
<span class="pl-ent">"wpm"</span>: <span class="pl-c1">73</span>,
|
<span class="pl-ent">"wpm"</span>: <span class="pl-c1">73</span>,
|
||||||
|
<span class="pl-ent">"accuracy"</span>: <span class="pl-c1">95</span>,
|
||||||
|
<span class="pl-ent">"test_time"</span>: <span class="pl-c1">115</span>,
|
||||||
|
<span class="pl-ent">"test_length"</span>: <span class="pl-c1">240</span>
|
||||||
}
|
}
|
||||||
]</pre></div>
|
]</pre></div>
|
||||||
|
<div class="markdown-heading"><h2 class="heading-element">Fields</h2><a id="user-content-fields" class="anchor" aria-label="Permalink: Fields" href="#fields"><span aria-hidden="true" class="octicon octicon-link"></span></a></div>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<code>username</code>: The name of the user.</li>
|
||||||
|
<li>
|
||||||
|
<code>wpm</code>: Words per minute, indicating the typing speed.</li>
|
||||||
|
<li>
|
||||||
|
<code>accuracy</code>: The accuracy of the user's typing, in percentage.</li>
|
||||||
|
<li>
|
||||||
|
<code>test_time</code>: The total time taken to complete the test, in seconds.</li>
|
||||||
|
<li>
|
||||||
|
<code>test_length</code>: The length of the test, typically measured in number of words.</li>
|
||||||
|
</ul>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
@ -1,38 +1,40 @@
|
|||||||
# Leaderboard
|
# Leaderboard API Endpoint
|
||||||
|
|
||||||
This API endpoint retrieves the highest test data from each user and returns it as a JSON array.
|
## GET `/api/leaderboard`
|
||||||
|
|
||||||
## Endpoint
|
Returns the highest test data from each user as a JSON array. The data includes metrics such as username, words per minute (WPM), accuracy percentage, the time taken for the test, and the length of the test for a comprehensive overview of user performance.
|
||||||
|
|
||||||
```
|
## Responses
|
||||||
GET /api/leaderboard
|
|
||||||
```
|
|
||||||
|
|
||||||
## Request Parameters
|
- `200 OK`: Successfully retrieves the leaderboard data.
|
||||||
|
- `404 Not Found`: Indicates that the leaderboard was not found.
|
||||||
|
- `500 Internal Server Error`: Indicates an issue with accessing the database.
|
||||||
|
|
||||||
This endpoint does not require any request parameters.
|
## Example Response
|
||||||
|
|
||||||
## Example Request
|
|
||||||
|
|
||||||
```bash
|
|
||||||
curl -X GET "https://example.com/api/leaderboard"
|
|
||||||
```
|
|
||||||
|
|
||||||
## Response
|
|
||||||
|
|
||||||
```json
|
```json
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
"userName": "user_1",
|
"username": "user1",
|
||||||
"wpm": 85,
|
"wpm": 75,
|
||||||
|
"accuracy": 97,
|
||||||
|
"test_time": 120,
|
||||||
|
"test_length": 250
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"userName": "user_2",
|
"username": "user2",
|
||||||
"score": 80,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"userName": "user_3",
|
|
||||||
"wpm": 73,
|
"wpm": 73,
|
||||||
|
"accuracy": 95,
|
||||||
|
"test_time": 115,
|
||||||
|
"test_length": 240
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Fields
|
||||||
|
|
||||||
|
- `username`: The name of the user.
|
||||||
|
- `wpm`: Words per minute, indicating the typing speed.
|
||||||
|
- `accuracy`: The accuracy of the user's typing, in percentage.
|
||||||
|
- `test_time`: The total time taken to complete the test, in seconds.
|
||||||
|
- `test_length`: The length of the test, typically measured in number of words.
|
30
public/leaderboard/index.html
Normal file
30
public/leaderboard/index.html
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
|
<title>Leaderboard</title>
|
||||||
|
<link rel="stylesheet" href="styles.css">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<H1>Leaderboard</H1>
|
||||||
|
<button class="refresh-button" onclick="fetchLeaderboard()">⟳</button>
|
||||||
|
<table id="leaderboardTable">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Username</th>
|
||||||
|
<th>WPM</th>
|
||||||
|
<th>Accuracy (%)</th>
|
||||||
|
<th>Test Time (s)</th>
|
||||||
|
<th>Test Length (characters)</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<!-- Rows will be filled by JavaScript -->
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
|
||||||
|
<script src="script.js"></script>
|
||||||
|
</body>
|
||||||
|
</html>
|
22
public/leaderboard/script.js
Normal file
22
public/leaderboard/script.js
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
async function fetchLeaderboardData() {
|
||||||
|
const response = await fetch('/api/leaderboard');
|
||||||
|
if (!response.ok) {
|
||||||
|
console.error('Failed to fetch leaderboard data');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const data = await response.json();
|
||||||
|
const tableBody = document.getElementById('leaderboardTable').getElementsByTagName('tbody')[0];
|
||||||
|
tableBody.innerHTML = ''; // Clear existing rows
|
||||||
|
data.forEach(item => {
|
||||||
|
const row = tableBody.insertRow();
|
||||||
|
row.insertCell(0).innerText = item.username;
|
||||||
|
row.insertCell(1).innerText = item.wpm;
|
||||||
|
row.insertCell(2).innerText = item.accuracy;
|
||||||
|
row.insertCell(3).innerText = item.test_time;
|
||||||
|
row.insertCell(4).innerText = item.test_length;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure this function is called on page load and when the refresh button is clicked.
|
||||||
|
document.addEventListener('DOMContentLoaded', fetchLeaderboardData);
|
||||||
|
document.getElementById('refreshButton').addEventListener('click', fetchLeaderboardData);
|
56
public/leaderboard/styles.css
Normal file
56
public/leaderboard/styles.css
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
flex-direction: column;
|
||||||
|
align-items: center;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
table {
|
||||||
|
width: 60%;
|
||||||
|
border-collapse: collapse;
|
||||||
|
margin-top: 20px;
|
||||||
|
}
|
||||||
|
th, td {
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
text-align: left;
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
th {
|
||||||
|
background-color: #f2f2f2;
|
||||||
|
}
|
||||||
|
tr:nth-child(even) {
|
||||||
|
background-color: #f9f9f9;
|
||||||
|
}
|
||||||
|
.refresh-button {
|
||||||
|
cursor: pointer;
|
||||||
|
border: none;
|
||||||
|
background-color: transparent;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
color: #4CAF50;
|
||||||
|
}
|
||||||
|
|
||||||
|
.refresh-button:hover {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Dark Mode styles */
|
||||||
|
@media (prefers-color-scheme: dark) {
|
||||||
|
body {
|
||||||
|
background-color: #121212;
|
||||||
|
color: #e0e0e0;
|
||||||
|
}
|
||||||
|
table {
|
||||||
|
border-color: #424242;
|
||||||
|
}
|
||||||
|
th {
|
||||||
|
background-color: #333;
|
||||||
|
}
|
||||||
|
tr:nth-child(even) {
|
||||||
|
background-color: #2a2a2a;
|
||||||
|
}
|
||||||
|
.refresh-icon {
|
||||||
|
fill: #90caf9;
|
||||||
|
}
|
||||||
|
}
|
@ -183,7 +183,7 @@ impl Database {
|
|||||||
_user_id: u32,
|
_user_id: u32,
|
||||||
) -> Result<Vec<LeaderBoardTest>, sqlx::Error> {
|
) -> Result<Vec<LeaderBoardTest>, sqlx::Error> {
|
||||||
let tests = sqlx::query!(
|
let tests = sqlx::query!(
|
||||||
"SELECT users.username, tests.wpm
|
"SELECT users.username, tests.wpm, tests.accuracy, tests.test_time, tests.test_length
|
||||||
FROM tests
|
FROM tests
|
||||||
INNER JOIN users ON users.user_id = tests.user_id
|
INNER JOIN users ON users.user_id = tests.user_id
|
||||||
GROUP BY users.username
|
GROUP BY users.username
|
||||||
@ -197,6 +197,9 @@ impl Database {
|
|||||||
.map(|test| LeaderBoardTest {
|
.map(|test| LeaderBoardTest {
|
||||||
username: test.username.clone(),
|
username: test.username.clone(),
|
||||||
wpm: test.wpm.unwrap() as u8,
|
wpm: test.wpm.unwrap() as u8,
|
||||||
|
accuracy: test.accuracy.unwrap() as u8,
|
||||||
|
test_time: test.test_time.unwrap() as u32,
|
||||||
|
test_length: test.test_length.unwrap() as u32
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
@ -262,11 +265,21 @@ pub struct Test {
|
|||||||
accuracy: u8,
|
accuracy: u8,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// struct that represents all the data that gets sent to the user
|
/// Represents leaderboard data sent to the user upon request.
|
||||||
/// when they make a leaderboard request
|
/// This data includes username, words per minute (WPM), accuracy percentage,
|
||||||
|
/// the time taken for the test, and the length of the test.
|
||||||
|
///
|
||||||
|
/// - `username`: The name of the user.
|
||||||
|
/// - `wpm`: Words per minute, indicating the typing speed of the user.
|
||||||
|
/// - `accuracy`: The accuracy of the user's typing, in percentage.
|
||||||
|
/// - `test_time`: The total time taken to complete the test, in seconds.
|
||||||
|
/// - `test_length`: The length of the test, typically measured in number of words.
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
#[serde(crate = "rocket::serde")]
|
#[serde(crate = "rocket::serde")]
|
||||||
pub struct LeaderBoardTest {
|
pub struct LeaderBoardTest {
|
||||||
username: String,
|
username: String,
|
||||||
wpm: u8,
|
wpm: u8,
|
||||||
|
accuracy: u8,
|
||||||
|
test_time: u32,
|
||||||
|
test_length: u32,
|
||||||
}
|
}
|
||||||
|
25
src/cors.rs
Normal file
25
src/cors.rs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
use rocket::fairing::{Fairing, Info, Kind};
|
||||||
|
use rocket::http::Header;
|
||||||
|
use rocket::{Request, Response};
|
||||||
|
|
||||||
|
pub struct CORS;
|
||||||
|
|
||||||
|
#[rocket::async_trait]
|
||||||
|
impl Fairing for CORS {
|
||||||
|
fn info(&self) -> Info {
|
||||||
|
Info {
|
||||||
|
name: "Add CORS headers to responses",
|
||||||
|
kind: Kind::Response,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fn on_response<'r>(&self, _request: &'r Request<'_>, response: &mut Response<'r>) {
|
||||||
|
response.set_header(Header::new("Access-Control-Allow-Origin", "*"));
|
||||||
|
response.set_header(Header::new(
|
||||||
|
"Access-Control-Allow-Methods",
|
||||||
|
"GET"
|
||||||
|
));
|
||||||
|
response.set_header(Header::new("Access-Control-Allow-Headers", "*"));
|
||||||
|
response.set_header(Header::new("Access-Control-Allow-Credentials", "true"));
|
||||||
|
}
|
||||||
|
}
|
61
src/main.rs
61
src/main.rs
@ -6,38 +6,16 @@
|
|||||||
//! - move structures into a different file
|
//! - move structures into a different file
|
||||||
//! - find a way to make logging in more secure (password hashes?)
|
//! - find a way to make logging in more secure (password hashes?)
|
||||||
|
|
||||||
// use rocket::fairing::{Fairing, Info, Kind};
|
mod cors;
|
||||||
// use rocket::http::Header;
|
use crate::cors::CORS;
|
||||||
// use rocket::{Request, Response};
|
|
||||||
|
|
||||||
// pub struct CORS;
|
|
||||||
|
|
||||||
// #[rocket::async_trait]
|
|
||||||
// impl Fairing for CORS {
|
|
||||||
// fn info(&self) -> Info {
|
|
||||||
// Info {
|
|
||||||
// name: "Add CORS headers to responses",
|
|
||||||
// kind: Kind::Response,
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// async fn on_response<'r>(&self, _request: &'r Request<'_>, response: &mut Response<'r>) {
|
|
||||||
// response.set_header(Header::new("Access-Control-Allow-Origin", "*"));
|
|
||||||
// response.set_header(Header::new(
|
|
||||||
// "Access-Control-Allow-Methods",
|
|
||||||
// "POST, GET, PATCH, OPTIONS",
|
|
||||||
// ));
|
|
||||||
// response.set_header(Header::new("Access-Control-Allow-Headers", "*"));
|
|
||||||
// response.set_header(Header::new("Access-Control-Allow-Credentials", "true"));
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// Imports for rocket
|
// Imports for rocket
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate rocket;
|
extern crate rocket;
|
||||||
use rocket::{
|
use rocket::{
|
||||||
fs::{relative, FileServer},
|
fs::{relative, FileServer},
|
||||||
Build, Rocket,
|
response::Redirect,
|
||||||
|
Build, Rocket
|
||||||
};
|
};
|
||||||
|
|
||||||
mod api;
|
mod api;
|
||||||
@ -61,34 +39,43 @@ fn test() -> &'static str {
|
|||||||
"Hello World! I'm A rocket Webserver"
|
"Hello World! I'm A rocket Webserver"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[get("/")]
|
||||||
|
async fn typing_redirect() -> Redirect {
|
||||||
|
Redirect::to(uri!("/typing/index.html"))
|
||||||
|
}
|
||||||
|
|
||||||
/// The main function which builds and launches the
|
/// The main function which builds and launches the
|
||||||
/// webserver with all appropriate routes and fileservers
|
/// webserver with all appropriate routes and fileservers
|
||||||
#[launch]
|
#[launch]
|
||||||
async fn rocket() -> Rocket<Build> {
|
async fn rocket() -> Rocket<Build> {
|
||||||
rocket::build()
|
rocket::build()
|
||||||
// .attach(CORS)
|
// Allow external to any get API methods
|
||||||
// testing only, should return "Hello world"
|
.attach(CORS)
|
||||||
.mount("/test", routes![test])
|
|
||||||
// hosts the api routes necessary for the website
|
// hosts the api routes necessary for the website
|
||||||
// to interact with the database
|
// to interact with the database
|
||||||
.mount("/api/documentation", FileServer::from(relative!("documentation")))
|
.mount("/api/documentation", FileServer::from(relative!("documentation")))
|
||||||
.register("/api/documentation", catchers![documentation_not_found])
|
.register("/api/documentation", catchers![documentation_not_found])
|
||||||
.mount(
|
.mount("/api",routes![
|
||||||
"/api",
|
|
||||||
routes![
|
|
||||||
sign_up,
|
sign_up,
|
||||||
create_test,
|
|
||||||
login,
|
login,
|
||||||
get_tests,
|
|
||||||
leaderboard,
|
|
||||||
new_test,
|
new_test,
|
||||||
],
|
create_test,
|
||||||
)
|
get_tests,
|
||||||
|
leaderboard
|
||||||
|
])
|
||||||
.register("/api", catchers![api_not_found])
|
.register("/api", catchers![api_not_found])
|
||||||
|
|
||||||
|
|
||||||
// hosts the fileserver
|
// hosts the fileserver
|
||||||
|
.mount("/typing", routes![typing_redirect])
|
||||||
.mount("/typing", FileServer::from(relative!("public")))
|
.mount("/typing", FileServer::from(relative!("public")))
|
||||||
.register("/typing", catchers![frontend_not_found])
|
.register("/typing", catchers![frontend_not_found])
|
||||||
|
// The state which allows routes to access the database
|
||||||
.manage(Database::new().await.unwrap())
|
.manage(Database::new().await.unwrap())
|
||||||
|
|
||||||
|
|
||||||
|
// testing only, should return "Hello world"
|
||||||
|
.mount("/test", routes![test])
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user