Album Page Component

This commit is contained in:
Aidan Westphal 2024-10-22 03:32:55 +00:00
parent cdffd2c5eb
commit df01bafbd1
6 changed files with 81 additions and 5 deletions

View File

@ -7,6 +7,7 @@ use leptos_meta::*;
use leptos_router::*;
use crate::pages::login::*;
use crate::pages::signup::*;
use crate::pages::album::*;
use crate::error_template::{AppError, ErrorTemplate};
@ -42,6 +43,7 @@ pub fn App() -> impl IntoView {
<Route path="" view=Dashboard />
<Route path="dashboard" view=Dashboard />
<Route path="search" view=Search />
<Route path="album/:id" view=AlbumPage />
</Route>
<Route path="/login" view=Login />
<Route path="/signup" view=Signup />

View File

@ -1,13 +1,15 @@
use std::time::SystemTime;
use leptos::{server, ServerFnError};
use time::Date;
use serde::{Deserialize, Serialize};
use crate::songdata::SongData;
use cfg_if::cfg_if;
cfg_if! {
if #[cfg(feature = "ssr")] {
use diesel::prelude::*;
use crate::database::PgPooledConn;
use crate::database::*;
use std::error::Error;
}
}
@ -499,7 +501,7 @@ impl Album {
Ok(())
}
/// Get songs by this artist from the database
/// Get songs by this album from the database
///
/// The `id` field of this album must be present (Some) to get songs
///
@ -528,6 +530,22 @@ impl Album {
}
}
#[server(endpoint = "get_album")]
pub async fn get_album(a_id: i32) -> Result<Vec<SongData>,ServerFnError> {
use crate::schema::songs::dsl::*;
use crate::schema::song_artists::dsl::*;
let conn = get_db_conn();
let songs = songs
.inner_join(song_artists)
.filter(album_id.eq(a_id))
.select(songs::all_columns())
.load(conn)?;
Ok(songs.into())
}
/// Model for a song
#[cfg_attr(feature = "ssr", derive(Queryable, Selectable, Insertable))]
#[cfg_attr(feature = "ssr", diesel(table_name = crate::schema::songs))]

View File

@ -1,2 +1,3 @@
pub mod login;
pub mod signup;
pub mod album;

54
src/pages/album.rs Normal file
View File

@ -0,0 +1,54 @@
use leptos::leptos_dom::*;
use leptos::*;
use leptos_icons::*;
use leptos_router::*;
use crate::models::*;
use crate::components::song_list::*;
#[derive(Params, PartialEq)]
struct AlbumParams {
id: i32
}
#[component]
pub fn AlbumPage() -> impl IntoView {
let params = use_params::<AlbumParams>();
let id = move || {params.with(|params| {
params.as_ref()
.map(|params| params.id)
.map_err(|e| e.clone())
})
};
let song_list = create_resource(
id,
|value| async move {
match value {
Ok(v) => {get_album(v).await},
Err(e) => {Err(ServerFnError::Request("Invalid album!".into()))},
}
},
);
view! {
<Suspense
fallback=move || view! { <p>"Loading..."</p> }
>
{move || {
song_list.with( |song_list| {
match song_list {
Some(Ok(s)) => {
view! { <SongList songs=s.clone().into()/> }.into_view()
},
Some(Err(e)) => {
view! { <div>"Error loading albums"</div> }.into_view()
},
None => {view! { }.into_view()}
}
})
}}
</Suspense>
}
}

View File

@ -1,12 +1,13 @@
use crate::models::{Album, Artist, Song};
use crate::components::dashboard_tile::DashboardTile;
use serde::{Serialize, Deserialize};
use time::Date;
/// Holds information about a song
///
/// Intended to be used in the front-end, as it includes artist and album objects, rather than just their ids.
#[derive(Clone)]
#[derive(Clone, Serialize, Deserialize)]
pub struct SongData {
/// Song id
pub id: i32,