From c6172a3e40e84ecce4139522d5c8d749dac8fcff Mon Sep 17 00:00:00 2001 From: hye-inA Date: Thu, 22 Jan 2026 15:30:46 +0900 Subject: [PATCH 1/4] =?UTF-8?q?feat=20:=20AI=20=EB=A7=90=ED=95=98=EA=B8=B0?= =?UTF-8?q?=20=EC=97=B0=EC=8A=B5=20=ED=99=94=EB=A9=B4=20=EA=B5=AC=ED=98=84?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/App.jsx | 214 ++++++------- src/api/axios.js | 21 +- .../components/SpeakingChatMessage.jsx | 163 ++++++++++ .../speaking/components/SpeakingInput.jsx | 294 ++++++++++++++++++ .../speaking/constants/speakingConstants.js | 31 ++ src/domains/speaking/hooks/useSpeaking.js | 119 +++++++ src/domains/speaking/index.js | 15 + src/domains/speaking/pages/SpeakingPage.jsx | 216 +++++++++++++ src/domains/speaking/services/speakingApi.js | 58 ++++ 9 files changed, 1015 insertions(+), 116 deletions(-) create mode 100644 src/domains/speaking/components/SpeakingChatMessage.jsx create mode 100644 src/domains/speaking/components/SpeakingInput.jsx create mode 100644 src/domains/speaking/constants/speakingConstants.js create mode 100644 src/domains/speaking/hooks/useSpeaking.js create mode 100644 src/domains/speaking/index.js create mode 100644 src/domains/speaking/pages/SpeakingPage.jsx create mode 100644 src/domains/speaking/services/speakingApi.js diff --git a/src/App.jsx b/src/App.jsx index bb70c3a..dfda542 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -1,6 +1,6 @@ -import {useState} from 'react' -import {Navigate, Route, Routes, useNavigate} from 'react-router-dom' -import {Box, Button, Card, CardContent, CircularProgress, Collapse, Container, Grid, Typography} from '@mui/material' +import { useState, useEffect } from 'react' +import { Navigate, Route, Routes, useNavigate } from 'react-router-dom' +import { Box, Button, Card, CardContent, CircularProgress, Collapse, Container, Grid, Typography } from '@mui/material' import { ChevronRight as ChevronRightIcon, Create as WritingCategoryIcon, @@ -18,6 +18,7 @@ import { } from '@mui/icons-material' import MainLayout from './layouts/MainLayout' import FreetalkPeoplePage from './domains/freetalk/pages/FreetalkPeoplePage' +import { SpeakingPage } from './domains/speaking' import ChatRoomPage from './domains/freetalk/pages/ChatRoomPage' import ChatRoomModal from './domains/freetalk/components/ChatRoomModal' import VocabDashboard from './domains/vocab/pages/VocabDashboard' @@ -25,20 +26,20 @@ import DailyLearning from './domains/vocab/pages/DailyLearning' import TestPage from './domains/vocab/pages/TestPage' import WordListPage from './domains/vocab/pages/WordListPage' import StatsPage from './domains/vocab/pages/StatsPage' -import {WritingPage} from './domains/grammar' -import {BadgeSection} from './domains/badge' +import { WritingPage } from './domains/grammar' +import { BadgeSection } from './domains/badge' import CatchmindLobbyPage from './domains/games/pages/CatchmindLobbyPage' import CatchmindWaitingPage from './domains/games/pages/CatchmindWaitingPage' import CatchmindPlayPage from './domains/games/pages/CatchmindPlayPage' -import {useChat} from './contexts/ChatContext' -import {useSettings} from './contexts/SettingsContext' -import {useAuth} from './contexts/AuthContext' +import { useChat } from './contexts/ChatContext' +import { useSettings } from './contexts/SettingsContext' +import { useAuth } from './contexts/AuthContext' import LoginPage from './pages/Login' import SignUpPage from './pages/SignUp' -function ProtectedRoute({children}) { - const {isAuthenticated, isLoading} = useAuth() +function ProtectedRoute({ children }) { + const { isAuthenticated, isLoading } = useAuth() if (isLoading) { return ( @@ -48,21 +49,21 @@ function ProtectedRoute({children}) { alignItems: 'center', justifyContent: 'center' }}> - + ) } if (!isAuthenticated) { - return + return } return children } // 이미 로그인된 경우 대시보드로 -function PublicRoute({children}) { - const {isAuthenticated, isLoading} = useAuth() +function PublicRoute({ children }) { + const { isAuthenticated, isLoading } = useAuth() if (isLoading) { return ( @@ -72,13 +73,13 @@ function PublicRoute({children}) { alignItems: 'center', justifyContent: 'center' }}> - + ) } if (isAuthenticated) { - return + return } return children @@ -88,7 +89,7 @@ function PublicRoute({children}) { function Dashboard() { const navigate = useNavigate() const [expandedCard, setExpandedCard] = useState(null) - const {t} = useSettings() + const { t } = useSettings() const learningModes = [ { @@ -203,9 +204,9 @@ function Dashboard() { } return ( - + {/* Header */} - + - + - + {t('dashboard.greeting')} @@ -240,7 +241,7 @@ function Dashboard() { const hasChildren = mode.children && mode.children.length > 0 return ( - + handleCardHover(mode.id)} onMouseLeave={handleCardLeave} @@ -261,8 +262,8 @@ function Dashboard() { minHeight: isExpanded ? 'auto' : 140, }} > - - + + {/* Icon */} - + {/* Text */} - + )} - + {mode.description} @@ -358,14 +359,14 @@ function Dashboard() { boxShadow: '0 2px 8px -2px rgba(0,0,0,0.1)', }} > - + + sx={{ mb: 0.5 }}> {child.title} + sx={{ lineHeight: 1.3 }}> {child.description} @@ -382,12 +383,12 @@ function Dashboard() { {/* Recent Activity */} - - + + {t('dashboard.recentActivity')} - + - + {t('dashboard.noHistory')} - + {t('dashboard.startLearning')}