diff --git a/src/app.rs b/src/app.rs
index 09b05f0..bb3064d 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -1,8 +1,10 @@
use crate::pages::{AboutPage, HomePage, ProviderPortal, ComparisonTestPage, ScholarshipInfoPage, TestPage, ProviderContactPage, LoanerShell, LoanerFallback, LoanerBorrowForm, LoanerReturnForm, AuthCallbackPage};
use leptos::prelude::*;
use leptos_meta::{MetaTags, Stylesheet, Title, provide_meta_context};
-use leptos_oidc::{Auth, AuthParameters, AuthSignal, Challenge};
-use leptos_router::{components::{Route, Router, Routes, ParentRoute}, path};
+use leptos_oidc::AuthSignal;
+use leptos_router::{components::{Route, Router, Routes, ParentRoute}, path, MatchNestedRoutes};
+use leptos_router::any_nested_route::IntoAnyNestedRoute;
+use crate::components::login::ProviderLoginContext;
use crate::components::ToastList;
pub fn shell(options: LeptosOptions) -> impl IntoView {
@@ -43,54 +45,15 @@ pub fn App() -> impl IntoView {
}
}
-fn use_origin() -> String {
- #[cfg(target_arch = "wasm32")] {
- use leptos::web_sys;
- // Just get the current URL origin.
- web_sys::window()
- .unwrap()
- .location()
- .origin()
- .unwrap_or("http://localhost:3000/".to_string())
- }
-
- #[cfg(not(target_arch = "wasm32"))] {
- // Read the expected origin out of an environment variable.
- std::env::var("LP_SITE_ORIGIN").unwrap_or("http://localhost:3000/".to_string())
- }
-}
-
#[component]
pub fn AppWithRoutes() -> impl IntoView {
provide_meta_context();
- let current_origin = use_origin();
-
- // Authentication setup
- let parameters = AuthParameters {
- issuer: "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_Lfjuy5zaM".into(),
- client_id: "10jr2h3vtpu9n7gj46pvg5qo2q".into(),
- redirect_uri: format!("{}/auth/callback", current_origin),
- post_logout_redirect_uri: current_origin,
- scope: Some("openid%20profile%20email".into()),
- audience: None,
- challenge: Challenge::None,
- };
-
- let auth = Auth::signal();
- provide_context(auth); // allows use of this signal in lower areas of the tree without
- // explicitly passing it through the html tree
-
- let _ = Auth::init(parameters);
-
view! {
// injects a stylesheet into the document
// id=leptos means cargo-leptos will hot-reload this stylesheet
- // "Authentication is loading"
- //
-
// sets the document title
@@ -99,27 +62,47 @@ pub fn AppWithRoutes() -> impl IntoView {
// TODO Create a 404 page
-
-
-
-
-
-
-
-
-
-
-
-
+
+
}
}
+#[component(transparent)]
+fn ProviderRoutes() -> impl MatchNestedRoutes + Clone {
+ view! {
+
+
+
+
+
+
+
+
+
+ }
+ .into_inner()
+ .into_any_nested_route()
+}
+
+#[component(transparent)]
+fn LoanerRoutes() -> impl MatchNestedRoutes + Clone {
+ view! {
+
+
+
+
+
+ }
+ .into_inner()
+ .into_any_nested_route()
+}
+
#[component]
pub fn AuthErrorView() -> impl IntoView {
let auth = use_context::().expect("AuthError: RwSignal was not found");
diff --git a/src/components/login/mod.rs b/src/components/login/mod.rs
new file mode 100644
index 0000000..fae50eb
--- /dev/null
+++ b/src/components/login/mod.rs
@@ -0,0 +1,5 @@
+mod provider;
+pub use provider::*;
+mod student;
+pub use student::*;
+pub(crate) mod setup;
\ No newline at end of file
diff --git a/src/components/login/provider.rs b/src/components/login/provider.rs
new file mode 100644
index 0000000..ce1fb6d
--- /dev/null
+++ b/src/components/login/provider.rs
@@ -0,0 +1,30 @@
+use leptos::prelude::*;
+use leptos_router::components::Outlet;
+use super::setup::provide_auth_context;
+
+///# Provider Login Context Component
+///
+/// This component handles providing context to the provider login information.
+/// It creates the corresponding [`AuthSignal`], specific to the student login page and redirects.
+///
+/// Example usage:
+/// ```
+/// view! {
+///
+/// // The rest of the student application. Don't forget AuthLoaded and
+/// // Authenticated components!
+///
+/// }
+#[component]
+pub fn ProviderLoginContext() -> impl IntoView {
+ provide_auth_context(
+ crate::utils::use_origin(),
+ "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_Lfjuy5zaM",
+ "56c2bqvl021rv8d5mq36blt7jv",
+ "/providers/callback"
+ );
+
+ view! {
+
+ }
+}
diff --git a/src/components/login/setup.rs b/src/components/login/setup.rs
new file mode 100644
index 0000000..a5ebae6
--- /dev/null
+++ b/src/components/login/setup.rs
@@ -0,0 +1,24 @@
+use leptos::prelude::*;
+use leptos_oidc::{Auth, AuthParameters, Challenge};
+
+pub fn provide_auth_context(
+ origin: String,
+ issuer: impl Into,
+ client_id: impl Into,
+ redirect_path: impl Into,
+) {
+ let params = AuthParameters {
+ issuer: issuer.into(),
+ client_id: client_id.into(),
+ redirect_uri: format!("{}{}", origin, redirect_path.into()),
+ post_logout_redirect_uri: origin,
+ scope: Some("openid%20profile%20email".into()),
+ audience: None,
+ challenge: Challenge::None,
+ };
+
+ let auth = Auth::signal();
+ provide_context(auth);
+
+ let _ = Auth::init(params);
+}
diff --git a/src/components/login/student.rs b/src/components/login/student.rs
new file mode 100644
index 0000000..f3b89df
--- /dev/null
+++ b/src/components/login/student.rs
@@ -0,0 +1,30 @@
+use leptos::prelude::*;
+use leptos_router::components::Outlet;
+use super::setup::provide_auth_context;
+
+///# Student Login Context Component
+///
+/// This component handles providing context to the student login information.
+/// It creates the corresponding [`AuthSignal`], specific to the student login page and redirects.
+///
+/// Example usage:
+/// ```
+/// view! {
+///
+/// // The rest of the student application. Don't forget AuthLoaded and
+/// // Authenticated components!
+///
+/// }
+#[component]
+pub fn StudentLoginContext() -> impl IntoView {
+ provide_auth_context(
+ crate::utils::use_origin(),
+ "https://cognito-idp.us-east-1.amazonaws.com/us-east-1_Lfjuy5zaM",
+ "10jr2h3vtpu9n7gj46pvg5qo2q",
+ "/students/callback"
+ );
+
+ view! {
+
+ }
+}
diff --git a/src/components/mod.rs b/src/components/mod.rs
index ade0f49..27d6b69 100644
--- a/src/components/mod.rs
+++ b/src/components/mod.rs
@@ -12,6 +12,7 @@ mod validated_form;
mod lists;
mod toasts;
mod header;
+pub mod login;
pub use self::{
action_button::*, banner::*, dashboard_button::*, lists::*,
diff --git a/src/lib.rs b/src/lib.rs
index 9958e9f..7ed69e6 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -2,6 +2,7 @@ pub mod app;
mod common;
mod components;
mod pages;
+mod utils;
#[cfg(feature = "hydrate")]
#[wasm_bindgen::prelude::wasm_bindgen]
diff --git a/src/pages/api/comparisons.rs b/src/pages/api/comparisons.rs
index b60acef..bd00cd2 100644
--- a/src/pages/api/comparisons.rs
+++ b/src/pages/api/comparisons.rs
@@ -1,6 +1,5 @@
-use std::collections::HashMap;
#[cfg(feature = "ssr")]
-use crate::pages::utils::server_utils::create_dynamo_client;
+use crate::utils::server::create_dynamo_client;
#[cfg(feature = "ssr")]
use aws_sdk_dynamodb::error::ProvideErrorMetadata;
@@ -12,6 +11,7 @@ use crate::common::{
ComparisonData, ComparisonType, MapListComparison, NumberComparison, NumberListComparison,
TextComparison, TextListComparison, ValueType,
};
+use std::collections::HashMap;
use leptos::prelude::ServerFnError;
use leptos::server;
diff --git a/src/pages/api/scholarships.rs b/src/pages/api/scholarships.rs
index aaf5d47..d4071d0 100644
--- a/src/pages/api/scholarships.rs
+++ b/src/pages/api/scholarships.rs
@@ -8,7 +8,7 @@ use leptos::leptos_dom::log;
#[cfg(feature = "ssr")]
use uuid::Uuid;
#[cfg(feature = "ssr")]
-use crate::pages::utils::server_utils::create_dynamo_client;
+use crate::utils::server::{create_dynamo_client, into_attr_map};
#[cfg(feature = "ssr")]
use crate::common::ValueType;
@@ -51,7 +51,6 @@ pub async fn get_scholarship_info(id: String) -> Result Result<(), ServerFnError> {
- use crate::pages::utils::server_utils::create_dynamo_client;
use aws_sdk_dynamodb::error::ProvideErrorMetadata;
let client = create_dynamo_client().await;
diff --git a/src/pages/comparison_test.rs b/src/pages/comparison_test.rs
index 57afa5a..50dd46f 100644
--- a/src/pages/comparison_test.rs
+++ b/src/pages/comparison_test.rs
@@ -3,12 +3,12 @@ use super::api::{get_all_scholarship_info, get_comparison_info};
use super::home_page::get_submission;
use crate::common::{ComparisonData, ExpandableInfo, ValueType};
use crate::components::{ActionButton, Loading, Panel, Row};
-use crate::pages::utils::get_user_claims;
use leptos::either::Either;
use leptos::leptos_dom::logging::console_log;
use leptos::logging::log;
use leptos::prelude::*;
use leptos_oidc::{AuthLoaded, Authenticated};
+use crate::utils::get_user_claims;
#[component]
pub fn ComparisonTestPage() -> impl IntoView {
diff --git a/src/pages/home_page.rs b/src/pages/home_page.rs
index f303195..4e109a8 100644
--- a/src/pages/home_page.rs
+++ b/src/pages/home_page.rs
@@ -10,7 +10,6 @@ use std::io::Write;
use crate::common::{ComparisonData, ExpandableInfo};
use crate::pages::UnauthenticatedPage;
-use crate::pages::utils::get_user_claims;
use crate::components::{
ActionButton, CheckboxList, Loading, MultiEntry, OutlinedTextField, Panel, RadioList, Row,
Select, TextFieldType, ValidatedForm
@@ -26,6 +25,7 @@ use leptos::web_sys::HtmlAnchorElement;
use leptos::wasm_bindgen::JsCast;
use std::collections::HashMap;
use crate::pages::api::get_comparisons_categorized;
+use crate::utils::get_user_claims;
/// # Get Student Info
/// Gets a student's information given their `subject`.
diff --git a/src/pages/mod.rs b/src/pages/mod.rs
index 1b363d8..6b76373 100644
--- a/src/pages/mod.rs
+++ b/src/pages/mod.rs
@@ -7,7 +7,6 @@ mod provider_portal;
mod scholarship_info;
mod test_page;
mod unauthenticated_page;
-mod utils;
mod provider_contact;
mod auth_callback;
diff --git a/src/pages/provider_contact.rs b/src/pages/provider_contact.rs
index 55a01b4..ea03899 100644
--- a/src/pages/provider_contact.rs
+++ b/src/pages/provider_contact.rs
@@ -1,14 +1,14 @@
-use std::collections::HashMap;
+#[cfg(feature = "ssr")]
+use crate::utils::server::{create_dynamo_client, into_attr_map};
+
+use std::collections::HashMap;
use leptos::logging::log;
use leptos::prelude::*;
use leptos_oidc::{AuthLoaded, Authenticated};
use crate::common::ValueType;
use crate::components::{Banner, Loading, OutlinedTextField, Panel, Row, TextFieldType, Toast, ToastContext, ToastList, ValidatedForm};
use crate::pages::UnauthenticatedPage;
-use crate::pages::utils::get_user_claims;
-
-#[cfg(feature = "ssr")]
-use crate::pages::utils::server_utils::create_dynamo_client;
+use crate::utils::get_user_claims;
#[cfg(feature = "ssr")]
static PROVIDER_CONTACT_TABLE: &str = "leptos-provider-contacts";
@@ -52,7 +52,6 @@ async fn get_provider_contact(id: String) -> Result,
#[server]
async fn put_provider_contact(id: String, contact_info: HashMap) -> Result<(), ServerFnError> {
use aws_sdk_dynamodb::error::ProvideErrorMetadata;
- use crate::pages::utils::server_utils::into_attr_map;
let client = create_dynamo_client().await;
diff --git a/src/pages/scholarship_info.rs b/src/pages/scholarship_info.rs
index df41afd..53bca79 100644
--- a/src/pages/scholarship_info.rs
+++ b/src/pages/scholarship_info.rs
@@ -8,7 +8,7 @@ use leptos_router::hooks::{use_navigate, use_params};
use crate::common::{ExpandableInfo, ScholarshipFormParams, SubmitStatus, ValueType};
use crate::components::{ActionButton, Banner, ChipsList, Loading, OutlinedTextField, Panel, RadioList, Row, TextFieldType, Toast, ToastContext, ToastList, ValidatedForm};
use super::UnauthenticatedPage;
-use crate::pages::utils::get_user_claims;
+use crate::utils::get_user_claims;
use super::api::{get_provider_scholarships, get_scholarship_info, CreateScholarshipInfo, RegisterScholarship, DeleteProviderScholarship, get_comparisons_categorized, CreateTestComparisons};
diff --git a/src/pages/utils.rs b/src/pages/utils.rs
deleted file mode 100644
index cc26488..0000000
--- a/src/pages/utils.rs
+++ /dev/null
@@ -1,42 +0,0 @@
-use crate::common::UserClaims;
-use leptos::prelude::{Signal, With, use_context};
-use leptos_oidc::{Algorithm, AuthSignal, TokenData};
-
-/// # Server Utilities
-///
-/// These utility functions can only be used from the server. They are created to use server-side
-/// dependencies like the AWS SDK. Use of these functions will crash the front end, as these
-/// dependencies cannot be compiled for WASM (nor should they be).
-#[cfg(feature = "ssr")]
-pub mod server_utils {
- use std::collections::HashMap;
- use aws_config::SdkConfig;
- use crate::common::ValueType;
-
- /// Creates an [`SdkConfig`] struct for use with AWS SDK structs.
- pub async fn create_aws_config() -> SdkConfig {
- aws_config::load_defaults(aws_config::BehaviorVersion::latest()).await
- }
-
- /// Creates a DynamoDB client.
- pub async fn create_dynamo_client() -> aws_sdk_dynamodb::Client {
- aws_sdk_dynamodb::Client::new(&create_aws_config().await)
- }
-
- pub fn into_attr_map(map: HashMap) -> HashMap {
- map.into_iter().map(|(k, v)| (k, v.into())).collect()
- }
-}
-
-/// Gets the current user claims. This function should only be used in an area that has
-/// access to an AuthSignal, or it will result in a total failure.
-pub fn get_user_claims() -> Signal