Location: src/types/index.ts
Comprehensive TypeScript types matching backend models:
- User - firstName, lastName, email, accountType, image, courses[], cart, wishlist
- Course - courseName, instructor, price, thumbnail, courseContent[], studentsEnrolled[], averageRating, status
- Section - sectionName, subSection[]
- SubSection - title, timeDuration, description, videoUrl
- Quiz - courseId, title, questions[], totalPoints, passingScore, duration
- QuizQuestion - questionText, options[], correctAnswer, points
- Discussion - courseId, userId, content, parentId (for replies), isInstructorReply, isPinned, likes[]
- Cart - userId, courses[] (populated Course objects), totalAmount
- Wishlist - userId, courses[] (populated Course objects)
- Payment - userId, courses[], amount, stripeSessionId, couponCode, status
- RatingAndReview - user, rating (1-5), review, course
- CourseProgress - userId, courseId, completedVideos[], completedQuizzes[], progressPercentage
- Certificate - userId, courseId, certificateUrl, issuedAt
-
CourseCard.tsx ✅
- Now accepts
course: Courseprop (full course object from backend) - Uses
course.averageRatinginstead ofrating - Uses
course.studentsEnrolled.lengthfor student count - Updated route to
/course/{courseId} - Fixed currency to ₹ (Indian Rupees)
- Now accepts
-
CartItemCard.tsx ✅
- Updated to work with populated Course objects in cart
- Removed quantity controls (backend cart stores courses, not quantities)
- Single price display (no unit price × quantity)
-
CourseReview.tsx ✅
- Already uses RatingAndReview type structure
-
Curriculum.tsx ✅
- Already uses Section/SubSection types correctly
-
CartSummary.tsx
- Already structured correctly for backend integration
- Works with total amount from backend Cart model
- Coupon fields match Payment model
-
QuizQuestion.tsx
- Need to add
pointsdisplay (from QuizQuestion.points in backend) - Uses correct Quiz types
- Need to add
-
QuizResult.tsx
- Update to use QuizResult type from backend
- Display totalPoints and final score correctly
-
DiscussionThread.tsx
- Update to use Discussion type
- Handle parentId for nested replies properly
- Display isInstructorReply and isPinned badges
- Use likes[] array instead of upvotes
-
WishlistItem.tsx
- Update to accept
course: Courseprop - Uses course.averageRating and course.studentsEnrolled correctly
- Update to accept
// From Backend API
const course: Course = {
_id: '123',
courseName: 'React Advanced',
instructor: { _id: '1', firstName: 'John', lastName: 'Doe', ... },
price: 4999,
thumbnail: 'url',
averageRating: 4.5,
studentsEnrolled: ['user1', 'user2', 'user3'], // IDs or User objects
courseContent: [{ sectionName: '...', subSection: [...] }],
status: 'Published',
tag: ['React', 'JavaScript'],
...
}
// Component Usage
<CourseCard
course={course}
onAddToCart={(id) => addToCart(id)}
isWishlisted={true}
/>// From Backend API
const cart: Cart = {
_id: '123',
userId: 'user123',
courses: [ // Populated Course objects from backend
{ _id: '1', courseName: 'React', price: 4999, ... },
{ _id: '2', courseName: 'Node', price: 3999, ... }
],
totalAmount: 8998
}
// Component usage
{cart.courses.map(course => (
<CartItemCard
key={course._id}
course={course}
onRemove={(id) => removeFromCart(id)}
/>
))}// From Backend
const quiz: Quiz = {
_id: 'quiz1',
title: 'React Basics',
questions: [
{
_id: 'q1',
questionText: 'What is JSX?',
options: ['...', '...', '...', '...'],
correctAnswer: 0, // Index of correct option
points: 5 // Points for this question
}
],
totalPoints: 50,
passingScore: 30,
duration: 30
}
// Component usage
<QuizQuestion
question={quiz.questions[0]}
questionNumber={1}
totalQuestions={quiz.questions.length}
onAnswer={handleAnswer}
/>// From Backend
const discussion: Discussion = {
_id: 'disc1',
courseId: 'course1',
userId: { firstName: 'John', lastName: 'Doe', ... },
content: 'How to use hooks?',
isInstructorReply: false,
isPinned: true,
likes: ['user1', 'user2'],
parentId: null, // Null for original questions
createdAt: '2024-03-04T...'
}
// Children replies come from separate queries where parentId = 'disc1'
const replies: Discussion[] = [
{
_id: 'disc2',
parentId: 'disc1',
userId: { ... },
content: 'Hooks are great!',
isInstructorReply: true, // Instructor reply badge
...
}
]
// Component usage
<DiscussionThread
discussion={discussion}
replies={replies}
currentUserId={userId}
onReply={handleReply}
onLike={handleLike}
/>import { Course, Cart, Quiz, Discussion, Payment } from '../../types';state.auth.user- User typestate.cart.items- Cart type (or course[] if simplified)state.profile.courses- Course[] typestate.course.currentCourse- Course type
// Expected backend API response format
interface ApiResponse<T> {
success: boolean;
message: string;
data?: T;
error?: string;
}
// Usage
const getCourse = async (courseId: string) => {
const response = await apiConnector('GET', `/courses/${courseId}`);
// response.data is Course type
}36 Components Created + Comprehensive Types File
- All components now ready for actual backend API integration
- Type-safe development with full TypeScript support
- Backend models matched exactly in frontend types
- Ready for Redux slices and API service calls