You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

170 lines
6.4 KiB

use axum::extract::Query;
use maud::{html, Markup, PreEscaped, DOCTYPE};
use serde::Deserialize;
use crate::{
components::header::{Header, HeaderLink},
WATTPAD,
};
use wattpad::{SearchSort, SearchType};
#[derive(Deserialize)]
pub struct SearchParams {
query: Option<String>,
#[serde(rename = "type")]
search_type: Option<String>,
#[serde(rename = "sort")]
search_sort: Option<String>,
#[serde(rename = "page")]
page_number: Option<i64>,
}
/* if let Some(query) = params.query {
let search_type = params.search_type.unwrap_or("text".to_string());
let search_sort = params.search_sort.unwrap_or("hot".to_string());
} else {
} */
pub async fn render(Query(params): Query<SearchParams>) -> Markup {
let search_type = params.search_type.unwrap_or("text".to_string());
let search_sort = params.search_sort.unwrap_or("hot".to_string());
html! {
(DOCTYPE)
title {"Search | Voltpad"};
meta name="viewport" content="width=device-width, initial-scale=1.0";
style {(PreEscaped(
grass::include!("./css/index.scss")
))}
script {(PreEscaped(
include_str!("../../scripts/Search.js")
))}
(
Header(vec![
HeaderLink {
name: "Home".to_string(),
path: "/".to_string(),
prefix: None,
postfix: None
},
HeaderLink {
name: "Search".to_string(),
path: "/search".to_string(),
prefix: None,
postfix: None
},
HeaderLink {
name: "History".to_string(),
path: "/history".to_string(),
prefix: None,
postfix: None
},
HeaderLink {
name: "About".to_string(),
path: "/about".to_string(),
prefix: None,
postfix: None
},
], "/search".to_string())
)
div .index-content {
h1 { "Search" }
form method="GET" .search-form {
div {
input
#query
type="text"
name="query"
autocomplete="off"
placeholder="Search Query"
value=[params.query.clone()];
div {
div {
input
#text
type="radio"
name="type"
value="text"
checked=[(search_type == "text").then_some(80)]; // IS 80 ENOUGH PROOF FOR YOU?
label for="text" { "Text search" }
}
div {
input
#tag
type="radio"
name="type"
value="tag"
checked=[(search_type == "tag").then_some(80)];
label for="tag" { "Tag search" }
}
div {
select #sort name="sort" {
option
value="hot"
selected=[(search_sort == "hot").then_some(80)] { "Hot" };
option
value="new"
selected=[(search_sort == "new").then_some(80)] { "New" };
}
}
}
}
div .search-buttons {
input .submit-search type="submit" value="Submit";
input #favorite type="button" value="Favorite";
}
}
@if let Some(query) = params.query.clone() {
({
let page_number = params.page_number.unwrap_or(0);
let enumified_search_type = match search_type.as_str() {
"text" => SearchType::Text,
"title" => SearchType::Title,
"tag" => SearchType::Tag,
_ => SearchType::Text
};
let enumified_search_sort = match search_sort.as_str() {
"hot" => SearchSort::Hot,
"new" => SearchSort::New,
_ => SearchSort::Hot
};
let search = WATTPAD.search(&query, enumified_search_type, enumified_search_sort, 30)
.await
.expect("Failed to create search");
let results = search.page(page_number)
.await
.expect("Failed to get search results");
html! {
div .story-list {
@for result in results.stories.clone() {
a .listed-story href=(format!("/story?id={}", result.id)) {
img src=(result.cover);
div {
h3 { (result.title) }
p { (PreEscaped(result.description.replace('\n', "<br/>"))) }
}
}
}
div .story-nav {
@if page_number > 0 {
a href=(format!("/search?query={}&type={}&sort={}&page={}", query, search_type, search_sort, page_number-1)) { "<" }
}
" | "
@if search.page(page_number).await.expect("Failed to get search results 2").stories.len() > 0 {
a href=(format!("/search?query={}&type={}&sort={}&page={}", query, search_type, search_sort, page_number+1)) { ">" }
}
}
}
}
})
}
}
}
}