Skip to content

Commit

Permalink
Merge pull request #174 from kakao-tech-campus-2nd-step3/Week10
Browse files Browse the repository at this point in the history
Week10 5
  • Loading branch information
ppochaco authored Nov 10, 2024
2 parents afb906e + 2b54c02 commit 3e2bffe
Show file tree
Hide file tree
Showing 8 changed files with 225 additions and 157 deletions.
15 changes: 0 additions & 15 deletions src/api/services/group/group.api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,21 +141,6 @@ export const useGroupRanking = ({ groupId }: { groupId: number }) => {
})
}

export const getGroupQuestions = async (
groupId: string,
status: 'READY' | 'APPROVED' | 'REJECTED',
page: number,
size: number
) => {
const response = await authorizationInstance.get(
`/api/group/${groupId}/question`,
{
params: { status, page, size },
}
)
return response.data
}

export const approveGroupQuestion = async (
groupId: string,
questionId: number,
Expand Down
98 changes: 82 additions & 16 deletions src/api/services/question/group.api.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,21 @@
import { useSuspenseQuery } from '@tanstack/react-query'
import { useQuery, useSuspenseInfiniteQuery } from '@tanstack/react-query'

import { authorizationInstance } from '@/api/instance'
import { appendParamsToUrl } from '@/api/utils/common/appendParamsToUrl'
import { PagingRequestParams } from '@/types'

interface Question {
questionId: number
questionContent: string
status: 'READY' | 'APPROVED' | 'REJECTED'
}

export type GroupQuestionResponse = {
page: number
totalPages: number
content: Question[]
size: number
totalElements: number
questions: {
questionId: number
content: string
Expand All @@ -15,20 +28,6 @@ export type GroupQuestionResponse = {
}[]
}

const getGroupQuestion = async (groupId: number) => {
const response = await authorizationInstance.get<GroupQuestionResponse>(
`/api/group/${groupId}/question/random`
)

return response.data
}

export const useGroupQuestion = (groupId: number) => {
return useSuspenseQuery<GroupQuestionResponse>({
queryKey: ['group', groupId, 'question', 'random'],
queryFn: () => getGroupQuestion(groupId),
})
}
export type CreateGroupQuestionPayload = {
groupId: number
content: string
Expand All @@ -39,4 +38,71 @@ export const createGroupQuestion = async (
): Promise<string> => {
const response = await authorizationInstance.post('/api/group/question', data)
return response.data.message
}
}

const getGroupQuestions = async (
groupId: string,
status: 'READY' | 'APPROVED' | 'REJECTED',
page: number,
size: number
) => {
const response = await authorizationInstance.get(
`/api/group/${groupId}/question`,
{
params: { status, page, size },
}
)
return response.data
}

type GroupQuestionParams = {
groupId: string
status: 'READY' | 'APPROVED' | 'REJECTED'
} & PagingRequestParams

const getQuestionPaging = async (
groupId: number,
params: GroupQuestionParams
) => {
const response = await authorizationInstance.get<GroupQuestionResponse>(
appendParamsToUrl(`/api/group/${groupId}/question`, params)
)
const { data } = response
return {
data,
nextPageToken:
data.page !== data.totalPages - 1
? (data.page + 1).toString()
: undefined,
}
}

interface GroupQuestionPagingProps extends PagingRequestParams {
initPageToken?: string
groupId: string
status: 'READY' | 'APPROVED' | 'REJECTED'
}
export const useQuestionPaging = ({
size = 10,
sort,
groupId,
status,
initPageToken,
}: GroupQuestionPagingProps) => {
return useSuspenseInfiniteQuery({
queryKey: ['question', initPageToken],
queryFn: ({ pageParam = initPageToken }) =>
getQuestionPaging(Number(pageParam), { size, sort, groupId, status }),
initialPageParam: initPageToken,
getNextPageParam: (lastPage) => lastPage.nextPageToken,
})
}

export const useGroupQuestion = ({ groupId, status }: GroupQuestionParams) => {
return useQuery<GroupQuestionResponse>({
queryKey: ['groupQuestions', groupId, status],
queryFn: () => getGroupQuestions(groupId, status, 0, 10),
enabled: !!groupId,
staleTime: 0,
})
}
9 changes: 4 additions & 5 deletions src/components/RankingGraph/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ export const RankingGraph = ({ rank }: RankingGraphProps) => {
<HStack
spacing={12}
align="flex-start"
height="200px"
height="170px"
justifyContent="center"
marginTop="40px"
marginTop="20px"
>
{/* 왼쪽 그래프 */}
<HStack align="flex-end" spacing={6} height="100%">
<HStack align="flex-end" spacing={6} height="80%" marginTop="30px">
{sortedRank.map((item) => {
const percentage = (item.count / maxAmount) * 100

Expand Down Expand Up @@ -111,9 +111,8 @@ export const RankingGraph = ({ rank }: RankingGraphProps) => {
/>
)}
{!item.imageSrc && <div style={{ width: '60px' }} />}
<VStack align="flex-start" spacing={0} height="60px" width="250px">
<VStack align="flex-start" spacing={0} height="50px" width="250px">
{' '}
{/* 이미지 높이에 맞춰 텍스트 위아래 정렬 */}
<Text fontWeight="400" isTruncated width="100%">
{item.title}
</Text>
Expand Down
61 changes: 61 additions & 0 deletions src/pages/GroupPage/Management/Questions/QuestionList/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { Box, Radio, RadioGroup, Stack, Text } from '@chakra-ui/react'

import { Loading } from '@/components/Loading'

export interface Question {
questionId: number
questionContent: string
status: 'READY' | 'APPROVED' | 'REJECTED'
}

interface QuestionListProps {
questions: Question[]
isLoading: boolean
isError: boolean
onStatusChange: (questionId: number, approve: boolean) => void
}

export const QuestionList = ({
isLoading,
isError,
questions,
onStatusChange,
}: QuestionListProps) => {
if (isLoading) return <Loading />
if (isError) return <Text>질문을 불러오는 데 실패했습니다.</Text>
if (questions.length === 0) return <Text>질문이 없습니다.</Text>

return (
<Box maxHeight="400px" overflowY="scroll">
<Stack spacing="15px">
{questions.map((question) => (
<Box
key={question.questionId}
p="10px"
bg="white"
borderRadius="8px"
display="flex"
justifyContent="space-between"
alignItems="center"
>
<Text fontSize="16px" flex="1">
{question.questionContent}
</Text>
<RadioGroup
onChange={(value) => {
const approve = value === 'APPROVED'
onStatusChange(question.questionId, approve)
}}
value={question.status}
>
<Stack direction="row">
<Radio value="APPROVED" colorScheme="green" />
<Radio value="REJECTED" colorScheme="red" />
</Stack>
</RadioGroup>
</Box>
))}
</Stack>
</Box>
)
}
49 changes: 49 additions & 0 deletions src/pages/GroupPage/Management/Questions/StatusButton/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { Box, Button, Flex, Stack, Text } from '@chakra-ui/react'

interface StatusButtonsProps {
status: 'READY' | 'APPROVED' | 'REJECTED'
setStatus: (status: 'READY' | 'APPROVED' | 'REJECTED') => void
}

export const StatusButtons = ({ status, setStatus }: StatusButtonsProps) => {
return (
<Box mb="20px">
<Stack direction="row" spacing="15px">
<Button
onClick={() => setStatus('READY')}
colorScheme={status === 'READY' ? 'gray' : 'gray'}
variant={status === 'READY' ? 'solid' : 'outline'}
borderRadius="full"
>
승인 대기
</Button>
<Button
onClick={() => setStatus('APPROVED')}
colorScheme={status === 'APPROVED' ? 'green' : 'gray'}
variant={status === 'APPROVED' ? 'solid' : 'outline'}
borderRadius="full"
>
승인됨
</Button>
<Button
onClick={() => setStatus('REJECTED')}
colorScheme={status === 'REJECTED' ? 'red' : 'gray'}
variant={status === 'REJECTED' ? 'solid' : 'outline'}
borderRadius="full"
>
거절됨
</Button>
</Stack>
<Flex justifyContent="end">
<Text
fontSize="14px"
fontWeight="medium"
paddingRight="5px"
color="text_description"
>
승인 거절
</Text>
</Flex>
</Box>
)
}
Loading

0 comments on commit 3e2bffe

Please sign in to comment.