diff --git a/src/domains/freetalk/components/ChatRoomCard.jsx b/src/domains/freetalk/components/ChatRoomCard.jsx
index a513a93..f7e1fc9 100644
--- a/src/domains/freetalk/components/ChatRoomCard.jsx
+++ b/src/domains/freetalk/components/ChatRoomCard.jsx
@@ -1,5 +1,5 @@
-import { Card, CardContent, Box, Typography, Chip, Avatar, AvatarGroup } from '@mui/material'
-import { AccessTime as TimeIcon, People as PeopleIcon } from '@mui/icons-material'
+import { Card, CardContent, Box, Typography, Chip, Button } from '@mui/material'
+import { AccessTime as TimeIcon, People as PeopleIcon, Lock as LockIcon } from '@mui/icons-material'
const levelColors = {
beginner: { bg: '#e8f5e9', color: '#2e7d32', label: '초급' },
@@ -19,25 +19,27 @@ const formatTimeAgo = (date) => {
const formatDate = (date) => {
const d = new Date(date)
- const month = d.getMonth() + 1
- const day = d.getDate()
- const hours = d.getHours()
- const minutes = d.getMinutes().toString().padStart(2, '0')
- return `${month}/${day} ${hours}:${minutes}`
+ const year = d.getFullYear().toString().slice(2)
+ const month = (d.getMonth() + 1).toString().padStart(2, '0')
+ const day = d.getDate().toString().padStart(2, '0')
+ return `${year}/${month}/${day}`
}
const ChatRoomCard = ({ room, onClick }) => {
const level = levelColors[room.level] || levelColors.beginner
+ const handleEnterClick = (e) => {
+ e.stopPropagation()
+ onClick?.(room)
+ }
+
return (
onClick?.(room)}
sx={{
- width: '100%',
- height: '100%',
+ width: 300,
+ height: 140,
display: 'flex',
flexDirection: 'column',
- cursor: 'pointer',
transition: 'all 0.2s ease-in-out',
'&:hover': {
transform: 'translateY(-4px)',
@@ -45,9 +47,9 @@ const ChatRoomCard = ({ room, onClick }) => {
},
}}
>
-
-
- {/* 레벨 뱃지 */}
+
+ {/* 상단: 레벨 뱃지 + 방 이름 + 입장 버튼 */}
+
{
backgroundColor: level.bg,
color: level.color,
fontWeight: 600,
- minWidth: 48,
+ fontSize: 11,
+ height: 24,
}}
/>
- {/* 채팅방 정보 */}
-
-
+
+ {room.isPrivate && (
+
+ )}
+
{room.name}
+
-
- {/* 인원 */}
-
-
-
-
- {room.currentMembers}
-
- /{room.maxMembers}
-
-
+
+
- {/* 마지막 대화 */}
-
-
-
- {formatTimeAgo(room.lastMessageAt)}
-
-
-
+ {/* 중단: 소개 */}
+ {room.description && (
+
+ {room.description}
+
+ )}
- {/* 참여자 아바타 & 생성일 */}
-
-
- {room.participants?.map((participant, index) => (
-
- {participant.name?.[0]}
-
- ))}
-
+ {/* 하단: 인원, 마지막 대화, 생성일 */}
+
+
+
+
+
+ {room.currentMembers}
+
+ /{room.maxMembers}
+
+
-
- 생성: {formatDate(room.createdAt)}
-
-
+
+
+
+ {formatTimeAgo(room.lastMessageAt)}
+
+
+
+ · 생성: {formatDate(room.createdAt)}
+
diff --git a/src/domains/freetalk/pages/FreetalkPeoplePage.jsx b/src/domains/freetalk/pages/FreetalkPeoplePage.jsx
index fd90813..53762db 100644
--- a/src/domains/freetalk/pages/FreetalkPeoplePage.jsx
+++ b/src/domains/freetalk/pages/FreetalkPeoplePage.jsx
@@ -11,87 +11,87 @@ import {
ToggleButton,
Button,
Fab,
+ Dialog,
+ DialogTitle,
+ DialogContent,
+ DialogActions,
+ Chip,
} from '@mui/material'
import {
Search as SearchIcon,
Add as AddIcon,
- FilterList as FilterIcon,
+ Lock as LockIcon,
+ People as PeopleIcon,
} from '@mui/icons-material'
import ChatRoomCard from '../components/ChatRoomCard'
+const levelColors = {
+ beginner: { bg: '#e8f5e9', color: '#2e7d32', label: '초급' },
+ intermediate: { bg: '#fff3e0', color: '#ef6c00', label: '중급' },
+ advanced: { bg: '#fce4ec', color: '#c2185b', label: '고급' },
+}
+
// 더미 데이터
const mockRooms = [
{
id: 1,
name: '영어 일상 대화방',
+ description: '편하게 일상 영어로 대화해요',
level: 'beginner',
currentMembers: 3,
maxMembers: 6,
- lastMessageAt: new Date(Date.now() - 5 * 60 * 1000), // 5분 전
- createdAt: new Date(Date.now() - 2 * 24 * 60 * 60 * 1000), // 2일 전
- participants: [
- { name: '김철수', avatar: '' },
- { name: '이영희', avatar: '' },
- { name: 'John', avatar: '' },
- ],
+ lastMessageAt: new Date(Date.now() - 5 * 60 * 1000),
+ createdAt: new Date(Date.now() - 2 * 24 * 60 * 60 * 1000),
+ isPrivate: false,
+ isJoined: true,
},
{
id: 2,
name: '비즈니스 영어 연습',
+ description: '회의, 이메일, 프레젠테이션 영어',
level: 'intermediate',
currentMembers: 4,
maxMembers: 5,
- lastMessageAt: new Date(Date.now() - 30 * 60 * 1000), // 30분 전
- createdAt: new Date(Date.now() - 5 * 24 * 60 * 60 * 1000), // 5일 전
- participants: [
- { name: 'Mike', avatar: '' },
- { name: '박지성', avatar: '' },
- { name: 'Emma', avatar: '' },
- { name: '최민수', avatar: '' },
- ],
+ lastMessageAt: new Date(Date.now() - 30 * 60 * 1000),
+ createdAt: new Date(Date.now() - 5 * 24 * 60 * 60 * 1000),
+ isPrivate: true,
+ isJoined: false,
},
{
id: 3,
name: '고급 토론방',
+ description: '시사 이슈로 깊이 있는 토론',
level: 'advanced',
currentMembers: 2,
maxMembers: 4,
- lastMessageAt: new Date(Date.now() - 2 * 60 * 60 * 1000), // 2시간 전
- createdAt: new Date(Date.now() - 1 * 24 * 60 * 60 * 1000), // 1일 전
- participants: [
- { name: 'Sarah', avatar: '' },
- { name: '정유진', avatar: '' },
- ],
+ lastMessageAt: new Date(Date.now() - 2 * 60 * 60 * 1000),
+ createdAt: new Date(Date.now() - 1 * 24 * 60 * 60 * 1000),
+ isPrivate: true,
+ isJoined: true,
},
{
id: 4,
name: '영어 초보 환영',
+ description: '틀려도 괜찮아요! 함께 성장해요',
level: 'beginner',
currentMembers: 5,
maxMembers: 8,
- lastMessageAt: new Date(Date.now() - 10 * 60 * 1000), // 10분 전
- createdAt: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000), // 7일 전
- participants: [
- { name: '홍길동', avatar: '' },
- { name: 'Tom', avatar: '' },
- { name: '김미나', avatar: '' },
- { name: 'Lisa', avatar: '' },
- { name: '박준호', avatar: '' },
- ],
+ lastMessageAt: new Date(Date.now() - 10 * 60 * 1000),
+ createdAt: new Date(Date.now() - 7 * 24 * 60 * 60 * 1000),
+ isPrivate: false,
+ isJoined: false,
},
{
id: 5,
name: '프리토킹 중급반',
+ description: '자유 주제로 스피킹 연습',
level: 'intermediate',
currentMembers: 3,
maxMembers: 6,
- lastMessageAt: new Date(Date.now() - 45 * 60 * 1000), // 45분 전
- createdAt: new Date(Date.now() - 3 * 24 * 60 * 60 * 1000), // 3일 전
- participants: [
- { name: '이수진', avatar: '' },
- { name: 'David', avatar: '' },
- { name: '김태희', avatar: '' },
- ],
+ lastMessageAt: new Date(Date.now() - 45 * 60 * 1000),
+ createdAt: new Date(Date.now() - 3 * 24 * 60 * 60 * 1000),
+ isPrivate: false,
+ isJoined: true,
},
]
@@ -99,6 +99,10 @@ const FreetalkPeoplePage = () => {
const navigate = useNavigate()
const [searchQuery, setSearchQuery] = useState('')
const [levelFilter, setLevelFilter] = useState('all')
+ const [selectedRoom, setSelectedRoom] = useState(null)
+ const [modalOpen, setModalOpen] = useState(false)
+ const [password, setPassword] = useState('')
+ const [passwordError, setPasswordError] = useState('')
const handleLevelChange = (event, newLevel) => {
if (newLevel !== null) {
@@ -107,14 +111,44 @@ const FreetalkPeoplePage = () => {
}
const handleRoomClick = (room) => {
- // TODO: 채팅방 입장 로직
- console.log('Entering room:', room.id)
- navigate(`/freetalk/people/room/${room.id}`)
+ setSelectedRoom(room)
+ setPassword('')
+ setPasswordError('')
+ setModalOpen(true)
+ }
+
+ const handleCloseModal = () => {
+ setModalOpen(false)
+ setSelectedRoom(null)
+ setPassword('')
+ setPasswordError('')
+ }
+
+ const handleEnterRoom = () => {
+ if (selectedRoom?.isPrivate) {
+ // 비밀번호 검증 (더미: 1234)
+ if (password === '1234') {
+ navigate(`/freetalk/people/room/${selectedRoom.id}`)
+ handleCloseModal()
+ } else {
+ setPasswordError('비밀번호가 일치하지 않습니다')
+ }
+ } else {
+ navigate(`/freetalk/people/room/${selectedRoom.id}`)
+ handleCloseModal()
+ }
}
const filteredRooms = mockRooms.filter((room) => {
const matchesSearch = room.name.toLowerCase().includes(searchQuery.toLowerCase())
- const matchesLevel = levelFilter === 'all' || room.level === levelFilter
+ let matchesLevel = false
+ if (levelFilter === 'all') {
+ matchesLevel = true
+ } else if (levelFilter === 'joined') {
+ matchesLevel = room.isJoined
+ } else {
+ matchesLevel = room.level === levelFilter
+ }
return matchesSearch && matchesLevel
})
@@ -159,6 +193,7 @@ const FreetalkPeoplePage = () => {
초급
중급
고급
+ 참여중
@@ -199,6 +234,82 @@ const FreetalkPeoplePage = () => {
>
+
+ {/* 입장 모달 */}
+
)
}