Compare commits

..

3 Commits

Author SHA1 Message Date
august 5848b7360c Add date editing for posts 2025-01-09 18:29:24 -05:00
august d0a4b0f6a6 Update Cargo.lock 2025-01-09 12:06:01 -05:00
august 59a6205a1e RSS fixes 2025-01-09 12:05:42 -05:00
8 changed files with 50 additions and 13 deletions
Generated
+4 -4
View File
@@ -693,9 +693,9 @@ dependencies = [
[[package]] [[package]]
name = "event-listener" name = "event-listener"
version = "5.3.1" version = "5.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae"
dependencies = [ dependencies = [
"concurrent-queue", "concurrent-queue",
"parking", "parking",
@@ -1353,9 +1353,9 @@ dependencies = [
[[package]] [[package]]
name = "linux-raw-sys" name = "linux-raw-sys"
version = "0.4.14" version = "0.4.15"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab"
[[package]] [[package]]
name = "litemap" name = "litemap"
+13
View File
@@ -75,6 +75,19 @@ impl BlogDb {
.await?; .await?;
Ok(()) Ok(())
} }
/// Delete post by id
pub async fn set_post_date<S, T>(&self, id: S, date: T) -> anyhow::Result<()>
where
S: AsRef<str>,
T: AsRef<str>,
{
sqlx::query("UPDATE posts SET date=? WHERE id=?")
.bind(date.as_ref())
.bind(id.as_ref())
.execute(&self.db)
.await?;
Ok(())
}
} }
#[cfg(test)] #[cfg(test)]
+3 -3
View File
@@ -23,7 +23,7 @@ main {
} }
.admin-widget:not(.admin-widget-user) { .admin-widget:not(.admin-widget-user) {
max-inline-size: 50%; max-inline-size: calc(50% - (0.5 * var(--default-padding)));
} }
.admin-widget-user { .admin-widget-user {
@@ -122,8 +122,8 @@ main {
.blog-admin { .blog-admin {
box-sizing: border-box; box-sizing: border-box;
display: flex; display: flex;
gap: var(--default-padding);
flex-wrap: wrap; flex-wrap: wrap;
gap: var(--default-padding);
box-sizing: border-box; box-sizing: border-box;
min-block-size: 0; min-block-size: 0;
flex: 1; flex: 1;
@@ -246,7 +246,7 @@ main {
a.entry-content { a.entry-content {
color: inherit; color: inherit;
text-decoration: inherit; text-decoration: inherit;
inline-size: 90%; max-inline-size: 90%;
transition: all 0.3s ease; transition: all 0.3s ease;
+11
View File
@@ -0,0 +1,11 @@
const editDateButton = document.getElementById("date-update");
const postActions = document.getElementById("post-actions");
const children = postActions.innerHTML;
dateInput = `<button class="form-action" formaction="/admin" formmethod="get" formnovalidate>✕</button><input class="form-action" type="date" name="date" placeholder="Enter Date" autocomplete="off" aria-label="New Date" required /> <button class="form-action" type="submit" formaction="/api/posts/date">Update Date</button>`;
editDateButton.addEventListener("click", (ev) => {
ev.preventDefault();
console.log(ev, postActions, dateInput);
postActions.innerHTML = dateInput;
});
+6 -5
View File
@@ -295,8 +295,7 @@ async fn admin_entries(entry_type: EntryType, session_id: i64, db: &BlogDb) -> S
let is_empty: bool; let is_empty: bool;
let entries_html = match entry_type { let entries_html = match entry_type {
EntryType::Post => { EntryType::Post => {
let mut entries = db.get_posts().await.unwrap_or(vec![]); let entries = db.get_posts().await.unwrap_or(vec![]);
entries.reverse();
let mut entry_list_html = String::new(); let mut entry_list_html = String::new();
is_empty = entries.is_empty(); is_empty = entries.is_empty();
if !is_empty { if !is_empty {
@@ -856,9 +855,11 @@ pub(crate) async fn rss(db: &BlogDb) -> String {
.collect::<Vec<u32>>() .collect::<Vec<u32>>()
.try_into() .try_into()
.unwrap_or_default(); .unwrap_or_default();
let date_time: DateTime<Utc> = Utc let date_time: DateTime<FixedOffset> =
.with_ymd_and_hms(date[0] as i32, date[1], date[2], 0, 0, 0) FixedOffset::west_opt(5 * 3600) // New York City
.unwrap(); .unwrap()
.with_ymd_and_hms(date[0] as i32, date[1], date[2], 0, 0, 0)
.unwrap();
date_time.to_rfc2822() date_time.to_rfc2822()
}; };
pub_date.set_inner_content(&date, ContentType::Text); pub_date.set_inner_content(&date, ContentType::Text);
+8
View File
@@ -38,6 +38,7 @@ pub(super) fn api(state: BlogState) -> Router {
struct Entries { struct Entries {
#[serde(default)] #[serde(default)]
item: Vec<String>, item: Vec<String>,
date: Option<String>,
} }
#[derive(Debug, Deserialize)] #[derive(Debug, Deserialize)]
@@ -45,6 +46,7 @@ struct Entries {
enum PostsEndpoints { enum PostsEndpoints {
delete, delete,
unpublish, unpublish,
date,
} }
async fn posts( async fn posts(
@@ -71,6 +73,12 @@ async fn posts(
state.index_delete(term); state.index_delete(term);
} }
} }
PostsEndpoints::date => {
let date = &data.date.clone().unwrap_or("1970-01-01".to_string());
for post_id in data.item.iter() {
let _ = db.set_post_date(post_id, &date).await;
}
}
} }
state.index_commit(); state.index_commit();
let mut headers = HeaderMap::new(); let mut headers = HeaderMap::new();
@@ -3,11 +3,14 @@
<h1>Published Posts</h1> <h1>Published Posts</h1>
</div> </div>
<form method="post"> <form method="post">
<div class="form-actions"> <div class="form-actions" id="post-actions">
<button class="form-action" type="submit" formaction="/api/posts/delete">Delete posts <button class="form-action" type="submit" formaction="/api/posts/delete">Delete posts
</button> </button>
<button class=" form-action" type="submit" formaction="/api/posts/unpublish">Unpublish Posts <button class=" form-action" type="submit" formaction="/api/posts/unpublish">Unpublish Posts
</button> </button>
<button id="date-update" class="form-action" type="submit" formaction="#update-date" formmethod="get">Edit
Date
</button>
</div> </div>
<ul tabindex="-1"> <ul tabindex="-1">
</ul> </ul>
+1
View File
@@ -3,3 +3,4 @@
<admin-widget type="drafts"></admin-widget> <admin-widget type="drafts"></admin-widget>
<admin-widget type="posts"></admin-widget> <admin-widget type="posts"></admin-widget>
</div> </div>
<script src="/assets/js/admin.js"></script>