Start roughing in series management
- Set up asset struct for rust-embed. Create SQL assets. - Write convenience for loading SQL assets. - Rough out view series route. - Rough out and wire up add series route.
This commit is contained in:
parent
ddb06d2993
commit
3d3b08caf1
7 changed files with 68 additions and 4 deletions
1
sql/insert_series.sql
Normal file
1
sql/insert_series.sql
Normal file
|
@ -0,0 +1 @@
|
||||||
|
insert into series (name) values ($1);
|
1
sql/select_series.sql
Normal file
1
sql/select_series.sql
Normal file
|
@ -0,0 +1 @@
|
||||||
|
select * from series;
|
|
@ -1,9 +1,13 @@
|
||||||
use super::series::SeriesList;
|
use super::series::{add::AddSeries, SeriesList};
|
||||||
use leptos::*;
|
use leptos::*;
|
||||||
use leptos_router::*;
|
use leptos_router::*;
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn HomePage() -> impl IntoView {
|
pub fn HomePage() -> impl IntoView {
|
||||||
|
let add_series = create_server_action::<AddSeries>();
|
||||||
|
|
||||||
|
provide_context(add_series);
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
<h1 class="mt-3 mb-5">"What We're Watching"</h1>
|
<h1 class="mt-3 mb-5">"What We're Watching"</h1>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
|
|
|
@ -1,15 +1,48 @@
|
||||||
use leptos::*;
|
use leptos::*;
|
||||||
|
use leptos_router::*;
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn AddSeries() -> impl IntoView {
|
pub fn AddSeries() -> impl IntoView {
|
||||||
|
let add_series = expect_context::<Action<AddSeries, Result<(), ServerFnError>>>();
|
||||||
view! {
|
view! {
|
||||||
<div class="card p-3">
|
<div class="card p-3">
|
||||||
<div class="card-heading">
|
<div class="card-heading">
|
||||||
<h2>Add Series</h2>
|
<h2>Add Series</h2>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-body">
|
<div class="card-body">
|
||||||
To Do
|
<ActionForm action=add_series>
|
||||||
|
<div class="input-group mb-3">
|
||||||
|
<input type="text"
|
||||||
|
name="name"
|
||||||
|
class="form-control"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<input type="submit"
|
||||||
|
class="btn btn-primary"
|
||||||
|
value="Add Series"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</ActionForm>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[server(AddSeries)]
|
||||||
|
pub async fn add_series(name: String) -> Result<(), ServerFnError> {
|
||||||
|
use crate::db::load_statement;
|
||||||
|
use sqlx::{Pool, Postgres};
|
||||||
|
let pool = expect_context::<Pool<Postgres>>();
|
||||||
|
|
||||||
|
let s = load_statement("insert_series.sql");
|
||||||
|
sqlx::query(&s)
|
||||||
|
.persistent(true)
|
||||||
|
.bind(name)
|
||||||
|
.execute(&pool)
|
||||||
|
.await?;
|
||||||
|
|
||||||
|
leptos_axum::redirect("/");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
use self::add::AddSeries;
|
||||||
use leptos::*;
|
use leptos::*;
|
||||||
use leptos_router::*;
|
use leptos_router::*;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
|
@ -10,7 +11,11 @@ pub mod view;
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn SeriesList() -> impl IntoView {
|
pub fn SeriesList() -> impl IntoView {
|
||||||
let load = create_resource(|| (), |_| async move { get_all().await });
|
let add_user = expect_context::<Action<AddSeries, Result<(), ServerFnError>>>();
|
||||||
|
let load = create_resource(
|
||||||
|
move || add_user.version().get(),
|
||||||
|
|_| async move { get_all().await },
|
||||||
|
);
|
||||||
view! {
|
view! {
|
||||||
<Suspense fallback=|| view!{ <div>"Loading..."</div> }>
|
<Suspense fallback=|| view!{ <div>"Loading..."</div> }>
|
||||||
<ul class="list-group mb-3">
|
<ul class="list-group mb-3">
|
||||||
|
@ -55,12 +60,14 @@ pub struct Series {
|
||||||
|
|
||||||
#[server]
|
#[server]
|
||||||
pub async fn get_all() -> Result<Vec<Series>, ServerFnError> {
|
pub async fn get_all() -> Result<Vec<Series>, ServerFnError> {
|
||||||
|
use crate::db::load_statement;
|
||||||
use sqlx::{Pool, Postgres};
|
use sqlx::{Pool, Postgres};
|
||||||
use tokio_stream::StreamExt;
|
use tokio_stream::StreamExt;
|
||||||
|
|
||||||
let pool: Pool<Postgres> = expect_context();
|
let pool: Pool<Postgres> = expect_context();
|
||||||
|
|
||||||
let mut r = sqlx::query_as::<_, Series>("select * from series;").fetch(&pool);
|
let s = load_statement("select_series.sql");
|
||||||
|
let mut r = sqlx::query_as::<_, Series>(&s).fetch(&pool);
|
||||||
|
|
||||||
let mut found = Vec::new();
|
let mut found = Vec::new();
|
||||||
while let Some(series) = r.try_next().await? {
|
while let Some(series) = r.try_next().await? {
|
||||||
|
|
16
src/db.rs
Normal file
16
src/db.rs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
use anyhow::format_err;
|
||||||
|
use rust_embed::RustEmbed;
|
||||||
|
|
||||||
|
#[derive(RustEmbed)]
|
||||||
|
#[folder = "sql/"]
|
||||||
|
pub struct Asset;
|
||||||
|
|
||||||
|
pub fn load_statement<S: AsRef<str>>(asset: S) -> String {
|
||||||
|
let asset = asset.as_ref();
|
||||||
|
let loaded = Asset::get(asset)
|
||||||
|
.ok_or_else(|| format_err!("Could not load SQL asset, {asset}!"))
|
||||||
|
.unwrap();
|
||||||
|
String::from_utf8(loaded.data.to_vec()).expect(&format!(
|
||||||
|
"SQL asset, {asset}, could not be parsed as UTF-8!"
|
||||||
|
))
|
||||||
|
}
|
|
@ -1,4 +1,6 @@
|
||||||
pub mod app;
|
pub mod app;
|
||||||
|
#[cfg(feature = "ssr")]
|
||||||
|
pub mod db;
|
||||||
pub mod error_template;
|
pub mod error_template;
|
||||||
#[cfg(feature = "ssr")]
|
#[cfg(feature = "ssr")]
|
||||||
pub mod fileserv;
|
pub mod fileserv;
|
||||||
|
|
Loading…
Reference in a new issue