Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
53 changes: 53 additions & 0 deletions app/(routes)/courses/[courseId]/_components/CourseChapters.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,12 @@ import {
AccordionTrigger,
} from "@/components/ui/accordion"
import { Button } from '@/components/ui/button'
import {
Tooltip,
TooltipContent,
TooltipProvider,
TooltipTrigger,
} from "@/components/ui/tooltip"


type Props = {
Expand All @@ -16,6 +22,38 @@ type Props = {
}

function CourseChapters({loading,courseDetail}:Props) {

const EnableExercise = (
chapterIndex: number,
exerciseIndex: number,
chapterExercisesLength: number
) => {
const completed = courseDetail?.completedExcercises;

// If nothing is completed, enable FIRST exercise ONLY
if (!completed || completed.length === 0) {
return chapterIndex === 0 && exerciseIndex === 0;
}

// last completed
const last = completed[completed.length - 1];

// Convert to global exercise number
const currentExerciseNumber =
chapterIndex * chapterExercisesLength + exerciseIndex + 1;

const lastCompletedNumber =
(last.chapterId - 1) * chapterExercisesLength + last.exerciseId;

return currentExerciseNumber === lastCompletedNumber + 2;
};

const isExerciseCompleted=(chapterId:number,exerciseId:number)=>{
const completeChapters = courseDetail?.completedExcercises;
const completeChapter = completeChapters?.find(item=>(item.chapterId==chapterId && item.exerciseId== exerciseId))
return completeChapter?true:false
}

return (
<div>
<div className='p-5 border-4 rounded-2xl'>
Expand All @@ -31,7 +69,22 @@ function CourseChapters({loading,courseDetail}:Props) {
<h2 className='text-3xl'>Exercise {index +1}</h2>
<h2>{exc.name}</h2>
</div>
{
isExerciseCompleted(chapter?.chapterId,index+1)&&
<Button variant={"pixel"} className='bg-green-600'>Completed</Button>}
{EnableExercise(index,index, chapter?.exercises.length)?
<Button variant={"pixel"}>{exc?.xp} xp</Button>

:<TooltipProvider>
<Tooltip>
<TooltipTrigger asChild>
<Button variant="pixelDisabled">***</Button>
</TooltipTrigger>
<TooltipContent>
<p className='text-lg font-game'>Please Enroll First!!</p>
</TooltipContent>
</Tooltip>
</TooltipProvider>}
</div>
))}
</div>
Expand Down
56 changes: 50 additions & 6 deletions app/(routes)/courses/[courseId]/_components/CourseStatus.tsx
Original file line number Diff line number Diff line change
@@ -1,22 +1,66 @@
import React from 'react'
import React, { useEffect, useState } from 'react'
import Image from 'next/image'
import { Progress } from '@/components/ui/progress'
function CourseStatus() {
import { Course } from '../../_components/CourseList'
import { Item } from '@radix-ui/react-navigation-menu'


type Props={
courseDetail:Course|undefined
}

function CourseStatus({courseDetail}:Props) {

const [counts,setCounts] = useState<{
totalExce: number,
totalXp: number,
}>()

useEffect(()=>{
courseDetail && GetCounts()
},[courseDetail])

const GetCounts=()=>{
let totalExercises = 0;
let totalXp = 0;
courseDetail?.chapters?.forEach((chapters)=>{
totalExercises = totalExercises+chapters?.exercises?.length
chapters?.exercises?.forEach(exc=>{
totalXp=totalXp+exc?.xp;
})
})

setCounts({
totalExce:totalExercises,
totalXp:totalXp
})
}

const updateProgress =(currentValue:number,totalvalue: number)=>{
if(currentValue&&totalvalue){

const perc = (currentValue*100)/totalvalue;
return perc

}return 0
}
return (
<div className='font-game p-4 border-4 rounded-2xl w-full'>
<h2 className='text-3xl'>Course Progress</h2>
<div className='flex items-center mt-4 gap-5 '>
<Image src={'/books.png'} alt='image' width={50} height={50}/>
<h2 className='flex justify-between text-2xl '>Exercises-
<span className='text-yellow-500'>1/72</span> </h2>
<Progress value={37} className='mt-2'/>
<span className='text-yellow-500'>1/{courseDetail?.completedExcercises?.length}/{counts?.totalExce}</span> </h2>
{/* @ts-ignore */}
<Progress value={updateProgress(courseDetail?.completedExcercises?.length??0,counts?.totalExce)} className='mt-2'/>
</div>

<div className='flex items-center mt-4 gap-5 '>
<Image src={'/star.png'} alt='image' width={50} height={50}/>
<h2 className='flex justify-between text-2xl '>XP Earned
<span className='text-yellow-500'>1/340</span> </h2>
<Progress value={37} className='mt-2'/>
<span className='text-yellow-500'>{courseDetail?.courseEnrolledInfo?.xpEarned}/{counts?.totalXp}</span> </h2>
{/* @ts-ignore */}
<Progress value={updateProgress(courseDetail?.courseEnrolledInfo?.xpEarned??0,counts?.totalXp)} className='mt-2'/>
</div>


Expand Down
4 changes: 2 additions & 2 deletions app/(routes)/courses/[courseId]/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import axios from 'axios'
import { Course } from '../_components/CourseList'
import CourseChapters from './_components/CourseChapters'
import CourseStatus from './_components/CourseStatus'
import UpgradeToPro from '../../dashboard/_components/Upgrade-To-Pro'
import UpgradeToPro from '../../dashboard/_components/UpgradeToPro'
import Header from '@/app/_components/Header'

function CourseDetails() {
Expand Down Expand Up @@ -53,7 +53,7 @@ function CourseDetails() {
</div>

<div>
<CourseStatus />
<CourseStatus courseDetail={courseDetail}/>
<UpgradeToPro />
</div>
</div>
Expand Down
10 changes: 9 additions & 1 deletion app/(routes)/courses/_components/CourseList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,17 @@ export type Course = {
tag: string,
chapters?:Chapter[],
userEnrolled?: boolean,
courseEnrolledInfo?: courseEnrolledInfo
courseEnrolledInfo?: courseEnrolledInfo,
completedExcercises?: completedExcercises[]
}

type completedExcercises={
chapterId: number,
courseId: number,
exerciseId: number
}


type courseEnrolledInfo={
xpEarned: number,
enrolledDate: any,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import Image from "next/image";
import { Input } from '@/components/ui/input';
import { Button } from '@/components/ui/button';

function InviteFrame() {
function InviteFriend() {
return (
<div className='flex flex-col items-center mt-8 p-4 border rounded-xl'>
<Image src={'/invitation.gif'} alt='mail' width={80} height={80}/>
Expand All @@ -17,4 +17,4 @@ function InviteFrame() {
)
}

export default InviteFrame
export default InviteFriend
1 change: 1 addition & 0 deletions app/(routes)/dashboard/_components/UserStates.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { useUser } from '@clerk/nextjs';
function UserStates() {
const { user } = useUser()


return (
<div className='p-5 border-4 rounded-2xl'>

Expand Down
4 changes: 2 additions & 2 deletions app/(routes)/dashboard/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import React from 'react'
import WelcomeBanner from './_components/WelcomeBanner'
import EnrolledCourses from './_components/EnrolledCourses'
import ExploreMore from './_components/ExploreMore'
import InviteFrame from './_components/InviteFrame'
import InviteFrame from './_components/InviteFriend'
import UserStates from './_components/UserStates'
import UpgradeToPro from './_components/Upgrade-To-Pro'
import UpgradeToPro from './_components/UpgradeToPro'
import Header from '@/app/_components/Header'

function Dashboard() {
Expand Down
12 changes: 9 additions & 3 deletions app/api/course/route.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {db} from '@/config/db';
import { CourseChapterTable, CourseTable, EnrolledCourseTable } from '@/config/schema';
import { CompletedExerciseTable, CourseChapterTable, CourseTable, EnrolledCourseTable } from '@/config/schema';
import { currentUser } from '@clerk/nextjs/server';
import { and, asc, eq } from 'drizzle-orm';
import { and, asc, desc, eq } from 'drizzle-orm';
import { NextRequest, NextResponse } from 'next/server';


Expand All @@ -25,11 +25,17 @@ if (courseId){
.where(and(eq(EnrolledCourseTable?.courseId,courseId),eq(EnrolledCourseTable.userId,user?.primaryEmailAddress?.emailAddress) ))

const isEnrolledCourse = enrolledCourse?.length>0?true:false
//@ts-ignore
const completedExercises = await db.select().from(CompletedExerciseTable).where(and(eq(CompletedExerciseTable.courseId,courseId),eq(CompletedExerciseTable.userId,user?.primaryEmailAddress?.emailAddress)))
.orderBy(desc(CompletedExerciseTable?.courseId))


return NextResponse.json({
...result[0],
chapters:chapterResult,
userEnrolled: isEnrolledCourse,
courseEnrolledInfo: enrolledCourse[0]
courseEnrolledInfo: enrolledCourse[0],
completedExercises: completedExercises
})
}
else{
Expand Down
5 changes: 5 additions & 0 deletions components/ui/button.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ const buttonVariants = cva(
link: "text-primary underline-offset-4 hover:underline",
pixel:
"bg-yellow-400 text-black border-2 border-black shadow-[0px_0px_0_0_#c69405,2px_2px_0_0_#c69405] active:shadow-[0_0_0_0_#000] hover:brightness-105",

pixelDisabled:
"bg-gray-400 text-gray-700 border-2 border-gray-500 shadow-[0px_0px_0_0_#9ca3af,2px_2px_0_0_#9ca3af] cursor-not-allowed hover:brightness-100 active:shadow-[0_0_0_0_#000]"




},
Expand Down
3 changes: 0 additions & 3 deletions config/db.js

This file was deleted.

2 changes: 1 addition & 1 deletion config/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,4 +43,4 @@ export const CompletedExerciseTable = pgTable('completedExercise',{
chapterId: integer(),
exerciseId: integer(),
userId: varchar()
})
})
2 changes: 1 addition & 1 deletion drizzle.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import 'dotenv/config';
import { defineConfig } from 'drizzle-kit';

export default defineConfig({
schema: './config/schema.tsx',
schema: './config/schema.ts',
dialect: 'postgresql',
dbCredentials: {
url: process.env.DATABASE_URL!,
Expand Down