Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
25 changes: 24 additions & 1 deletion package-lock.json

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

3 changes: 2 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@
"react": "^19.1.1",
"react-dom": "^19.1.1",
"react-icons": "^5.5.0",
"react-router-dom": "^7.8.2"
"react-router-dom": "^7.8.2",
"react-toastify": "^11.0.5"
},
"devDependencies": {
"@eslint/js": "^9.33.0",
Expand Down
14 changes: 14 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Routes, Route } from 'react-router-dom';
import { ToastContainer, Bounce } from 'react-toastify';
import Home from './page/home';
import Login from './page/login';
import Event from './page/event';
Expand All @@ -13,6 +14,19 @@ const App: React.FC = () => {
<Route path='/event' element={<Event />} />
<Route path='*' element={<NotFound />} />
</Routes>
<ToastContainer
position="top-center"
autoClose={2500}
hideProgressBar={false}
newestOnTop={false}
closeOnClick={false}
rtl={false}
pauseOnFocusLoss
draggable
pauseOnHover
theme="colored"
transition={Bounce}
/>
</>
);
};
Expand Down
10 changes: 6 additions & 4 deletions src/api/activity/post-memebr-activities.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL;
import { showError } from '../../utils/alert';

export interface MemberActivityRequest {
activityId: number;
Expand Down Expand Up @@ -26,18 +27,19 @@ export async function PostMemberActivities(activityId: number, memberId: number)
if (!res.ok) {
switch (res.status) {
case 400:
alert("잘못된 요청입니다. 입력 데이터를 확인해주세요.");
showError("잘못된 요청입니다. 관리자에게 문의해주세요.");
break;
case 404:
alert("해당 활동 또는 회원을 찾을 수 없습니다.");
showError("해당 활동 또는 회원을 찾을 수 없습니다. 관리자에게 문의해주세요.");
break;
case 409:
alert("이미 참여한 활동입니다.");
showError("이미 참여한 활동입니다.");
break;
default:
alert("요청 처리 중 오류가 발생했습니다.");
showError("요청 처리 중 오류가 발생했습니다. 관리자에게 문의해주세요.");
break;
}
return false;
}

return true;
Expand Down
4 changes: 2 additions & 2 deletions src/api/auth/logout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export async function logout(): Promise<boolean> {
sessionStorage.clear(); // 환영 메시지 플래그도 함께 삭제됨
localStorage.removeItem('currentActivityId'); // 기존에 사용된 로컬스토리지 항목만 삭제

console.log("로그아웃 완료 - 모든 쿠키와 세션 정보가 삭제되었습니다.");
// console.log("로그아웃 완료 - 모든 쿠키와 세션 정보가 삭제되었습니다.");
return true;
} catch (err) {
console.error("로그아웃 처리 실패:", err);
Expand All @@ -47,7 +47,7 @@ export async function logout(): Promise<boolean> {
export function logoutWithSpecificCookie(cookieName: string): boolean {
try {
deleteCookie(cookieName);
console.log(`쿠키 '${cookieName}'이(가) 삭제되었습니다.`);
// console.log(`쿠키 '${cookieName}'이(가) 삭제되었습니다.`);
return true;
} catch (err) {
console.error("쿠키 삭제 실패:", err);
Expand Down
20 changes: 13 additions & 7 deletions src/api/auth/members.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const API_BASE_URL = import.meta.env.VITE_API_BASE_URL;
import { showError, showSuccess } from '../../utils/alert';

export async function Members(): Promise<boolean> {
try {
Expand All @@ -18,18 +19,23 @@ export async function Members(): Promise<boolean> {
const data = await res.json();

if (data.role === "ADMIN") {
// 세션 스토리지에서 환영 메시지 표시 여부 확인
const hasShownWelcome = sessionStorage.getItem('hasShownWelcome');
// 로그인 페이지에서는 환영 메시지를 표시하지 않음
const isLoginPage = window.location.pathname === '/login';

if (!hasShownWelcome) {
alert(`안녕하세요 ${data.name} 관리자님!`);
// 환영 메시지를 표시했다는 것을 세션 스토리지에 저장
sessionStorage.setItem('hasShownWelcome', 'true');
if (!isLoginPage) {
// 세션 스토리지에서 환영 메시지 표시 여부 확인
const hasShownWelcome = sessionStorage.getItem('hasShownWelcome');

if (!hasShownWelcome) {
showSuccess(`안녕하세요 ${data.name} 관리자님!`);
// 환영 메시지를 표시했다는 것을 세션 스토리지에 저장
sessionStorage.setItem('hasShownWelcome', 'true');
}
}

return true;
} else {
alert("로그인 실패! 관리자만 접근 가능합니다.");
showError("로그인 실패! 관리자만 접근 가능합니다.");
return false;
}
} catch (err) {
Expand Down
26 changes: 14 additions & 12 deletions src/components/EventTable.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useState } from 'react';
import QRScannerComponent from './QRScanner';
import { showError, showSuccess, showWarning } from '../utils/alert';
import { getActivityById, updateActivity } from '../api/activity/put-activities';
import { deleteActivity } from '../api/activity/delete-acitivites';
import { GetActivities } from '../api/activity/get-activities';
Expand All @@ -26,7 +27,7 @@ const EventTable: React.FC<EventTableProps> = ({ rows, setRows }) => {


const handleQRClose = () => {
// URL 파라미터에서 id 제거
// URL 파라미터에서 ID 제거
const url = new URL(window.location.href);
url.searchParams.delete('id');
window.history.pushState({}, '', url);
Expand Down Expand Up @@ -68,19 +69,20 @@ const EventTable: React.FC<EventTableProps> = ({ rows, setRows }) => {
setShowEditModal(true);
} else {
console.log('활동 정보를 찾을 수 없습니다.');
alert('활동 정보를 불러올 수 없습니다.');
showError('활동 정보를 불러올 수 없습니다.');
}
} catch (error) {
console.error('수정 모달 열기 오류:', error);
alert('오류가 발생했습니다.');
showError('오류가 발생했습니다.');
}
};

const handleDelete = async (activityId: number) => {
if (confirm('정말로 이 활동을 삭제하시겠습니까?')) {
const confirmed = await showWarning('정말로 이 활동을 삭제하시겠습니까?');
if (confirmed) {
const success = await deleteActivity(activityId);
if (success) {
alert('활동이 삭제되었습니다.');
showSuccess('활동이 삭제되었습니다.');
// 삭제 후 자동으로 정보 업데이트
const updatedActivities = await GetActivities();
const formattedRows = updatedActivities.map(activity => ({
Expand All @@ -90,7 +92,7 @@ const EventTable: React.FC<EventTableProps> = ({ rows, setRows }) => {
}));
setRows(formattedRows);
} else {
alert('삭제에 실패했습니다.');
showError('삭제에 실패했습니다.');
}
}
};
Expand All @@ -111,21 +113,21 @@ const EventTable: React.FC<EventTableProps> = ({ rows, setRows }) => {
e.preventDefault();

if (!eventName.trim()) {
alert('행사 이름을 입력하세요.');
showError('행사 이름을 입력하세요.');
return;
}

const pointValue = parseInt(pointAmount, 10);
if (isNaN(pointValue)) {
alert('올바른 포인트 값을 입력하세요.');
showError('올바른 포인트 값을 입력하세요.');
return;
}

if (editingActivityId) {
// 수정 모드
const success = await updateActivity(editingActivityId, eventName.trim(), pointValue);
if (success) {
alert('행사가 수정되었습니다.');
showSuccess('행사가 수정되었습니다.');
handleCloseModal();
// 수정 후 자동으로 정보 업데이트
const updatedActivities = await GetActivities();
Expand All @@ -136,13 +138,13 @@ const EventTable: React.FC<EventTableProps> = ({ rows, setRows }) => {
}));
setRows(formattedRows);
} else {
alert('행사 수정에 실패했습니다.');
showError('행사 수정에 실패했습니다.');
}
} else {
// 생성 모드
const success = await PostMemberActivities(eventName.trim(), pointValue);
if (success) {
alert('행사가 생성되었습니다.');
showSuccess('행사가 생성되었습니다.');
handleCloseModal();
// 생성 후 자동으로 정보 업데이트
const updatedActivities = await GetActivities();
Expand All @@ -153,7 +155,7 @@ const EventTable: React.FC<EventTableProps> = ({ rows, setRows }) => {
}));
setRows(formattedRows);
} else {
alert('행사 생성에 실패했습니다.');
showError('행사 생성에 실패했습니다.');
}
}
};
Expand Down
8 changes: 5 additions & 3 deletions src/components/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { IoLogOutOutline } from "react-icons/io5";
import AegisLogo from '../assets/logos/aegis.svg';
import { useNavigate } from "react-router-dom";
import { logout } from '../api/auth/logout';
import { showSuccess, showError, showCustomConfirm } from "../utils/alert";

const Header: React.FC = () => {
const navigate = useNavigate();
Expand All @@ -11,13 +12,14 @@ const Header: React.FC = () => {
}

const handleLogout = async () => {
if (confirm('로그아웃 하시겠습니까?')) {
const confirmed = await showCustomConfirm('로그아웃 하시겠습니까?');
if (confirmed) {
const success = await logout();
if (success) {
alert('로그아웃 되었습니다.');
showSuccess('로그아웃 되었습니다.');
window.location.href = '/login';
} else {
alert('로그아웃 중 오류가 발생했습니다.');
showError('로그아웃 중 오류가 발생했습니다.');
}
}
}
Expand Down
Loading