From 1cd0b1b08c6e117427f55974cec21c0c96b99800 Mon Sep 17 00:00:00 2001 From: guillermoscript Date: Sun, 16 Jun 2024 20:00:49 -0400 Subject: [PATCH 01/14] refactor: Update package dependencies for @radix-ui/react-popover to version 1.0.7 --- package-lock.json | 1 + package.json | 1 + 2 files changed, 2 insertions(+) diff --git a/package-lock.json b/package-lock.json index 60453ffc..bf49b651 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "@radix-ui/react-icons": "^1.3.0", "@radix-ui/react-label": "^2.0.2", "@radix-ui/react-menubar": "^1.0.4", + "@radix-ui/react-popover": "^1.0.7", "@radix-ui/react-radio-group": "^1.1.3", "@radix-ui/react-scroll-area": "^1.0.5", "@radix-ui/react-select": "^2.0.0", diff --git a/package.json b/package.json index aeee4cf2..c516b212 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "@radix-ui/react-icons": "^1.3.0", "@radix-ui/react-label": "^2.0.2", "@radix-ui/react-menubar": "^1.0.4", + "@radix-ui/react-popover": "^1.0.7", "@radix-ui/react-radio-group": "^1.1.3", "@radix-ui/react-scroll-area": "^1.0.5", "@radix-ui/react-select": "^2.0.0", From 5eabb0bf2c787d032b714819c0f337a79254cdec Mon Sep 17 00:00:00 2001 From: guillermoscript Date: Sun, 16 Jun 2024 20:00:55 -0400 Subject: [PATCH 02/14] refactor: Add Popover component for UI element with interactive content This commit adds a new component, Popover, to the components/ui/popover.tsx file. The Popover component is used to create a UI element with interactive content. It utilizes the @radix-ui/react-popover library for the implementation. This refactor enhances the user experience by providing a versatile and customizable popover functionality for various use cases. --- components/ui/popover.tsx | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 components/ui/popover.tsx diff --git a/components/ui/popover.tsx b/components/ui/popover.tsx new file mode 100644 index 00000000..2bd5a03d --- /dev/null +++ b/components/ui/popover.tsx @@ -0,0 +1,31 @@ +"use client" + +import * as React from "react" +import * as PopoverPrimitive from "@radix-ui/react-popover" + +import { cn } from "@/utils" + +const Popover = PopoverPrimitive.Root + +const PopoverTrigger = PopoverPrimitive.Trigger + +const PopoverContent = React.forwardRef< + React.ElementRef, + React.ComponentPropsWithoutRef +>(({ className, align = "center", sideOffset = 4, ...props }, ref) => ( + + + +)) +PopoverContent.displayName = PopoverPrimitive.Content.displayName + +export { Popover, PopoverTrigger, PopoverContent } From 7c5eb2f3308a372ecf82b19b280d31dbaa45fb91 Mon Sep 17 00:00:00 2001 From: guillermoscript Date: Sun, 16 Jun 2024 20:01:03 -0400 Subject: [PATCH 03/14] refactor: Add support for adding reactions to comments This commit adds the functionality to add reactions to comments in the student dashboard. It introduces a new function, addReactionToComment, which allows users to react to comments with different types of reactions. The function handles updating and deleting reactions based on the user's selection. This enhancement improves the user experience by providing an interactive way for students to engage with comments in the dashboard. --- actions/dashboard/studentActions.ts | 89 +++++++++++++++++++++++++++++ 1 file changed, 89 insertions(+) diff --git a/actions/dashboard/studentActions.ts b/actions/dashboard/studentActions.ts index 9bf95347..46175c08 100644 --- a/actions/dashboard/studentActions.ts +++ b/actions/dashboard/studentActions.ts @@ -5,6 +5,7 @@ import { revalidatePath } from 'next/cache' import { updateUserProfileSchema } from '@/components/dashboards/student/account/EditProfileForm' import { createResponse } from '@/utils/functions' import { createClient } from '@/utils/supabase/server' +import { Tables } from '@/utils/supabase/supabase' export async function studentSubmitLessonComment (state: { comment: string @@ -90,3 +91,91 @@ export async function updateUserProfile ({ revalidatePath('/dashboard/student/account/profile', 'layout') return createResponse('success', 'Profile updated successfully', null, null) } + +export async function addReactionToComment ({ + commentId, + reactionType, + isReactionPresent +}: { + commentId: number + reactionType: Tables<'comment_reactions'>['reaction_type'] + isReactionPresent: Tables<'comment_reactions'> +}) { + const supabase = createClient() + const userData = await supabase.auth.getUser() + + if (userData.error) { + return createResponse('error', 'Error user not found', null, 'Error user not found') + } + + if (isReactionPresent) { + // check if the reaction is the same as the one present + // if it is, delete the reaction else update the reaction + const selectedReaction = isReactionPresent.reaction_type + if (selectedReaction === reactionType) { + const reactionDelete = await supabase + .from('comment_reactions') + .delete() + .eq('id', isReactionPresent.id) + + if (reactionDelete.error) { + return createResponse('error', 'Error deleting reaction', null, 'Error deleting reaction') + } + + revalidatePath('/dashboard/student/courses/[courseId]/lessons/[lessonId]', 'layout') + return createResponse('success', 'Reaction deleted successfully', null, null) + } else { + const reactionUpdate = await supabase + .from('comment_reactions') + .update({ + reaction_type: reactionType + }) + .eq('id', isReactionPresent.id) + + if (reactionUpdate.error) { + return createResponse('error', 'Error updating reaction', null, 'Error updating reaction') + } + + revalidatePath('/dashboard/student/courses/[courseId]/lessons/[lessonId]', 'layout') + return createResponse('success', 'Reaction updated successfully', null, null) + } + } + + const studentId = userData.data.user?.id + + const reactionInsert = await supabase.from('comment_reactions').insert({ + user_id: studentId, + comment_id: commentId, + reaction_type: reactionType + }) + + if (reactionInsert.error) { + return createResponse('error', 'Error adding reaction', null, 'Error adding reaction') + } + + revalidatePath('/dashboard/student/courses/[courseId]/lessons/[lessonId]', 'layout') + return createResponse('success', 'Reaction added successfully', null, null) +} + +export async function updateComment ({ + commentId, + content +}: { + commentId: number + content: string +}) { + const supabase = createClient() + const commentUpdate = await supabase + .from('lesson_comments') + .update({ + content + }) + .eq('id', commentId) + + if (commentUpdate.error) { + return createResponse('error', 'Error updating comment', null, 'Error updating comment') + } + + revalidatePath('/dashboard/student/courses/[courseId]/lessons/[lessonId]', 'layout') + return createResponse('success', 'Comment updated successfully', null, null) +} From e0b1155c795817de4a2e59ada4bb13f2f4fff647 Mon Sep 17 00:00:00 2001 From: guillermoscript Date: Sun, 16 Jun 2024 20:01:10 -0400 Subject: [PATCH 04/14] refactor: Update LessonPage component with Tabs for comments and timeline --- .../student/courses/[courseId]/lessons/[lessonsId]/page.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/app/dashboard/student/courses/[courseId]/lessons/[lessonsId]/page.tsx b/app/dashboard/student/courses/[courseId]/lessons/[lessonsId]/page.tsx index 183a929b..343139e9 100644 --- a/app/dashboard/student/courses/[courseId]/lessons/[lessonsId]/page.tsx +++ b/app/dashboard/student/courses/[courseId]/lessons/[lessonsId]/page.tsx @@ -41,7 +41,8 @@ export default async function StudentLessonPage ({ .select(`*, courses(*), lesson_comments(*, - profiles(*) + profiles(*), + comment_reactions(*) ), lessons_ai_tasks(*), lessons_ai_task_messages(*) From f8b2264444e38f94a99150f6ca348cebef5c2cbe Mon Sep 17 00:00:00 2001 From: guillermoscript Date: Sun, 16 Jun 2024 20:01:18 -0400 Subject: [PATCH 05/14] refactor: Update CommentsSections component with improved UI and functionality This commit updates the CommentsSections component in the components/dashboards/Common/CommentsSections.tsx file. The changes include refactoring the component to improve its UI and functionality. It removes unused imports, simplifies the code structure, and adds support for lazy loading of images. These updates enhance the user experience by improving the performance and visual appeal of the comments section in the dashboard. --- .../dashboards/Common/CommentsSections.tsx | 98 ++++++------------- 1 file changed, 32 insertions(+), 66 deletions(-) diff --git a/components/dashboards/Common/CommentsSections.tsx b/components/dashboards/Common/CommentsSections.tsx index d02539aa..3edd73a8 100644 --- a/components/dashboards/Common/CommentsSections.tsx +++ b/components/dashboards/Common/CommentsSections.tsx @@ -1,30 +1,18 @@ import dayjs from 'dayjs' -import { User2 } from 'lucide-react' -import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar' -import { - Card, - CardContent, - CardDescription, - CardHeader, - CardTitle -} from '@/components/ui/card' -import ViewMarkdown from '@/components/ui/markdown/ViewMarkdown' -import { Separator } from '@/components/ui/separator' +import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' import { createClient } from '@/utils/supabase/server' -import { Tables } from '@/utils/supabase/supabase' import CommentEditor from '../student/course/lessons/CommentEditor' +import CommentCard from './comments/CommentsCard' export default async function CommentsSections ({ lesson_id, lesson_comments -}: { - lesson_id: number - lesson_comments: Array> }) { const supabase = createClient() const usersIds = lesson_comments.map((comment) => comment.user_id) + const currentUser = await supabase.auth.getUser() const profiles = await supabase .from('profiles') .select('*') @@ -36,23 +24,35 @@ export default async function CommentsSections ({ } return ( -
- {lesson_comments?.map((comment) => ( - - ))} - - - - - - - - +
+

Comments

+ {lesson_comments + .filter(comment => comment.parent_comment_id === null) + .map((comment) => { + const user = profiles.data.find((profile) => profile.id === comment.user_id) + const isReactionPresent = comment.comment_reactions.find( + (reaction) => reaction.user_id === currentUser.data.user.id + ) + + return ( + + ) + })} + + + Add a Comment @@ -62,37 +62,3 @@ export default async function CommentsSections ({
) } - -const CommentCard = ({ - name, - comment, - date -}: { - name: string - comment: string - date: string -}) => { - return ( - - - - - {name[0]} - - {name} - - {date} - - - - -
-
- -
-
-
- ) -} From 95dda7ce5157ca0ef5af7f6ea69251acf4d8f3f6 Mon Sep 17 00:00:00 2001 From: guillermoscript Date: Sun, 16 Jun 2024 20:01:38 -0400 Subject: [PATCH 06/14] refactor: Update CommentsSections component with improved UI and functionality, this allow the user to reply and react to comments in a simple UI --- .../Common/comments/CommentsCard.tsx | 226 ++++++++++++++++++ 1 file changed, 226 insertions(+) create mode 100644 components/dashboards/Common/comments/CommentsCard.tsx diff --git a/components/dashboards/Common/comments/CommentsCard.tsx b/components/dashboards/Common/comments/CommentsCard.tsx new file mode 100644 index 00000000..283df389 --- /dev/null +++ b/components/dashboards/Common/comments/CommentsCard.tsx @@ -0,0 +1,226 @@ +'use client' +import { User } from '@supabase/supabase-js' +import dayjs from 'dayjs' +import { Edit3, Flag, Meh, Reply, Smile, ThumbsDown, ThumbsUp } from 'lucide-react' +import { useState } from 'react' + +import { addReactionToComment } from '@/actions/dashboard/studentActions' +import CommentEditor from '@/components/dashboards/student/course/lessons/CommentEditor' +import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from '@/components/ui/accordion' +import { Avatar, AvatarFallback, AvatarImage } from '@/components/ui/avatar' +import { Button } from '@/components/ui/button' +import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '@/components/ui/card' +import ViewMarkdown from '@/components/ui/markdown/ViewMarkdown' +import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover' +import { Separator } from '@/components/ui/separator' +import { useToast } from '@/components/ui/use-toast' +import { Tables } from '@/utils/supabase/supabase' + +const ReactionButton = ({ type, icon: Icon, count, onClick }) => ( + +) + +const CommentCard = ({ + comment, + name, + avatar, + date, + isAuthor, + comment_reactions, + isReactionPresent, + allComments, + profiles, + currentUser +}: { + comment: Tables<'lesson_comments'> + name: string + avatar: string + date: string + isAuthor: boolean + comment_reactions: Array> + isReactionPresent?: Tables<'comment_reactions'> + allComments: any[] + profiles: Array> + currentUser: User +}) => { + const [showReplies, setShowReplies] = useState(false) + const [isEditing, setIsEditing] = useState(false) + const { toast } = useToast() + + const toggleReplies = () => setShowReplies(!showReplies) + const toggleEdit = () => setIsEditing(!isEditing) + + const reactionTypes: Array<{ + type: Tables<'comment_reactions'>['reaction_type'] + icon: any + color: string + }> = [ + { type: 'like', icon: ThumbsUp, color: 'text-blue-500' }, + { type: 'funny', icon: Smile, color: 'text-yellow-500' }, + { type: 'boring', icon: Meh, color: '' }, + { type: 'dislike', icon: ThumbsDown, color: 'text-red-500' } + ] + + async function AddReaction (reaction: Tables<'comment_reactions'>['reaction_type']) { + try { + const response = await addReactionToComment({ + commentId: comment.id, + reactionType: reaction, + isReactionPresent + }) + + const toastMessage = { + title: response.status === 'success' ? 'Success' : 'Error', + description: + response.status === 'success' + ? 'Reaction added successfully' + : response.message, + variant: response.status === 'success' ? null : 'destructive' + } + toast(toastMessage as any) + } catch (error) { + console.error(error) + toast({ + title: 'Error', + description: + 'An error occurred while adding reaction. Please try again.', + variant: 'destructive' + }) + } + } + + const reactionsForEachType = comment_reactions.reduce((acc, reaction) => { + acc[reaction.reaction_type] = acc[reaction.reaction_type] + 1 || 1 + return acc + }, {}) + + const replies = allComments.filter(reply => reply.parent_comment_id === comment.id) + + return ( + + + + + {name[0]} + +
+
+ {name} + {date} +
+
+ {isAuthor && ( + + )} + +
+
+
+ + + + {isEditing && isAuthor && ( +
+ setIsEditing(false)} + /> + +
+ )} + {showReplies && ( +
+
+ { setShowReplies(false) }} /> + +
+
+ )} +
+ + +
+
+ + + + + +
+ {reactionTypes.map(({ type, icon: Icon, color }) => ( + await AddReaction(type)} + /> + ))} +
+
+
+ +
+
+ + + View Replies ({replies.length}) + +
+ {replies.map((reply) => { + // Now we correctly find the user profile for replies + const replyUser = profiles.find(profile => profile.id === reply.user_id) + const isReplyAuthor = reply.user_id === currentUser.id + + return ( + reaction.user_id === currentUser.id + )} + allComments={allComments} + profiles={profiles} + currentUser={currentUser} + /> + ) + })} +
+
+
+
+
+
+ ) +} + +export default CommentCard From cb832dd192b2c6c75258bc91cd8789d99daf189a Mon Sep 17 00:00:00 2001 From: guillermoscript Date: Sun, 16 Jun 2024 20:01:52 -0400 Subject: [PATCH 07/14] refactor: Update CommentEditor component to support editing existing comments This commit updates the CommentEditor component in the components/dashboards/student/course/lessons/CommentEditor.tsx file. The changes include adding support for editing existing comments by passing a comment_id prop to the component. When the comment_id prop is provided, the component updates the comment instead of creating a new one. This enhancement improves the user experience by allowing students to edit their comments without having to delete and recreate them. --- .../student/course/lessons/CommentEditor.tsx | 41 +++++++++++-------- 1 file changed, 24 insertions(+), 17 deletions(-) diff --git a/components/dashboards/student/course/lessons/CommentEditor.tsx b/components/dashboards/student/course/lessons/CommentEditor.tsx index 4f7622aa..b5938841 100644 --- a/components/dashboards/student/course/lessons/CommentEditor.tsx +++ b/components/dashboards/student/course/lessons/CommentEditor.tsx @@ -2,36 +2,32 @@ import { useState } from 'react' -import { studentSubmitLessonComment } from '@/actions/dashboard/studentActions' +import { studentSubmitLessonComment, updateComment } from '@/actions/dashboard/studentActions' import { Button } from '@/components/ui/button' import { ForwardRefEditor } from '@/components/ui/markdown/ForwardRefEditor' import { useToast } from '@/components/ui/use-toast' export default function CommentEditor ({ lesson_id, - parent_comment_id + parent_comment_id, + comment_id, + callback }: { lesson_id: number parent_comment_id?: number + comment_id?: number + callback?: () => void }) { const [commentState, setComment] = useState('') const [isLoading, setIsLoading] = useState(false) const { toast } = useToast() - const handleFormSubmit = async (e: React.FormEvent) => { - e.preventDefault() + const submitComment = async () => { + const payload = comment_id ? { content: commentState, commentId: comment_id } : { comment: commentState, lesson_id, parent_comment_id } + const action = comment_id ? updateComment : studentSubmitLessonComment - if (!commentState) { - return - } - - setIsLoading(true) try { - const response = await studentSubmitLessonComment({ - comment: commentState, - lesson_id, - parent_comment_id - }) + const response = await action(payload as any) if (response.status === 'success') { setComment('') @@ -42,12 +38,12 @@ export default function CommentEditor ({ variant: 'destructive' }) } + callback && callback() } catch (error) { - console.log(error) + console.error(error) toast({ title: 'Error', - description: - 'An error occurred while submitting comment. Please try again.', + description: 'An error occurred while submitting comment. Please try again.', variant: 'destructive' }) } finally { @@ -55,6 +51,17 @@ export default function CommentEditor ({ } } + const handleFormSubmit = async (e: React.FormEvent) => { + e.preventDefault() + + if (!commentState) { + return + } + + setIsLoading(true) + await submitComment() + } + return ( <>
Date: Sun, 16 Jun 2024 20:01:59 -0400 Subject: [PATCH 08/14] new types --- utils/supabase/supabase.ts | 79 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) diff --git a/utils/supabase/supabase.ts b/utils/supabase/supabase.ts index 4c9c3595..d258a45c 100644 --- a/utils/supabase/supabase.ts +++ b/utils/supabase/supabase.ts @@ -70,6 +70,84 @@ export type Database = { }, ] } + comment_flags: { + Row: { + comment_id: number + created_at: string | null + id: number + reason: string + user_id: string + } + Insert: { + comment_id: number + created_at?: string | null + id?: never + reason: string + user_id: string + } + Update: { + comment_id?: number + created_at?: string | null + id?: never + reason?: string + user_id?: string + } + Relationships: [ + { + foreignKeyName: "comment_flags_comment_id_fkey" + columns: ["comment_id"] + isOneToOne: false + referencedRelation: "lesson_comments" + referencedColumns: ["id"] + }, + { + foreignKeyName: "comment_flags_user_id_fkey" + columns: ["user_id"] + isOneToOne: false + referencedRelation: "profiles" + referencedColumns: ["id"] + }, + ] + } + comment_reactions: { + Row: { + comment_id: number + created_at: string | null + id: number + reaction_type: Database["public"]["Enums"]["reactions"] + user_id: string + } + Insert: { + comment_id: number + created_at?: string | null + id?: never + reaction_type?: Database["public"]["Enums"]["reactions"] + user_id: string + } + Update: { + comment_id?: number + created_at?: string | null + id?: never + reaction_type?: Database["public"]["Enums"]["reactions"] + user_id?: string + } + Relationships: [ + { + foreignKeyName: "comment_reactions_comment_id_fkey" + columns: ["comment_id"] + isOneToOne: false + referencedRelation: "lesson_comments" + referencedColumns: ["id"] + }, + { + foreignKeyName: "comment_reactions_user_id_fkey" + columns: ["user_id"] + isOneToOne: false + referencedRelation: "profiles" + referencedColumns: ["id"] + }, + ] + } course_categories: { Row: { created_at: string | null @@ -1432,6 +1510,7 @@ export type Database = { app_role: "admin" | "moderator" | "teacher" | "student" currency_type: "usd" | "eur" enrollement_status: "active" | "disabled" + reactions: "like" | "dislike" | "boring" | "funny" review_status: "approved" | "pending" | "failed" status: "published" | "draft" | "archived" subscription_status: "active" | "canceled" | "expired" | "renewed" From ddfda322581ea50ca27565dd67da3bd416662792 Mon Sep 17 00:00:00 2001 From: guillermoscript Date: Sun, 16 Jun 2024 20:04:46 -0400 Subject: [PATCH 09/14] lint change --- components/ui/popover.tsx | 40 +++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/components/ui/popover.tsx b/components/ui/popover.tsx index 2bd5a03d..8ff4cc99 100644 --- a/components/ui/popover.tsx +++ b/components/ui/popover.tsx @@ -1,31 +1,31 @@ -"use client" +'use client' -import * as React from "react" -import * as PopoverPrimitive from "@radix-ui/react-popover" +import * as PopoverPrimitive from '@radix-ui/react-popover' +import * as React from 'react' -import { cn } from "@/utils" +import { cn } from '@/utils' const Popover = PopoverPrimitive.Root const PopoverTrigger = PopoverPrimitive.Trigger const PopoverContent = React.forwardRef< - React.ElementRef, - React.ComponentPropsWithoutRef ->(({ className, align = "center", sideOffset = 4, ...props }, ref) => ( - - - +React.ElementRef, +React.ComponentPropsWithoutRef +>(({ className, align = 'center', sideOffset = 4, ...props }, ref) => ( + + + )) PopoverContent.displayName = PopoverPrimitive.Content.displayName -export { Popover, PopoverTrigger, PopoverContent } +export { Popover, PopoverContent, PopoverTrigger } From 28d1f2e3f2ee7f7d226e3641c7fe574809d129fd Mon Sep 17 00:00:00 2001 From: guillermoscript Date: Sun, 16 Jun 2024 20:49:23 -0400 Subject: [PATCH 10/14] model update --- app/api/chat/route.ts | 2 +- app/api/lessons/chat/student/route.ts | 2 +- app/api/lessons/chat/teacher/route.ts | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/api/chat/route.ts b/app/api/chat/route.ts index 19a51d28..2eb81fa0 100644 --- a/app/api/chat/route.ts +++ b/app/api/chat/route.ts @@ -5,7 +5,7 @@ export async function POST (req: Request) { const { messages } = await req.json() const result = await streamText({ - model: google('models/gemini-1.5-flash-latest'), + model: google('models/gemini-1.5-pro-latest'), messages, temperature: 0 }) diff --git a/app/api/lessons/chat/student/route.ts b/app/api/lessons/chat/student/route.ts index f4fbcb7c..bfcf7f54 100644 --- a/app/api/lessons/chat/student/route.ts +++ b/app/api/lessons/chat/student/route.ts @@ -18,7 +18,7 @@ export async function POST (req: Request) { const supabase = createClient() const result = await streamText({ - model: google('models/gemini-1.5-flash-latest'), + model: google('models/gemini-1.5-pro-latest'), onFinish: async (event) => { const userData = await supabase.auth.getUser() if (userData.error) { diff --git a/app/api/lessons/chat/teacher/route.ts b/app/api/lessons/chat/teacher/route.ts index 9879ab16..149fb472 100644 --- a/app/api/lessons/chat/teacher/route.ts +++ b/app/api/lessons/chat/teacher/route.ts @@ -15,7 +15,7 @@ export async function POST (req: Request) { } = await req.json() const result = await streamText({ - model: google('models/gemini-1.5-flash-latest'), + model: google('models/gemini-1.5-pro-latest'), messages: convertToCoreMessages(messages), tools: { // server-side tool with execute function: From 52fd499931c018cecbbf1aaa487bdb22aee0210d Mon Sep 17 00:00:00 2001 From: guillermoscript Date: Sun, 16 Jun 2024 20:49:34 -0400 Subject: [PATCH 11/14] refactor: Update CreateCourse component with improved UI and functionality This commit updates the CreateCourse component in the components/dashboards/teacher/course/CreateCourse.tsx file. The changes include refactoring the component to improve its UI and functionality. It removes unused imports, simplifies the code structure, and updates the validation schema for the form fields. These updates enhance the user experience by improving the performance, usability, and reliability of the CreateCourse feature. --- .../teacher/course/CreateCourse.tsx | 88 +++++++------------ 1 file changed, 34 insertions(+), 54 deletions(-) diff --git a/components/dashboards/teacher/course/CreateCourse.tsx b/components/dashboards/teacher/course/CreateCourse.tsx index 7287c0fe..d2b9d8b5 100644 --- a/components/dashboards/teacher/course/CreateCourse.tsx +++ b/components/dashboards/teacher/course/CreateCourse.tsx @@ -21,7 +21,7 @@ const courseSchema = yup.object().shape({ title: yup.string().required(), description: yup.string().required(), status: yup.string().required().oneOf(['draft', 'published', 'archived']), - product_id: yup.number().optional(), + product_id: yup.optional(), thumbnail: yup.string().optional(), tags: yup.string().optional(), category_id: yup.number().optional() @@ -50,11 +50,9 @@ export default function CreateCourse () { const getItems = async (table: string, callback: (data: any) => void) => { try { setLoading(true) - const { data, error, status } = await supabase - .from(table) - .select('*') + const { data, error, status } = await supabase.from(table).select('*') - if ((error != null) && status !== 406) { + if (error != null && status !== 406) { console.log(error) throw error } @@ -79,10 +77,7 @@ export default function CreateCourse () { <>

Create a new course

- +
- +
- {loading - ? ( - <> - - - - - ) - : ( - <> - ) => ({ - value: product.product_id.toString(), - label: product.name - }) - )} - name="product_id" - displayName="Product ID" - /> - - )} + {loading ? ( + <> + + + + ) : ( + <> + ) => ({ + value: product.product_id.toString(), + label: product.name + }))} + name="product_id" + displayName="Product ID" + /> + + )} From 0422437e7edc039fd691c22ac53fc703c07cb539 Mon Sep 17 00:00:00 2001 From: guillermoscript Date: Sun, 16 Jun 2024 21:02:39 -0400 Subject: [PATCH 12/14] update type --- utils/supabase/supabase.ts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/utils/supabase/supabase.ts b/utils/supabase/supabase.ts index d258a45c..8877a83d 100644 --- a/utils/supabase/supabase.ts +++ b/utils/supabase/supabase.ts @@ -185,7 +185,7 @@ export type Database = { deleted_at: string | null description: string | null published_at: string | null - status: string + status: Database["public"]["Enums"]["status"] tags: string[] | null thumbnail_url: string | null title: string @@ -200,7 +200,7 @@ export type Database = { deleted_at?: string | null description?: string | null published_at?: string | null - status?: string + status?: Database["public"]["Enums"]["status"] tags?: string[] | null thumbnail_url?: string | null title: string @@ -215,7 +215,7 @@ export type Database = { deleted_at?: string | null description?: string | null published_at?: string | null - status?: string + status?: Database["public"]["Enums"]["status"] tags?: string[] | null thumbnail_url?: string | null title?: string From 8300e49c9364d1b2c1dab5b8115ef11a8d4c356f Mon Sep 17 00:00:00 2001 From: guillermoscript Date: Sun, 16 Jun 2024 21:15:28 -0400 Subject: [PATCH 13/14] refactor: Update const.ts with new imports and reaction types This commit updates the const.ts file in the utils directory. It adds new imports for the Meh, Smile, ThumbsDown, and ThumbsUp icons from the lucide-react library. Additionally, it adds a new array of reaction types with their corresponding icons and colors. These changes enhance the functionality and visual appeal of the code by providing support for comment reactions and improving the user experience. --- utils/const.ts | 34 ++++++++++++++++++++++++---------- 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/utils/const.ts b/utils/const.ts index 264128a6..1821ddf2 100644 --- a/utils/const.ts +++ b/utils/const.ts @@ -1,14 +1,28 @@ +import { Meh, Smile, ThumbsDown, ThumbsUp } from 'lucide-react' + +import { Tables } from '@/utils/supabase/supabase' export const formClassNames = { - label: "text-xs font-medium text-neutral-600", - input: "disabled:opacity-50", - error: "pt-2 text-red-400", - container: "mb-4 flex flex-col gap-4", -}; + label: 'text-xs font-medium text-neutral-600', + input: 'disabled:opacity-50', + error: 'pt-2 text-red-400', + container: 'mb-4 flex flex-col gap-4' +} export const selectClassNames = { - container: "mb-4 flex flex-col gap-4", - label: "text-xs my-2 font-medium text-neutral-600", - input: "flex my-2 h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1", - error: "pt-2 text-red-400", -} \ No newline at end of file + container: 'mb-4 flex flex-col gap-4', + label: 'text-xs my-2 font-medium text-neutral-600', + input: 'flex my-2 h-10 w-full items-center justify-between rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1', + error: 'pt-2 text-red-400' +} + +export const reactionTypes: Array<{ + type: Tables<'comment_reactions'>['reaction_type'] + icon: any + color: string +}> = [ + { type: 'like', icon: ThumbsUp, color: 'text-blue-500' }, + { type: 'funny', icon: Smile, color: 'text-yellow-500' }, + { type: 'boring', icon: Meh, color: '' }, + { type: 'dislike', icon: ThumbsDown, color: 'text-red-500' } +] From 3e08b04293dbe15c320b9a9739aef713decce216 Mon Sep 17 00:00:00 2001 From: guillermoscript Date: Sun, 16 Jun 2024 21:15:33 -0400 Subject: [PATCH 14/14] refactor: Update CommentsCard component to remove unused imports and add support for comment reactions This commit updates the CommentsCard component in the components/dashboards/Common/comments/CommentsCard.tsx file. The changes include removing unused imports for the Meh, Smile, ThumbsDown, and ThumbsUp icons from the lucide-react library. Additionally, it adds support for comment reactions by importing the necessary constants from the utils/const.ts file. These updates improve the code by removing unnecessary dependencies and enhancing the functionality of the CommentsCard component. --- .../dashboards/Common/comments/CommentsCard.tsx | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/components/dashboards/Common/comments/CommentsCard.tsx b/components/dashboards/Common/comments/CommentsCard.tsx index 283df389..5e8d2f35 100644 --- a/components/dashboards/Common/comments/CommentsCard.tsx +++ b/components/dashboards/Common/comments/CommentsCard.tsx @@ -1,7 +1,7 @@ 'use client' import { User } from '@supabase/supabase-js' import dayjs from 'dayjs' -import { Edit3, Flag, Meh, Reply, Smile, ThumbsDown, ThumbsUp } from 'lucide-react' +import { Edit3, Flag, Reply } from 'lucide-react' import { useState } from 'react' import { addReactionToComment } from '@/actions/dashboard/studentActions' @@ -14,6 +14,7 @@ import ViewMarkdown from '@/components/ui/markdown/ViewMarkdown' import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover' import { Separator } from '@/components/ui/separator' import { useToast } from '@/components/ui/use-toast' +import { reactionTypes } from '@/utils/const' import { Tables } from '@/utils/supabase/supabase' const ReactionButton = ({ type, icon: Icon, count, onClick }) => ( @@ -56,17 +57,6 @@ const CommentCard = ({ const toggleReplies = () => setShowReplies(!showReplies) const toggleEdit = () => setIsEditing(!isEditing) - const reactionTypes: Array<{ - type: Tables<'comment_reactions'>['reaction_type'] - icon: any - color: string - }> = [ - { type: 'like', icon: ThumbsUp, color: 'text-blue-500' }, - { type: 'funny', icon: Smile, color: 'text-yellow-500' }, - { type: 'boring', icon: Meh, color: '' }, - { type: 'dislike', icon: ThumbsDown, color: 'text-red-500' } - ] - async function AddReaction (reaction: Tables<'comment_reactions'>['reaction_type']) { try { const response = await addReactionToComment({