diff --git a/frontend/src/components/paginate_navbar.rs b/frontend/src/components/paginate_navbar.rs
index 7e670be..a36334a 100644
--- a/frontend/src/components/paginate_navbar.rs
+++ b/frontend/src/components/paginate_navbar.rs
@@ -70,8 +70,7 @@ fn PaginateNavbarButton(
#[prop(into)] page: ParamsMapKey,
) -> impl IntoView {
let query_map = use_query_map();
- let href =
- query_map.with_key_map(move |map| map.set_key(page, Some(i())));
+ let href = query_map.with_key_map(move |map| map.set_key(page, Some(i())));
let page = query_map.use_key_with_default(page);
let disabled = create_memo(move |_| page() == i());
view! {
diff --git a/frontend/src/components/paginate_table.rs b/frontend/src/components/paginate_table.rs
index a593065..8532933 100644
--- a/frontend/src/components/paginate_table.rs
+++ b/frontend/src/components/paginate_table.rs
@@ -25,8 +25,7 @@ where
};
let mut query_map = query_map.get_untracked();
if s == query_map.get_key_with_default(sort) {
- let toggle_order = match query_map.get_key_with_default(order)
- {
+ let toggle_order = match query_map.get_key_with_default(order) {
grpc::Order::Ascend => grpc::Order::Descend,
grpc::Order::Descend => grpc::Order::Ascend,
};
diff --git a/frontend/src/components/toast.rs b/frontend/src/components/toast.rs
index 8707c93..3ac3ca5 100644
--- a/frontend/src/components/toast.rs
+++ b/frontend/src/components/toast.rs
@@ -104,10 +104,7 @@ fn Toast(
stop,
is_pending,
..
- } = {
- let close = close;
- use_timeout_fn(move |_| close(), 4.0 * 1000.0)
- };
+ } = { use_timeout_fn(move |_| close(), 4.0 * 1000.0) };
let node_ref = create_node_ref::();
let hover = use_element_hover(node_ref);
diff --git a/frontend/src/pages/mod.rs b/frontend/src/pages/mod.rs
index 432ded9..2e6ec14 100644
--- a/frontend/src/pages/mod.rs
+++ b/frontend/src/pages/mod.rs
@@ -1,12 +1,96 @@
mod about;
+mod contest;
mod contests;
mod create;
mod home;
mod login;
-mod pages;
mod problem;
mod problems;
mod rank;
mod submission;
-mod contest;
-pub use pages::*;
+
+use about::About;
+use contest::Contest;
+use contests::Contests;
+use home::Home;
+use leptos::*;
+use leptos_router::*;
+use leptos_use::*;
+use login::Login;
+use problem::ProblemRouter;
+use problems::Problems;
+use rank::Rank;
+use submission::Submission;
+
+use crate::{components::*, utils::*};
+
+/// |Permission|Root|Admin|SuperUser|User|Guest
+/// |:-|:-:|:-:|:-:|:-:|:-:|
+/// |Register User|/|/|/|/|/|
+/// |Join *any* Contest|V||||
+/// |Create Admin|V||||
+/// |Create SuperUser|V|V|||
+/// |Create User|V|V|||
+/// |Create Announcement for Contest|V|V|||
+/// |Create/Publish Announcement|V|V|||
+/// |Create/Publish Problem|V|V|V||
+/// |Create/Publish Contest|V|V|V||
+/// |Submit Problem|V|V|V|V|
+/// > `/` 代表看 backend config
+#[component]
+pub fn Pages() -> impl IntoView {
+ let token = use_token();
+ let role = use_role();
+ let can_create_problem_or_contest = move || {
+ role().is_some_and(|role| match role {
+ grpc::Role::User => false,
+ grpc::Role::Super | grpc::Role::Admin | grpc::Role::Root => true,
+ })
+ };
+
+ let show_footer = move || {
+ !use_location()
+ .pathname
+ .with(|path| path.starts_with("/problem/"))
+ };
+ let page_wrapper = move || {
+ view! {
+
+
+
+
+
+ }
+ };
+
+ view! {
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ // Fallback
+
+
+
+ }
+}
diff --git a/frontend/src/pages/pages.rs b/frontend/src/pages/pages.rs
deleted file mode 100644
index 8063ce6..0000000
--- a/frontend/src/pages/pages.rs
+++ /dev/null
@@ -1,81 +0,0 @@
-use leptos::*;
-use leptos_router::*;
-use leptos_use::*;
-
-use super::{
- about::About, contest::Contest, contests::Contests, create, home::Home,
- login::Login, problem::ProblemRouter, problems::Problems, rank::Rank,
- submission::Submission,
-};
-use crate::{components::*, utils::*};
-
-/// |Permission|Root|Admin|SuperUser|User|Guest
-/// |:-|:-:|:-:|:-:|:-:|:-:|
-/// |Register User|/|/|/|/|/|
-/// |Join *any* Contest|V||||
-/// |Create Admin|V||||
-/// |Create SuperUser|V|V|||
-/// |Create User|V|V|||
-/// |Create Announcement for Contest|V|V|||
-/// |Create/Publish Announcement|V|V|||
-/// |Create/Publish Problem|V|V|V||
-/// |Create/Publish Contest|V|V|V||
-/// |Submit Problem|V|V|V|V|
-/// > `/` 代表看 backend config
-#[component]
-pub fn Pages() -> impl IntoView {
- let token = use_token();
- let role = use_role();
- let can_create_problem_or_contest = move || {
- role().is_some_and(|role| match role {
- grpc::Role::User => false,
- grpc::Role::Super | grpc::Role::Admin | grpc::Role::Root => true,
- })
- };
-
- let show_footer = move || {
- !use_location()
- .pathname
- .with(|path| path.starts_with("/problem/"))
- };
- let page_wrapper = move || {
- view! {
-
-
-
-
-
- }
- };
-
- view! {
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- // Fallback
-
-
-
- }
-}
diff --git a/frontend/src/pages/problem/mod.rs b/frontend/src/pages/problem/mod.rs
index ab14aa4..91efbda 100644
--- a/frontend/src/pages/problem/mod.rs
+++ b/frontend/src/pages/problem/mod.rs
@@ -2,11 +2,150 @@ mod content;
mod discussion;
mod editor;
mod education;
-mod problem;
mod submission;
pub use content::ProblemContent;
pub use discussion::ProblemDiscussion;
pub use editor::ProblemEditor;
pub use education::ProblemEducation;
-pub use problem::ProblemRouter;
+use leptos::*;
+use leptos_icons::*;
+use leptos_router::*;
pub use submission::ProblemSubmission;
+
+use crate::{components::*, utils::*};
+
+#[derive(Params, PartialEq, Clone, Copy)]
+struct ProblemParams {
+ id: i32,
+}
+
+#[component(transparent)]
+pub fn ProblemRouter() -> impl IntoView {
+ view! {
+
+
+
+
+
+
+ }
+}
+
+#[component]
+fn Problem() -> impl IntoView {
+ let params = use_params::();
+ let token = use_token();
+
+ let langs = create_resource(
+ move || token.get_untracked(),
+ |token| {
+ let mut client =
+ grpc::submit_client::SubmitClient::new(grpc::new_client());
+ async move {
+ let langs =
+ client.list_lang(().with_optional_token(token)).await?;
+ Result::<_>::Ok(langs.into_inner())
+ }
+ },
+ );
+
+ let editor = move || {
+ langs().map(|v| {
+ v.map(|langs| {
+ let id = params()?.id;
+
+ Result::<_>::Ok(view! { })
+ })
+ })
+ };
+
+ view! {
+
+
+
+
+
+
+
+ loading }
+ }>
+ {editor}
+
+
+
+ }
+}
+
+#[component]
+fn VerticalNavbar() -> impl IntoView {
+ view! {
+
+
+ Problem
+
+
+ Education
+
+
+ Discussion
+
+
+ Submission
+
+
+ }
+}
+
+#[component]
+fn VerticalNavbarButton(
+ icon: icondata::Icon,
+ href: impl ToHref + 'static,
+ children: Children,
+) -> impl IntoView {
+ view! {
+
+
+
+
+
+ {children()}
+
+
+ }
+}
+
+#[component]
+fn Content() -> impl IntoView {
+ let params = use_params::();
+ let token = use_token();
+
+ let full_info = create_resource(
+ move || (params(), token()),
+ |(params, token)| {
+ let mut client =
+ grpc::problem_client::ProblemClient::new(grpc::new_client());
+ async move {
+ let id: grpc::Id = params?.id.into();
+ let full_info =
+ client.full_info(id.with_optional_token(token)).await?;
+ Result::<_>::Ok(full_info.into_inner())
+ }
+ },
+ );
+
+ let content = move || {
+ full_info().map(|v| {
+ v.map(|full_info| {
+ view! { }
+ })
+ })
+ };
+ view! {
+ loading
}
+ }>
+ {content}
+
+ }
+}
diff --git a/frontend/src/pages/problem/problem.rs b/frontend/src/pages/problem/problem.rs
deleted file mode 100644
index 27fabc5..0000000
--- a/frontend/src/pages/problem/problem.rs
+++ /dev/null
@@ -1,142 +0,0 @@
-use leptos::*;
-use leptos_icons::*;
-use leptos_router::*;
-
-use super::*;
-use crate::{components::*, utils::*};
-
-#[derive(Params, PartialEq, Clone, Copy)]
-struct ProblemParams {
- id: i32,
-}
-
-#[component(transparent)]
-pub fn ProblemRouter() -> impl IntoView {
- view! {
-
-
-
-
-
-
- }
-}
-
-#[component]
-fn Problem() -> impl IntoView {
- let params = use_params::();
- let token = use_token();
-
- let langs = create_resource(
- move || token.get_untracked(),
- |token| {
- let mut client =
- grpc::submit_client::SubmitClient::new(grpc::new_client());
- async move {
- let langs =
- client.list_lang(().with_optional_token(token)).await?;
- Result::<_>::Ok(langs.into_inner())
- }
- },
- );
-
- let editor = move || {
- langs().map(|v| {
- v.map(|langs| {
- let id = params()?.id;
-
- Result::<_>::Ok(view! { })
- })
- })
- };
-
- view! {
-
-
-
-
-
-
-
- loading }
- }>
- {editor}
-
-
-
- }
-}
-
-#[component]
-fn VerticalNavbar() -> impl IntoView {
- view! {
-
-
- Problem
-
-
- Education
-
-
- Discussion
-
-
- Submission
-
-
- }
-}
-
-#[component]
-fn VerticalNavbarButton(
- icon: icondata::Icon,
- href: impl ToHref + 'static,
- children: Children,
-) -> impl IntoView {
- view! {
-
-
-
-
-
- {children()}
-
-
- }
-}
-
-#[component]
-fn Content() -> impl IntoView {
- let params = use_params::();
- let token = use_token();
-
- let full_info = create_resource(
- move || (params(), token()),
- |(params, token)| {
- let mut client =
- grpc::problem_client::ProblemClient::new(grpc::new_client());
- async move {
- let id: grpc::Id = params?.id.into();
- let full_info =
- client.full_info(id.with_optional_token(token)).await?;
- Result::<_>::Ok(full_info.into_inner())
- }
- },
- );
-
- let content = move || {
- full_info().map(|v| {
- v.map(|full_info| {
- view! { }
- })
- })
- };
- view! {
- loading }
- }>
- {content}
-
- }
-}
diff --git a/frontend/src/utils/router.rs b/frontend/src/utils/router.rs
index 56b4234..6102a96 100644
--- a/frontend/src/utils/router.rs
+++ b/frontend/src/utils/router.rs
@@ -57,7 +57,7 @@ where
impl Clone for ParamsMapKey {
fn clone(&self) -> Self {
- Self(self.0)
+ *self
}
}
@@ -181,11 +181,8 @@ pub trait ParamsMapExtra {
where
T: ParamsMapValue;
- fn set_key(
- &mut self,
- query: ParamsMapKey,
- value: Option,
- ) where
+ fn set_key(&mut self, query: ParamsMapKey, value: Option)
+ where
T: ParamsMapValue;
fn to_url(&self) -> String;
@@ -203,8 +200,7 @@ impl ParamsMapExtra for ParamsMap {
where
T: ParamsMapValue,
{
- self.get_key(query)
- .unwrap_or_else(move || query.default())
+ self.get_key(query).unwrap_or_else(move || query.default())
}
fn set_key(&mut self, query: ParamsMapKey, value: Option)