From 3746c370a23f660e2bd35fb6cdb420044f614722 Mon Sep 17 00:00:00 2001 From: dannyzou18 Date: Wed, 22 May 2024 23:04:21 -0400 Subject: [PATCH] completed add album component, front and backend --- src/api/albums.rs | 66 +++++++++++++++ src/api/artists.rs | 2 +- src/api/mod.rs | 3 +- src/app.rs | 2 + src/components.rs | 3 +- src/components/add_album.rs | 92 +++++++++++++++++++++ src/components/upload_dropdown.rs | 2 + style/addAlbum.scss | 132 ++++++++++++++++++++++++++++++ style/main.scss | 1 + style/upload.scss | 35 ++++++++ 10 files changed, 335 insertions(+), 3 deletions(-) create mode 100644 src/api/albums.rs create mode 100644 src/components/add_album.rs create mode 100644 style/addAlbum.scss diff --git a/src/api/albums.rs b/src/api/albums.rs new file mode 100644 index 0000000..0c0f934 --- /dev/null +++ b/src/api/albums.rs @@ -0,0 +1,66 @@ +use leptos::*; + +use cfg_if::cfg_if; + +cfg_if! { + if #[cfg(feature = "ssr")] { + use crate::database::get_db_conn; + use diesel::prelude::*; + use time::Date; + } +} + +/// Add an album to the database + /// + /// # Arguments + /// + /// * `album_title` - The name of the artist to add + /// * `release_data` - The release date of the album (Optional) + /// * `image_path` - The path to the album's image file (Optional) + /// + /// # Returns + /// * `Result<(), Box>` - A empty result if successful, or an error + /// +#[server(endpoint = "albums/add-album")] +pub async fn add_album(album_title: String, release_date: Option, image_path: Option) -> Result<(), ServerFnError> { + use crate::schema::albums::{self}; + use crate::models::Album; + use leptos::server_fn::error::NoCustomError; + + let date_format = time::macros::format_description!("[year]-[month]-[day]"); + let parsed_release_date = match release_date { + Some(date) => { + match Date::parse(&date, &date_format) { + Ok(parsed_date) => Some(parsed_date), + Err(_e) => return Err(ServerFnError::::ServerError("Invalid release date".to_string())) + } + }, + None => None + }; + + let image_path_arg = match image_path { + Some(image_path) => { + if image_path.is_empty() { + None + } else { + Some(image_path) + } + }, + None => None + }; + + let new_album = Album { + id: None, + title: album_title, + release_date: parsed_release_date, + image_path: image_path_arg + }; + + let db = &mut get_db_conn(); + diesel::insert_into(albums::table) + .values(&new_album) + .execute(db) + .map_err(|e| ServerFnError::::ServerError(format!("Error adding album: {}", e)))?; + + Ok(()) +} diff --git a/src/api/artists.rs b/src/api/artists.rs index fc0b81f..6545ef6 100644 --- a/src/api/artists.rs +++ b/src/api/artists.rs @@ -1,5 +1,4 @@ use leptos::*; -use crate::models::Artist; use cfg_if::cfg_if; @@ -22,6 +21,7 @@ cfg_if! { #[server(endpoint = "artists/add-artist")] pub async fn add_artist(artist_name: String) -> Result<(), ServerFnError> { use crate::schema::artists::dsl::*; + use crate::models::Artist; use leptos::server_fn::error::NoCustomError; let new_artist = Artist { diff --git a/src/api/mod.rs b/src/api/mod.rs index 06523f1..7bff812 100644 --- a/src/api/mod.rs +++ b/src/api/mod.rs @@ -1 +1,2 @@ -pub mod artists; \ No newline at end of file +pub mod artists; +pub mod albums; \ No newline at end of file diff --git a/src/app.rs b/src/app.rs index 113daef..aed0421 100644 --- a/src/app.rs +++ b/src/app.rs @@ -64,6 +64,7 @@ use crate::components::search::*; use crate::components::personal::*; use crate::components::upload::*; use crate::components::add_artist::AddArtist; +use crate::components::add_album::AddAlbum; /// Renders the home page of your application. #[component] @@ -72,6 +73,7 @@ fn HomePage(play_status: RwSignal, upload_open: RwSignal, add_
+ // This will render the child route components diff --git a/src/components.rs b/src/components.rs index e6757c3..38eb556 100644 --- a/src/components.rs +++ b/src/components.rs @@ -4,4 +4,5 @@ pub mod search; pub mod personal; pub mod upload; pub mod upload_dropdown; -pub mod add_artist; \ No newline at end of file +pub mod add_artist; +pub mod add_album; \ No newline at end of file diff --git a/src/components/add_album.rs b/src/components/add_album.rs new file mode 100644 index 0000000..7a36296 --- /dev/null +++ b/src/components/add_album.rs @@ -0,0 +1,92 @@ +use leptos::*; +use leptos::leptos_dom::log; +use leptos_icons::*; +use crate::api::albums::add_album; + +#[component] +pub fn AddAlbumBtn(add_album_open: RwSignal) -> impl IntoView { + let open_dialog = move |_| { + add_album_open.set(true); + }; + view! { + + } +} +#[component] +pub fn AddAlbum(open: RwSignal) -> impl IntoView { + let album_title = create_rw_signal("".to_string()); + let release_date = create_rw_signal("".to_string()); + let image_path = create_rw_signal("".to_string()); + + let close_dialog = move |ev: leptos::ev::MouseEvent| { + ev.prevent_default(); + open.set(false); + }; + + let on_add_album = move |ev: leptos::ev::SubmitEvent| { + ev.prevent_default(); + let album_title_clone = album_title.get(); + let release_date_clone = Some(release_date.get()); + let image_path_clone = Some(image_path.get()); + + spawn_local(async move { + let add_album_result = add_album(album_title_clone, release_date_clone, image_path_clone).await; + if let Err(err) = add_album_result { + log!("Error adding album: {:?}", err); + } else if let Ok(album) = add_album_result { + log!("Added album: {:?}", album); + album_title.set("".to_string()); + release_date.set("".to_string()); + image_path.set("".to_string()); + } + }) + }; + + view! { + +
+
+

Add Album

+
+
+
+
+ + Album Title +
+
+
+ Release + Date +
+ +
+
+ + Image Path +
+ +
+
+
+ } + +} \ No newline at end of file diff --git a/src/components/upload_dropdown.rs b/src/components/upload_dropdown.rs index 6be435b..83774a5 100644 --- a/src/components/upload_dropdown.rs +++ b/src/components/upload_dropdown.rs @@ -2,6 +2,7 @@ use leptos::*; use leptos_icons::*; use crate::components::upload::*; use crate::components::add_artist::*; +use crate::components::add_album::*; #[component] pub fn UploadDropdownBtn(dropdown_open: RwSignal) -> impl IntoView { @@ -23,6 +24,7 @@ pub fn UploadDropdown(upload_open: RwSignal, add_artist_open: RwSignal +
} } \ No newline at end of file diff --git a/style/addAlbum.scss b/style/addAlbum.scss new file mode 100644 index 0000000..b72bbf1 --- /dev/null +++ b/style/addAlbum.scss @@ -0,0 +1,132 @@ +@import "theme.scss"; + +.add-album-container { + position: fixed; + top: 45%; + left: 50%; + transform: translate(-50%, -50%); + width: 30rem; + height: 24rem; + border: 1px solid white; + border-radius: 5px; + padding: 1rem; + padding-top: 0; + z-index: 2; + display: flex; + flex-direction: column; + background-color: #1c1c1c; + .upload-header { + font-size: .7rem; + font-weight: 300; + padding-bottom: 0; + border-bottom: 1px solid white; + font-family: "Roboto", sans-serif; + } + .close-button { + position: absolute; + top: 5px; + right: 5px; + display: flex; + justify-content: center; + align-items: center; + cursor: pointer; + border-radius: 50%; + font-size: 1.6rem; + transition: all 0.3s; + border: none; + + } + .close-button:hover { + transform: scale(1.1); + background-color: rgba(255, 255, 255, 0.1); + } + .close-button:active { + transform: scale(0.8); + } + .create-album-form { + width:100%; + height: 100%; + position: relative; + .input-bx{ + margin-top: 1rem; + width: 300px; + input{ + width: 100%; + padding: 10px; + border: 2px solid #7f8fa6; + border-radius: 5px; + outline: none; + font-size: 1rem; + transition: 0.6s; + background-color: transparent; + } + span{ + position: absolute; + left: 0; + padding: 10px; + font-size: 1rem; + color: #7f8fa6; + text-transform: uppercase; + pointer-events: none; + transition: 0.6s; + background-color: transparent; + } + input:valid ~ span, + input:focus ~ span{ + color: #fff; + transform: translateX(10px) translateY(-7px); + font-size: 0.65rem; + font-weight: 600; + padding: 0 10px; + background: #1c1c1c; + letter-spacing: 0.1rem; + } + input:valid, + input:focus{ + color: #fff; + border: 2px solid #fff; + } + + } + .release-date { + margin-top: 1rem; + font-size: 1.2rem; + color: #7f8fa6; + font-family: "Roboto", sans-serif; + display: flex; + align-items: center; + .left { + display: flex; + flex-direction: column; + margin-left: 5px; + margin-right: 10px; + } + span { + font-size: .85rem; + } + input { + padding: 8px; + } + } + .upload-button { + position: absolute; + bottom: 5px; + margin-top: 1rem; + padding: 10px; + background-color: #7f8fa6; + color: #fff; + width: 100%; + font-size: 1rem; + font-family: "Roboto", sans-serif; + border: none; + border-radius: 5px; + cursor: pointer; + transition: 0.3s; + &:hover { + background-color: #fff; + color: #7f8fa6; + } + } + } + +} \ No newline at end of file diff --git a/style/main.scss b/style/main.scss index 94e01d0..6e61580 100644 --- a/style/main.scss +++ b/style/main.scss @@ -10,6 +10,7 @@ @import 'personal.scss'; @import 'upload.scss'; @import 'addArtist.scss'; +@import 'addAlbum.scss'; body { font-family: sans-serif; diff --git a/style/upload.scss b/style/upload.scss index 821bfd7..af84ef8 100644 --- a/style/upload.scss +++ b/style/upload.scss @@ -91,6 +91,41 @@ border: 2px solid #fff; } } + .release-date { + margin-top: 1rem; + font-size: 1.2rem; + color: #7f8fa6; + font-family: "Roboto", sans-serif; + display: flex; + align-items: center; + .left { + display: flex; + flex-direction: column; + margin-left: 5px; + margin-right: 10px; + } + span { + font-size: .85rem; + } + input { + padding: 8px; + } + } + .file { + margin-top: .5rem; + display: flex; + align-items: center; + span { + font-size: .9rem; + color: #7f8fa6; + font-family: "Roboto", sans-serif; + margin-left: 5px; + margin-right: 10px; + } + input { + padding: 10px; + } + } .upload-button { position: absolute; bottom: 5px;