Skip to content

Examn Generation with LLM for students to practices #71

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
104 commits
Select commit Hold shift + click to select a range
09adf61
refactor: Update types.ts to use consistent formatting
guillermoscript Jun 26, 2024
438a4ec
refactor: Add image plugin to InitializedMDXEditor
guillermoscript Jun 26, 2024
7695c06
refactor: Add 'use client' import to form.tsx
guillermoscript Jun 26, 2024
a03ef73
refactor: Improve chat item rendering in StudentChatSidebar
guillermoscript Jun 26, 2024
658367a
```text
guillermoscript Jun 26, 2024
e2c0bb4
refactor: Remove console.log statement in CommandDialogComponent
guillermoscript Jun 26, 2024
14a4630
refactor: Update NavLink component to support children
guillermoscript Jun 26, 2024
5de6970
refactor: Add sheet component to DashboardHeader
guillermoscript Jun 26, 2024
5ba9491
refactor: Update title and description in layout.tsx
guillermoscript Jun 26, 2024
ce7c22b
refactor: Update chat page title styling
guillermoscript Jun 26, 2024
854efcc
refactor: Update chat component to use generateId instead of nanoid
guillermoscript Jun 26, 2024
cd5761b
refactor: Add ExamPreparationActions to handle exam preparation chat …
guillermoscript Jun 26, 2024
4ba14c8
refactor: Improve modularity and organization of exam preparation cha…
guillermoscript Jun 26, 2024
68a5f43
refactor: Add ExamPrepChat component for exam preparation chat functi…
guillermoscript Jun 26, 2024
a469b75
refactor: Add ExamPrepChat component for exam preparation chat functi…
guillermoscript Jun 26, 2024
c7b3e03
refactor: Add ExamPrepChatLayout component for exam preparation chat …
guillermoscript Jun 26, 2024
c686c5d
refactor: Update chat page title styling
guillermoscript Jun 29, 2024
2724c2e
feat: Add ExamPrepChatIdLayout component for exam preparation chat la…
guillermoscript Jun 29, 2024
dca7c2a
refactor: Update button component to include disabled cursor style
guillermoscript Jun 29, 2024
de64b69
refactor: Add success and warning variants to alert component
guillermoscript Jun 29, 2024
6adac49
refactor: Update ExamPrepChatPage component to improve code organizat…
guillermoscript Jun 29, 2024
79974d9
refactor: Remove unused FreeChat component from ChatPage
guillermoscript Jun 29, 2024
1f1d086
refactor: Add stop state to ChatInput component for exam preparation …
guillermoscript Jun 29, 2024
3487297
refactor: Improve code organization and remove unused components in e…
guillermoscript Jun 29, 2024
e51e1b8
refactor: Improve code organization and remove unused components in e…
guillermoscript Jun 29, 2024
1b95de8
chore: Update npm dependencies for @ai-sdk/google and @ai-sdk/openai
guillermoscript Jun 30, 2024
905eed9
feat: Add ExamFeedbackCard component for displaying exam feedback
guillermoscript Jun 30, 2024
829d8a8
refactor: Improve code organization and remove unused components in e…
guillermoscript Jun 30, 2024
246d2ce
refactor: Improve code organization and remove unused components in e…
guillermoscript Jun 30, 2024
b9f219c
refactor: Improve code organization and remove unused components in e…
guillermoscript Jun 30, 2024
cb8a263
refactor: Improve code organization and remove unused components in e…
guillermoscript Jun 30, 2024
bf29bcb
refactor: Improve code organization and remove unused components in e…
guillermoscript Jul 4, 2024
4cf3ff6
refactor: Improve code organization and remove unused components in e…
guillermoscript Jul 4, 2024
0af5b21
refactor: Improve code organization and remove unused components in e…
guillermoscript Jul 4, 2024
e8d2f67
refactor: Remove ExamPrepChatLayout component
guillermoscript Jul 4, 2024
d77b325
refactor: Add Message component for chat feature
guillermoscript Jul 4, 2024
08c363d
refactor: Remove Suspense from ChatWindow component
guillermoscript Jul 4, 2024
ee07cee
refactor: Update ExamnChatIdPage component in exam preparation chat
guillermoscript Jul 4, 2024
4008214
refactor: Update ExamnChatIdPage component in exam preparation chat
guillermoscript Jul 4, 2024
e74aef7
refactor: Update ExamnChatIdPage component and add AI integration in …
guillermoscript Jul 4, 2024
61c3b74
refactor: Add ExamLink component for exam preparation chat
guillermoscript Jul 4, 2024
7fd8821
refactor: Update student chat actions and components
guillermoscript Jul 4, 2024
72aa8df
refactor: Add Loading component for exam preparation chat
guillermoscript Jul 4, 2024
ba04fa4
refactor: Improve code organization and remove unused components in e…
guillermoscript Jul 4, 2024
eeaf7c5
refactor: Update ExamnChatIdPage component in exam preparation chat
guillermoscript Jul 5, 2024
7acaee1
refactor: Update ExamnChatIdPage component in exam preparation chat
guillermoscript Jul 5, 2024
60ec789
refactor: Add ChatLoadingSkeleton component for student chat
guillermoscript Jul 6, 2024
9db4222
refactor: Add studentUpdateChatTitle function for updating chat title
guillermoscript Jul 6, 2024
33c59c1
refactor: Update ExamFeedbackCard component to use TypeScript interface
guillermoscript Jul 6, 2024
2d80c44
refactor: Add ChatLoadingSkeleton component and update student chat a…
guillermoscript Jul 6, 2024
ca695d5
refactor: Update ExamPrepAiComponent to handle hiding submit button
guillermoscript Jul 6, 2024
30c5c50
refactor: Update ExamPrepAiComponent to handle hiding submit button
guillermoscript Jul 6, 2024
8f0aae2
refactor: Update ExamnChatIdPageLayout to handle chat message IDs as …
guillermoscript Jul 6, 2024
d721928
replace the pages
guillermoscript Jul 6, 2024
9f1d546
refactor: Add Error component for handling chat loading errors
guillermoscript Jul 6, 2024
2c89c8a
feat: Add ExamnSuggestions component for displaying exam suggestions …
guillermoscript Jul 6, 2024
681d556
feat: Add ChatSidebarItem component for displaying chat items in the …
guillermoscript Jul 6, 2024
1897499
refactor: Update StudentChatSidebar to use ChatSidebarItem component
guillermoscript Jul 6, 2024
885d589
refactor: Remove commented out code for inserting chat message in Exa…
guillermoscript Jul 6, 2024
bc8ee27
refactor: Update ExamLink to use new chat ID route format
guillermoscript Jul 6, 2024
726a317
refactor: Update ExamFeedbackCard to handle optional score and overal…
guillermoscript Jul 6, 2024
255c1d4
refactor: Improve SuggestionsContainer component
guillermoscript Jul 6, 2024
2c52dfa
refactor: Remove unnecessary HoverCard components from ChatPage
guillermoscript Jul 6, 2024
ebde842
refactor: Remove unnecessary HoverCard components from ChatPage
guillermoscript Jul 6, 2024
cebfcbb
new tool for suggestions added, also added the message wrapper for th…
guillermoscript Jul 6, 2024
baeb2c1
refactor: Improve SuggestionsContainer component
guillermoscript Jul 6, 2024
bccb557
build fix
guillermoscript Jul 6, 2024
102890d
adding new meesage for the IA, new component for a new type of questi…
guillermoscript Jul 7, 2024
c3863bd
new type of question added, and better use of the propmpts
guillermoscript Jul 7, 2024
edfbf48
removed
guillermoscript Jul 7, 2024
d46aa03
refactor: Fix revalidatePath call in studentCreateNewChat
guillermoscript Jul 7, 2024
8895f76
refactor: Update generateId function usage in TaksMessages and TaskMe…
guillermoscript Jul 7, 2024
f8c6778
chore: Update npm dependencies for @radix-ui/react-collapsible to ver…
guillermoscript Jul 7, 2024
bbfac18
refactor: Uncomment revalidatePath call in deleteChat function
guillermoscript Jul 7, 2024
1c29c9b
```text
guillermoscript Jul 7, 2024
a501cdd
refactor: Update StudentChatSidebar to use Collapsible component
guillermoscript Jul 7, 2024
5d0c514
refactor: Update ChatSidebarItem component
guillermoscript Jul 7, 2024
b53345d
```text
guillermoscript Jul 7, 2024
35bf6c9
refactor: Update DashboardLayout component styles
guillermoscript Jul 7, 2024
afd1af8
refactor: Update h1 font weight in ChatLayout component
guillermoscript Jul 7, 2024
959b5c6
build fix
guillermoscript Jul 7, 2024
8bd6f05
chore: Update npm dependencies for @radix-ui/react-collapsible to ver…
guillermoscript Jul 7, 2024
ab89ac0
refactor: Add StudentCreateNewChat component
guillermoscript Jul 7, 2024
e6d00fd
refactor: Update StudentChatSidebar to use Collapsible component
guillermoscript Jul 7, 2024
ca95078
refactor: Remove console.log statements in chat route
guillermoscript Jul 7, 2024
f1a5b48
refactor: Add MDXEditorMethods to ChatInput for markdown handling
guillermoscript Jul 7, 2024
7905abc
chore: Update npm dependencies for sonner to version 1.5.0
guillermoscript Jul 7, 2024
de627eb
refactor: Add Sonner component for toast notifications
guillermoscript Jul 7, 2024
145d14a
refactor: Update resizable handle size and styling
guillermoscript Jul 7, 2024
4cde76b
feat: Add AllCoursesCard component for displaying all courses
guillermoscript Jul 7, 2024
ff1341f
refactor: Add ScrollToTopButton component for smooth scrolling to the…
guillermoscript Jul 7, 2024
b8e9293
feat: Add loading components for chat and courses
guillermoscript Jul 7, 2024
c8f9c4b
feat: Add metadata to course and dashboard layouts
guillermoscript Jul 7, 2024
c84410d
feat: Update lesson and course page metadata
guillermoscript Jul 7, 2024
43635c3
refactor: Update loading components for dashboard and student pages
guillermoscript Jul 7, 2024
218e8db
feat: Update loading component in exam prep page
guillermoscript Jul 7, 2024
10ca351
refactor: Remove unused code and improve layout of student page
guillermoscript Jul 7, 2024
dd19baf
refactor: Remove commented code in ExamChatPage component
guillermoscript Jul 7, 2024
87fea4c
refactor: Remove unused code and improve layout of student page
guillermoscript Jul 7, 2024
bec63b4
```text
guillermoscript Jul 7, 2024
a1e5aa6
refactor: Remove unused code and improve layout of CommentsCard compo…
guillermoscript Jul 7, 2024
7586946
refactor: Remove unused code and improve layout of CommandDialogCompo…
guillermoscript Jul 7, 2024
4ae260d
refactor: Improve layout and remove unused code in Toaster component
guillermoscript Jul 7, 2024
c0071c2
refactor: Improve layout and remove unused code in loading components
guillermoscript Jul 7, 2024
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
673 changes: 673 additions & 0 deletions actions/dashboard/ExamPreparationActions.tsx

Large diffs are not rendered by default.

128 changes: 123 additions & 5 deletions actions/dashboard/chatActions.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
'use server'

import { revalidatePath } from 'next/cache'

import { createResponse } from '@/utils/functions'
import { createClient } from '@/utils/supabase/server'
import { Tables } from '@/utils/supabase/supabase'
Expand Down Expand Up @@ -29,11 +31,11 @@ export async function studentCreateNewChat (state: {
}

// return chat id
// revalidatePath('/dashboard/student/chat/', 'layout')
revalidatePath('/dashboard/student/chat/', 'layout')
return createResponse('success', 'Chat created successfully', chatInsert.data, null)
}

export async function studentSubmitMessage (state: {
export async function studentInsertChatMessage (state: {
chatId: number
message: string
}) {
Expand All @@ -44,18 +46,134 @@ export async function studentSubmitMessage (state: {
return createResponse('error', 'Error no user found', null, 'Error no user found')
}

const studentId = userData.data.user?.id
const messageInsert = await supabase.from('messages').insert({
chat_id: state.chatId,
message: state.message,
sender: 'user',
created_at: new Date().toISOString()
})

if (messageInsert.error) {
return createResponse('error', 'Error creating message', null, 'Error creating message')
}

return createResponse('success', 'Message sent successfully', null, null)
}

export async function studentUpdateChatTitle (state: {
chatId: number
title: string
}) {
const supabase = createClient()
const userData = await supabase.auth.getUser()

if (userData.error) {
return createResponse('error', 'Error no user found', null, 'Error no user found')
}

const chatUpdate = await supabase.from('chats').update({
title: state.title
}).eq('chat_id', state.chatId)

if (chatUpdate.error) {
return createResponse('error', 'Error updating chat', null, 'Error updating chat')
}

revalidatePath('/dashboard/student/chat/', 'layout')
return createResponse('success', 'Chat updated successfully', null, null)
}

export async function insertChatMessage (state: {
chatId: number
message: string
sender: Tables<'messages'>['sender']
}) {
const supabase = createClient()
const userData = await supabase.auth.getUser()

if (userData.error) {
return createResponse('error', 'Error no user found', null, 'Error no user found')
}

const messageInsert = await supabase.from('messages').insert({
chat_id: state.chatId,
message: state.message,
sender: state.sender,
created_at: new Date().toISOString()
})

if (messageInsert.error) {
return createResponse('error', 'Error creating message', null, 'Error creating message')
}

return createResponse('success', 'Message sent successfully', null, null)
}

export async function studentUpdateChat (state: {
chatId: number
title: string
}) {
const supabase = createClient()
const userData = await supabase.auth.getUser()

if (userData.error) {
return createResponse('error', 'Error no user found', null, 'Error no user found')
}

const chatUpdate = await supabase.from('chats').update({
title: state.title
}).eq('chat_id', state.chatId)

if (chatUpdate.error) {
return createResponse('error', 'Error updating chat', null, 'Error updating chat')
}

// revalidatePath('/dashboard/student/chat/', 'layout')
return createResponse('success', 'Chat updated successfully', null, null)
}

export async function studentSubmitMessage (state: {
chatId: number
message: string
}) {
const supabase = createClient()
const userData = await supabase.auth.getUser()

if (userData.error) {
return createResponse('error', 'Error no user found', null, 'Error no user found')
}

const messageInsert = await supabase.from('messages').insert({
user_id: studentId,
chat_id: state.chatId,
content: state.message,
message: state.message,
sender: 'user',
created_at: new Date().toISOString()
})

if (messageInsert.error) {
console.log(messageInsert.error)
return createResponse('error', 'Error creating message', null, 'Error creating message')
}

return createResponse('success', 'Message sent successfully', null, null)
}

export async function deleteChat (state: {
chatId: number
}) {
const supabase = createClient()
const userData = await supabase.auth.getUser()

if (userData.error) {
return createResponse('error', 'Error no user found', null, 'Error no user found')
}

const chatDelete = await supabase.from('chats').delete().eq('chat_id', state.chatId)

if (chatDelete.error) {
return createResponse('error', 'Error deleting chat', null, 'Error deleting chat')
}

revalidatePath('/dashboard/student/chat/', 'layout')
return createResponse('success', 'Chat deleted successfully', null, null)
}
6 changes: 0 additions & 6 deletions app/api/chat/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,10 +23,6 @@ export async function POST (req: Request) {
async onFinish (event) {
const lastUserMessage = messages[messages.length - 1]

console.log(messages)

console.log(lastUserMessage)

const chat_id = chatId ?? (await supabase.from('chats').select('chat_id').eq('title', lastUserMessage.content).single()).data.chat_id

console.log(chat_id)
Expand All @@ -50,8 +46,6 @@ export async function POST (req: Request) {
if (messageInsert.error) {
console.log('Error creating message', messageInsert.error)
}

console.log('Message sent successfully')
}
})

Expand Down
31 changes: 5 additions & 26 deletions app/dashboard/loading.tsx
Original file line number Diff line number Diff line change
@@ -1,35 +1,14 @@
/**
* v0 by Vercel.
* @see https://v0.dev/t/vkBhDMemo6s
* Documentation: https://v0.dev/docs#integrating-generated-code-into-your-nextjs-app
*/
import { Skeleton } from '@/components/ui/skeleton'

export default function Component () {
return (
<div className="grid min-h-screen w-full lg:grid-cols-[280px_1fr]">
<div className="hidden border-r bg-gray-100/40 lg:block dark:bg-gray-800/40">
<div className="flex h-full max-h-screen flex-col gap-2">
<div className="flex h-[60px] items-center border-b px-6">
<Skeleton className="h-6 w-6 rounded-full" />
<Skeleton className="h-5 w-24 ml-2" />
</div>
<div className="flex-1 overflow-auto py-2">
<nav className="grid gap-2 px-4">
<Skeleton className="h-8 w-full rounded-md" />
<Skeleton className="h-8 w-full rounded-md" />
<Skeleton className="h-8 w-full rounded-md" />
<Skeleton className="h-8 w-full rounded-md" />
<Skeleton className="h-8 w-full rounded-md" />
</nav>
</div>
<div className="mt-auto p-4">
<Skeleton className="h-[125px] w-full rounded-lg" />
</div>
</div>
</div>
<div className="grid min-h-screen w-full lg:grid-cols-[1fr]">
<div className="flex flex-col">
<main className="flex-1 p-4 md:p-6">
<div className="flex items-center">
<Skeleton className="h-6 w-40 rounded-md" />
<Skeleton className="h-8 w-20 ml-auto rounded-md" />
</div>
<div className="mt-4 border rounded-lg shadow-sm">
<Skeleton className="h-[200px] w-full rounded-t-lg" />
<div className="p-4 md:p-6">
Expand Down
26 changes: 26 additions & 0 deletions app/dashboard/student/chat/[chatId]/exam-prep/error.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
'use client' // Error components must be Client Components

import { useEffect } from 'react'

import GenericError from '@/components/GenericError'

export default function Error ({
error,
reset
}: {
error: Error & { digest?: string }
reset: () => void
}) {
useEffect(() => {
// Log the error to an error reporting service
console.error(error)
}, [error])

return (
<GenericError
retry={reset}
title="Oh no! An error occurred loading the chat."
description={error.message}
/>
)
}
107 changes: 107 additions & 0 deletions app/dashboard/student/chat/[chatId]/exam-prep/layout.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { AI, getUIStateFromAIState } from '@/actions/dashboard/ExamPreparationActions'
import { createClient } from '@/utils/supabase/server'

export default async function ExamnChatIdPageLayout ({
params,
children
}: {
params: {
chatId: string
}
children: React.ReactNode
}) {
const supabase = createClient()

const messagesData = await supabase
.from('chats')
.select('*, messages(*)')
.eq('chat_id', Number(params.chatId))
.order('created_at', { foreignTable: 'messages', ascending: true })
.single()

if (messagesData.error) {
console.log(messagesData.error)
throw new Error('Error fetching messages')
}

// WTF!!!! why this need an await?????
const uiState = await getUIStateFromAIState({
id: messagesData.data.chat_id.toString(),
createdAt: new Date(messagesData.data.created_at),
messages: messagesData.data.messages.map((message) => {
if (!message) return null

if (message.sender === 'tool') {
return ({
id: message.id,
role: message.sender as any,
content: JSON.parse(message.message)
})
}

if (message.sender === 'assistant') {
// if the content is a json stringified object then parse it
if (message.message.startsWith('{') || message.message.startsWith('[')) {
return ({
id: message.id,
role: message.sender as any,
content: JSON.parse(message.message)
})
}
return ({
id: message.id,
role: message.sender as any,
content: message.message
})
}

return ({
id: message.id,
role: message.sender as any,
content: message.message
})
}) as any
})

const messsages = messagesData.data.messages.map((message) => {
if (message.sender === 'tool') {
return ({
id: message.id.toString(),
role: message.sender as any,
content: JSON.parse(message.message)
})
}

if (message.sender === 'assistant') {
// if the content is a json stringified object then parse it
if (message.message.startsWith('{') || message.message.startsWith('[')) {
return ({
id: message.id.toString(),
role: message.sender as any,
content: JSON.parse(message.message)
})
}

return ({
id: message.id.toString(),
role: message.sender as any,
content: message.message
})
}

return ({
id: message.id.toString(),
role: message.sender as any,
content: message.message
})
})

return (
<AI
initialUIState={uiState}
initialAIState={{ chatId: (params.chatId), messages: messsages }}
>
{children}
</AI>
)
}
7 changes: 7 additions & 0 deletions app/dashboard/student/chat/[chatId]/exam-prep/loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import ChatLoadingSkeleton from '@/components/dashboards/student/chat/ChatLoadingSkeleton'

export default function Loading () {
return (
<ChatLoadingSkeleton />
)
}
18 changes: 18 additions & 0 deletions app/dashboard/student/chat/[chatId]/exam-prep/page.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import ExamPrepChat from '@/components/dashboards/student/chat/ExamPrepChat'

export const dynamic = 'force-dynamic'
export const maxDuration = 30

export default async function ExamnChatIdPage ({
params
}: {
params: {
chatId: string
}
}) {
return (
<ExamPrepChat
chatId={Number(params.chatId)}
/>
)
}
7 changes: 7 additions & 0 deletions app/dashboard/student/chat/[chatId]/free-chat/loading.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import ChatLoadingSkeleton from '@/components/dashboards/student/chat/ChatLoadingSkeleton'

export default function Loading () {
return (
<ChatLoadingSkeleton />
)
}
2 changes: 1 addition & 1 deletion app/dashboard/student/chat/[chatId]/layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export default async function CoursesLayout ({

return (
<div className='flex flex-col gap-4 p-4'>
<h1 className="text-2xl font-semibold text-gray-800">
<h1 className="text-2xl font-semibold">
{chatData.data.title}
</h1>
{children}
Expand Down
Loading
Loading