Skip to content
Merged

89 #44

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
29 changes: 27 additions & 2 deletions src/components/ChatRoomList.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import ChatService from '../services/ChatService';
import ChatRoom from './ChatRoom';
import PasswordModal from './PasswordModal';
import './ChatStyles.css';
import { API_BACKEND_URL } from '../config';

const ChatRoomList = () => {
const [rooms, setRooms] = useState([]);
Expand Down Expand Up @@ -255,6 +256,16 @@ const ChatRoomList = () => {
// Check if room list is empty
const isRoomsEmpty = rooms.length === 0;

const getImageUrl = (imageUrl) => {
if (!imageUrl) return null;
console.log('Original imageUrl:', imageUrl); // 디버깅용
// API_BACKEND_URL이 이미 슬래시로 끝나지 않는지 확인
const baseUrl = API_BACKEND_URL.endsWith('/') ? API_BACKEND_URL.slice(0, -1) : API_BACKEND_URL;
const fullUrl = `${baseUrl}${imageUrl}`;
console.log('Full imageUrl:', fullUrl); // 디버깅용
return fullUrl;
};

return (
<div className="chat-layout">
{/* 채팅방 목록 컨테이너 */}
Expand Down Expand Up @@ -320,8 +331,22 @@ const ChatRoomList = () => {
onClick={() => handleJoinRoom(room.id)}
>
<div className="profile-img">
{/* 프로필 이미지 또는 잠금 아이콘 표시 */}
{room.isPrivate && <i className="fa-solid fa-lock" style={{ color: '#e74c3c' }}></i>}
{room.imageUrl ? (
<img
src={getImageUrl(room.imageUrl)}
alt={room.title}
className="room-image"
onError={(e) => {
console.log('Image load failed:', room.imageUrl);
e.target.onerror = null;
e.target.src = '/default-room.png';
}}
/>
) : (
<div className="default-room-image">
<i className="fa-solid fa-comments"></i>
</div>
)}
</div>
<div className="chat-info">
<div className="chat-name">
Expand Down
31 changes: 25 additions & 6 deletions src/components/ChatStyles.css
Original file line number Diff line number Diff line change
Expand Up @@ -138,15 +138,34 @@
}

.chat-room .profile-img {
width: 50px;
height: 50px;
border-radius: 50%;
background-color: var(--pink);
margin-right: 15px;
width: 60px;
height: 60px;
min-width: 60px;
border-radius: 8px;
overflow: hidden;
margin-right: 12px;
background: #f0f0f0;
display: flex;
align-items: center;
justify-content: center;
}

.chat-room .room-image {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 8px;
}

.chat-room .default-room-image {
width: 100%;
height: 100%;
display: flex;
align-items: center;
overflow: hidden;
justify-content: center;
background-color: #e9ecef;
color: #6c757d;
font-size: 24px;
}

.chat-room .chat-info {
Expand Down
76 changes: 55 additions & 21 deletions src/components/CreateChatRoom.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ const CreateChatRoom = () => {
const [userCountMax, setUserCountMax] = useState(10);
const [password, setPassword] = useState('');
const [isPrivate, setIsPrivate] = useState(false);
const [file, setFile] = useState(null);
const [previewUrl, setPreviewUrl] = useState(null);
const [loading, setLoading] = useState(false);
const [errors, setErrors] = useState({});
const navigate = useNavigate();
Expand Down Expand Up @@ -60,40 +62,52 @@ const CreateChatRoom = () => {
return Object.keys(newErrors).length === 0;
};

const handleSubmit = async (e) => {
e.preventDefault();
const handleFileChange = (e) => {
const selectedFile = e.target.files[0];
if (selectedFile) {
// 파일 정보 로깅
console.log('Selected file:', {
name: selectedFile.name,
type: selectedFile.type,
size: selectedFile.size
});

// 파일 크기 검사 (5MB)
if (selectedFile.size > 5 * 1024 * 1024) {
setErrors({ ...errors, file: '파일 크기는 5MB를 초과할 수 없습니다.' });
return;
}

// 이미지 파일 타입 검사
if (!selectedFile.type.startsWith('image/')) {
setErrors({ ...errors, file: '이미지 파일만 업로드 가능합니다.' });
return;
}

if (!validateForm()) {
return;
setFile(selectedFile);
setPreviewUrl(URL.createObjectURL(selectedFile));
setErrors({ ...errors, file: null });
}
};

const handleSubmit = async (e) => {
e.preventDefault();
if (!validateForm()) return;

setLoading(true);
try {
// 비공개방이 아니면 비밀번호 없이 전송
const roomData = {
title,
userCountMax,
...(isPrivate && { password })
};

console.log('Creating room with:', roomData);
const response = await ChatService.createRoom(roomData.title, roomData.userCountMax, roomData.password);
console.log('Create room response:', response);

console.log('Submitting form with file:', file);
const response = await ChatService.createRoom(title, userCountMax, file);

if (response && !response.errorCode) {
// 성공 메시지 표시
alert('채팅방이 성공적으로 생성되었습니다.');

// 로컬 스토리지를 사용하여 상태 갱신 트리거
localStorage.setItem('chatRoomChanged', Date.now().toString());

// 채팅방 목록으로 이동
navigate('/chat-rooms', { replace: true });
} else {
alert(response.message || '채팅방 생성에 실패했습니다.');
}
} catch (err) {
console.error('Error creating room:', err);
console.error('Error in handleSubmit:', err);
alert(err.message || '채팅방 생성에 실패했습니다.');
} finally {
setLoading(false);
Expand Down Expand Up @@ -173,6 +187,26 @@ const CreateChatRoom = () => {
</div>
)}

<div className="form-group">
<label className="form-label">채팅방 이미지</label>
<input
type="file"
accept="image/*"
onChange={handleFileChange}
className="form-control"
/>
{errors.file && <p className="error-message">{errors.file}</p>}
{previewUrl && (
<div className="image-preview">
<img
src={previewUrl}
alt="미리보기"
style={{ maxWidth: '200px', maxHeight: '200px' }}
/>
</div>
)}
</div>

<div className="form-actions">
<button
type="button"
Expand Down
30 changes: 23 additions & 7 deletions src/services/ChatService.js
Original file line number Diff line number Diff line change
Expand Up @@ -152,27 +152,43 @@ const ChatService = {
}
},

createRoom: async (title, userCountMax) => {
createRoom: async (title, userCountMax, file = null) => {
try {
if (!title || !userCountMax) {
throw new Error('제목과 최대 인원 수는 필수 입력값입니다.');
}

console.log('Creating room with:', { title, userCountMax: parseInt(userCountMax) });
const response = await apiClient.post('/chat/room', {
title,
userCountMax: parseInt(userCountMax)
const formData = new FormData();
formData.append('title', title);
formData.append('userCountMax', parseInt(userCountMax));

// 파일 업로드 디버깅
if (file) {
console.log('Uploading file:', file);
formData.append('file', file);
}

// FormData 내용 확인
for (let pair of formData.entries()) {
console.log(pair[0] + ': ' + pair[1]);
}

console.log('Creating room with:', { title, userCountMax, file });
const response = await apiClient.post('/chat/room', formData, {
headers: {
'Content-Type': 'multipart/form-data',
},
});

console.log('Create room response:', response);

if (response && !response.errorCode) {
// 모든 캐시 초기화
cache.clearCache();
}

return response;
} catch (error) {
console.error('Error creating room:', error);
console.error('Error creating room:', error.response || error);
throw error;
}
},
Expand Down