개인정보-컴플라이언스-웹애플리케이션(10) - (시스템) 프론트 코드
2025. 1. 28. 22:37ㆍ프로젝트
728x90
반응형
import React from "react";
import axios from "axios";
import { useNavigate } from "react-router-dom";
import { useRecoilValue, useRecoilState } from "recoil";
import { authState } from "../../state/authState";
import { formState } from "../../state/formState";
function SystemRegistration() {
const auth = useRecoilValue(authState); // 로그인된 사용자 정보 가져오기
const [formData, setFormData] = useRecoilState(formState); // 전역 상태 관리
const navigate = useNavigate();
// 폼 데이터 변경 핸들러
const handleChange = (e) => {
const { name, value } = e.target;
setFormData((prevState) => ({
...prevState,
[name]: value || "", // 기본값 설정
}));
};
// 폼 제출 핸들러
const handleSubmit = async (e) => {
e.preventDefault();
try {
if (!auth.user || !auth.user.id) {
alert("사용자 정보가 없습니다. 다시 로그인해주세요.");
return;
}
console.log("🚀 [POST] 요청 데이터:", {
...formData,
user_id: auth.user.id,
});
console.log("📋 [DEBUG] reason 값:", formData.reason);
const response = await axios.post(
"http://localhost:3000/systems",
{ ...formData, user_id: auth.user.id },
{
withCredentials: true,
}
);
console.log("✅ [POST] 응답 데이터:", response.data);
alert("시스템 등록이 완료되었습니다!");
navigate("/dashboard"); // 등록 완료 후 대시보드로 이동
} catch (error) {
console.error(
"❌ [POST] 에러 응답:",
error.response?.data || error.message
);
alert(error.response?.data?.message || "시스템 등록 실패");
}
};
return (
<div className="min-h-screen flex items-center justify-center bg-gray-100">
<div className="bg-white p-6 rounded-lg shadow-md w-3/4 max-w-2xl">
<h1 className="text-3xl font-bold mb-6">시스템 등록 확인</h1>
<form onSubmit={handleSubmit} className="space-y-4">
<div>
<label className="block text-gray-700 font-medium">
시스템 이름
</label>
<input
type="text"
name="name"
value={formData.name || ""}
onChange={handleChange}
className="w-full p-2 border rounded"
placeholder="시스템 이름을 입력하세요"
required
/>
</div>
<div>
<label className="block text-gray-700 font-medium">
최소 문항 수
</label>
<input
type="number"
name="min_subjects"
value={formData.min_subjects || ""}
onChange={handleChange}
className="w-full p-2 border rounded"
placeholder="최소 문항 수를 입력하세요"
required
/>
</div>
<div>
<label className="block text-gray-700 font-medium">
최대 문항 수
</label>
<input
type="number"
name="max_subjects"
value={formData.max_subjects || ""}
onChange={handleChange}
className="w-full p-2 border rounded"
placeholder="최대 문항 수를 입력하세요"
required
/>
</div>
<div>
<label className="block text-gray-700 font-medium">처리 목적</label>
<input
type="text"
name="purpose"
value={formData.purpose || ""}
onChange={handleChange}
className="w-full p-2 border rounded"
placeholder="처리 목적을 입력하세요"
required
/>
</div>
<div>
<label className="block text-gray-700 font-medium">
민감 정보 포함 여부
</label>
<select
name="is_private"
value={formData.is_private || "포함"}
onChange={handleChange}
className="w-full p-2 border rounded"
>
<option value="포함">포함</option>
<option value="미포함">미포함</option>
</select>
</div>
<div>
<label className="block text-gray-700 font-medium">
고유 식별 정보 포함 여부
</label>
<select
name="is_unique"
value={formData.is_unique || "미포함"}
onChange={handleChange}
className="w-full p-2 border rounded"
>
<option value="포함">포함</option>
<option value="미포함">미포함</option>
</select>
</div>
<div>
<label className="block text-gray-700 font-medium">
주민등록번호 포함 여부
</label>
<select
name="is_resident"
value={formData.is_resident || "포함"}
onChange={handleChange}
className="w-full p-2 border rounded"
>
<option value="포함">포함</option>
<option value="미포함">미포함</option>
</select>
</div>
<div>
<label className="block text-gray-700 font-medium">수집 근거</label>
<select
name="reason"
value={formData.reason || "동의"}
onChange={handleChange}
className="w-full p-2 border rounded"
>
<option value="동의">동의</option>
<option value="법적 근거">법적 근거</option>
<option value="기타">기타</option>
</select>
</div>
<button
type="submit"
className="w-full px-4 py-2 bg-blue-600 text-white rounded hover:bg-blue-700"
>
확인
</button>
</form>
</div>
</div>
);
}
export default SystemRegistration;
이 코드는 Recoil을 사용하여 일반 사용자가 시스템 등록을 처리하는 페이지입니다.
사용자는 입력 폼을 통해 시스템 정보를 입력하고, 해당 데이터를 서버에 전송하여 등록 요청을 처리합니다.
아래는 코드의 각 부분을 상세히 분석한 내용입니다.
1. 전역 상태 및 기본 설정
const auth = useRecoilValue(authState); // 로그인된 사용자 정보
const [formData, setFormData] = useRecoilState(formState); // 폼 데이터 상태
const navigate = useNavigate(); // 페이지 이동을 위한 훅
authState: 로그인된 사용자 정보를 가져오는 Recoil 상태입니다.
formState: 입력된 폼 데이터를 전역에서 관리하기 위한 Recoil 상태입니다.
navigate: 사용자가 등록을 완료하거나 오류가 발생했을 때 페이지를 이동시키는 함수입니다.
2. 폼 데이터 관리
const handleChange = (e) => {
const { name, value } = e.target;
setFormData((prevState) => ({
...prevState,
[name]: value || "", // 기본값 설정
}));
};
사용자가 입력한 값(value)을 해당 입력 필드의 이름(name)과 매핑하여 formData 상태에 저장합니다.
입력값이 비어 있을 경우 기본값으로 빈 문자열을 저장합니다.
폼 제출 핸들러
const handleSubmit = async (e) => {
e.preventDefault(); // 폼 제출 시 페이지 리로드 방지
try {
if (!auth.user || !auth.user.id) {
alert("사용자 정보가 없습니다. 다시 로그인해주세요.");
return;
}
console.log("🚀 [POST] 요청 데이터:", {
...formData,
user_id: auth.user.id,
});
console.log("📋 [DEBUG] reason 값:", formData.reason);
const response = await axios.post(
"http://localhost:3000/systems",
{ ...formData, user_id: auth.user.id }, // 사용자 ID 포함
{ withCredentials: true } // 쿠키 인증 포함
);
console.log("✅ [POST] 응답 데이터:", response.data);
alert("시스템 등록이 완료되었습니다!");
navigate("/dashboard"); // 성공 시 대시보드로 이동
} catch (error) {
console.error(
"❌ [POST] 에러 응답:",
error.response?.data || error.message
);
alert(error.response?.data?.message || "시스템 등록 실패");
}
};
1. 입력값 검증:
사용자 정보(auth.user.id)가 없으면 경고 메시지를 출력하고 종료.
2. API 요청:
서버에 formData와 사용자 ID를 포함한 데이터를 전송.
3. withCredentials: true:
서버로 인증 쿠키를 함께 전송하여 사용자를 인증.
4. 요청 성공:
성공 메시지를 출력하고 /dashboard 페이지로 이동.
요청 실패:
오류 메시지를 출력하며, 서버에서 제공한 메시지가 없으면 기본 메시지를 사용.
'프로젝트' 카테고리의 다른 글
개인정보-컴플라이언스-웹애플리케이션(12) - (자가진단 정량문항,정성문항) 프론트 코드 (0) | 2025.01.29 |
---|---|
개인정보-컴플라이언스-웹애플리케이션(11) - (자가진단 설문) 프론트 코드 (0) | 2025.01.29 |
개인정보-컴플라이언스-웹애플리케이션(9) - (회원가입 로그인) 프론트 코드 (0) | 2025.01.28 |
개인정보-컴플라이언스-웹애플리케이션(8) - (피드백) 백엔드 코드 (0) | 2025.01.26 |
개인정보-컴플라이언스-웹애플리케이션(7) - (자가진단 설문 결과) 백엔드 코드 (0) | 2025.01.26 |