Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refact: 통계 페이지 커스텀 훅 수정, UI 수정 #38

Closed
wants to merge 8 commits into from
12 changes: 9 additions & 3 deletions src/components/form/DropDown.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,17 @@ export interface DropDownProps {
color: string;
width: string;
height: string;
selectedMajor?: string;
setSelectedMajor?: React.Dispatch<React.SetStateAction<string>>;
selectedDepartment?: string;
setSelectedDepartment?: React.Dispatch<React.SetStateAction<string>>;
}

export default function DropDown({ color, width, height, selectedMajor, setSelectedMajor }: DropDownProps) {
export default function DropDown({
color,
width,
height,
selectedDepartment: selectedMajor,
setSelectedDepartment: setSelectedMajor,
}: DropDownProps) {
const majors = [
{ label: "📖 인문대학", value: "humanities" },
{ label: "📋 사회과학대학", value: "social-sciences" },
Expand Down
6 changes: 6 additions & 0 deletions src/config/axios.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import axios from "axios";

export const api = axios.create({
baseURL: "https://api.dongbti.com",
withCredentials: true,
});
30 changes: 30 additions & 0 deletions src/hooks/useTop10.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import { useEffect, useState } from "react";

import { top10Response } from "@/pages/AnalyticsPage";

import { api } from "@/config/axios";

export const useTop10 = () => {
const [top10, setTop10] = useState<top10Response | null>(null);
const [isPending, setIsPending] = useState<boolean>(false);
const [isError, setIsError] = useState<boolean>(false);

useEffect(() => {
setIsPending(true);
setIsError(false);

api.get<top10Response>(`/stats/top/mbti`)
.then((data) => {
setTop10({ top: data.data.top });
console.log(data.data.top);
})
.catch(() => {
setIsError(true);
})
.finally(() => {
setIsPending(false);
});
}, []);

return { isPending, isError, top10 };
};
34 changes: 34 additions & 0 deletions src/hooks/useTop10ByDepartment.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import { useState, useEffect } from "react";

import { top10Response } from "@/pages/AnalyticsPage";

import { api } from "@/config/axios";

interface top10ByDepartmentProps {
department: string;
}

export const useTop10ByDepartment = (department: top10ByDepartmentProps) => {
const [top10ByDepartment, setTop10ByDepartment] = useState<top10Response | null>(null);
const [isPending, setIsPending] = useState<boolean>(false);
const [isError, setIsError] = useState<boolean>(false);

useEffect(() => {
setIsPending(true);
setIsError(false);

api.get<top10Response>(`/stats/top/department?key=${department}`)
.then((data) => {
setTop10ByDepartment({ top: data.data.top });
console.log(data.data.top);
})
.catch(() => {
setIsError(true);
})
.finally(() => {
setIsPending(false);
});
}, [department]);

return { isPending, isError, top10ByDepartment };
};
4 changes: 2 additions & 2 deletions src/pages/AnalyticsPage.style.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@ export const TitleContainer = styled.div`

export const TitleTop = styled.div`
display: flex;
width: 60%;
align-items: center;
justify-content: flex-start;
justify-content: center;
flex-direction: row;
`;

export const Main = styled.div``;
Expand Down
76 changes: 38 additions & 38 deletions src/pages/AnalyticsPage.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,26 @@
import React from "react";
import { useState, useEffect } from "react";
import { useNavigate } from "react-router-dom";

import Footer from "@/components/display/Footer";
import DropDown from "@/components/form/DropDown";
import TopBar from "@/components/layout/TopBar";
import { Text } from "@/components/typography";

import useAxios from "@/hooks/useAxios";
import { useTop10 } from "@/hooks/useTop10";
import { useTop10ByDepartment } from "@/hooks/useTop10ByDepartment";

import backIcon from "@/assets/back.svg";

import { TitleContainer, TitleTop, Main, MiddleSection, TableContainer, Card, Rank, Type } from "./AnalyticsPage.style";

interface axiosProps {
top: Array<[number, string]>;
export interface top10Response {
top: [string, number][];
}

const renderData = (data: axiosProps | null, loading: boolean, error: any) => {
if (loading) return <Text size="m">Loading...</Text>;
if (error) return <Text size="m">Error: {error.message}</Text>;
if (data?.top.length == 0) {
const renderData = (data: top10Response | null, isPending: boolean, isError: any) => {
if (isPending) return <Text size="m">로딩중...</Text>;
if (isError) return <Text size="m">오류가 발생했습니다.</Text>;
if (!data) {
return (
<Text size="m" color="secondary">
데이터가 존재하지 않습니다.
Expand All @@ -41,65 +43,63 @@
};

export default function AnalyticsPage() {
const [selectedMajor, setSelectedMajor] = React.useState<string>("humanities");
const [selectedDepartment, setSelectedDepartment] = useState<string>("");
const navigate = useNavigate();

const handleGoBack = () => {
navigate("/");
};

const { top10, isPending: top10Loading, isError: top10Error } = useTop10();
const {
data: allData,
loading: allDataLoading,
error: allDataError,
} = useAxios<axiosProps | null>(
{
url: `/stats/top/mbti`,
method: "GET",
},
[],
);
top10ByDepartment,
isPending: top10ByDepartmentLoading,
isError: top10ByDepartmentError,
} = useTop10ByDepartment(selectedDepartment);

Check failure on line 58 in src/pages/AnalyticsPage.tsx

View workflow job for this annotation

GitHub Actions / e2e

Argument of type 'string' is not assignable to parameter of type 'top10ByDepartmentProps'.

const {
data: majorData,
loading: majorDataLoading,
error: majorDataError,
} = useAxios<axiosProps | null>(
{
url: `/stats/top/department?key=${selectedMajor}`,
method: "GET",
},
[selectedMajor],
);
useEffect(() => {
if (selectedDepartment) {
setSelectedDepartment(selectedDepartment);
}
}, [selectedDepartment]);

return (
<>
<img src={backIcon} onClick={handleGoBack} />
<TopBar title="전체 통계" />

<TitleContainer>
<Text size="m">어떤 유형이 가장 많을까요?</Text>
<Text size="m" weight="bold">
어떤 유형이 가장 많을까요?
</Text>
</TitleContainer>

<Main>{renderData(allData, allDataLoading, allDataError)}</Main>
<Main>{renderData(top10, top10Loading, top10Error)}</Main>

<MiddleSection />

<TitleContainer>
<TitleTop>
<DropDown
color="secondary"
width="100%"
width="160px"
height="40px"
selectedMajor={selectedMajor}
setSelectedMajor={setSelectedMajor}
selectedDepartment={selectedDepartment}
setSelectedDepartment={setSelectedDepartment}
/>
<Text size="m">에서</Text>
<Text size="m" weight="bold">
에서
</Text>
</TitleTop>

<Text size="m">어떤 유형이 가장 많을까요?</Text>
<Text size="m" weight="bold">
어떤 유형이 가장 많을까요?
</Text>
</TitleContainer>
<Main>{renderData(majorData, majorDataLoading, majorDataError)}</Main>
<Main>
{selectedDepartment && renderData(top10ByDepartment, top10ByDepartmentLoading, top10ByDepartmentError)}
</Main>
<Footer />
</>
);
}
Loading