Skip to content

Commit

Permalink
모든 api 기능 구현 (#46)
Browse files Browse the repository at this point in the history
모든 api 기능 구현
  • Loading branch information
Dobbymin authored Nov 9, 2024
2 parents 968b88c + 7617743 commit 2a56b99
Show file tree
Hide file tree
Showing 15 changed files with 110 additions and 108 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,8 @@ export const QRCodeScannerPage = () => {
alert("QR Code가 정상적으로 스캔되었습니다.");

try {
// JSON 파싱
const parsedData = JSON.parse(result.text);

// studentId 추출
const studentId = parsedData.studentId;
setScannedStudentId(studentId);
} catch (error) {
Expand All @@ -33,9 +31,6 @@ export const QRCodeScannerPage = () => {
}
};

console.log(scannedData);
console.log(typeof scannedStudentId);

return (
<div className="p-4 space-y-4">
<h2 className="text-xl font-semibold">QR Code Scanner</h2>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@ import { useMutation } from "@tanstack/react-query";
export const useDeleteInfo = (id: number) => {
return useMutation({
mutationFn: () => deleteInfo(id),
onSuccess: () => {
alert("참가자 정보가 삭제되었습니다.");
},
onError: (error) => {
console.error(error);
alert("참가자 정보 삭제에 실패했습니다.");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,20 +1,16 @@
import { putDepositCheck, putDepositCheckPath } from "../deposit-check";
import { putDepositCheck } from "../deposit-check";
import { DepositCheckResponse } from "../types";
import { queryClient } from "@/shared";
import { useMutation, UseMutationResult } from "@tanstack/react-query";

const putDepositCheckQueryKey = [putDepositCheckPath];

export const usePutDepositCheck = (id: number): UseMutationResult<DepositCheckResponse, Error, void> => {
return useMutation<DepositCheckResponse, Error, void>({
mutationFn: () => putDepositCheck(id),
onSuccess: () => {
queryClient.invalidateQueries({ queryKey: [putDepositCheckQueryKey, id] });
alert("승인 상태로 변경되었습니다.");
alert("입금 완료로 상태가 변경되었습니다.");
},
onError: (error) => {
console.error("승인 상태 변경에 실패했습니다.", error);
alert("승인 상태 변경에 실패했습니다.");
console.error("입금 완료 상태 변경에 실패했습니다.", error);
alert("입금 완료 상태 변경에 실패했습니다.");
},
});
};
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
import { useState, useEffect } from "react";

import {
InputField,
PeopleTable,
useUpdatePersonStatus,
useFilteredPeople,
useGetApplicantList,
ApplyPeople,
} from "@/features";
import { InputField, PeopleTable, useFilteredPeople, useGetApplicantList, ApplyPeople } from "@/features";

export const MainContents = () => {
const [searchTerm, setSearchTerm] = useState("");
Expand All @@ -21,8 +14,6 @@ export const MainContents = () => {
}
}, [data]);

const updatePersonStatus = useUpdatePersonStatus(people, setPeople);

const filteredPeople = useFilteredPeople(people, searchTerm);

return (
Expand All @@ -31,7 +22,6 @@ export const MainContents = () => {
<InputField searchTerm={searchTerm} setSearchTerm={setSearchTerm} />
<PeopleTable
people={filteredPeople}
updatePersonStatus={updatePersonStatus}
isLoading={isLoading}
hasNextPage={hasNextPage}
fetchNextPage={fetchNextPage}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
type Props = {
checkined: boolean;
};

export const CheckInStatus = ({ checkined }: Props) => (
<span
className={`inline-flex items-center px-3 py-1 rounded-full text-sm font-medium ${
checkined ? "bg-blue-100 text-blue-800" : "bg-gray-100 text-gray-800"
}`}
>
{checkined ? "체크인됨" : "미체크인"}
</span>
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { X } from "lucide-react";

import { useDeleteInfo } from "../../api";

type Props = {
id: number;
name: string;
};

export const DeleteButton = ({ id, name }: Props) => {
const { mutate: deleteInfo } = useDeleteInfo(id);

const deletePerson = () => {
const isConfirmed = window.confirm(`${name}님을 정말 삭제하시겠습니까?`);

if (isConfirmed) {
deleteInfo();
}
};

return (
<button className="text-red-600 hover:text-red-900" onClick={deletePerson}>
<X className="w-5 h-5" />
</button>
);
};
Original file line number Diff line number Diff line change
@@ -1,19 +1,17 @@
import { useState, useRef, useEffect, useCallback } from "react";

import { ChevronDown } from "lucide-react";

import { ApplyPeople } from "@/features";
import { ApplyPeople, CheckInStatus, DeleteButton, StatusButton, TABLE_HEADERS } from "@/features";

type Props = {
people?: ApplyPeople[];
isLoading: boolean;
hasNextPage: boolean;
fetchNextPage: () => void;
updatePersonStatus: (id: number, status: "accepted" | "rejected" | "checkedIn" | "checkedOut") => void;
};

export const PeopleTable = ({ people, updatePersonStatus, isLoading, hasNextPage, fetchNextPage }: Props) => {
export const PeopleTable = ({ people, isLoading, hasNextPage, fetchNextPage }: Props) => {
const [applyPeople, setApplyPeople] = useState<ApplyPeople[]>([]);

const observer = useRef<IntersectionObserver | null>(null);

useEffect(() => {
Expand Down Expand Up @@ -41,27 +39,14 @@ export const PeopleTable = ({ people, updatePersonStatus, isLoading, hasNextPage
<table className="w-full">
<thead>
<tr className="bg-gray-50">
<th className="px-6 py-3 text-xs font-medium tracking-wider text-left text-gray-500 uppercase">
이름
</th>
<th className="px-6 py-3 text-xs font-medium tracking-wider text-left text-gray-500 uppercase">
학번
</th>
<th className="px-6 py-3 text-xs font-medium tracking-wider text-left text-gray-500 uppercase">
전화번호
</th>
<th className="px-6 py-3 text-xs font-medium tracking-wider text-left text-gray-500 uppercase">
팀 이름
</th>
<th className="px-6 py-3 text-xs font-medium tracking-wider text-left text-gray-500 uppercase">
전공
</th>
<th className="px-6 py-3 text-xs font-medium tracking-wider text-left text-gray-500 uppercase">
승인
</th>
<th className="px-6 py-3 text-xs font-medium tracking-wider text-left text-gray-500 uppercase">
체크인/아웃
</th>
{TABLE_HEADERS.map((header) => (
<th
key={header.key}
className="px-6 py-3 text-xs font-medium tracking-wider text-left text-gray-500 uppercase"
>
{header.label}
</th>
))}
</tr>
</thead>
<tbody className="bg-white divide-y divide-gray-200">
Expand Down Expand Up @@ -102,38 +87,17 @@ export const PeopleTable = ({ people, updatePersonStatus, isLoading, hasNextPage
<td className="px-6 py-4 whitespace-nowrap">{person.teamName}</td>
<td className="px-6 py-4 whitespace-nowrap">{person.major}</td>
<td className="px-6 py-4 whitespace-nowrap">
<button
className={`inline-flex items-center px-3 py-1 rounded-full text-sm font-medium ${
person.accepted
? "bg-green-100 text-green-800"
: "bg-yellow-100 text-yellow-800"
}`}
onClick={() =>
updatePersonStatus(person.id, person.accepted ? "rejected" : "accepted")
}
>
{person.accepted ? "승인됨" : "미승인"}
<ChevronDown className="w-4 h-4 ml-1" />
</button>
<StatusButton
accepted={person.accepted}
id={person.studentId}
// onClick={() => handleStatusChange(person.studentId, person.accepted)}
/>
</td>
<td className="px-6 py-4 whitespace-nowrap">
<CheckInStatus checkined={person.checkined} />
</td>
<td className="px-6 py-4 whitespace-nowrap">
<button
className={`inline-flex items-center px-3 py-1 rounded-full text-sm font-medium ${
person.checkined
? "bg-blue-100 text-blue-800"
: "bg-gray-100 text-gray-800"
}`}
onClick={() =>
updatePersonStatus(
person.id,
person.checkined ? "checkedOut" : "checkedIn",
)
}
disabled={!person.accepted}
>
{person.checkined ? "체크인됨" : "미체크인"}
<ChevronDown className="w-4 h-4 ml-1" />
</button>
<DeleteButton id={person.studentId} name={person.name} />
</td>
</tr>
))}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { ChevronDown } from "lucide-react";

import { usePutDepositCheck } from "../../api";

type Props = {
accepted: boolean;
id: number;
};

export const StatusButton = ({ accepted, id }: Props) => {
const { mutate: updatePersonStatus } = usePutDepositCheck(id);
const handleChangeStatus = () => {
updatePersonStatus();
};

return (
<button
className={`inline-flex items-center px-3 py-1 rounded-full text-sm font-medium ${
accepted ? "bg-green-100 text-green-800" : "bg-yellow-100 text-yellow-800"
}`}
onClick={handleChangeStatus}
>
{accepted ? "입금 완료" : "입금 전"}
<ChevronDown className="w-4 h-4 ml-1" />
</button>
);
};
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
export { InputField } from "./InputField";
export { PeopleTable } from "./PeopleTable";
export { StatusButton } from "./StatusButton";
export { CheckInStatus } from "./CheckInStatus";
export { DeleteButton } from "./DeleteButton";
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./table-header";
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
export const TABLE_HEADERS = [
{ label: "이름", key: "name" },
{ label: "학번", key: "studentId" },
{ label: "전화번호", key: "phoneNumber" },
{ label: "팀 이름", key: "teamName" },
{ label: "전공", key: "major" },
{ label: "입금 확인", key: "accepted" },
{ label: "체크인 상태", key: "checkined" },
{ label: "삭제", key: "delete" },
];
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { TABLE_HEADERS } from "./TableHeader";
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
export { useFilteredPeople } from "./useFilteredPeople";
export { useUpdatePersonStatus } from "./useUpdatePersonStatus";

This file was deleted.

1 change: 1 addition & 0 deletions packages/admin/src/features/people-management/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from "./api";
export * from "./data";
export * from "./hook";
export * from "./components";
export * from "./ui";

0 comments on commit 2a56b99

Please sign in to comment.