Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
limkhl committed Apr 3, 2024
2 parents 70aadb9 + 8ff9a65 commit bfcd27b
Show file tree
Hide file tree
Showing 6 changed files with 196 additions and 15 deletions.
41 changes: 41 additions & 0 deletions src/app/stats/candidate/page.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
"use client"

import * as styles from '../stats.module.css'
import { useEffect, useState } from "react"

export default function StatsByCandidate() {
const [loading, setLoading] = useState(false)
const [requestsByCandidate, setRequestsByCandidate] = useState([])

const getRequestsByCandidate = async () => {
setLoading(true)
const response = await fetch(`/candidates.json`)
const candidates = await response.json()
const candidatesRequests = await Promise.all(candidates.map(async (candidate) => {
const response = await fetch(`/api/candidates/${candidate.id}/stats`)
const {data} = await response.json()
return { name: candidate.name, requests: data.requests, party: candidate.party }
}))
setRequestsByCandidate(candidatesRequests)
setLoading(false)
}

useEffect(() => {
getRequestsByCandidate()
}, [])

const hasData = !loading && requestsByCandidate.length > 0
const candidateWithMaxRequest = requestsByCandidate.reduce((acc, cur) => {
return cur.requests > acc.requests ? cur : acc
}, { name: '', requests: 0, party: '' })

return (
<div className={styles.statsContainer}>
<section>
<h3>가장 질문이 많은 후보</h3>
{loading && <p>Loading...</p>}
{hasData && <p>{candidateWithMaxRequest.name}({candidateWithMaxRequest.party}) : {candidateWithMaxRequest.requests}</p>}
</section>
</div>
)
}
75 changes: 75 additions & 0 deletions src/app/stats/city/page.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
"use client"

import * as styles from '../stats.module.css'
import { useEffect, useState } from "react"

export default function StatsByCity() {
const [loading, setLoading] = useState(false)
const [requestsByCities, setRequestsByCities] = useState([])

async function fetchCandidatesRequestsByCity(city) {
const response = await fetch(`/cities/${city}/regions.json`)
const data = await response.json()
const candidatesRequests = await data.reduce(async (acc, {name}) => {
const response = await fetch(`/cities/${city}/regions/${name}/candidates.json`)
const candidatesByRegions = await response.json()
const requests = await Promise.all(candidatesByRegions.map(async (candidate) => {
const response = await fetch(`/api/candidates/${candidate.id}/stats`)
const {data} = await response.json()
return data.requests
}))

const sum = requests.reduce((acc, counter) => acc + counter, 0)
return await acc + sum
}, 0)
return candidatesRequests
}

const getRequestsByCities = async () => {
setLoading(true)
const response = await fetch(`/cities.json`)
const cities = await response.json()
const citiesRequests = await Promise.all(cities.map(async ({name}) => {
const requests = await fetchCandidatesRequestsByCity(name)
return { city: name, requests }
}))
setRequestsByCities(citiesRequests)
setLoading(false)
}

useEffect(() => {
getRequestsByCities()
}, [])

const hasData = !loading && requestsByCities.length > 0
const cityWithMaxRequest = requestsByCities.reduce((acc, {city, requests}) => {
return requests > acc.requests ? { city, requests } : acc
}, { city: '', requests: 0 })
const cityWithMinRequest = requestsByCities.reduce((acc, {city, requests}) => {
return requests < acc.requests ?{ city, requests } : acc
}, { city: '', requests: Number.MAX_SAFE_INTEGER })

return (
<div className={styles.statsContainer}>
<section>
<h3>지역별 질문 수</h3>
{loading && <p>Loading...</p>}
{hasData && requestsByCities.map(({city, requests}) => (
<div key={city}>
<p>{city} : {requests}</p>
</div>
))}
</section>
<section>
<h3>가장 질문이 많은 지역</h3>
{loading && <p>Loading...</p>}
{hasData && <p>{cityWithMaxRequest.city} : {cityWithMaxRequest.requests}</p>}
</section>
<section>
<h3>가장 질문이 적은 지역</h3>
{loading && <p>Loading...</p>}
{hasData && <p>{cityWithMinRequest.city} : {cityWithMinRequest.requests}</p>}
</section>
</div>
)
}
69 changes: 69 additions & 0 deletions src/app/stats/party/page.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
"use client"

import * as styles from '../stats.module.css'
import { useEffect, useState } from "react"

export default function StatsByParty() {
const [loading, setLoading] = useState(false)
const [requestsByParties, setRequestsByParties] = useState([])

async function fetchCandidatesRequestsByParty(party) {
const response = await fetch(`/parties/${party}/candidates.json`)
const candidatesByParties = await response.json()
const requests = await Promise.all(candidatesByParties.map(async (candidate) => {
const response = await fetch(`/api/candidates/${candidate.id}/stats`)
const {data} = await response.json()
return data.requests
}))
const sum = requests.reduce((acc, counter) => acc + counter, 0)
return sum
}

const getRequestsByParties = async () => {
setLoading(true)
const response = await fetch(`/parties.json`)
const parties = await response.json()
const partiesRequests = await Promise.all(parties.map(async ({name}) => {
const requests = await fetchCandidatesRequestsByParty(name)
return { party: name, requests }
}))
setRequestsByParties(partiesRequests)
setLoading(false)
}

useEffect(() => {
getRequestsByParties()
}, [])

const hasData = !loading && requestsByParties.length > 0
const partyWithMaxRequest = requestsByParties.reduce((acc, {party, requests}) => {
return requests > acc.requests ? { party, requests } : acc
}, { party: '', requests: 0 })
const partyWithMinRequest = requestsByParties.reduce((acc, {party, requests}) => {
return requests < acc.requests ?{ party, requests } : acc
}, { party: '', requests: Number.MAX_SAFE_INTEGER })

return (
<div className={styles.statsContainer}>
<section>
<h3>정당별 질문 수</h3>
{loading && <p>Loading...</p>}
{hasData && requestsByParties.map(({party, requests}) => (
<div key={party}>
<p>{party} : {requests}</p>
</div>
))}
</section>
<section>
<h3>가장 질문이 많은 정당</h3>
{loading && <p>Loading...</p>}
{hasData && <p>{partyWithMaxRequest.party} : {partyWithMaxRequest.requests}</p>}
</section>
<section>
<h3>가장 질문이 적은 정당</h3>
{loading && <p>Loading...</p>}
{hasData && <p>{partyWithMinRequest.party} : {partyWithMinRequest.requests}</p>}
</section>
</div>
)
}
5 changes: 5 additions & 0 deletions src/app/stats/stats.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
.statsContainer {
display: grid;
flex-direction: column;
gap: 20px;
}
6 changes: 0 additions & 6 deletions src/components/Ask/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,12 +89,6 @@ export const useCandidates = () => {
const response = await fetch(`/parties/${party.value}/candidates.json`)
const data = await response.json()
actions.SET(data)
},
byId: async id => {
actions.FETCH()
const response = await fetch(`/candidates/${id}.json`)
const data = await response.json()
return data
}
}

Expand Down
15 changes: 6 additions & 9 deletions src/components/Result.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,23 +16,20 @@ const Response = ({member}: any) => (
)

const Result = () => {
const { fetchCandidates } = useCandidates()
const [agrees, setAgrees] = React.useState<any[]>([])
const [disagrees, setDisagrees] = React.useState<any[]>([])
// const [disagrees, setDisagrees] = React.useState<any[]>([])

const fetchResponses = async () => {
const { data: responses } = await client().get(`/api/responses`)
// const { agreed, disagreed } = responses
const agreedCandidates = await getCandidate(responses.agreed)
// const disagreedCandidates = await getCandidate(disagreed)

const agreedCandidates = await joinPersonalInfo(responses.agreed)
// const disagreedCandidates = await joinPersonalInfo(responses.disagreed)
setAgrees(agreedCandidates)
// setDisagrees(disagreedCandidates)
}

async function getCandidate(candidates: any) {
async function joinPersonalInfo(candidates: any) {
return Promise.all(candidates.map(async (candidate: any) => {
const candidateInfo = await fetchCandidates.byId(candidate.id)
const candidateInfo = await fetch(`/candidates/${candidate.id}.json`).then((res) => res.json())
const { choice, id } = candidate
return { candidate: candidateInfo, choice, id }
}))
Expand All @@ -57,7 +54,7 @@ const Result = () => {

{agrees.length > 0 &&
<div>
<h3 className="listTitle">동의한 후보 목록</h3>
<h3 className="listTitle">동의한 후보 {agrees.length}</h3>
<ul className="list">
{agrees.map(response => (
<li key={`agree-${response.id}`} style={{padding: '10px 0'}}>
Expand Down

0 comments on commit bfcd27b

Please sign in to comment.