Skip to content

Commit 3269a2a

Browse files
authored
CHAOS-224-KHAOS-rewrite-fix: fix roles not fetching upon addition (#654)
* fix: fix bug relating to roles not fetching on addition * chore: remove unnecessary package.json change * style: clean up console logs left over * feat: switch back to in progress application idk why it's defaulting to regular * Update applicationanswer.tsx * Delete frontend-nextjs/package-lock.json
1 parent d58c814 commit 3269a2a

3 files changed

Lines changed: 173 additions & 81 deletions

File tree

frontend-nextjs/src/app/[lang]/campaign/apply/[campaignId]/application/[applicationId]/applicationanswer.tsx

Lines changed: 75 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,16 @@
22

33
import { useQuery, useQueryClient } from "@tanstack/react-query";
44
import { getCampaign, getCampaignRoles } from "@/models/campaign";
5-
import { getApplication, submitApplication } from "@/models/application";
6-
import { Answer, updateApplicationRoles } from "@/models/answer";
5+
import { getInProgressApplication, submitApplication } from "@/models/application";
6+
import { Answer, getAllCommonAnswers, updateApplicationRoles } from "@/models/answer";
77
import { useState, useEffect } from "react";
88
import RoleSelector from "../../../../../../../components/applicationanswer/roleselector";
99
import RoleTabs from "../../../../../../../components/applicationanswer/roletabs";
1010
import MainContent from "../../../../../../../components/applicationanswer/maincontent";
1111
import ReviewCard from "@/components/applicationanswer/reviewcard";
12-
import { linkQuestionsAndAnswers, Question, QuestionAndAnswer } from "@/models/question";
12+
import { getAllCommonQuestions, linkQuestionsAndAnswers, Question, QuestionAndAnswer } from "@/models/question";
13+
import { getAllRoleAnswers } from "@/models/answer";
14+
import { getAllRoleQuestions } from "@/models/question";
1315
import { redirect, useRouter } from "next/navigation";
1416

1517
interface ApplicationReviewProps {
@@ -47,15 +49,43 @@ export default function ApplicationReview({
4749

4850
const { data: application } = useQuery({
4951
queryKey: [`application-${applicationId}`],
50-
queryFn: () => getApplication(applicationId),
52+
queryFn: () => getInProgressApplication(applicationId),
5153
});
5254

5355
const [selectedRoleIds, setSelectedRoleIds] = useState<string[]>([]);
5456
const [activeTab, setActiveTab] = useState<"general" | string>("general");
55-
const [qaByRole, setQAByRole] = useState<Map<string,QuestionAndAnswer[]>>(new Map());
57+
const [qaByRole, setQAByRole] = useState<Map<string, QuestionAndAnswer[]>>(new Map());
5658
const queryClient = useQueryClient()
5759

58-
const populateQAByRole = (roleIds:string[], campaignId: string, applicationId: string) => {
60+
// always fetch general qAndAs on load
61+
useEffect(() => {
62+
(async () => {
63+
try {
64+
const [generalQs, generalAnswers] = await Promise.all([
65+
queryClient.fetchQuery({
66+
queryKey: [`${applicationId}-common-questions`],
67+
queryFn: () => getAllCommonQuestions(campaignId),
68+
}),
69+
queryClient.fetchQuery({
70+
queryKey: [`${applicationId}-common-answers`],
71+
queryFn: () => getAllCommonAnswers(applicationId),
72+
}),
73+
]);
74+
75+
const linkedGeneral = linkQuestionsAndAnswers(generalQs, generalAnswers);
76+
77+
setQAByRole(prev => {
78+
const newMap = new Map(prev);
79+
newMap.set("general", linkedGeneral);
80+
return newMap;
81+
});
82+
} catch (err) {
83+
console.error("Failed to fetch general questions/answers", err);
84+
}
85+
})();
86+
}, [campaignId, applicationId, queryClient]);
87+
88+
const populateQAByRole = (roleIds: string[], campaignId: string, applicationId: string) => {
5989
setQAByRole(prev => {
6090
const newQAMap = new Map(prev);
6191
if (!newQAMap.has('general')) {
@@ -69,7 +99,7 @@ export default function ApplicationReview({
6999

70100
for (const roleId of roleIds) {
71101
//if (newQAMap.has(roleId)) continue;
72-
const roleQs: Question[] | undefined = queryClient.getQueryData([`${campaignId}-${roleId}-role-questions`])
102+
const roleQs: Question[] | undefined = queryClient.getQueryData([`${campaignId}-${roleId}-role-questions`])
73103
const roleAnswers: Answer[] | undefined = queryClient.getQueryData([`${applicationId}-${roleId}-role-answers`])
74104
if (roleQs && roleAnswers) {
75105
const linked = linkQuestionsAndAnswers(roleQs, roleAnswers);
@@ -96,7 +126,7 @@ export default function ApplicationReview({
96126

97127
return newQAMap;
98128
});
99-
};
129+
};
100130

101131
// format roles to match what backend expects
102132
const buildUpdatedRolesPayload = (orderedIds: string[]) => {
@@ -131,7 +161,6 @@ export default function ApplicationReview({
131161
setSelectedRoleIds(nextSelectedRoles)
132162
setQAByRole(prev => {
133163
const newQAMap = new Map<string, QuestionAndAnswer[]>();
134-
135164
if (prev.has('general')) {
136165
newQAMap.set('general', prev.get('general')!);
137166
}
@@ -146,7 +175,30 @@ export default function ApplicationReview({
146175
const linked = linkQuestionsAndAnswers(roleQs, roleAnswers);
147176
newQAMap.set(roleId, linked);
148177
} else {
149-
newQAMap.set(roleId, []);
178+
(async () => {
179+
try {
180+
const [roleQs, roleAnswers] = await Promise.all([
181+
queryClient.fetchQuery({
182+
queryKey: [`${campaignId}-${roleId}-role-questions`],
183+
queryFn: () => getAllRoleQuestions(campaignId, roleId),
184+
}),
185+
queryClient.fetchQuery({
186+
queryKey: [`${applicationId}-${roleId}-role-answers`],
187+
queryFn: () => getAllRoleAnswers(applicationId, roleId),
188+
}),
189+
]);
190+
191+
const linked = linkQuestionsAndAnswers(roleQs, roleAnswers);
192+
193+
setQAByRole(prevInner => {
194+
const updated = new Map(prevInner);
195+
updated.set(roleId, linked);
196+
return updated;
197+
});
198+
} catch (err) {
199+
console.error(`Failed to fetch QAs for role ${roleId}:`, err);
200+
}
201+
})();
150202
}
151203
}
152204
}
@@ -175,28 +227,25 @@ export default function ApplicationReview({
175227
}, [application]);
176228

177229
const handleApplicationSubmit = async () => {
178-
try {
179-
await submitApplication(applicationId)
180-
queryClient.invalidateQueries({ queryKey: [`application-${applicationId}`] });
181-
router.push(`/campaign/apply/${campaignId}/finish`);
182-
} catch (e) {
183-
console.error("Submission failed: ", e);
184-
}
230+
try {
231+
await submitApplication(applicationId)
232+
queryClient.invalidateQueries({ queryKey: [`application-${applicationId}`] });
233+
router.push(`/campaign/apply/${campaignId}/finish`);
234+
} catch (e) {
235+
console.error("Submission failed: ", e);
236+
}
185237
}
186238

187239
useEffect(() => {
188240
if (selectedRoleIds.length === 0) return;
189241

190-
const generalQs = queryClient.getQueryData([`${applicationId}-common-questions`]);
191-
const generalAnswers = queryClient.getQueryData([`${applicationId}-common-answers`]);
192-
193242
const allRoleQueriesReady = selectedRoleIds.every(roleId => {
194243
const roleQs = queryClient.getQueryData([`${campaignId}-${roleId}-role-questions`]);
195244
const roleAnswers = queryClient.getQueryData([`${applicationId}-${roleId}-role-answers`]);
196245
return roleQs !== undefined && roleAnswers !== undefined;
197246
});
198247

199-
if (generalQs && generalAnswers && allRoleQueriesReady) {
248+
if (allRoleQueriesReady) {
200249
populateQAByRole(selectedRoleIds, campaignId, applicationId);
201250
}
202251
}, [selectedRoleIds, campaignId, applicationId, queryClient]);
@@ -214,14 +263,14 @@ export default function ApplicationReview({
214263
</div>
215264
<div></div>
216265
<div className="flex gap-8 w-full">
217-
<RoleSelector roles={roles} maxRolesPerApplication={campaign?.max_roles_per_application} selectedRoleIds={selectedRoleIds} onChangeSelectedRoles={updateRoles} applicationId={applicationId} dict={dict}/>
266+
<RoleSelector roles={roles} maxRolesPerApplication={campaign?.max_roles_per_application} selectedRoleIds={selectedRoleIds} onChangeSelectedRoles={updateRoles} applicationId={applicationId} dict={dict} />
218267
<div className="flex-1">
219-
<RoleTabs roles={roles} selectedRoleIds={selectedRoleIds} activeTab={activeTab} onChangeActiveTab={setActiveTab} dict={dict}/>
220-
<MainContent campaignId={campaignId} applicationId={applicationId} activeTab={activeTab} dict={dict} updateRoleAnswers={updateQuestionAnswer}/>
221-
<ReviewCard questionsAndAnswersByRole={qaByRole} roles={roles} applicationId={applicationId} handleSubmit={handleApplicationSubmit} dict={dict}/>
268+
<RoleTabs roles={roles} selectedRoleIds={selectedRoleIds} activeTab={activeTab} onChangeActiveTab={setActiveTab} dict={dict} />
269+
<MainContent campaignId={campaignId} applicationId={applicationId} activeTab={activeTab} dict={dict} updateRoleAnswers={updateQuestionAnswer} />
270+
<ReviewCard questionsAndAnswersByRole={qaByRole} selectedRoleIds={selectedRoleIds} roles={roles} applicationId={applicationId} handleSubmit={handleApplicationSubmit} dict={dict} />
222271
</div>
223272
</div>
224273
</div>
225274
</div>
226275
);
227-
}
276+
}

frontend-nextjs/src/components/applicationanswer/maincontent.tsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ export default function MainContent({
7676
});
7777
} else {
7878
await queryClient.invalidateQueries({
79-
queryKey: [`${applicationId}-${activeTab}-role-answers}`]
79+
queryKey: [`${applicationId}-${activeTab}-role-answers`]
8080
})
8181
}
8282
}
@@ -101,7 +101,9 @@ export default function MainContent({
101101
}
102102

103103
useEffect(() => {
104-
if (!questions || !answers) return;
104+
if (!questions || !answers) {
105+
return;
106+
}
105107
const linked = linkQuestionsAndAnswers(questions, answers)
106108
setQuestionsAndAnswers(linked);
107109
}, [questions, answers]);

0 commit comments

Comments
 (0)