From 88a12de45b79fc43e8b2c887f0395518d86df944 Mon Sep 17 00:00:00 2001 From: guillermoscript Date: Sun, 13 Oct 2024 16:18:25 -0400 Subject: [PATCH 01/15] Refactor ChatBox component to display localized text and improve user experience --- app/locales/en/components.ts | 18 ++++++++++++++++++ app/locales/es/components.ts | 18 ++++++++++++++++++ 2 files changed, 36 insertions(+) diff --git a/app/locales/en/components.ts b/app/locales/en/components.ts index e34b0ac3..239800ba 100644 --- a/app/locales/en/components.ts +++ b/app/locales/en/components.ts @@ -534,5 +534,23 @@ If you have doubts, try saying: "Could you give me a fake scenario to practice m vibrantCommunity: 'Join our vibrant learning community', certificates: 'Certificates', earnCertificates: 'Earn certificates upon course completion', + }, + ChatBox: { + closeChat: 'Close chat', + openChat: 'Open chat', + chatAssistant: 'Chat Assistant', + minimize: 'Minimize', + expand: 'Expand', + greeting: "Hi! I'm your AI assistant. How can I help you today?", + quickAccess: { + productQuestions: 'Product & General questions', + shareFeedback: 'Share feedback', + loggingIn: 'Logging in', + reset2FA: 'Reset 2FA', + abuseReport: 'Abuse report', + contactingSales: 'Contacting Sales & Partnerships', + }, + typeMessage: 'Type your message...', + sendMessage: 'Send message', } } as const diff --git a/app/locales/es/components.ts b/app/locales/es/components.ts index f72638a5..dfbc08ca 100644 --- a/app/locales/es/components.ts +++ b/app/locales/es/components.ts @@ -531,5 +531,23 @@ Si tienes dudas, intenta diciendo: "Could you give me a fake scenario to practic vibrantCommunity: 'Únete a nuestra vibrante comunidad de aprendizaje', certificates: 'Certificados', earnCertificates: 'Obtén certificados al completar los cursos', + }, + ChatBox: { + closeChat: 'Cerrar chat', + openChat: 'Abrir chat', + chatAssistant: 'Asistente de Chat', + minimize: 'Minimizar', + expand: 'Expandir', + greeting: '¡Hola! Soy tu asistente de IA. ¿Cómo puedo ayudarte hoy?', + quickAccess: { + productQuestions: 'Preguntas sobre productos y generales', + shareFeedback: 'Compartir comentarios', + loggingIn: 'Iniciar sesión', + reset2FA: 'Restablecer 2FA', + abuseReport: 'Informe de abuso', + contactingSales: 'Contactar con Ventas y Asociaciones', + }, + typeMessage: 'Escribe tu mensaje...', + sendMessage: 'Enviar mensaje', } } as const From c6c7e8a680b7102cc6e20de8d9dfed9736546e0f Mon Sep 17 00:00:00 2001 From: guillermoscript Date: Sun, 13 Oct 2024 16:18:34 -0400 Subject: [PATCH 02/15] Refactor ChatBox component to use streamText for generating AI responses --- app/api/chatbox-ai/route.ts | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/app/api/chatbox-ai/route.ts b/app/api/chatbox-ai/route.ts index 87b430a7..e916e806 100644 --- a/app/api/chatbox-ai/route.ts +++ b/app/api/chatbox-ai/route.ts @@ -1,28 +1,23 @@ import { google } from '@ai-sdk/google' -import { generateText } from 'ai' +import { convertToCoreMessages, Message, streamText } from 'ai' import { NextRequest, NextResponse } from 'next/server' interface RequestBody { - message: string; - instructions: string; + messages: Message[]; } -export async function POST(request: NextRequest): Promise { +export async function POST(request: NextRequest) { try { const reqBody: RequestBody = await request.json() - const { message, instructions } = reqBody const model = google('gemini-1.5-flash') - const result = await generateText({ + const result = await streamText({ model, - system: `Act like a teacher. Always provide responses in plain text without using any markdown or special formatting like **, _ or other font styles. Respond naturally and clearly. ${instructions}`, - prompt: message, + messages: convertToCoreMessages(reqBody.messages), temperature: 0.7, }) - const responseText = result.text - - return new NextResponse(responseText) + return result.toDataStreamResponse() } catch (error) { console.error('Error al generar la respuesta:', error) return NextResponse.json( From 28c41d737362dab072b2dbf30fe12ff550dfdcd9 Mon Sep 17 00:00:00 2001 From: guillermoscript Date: Sun, 13 Oct 2024 16:18:40 -0400 Subject: [PATCH 03/15] Refactor POST function in chat/exercises/student/route.ts --- app/api/chat/exercises/student/route.ts | 7 ------- 1 file changed, 7 deletions(-) diff --git a/app/api/chat/exercises/student/route.ts b/app/api/chat/exercises/student/route.ts index 8426bb0e..82eea841 100644 --- a/app/api/chat/exercises/student/route.ts +++ b/app/api/chat/exercises/student/route.ts @@ -42,13 +42,8 @@ export async function POST(req: Request) { } }, async onFinish({ responseMessages, text, toolResults }) { - console.log('Response messages:', responseMessages) - console.log(text, 'TEXT') - const lastMessage = body.messages[body.messages.length - 1] - console.log('Tool results:', toolResults) - const save = await supabase.from('exercise_messages').insert([ { exercise_id: body.exerciseId, @@ -79,8 +74,6 @@ export async function POST(req: Request) { } ) } - - console.log('Save:', save) } }) From 6798a8d37b1b399aa4220e56cd4a1c566c22c263 Mon Sep 17 00:00:00 2001 From: guillermoscript Date: Sun, 13 Oct 2024 16:20:32 -0400 Subject: [PATCH 04/15] Refactor ExerciseChat component to improve chat scrolling behavior --- .../student/course/exercises/exerciseChat.tsx | 129 +++++++++--------- 1 file changed, 68 insertions(+), 61 deletions(-) diff --git a/components/dashboards/student/course/exercises/exerciseChat.tsx b/components/dashboards/student/course/exercises/exerciseChat.tsx index db732b6e..70b65da0 100644 --- a/components/dashboards/student/course/exercises/exerciseChat.tsx +++ b/components/dashboards/student/course/exercises/exerciseChat.tsx @@ -42,6 +42,9 @@ export default function ExerciseChat({ const chatContainerRef = useRef(null) const [isCompleted, setIsCompleted] = useState(isExerciseCompleted) + // Create a ref for the scroll anchor + const scrollAnchorRef = useRef(null) + const { messages, input, handleInputChange, handleSubmit, isLoading, stop, append } = useChat({ api: apiEndpoint ?? '/api/chat/exercises', @@ -60,11 +63,11 @@ export default function ExerciseChat({ }) useEffect(() => { - if (chatContainerRef.current) { - chatContainerRef.current.scrollTop = - chatContainerRef.current.scrollHeight + // Skip the initial render + if (messages.length > initialMessages.length && scrollAnchorRef.current) { + scrollAnchorRef.current.scrollIntoView({ behavior: 'smooth' }) } - }, [messages]) + }, [messages, initialMessages.length]) const handleFileChange = (event: React.ChangeEvent) => { if (event.target.files) { @@ -82,70 +85,74 @@ export default function ExerciseChat({ return ( - - {messages.map((m: Message) => { - if (m.role === 'system') return null + +
+ {messages.map((m: Message) => { + if (m.role === 'system') return null - return ( -
-
- - - - {m.role === 'user' ? ( - profile.full_name[0] - ) : ( - 'A' - )} - - -
-
- +
+ + -
- {dayjs(m.createdAt).format( - 'MMM D, YYYY [at] h:mm A' + + {m.role === 'user' ? ( + profile.full_name[0] + ) : ( + 'A' )} + + +
+
+ +
+ {dayjs(m.createdAt).format( + 'MMM D, YYYY [at] h:mm A' + )} +
-
- {m.toolInvocations?.map( - ( - toolInvocation: ToolInvocation - ) => { - console.log(toolInvocation) - if ( - toolInvocation.toolName === - 'makeUserAssigmentCompleted' && - 'result' in toolInvocation - ) { - return ( -
- {toolInvocation.result} -
- ) + {m.toolInvocations?.map( + ( + toolInvocation: ToolInvocation + ) => { + console.log(toolInvocation) + if ( + toolInvocation.toolName === + 'makeUserAssigmentCompleted' && + 'result' in toolInvocation + ) { + return ( +
+ {toolInvocation.result} +
+ ) + } + return null } - return null - } - )} - + )} + +
-
- ) - })} + ) + })} + {/* Scroll Anchor */} +
+
{isCompleted ? ( <> From 58a3cfd42d11d9ee98e29bc7b47f10bf723181c3 Mon Sep 17 00:00:00 2001 From: guillermoscript Date: Sun, 13 Oct 2024 16:20:41 -0400 Subject: [PATCH 05/15] Refactor ScrollToTopButton component to adjust button position --- components/ScrollToTopButton.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/ScrollToTopButton.tsx b/components/ScrollToTopButton.tsx index f8c312db..05b3d0fe 100644 --- a/components/ScrollToTopButton.tsx +++ b/components/ScrollToTopButton.tsx @@ -35,7 +35,7 @@ function ScrollToTopButton () { From cad0de35c79d8a624e3c08ee97303fb62208ddcd Mon Sep 17 00:00:00 2001 From: guillermoscript Date: Sun, 13 Oct 2024 16:20:46 -0400 Subject: [PATCH 06/15] Refactor code to improve chat scrolling behavior --- components/chatbox/ChatBox.tsx | 377 +++++++++++++++++++-------------- 1 file changed, 215 insertions(+), 162 deletions(-) diff --git a/components/chatbox/ChatBox.tsx b/components/chatbox/ChatBox.tsx index d616933b..0e1b8f2d 100644 --- a/components/chatbox/ChatBox.tsx +++ b/components/chatbox/ChatBox.tsx @@ -1,8 +1,19 @@ 'use client' + import { useChat } from 'ai/react' -import { Maximize2, MessageSquare, Minimize2, Trash2, X } from 'lucide-react' +import { AnimatePresence, motion } from 'framer-motion' +import { + ChevronDown, + ChevronUp, + Loader2, + MessageSquare, + Send, + X, +} from 'lucide-react' import { useEffect, useRef, useState } from 'react' +import { useScopedI18n } from '@/app/locales/client' +import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar' import { Button } from '@/components/ui/button' import { Card, @@ -14,45 +25,49 @@ import { import { Input } from '@/components/ui/input' import { ScrollArea } from '@/components/ui/scroll-area' +import ViewMarkdown from '../ui/markdown/ViewMarkdown' +import { generateId } from 'ai' + interface ChatBoxProps { instructions: string } +const quickAccessButtons = [ + { label: 'productQuestions', icon: '📦' }, + { label: 'shareFeedback', icon: '📝' }, + { label: 'loggingIn', icon: '🔐' }, + { label: 'reset2FA', icon: '🔑' }, + { label: 'abuseReport', icon: '🚫' }, + { label: 'contactingSales', icon: '💼' }, +] + export default function ChatBox({ instructions }: ChatBoxProps) { const [isChatOpen, setIsChatOpen] = useState(false) const [isExpanded, setIsExpanded] = useState(false) const scrollAreaRef = useRef(null) const chatBoxRef = useRef(null) + const t = useScopedI18n('ChatBox') const { messages, input, handleInputChange, handleSubmit, - setMessages, isLoading, + append, } = useChat({ - api: '/api/chatbox-ai', // La API personalizada - streamProtocol: 'text', // Protocolo de comunicación - keepLastMessageOnError: true, + api: '/api/chatbox-ai', + initialMessages: [ + { + id: generateId(), + content: instructions, + role: 'system', + }, + ], }) - const toggleChat = () => { - if (isChatOpen) { - setIsChatOpen(false) - setIsExpanded(false) - } else { - setIsChatOpen(true) - } - } - - const clearChat = () => { - setMessages([]) - } - - const toggleExpand = () => { - setIsExpanded((prev) => !prev) - } + const toggleChat = () => setIsChatOpen((prev) => !prev) + const toggleExpand = () => setIsExpanded((prev) => !prev) const scrollToBottom = () => { if (scrollAreaRef.current) { @@ -88,160 +103,198 @@ export default function ChatBox({ instructions }: ChatBoxProps) { } }, []) + const handleQuickAccess = (question: string) => { + append({ + content: t(`quickAccess.${question}`), + role: 'user', + }) + } + return ( <> - {/* Botón para abrir/cerrar el chat */} - {/* Contenedor del chat */} - {isChatOpen && ( -
- - {/* Cabecera del chat */} - - - Chat - -
- {/* Botón para limpiar el chat */} - - {/* Botón para minimizar/maximizar el chat */} - - {/* Botón para cerrar el chat */} - + +
+
+ + + - - Close chat - -
- - - {/* Contenido del chat */} - - - {messages.length === 0 ? ( -

- No messages yet. -

- ) : ( - messages.map((message) => ( -
- {/* Remitente del mensaje */} -
- {message.role === 'user' - ? 'User' - : 'Bot'} -
- {/* Burbuja del mensaje */} -
- {message.content} -
-
- )) - )} -
-
- - {/* Pie de página del chat con el input y el botón de enviar */} - -
- handleSubmit(e, { - body: { - message: input, // Mensaje del usuario - instructions, // Instrucciones pasadas como props - }, - }) - } - > - - + ) + )} +
+ + ) : ( + messages.map((message) => { + if (message.role === 'system') { + return null + } + + return ( +
+ + + + {message.role === + 'user' + ? 'U' + : 'A'} + + +
+ +
+
+ ) + }) + )} +
+
+
+ + + + handleSubmit(e, { + body: { + message: input, + instructions, + }, + }) + } > - {isLoading ? 'Loading...' : 'Send'} - - - -
- - )} + + + + + + + )} + ) } From d2f54caadb940a841b04eacfbaa39c4d32320369 Mon Sep 17 00:00:00 2001 From: guillermoscript Date: Sun, 13 Oct 2024 16:24:07 -0400 Subject: [PATCH 07/15] lint fix --- components/chatbox/ChatBox.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/chatbox/ChatBox.tsx b/components/chatbox/ChatBox.tsx index 0e1b8f2d..b695fb07 100644 --- a/components/chatbox/ChatBox.tsx +++ b/components/chatbox/ChatBox.tsx @@ -1,5 +1,6 @@ 'use client' +import { generateId } from 'ai' import { useChat } from 'ai/react' import { AnimatePresence, motion } from 'framer-motion' import { @@ -26,7 +27,6 @@ import { Input } from '@/components/ui/input' import { ScrollArea } from '@/components/ui/scroll-area' import ViewMarkdown from '../ui/markdown/ViewMarkdown' -import { generateId } from 'ai' interface ChatBoxProps { instructions: string From 5ad034d4709b50e5033f9cc607d61b1a2e65ae47 Mon Sep 17 00:00:00 2001 From: guillermoscript Date: Sun, 13 Oct 2024 17:07:13 -0400 Subject: [PATCH 08/15] Refactor ExerciseChat component to add router refresh on completion --- .../dashboards/student/course/exercises/exerciseChat.tsx | 3 +++ 1 file changed, 3 insertions(+) diff --git a/components/dashboards/student/course/exercises/exerciseChat.tsx b/components/dashboards/student/course/exercises/exerciseChat.tsx index 70b65da0..1b3f859d 100644 --- a/components/dashboards/student/course/exercises/exerciseChat.tsx +++ b/components/dashboards/student/course/exercises/exerciseChat.tsx @@ -18,6 +18,7 @@ import { ScrollArea } from '@/components/ui/scroll-area' import { Separator } from '@/components/ui/separator' import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs' import { Textarea } from '@/components/ui/textarea' +import { useRouter } from 'next/navigation' interface ExerciseChatProps { apiEndpoint: string @@ -44,6 +45,7 @@ export default function ExerciseChat({ // Create a ref for the scroll anchor const scrollAnchorRef = useRef(null) + const router = useRouter() const { messages, input, handleInputChange, handleSubmit, isLoading, stop, append } = useChat({ @@ -58,6 +60,7 @@ export default function ExerciseChat({ console.log('Tool call:', toolCall) if (toolCall.toolName === 'makeUserAssigmentCompleted') { setIsCompleted(true) + router.refresh() } }, }) From 02f8c2a92e0e1b46fe98f2ca6f65acefd03c2ac5 Mon Sep 17 00:00:00 2001 From: guillermoscript Date: Sun, 13 Oct 2024 17:07:17 -0400 Subject: [PATCH 09/15] Refactor ChatBox component to update bot avatar image path --- components/chatbox/ChatBox.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/chatbox/ChatBox.tsx b/components/chatbox/ChatBox.tsx index b695fb07..c1bf95e9 100644 --- a/components/chatbox/ChatBox.tsx +++ b/components/chatbox/ChatBox.tsx @@ -227,7 +227,7 @@ export default function ChatBox({ instructions }: ChatBoxProps) { message.role === 'user' ? '/user-avatar.png' - : '/bot-avatar.png' + : '/img/robot.jpeg' } /> From 1fa791f7ae90303a24b978dc96d9424c6eba816c Mon Sep 17 00:00:00 2001 From: guillermoscript Date: Sun, 13 Oct 2024 17:15:09 -0400 Subject: [PATCH 10/15] lint --- components/dashboards/student/course/exercises/exerciseChat.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/components/dashboards/student/course/exercises/exerciseChat.tsx b/components/dashboards/student/course/exercises/exerciseChat.tsx index 1b3f859d..55c987e9 100644 --- a/components/dashboards/student/course/exercises/exerciseChat.tsx +++ b/components/dashboards/student/course/exercises/exerciseChat.tsx @@ -4,6 +4,7 @@ import { ToolInvocation } from 'ai' import { Message, useChat } from 'ai/react' import dayjs from 'dayjs' import { Paperclip, Send } from 'lucide-react' +import { useRouter } from 'next/navigation' import { useEffect, useRef, useState } from 'react' import { useScopedI18n } from '@/app/locales/client' @@ -18,7 +19,6 @@ import { ScrollArea } from '@/components/ui/scroll-area' import { Separator } from '@/components/ui/separator' import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs' import { Textarea } from '@/components/ui/textarea' -import { useRouter } from 'next/navigation' interface ExerciseChatProps { apiEndpoint: string From cd798d7636fb224b49941f3f3e9690e0b55d3aa5 Mon Sep 17 00:00:00 2001 From: guillermoscript Date: Sun, 13 Oct 2024 18:00:00 -0400 Subject: [PATCH 11/15] Refactor language translations for exercise status and navigation buttons --- app/locales/en/views.ts | 2 ++ app/locales/es/views.ts | 2 ++ 2 files changed, 4 insertions(+) diff --git a/app/locales/en/views.ts b/app/locales/en/views.ts index adb74d3f..9354bff3 100644 --- a/app/locales/en/views.ts +++ b/app/locales/en/views.ts @@ -144,6 +144,8 @@ export default { startExercise: 'Start Exercise', exercises: 'Exercises', exercisesCompleted: 'Exercises Completed', + inProgress: 'In Progress', + continue: 'Continue', }, LessonPage: { description: 'View and track your progress through the course lessons.', diff --git a/app/locales/es/views.ts b/app/locales/es/views.ts index c0f680ce..41552d0f 100644 --- a/app/locales/es/views.ts +++ b/app/locales/es/views.ts @@ -145,6 +145,8 @@ export default { viewExercise: 'Ver ejercicio', exercises: 'Ejercicios', exercisesCompleted: 'Ejercicios completados', + inProgress: 'En progreso', + continue: 'Continuar', }, LessonPage: { description: 'Ver y realizar un seguimiento de tu progreso a través de la lección.', From 7368f04e7365947ad97cfeed6c96ce81962683b7 Mon Sep 17 00:00:00 2001 From: guillermoscript Date: Sun, 13 Oct 2024 18:00:06 -0400 Subject: [PATCH 12/15] Refactor ExerciseChat component to add ChatLoadingSkeleton --- .../student/course/exercises/exerciseChat.tsx | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/components/dashboards/student/course/exercises/exerciseChat.tsx b/components/dashboards/student/course/exercises/exerciseChat.tsx index 55c987e9..3ddc45e3 100644 --- a/components/dashboards/student/course/exercises/exerciseChat.tsx +++ b/components/dashboards/student/course/exercises/exerciseChat.tsx @@ -19,6 +19,7 @@ import { ScrollArea } from '@/components/ui/scroll-area' import { Separator } from '@/components/ui/separator' import { Tabs, TabsContent, TabsList, TabsTrigger } from '@/components/ui/tabs' import { Textarea } from '@/components/ui/textarea' +import ChatLoadingSkeleton from '@/components/dashboards/chat/ChatLoadingSkeleton' interface ExerciseChatProps { apiEndpoint: string @@ -105,11 +106,9 @@ export default function ExerciseChat({ } /> - {m.role === 'user' ? ( - profile.full_name[0] - ) : ( - 'A' - )} + {m.role === 'user' + ? profile.full_name[0] + : 'A'}
@@ -131,7 +130,8 @@ export default function ExerciseChat({ if ( toolInvocation.toolName === 'makeUserAssigmentCompleted' && - 'result' in toolInvocation + 'result' in + toolInvocation ) { return (
- {toolInvocation.result} + { + toolInvocation.result + }
) } @@ -153,6 +155,7 @@ export default function ExerciseChat({
) })} + {isLoading && } {/* Scroll Anchor */}
From 0d3b22c43ea785a7e8f58a589c07c926482971bd Mon Sep 17 00:00:00 2001 From: guillermoscript Date: Sun, 13 Oct 2024 18:00:25 -0400 Subject: [PATCH 13/15] Refactor ChatBox component to add ChatLoadingSkeleton --- components/chatbox/ChatBox.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/components/chatbox/ChatBox.tsx b/components/chatbox/ChatBox.tsx index c1bf95e9..3a8abd6e 100644 --- a/components/chatbox/ChatBox.tsx +++ b/components/chatbox/ChatBox.tsx @@ -27,6 +27,7 @@ import { Input } from '@/components/ui/input' import { ScrollArea } from '@/components/ui/scroll-area' import ViewMarkdown from '../ui/markdown/ViewMarkdown' +import ChatLoadingSkeleton from '../dashboards/chat/ChatLoadingSkeleton' interface ChatBoxProps { instructions: string @@ -252,6 +253,7 @@ export default function ChatBox({ instructions }: ChatBoxProps) { ) }) )} + {isLoading && } From 7bc6c2f5248fb7ad90ce8080e432a852d8873928 Mon Sep 17 00:00:00 2001 From: guillermoscript Date: Sun, 13 Oct 2024 18:00:59 -0400 Subject: [PATCH 14/15] Refactor ExerciseCard component to update exercise status badges and buttons --- .../student/courses/[courseId]/page.tsx | 51 +++++++++++-------- 1 file changed, 31 insertions(+), 20 deletions(-) diff --git a/app/[locale]/dashboard/student/courses/[courseId]/page.tsx b/app/[locale]/dashboard/student/courses/[courseId]/page.tsx index ffd41c65..04e27be0 100644 --- a/app/[locale]/dashboard/student/courses/[courseId]/page.tsx +++ b/app/[locale]/dashboard/student/courses/[courseId]/page.tsx @@ -1,4 +1,4 @@ -import { CheckCircle, Clock, Dumbbell, FileText } from 'lucide-react' +import { CheckCircle, Clock, Clock10, Dumbbell, FileText } from 'lucide-react' import Image from 'next/image' import Link from 'next/link' import { redirect } from 'next/navigation' @@ -17,9 +17,9 @@ const ExerciseCard = ({ title, description, difficulty, type, status, courseId, {title} - - {status === 'Completed' ? : } - {status === 'Completed' ? t('dashboard.student.CourseStudentPage.completed') : t('dashboard.student.CourseStudentPage.notStarted')} + + {status === 'Completed' ? : status === 'In Progress' ? : } + {status === 'Completed' ? t('dashboard.student.CourseStudentPage.completed') : status === 'In Progress' ? t('dashboard.student.CourseStudentPage.inProgress') : t('dashboard.student.CourseStudentPage.notStarted')} {type} - {difficulty} @@ -29,12 +29,15 @@ const ExerciseCard = ({ title, description, difficulty, type, status, courseId, @@ -211,7 +214,8 @@ export default async function CourseStudentPage({ ) ), exercises(*, - exercise_completions(id) + exercise_completions(id), + exercise_messages(id) ) ` ) @@ -220,6 +224,7 @@ export default async function CourseStudentPage({ .eq('lessons.lesson_completions.user_id', userData.data.user.id) .eq('exams.exam_submissions.student_id', userData.data.user.id) .eq('exercises.exercise_completions.user_id', userData.data.user.id) + .eq('exercises.exercise_messages.user_id', userData.data.user.id) .single() if (courseData.error != null) { @@ -294,19 +299,25 @@ export default async function CourseStudentPage({ value="exercises" > {courseData.data.exercises - .map((exercise) => ( - 0 ? 'Completed' : 'Not Started'} - courseId={courseData.data.course_id} - exerciseId={exercise.id} - t={t} - /> - ))} + .map((exercise) => { + + // if exercise has a completion, it is completed, else if it has a message, it is in progress else not started + const status = exercise.exercise_completions?.length > 0 ? 'Completed' : exercise.exercise_messages?.length > 0 ? 'In Progress' : 'Not Started' + + return ( + + ) + })} Date: Sun, 13 Oct 2024 18:04:51 -0400 Subject: [PATCH 15/15] lint change --- app/[locale]/dashboard/student/courses/[courseId]/page.tsx | 5 ++--- components/chatbox/ChatBox.tsx | 2 +- .../dashboards/student/course/exercises/exerciseChat.tsx | 2 +- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/app/[locale]/dashboard/student/courses/[courseId]/page.tsx b/app/[locale]/dashboard/student/courses/[courseId]/page.tsx index 04e27be0..086fc4e9 100644 --- a/app/[locale]/dashboard/student/courses/[courseId]/page.tsx +++ b/app/[locale]/dashboard/student/courses/[courseId]/page.tsx @@ -34,7 +34,7 @@ const ExerciseCard = ({ title, description, difficulty, type, status, courseId, className='w-full' > - + { status === 'Completed' ? t('dashboard.student.CourseStudentPage.review') : status === 'In Progress' ? t('dashboard.student.CourseStudentPage.continue') : t('dashboard.student.CourseStudentPage.start') } @@ -300,10 +300,9 @@ export default async function CourseStudentPage({ > {courseData.data.exercises .map((exercise) => { - // if exercise has a completion, it is completed, else if it has a message, it is in progress else not started const status = exercise.exercise_completions?.length > 0 ? 'Completed' : exercise.exercise_messages?.length > 0 ? 'In Progress' : 'Not Started' - + return (