Add, user modify
This commit is contained in:
@ -10,6 +10,7 @@ import PostCreate from "./pages/PostCreate";
|
|||||||
import PostEdit from "./pages/PostEdit";
|
import PostEdit from "./pages/PostEdit";
|
||||||
import PostCategory from "./pages/PostCategory";
|
import PostCategory from "./pages/PostCategory";
|
||||||
import Login from "./pages/Login";
|
import Login from "./pages/Login";
|
||||||
|
import Profile from "./pages/Profile";
|
||||||
import { AuthProvider } from "./context/AuthContext";
|
import { AuthProvider } from "./context/AuthContext";
|
||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
@ -28,6 +29,7 @@ function App() {
|
|||||||
<Route path="/posts/:id/edit" element={<PostEdit />} />
|
<Route path="/posts/:id/edit" element={<PostEdit />} />
|
||||||
<Route path="/post/:category" element={<PostCategory />} />
|
<Route path="/post/:category" element={<PostCategory />} />
|
||||||
<Route path="/login" element={<Login />} />
|
<Route path="/login" element={<Login />} />
|
||||||
|
<Route path="/profile" element={<Profile />} />
|
||||||
</Routes>
|
</Routes>
|
||||||
</main>
|
</main>
|
||||||
<Footer />
|
<Footer />
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { Link, useNavigate } from 'react-router-dom';
|
import { Link, useNavigate } from 'react-router-dom';
|
||||||
import { useAuth } from '../context/AuthContext'; // ✅ Context에서 로그인 상태 사용
|
import { useAuth } from '../context/AuthContext';
|
||||||
|
|
||||||
const Navbar = () => {
|
const Navbar = () => {
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
const { isLoggedIn, logout } = useAuth();
|
const { isLoggedIn, logout } = useAuth();
|
||||||
|
|
||||||
// ✅ 'board' → 'posts'로 변경
|
|
||||||
const menuItems = ['home', 'about', 'posts', 'paas', 'infra'];
|
const menuItems = ['home', 'about', 'posts', 'paas', 'infra'];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
@ -26,7 +25,14 @@ const Navbar = () => {
|
|||||||
</Link>
|
</Link>
|
||||||
))}
|
))}
|
||||||
|
|
||||||
{isLoggedIn ? (
|
{isLoggedIn && (
|
||||||
|
<>
|
||||||
|
<Link
|
||||||
|
to="/profile"
|
||||||
|
className="text-gray-600 hover:text-[#3B82F6]"
|
||||||
|
>
|
||||||
|
내 정보
|
||||||
|
</Link>
|
||||||
<button
|
<button
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
logout();
|
logout();
|
||||||
@ -36,7 +42,10 @@ const Navbar = () => {
|
|||||||
>
|
>
|
||||||
로그아웃
|
로그아웃
|
||||||
</button>
|
</button>
|
||||||
) : (
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{!isLoggedIn && (
|
||||||
<Link
|
<Link
|
||||||
to="/login"
|
to="/login"
|
||||||
className="bg-[#3B82F6] text-white px-4 py-2 rounded hover:bg-blue-700"
|
className="bg-[#3B82F6] text-white px-4 py-2 rounded hover:bg-blue-700"
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
// ./src/pages/Login.js
|
||||||
import React, { useState } from 'react';
|
import React, { useState } from 'react';
|
||||||
import { useNavigate } from 'react-router-dom';
|
import { useNavigate } from 'react-router-dom';
|
||||||
import authApi from '../api/authApi';
|
import authApi from '../api/authApi';
|
||||||
|
53
src/pages/Profile/EditForm.js
Normal file
53
src/pages/Profile/EditForm.js
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import React from 'react';
|
||||||
|
|
||||||
|
function EditForm({ form, onChange, onSubmit }) {
|
||||||
|
return (
|
||||||
|
<form onSubmit={onSubmit} className="bg-white p-8 rounded shadow-md w-full max-w-md mx-auto">
|
||||||
|
<h2 className="text-2xl font-bold mb-6 text-center text-[#3B82F6]">회원정보 수정</h2>
|
||||||
|
|
||||||
|
<div className="mb-4">
|
||||||
|
<label className="block text-sm font-medium text-gray-700 mb-1">이름</label>
|
||||||
|
<input
|
||||||
|
name="name"
|
||||||
|
value={form.name}
|
||||||
|
onChange={onChange}
|
||||||
|
className="w-full px-4 py-2 border border-gray-300 rounded"
|
||||||
|
placeholder="이름을 입력하세요"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mb-4">
|
||||||
|
<label className="block text-sm font-medium text-gray-700 mb-1">이메일</label>
|
||||||
|
<input
|
||||||
|
name="email"
|
||||||
|
type="email"
|
||||||
|
value={form.email}
|
||||||
|
onChange={onChange}
|
||||||
|
className="w-full px-4 py-2 border border-gray-300 rounded"
|
||||||
|
placeholder="이메일을 입력하세요"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className="mb-6">
|
||||||
|
<label className="block text-sm font-medium text-gray-700 mb-1">설명</label>
|
||||||
|
<textarea
|
||||||
|
name="desc"
|
||||||
|
value={form.desc}
|
||||||
|
onChange={onChange}
|
||||||
|
rows="4"
|
||||||
|
className="w-full px-4 py-2 border border-gray-300 rounded"
|
||||||
|
placeholder="자기소개 또는 간단한 설명을 입력하세요"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<button
|
||||||
|
type="submit"
|
||||||
|
className="w-full bg-[#3B82F6] text-white py-2 rounded hover:bg-blue-700 transition"
|
||||||
|
>
|
||||||
|
수정
|
||||||
|
</button>
|
||||||
|
</form>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default EditForm;
|
58
src/pages/Profile/index.js
Normal file
58
src/pages/Profile/index.js
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
import React, { useEffect, useState } from 'react';
|
||||||
|
import { useNavigate } from 'react-router-dom';
|
||||||
|
import EditForm from './EditForm';
|
||||||
|
import authApi from '../../api/authApi';
|
||||||
|
|
||||||
|
function ProfilePage() {
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
|
const [form, setForm] = useState({
|
||||||
|
name: '',
|
||||||
|
email: '',
|
||||||
|
desc: '' // ✅ desc 상태 추가
|
||||||
|
});
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const token = localStorage.getItem('access');
|
||||||
|
if (!token) {
|
||||||
|
navigate('/login');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const fetchUser = async () => {
|
||||||
|
try {
|
||||||
|
const res = await authApi.get('/api/auth/me/');
|
||||||
|
const { name, email, desc } = res.data;
|
||||||
|
setForm({ name, email, desc }); // ✅ desc 상태 반영
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
navigate('/login');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
fetchUser();
|
||||||
|
}, [navigate]);
|
||||||
|
|
||||||
|
const handleChange = (e) => {
|
||||||
|
setForm({ ...form, [e.target.name]: e.target.value });
|
||||||
|
};
|
||||||
|
|
||||||
|
const handleSubmit = async (e) => {
|
||||||
|
e.preventDefault();
|
||||||
|
try {
|
||||||
|
await authApi.put('/api/auth/me/', form); // ✅ desc 포함해서 PUT
|
||||||
|
alert('회원정보가 수정되었습니다.');
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
alert('수정 실패');
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="container mt-5">
|
||||||
|
<EditForm form={form} onChange={handleChange} onSubmit={handleSubmit} />
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default ProfilePage;
|
Reference in New Issue
Block a user