Skip to content

Commit 6893825

Browse files
committed
fix: judge search in prizetrack page uses real people search endpoint
1 parent 1b095b3 commit 6893825

File tree

1 file changed

+84
-190
lines changed

1 file changed

+84
-190
lines changed

src/ui/pages/hackathon/judging_admin.rs

Lines changed: 84 additions & 190 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ pub fn HackathonJudgingAdmin(slug: String) -> Element {
3434
let hackathon = use_context::<Signal<HackathonInfo>>();
3535
let mut status: Signal<Option<JudgingStatus>> = use_signal(|| None);
3636
let mut features: Signal<Vec<FeatureInfo>> = use_signal(|| Vec::new());
37-
let mut available_users: Signal<Vec<(i32, String)>> = use_signal(|| Vec::new());
37+
3838
let mut loading = use_signal(|| false);
3939
let mut error_msg: Signal<Option<String>> = use_signal(|| None);
4040
let mut success_msg: Signal<Option<String>> = use_signal(|| None);
@@ -69,19 +69,6 @@ pub fn HackathonJudgingAdmin(slug: String) -> Element {
6969
Err(e) => error_msg.set(Some(format!("Failed to get features: {}", e))),
7070
}
7171

72-
// Fetch available users for judge assignment
73-
match get_hackathon_people(slug.clone(), None, None, None, None).await {
74-
Ok(response) => {
75-
let user_list: Vec<(i32, String)> = response
76-
.people
77-
.into_iter()
78-
.map(|u: HackathonPerson| (u.user_id, u.name.unwrap_or_else(|| u.email)))
79-
.collect();
80-
available_users.set(user_list);
81-
}
82-
Err(_) => {} // Silently fail - users just won't be able to add judges
83-
}
84-
8572
// Fetch prizes with judges
8673
match get_prizes_with_judges(slug).await {
8774
Ok(p) => prizes_with_judges.set(p),
@@ -270,6 +257,30 @@ pub fn HackathonJudgingAdmin(slug: String) -> Element {
270257
}
271258
};
272259

260+
// Resource for searching judges
261+
let mut judges_resource = use_resource(use_reactive(
262+
&(slug.clone(), prize_judge_search()),
263+
move |(slug, search)| async move {
264+
let search_val = if search.trim().is_empty() {
265+
None
266+
} else {
267+
Some(search)
268+
};
269+
get_hackathon_people(
270+
slug,
271+
Some(0),
272+
Some(20),
273+
search_val,
274+
Some(vec![
275+
"judge".to_string(),
276+
"organizer".to_string(),
277+
"admin".to_string(),
278+
]),
279+
)
280+
.await
281+
},
282+
));
283+
273284
let mut select_feature = move |feature: FeatureInfo| {
274285
edit_name.set(feature.name.clone());
275286
edit_description.set(feature.description.clone().unwrap_or_default());
@@ -648,6 +659,7 @@ pub fn HackathonJudgingAdmin(slug: String) -> Element {
648659

649660

650661

662+
651663
if let Some(desc) = &feature.description {
652664
p { class: "text-sm text-foreground-neutral-secondary line-clamp-3", "{desc}" }
653665
}
@@ -779,33 +791,6 @@ pub fn HackathonJudgingAdmin(slug: String) -> Element {
779791
show_prize_judge_picker.set(false);
780792
prize_judge_search.set(String::new());
781793
},
782-
783-
784-
785-
786-
787-
788-
789-
790-
791-
792-
793-
794-
795-
796-
797-
798-
799-
800-
801-
802-
803-
804-
805-
806-
807-
808-
809794
div { class: "flex items-center justify-between mb-2",
810795
h3 { class: "font-semibold text-lg text-foreground-neutral-primary", "{pwj.prize.name}" }
811796
if pwj.is_default {
@@ -819,6 +804,7 @@ pub fn HackathonJudgingAdmin(slug: String) -> Element {
819804
}
820805
}
821806

807+
822808
if !pwj.is_default && !pwj.judges.is_empty() {
823809
div { class: "flex flex-wrap gap-2 mt-2",
824810
for judge in pwj.judges.iter().take(5) {
@@ -861,116 +847,12 @@ pub fn HackathonJudgingAdmin(slug: String) -> Element {
861847
selected_prize.set(None);
862848
show_prize_judge_picker.set(false);
863849
},
864-
865-
// Assigned judges list
866-
867-
// Update selected judges
868-
869-
// Judge picker dropdown
870-
// Update selected judges
871-
872-
// Make Default button
873-
874-
875-
876-
877-
878-
879-
880-
881-
882-
883-
884-
885-
886-
887-
888-
889-
890-
891-
892-
893-
894-
895-
896-
897-
898-
899-
900-
901-
902-
903-
904-
905-
906-
907-
908-
909-
910-
911-
912-
913-
914-
915-
916-
917-
918-
919-
920-
921-
922-
923-
924-
925-
926-
927-
928-
929-
930-
931-
932-
933-
934-
935-
936-
937-
938-
939-
940-
941-
942-
943-
944-
945-
946-
947-
948-
949-
950-
951-
952-
953-
954-
955-
956-
957-
958-
959-
960-
961-
962-
963-
964-
965-
966-
967-
968-
969-
970850
Icon { width: 20, height: 20, icon: LdX }
971851
}
972852
}
973853

854+
855+
974856
div { class: "mb-4",
975857
div { class: "flex items-center justify-between mb-2",
976858
label { class: "text-sm text-foreground-neutral-secondary", "Assigned Judges" }
@@ -1041,54 +923,66 @@ pub fn HackathonJudgingAdmin(slug: String) -> Element {
1041923
}
1042924
div { class: "max-h-48 overflow-y-auto space-y-1",
1043925
{
1044-
let search = prize_judge_search.read().to_lowercase();
926+
let judges_result = judges_resource.read();
927+
let filtered_judges = match judges_result.as_ref() {
928+
Some(Ok(response)) => response.people.clone(),
929+
_ => Vec::new(),
930+
};
931+
1045932
let assigned_ids: Vec<i32> = selected_prize_judges
1046933
.read()
1047934
.iter()
1048935
.map(|j| j.user_id)
1049936
.collect();
1050-
let filtered: Vec<_> = available_users
1051-
.read()
1052-
.iter()
1053-
.filter(|(id, name)| {
1054-
!assigned_ids.contains(id) && name.to_lowercase().contains(&search)
1055-
})
1056-
.take(10)
1057-
.cloned()
1058-
.collect();
937+
1059938
rsx! {
1060-
for (id , name) in filtered {
1061-
{
1062-
let slug = slug.clone();
1063-
let refresh = refresh.clone();
1064-
let prize_id = selected_prize.read().as_ref().map(|p| p.id).unwrap_or_default();
1065-
rsx! {
1066-
button {
1067-
class: "w-full text-left px-3 py-2 hover:bg-background-neutral-secondary-enabled rounded cursor-pointer",
1068-
onclick: move |_| {
1069-
let slug = slug.clone();
1070-
let refresh = refresh.clone();
1071-
spawn(async move {
1072-
let request = AssignJudgesRequest {
1073-
judge_ids: vec![id],
1074-
};
1075-
if assign_prize_judges(slug.clone(), prize_id, request).await.is_ok() {
1076-
refresh();
1077-
if let Ok(p) = get_prizes_with_judges(slug).await {
1078-
prizes_with_judges.set(p.clone());
1079-
let judges = p
1080-
.iter()
1081-
.find(|pwj| pwj.prize.id == prize_id)
1082-
.map(|pwj| pwj.judges.clone())
1083-
.unwrap_or_default();
1084-
selected_prize_judges.set(judges);
1085-
}
1086-
show_prize_judge_picker.set(false);
1087-
prize_judge_search.set(String::new());
1088-
}
1089-
});
1090-
},
1091-
"{name}"
939+
if let Some(Err(e)) = judges_result.as_ref() {
940+
div { class: "p-2 text-sm text-foreground-danger-primary",
941+
"Error loading judges: {e}"
942+
}
943+
} else if filtered_judges.is_empty() {
944+
div { class: "p-2 text-sm text-foreground-neutral-secondary",
945+
"No judges found."
946+
}
947+
} else {
948+
for person in filtered_judges {
949+
if !assigned_ids.contains(&person.user_id) {
950+
{
951+
let id = person.user_id;
952+
let name = person.name.clone().unwrap_or_else(|| person.email.clone());
953+
let slug = slug.clone();
954+
let refresh = refresh.clone();
955+
let prize_id = selected_prize.read().as_ref().map(|p| p.id).unwrap_or_default();
956+
957+
rsx! {
958+
button {
959+
class: "w-full text-left px-3 py-2 hover:bg-background-neutral-secondary-enabled rounded cursor-pointer",
960+
onclick: move |_| {
961+
let slug = slug.clone();
962+
let refresh = refresh.clone();
963+
spawn(async move {
964+
let request = AssignJudgesRequest {
965+
judge_ids: vec![id],
966+
};
967+
if assign_prize_judges(slug.clone(), prize_id, request).await.is_ok() {
968+
refresh();
969+
if let Ok(p) = get_prizes_with_judges(slug).await {
970+
prizes_with_judges.set(p.clone());
971+
let judges = p
972+
.iter()
973+
.find(|pwj| pwj.prize.id == prize_id)
974+
.map(|pwj| pwj.judges.clone())
975+
.unwrap_or_default();
976+
selected_prize_judges.set(judges);
977+
}
978+
show_prize_judge_picker.set(false);
979+
prize_judge_search.set(String::new());
980+
}
981+
});
982+
},
983+
"{name}"
984+
}
985+
}
1092986
}
1093987
}
1094988
}
@@ -1126,9 +1020,9 @@ pub fn HackathonJudgingAdmin(slug: String) -> Element {
11261020
},
11271021
"Assign All Judges"
11281022
}
1129-
11301023
}
11311024
}
1025+
11321026
}
11331027
}
11341028
}

0 commit comments

Comments
 (0)