Skip to content

Commit 1d52547

Browse files
committed
게시판 댓글 수정 버전
1 parent afc06e1 commit 1d52547

122 files changed

Lines changed: 196 additions & 8226 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.screen-graph.json

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -178,15 +178,15 @@
178178
}
179179
},
180180
{
181-
"id": "src\\screens\\Desktop\\sections\\IngredientInventory\\IngredientInventory.jsx:74:8-to-src\\screens\\AddIngredientPage\\AddIngredientPage.jsx",
181+
"id": "src\\screens\\Desktop\\sections\\IngredientInventory\\IngredientInventory.jsx:58:8-to-src\\screens\\AddIngredientPage\\AddIngredientPage.jsx",
182182
"source": "src\\screens\\Desktop\\Desktop.jsx",
183183
"target": "src\\screens\\AddIngredientPage\\AddIngredientPage.jsx",
184184
"data": {
185185
"viaRoute": "/addingredient",
186186
"trigger": {
187-
"element": "<Link to=\"/addingredient\" className=\"add-new-ingredient\">\n <div className=\"add-new-container\">\n <div className=\"add-new-header\">\n <div className=\"add-new-header-text\">추가하기</div>\n </div>\n\n <div className=\"add-new-section\">\n <img\n className=\"add-new-icon\"\n alt=\"Add new icon\"\n src=\"https://c.animaapp.com/sjWITF5i/img/addnewicon.svg\"\n />\n </div>\n </div>\n </Link>",
188-
"line": 74,
189-
"endLine": 88,
187+
"element": "<Link \n to=\"/addingredient\" \n className=\"add-new-ingredient\"\n >\n <div className=\"add-new-container\">\n <div className=\"add-new-header\">\n <div className=\"add-new-header-text\">추가하기</div>\n </div>\n\n <div className=\"add-new-section\">\n <img\n className=\"add-new-icon\"\n alt=\"Add new icon\"\n src=\"https://c.animaapp.com/sjWITF5i/img/addnewicon.svg\"\n />\n </div>\n </div>\n </Link>",
188+
"line": 58,
189+
"endLine": 75,
190190
"column": 8,
191191
"endColumn": 15,
192192
"sourceFile": "src\\screens\\Desktop\\sections\\IngredientInventory\\IngredientInventory.jsx"
@@ -706,47 +706,31 @@
706706
}
707707
},
708708
{
709-
"id": "src\\screens\\CommunityContent\\sections\\Communitycontentpage\\Communitycontentpage.jsx:87:6-to-src\\screens\\CommunityPage\\CommunityPage.jsx",
710-
"source": "src\\screens\\CommunityContent\\CommunityContent.jsx",
711-
"target": "src\\screens\\CommunityPage\\CommunityPage.jsx",
712-
"data": {
713-
"viaRoute": "/communitypage",
714-
"trigger": {
715-
"element": "<Link className=\"communitycontentpage-wrapper\" to=\"/communitypage\">\n <div className=\"text-wrapper-5\">재료 나눔 게시판</div>\n </Link>",
716-
"line": 87,
717-
"endLine": 89,
718-
"column": 6,
719-
"endColumn": 13,
720-
"sourceFile": "src\\screens\\CommunityContent\\sections\\Communitycontentpage\\Communitycontentpage.jsx"
721-
}
722-
}
723-
},
724-
{
725-
"id": "src\\screens\\AddIngredientPage\\AddIngredientPage.jsx:54:4-to-src\\screens\\Desktop\\Desktop.jsx",
709+
"id": "src\\screens\\AddIngredientPage\\AddIngredientPage.jsx:69:4-to-src\\screens\\Desktop\\Desktop.jsx",
726710
"source": "src\\screens\\AddIngredientPage\\AddIngredientPage.jsx",
727711
"target": "src\\screens\\Desktop\\Desktop.jsx",
728712
"data": {
729713
"viaRoute": "/desktop",
730714
"trigger": {
731715
"element": "navigate(\"/desktop\")",
732-
"line": 54,
733-
"endLine": 54,
716+
"line": 69,
717+
"endLine": 69,
734718
"column": 4,
735719
"endColumn": 24,
736720
"sourceFile": "src\\screens\\AddIngredientPage\\AddIngredientPage.jsx"
737721
}
738722
}
739723
},
740724
{
741-
"id": "src\\screens\\AddIngredientPage\\AddIngredientPage.jsx:118:12-to-src\\screens\\Desktop\\Desktop.jsx",
725+
"id": "src\\screens\\AddIngredientPage\\AddIngredientPage.jsx:133:12-to-src\\screens\\Desktop\\Desktop.jsx",
742726
"source": "src\\screens\\AddIngredientPage\\AddIngredientPage.jsx",
743727
"target": "src\\screens\\Desktop\\Desktop.jsx",
744728
"data": {
745729
"viaRoute": "/desktop",
746730
"trigger": {
747731
"element": "<Link to=\"/desktop\" className=\"add-ingredient-cancel-btn\">\n 취소\n </Link>",
748-
"line": 118,
749-
"endLine": 120,
732+
"line": 133,
733+
"endLine": 135,
750734
"column": 12,
751735
"endColumn": 19,
752736
"sourceFile": "src\\screens\\AddIngredientPage\\AddIngredientPage.jsx"

index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
body {
1818
margin: 0px;
1919
height: 100%;
20+
overflow-y: scroll; /* Explicitly enable vertical scrolling */
2021
}
2122
/* a blue color as a generic focus style */
2223
button:focus-visible {

src/App.jsx

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React from "react";
22
import { RouterProvider, createBrowserRouter } from "react-router-dom";
33
import { AuthProvider } from "./contexts/AuthContext";
4+
import { ScrollToTop } from "./components/ScrollToTop"; // Import ScrollToTop
45
import { CommunityContent } from "./screens/CommunityContent";
56
import { CommunityPage } from "./screens/CommunityPage";
67
import { Desktop } from "./screens/Desktop";
@@ -52,7 +53,9 @@ const router = createBrowserRouter([
5253
export const App = () => {
5354
return (
5455
<AuthProvider>
55-
<RouterProvider router={router} />
56+
<RouterProvider router={router}>
57+
<ScrollToTop /> {/* Render ScrollToTop inside RouterProvider */}
58+
</RouterProvider>
5659
</AuthProvider>
5760
);
5861
};

src/components/LoginPopup/LoginPopup.jsx

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -3,36 +3,36 @@ import { useAuth } from "../../contexts/AuthContext";
33
import "./style.css";
44

55
export const LoginPopup = ({ onClose, onSwitchToSignup }) => {
6-
const [username, setUsername] = useState("");
6+
const [email, setEmail] = useState(""); // Changed to email
77
const [password, setPassword] = useState("");
88
const { login } = useAuth();
99

1010
const handleLogin = async (e) => {
1111
e.preventDefault();
1212

1313
// TODO: Backend Integration: Replace with actual backend API call for login
14-
// Example: axios.post('/api/login', { username, password })
14+
// Example: axios.post('/api/login', { email, password })
1515
// .then(response => {
16-
// login(response.data.user);
16+
// login(response.data.user); // Assuming backend returns user data including username
1717
// onClose();
1818
// })
1919
// .catch(error => {
20-
// alert("아이디 또는 비밀번호가 일치하지 않습니다.");
20+
// alert("이메일 또는 비밀번호가 일치하지 않습니다.");
2121
// });
2222

2323
// Simulating backend validation with localStorage
2424
const mockUsers = JSON.parse(localStorage.getItem("registeredUsers") || "[]");
2525
const foundUser = mockUsers.find(
26-
(u) => u.username === username && u.password === password
26+
(u) => u.email === email && u.password === password // Validate by email
2727
);
2828

2929
if (foundUser) {
30-
const userData = { username: foundUser.username };
30+
const userData = { username: foundUser.username, email: foundUser.email }; // Store username for display
3131
login(userData);
3232
console.log("Login successful:", userData);
3333
onClose();
3434
} else {
35-
alert("아이디 또는 비밀번호가 일치하지 않습니다.");
35+
alert("이메일 또는 비밀번호가 일치하지 않습니다.");
3636
}
3737
};
3838

@@ -47,13 +47,13 @@ export const LoginPopup = ({ onClose, onSwitchToSignup }) => {
4747

4848
<form className="login-popup-form" onSubmit={handleLogin}>
4949
<div className="login-popup-input-group">
50-
<label className="login-popup-label">아이디</label>
50+
<label className="login-popup-label">이메일</label> {/* Changed label */}
5151
<input
52-
type="text"
52+
type="email" // Changed type to email
5353
className="login-popup-input"
54-
value={username}
55-
onChange={(e) => setUsername(e.target.value)}
56-
placeholder="아이디를 입력하세요"
54+
value={email} // Changed value to email
55+
onChange={(e) => setEmail(e.target.value)} // Changed onChange to setEmail
56+
placeholder="이메일을 입력하세요" // Changed placeholder
5757
required
5858
/>
5959
</div>
File renamed without changes.
File renamed without changes.

src/components/SignupPopup/SignupPopup.jsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ export const SignupPopup = ({ onClose, onSwitchToLogin, onSwitchToPreferences })
2929
// Simulating backend validation and storage with localStorage
3030
const mockUsers = JSON.parse(localStorage.getItem("registeredUsers") || "[]");
3131

32-
// Check if username already exists
33-
if (mockUsers.find((u) => u.username === username)) {
34-
alert("이미 존재하는 아이디입니다.");
32+
// Check if email already exists
33+
if (mockUsers.find((u) => u.email === email)) { // Check for duplicate email
34+
alert("이미 존재하는 이메일입니다.");
3535
return;
3636
}
3737

src/components/UnifiedHeader/UnifiedHeader.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ export const UnifiedHeader = () => {
8686
</Link>
8787
{isAuthenticated ? (
8888
<div className="unified-user-info">
89-
<span className="unified-username">{user?.username}</span>
89+
<span className="unified-username">{user?.username}</span> {/* Added "님" */}
9090
<button className="unified-logout-btn" onClick={logout}>
9191
로그아웃
9292
</button>

src/screens/AddIngredientPage/AddIngredientPage.jsx

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import React, { useState } from "react";
2-
import { Link, useNavigate } from "react-router-dom";
1+
import React, { useState, useEffect } from "react";
2+
import { Link, useNavigate } from "react-router-dom"; // Removed useLocation
33
import { UnifiedHeader } from "../../components/UnifiedHeader";
44
import "./style.css";
55

@@ -27,6 +27,10 @@ const MOCK_INGREDIENT_DATABASE = [
2727

2828
export const AddIngredientPage = () => {
2929
const navigate = useNavigate();
30+
// Removed useLocation and onAddMultipleIngredients here
31+
// const location = useLocation();
32+
// const onAddMultipleIngredients = location.state?.onAddMultipleIngredients;
33+
3034
const [selectedCategory, setSelectedCategory] = useState("전체");
3135
const [searchQuery, setSearchQuery] = useState("");
3236
const [selectedIngredients, setSelectedIngredients] = useState([]);
@@ -43,15 +47,26 @@ export const AddIngredientPage = () => {
4347
if (exists) {
4448
return prev.filter((item) => item.id !== ingredient.id);
4549
} else {
46-
return [...prev, { ...ingredient, expiryDays: 7 }];
50+
return [...prev, { ...ingredient, expiryDays: 7 }]; // Default expiry days
4751
}
4852
});
4953
};
5054

5155
const handleAddIngredients = () => {
52-
// TODO: Send selected ingredients to backend
53-
console.log("Adding ingredients:", selectedIngredients);
54-
navigate("/desktop");
56+
if (selectedIngredients.length === 0) {
57+
alert("추가할 식재료를 선택해주세요.");
58+
return;
59+
}
60+
61+
// Directly update localStorage for userIngredients
62+
const currentIngredients = JSON.parse(localStorage.getItem("userIngredients") || "[]");
63+
const updatedIngredients = [...currentIngredients, ...selectedIngredients];
64+
localStorage.setItem("userIngredients", JSON.stringify(updatedIngredients));
65+
66+
// TODO: Backend Integration: Send selectedIngredients to backend
67+
console.log("Adding ingredients to mock DB:", selectedIngredients);
68+
69+
navigate("/desktop"); // Navigate back to desktop
5570
};
5671

5772
return (

src/screens/CommunityContent/sections/Communitycontentpage/Communitycontentpage.jsx

Lines changed: 34 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,11 @@
1-
import React, { useState } from "react";
1+
import React, { useState, useEffect } from "react";
22
import { Link, useLocation, useParams } from "react-router-dom";
33
import { useAuth } from "../../../../contexts/AuthContext";
44
import { CommunitypageWrapper } from "../../../../components/CommunitypageWrapper";
5-
import { PageButton } from "../../../../components/PageButton";
65
import "./style.css";
76

8-
const ALL_POSTS = [
9-
// TODO: Backend Integration: Replace with API call to fetch all community posts
7+
// Default posts for fallback if localStorage is empty
8+
const DEFAULT_POSTS = [
109
{ id: 1, title: "돼지고기 100g 나눔합니다.", author: "test3User", date: "2025-11-03", category: "나눔", content: "돼지고기를 너무 많이 샀네요 남는 돼지고기 나눔해요" },
1110
{ id: 2, title: "양파 2개 나눔해요", author: "user123", date: "2025-11-02", category: "나눔", content: "양파 2개 필요하신 분 가져가세요" },
1211
{ id: 3, title: "닭고기 500g 나눔", author: "foodlover", date: "2025-11-01", category: "나눔", content: "신선한 닭고기 나눔합니다" },
@@ -24,35 +23,45 @@ export const Communitycontentpage = () => {
2423
const { id } = useParams();
2524
const { user, isAuthenticated } = useAuth();
2625
const [newComment, setNewComment] = useState("");
27-
28-
// Load comments from localStorage for this specific post
29-
const [comments, setComments] = useState(() => {
26+
const [allCommunityPosts, setAllCommunityPosts] = useState([]);
27+
const [comments, setComments] = useState([]);
28+
29+
// Load comments from localStorage for this specific post, and re-load when 'id' changes
30+
useEffect(() => {
3031
const storedComments = localStorage.getItem(`comments_${id}`);
31-
return storedComments ? JSON.parse(storedComments) : [];
32-
});
33-
34-
const post = location.state?.post || {
35-
// TODO: Backend Integration: Fetch post details by ID if not available in state
36-
id: id,
37-
title: "돼지고기 100g 나눔합니다.",
38-
author: "test3User",
39-
date: "2025-11-03",
40-
category: "나눔",
41-
content: "돼지고기를 너무 많이 샀네요 남는 돼지고기 나눔해요"
42-
};
32+
setComments(storedComments ? JSON.parse(storedComments) : []);
33+
}, [id]);
34+
35+
useEffect(() => {
36+
// Load all community posts from localStorage to find related posts
37+
const storedPosts = JSON.parse(localStorage.getItem("communityPosts") || "[]");
38+
const combined = [...storedPosts, ...DEFAULT_POSTS];
39+
setAllCommunityPosts(combined);
40+
}, []);
41+
42+
const post = location.state?.post ||
43+
allCommunityPosts.find(p => p.id === parseInt(id)) ||
44+
{
45+
id: id,
46+
title: "게시글을 찾을 수 없습니다.",
47+
author: "알 수 없음",
48+
date: "",
49+
category: "",
50+
content: "해당 게시글을 불러오는 데 실패했습니다."
51+
};
4352

4453
// Get related posts (2 before and 2 after current post)
45-
const currentIndex = ALL_POSTS.findIndex(p => p.id === parseInt(id));
54+
const currentIndex = allCommunityPosts.findIndex(p => p.id === parseInt(id));
4655
const relatedPosts = [];
4756

4857
// Get 2 posts before
4958
for (let i = Math.max(0, currentIndex - 2); i < currentIndex; i++) {
50-
if (ALL_POSTS[i]) relatedPosts.push(ALL_POSTS[i]);
59+
if (allCommunityPosts[i]) relatedPosts.push(allCommunityPosts[i]);
5160
}
5261

5362
// Get 2 posts after
54-
for (let i = currentIndex + 1; i <= Math.min(ALL_POSTS.length - 1, currentIndex + 2); i++) {
55-
if (ALL_POSTS[i]) relatedPosts.push(ALL_POSTS[i]);
63+
for (let i = currentIndex + 1; i <= Math.min(allCommunityPosts.length - 1, currentIndex + 2); i++) {
64+
if (allCommunityPosts[i]) relatedPosts.push(allCommunityPosts[i]);
5665
}
5766

5867
const handleCommentSubmit = (e) => {
@@ -81,13 +90,8 @@ export const Communitycontentpage = () => {
8190
setNewComment("");
8291
};
8392

84-
8593
return (
8694
<div className="communitycontentpage">
87-
<Link className="communitycontentpage-wrapper" to="/communitypage">
88-
<div className="text-wrapper-5">재료 나눔 게시판</div>
89-
</Link>
90-
9195
<div className="div-3">
9296
<div className="content-category">
9397
<img
@@ -106,7 +110,7 @@ export const Communitycontentpage = () => {
106110
<div className="navbar">
107111
<div className="text-wrapper-6">작성자</div>
108112

109-
<div className="text-wrapper-6">{post.author}</div>
113+
<div className="text-wrapper-6">{post.author}</div>
110114

111115
<div className="text-wrapper-6">작성일</div>
112116

@@ -127,7 +131,7 @@ export const Communitycontentpage = () => {
127131
<div className="comments-list">
128132
{comments.map((comment) => (
129133
<div key={comment.id} className="comment-item">
130-
<div className="comment-author">{comment.author}</div>
134+
<div className="comment-author">{comment.author}</div>
131135
<div className="comment-content">{comment.content}</div>
132136
<div className="comment-date">{comment.date}</div>
133137
</div>

0 commit comments

Comments
 (0)