Implement template student portal #62
@@ -1,10 +1,12 @@
|
|||||||
use crate::common::{ComparisonData, ExpandableInfo, SchemaNode, SchemaType, ValueType};
|
use crate::common::{ComparisonData, ExpandableInfo, ValueType};
|
||||||
use crate::components::ValueDisplay;
|
use crate::components::{FileDrop, Header};
|
||||||
|
use crate::pages::api::files::list_files;
|
||||||
use crate::pages::api::students::get_all_student_data;
|
use crate::pages::api::students::get_all_student_data;
|
||||||
use crate::pages::api::{get_all_scholarship_info, get_comparison_info};
|
use crate::pages::api::{get_all_scholarship_info, get_comparison_info};
|
||||||
use crate::utils::get_user_claims;
|
use crate::utils::get_user_claims;
|
||||||
use leptos::logging::debug_log;
|
use leptos::logging::debug_log;
|
||||||
use leptos::prelude::*;
|
use leptos::prelude::*;
|
||||||
|
use leptos_oidc::AuthSignal;
|
||||||
|
|
||||||
#[component]
|
#[component]
|
||||||
pub fn StudentEligibilityPage() -> impl IntoView {
|
pub fn StudentEligibilityPage() -> impl IntoView {
|
||||||
@@ -18,9 +20,12 @@ pub fn StudentEligibilityPage() -> impl IntoView {
|
|||||||
// My only reservation with showing the scholarships that aren't valid is that people will want
|
// My only reservation with showing the scholarships that aren't valid is that people will want
|
||||||
// to know why. That's hard information to keep track of right now.
|
// to know why. That's hard information to keep track of right now.
|
||||||
|
|
||||||
|
let auth = expect_context::<AuthSignal>();
|
||||||
let user_claims = get_user_claims();
|
let user_claims = get_user_claims();
|
||||||
let user_id = Memo::new(move |_| user_claims.get().map(|info| info.claims.subject.clone()));
|
let user_id = Memo::new(move |_| user_claims.get().map(|info| info.claims.subject.clone()));
|
||||||
|
|
||||||
|
let form_id = StoredValue::new("scholarship_essays".to_string());
|
||||||
|
|
||||||
let refresh_trigger = Trigger::new();
|
let refresh_trigger = Trigger::new();
|
||||||
|
|
||||||
let scholarships_resource = Resource::new(
|
let scholarships_resource = Resource::new(
|
||||||
@@ -38,7 +43,7 @@ pub fn StudentEligibilityPage() -> impl IntoView {
|
|||||||
|
|
||||||
view! {
|
view! {
|
||||||
<div class="flex-1" />
|
<div class="flex-1" />
|
||||||
<div>
|
<div class="flex-2 mb-4 flex flex-col">
|
||||||
<Suspense fallback=move || {
|
<Suspense fallback=move || {
|
||||||
view! { <div>"Checking eligibility..."</div> }
|
view! { <div>"Checking eligibility..."</div> }
|
||||||
}>
|
}>
|
||||||
@@ -117,39 +122,91 @@ pub fn StudentEligibilityPage() -> impl IntoView {
|
|||||||
});
|
});
|
||||||
if valid {
|
if valid {
|
||||||
debug_log!("Scholarship is valid.");
|
debug_log!("Scholarship is valid.");
|
||||||
Some(scholarship.clone())
|
let scholarship_id = StoredValue::new(scholarship.subject.clone());
|
||||||
|
let resource = Resource::new(
|
||||||
|
move || (
|
||||||
|
auth
|
||||||
|
.try_with(|a| a.authenticated().map(|a| a.access_token()))
|
||||||
|
.flatten(),
|
||||||
|
form_id.get_value(),
|
||||||
|
scholarship_id.get_value(),
|
||||||
|
),
|
||||||
|
async move |(access_token, form_id, scholarship_id)| {
|
||||||
|
list_files(
|
||||||
|
access_token.unwrap_or_default(),
|
||||||
|
form_id,
|
||||||
|
scholarship_id,
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
},
|
||||||
|
);
|
||||||
|
Some((scholarship.clone(), resource))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.collect::<Vec<ExpandableInfo>>();
|
.collect::<
|
||||||
|
Vec<(ExpandableInfo, Resource<Result<Vec<String>, ServerFnError>>)>,
|
||||||
|
>();
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
<div>{format!("Valid scholarships: {}", valid_list.len())}</div>
|
<Header
|
||||||
|
title="Eligible Scholarships"
|
||||||
|
description="This is the list of scholarships that you are eligible for, as well as those that require essays.
|
||||||
|
Once you have fulfilled the essay requirement, you will be automatically applied for that scholarship.
|
||||||
|
If there is no essay requirement, you have already been applied."
|
||||||
|
/>
|
||||||
|
<div>
|
||||||
<For
|
<For
|
||||||
each=move || valid_list.clone()
|
each=move || valid_list.clone()
|
||||||
key=|scholarship| { scholarship.subject.clone() }
|
key=|(scholarship, _)| { scholarship.subject.clone() }
|
||||||
children=move |scholarship| {
|
children=move |(scholarship, resource)| {
|
||||||
let scholarship = StoredValue::new(scholarship);
|
let scholarship_id = StoredValue::new(
|
||||||
let display_schema = SchemaNode::new(SchemaType::Map)
|
scholarship.subject.clone(),
|
||||||
.header("Eligible Scholarship")
|
);
|
||||||
.child(
|
let scholarship_name = StoredValue::new(
|
||||||
"name",
|
scholarship
|
||||||
SchemaNode::new(SchemaType::String)
|
.data
|
||||||
.header("Scholarship Name"),
|
.get("name")
|
||||||
)
|
.map(|v| v.as_string().ok().flatten().unwrap_or_default())
|
||||||
.child(
|
.unwrap_or_default(),
|
||||||
"essay_prompt",
|
);
|
||||||
SchemaNode::new(SchemaType::String).header("Essay Prompt"),
|
let scholarship_essay = StoredValue::new(
|
||||||
|
scholarship
|
||||||
|
.data
|
||||||
|
.get("essay_prompt")
|
||||||
|
.map(|v| v.as_string().ok().flatten().unwrap_or_default())
|
||||||
|
.unwrap_or_default(),
|
||||||
);
|
);
|
||||||
|
|
||||||
view! {
|
view! {
|
||||||
<ValueDisplay
|
<div class="m-1.5 flex flex-col gap-2 shadow-lg rounded-lg">
|
||||||
schema=display_schema
|
<div class="rounded-t-lg bg-red-900 p-2 text-white font-bold">
|
||||||
data_map=scholarship.get_value().data
|
{scholarship_name.get_value()}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="p-2 flex flex-col gap-2">
|
||||||
|
<Show
|
||||||
|
when=move || !scholarship_essay.get_value().is_empty()
|
||||||
|
fallback=move || {
|
||||||
|
view! {
|
||||||
|
<div>"This scholarship does not require an essay."</div>
|
||||||
|
}
|
||||||
|
}
|
||||||
|
>
|
||||||
|
<div>{scholarship_essay.get_value()}</div>
|
||||||
|
<FileDrop
|
||||||
|
form_id=form_id.get_value()
|
||||||
|
name=scholarship_id.get_value()
|
||||||
|
existing_files=resource
|
||||||
/>
|
/>
|
||||||
|
</Show>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
.into_any()
|
.into_any()
|
||||||
}}
|
}}
|
||||||
|
|||||||
Reference in new issue
Block a user