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

Hotfix #39

Merged
merged 19 commits into from
Sep 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 1 addition & 3 deletions .github/workflows/cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ jobs:
run: aws s3 sync ./dist s3://$BUCKET_NAME --delete

- name: CloudFront Invalidation
env:
CLOUD_FRONT_ID: ${{ secrets.AWS_CLOUDFRONT_ID}}
run: |
aws cloudfront create-invalidation \
--distribution-id $CLOUD_FRONT_ID --paths /*
--distribution-id ${{ secrets.AWS_CLOUDFRONT_ID}} --paths /*
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "dongbti",
"private": true,
"version": "1.0.1",
"version": "1.0.2",
"type": "module",
"scripts": {
"dev": "vite",
Expand Down
85 changes: 81 additions & 4 deletions serverless/dongbti/handler.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,46 @@ const departmentTypes = [
"undeclared",
];

const resultTypes = [
"intenseSportsman",
"coatSportsman",
"compatitionSportsman",
"fontSportsman",
"natureSportsman",
"matSportsman",
"fightSportsman",
"uniqueSportsman",
"10cm",
"tchaikovsky",
"stageMusician",
"mozart",
"parkHyoShin",
"newJeans",
"macGyver",
"cutieArtist",
"leedongjin",
"multiArtist",
"heatDebater",
"siliconValley",
"creator",
"winner",
"scholar",
"god",
"budda",
"hyunwoojin",
"philanthropist",
"teresa",
"american",
];

// 사용자의 MBTI와 학과를 저장하고 통계 업데이트
app.post("/stats", async (req, res) => {
const { department, mbti } = req.body;

if (!departmentTypes.includes(department))
return res.status(400).json({ status: 400, message: "department 의 값이 유효하지 않습니다" });
if (typeof mbti !== "string")
return res.status(400).json({ status: 400, message: "mbti 는 string 값이어야 합니다" });
if (!resultTypes.includes(mbti))
return res.status(400).json({ status: 400, message: "mbti 의 값이 유효하지 않습니다" });

const userId = uuid();

Expand All @@ -57,13 +89,33 @@ app.post("/stats", async (req, res) => {
}),
);

const stats = await db.send(
const totalStats = await db.send(
new GetCommand({
TableName: STATS_TABLE,
Key: { id: "total_count" },
}),
);
const total_count = stats.Item.total_count || 0;
const total_count = totalStats.Item.total_count || 0;

const mbtiStats = await db.send(
new GetCommand({
TableName: STATS_TABLE,
Key: { id: "mbti" },
}),
);
const mbtiCount = mbtiStats.Item[mbti];

await db.send(
new UpdateCommand({
TableName: STATS_TABLE,
Key: { id: "mbti" },
UpdateExpression: `set ${mbti} = :updated_count`,
ExpressionAttributeValues: {
":updated_count": mbtiCount + 1,
},
}),
);

await db.send(
new UpdateCommand({
TableName: STATS_TABLE,
Expand All @@ -82,6 +134,31 @@ app.post("/stats", async (req, res) => {
}
});

app.get("/stats", async (req, res) => {
const { type } = req.query;

if (!resultTypes.includes(type))
return res.status(400).json({ status: 400, message: "type 값은 string 이어야 합니다" });

const params = {
TableName: STATS_TABLE,
Key: { id: "mbti" },
};
try {
const data = await db.send(new GetCommand(params));
const totalCount = await db.send(
new GetCommand({
TableName: STATS_TABLE,
Key: { id: "total_count" },
}),
);
return res.status(200).json({ status: 200, count: data.Item[type], total_count: totalCount.Item.total_count });
} catch (e) {
console.error(e);
return res.status(500).json({ status: 500, message: "서버 내부 오류 발생" });
}
});

// 총 사용자 수 조회
app.get("/stats/total", async (req, res) => {
const params = {
Expand Down
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
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.department}`)
.then((data) => {
setTop10ByDepartment({ top: data.data.top });
console.log(data.data.top);
})
.catch(() => {
setIsError(true);
})
.finally(() => {
setIsPending(false);
});
}, [department.department]);

return { isPending, isError, top10ByDepartment };
};
11 changes: 7 additions & 4 deletions src/hooks/useTotalStats.tsx → src/hooks/useTotalCount.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,21 @@ import { useEffect, useState } from "react";

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

interface TotalStatsResponse {
interface TotalCountResponse {
status: number;
total_count: number;
}

export const useTotalStats = () => {
export const useTotalCount = () => {
const [totalCount, setTotalCount] = useState<number | null>(null);
const [isPending, setIsPending] = useState<boolean>(false);
const [isError, setIsError] = useState<boolean>(false);
const [totalCount, setTotalCount] = useState<number>(0);

useEffect(() => {
setIsPending(true);
api.get<TotalStatsResponse>(`/stats/total`)
setIsError(false);

api.get<TotalCountResponse>(`/stats/total`)
.then((data) => {
setTotalCount(data.data.total_count);
})
Expand Down
7 changes: 1 addition & 6 deletions src/main.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,5 @@
import React from "react";
import ReactDOM from "react-dom/client";

import App from "./App.tsx";

ReactDOM.createRoot(document.getElementById("root")!).render(
<React.StrictMode>
<App />
</React.StrictMode>,
);
ReactDOM.createRoot(document.getElementById("root")!).render(<App />);
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
Loading