✨ Adds fetching hits
This commit is contained in:
@@ -1,8 +1,9 @@
|
|||||||
use crate::auth::Authenticated;
|
use crate::auth::Authenticated;
|
||||||
|
use crate::dtos::hit::HitDTO;
|
||||||
use crate::dtos::tracker::{NewTrackerDTO, TrackerDTO};
|
use crate::dtos::tracker::{NewTrackerDTO, TrackerDTO};
|
||||||
use crate::models::AppState;
|
use crate::models::AppState;
|
||||||
use crate::models::tracker::Tracker;
|
use crate::models::tracker::Tracker;
|
||||||
use crate::schema::hits::dsl as hits;
|
use crate::schema::hits;
|
||||||
use crate::schema::trackers;
|
use crate::schema::trackers;
|
||||||
use crate::schema::trackers::dsl;
|
use crate::schema::trackers::dsl;
|
||||||
use chrono::Utc;
|
use chrono::Utc;
|
||||||
@@ -61,6 +62,30 @@ pub fn get(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[get("/<id>/hits")]
|
||||||
|
pub fn get_hits(
|
||||||
|
id: &str,
|
||||||
|
_auth: Authenticated,
|
||||||
|
state: &State<AppState>,
|
||||||
|
) -> Result<Json<Vec<HitDTO>>, Status> {
|
||||||
|
let mut db = state.db.lock().unwrap();
|
||||||
|
|
||||||
|
let id = match Uuid::parse_str(id).ok() {
|
||||||
|
Some(id) => id,
|
||||||
|
None => return Err(Status::BadRequest),
|
||||||
|
};
|
||||||
|
|
||||||
|
let result = hits::dsl::hits
|
||||||
|
.filter(hits::tracker_id.eq(id))
|
||||||
|
.load(&mut *db)
|
||||||
|
.ok();
|
||||||
|
|
||||||
|
match result {
|
||||||
|
Some(results) => Ok(Json(results.iter().map(HitDTO::from).collect())),
|
||||||
|
None => Err(Status::NotFound),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[post("/", format = "json", data = "<data>")]
|
#[post("/", format = "json", data = "<data>")]
|
||||||
pub fn create(
|
pub fn create(
|
||||||
data: Json<NewTrackerDTO>,
|
data: Json<NewTrackerDTO>,
|
||||||
@@ -108,7 +133,7 @@ pub fn delete(
|
|||||||
|
|
||||||
if delete_hits {
|
if delete_hits {
|
||||||
let hit_count =
|
let hit_count =
|
||||||
diesel::delete(hits::hits.filter(hits::tracker_id.eq(id))).execute(&mut *db);
|
diesel::delete(hits::dsl::hits.filter(hits::tracker_id.eq(id))).execute(&mut *db);
|
||||||
if let Err(err) = hit_count {
|
if let Err(err) = hit_count {
|
||||||
error!("Failed to delete associated hits: {}", err)
|
error!("Failed to delete associated hits: {}", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ fn rocket() -> _ {
|
|||||||
routes![
|
routes![
|
||||||
tracker::index,
|
tracker::index,
|
||||||
tracker::get,
|
tracker::get,
|
||||||
|
tracker::get_hits,
|
||||||
tracker::create,
|
tracker::create,
|
||||||
tracker::delete
|
tracker::delete
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -118,11 +118,44 @@
|
|||||||
width: 15rem;
|
width: 15rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
#tracker-table td, #tracker-table th {
|
#tracker-table td:nth-child(4) {
|
||||||
|
width: 10rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#tracker-table td, #tracker-table th, #hit-table td, #hit-table th {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0.2rem 0;
|
||||||
border-bottom: 1px solid black;
|
border-bottom: 1px solid black;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#hit-title {
|
||||||
|
font-size: 1.15rem;
|
||||||
|
width: 100%;
|
||||||
|
margin-top: 2rem;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#hit-table {
|
||||||
|
width: 100%;
|
||||||
|
overflow: auto;
|
||||||
|
font-size: 1.10rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#hit-table th:nth-child(1) {
|
||||||
|
width: 20rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#hit-table th:nth-child(2) {
|
||||||
|
width: 10rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#hit-table th:nth-child(4) {
|
||||||
|
width: 8rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#hit-table th:nth-child(5) {
|
||||||
|
width: 15rem;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@@ -141,7 +174,18 @@
|
|||||||
<th>ID</th>
|
<th>ID</th>
|
||||||
<th>Name</th>
|
<th>Name</th>
|
||||||
<th>Created at</th>
|
<th>Created at</th>
|
||||||
<th>Hits</th>
|
<th></th>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<p id="hit-title">No tracker selected</p>
|
||||||
|
<table id="hit-table">
|
||||||
|
<tr>
|
||||||
|
<th>ID</th>
|
||||||
|
<th>IP</th>
|
||||||
|
<th>Agent</th>
|
||||||
|
<th>Language</th>
|
||||||
|
<th>Created at</th>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
|
||||||
@@ -184,21 +228,68 @@
|
|||||||
}
|
}
|
||||||
}).then((res) => {
|
}).then((res) => {
|
||||||
res.json().then((trackers) => {
|
res.json().then((trackers) => {
|
||||||
console.log(trackers);
|
|
||||||
trackers.forEach((tracker) => {
|
trackers.forEach((tracker) => {
|
||||||
document.getElementById("tracker-table").innerHTML += `
|
document.getElementById("tracker-table").innerHTML += `
|
||||||
<tr>
|
<tr>
|
||||||
<td>${tracker.id}</td>
|
<td>${tracker.id}</td>
|
||||||
<td>${tracker.name}</td>
|
<td>${tracker.name}</td>
|
||||||
<td>${tracker.created_at}</td>
|
<td>${tracker.created_at}</td>
|
||||||
<td>${tracker.hits}</td>
|
<td>
|
||||||
</tr>
|
<button onclick="loadTrigger('${tracker.id}')">
|
||||||
`;
|
Show more
|
||||||
})
|
</button>
|
||||||
|
|
||||||
|
<button onclick="copyLink('${tracker.id}')">
|
||||||
|
Copy link
|
||||||
|
</button>
|
||||||
|
</td>
|
||||||
|
</tr>`;
|
||||||
|
});
|
||||||
}).catch((err) => alert(`Couldn't unwrap json: ${err}`))
|
}).catch((err) => alert(`Couldn't unwrap json: ${err}`))
|
||||||
}).catch((err) => alert(`Couldn't fetch trackers: ${err}`));
|
}).catch((err) => alert(`Couldn't fetch trackers: ${err}`));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function loadTrigger(id) {
|
||||||
|
const apiKey = localStorage.getItem("api-key");
|
||||||
|
if (!apiKey) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
fetch(`http://localhost:8000/tracker/${id}/hits`, {
|
||||||
|
method: "GET",
|
||||||
|
headers: {
|
||||||
|
Authorization: apiKey,
|
||||||
|
}
|
||||||
|
}).then((res) => {
|
||||||
|
res.json().then((hits) => {
|
||||||
|
document.getElementById("hit-title").innerHTML = `${hits.length} hit(s) for tracker ${id}`;
|
||||||
|
document.getElementById("hit-table").innerHTML = `
|
||||||
|
<tr>
|
||||||
|
<th>ID</th>
|
||||||
|
<th>IP</th>
|
||||||
|
<th>Agent</th>
|
||||||
|
<th>Language</th>
|
||||||
|
<th>Created at</th>
|
||||||
|
</tr>`;
|
||||||
|
|
||||||
|
hits.forEach((hit) => {
|
||||||
|
document.getElementById("hit-table").innerHTML += `
|
||||||
|
<tr>
|
||||||
|
<td>${hit.id}</td>
|
||||||
|
<td>${hit.ip}</td>
|
||||||
|
<td>${hit.agent}</td>
|
||||||
|
<td>${hit.language}</td>
|
||||||
|
<td>${hit.created_at}</td>
|
||||||
|
</tr>`;
|
||||||
|
});
|
||||||
|
}).catch((err) => alert(`Couldn't unwrap json: ${err}`));
|
||||||
|
}).catch((err) => alert(`Couldn't fetch hits: ${err}`));
|
||||||
|
}
|
||||||
|
|
||||||
|
function copyLink(id) {
|
||||||
|
navigator.clipboard.writeText(`http://localhost:8000/image/${id}`).catch((err) => alert(`Couldn't copy: ${err}`));
|
||||||
|
}
|
||||||
|
|
||||||
init();
|
init();
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
Reference in New Issue
Block a user