Final provider changes #56

Merged
BobdaFett merged 4 commits from feat/table-changes into main 2026-01-19 19:44:27 +00:00
9 changed files with 104 additions and 54 deletions

No files matched your search

+3 -2
View File
@@ -1,4 +1,4 @@
use crate::pages::{ProviderPortal, ScholarshipInfoPage, ProviderContactPage, LoanerShell, LoanerFallback, LoanerBorrowForm, LoanerReturnForm, AuthCallbackPage};
use crate::pages::{ProviderPortal, ScholarshipInfoPage, ProviderContactPage, LoanerShell, LoanerFallback, LoanerBorrowForm, LoanerReturnForm, AuthCallbackPage, ApplicantsPageFallback};
use leptos::prelude::*;
use leptos_meta::{MetaTags, Stylesheet, Title, provide_meta_context};
use leptos_oidc::AuthSignal;
@@ -73,8 +73,9 @@ pub fn AppWithRoutes() -> impl IntoView {
fn ProviderRoutes() -> impl MatchNestedRoutes + Clone {
view! {
<ParentRoute path=path!("/providers") view=ProviderLoginContext>
<Route path=path!("/callback") view=AuthCallbackPage />
<Route path=path!("") view=ProviderPortal />
<Route path=path!("/applicants") view=ApplicantsPageFallback />
<Route path=path!("/callback") view=AuthCallbackPage />
<Route path=path!("/profile") view=ProviderContactPage />
<ParentRoute path=path!("/scholarships") view=ScholarshipInfoPage>
<Route path=path!(":id") view=ScholarshipInfoPage />
+1 -1
View File
@@ -16,7 +16,7 @@ use leptos::prelude::ServerFnError;
use leptos::server;
#[cfg(feature = "ssr")]
static COMPARISONS_TABLE: &str = "leptos-comparison-test";
static COMPARISONS_TABLE: &str = "leptos-comparisons";
/// Helper function to create all sports comparisons. Only used to create initial
/// comparison data, and should be removed upon completion of a comparison editor page.
+5 -2
View File
@@ -12,13 +12,16 @@ use aws_sdk_dynamodb::{
Client as DynamoClient
};
#[cfg(feature = "ssr")]
use crate::utils::server::create_dynamo_client;
#[cfg(feature = "ssr")]
use std::sync::Arc;
#[server]
pub async fn create_dates(dates: Vec<DateInfo>) -> Result<(), ServerFnError> {
// Serialize and put dates into the database.
let client = expect_context::<Arc<DynamoClient>>();
let client = create_dynamo_client().await;
log!("Creating dates: {:?}", dates);
@@ -51,7 +54,7 @@ pub async fn create_dates(dates: Vec<DateInfo>) -> Result<(), ServerFnError> {
#[server]
pub async fn get_important_dates() -> Result<Vec<DateInfo>, ServerFnError> {
let client = expect_context::<Arc<DynamoClient>>();
let client = create_dynamo_client().await;
client
.scan()
+9 -10
View File
@@ -18,9 +18,9 @@ use leptos::prelude::ServerFnError;
use leptos::server;
#[cfg(feature = "ssr")]
static SCHOLARSHIPS_TABLE: &str = "leptos-scholarship-test";
static SCHOLARSHIPS_TABLE: &str = "leptos-scholarships";
#[server(GetScholarshipInfo, endpoint = "/scholarship/info/get")]
#[server(GetScholarshipInfo)]
pub async fn get_scholarship_info(id: String) -> Result<ExpandableInfo, ServerFnError> {
let client = create_dynamo_client().await;
@@ -50,7 +50,7 @@ pub async fn get_scholarship_info(id: String) -> Result<ExpandableInfo, ServerFn
}
}
#[server(CreateScholarshipInfo, endpoint = "/scholarship/info/create")]
#[server(CreateScholarshipInfo)]
pub async fn create_scholarship_info(info: ExpandableInfo) -> Result<(), ServerFnError> {
use aws_sdk_dynamodb::error::ProvideErrorMetadata;
@@ -73,7 +73,7 @@ pub async fn create_scholarship_info(info: ExpandableInfo) -> Result<(), ServerF
}
}
#[server(GetAllScholarshipInfo, endpoint = "/scholarship/info/get-all")]
#[server(GetAllScholarshipInfo)]
pub async fn get_all_scholarship_info() -> Result<Vec<ExpandableInfo>, ServerFnError> {
let client = create_dynamo_client().await;
log!("Getting all scholarship info");
@@ -98,7 +98,7 @@ pub async fn get_all_scholarship_info() -> Result<Vec<ExpandableInfo>, ServerFnE
}
/// Gets all scholarships that are associated with the given scholarship provider's ID.
#[server(GetProviderScholarships, "/providers/scholarships/get")]
#[server(GetProviderScholarships)]
pub async fn get_provider_scholarships(provider_id: String) -> Result<Vec<ExpandableInfo>, ServerFnError> {
let client = create_dynamo_client().await;
@@ -127,16 +127,15 @@ pub async fn get_provider_scholarships(provider_id: String) -> Result<Vec<Expand
}
/// Creates a new scholarship with a unique ID, and then returns that ID.
#[server(RegisterScholarship, "/providers/scholarships/create")]
pub async fn register_scholarship(provider_id: String, scholarship_name: String) -> Result<String, ServerFnError> {
#[server(RegisterScholarship)]
pub async fn register_scholarship(provider_id: String) -> Result<String, ServerFnError> {
let client = create_dynamo_client().await;
log!("Creating scholarship for provider with ID {:?}", provider_id);
let mut current_uuid = "testing".to_string();
let mut current_uuid = Uuid::new_v4().to_string();
let mut item = ExpandableInfo::new(current_uuid.clone());
item.data.insert("provider_id".to_string(), ValueType::String(Some(provider_id)));
item.data.insert("scholarship_name".to_string(), ValueType::String(Some(scholarship_name)));
loop {
let ser_item = serde_dynamo::to_item(&item)?;
match client
@@ -172,7 +171,7 @@ pub async fn register_scholarship(provider_id: String, scholarship_name: String)
}
/// Deletes a provider's scholarship given their provider ID and scholarship ID.
#[server(DeleteProviderScholarship, "/providers/scholarships/delete")]
#[server(DeleteProviderScholarship)]
pub async fn delete_provider_scholarship(provider_id: String, scholarship_id: String) -> Result<(), ServerFnError> {
let client = create_dynamo_client().await;
+2 -1
View File
@@ -9,9 +9,10 @@ mod test_page;
mod unauthenticated_page;
mod provider_contact;
mod auth_callback;
mod provider_applicants;
pub use self::{
about_page::*, comparison_test::*, home_page::*, loaner_page::*, provider_portal::*,
test_page::*, unauthenticated_page::*, scholarship_info::*, provider_contact::*,
auth_callback::*,
auth_callback::*, provider_applicants::*
};
+15
View File
@@ -0,0 +1,15 @@
use leptos::prelude::*;
use crate::components::Banner;
#[component]
pub fn ApplicantsPageFallback() -> impl IntoView {
view! {
<Banner title="R15 Scholarships" logo="/PHS_Stacked_Acronym.png" path="/providers" />
<div class="flex flex-col gap-4 mt-3 items-center justify-center">
<h1 class="text-3xl font-bold">"Applicants Page"</h1>
<p>"This page is under construction! It will show all the students that are eligible for your scholarship(s)."</p>
<p>"Come back soon!"</p>
</div>
}
}
+1 -1
View File
@@ -43,7 +43,7 @@ pub fn ProviderPortal() -> impl IntoView {
title="Applicants"
description="View Scholarship Applicants"
icon="/Form_Black.png"
path="/"
path="/providers/applicants"
/>
</section>
<section class="space-y-4">
+1 -2
View File
@@ -128,8 +128,7 @@ fn ScholarshipList(
// Button handlers
let create_on_click = move |_| {
create_action.dispatch(RegisterScholarship {
provider_id: provider_id.get().unwrap(),
scholarship_name: "Testing Scholarship".to_string()
provider_id: provider_id.get().unwrap()
});
};
+67 -35
View File
@@ -1,43 +1,75 @@
use crate::components::DashboardButton;
use chrono::DateTime;
use crate::components::ActionButton;
use leptos::prelude::*;
use crate::common::{DateInfo, DateRange};
use crate::pages::api::{CreateDates, CreateTestComparisons};
fn get_important_dates() -> Vec<DateInfo> {
vec! [
DateInfo {
id: uuid::Uuid::new_v4().to_string(),
title: "Provider Forms Open".to_string(),
date: DateRange::Range(
DateTime::parse_from_rfc3339("2026-01-20T07:15:00-05:00").unwrap(),
DateTime::parse_from_rfc3339("2026-03-03T23:59:00-05:00").unwrap()
),
description: "".to_string(),
},
DateInfo {
id: uuid::Uuid::new_v4().to_string(),
title: "Student Forms Open".to_string(),
date: DateRange::Range(
DateTime::parse_from_rfc3339("2026-03-03T07:15:00-05:00").unwrap(),
DateTime::parse_from_rfc3339("2026-03-27T14:05:00-05:00").unwrap()
),
description: "".to_string(),
},
DateInfo {
id: uuid::Uuid::new_v4().to_string(),
title: "Scholarship Decision Window".to_string(),
date: DateRange::Range(
DateTime::parse_from_rfc3339("2026-04-10T07:15:00-05:00").unwrap(),
DateTime::parse_from_rfc3339("2026-05-01T23:59:00-05:00").unwrap()
),
description: "Start date may change if available sooner.".to_string(),
},
DateInfo {
id: uuid::Uuid::new_v4().to_string(),
title: "PHS Scholarship Committee".to_string(),
date: DateRange::Single(
DateTime::parse_from_rfc3339("2026-05-18T00:00:00-05:00").unwrap(),
),
description: "Time TBD".to_string(),
},
DateInfo {
id: uuid::Uuid::new_v4().to_string(),
title: "Scholarship and Awards Night".to_string(),
date: DateRange::Single(
DateTime::parse_from_rfc3339("2026-06-09T00:00:00-05:00").unwrap(),
),
description: "Time TBD".to_string(),
},
]
}
#[component]
pub fn TestPage() -> impl IntoView {
pub fn TestPage() -> impl IntoView {
let create_comparisons = ServerAction::<CreateTestComparisons>::new();
let create_dates = ServerAction::<CreateDates>::new();
let on_click_comparisons = move |_| {
create_comparisons.dispatch(CreateTestComparisons{});
};
let on_click_dates = move |_| {
create_dates.dispatch(CreateDates{dates: get_important_dates()});
};
view! {
<div class="mx-auto px-6">
<div class="container mx-auto px-6 py-8 space-y-8">
<div class="grid grid-cols-1 lg:grid-cols-2 gap-8">
<section class="space-y-4">
<DashboardButton
title="Profile"
description="Edit user profile"
icon="/Person_Black.png"
path="/"
/>
<DashboardButton
title="Create Scholarship"
description="Navigate to Scholarship Creation Page"
icon="/Create_Black.png"
path="/"
/>
<DashboardButton
title="Applicants"
description="View Scholarship Applicants"
icon="/Form_Black.png"
path="/"
/>
</section>
<section class="space-y-2">
<div class="rounded-lg shadow-lg/25 overflow-hidden">
<div class="bg-red-900 text-white px-4 py-3 shadow-lg">
<h3 class="text-white font-bold">Important Dates</h3>
</div>
<div class="p-2">
<div class="flex flex-col p-3 gap-3"></div>
</div>
</div>
</section>
</div>
<div class="flex flex-col gap-4">
<ActionButton on:click=on_click_comparisons>"Create Comparisons"</ActionButton>
<ActionButton on:click=on_click_dates>"Create Dates"</ActionButton>
</div>
</div>
}.into_any()