From e3c384ea5af136826a29c7da1675af1a8d2e6627 Mon Sep 17 00:00:00 2001 From: David Westgate Date: Tue, 11 Jun 2024 22:12:21 -0700 Subject: [PATCH] check joke refs to questions --- backend/src/main.rs | 27 ++++++++++++++++++++-- frontend/src/finder.rs | 4 ++-- frontend/src/main.rs | 48 ++++++++++++++++++++-------------------- frontend/src/question.rs | 44 ++++++++++++++++++------------------ 4 files changed, 72 insertions(+), 51 deletions(-) diff --git a/backend/src/main.rs b/backend/src/main.rs index c6a1619..22e5b65 100644 --- a/backend/src/main.rs +++ b/backend/src/main.rs @@ -5,8 +5,9 @@ mod question; mod question_tag; mod tag; use axum::{ - extract::{Path, Query, State}, - http::{StatusCode, Uri}, + extract::{Path, Query, Request, State}, + http::{header, StatusCode, Uri}, + middleware::Next, response::{IntoResponse, Response}, routing::{delete, get, post, put}, Form, Json, Router, @@ -57,6 +58,27 @@ fn db_string() -> String { ) } +// Simple cors middleware to avoid pulling in tower just for this +async fn add_cors_headers( + req: Request, + next: Next, +) -> Result { + let mut response = next.run(req).await; + response.headers_mut().insert( + header::ACCESS_CONTROL_ALLOW_ORIGIN, + header::HeaderValue::from_static("*"), + ); + response.headers_mut().insert( + header::ACCESS_CONTROL_ALLOW_METHODS, + header::HeaderValue::from_static("GET, POST, PUT, DELETE"), + ); + response.headers_mut().insert( + header::ACCESS_CONTROL_ALLOW_HEADERS, + header::HeaderValue::from_static("Content-Type, Authorization"), + ); + Ok(response) +} + #[tokio::main] async fn main() { let db_url: String = db_string(); @@ -76,6 +98,7 @@ async fn main() { .nest("/api/v1", apis) .route("/", get(serve_file)) .route("/*path", get(serve_file)) + .layer(axum::middleware::from_fn(add_cors_headers)) .fallback(handler_404); axum::serve(listener, app).await.unwrap(); diff --git a/frontend/src/finder.rs b/frontend/src/finder.rs index 0bd5457..331f7c8 100644 --- a/frontend/src/finder.rs +++ b/frontend/src/finder.rs @@ -27,9 +27,9 @@ pub fn Finder(props: &FinderProps) -> Html { let props = props.clone(); html! { <>
- +
} diff --git a/frontend/src/main.rs b/frontend/src/main.rs index e374466..9dc0ece 100644 --- a/frontend/src/main.rs +++ b/frontend/src/main.rs @@ -1,8 +1,8 @@ mod finder; -mod joke; +mod question; use finder::*; -use joke::*; +use question::*; use std::collections::HashSet; @@ -13,21 +13,21 @@ extern crate wasm_bindgen_futures; use web_sys::HtmlTextAreaElement; use yew::prelude::*; -pub type JokeResult = Result; +pub type QuestionResult = Result; struct App { - joke: JokeResult, + question: QuestionResult, } pub enum Msg { - GotJoke(JokeResult), - GetJoke(Option), + GotQuestion(QuestionResult), + GetQuestion(Option), } impl App { - fn refresh_joke(ctx: &Context, key: Option) { - let got_joke = JokeStruct::get_joke(key); - ctx.link().send_future(got_joke); + fn refresh_question(ctx: &Context, key: Option) { + let got_question = QuestionStruct::get_question(key); + ctx.link().send_future(got_question); } } @@ -36,42 +36,42 @@ impl Component for App { type Properties = (); fn create(ctx: &Context) -> Self { - App::refresh_joke(ctx, None); - let joke = Err(gloo_net::Error::GlooError("Loading Joke…".to_string())); - Self { joke } + App::refresh_question(ctx, None); + let question = Err(gloo_net::Error::GlooError("Loading Question…".to_string())); + Self { question } } fn update(&mut self, ctx: &Context, msg: Self::Message) -> bool { match msg { - Msg::GotJoke(joke) => { - self.joke = joke; + Msg::GotQuestion(question) => { + self.question = question; true } - Msg::GetJoke(key) => { - // log!(format!("GetJoke: {:?}", key)); - App::refresh_joke(ctx, key); + Msg::GetQuestion(key) => { + // log!(format!("GetQuestion: {:?}", key)); + App::refresh_question(ctx, key); false } } } fn view(&self, ctx: &Context) -> Html { - let joke = &self.joke; + let question = &self.question; html! { <> -

{ "Knock-Knock" }

- if let Ok(ref joke) = joke { - +

{ "Question and Answer" }

+ if let Ok(ref question) = question { + } - if let Err(ref error) = joke { + if let Err(ref error) = question {
{format!("Server Error: {error}")}
}
- +
- + } } diff --git a/frontend/src/question.rs b/frontend/src/question.rs index 645d7e5..0439b54 100644 --- a/frontend/src/question.rs +++ b/frontend/src/question.rs @@ -1,24 +1,24 @@ use crate::*; #[derive(Properties, Clone, PartialEq, serde::Deserialize)] -pub struct JokeStruct { +pub struct QuestionStruct { pub id: String, - pub whos_there: String, - pub answer_who: String, + pub title: String, + pub content: String, pub tags: Option>, pub source: Option, } -impl JokeStruct { - pub async fn get_joke(key: Option) -> Msg { +impl QuestionStruct { + pub async fn get_question(key: Option) -> Msg { let request = match &key { - None => "http://localhost:3000/api/v1/joke".to_string(), - Some(ref key) => format!("http://localhost:3000/api/v1/joke/{}", key,), + None => "http://localhost:3000/api/v1/question/2".to_string(), + Some(ref key) => format!("http://localhost:3000/api/v1/question/{}", key,), }; let response = http::Request::get(&request).send().await; match response { - Err(e) => Msg::GotJoke(Err(e)), - Ok(data) => Msg::GotJoke(data.json().await), + Err(e) => Msg::GotQuestion(Err(e)), + Ok(data) => Msg::GotQuestion(data.json().await), } } } @@ -28,27 +28,25 @@ pub fn format_tags(tags: &HashSet) -> String { } #[derive(Properties, Clone, PartialEq, serde::Deserialize)] -pub struct JokeProps { - pub joke: JokeStruct, +pub struct QuestionProps { + pub question: QuestionStruct, } -#[function_component(Joke)] -pub fn joke(joke: &JokeProps) -> Html { - let joke = &joke.joke; +#[function_component(Question)] +pub fn question(question: &QuestionProps) -> Html { + let question = &question.question; html! { <> -
- {"Knock-Knock!"}
- {"Who's there?"}
- {joke.whos_there.clone()}
- {format!("{} who?", &joke.whos_there)}
- {joke.answer_who.clone()} +
+ {"Question time!"}
+ {question.title.clone()}
+ {question.content.clone()}
- {format!("[id: {}", &joke.id)} - if let Some(ref tags) = joke.tags { + {format!("[id: {}", &question.id)} + if let Some(ref tags) = question.tags { {format!("; tags: {}", &format_tags(tags))} } - if let Some(ref source) = joke.source { + if let Some(ref source) = question.source { {format!("; source: {}", source)} } {"]"}