add links

This commit is contained in:
Romulus21
2024-11-06 15:55:35 +01:00
parent bd48522b66
commit c8c35bde09
6 changed files with 148 additions and 13 deletions

View File

@@ -0,0 +1 @@
DROP TABLE IF EXISTS `links`;

View File

@@ -0,0 +1,7 @@
CREATE TABLE IF NOT EXISTS links (
id BIGINT UNSIGNED PRIMARY KEY NOT NULL AUTO_INCREMENT,
name TEXT NOT NULL,
link TEXT NOT NULL,
position BIGINT NOT NULL DEFAULT 1,
created_at DATETIME NOT NULL
);

View File

@@ -2,7 +2,40 @@ use serde::{Deserialize, Serialize};
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct Link {
id: u16,
link: String,
name: String,
id: u64,
pub link: String,
pub name: String,
position: i64,
created_at: String,
}
impl Link {
#[cfg(feature = "ssr")]
pub async fn insert(
name: String,
link: String,
) -> Result<sqlx::mysql::MySqlQueryResult, sqlx::Error> {
sqlx::query!(
"INSERT INTO links (name, link, position, created_at) VALUES (?, ?, (SELECT COALESCE(MAX(position) + 1, 1) FROM links lin), ?)",
name,
link,
chrono::Local::now().naive_local(),
)
.execute(crate::database::get_db())
.await
}
#[cfg(feature = "ssr")]
pub async fn get_all() -> Result<Vec<Self>, sqlx::Error> {
sqlx::query!("SELECT id, name, link, position, created_at FROM links ORDER BY position")
.map(|x| Self {
id: x.id,
name: x.name,
link: x.link,
position: x.position,
created_at: x.created_at.format("%d/%m/%Y %H:%M").to_string(),
})
.fetch_all(crate::database::get_db())
.await
}
}

View File

@@ -1,4 +1,5 @@
mod link;
mod value;
pub use link::Link;
pub use value::Value;
pub use value::OPTIONS;

View File

@@ -1,23 +1,108 @@
use leptos::*;
//use leptos_meta::*;
//use leptos_router::*;
use leptos_router::*;
#[server(GetLinksAction, "/api", "GetJson")]
#[tracing::instrument]
pub async fn get_links() -> Result<Vec<crate::models::Link>, ServerFnError> {
crate::models::Link::get_all().await.map_err(|x| {
let err = format!("Error while posting a link: {x:?}");
tracing::error!("{err}");
ServerFnError::ServerError("Could not post a link, try again later".into())
})
}
#[server(LinkAction, "/api")]
pub async fn add_value(name: String, link: String) -> Result<(), ServerFnError> {
crate::models::Link::insert(name, link)
.await
.map(|_| ())
.map_err(|x| {
let err = format!("Error while posting a comment: {x:?}");
tracing::error!("{err}");
ServerFnError::ServerError("Could not post a comment, try again later".into())
})
}
#[component]
pub fn Links() -> impl IntoView {
let (show, set_show) = create_signal(false);
let link_action = create_server_action::<LinkAction>();
let result = link_action.version();
let reset_form = create_rw_signal("");
let links = create_resource(
move || (result.get()),
move |_| async move {
reset_form.set("");
set_show.set(false);
get_links().await
},
);
let form = move || {
show.get().then(|| {
view! { <div class="my-0 mx-auto w-72 text-center">
<h2 class="p-6 text-4xl">"Ajout d'un lien"</h2>
<ActionForm action=link_action attr:class="border border-lime-500">
<div>
<label class="block mt-3 mb-1">"Nom"</label>
<input type="text"
name="name"
prop:value=move || reset_form.get()
class="text-center dark:bg-slate-800 focus:border-lime-500 dark:text-white px-2 py-2 w-60" />
</div>
<div>
<label class="block mt-3 mb-1">"Lien"</label>
<input type="url"
name="link"
prop:value=move || reset_form.get()
class="text-center dark:bg-slate-800 focus:border-lime-500 dark:text-white px-2 py-2 w-60" />
</div>
<div>
<button type="submit" class="bg-lime-500 hover:bg-lime-400 text-black px-2 py-1 w-60 my-5">"Valider"</button>
</div>
</ActionForm>
</div> }
})
};
view! {
<ul class="flex gap-5 mt-5 justify-center">
<Link link="aa".to_string() name="Mon Lien".to_string() />
<Link link="aa".to_string() name="mon lien 2".to_string() />
<Link link="aa".to_string() name="mon lien 3".to_string() />
<Suspense fallback=move || view! {<p>"Loading Comments from the article"</p> }>
<ErrorBoundary fallback=|_| {
view! { <p class="error-messages text-xs-center">"Something went wrong."</p>}
}>
{move || links.get().map(move |x| x.map(move |c| {
view! {
<For each=move || c.clone().into_iter().enumerate()
key=|(i, _)| *i
children=move |(_, link)| {
let link = create_rw_signal(link);
view!{<Link link />}
}/>
}
}))}
</ErrorBoundary>
</Suspense>
</ul>
<div>
<button on:click=move |_| {set_show.set(true)}>"Add"</button>
{form}
</div>
}
}
#[component]
fn Link(link: String, name: String) -> impl IntoView {
fn Link(link: RwSignal<crate::models::Link>) -> impl IntoView {
view! {
<li>
<a class="border border-lime-500 bg-lime-500 hover:bg-lime-400 text-black px-3 py-2 inline-block" href=link>{name}</a>
<a class="border border-lime-500 bg-lime-500 hover:bg-lime-400 text-black px-3 py-2 inline-block"
target="_blank"
href={move || link.with(|x| x.link.to_string())}>
{move || link.with(|x| x.name.to_string())}
</a>
</li>
}
}

View File

@@ -19,8 +19,14 @@ pub async fn add_value(device: String, value: String) -> Result<(), ServerFnErro
#[component]
pub fn FormValues() -> impl IntoView {
let value_action = create_server_action::<ValueAction>();
//let value = value_action.value();
//let has_error = move || value.with(|val| matches!(val, Some(Err(_))));
let result = value_action.version();
let reset_value = create_rw_signal("");
let _ = create_resource(
move || (result.get()),
move |_| async move {
reset_value.set("");
},
);
view! {
<div class="my-0 mx-auto w-72 text-center">
@@ -37,7 +43,9 @@ pub fn FormValues() -> impl IntoView {
</div>
<div>
<label class="block mt-3 mb-1">Valeur</label>
<input type="text" name="value" type="number"
<input name="value"
type="number"
prop:value=move || reset_value.get()
class="text-center dark:bg-slate-800 focus:border-lime-500 dark:text-white px-2 py-2 w-60" />
</div>
<div>