Skip to content

Commit

Permalink
Merge pull request #47 from BU-Spark/qAndA
Browse files Browse the repository at this point in the history
Boston Voter App: Q and A strapi calls done and styled
  • Loading branch information
eelkus01 authored Jun 25, 2024
2 parents 2292107 + 570446e commit 59ea1df
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 7 deletions.
71 changes: 69 additions & 2 deletions client/src/pages/ballotInfo/[candidate].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@ import React, { use, useEffect, useState } from 'react';
import { useRouter } from 'next/router';
import { localCandidateAPI, deployedCandidateAPI } from '@/common';
import { all } from 'axios';
import { Accordion, AccordionDetails, AccordionSummary, Typography } from '@mui/material';
import ExpandMoreIcon from '@mui/icons-material/ExpandMore';


interface CandidateAttributes {
CampaignSiteLink: string | null;
Expand All @@ -19,6 +22,16 @@ interface CandidateAttributes {
createdAt: string;
publishedAt: string;
updatedAt: string;
Question1: string | null;
Answer1: string | null;
Question2: string | null;
Answer2: string | null;
Question3: string | null;
Answer3: string | null;
Question4: string | null;
Answer4: string | null;
Question5: string | null;
Answer5: string | null;
}

interface CandidateDataObject {
Expand All @@ -30,12 +43,17 @@ interface Candidate {
attributes: CandidateAttributes;
}

interface QuestionsAndAnswers {
[key: string]: { question: string | null, answer: string | null };
}

export default function Candidate() {
const router = useRouter();

const [candidateName, setCandidateName] = useState<string>('');
const [allCandidateData, setAllCandidateData] = useState<CandidateDataObject[]>([])
const [candidateData, setCandidateData] = useState<CandidateAttributes | null>(null);
const [questionsAndAnswers, setQuestionsAndAnswers] = useState<QuestionsAndAnswers>({});

useEffect(() => {
if (!router.isReady) return;
Expand Down Expand Up @@ -86,11 +104,32 @@ export default function Candidate() {
console.log(candidateData);
}, [candidateData])

// Get filled out questions and answers and populate map
useEffect(() => {
if (candidateData) {
const qaMap = Object.entries(candidateData)
.filter(([key, value]) => key.startsWith('Question') || key.startsWith('Answer'))
.reduce<QuestionsAndAnswers>((acc, [key, value]) => {
const questionIndex = key.match(/\d+/)?.[0];
if (questionIndex) {
if (!acc[questionIndex]) {
acc[questionIndex] = { question: null, answer: null };
}
acc[questionIndex][key.includes('Question') ? 'question' : 'answer'] = value;
}
return acc;
}, {});
setQuestionsAndAnswers(qaMap);
}
}, [candidateData]);


return (
<div className="max-w-2xl mx-auto p-4 #d1e4fa">
<div>
{candidateData ? (
<>
{/* Main content */}
<div className='max-w-2xl mx-auto p-4 #d1e4fa'></div>
<h1 className="text-4xl font-bold mb-4 justify-center text-center">{candidateData?.Name}</h1>
<div className="border-t border-gray-800 pt-4">
<div className="flex flex-col items-center">
Expand All @@ -104,8 +143,36 @@ export default function Candidate() {
<p className="text-lg mb-2 font-semibold"> <a href={candidateData.LinkedinLink} className="text-blue-500">{candidateData.LinkedinLink}</a></p>
)}
<p className="text-lg mb-2 font-semibold"> {candidateData.Role}</p>
</div>
</div>
</div>


{/* Questions and answers */}
{Object.entries(questionsAndAnswers).length > 0 ? (
<div className="flex flex-col justify-center items-center py-8 px-6 my-6">
<p className="text-2xl font-semibold mb-8 text-center">Questions curated by the founder, journalist Yawu Miller</p>
{Object.entries(questionsAndAnswers).map(([index, qa]) => (
qa.question && qa.answer ? (
<Accordion key={index} className='bg-white w-full lg:w-3/4 md:w-3/4 mb-3'>

{/* Question */}
<AccordionSummary
expandIcon={<ExpandMoreIcon />}
aria-controls={`panel${index}-content`}
id={`panel${index}-header`}
>
<Typography className='text-blue-700 text-xl'>{qa.question}</Typography>
</AccordionSummary>

{/* Answer */}
<AccordionDetails>
<Typography className='mb-8 text-xl'>{qa.answer}</Typography>
</AccordionDetails>
</Accordion>
) : null
))}
</div>
) : null}
</>
) : (
<p className="text-lg">Loading candidate data...</p>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,6 @@ export default function CandidateData() {
{/* Description of the role */}
<Typography className='mx-4 mb-8 text-lg'>
{candidateRoleDate[role] ? candidateRoleDate[role] : 'No description available for this role'}

</Typography>

{/* Map over the candidates for each role */}
Expand Down
3 changes: 0 additions & 3 deletions strapi/src/api/candidate/content-types/candidate/schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -108,9 +108,6 @@
},
"Answer10": {
"type": "text"
},
"QuestionsAnswers": {
"type": "json"
}
}
}
1 change: 0 additions & 1 deletion strapi/types/generated/contentTypes.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -926,7 +926,6 @@ export interface ApiCandidateCandidate extends Schema.CollectionType {
Answer9: Attribute.Text;
Question10: Attribute.String;
Answer10: Attribute.Text;
QuestionsAnswers: Attribute.JSON;
createdAt: Attribute.DateTime;
updatedAt: Attribute.DateTime;
publishedAt: Attribute.DateTime;
Expand Down

0 comments on commit 59ea1df

Please sign in to comment.