admin view
This commit is contained in:
parent
05139b19bc
commit
5b49586da3
@ -1,7 +1,5 @@
|
|||||||
use crate::services::confirm::ConfirmService;
|
|
||||||
use crate::services::rest::RestService;
|
use crate::services::rest::RestService;
|
||||||
use common::Achievement;
|
use common::Achievement;
|
||||||
use common::DeleteAchievement;
|
|
||||||
use common::ToggleAchievement;
|
use common::ToggleAchievement;
|
||||||
use wasm_bindgen_futures::spawn_local;
|
use wasm_bindgen_futures::spawn_local;
|
||||||
use yew::classes;
|
use yew::classes;
|
||||||
@ -38,20 +36,6 @@ pub fn AchievementComponent(props: &Props) -> Html {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
let onclick_delete = Callback::from(move |_| {
|
|
||||||
if !ConfirmService::confirm("Are you sure you want to delete?") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
log::info!("Delete achievement confirmed.");
|
|
||||||
|
|
||||||
spawn_local(async move {
|
|
||||||
match RestService::delete_achievement(DeleteAchievement { uuid }).await {
|
|
||||||
Ok(_response) => {}
|
|
||||||
Err(_err) => {}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
let toggle_button_class = if *completed {
|
let toggle_button_class = if *completed {
|
||||||
"button-primary color-secondary"
|
"button-primary color-secondary"
|
||||||
} else {
|
} else {
|
||||||
@ -69,9 +53,6 @@ pub fn AchievementComponent(props: &Props) -> Html {
|
|||||||
<div class="flex-grow">
|
<div class="flex-grow">
|
||||||
<p>{goal}</p>
|
<p>{goal}</p>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex-intrinsic-size">
|
|
||||||
<button onclick={onclick_delete} class="button narrow color-danger"><i class="fas fa-trash"/></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,125 +0,0 @@
|
|||||||
use crate::services::rest::RestService;
|
|
||||||
use common::Achievement;
|
|
||||||
use common::UpdateAchievementTimeOfReveal;
|
|
||||||
use wasm_bindgen::JsCast;
|
|
||||||
use wasm_bindgen_futures::spawn_local;
|
|
||||||
use yew::function_component;
|
|
||||||
use yew::html;
|
|
||||||
use yew::use_state;
|
|
||||||
use yew::Callback;
|
|
||||||
use yew::Html;
|
|
||||||
use yew::Properties;
|
|
||||||
|
|
||||||
#[derive(Properties, PartialEq)]
|
|
||||||
pub struct Props {
|
|
||||||
pub achievement: Achievement,
|
|
||||||
pub number: usize,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[function_component]
|
|
||||||
pub fn AchievementRevealTime(props: &Props) -> Html {
|
|
||||||
let achievement = &props.achievement;
|
|
||||||
let uuid = achievement.uuid;
|
|
||||||
|
|
||||||
let time_of_reveal: Option<String> = achievement
|
|
||||||
.time_of_reveal
|
|
||||||
.map(|naive_time| naive_time.format("%H:%M").to_string());
|
|
||||||
|
|
||||||
let timed_reveal_enabled = use_state(|| time_of_reveal.is_some());
|
|
||||||
let input_time = use_state(|| time_of_reveal.clone().unwrap_or("".to_string()));
|
|
||||||
let awaiting_response = use_state(|| false);
|
|
||||||
|
|
||||||
let onsubmit = {
|
|
||||||
let awaiting_response = awaiting_response.clone();
|
|
||||||
let timed_reveal_enabled = timed_reveal_enabled.clone();
|
|
||||||
let input_time = input_time.clone();
|
|
||||||
Callback::from(move |e: web_sys::SubmitEvent| {
|
|
||||||
e.prevent_default();
|
|
||||||
|
|
||||||
let new_time_of_reveal = if *timed_reveal_enabled {
|
|
||||||
if let Ok(naive_time) = chrono::NaiveTime::parse_from_str(&input_time, "%H:%M") {
|
|
||||||
Some(naive_time)
|
|
||||||
} else {
|
|
||||||
// TODO: show UI error
|
|
||||||
log::debug!("Could not parse time: {}", *input_time);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
let payload = UpdateAchievementTimeOfReveal {
|
|
||||||
time_of_reveal: new_time_of_reveal,
|
|
||||||
uuid,
|
|
||||||
};
|
|
||||||
awaiting_response.set(true);
|
|
||||||
let awaiting_response = awaiting_response.clone();
|
|
||||||
spawn_local(async move {
|
|
||||||
let res = RestService::update_time_of_reveal(payload).await;
|
|
||||||
awaiting_response.set(false);
|
|
||||||
});
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
let oninput_time = {
|
|
||||||
let input_time = input_time.clone();
|
|
||||||
Callback::from(move |e: web_sys::InputEvent| {
|
|
||||||
let Some(input) = e
|
|
||||||
.target()
|
|
||||||
.and_then(|t| t.dyn_into::<web_sys::HtmlInputElement>().ok()) else { unreachable!() };
|
|
||||||
log::debug!("{:?}", input.value());
|
|
||||||
input_time.set(input.value());
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
let oninput_timed_reveal_checkbox = {
|
|
||||||
let timed_reveal_enabled = timed_reveal_enabled.clone();
|
|
||||||
Callback::from(move |e: web_sys::InputEvent| {
|
|
||||||
let Some(input) = e
|
|
||||||
.target()
|
|
||||||
.and_then(|t| t.dyn_into::<web_sys::HtmlInputElement>().ok()) else { unreachable!() };
|
|
||||||
timed_reveal_enabled.set(input.checked());
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
let new_value: Option<&str> = timed_reveal_enabled.then_some(&**input_time);
|
|
||||||
let show_submit_button: bool = time_of_reveal.as_deref() != new_value;
|
|
||||||
|
|
||||||
html! {
|
|
||||||
<form {onsubmit}>
|
|
||||||
|
|
||||||
<div class="row flex">
|
|
||||||
// Achievement number
|
|
||||||
<div class="flex-intrinsic-size">
|
|
||||||
<p>{format!("{}.", props.number)}</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
// Achievement text
|
|
||||||
<div class="flex-grow">
|
|
||||||
<p>{&achievement.goal}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
// Enable timed reveal checkbox
|
|
||||||
<label class="row">
|
|
||||||
<input oninput={oninput_timed_reveal_checkbox} checked={*timed_reveal_enabled} type="checkbox" />
|
|
||||||
<span class="label-body">{"Timed reveal"}</span>
|
|
||||||
</label>
|
|
||||||
|
|
||||||
{ if *timed_reveal_enabled { html! {
|
|
||||||
// Time input
|
|
||||||
<div>
|
|
||||||
<label for="revealTimeInput">{"Reveal time"}</label>
|
|
||||||
<input oninput={oninput_time} value={(*input_time).clone()} type="time" id="revealTimeInput" />
|
|
||||||
</div>
|
|
||||||
}} else { html! {}}}
|
|
||||||
|
|
||||||
// Submit button
|
|
||||||
{ if show_submit_button { html! {
|
|
||||||
<input class="button-primary" type="submit" value="Submit" disabled={ *awaiting_response } />
|
|
||||||
}} else { html! {}}}
|
|
||||||
|
|
||||||
<hr />
|
|
||||||
</form>
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,32 +0,0 @@
|
|||||||
use crate::components::achievement_reveal_time::AchievementRevealTime;
|
|
||||||
use yew::functional::*;
|
|
||||||
use yew::prelude::*;
|
|
||||||
use yew_router::prelude::*;
|
|
||||||
|
|
||||||
#[function_component]
|
|
||||||
pub fn AchievementRevealTimes() -> Html {
|
|
||||||
let nav = use_navigator().expect("cannot get navigator");
|
|
||||||
let app_state = use_context::<crate::AppState>().expect("no app state ctx found");
|
|
||||||
|
|
||||||
let achievements = app_state
|
|
||||||
.state
|
|
||||||
.achievements
|
|
||||||
.iter()
|
|
||||||
.cloned()
|
|
||||||
.enumerate()
|
|
||||||
.map(|(idx, a)| (idx + 1, a))
|
|
||||||
.map(|(n, a)| {
|
|
||||||
html! {
|
|
||||||
<AchievementRevealTime number={n} achievement={a} />
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect::<Html>();
|
|
||||||
|
|
||||||
html! {
|
|
||||||
<>
|
|
||||||
<h1>{"Achievement Timed Reveals"}</h1>
|
|
||||||
<hr />
|
|
||||||
{achievements}
|
|
||||||
</>
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,7 +1,252 @@
|
|||||||
|
use crate::services::confirm::ConfirmService;
|
||||||
|
use crate::services::rest::RestService;
|
||||||
|
use common::DeleteAchievement;
|
||||||
|
use common::DeleteMilestone;
|
||||||
|
use common::UpdateAchievementTimeOfReveal;
|
||||||
|
use wasm_bindgen::JsCast;
|
||||||
|
use wasm_bindgen_futures::spawn_local;
|
||||||
|
use yew::function_component;
|
||||||
use yew::functional::*;
|
use yew::functional::*;
|
||||||
use yew::prelude::*;
|
use yew::html;
|
||||||
|
use yew::use_state;
|
||||||
|
use yew::Callback;
|
||||||
|
use yew::Html;
|
||||||
|
use yew::Properties;
|
||||||
|
use yew_router::prelude::use_navigator;
|
||||||
|
|
||||||
#[function_component(Admin)]
|
#[function_component]
|
||||||
pub fn admin() -> Html {
|
pub fn Admin() -> Html {
|
||||||
html! {}
|
let nav = use_navigator().expect("cannot get navigator");
|
||||||
|
let app_state = use_context::<crate::AppState>().expect("no app state ctx found");
|
||||||
|
|
||||||
|
let achievements = app_state
|
||||||
|
.state
|
||||||
|
.achievements
|
||||||
|
.iter()
|
||||||
|
.cloned()
|
||||||
|
.enumerate()
|
||||||
|
.map(|(idx, a)| (idx + 1, a))
|
||||||
|
.map(|(n, a)| {
|
||||||
|
html! {
|
||||||
|
<Achievement number={n} achievement={a} />
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect::<Html>();
|
||||||
|
|
||||||
|
let onclick_create_achievement = {
|
||||||
|
let nav = nav.clone();
|
||||||
|
Callback::from(move |_: web_sys::MouseEvent| {
|
||||||
|
nav.push(&crate::Route::CreateAchievement);
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
let onclick_create_milestone = Callback::from(move |_: web_sys::MouseEvent| {
|
||||||
|
nav.push(&crate::Route::CreateMilestone);
|
||||||
|
});
|
||||||
|
|
||||||
|
let mut milestones = app_state.state.milestones.clone();
|
||||||
|
milestones.sort_by_key(|m| m.goal);
|
||||||
|
let milestones = milestones
|
||||||
|
.into_iter()
|
||||||
|
.map(|m| html! { <Milestone milestone={m}/> })
|
||||||
|
.collect::<Html>();
|
||||||
|
|
||||||
|
html! {
|
||||||
|
<>
|
||||||
|
<h1>{"Admin View"}</h1>
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<div class="row flex flex-wrap">
|
||||||
|
<div class="flex-grow">
|
||||||
|
<h3>{"Milestones"}</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex-intrinsic-size">
|
||||||
|
<button onclick={onclick_create_milestone} class="button-primary">{"New"}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{milestones}
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
|
||||||
|
<div class="row flex flex-wrap">
|
||||||
|
<div class="flex-grow">
|
||||||
|
<h3>{"Achievements"}</h3>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex-intrinsic-size">
|
||||||
|
<button onclick={onclick_create_achievement} class="button-primary">{"New"}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{achievements}
|
||||||
|
</>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Properties, PartialEq)]
|
||||||
|
struct AchievementProps {
|
||||||
|
achievement: common::Achievement,
|
||||||
|
number: usize,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
fn Achievement(props: &AchievementProps) -> Html {
|
||||||
|
let achievement = &props.achievement;
|
||||||
|
let uuid = achievement.uuid;
|
||||||
|
|
||||||
|
let time_of_reveal: Option<String> = achievement
|
||||||
|
.time_of_reveal
|
||||||
|
.map(|naive_time| naive_time.format("%H:%M").to_string());
|
||||||
|
|
||||||
|
let timed_reveal_enabled = use_state(|| time_of_reveal.is_some());
|
||||||
|
let input_time = use_state(|| time_of_reveal.clone().unwrap_or("".to_string()));
|
||||||
|
let awaiting_response = use_state(|| false);
|
||||||
|
|
||||||
|
let onsubmit_timed_reveal = {
|
||||||
|
let awaiting_response = awaiting_response.clone();
|
||||||
|
let timed_reveal_enabled = timed_reveal_enabled.clone();
|
||||||
|
let input_time = input_time.clone();
|
||||||
|
Callback::from(move |e: web_sys::SubmitEvent| {
|
||||||
|
e.prevent_default();
|
||||||
|
|
||||||
|
let new_time_of_reveal = if *timed_reveal_enabled {
|
||||||
|
if let Ok(naive_time) = chrono::NaiveTime::parse_from_str(&input_time, "%H:%M") {
|
||||||
|
Some(naive_time)
|
||||||
|
} else {
|
||||||
|
// TODO: show UI error
|
||||||
|
log::debug!("Could not parse time: {}", *input_time);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
let payload = UpdateAchievementTimeOfReveal {
|
||||||
|
time_of_reveal: new_time_of_reveal,
|
||||||
|
uuid,
|
||||||
|
};
|
||||||
|
awaiting_response.set(true);
|
||||||
|
let awaiting_response = awaiting_response.clone();
|
||||||
|
spawn_local(async move {
|
||||||
|
let res = RestService::update_time_of_reveal(payload).await;
|
||||||
|
awaiting_response.set(false);
|
||||||
|
});
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
let oninput_time = {
|
||||||
|
let input_time = input_time.clone();
|
||||||
|
Callback::from(move |e: web_sys::InputEvent| {
|
||||||
|
let Some(input) = e
|
||||||
|
.target()
|
||||||
|
.and_then(|t| t.dyn_into::<web_sys::HtmlInputElement>().ok()) else { unreachable!() };
|
||||||
|
log::debug!("{:?}", input.value());
|
||||||
|
input_time.set(input.value());
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
let oninput_timed_reveal_checkbox = {
|
||||||
|
let timed_reveal_enabled = timed_reveal_enabled.clone();
|
||||||
|
Callback::from(move |e: web_sys::InputEvent| {
|
||||||
|
let Some(input) = e
|
||||||
|
.target()
|
||||||
|
.and_then(|t| t.dyn_into::<web_sys::HtmlInputElement>().ok()) else { unreachable!() };
|
||||||
|
timed_reveal_enabled.set(input.checked());
|
||||||
|
})
|
||||||
|
};
|
||||||
|
|
||||||
|
let onclick_delete = Callback::from(move |_| {
|
||||||
|
if !ConfirmService::confirm("Are you sure you want to delete?") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
log::info!("Delete achievement confirmed.");
|
||||||
|
|
||||||
|
spawn_local(async move {
|
||||||
|
match RestService::delete_achievement(DeleteAchievement { uuid }).await {
|
||||||
|
Ok(_response) => {}
|
||||||
|
Err(_err) => {}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
let new_value: Option<&str> = timed_reveal_enabled.then_some(&**input_time);
|
||||||
|
let show_submit_button: bool = time_of_reveal.as_deref() != new_value;
|
||||||
|
|
||||||
|
html! {
|
||||||
|
<div>
|
||||||
|
<div class="row flex">
|
||||||
|
// Achievement number
|
||||||
|
<div class="flex-intrinsic-size">
|
||||||
|
<p>{format!("{}.", props.number)}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
// Achievement text
|
||||||
|
<div class="flex-grow">
|
||||||
|
<p>{&achievement.goal}</p>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
// Delete button
|
||||||
|
<button onclick={onclick_delete} class="flex-intrinsic-size button narrow color-danger"><i class="fas fa-trash" style="padding-right: 0.5em"/>{"Delete"}</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
// Timed reveal form
|
||||||
|
<form onsubmit={onsubmit_timed_reveal}>
|
||||||
|
// Timed reveal: Enable checkbox
|
||||||
|
<label>
|
||||||
|
<span class="label-body" style="margin-right: 0.5rem; font-weight: bold"><i class="fas fa-clock" style="padding-right: 0.5em"/>{"Enable Timed Reveal:"}</span>
|
||||||
|
<input oninput={oninput_timed_reveal_checkbox} checked={*timed_reveal_enabled} type="checkbox" />
|
||||||
|
</label>
|
||||||
|
|
||||||
|
<div class="row flex">
|
||||||
|
// Time input
|
||||||
|
{ if *timed_reveal_enabled { html! {
|
||||||
|
<div>
|
||||||
|
<label for="revealTimeInput">{"Reveal time"}</label>
|
||||||
|
<input oninput={oninput_time} value={(*input_time).clone()} type="time" id="revealTimeInput" />
|
||||||
|
</div>
|
||||||
|
}} else { html! {}}}
|
||||||
|
|
||||||
|
// Timed reveal form submit button
|
||||||
|
{ if show_submit_button { html! {
|
||||||
|
<input class="button-primary" type="submit" value="Update" disabled={ *awaiting_response } />
|
||||||
|
}} else { html! {}}}
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
|
||||||
|
|
||||||
|
<hr />
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[function_component]
|
||||||
|
fn Milestone(props: &MilestoneProps) -> Html {
|
||||||
|
let uuid = props.milestone.uuid;
|
||||||
|
let onclick_delete = Callback::from(move |_| {
|
||||||
|
if !ConfirmService::confirm("Are you sure you want to delete?") {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
spawn_local(async move {
|
||||||
|
match RestService::delete_milestone(DeleteMilestone { uuid }).await {
|
||||||
|
Ok(_response) => {}
|
||||||
|
Err(_err) => {}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
html! {
|
||||||
|
<div class="row flex">
|
||||||
|
<p class="flex-grow">{format!("Goal: {} achievements", props.milestone.goal)}</p>
|
||||||
|
|
||||||
|
<div class="flex-intrinsic-size">
|
||||||
|
<button onclick={onclick_delete} class="button narrow color-danger"><i style="margin-right: 0.5em" class="fas fa-trash"/>{"Delete"}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#[derive(Properties, Clone, PartialEq)]
|
||||||
|
struct MilestoneProps {
|
||||||
|
milestone: common::Milestone,
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,4 @@
|
|||||||
use crate::services::confirm::ConfirmService;
|
|
||||||
use crate::services::rest::RestService;
|
|
||||||
use common::DeleteMilestone;
|
|
||||||
use common::Milestone;
|
use common::Milestone;
|
||||||
use wasm_bindgen_futures::spawn_local;
|
|
||||||
use yew::prelude::*;
|
use yew::prelude::*;
|
||||||
|
|
||||||
#[derive(Properties, Clone, PartialEq)]
|
#[derive(Properties, Clone, PartialEq)]
|
||||||
@ -28,21 +24,6 @@ pub fn milestone_component(props: &Props) -> Html {
|
|||||||
.take(filled)
|
.take(filled)
|
||||||
.collect::<Html>();
|
.collect::<Html>();
|
||||||
|
|
||||||
let uuid = props.milestone.uuid;
|
|
||||||
let onclick_delete = Callback::from(move |_| {
|
|
||||||
if !ConfirmService::confirm("Are you sure you want to delete?") {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
log::info!("Delete achievement confirmed.");
|
|
||||||
|
|
||||||
spawn_local(async move {
|
|
||||||
match RestService::delete_milestone(DeleteMilestone { uuid }).await {
|
|
||||||
Ok(_response) => {}
|
|
||||||
Err(_err) => {}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
html! {
|
html! {
|
||||||
<div class="row flex">
|
<div class="row flex">
|
||||||
<p style="text-align: center" class="flex-grow">
|
<p style="text-align: center" class="flex-grow">
|
||||||
@ -73,9 +54,6 @@ pub fn milestone_component(props: &Props) -> Html {
|
|||||||
{filled_stars}
|
{filled_stars}
|
||||||
{unfilled_stars}
|
{unfilled_stars}
|
||||||
</p>
|
</p>
|
||||||
<div class="flex-intrinsic-size">
|
|
||||||
<button onclick={onclick_delete} class="button narrow color-danger"><i class="fas fa-trash"/></button>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
pub mod achievement;
|
pub mod achievement;
|
||||||
pub mod achievement_reveal_time;
|
|
||||||
pub mod achievement_reveal_times;
|
|
||||||
pub mod admin;
|
pub mod admin;
|
||||||
pub mod create_achievement;
|
pub mod create_achievement;
|
||||||
pub mod create_milestone;
|
pub mod create_milestone;
|
||||||
|
@ -10,17 +10,6 @@ pub fn Root() -> Html {
|
|||||||
let nav = use_navigator().expect("cannot get navigator");
|
let nav = use_navigator().expect("cannot get navigator");
|
||||||
let app_state = use_context::<crate::AppState>().expect("no app state ctx found");
|
let app_state = use_context::<crate::AppState>().expect("no app state ctx found");
|
||||||
|
|
||||||
let onclick_create_achievement = {
|
|
||||||
let nav = nav.clone();
|
|
||||||
Callback::from(move |_: web_sys::MouseEvent| {
|
|
||||||
nav.push(&crate::Route::CreateAchievement);
|
|
||||||
})
|
|
||||||
};
|
|
||||||
|
|
||||||
let onclick_create_milestone = Callback::from(move |_: web_sys::MouseEvent| {
|
|
||||||
nav.push(&crate::Route::CreateMilestone);
|
|
||||||
});
|
|
||||||
|
|
||||||
let current_time: chrono::NaiveTime = chrono::Local::now().time();
|
let current_time: chrono::NaiveTime = chrono::Local::now().time();
|
||||||
|
|
||||||
let achievements = app_state.state.achievements.clone();
|
let achievements = app_state.state.achievements.clone();
|
||||||
@ -76,11 +65,7 @@ pub fn Root() -> Html {
|
|||||||
<hr />
|
<hr />
|
||||||
<div class="row flex flex-wrap">
|
<div class="row flex flex-wrap">
|
||||||
<div class="flex-grow">
|
<div class="flex-grow">
|
||||||
<h3>{"Milestones"}</h3>
|
<h3><i style="margin-right: 0.5em" class="fas fa-trophy" />{"Milestones"}</h3>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex-intrinsic-size">
|
|
||||||
<button onclick={onclick_create_milestone} class="button-primary">{"New"}</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{milestones}
|
{milestones}
|
||||||
@ -88,11 +73,7 @@ pub fn Root() -> Html {
|
|||||||
<hr />
|
<hr />
|
||||||
<div class="row flex flex-wrap">
|
<div class="row flex flex-wrap">
|
||||||
<div class="flex-grow">
|
<div class="flex-grow">
|
||||||
<h3>{"Achievements"}</h3>
|
<h3><i style="margin-right: 0.5em" class="fas fa-star" />{"Achievements"}</h3>
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex-intrinsic-size">
|
|
||||||
<button onclick={onclick_create_achievement} class="button-primary">{"New"}</button>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{achievements}
|
{achievements}
|
||||||
|
@ -2,7 +2,6 @@ use crate::components::error::error_component::ErrorComponent;
|
|||||||
use crate::components::error::error_provider::ErrorProvider;
|
use crate::components::error::error_provider::ErrorProvider;
|
||||||
use crate::event_bus::EventBus;
|
use crate::event_bus::EventBus;
|
||||||
use crate::services::websocket::WebsocketService;
|
use crate::services::websocket::WebsocketService;
|
||||||
use components::achievement_reveal_times::AchievementRevealTimes;
|
|
||||||
use components::admin::Admin;
|
use components::admin::Admin;
|
||||||
use components::create_achievement::CreateAchievementComponent;
|
use components::create_achievement::CreateAchievementComponent;
|
||||||
use components::create_milestone::CreateMilestoneComponent;
|
use components::create_milestone::CreateMilestoneComponent;
|
||||||
@ -23,14 +22,12 @@ pub mod util;
|
|||||||
enum Route {
|
enum Route {
|
||||||
#[at("/")]
|
#[at("/")]
|
||||||
Root,
|
Root,
|
||||||
#[at("/chat")]
|
|
||||||
Admin,
|
|
||||||
#[at("/create-achievement")]
|
#[at("/create-achievement")]
|
||||||
CreateAchievement,
|
CreateAchievement,
|
||||||
#[at("/create-milestone")]
|
#[at("/create-milestone")]
|
||||||
CreateMilestone,
|
CreateMilestone,
|
||||||
#[at("/reveal-times")]
|
#[at("/en-lille-nisse-rejste")]
|
||||||
RevealTimes,
|
Admin,
|
||||||
#[not_found]
|
#[not_found]
|
||||||
#[at("/404")]
|
#[at("/404")]
|
||||||
NotFound,
|
NotFound,
|
||||||
@ -43,7 +40,6 @@ fn switch(selected_route: Route) -> Html {
|
|||||||
Route::CreateAchievement => html! {<CreateAchievementComponent/>},
|
Route::CreateAchievement => html! {<CreateAchievementComponent/>},
|
||||||
Route::CreateMilestone => html! {<CreateMilestoneComponent/>},
|
Route::CreateMilestone => html! {<CreateMilestoneComponent/>},
|
||||||
Route::NotFound => html! {<h1>{"404 not found"}</h1>},
|
Route::NotFound => html! {<h1>{"404 not found"}</h1>},
|
||||||
Route::RevealTimes => html! {<AchievementRevealTimes/>},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user