An implementation of a full-stack web application. The application is a platform to manage an online learning platform that serves 4 different types of users : Individual/Corporate Trainees , Instructors and Admins. It was built using the MERN stack.
- The project is currently in development.
- The admin need some improvements
- Course Page and API' needs Pagagination.
- The Unit tests needs modifications.
- A CI/CD pipeline needs to be migrated to Jenkins.
- A caching layer needs to be added to the application.
- A message broker needs to be added to the application to handle asynchronous tasks such as sending emails and notifications.
The code style is enforced using eslint and prettier. The code style is enforced using pre-commit hooks and pre-commit github action.
The pre-commit hook is managed by pre-commit. It is a versatile way of managing the pre-commit tool but it also permits you to run the script on arbitrary files without committing. The module will take charge of installing your required dependencies (such as code-style tools: prettier, eslint, etc.) and will run them on the files you want to commit.
Install pre-commit package by running
> pip install pre-commitOnce installed, run the following for a one-time setup
> pre-commit installAfterwards, the hook should run the next commit you will attempt!
- React
- Redux
- Node.js
- Express
- MongoDB
- Mongoose
- Jest
- Swagger
- Material-UI
- Stripe
- Typescript
- Git
- Github Actions
- NodeMailer
- Handlebars
- MongoDB Atlas
- Postman
- VSCode
- Pre-commit
- Mailtrap
The system serves different type of users (Admin, Instructor , Individual Trainee, Corporate Trainee)
As an Admin I can
- Add instructors and corporate trainees to the system
- View Reported problems and resolve them
- View access requests from Corporate Trainees and grant access
- View Refund Requests from Individual Trainees
As an Instructor I can
- Create and edit a draft Course
- Publish draft Course so trainees could enroll in
- Close a published course to prevent more trainees from enrolling in it
- View my settlements and update my profile
- Add a promotion for a specific period
As an Individual Trainee I can
- Search and filter Courses
- Pay for a course
- Report problems
- Watch a video and solve exercises from my courses
- See my progress
- Recieve a certificate by mail
- Request refund
- Rate a course and its instructor
As a Corporate Trainee I can
- Search and filter Courses
- Send access requests for specific course
- Watch a video and solve exercises from my courses
- See my progress
- Recieve a certificate by mail
- Rate a course and its instructor
As Guest I can
- Sign up as individual trainee
- Search and filter courses
Send Certificate Service
import { sendEmail } from "./sendMailService";
export const sendCertificateEmail = async (email: string, courseName: string, certificatePath: string) => {
const context = {
courseName: courseName,
email: email
};
const attachments = [
{
filename: "certificate.pdf",
path: certificatePath,
contentType: "application/pdf"
}
];
sendEmail(email, context, "certificateUponCompletion", "Linear Depression | Congrats π", attachments);
};Course Action Methods
courseSchema.methods.close = async function (this: ICourseModel) {
if (this.status !== CourseStatus.PUBLISHED) {
throw new Error("Invalid Transition, course must be published to be closed");
}
this.status = CourseStatus.CLOSED;
await this.save();
};
courseSchema.methods.publish = async function (this: ICourseModel) {
if (this.status !== CourseStatus.DRAFT) {
throw new Error("Invalid Transition, course must be draft to be published");
}
this.status = CourseStatus.PUBLISHED;
await this.save();
};
courseSchema.methods.reOpen = async function (this: ICourseModel) {
if (this.status !== CourseStatus.CLOSED) {
throw new Error("Invalid Transition, course must be closed to be re-opened");
}
this.status = CourseStatus.PUBLISHED;
await this.save();
};Setting Rate Limiters
const rateLimiter = (requestsPerMinute: number = 120) => {
return rateLimit({
windowMs: 60 * 1000, // 1 minute
max: requestsPerMinute, // Limit each IP to n requests per `window` per minute
message: { message: `Too many requests from this IP, please try again after a 60 second pause` },
handler: (req: Request, res: Response, next: NextFunction, options: any) => {
res.status(options.statusCode).send(options.message);
},
standardHeaders: true, // Return rate limit info in the `RateLimit-*` headers
legacyHeaders: false // Disable the `X-RateLimit-*` headers
});
};Caching Currency Rates
// run every day at 00:00
const getCurrencyRatesTask = new CronJob("0 0 0 * * *", async () => {
console.log("Cache currency rates");
const data = fs.readFileSync("src/media/country-currency.json", "utf8");
const currencies = JSON.parse(data);
// convert to distinct currency codes
const currencyCodes = currencies.map((currency: any) => currency.Code) as string[];
const distinctCurrencyCodes = [...new Set(currencyCodes)] as string[];
const currencyRates = {} as CurrencyRate;
for (const currencyCode of distinctCurrencyCodes) {
try {
const rate = await getCurrencyRate(currencyCode, "USD");
console.log(`Currency code: ${currencyCode}, rate: ${rate}`);
currencyRates[currencyCode] = rate;
} catch (error) {
console.log(error);
}
}
fs.writeFileSync("src/media/currency-rates.json", JSON.stringify(currencyRates));
});Promotion Validator
export const PromotionValidator = {
validate: async (promotion: IPromotionModel) => {
if (!isValidStartDate(promotion)) {
throw new Error("Promotion start date is invalid");
}
if (!isValidEndDate(promotion)) {
throw new Error("Promotion end date is invalid");
}
if (!(await onlyIncludesPaidCourses(promotion))) {
throw new Error("Promotion can only include paid courses");
}
if (!(await noConflictWithAdminPromotion(promotion))) {
throw new Error("Promotion conflicts with Admin promotion");
}
return true;
}
};Course NavBar
<HorizontalContainer>
<NavItem>
<Image src={logo} alt="logo" onClick={() => navigate("/")} />
</NavItem>
<CustomDivider orientation="vertical" flexItem />
<NavItem>
<ArrowBackIcon sx={{ marginRight: "10px" }} />
<Link className="navbar-brand" to={`/courses/${course.data?._id}`}>
{course.data?.title}
</Link>
</NavItem>
{enrollment.data && (
<ProgressContainer>
<NavItem>{enrollment.data && <CircularProgressBar value={enrollment.data?.progress} />}</NavItem>
{enrollment.data?.progress === 100 ? (
<Button
sx={{
color: "white",
textTransform: "none"
}}
onClick={handleDownloadCertificate}
>
Get Certificate
</Button>
) : (
"Your Progress"
)}
</ProgressContainer>
)}
</HorizontalContainer>Question Card
<ErrorCourseCard>
<div key={index}>
<HorizontalContainer>
<QuestionTitle>{question.question}</QuestionTitle>
<QuestionAction>
<ModeEditIcon
onClick={() => {
handleOpenEditQuestion(index);
}}
sx={{
"&:hover": {
fontSize: "1.8rem"
},
margin: "5px"
}}
/>
<DeleteIcon
onClick={() => {
deleteQuestion(index);
}}
sx={{
color: "error.main",
"&:hover": {
fontSize: "1.8rem"
},
margin: "5px"
}}
/>
</QuestionAction>
</HorizontalContainer>
<GroupRadioButton
answer={question.answerIndex}
questionNumber={index}
choices={question.choices}
onChange={handleSetAnswer}
/>
</div>
</ErrorCourseCard>The testing is done using jest. To run the tests, run the following command
> cd server && npm run testClick Me!
.
βββ test_apis
βΒ Β βββ course
βΒ Β βΒ Β βββ course.test.ts
βΒ Β βββ course_ratings
βΒ Β βΒ Β βββ rating.test.ts
βΒ Β βββ example.test.ts
βΒ Β βββ instructor
βΒ Β βΒ Β βββ instructor.test.ts
βΒ Β βββ instructor_ratings
βΒ Β βΒ Β βββ instructor_ratings.test.ts
βΒ Β βββ trainee
βΒ Β βββ corporateTrainee.test.ts
βΒ Β βββ individualTrainee.test.ts
βββ test_models
βΒ Β βββ answer
βΒ Β βΒ Β βββ answer.test.ts
βΒ Β βΒ Β βββ factory.ts
βΒ Β βββ course
βΒ Β βΒ Β βββ course.test.ts
βΒ Β βΒ Β βββ factory.ts
βΒ Β βββ enrollment
βΒ Β βΒ Β βββ factory.ts
βΒ Β βββ exercise
βΒ Β βΒ Β βββ exercise.test.ts
βΒ Β βΒ Β βββ factory.ts
βΒ Β βββ instructor
βΒ Β βΒ Β βββ factory.ts
βΒ Β βΒ Β βββ instructor.test.ts
βΒ Β βββ lesson
βΒ Β βΒ Β βββ factory.ts
βΒ Β βΒ Β βββ lesson.test.ts
βΒ Β βββ rating
βΒ Β βΒ Β βββ factory.ts
βΒ Β βΒ Β βββ rating.test.ts
βΒ Β βββ trainee
βΒ Β βΒ Β βββ factory.ts
βΒ Β βΒ Β βββ trainee.test.ts
βΒ Β βββ userFactory.ts
βββ test_services
βΒ Β βββ CourseService.test.ts
βββ test_utils
βββ modelUtilities.test.ts
js-faker is used to generate data to test different models
There is tests done for the following models : Trainee , Course , Exercise, Rating, Lesson, Answer, Instructor
Also curl with used througout the process
Install my-project with npm
> git clone https://github.com/Advanced-Computer-Lab-2022/Linear-Depression
> cd Linear-Depression/
> cd server && npm i && cd -
> cd client && npm i -f && cd -To run backend
cd server && nodemon src/start.tsTo run frontend
cd client && npm startthe backend server and client will be running on the specified ports on your env files.
To run this project, you will need to add the following environment variables to your .env file
envs
REACT_APP_API_URL
REACT_APP_STRIPE_PUBLISHABLE_KEY
MONGO_URL
MONGO_TEST_URL
SERVER_PORT
FRONT_END_URL
JWT_ACCESS_TOKEN_SECRET
JWT_REFRESH_TOKEN_SECRET
EMAIL_HOST
EMAIL_PORT
EMAIL_USER
EMAIL_PASSWORD
PASSWORD_RESET_EMAIL_FROM
PASSWORD_RESET_EMAIL_SUBJECT
EMAIL_FROM
STRIPE_SECRET_KEY
STRIPE_WEBHOOK_SECRET
- Currency rates are cached using an cron job that runs at 12 AM.
- Asynchronous programming was used.
- Index was used on db to optimize search
Contributions are always welcome!
See contributing.md for ways to get started.
Please adhere to this project's code of conduct.
Click to expand!
## Project Structure
.
βββ client
βΒ Β βββ craco.config.js
βΒ Β βββ package.json
βΒ Β βββ package-lock.json
βΒ Β βββ public
βΒ Β βΒ Β βββ favicon.ico
βΒ Β βΒ Β βββ index.html
βΒ Β βΒ Β βββ manifest.json
βΒ Β βΒ Β βββ robots.txt
βΒ Β βββ README.md
βΒ Β βββ src
βΒ Β βΒ Β βββ api
βΒ Β βΒ Β βΒ Β βββ endpoints.ts
βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βββ report
βΒ Β βΒ Β βΒ Β βββ addReport.ts
βΒ Β βΒ Β βΒ Β βββ addThreadReply.ts
βΒ Β βΒ Β βΒ Β βββ getReport.ts
βΒ Β βΒ Β βΒ Β βββ getUserReports.ts
βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βββ App.tsx
βΒ Β βΒ Β βββ components
βΒ Β βΒ Β βΒ Β βββ AuthHandler.tsx
βΒ Β βΒ Β βΒ Β βββ Avatar.tsx
βΒ Β βΒ Β βΒ Β βββ CircularProgressBar.tsx
βΒ Β βΒ Β βΒ Β βββ Copyright.tsx
βΒ Β βΒ Β βΒ Β βββ course
βΒ Β βΒ Β βΒ Β βΒ Β βββ courseContent
βΒ Β βΒ Β βΒ Β βΒ Β βΒ Β βββ ContentAccordion.css
βΒ Β βΒ Β βΒ Β βΒ Β βΒ Β βββ ContentAccordion.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βΒ Β βββ ContentItem.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βββ CourseContent.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βββ courseHeader
βΒ Β βΒ Β βΒ Β βΒ Β βΒ Β βββ CourseActions.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βΒ Β βββ courseInfo
βΒ Β βΒ Β βΒ Β βΒ Β βΒ Β βΒ Β βββ BadgeRatedEnrolled.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βΒ Β βββ CourseInfo.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βββ CourseHeader.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βββ CourseReviews.tsx
βΒ Β βΒ Β βΒ Β βββ CourseNavbar.tsx
βΒ Β βΒ Β βΒ Β βββ CoursePrice.tsx
βΒ Β βΒ Β βΒ Β βββ coursesListWithFilters
βΒ Β βΒ Β βΒ Β βΒ Β βββ BrowseBy.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βββ coursesList
βΒ Β βΒ Β βΒ Β βΒ Β βΒ Β βββ CourseCard.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βββ CoursesList.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βββ filter
βΒ Β βΒ Β βΒ Β βΒ Β βΒ Β βββ PriceFilter.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βΒ Β βββ RatingFilter.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βΒ Β βββ SubjectsFilter.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βββ Filter.tsx
βΒ Β βΒ Β βΒ Β βββ CoursesListWithFilters.tsx
βΒ Β βΒ Β βΒ Β βββ exercise
βΒ Β βΒ Β βΒ Β βΒ Β βββ Header.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ QuestionCard.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ QuestionTitle.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ SolvedQuestion.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βββ SubmitButton.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ Title.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ TotalGrade.tsx
βΒ Β βΒ Β βΒ Β βββ FloatingButton.ts
βΒ Β βΒ Β βΒ Β βββ GroupRadioButton.tsx
βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βββ modals
βΒ Β βΒ Β βΒ Β βΒ Β βββ AddCourse.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βββ AddExercise.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βββ AddLesson.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βββ AddPromotion.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βββ AddQuestion.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βββ AddReview.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βββ EditCourse.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βββ EditLesson.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βββ EditProfile.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ ViewAndAcceptContract.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βββ ViewMySettlements.tsx
βΒ Β βΒ Β βΒ Β βββ navbar
βΒ Β βΒ Β βΒ Β βΒ Β βββ CountrySelect.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βββ Navbar.css
βΒ Β βΒ Β βΒ Β βββ Navbar.tsx
βΒ Β βΒ Β βΒ Β βββ OptionsButton.tsx
βΒ Β βΒ Β βΒ Β βββ report
βΒ Β βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ listing
βΒ Β βΒ Β βΒ Β βΒ Β βΒ Β βββ table
βΒ Β βΒ Β βΒ Β βΒ Β βΒ Β βΒ Β βββ BodyContainer.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βΒ Β βΒ Β βββ Header.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βΒ Β βΒ Β βββ Row.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βΒ Β βββ TableContainer.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βββ new
βΒ Β βΒ Β βΒ Β βΒ Β βΒ Β βββ Form.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βΒ Β βββ HorizontalCourseCard.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βββ PageContainter.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βββ PageHeader.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βββ thread
βΒ Β βΒ Β βΒ Β βΒ Β βββ Author.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βββ CardContainer.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βββ Card.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βββ Container.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βββ ReplyForm.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βββ SubjectDivider.tsx
βΒ Β βΒ Β βΒ Β βββ ReviewItem.tsx
βΒ Β βΒ Β βΒ Β βββ SimpleAccordion.tsx
βΒ Β βΒ Β βΒ Β βββ VideoPlayer.tsx
βΒ Β βΒ Β βββ config
βΒ Β βΒ Β βΒ Β βββ config.ts
βΒ Β βΒ Β βββ contexts
βΒ Β βΒ Β βΒ Β βββ AuthProvider.tsx
βΒ Β βΒ Β βΒ Β βββ CountryContext.ts
βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βββ ToastProvider.tsx
βΒ Β βΒ Β βββ hooks
βΒ Β βΒ Β βΒ Β βββ course
βΒ Β βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ useFetchAllCourses.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ useFetchCourseById.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ useFetchMyCourses.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ useFetchSubjects.ts
βΒ Β βΒ Β βΒ Β βββ enrollment
βΒ Β βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ useFetchMyEnrollment.ts
βΒ Β βΒ Β βΒ Β βββ exercise
βΒ Β βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ useFetchEvaluation.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ useFetchExerciseById.ts
βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βββ instructor
βΒ Β βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ useGetInstructorContractStatus.ts
βΒ Β βΒ Β βΒ Β βββ lesson
βΒ Β βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ useFetchLessonById.ts
βΒ Β βΒ Β βΒ Β βββ localization
βΒ Β βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ useGetLocalizationData.ts
βΒ Β βΒ Β βΒ Β βββ note
βΒ Β βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ useFetchMyNote.ts
βΒ Β βΒ Β βΒ Β βββ profile
βΒ Β βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ useFetchProfile.ts
βΒ Β βΒ Β βΒ Β βββ report
βΒ Β βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ useFetchReports.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ useFetchThread.ts
βΒ Β βΒ Β βΒ Β βββ request
βΒ Β βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ useFetchMyAccessRequest.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ useFetchMyRefundRequest.ts
βΒ Β βΒ Β βΒ Β βββ review
βΒ Β βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ useFetchCourseReviews.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ useFetchMyReviews.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ useFetchMyReviewSubmission.ts
βΒ Β βΒ Β βΒ Β βββ settlements
βΒ Β βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ useFetchMySettlements.ts
βΒ Β βΒ Β βΒ Β βββ useAuth.ts
βΒ Β βΒ Β βΒ Β βββ useToast.ts
βΒ Β βΒ Β βββ index.css
βΒ Β βΒ Β βββ index.tsx
βΒ Β βΒ Β βββ media
βΒ Β βΒ Β βΒ Β βββ country-currency.json
βΒ Β βΒ Β βββ pages
βΒ Β βΒ Β βΒ Β βββ auth
βΒ Β βΒ Β βΒ Β βΒ Β βββ ChangePassword.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βββ ForgotPassword.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βββ Login.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βββ PasswordReset.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βββ Register.tsx
βΒ Β βΒ Β βΒ Β βββ CorporateTraineeProfile.tsx
βΒ Β βΒ Β βΒ Β βββ Course.tsx
βΒ Β βΒ Β βΒ Β βββ CreateExercise.tsx
βΒ Β βΒ Β βΒ Β βββ Exercise.tsx
βΒ Β βΒ Β βΒ Β βββ home
βΒ Β βΒ Β βΒ Β βΒ Β βββ AllCourses.tsx
βΒ Β βΒ Β βΒ Β βββ Home.tsx
βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βββ IndividualTraineeProfile.tsx
βΒ Β βΒ Β βΒ Β βββ InstructorCourse.tsx
βΒ Β βΒ Β βΒ Β βββ InstructorExercise.tsx
βΒ Β βΒ Β βΒ Β βββ instructorProfile
βΒ Β βΒ Β βΒ Β βΒ Β βββ MyReviews.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βββ ViewProfile.tsx
βΒ Β βΒ Β βΒ Β βββ InstructorProfile.tsx
βΒ Β βΒ Β βΒ Β βββ lesson
βΒ Β βΒ Β βΒ Β βΒ Β βββ Note.tsx
βΒ Β βΒ Β βΒ Β βββ Lesson.tsx
βΒ Β βΒ Β βΒ Β βββ MyCourses.tsx
βΒ Β βΒ Β βΒ Β βββ payment
βΒ Β βΒ Β βΒ Β βΒ Β βββ Cancelled.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ Success.tsx
βΒ Β βΒ Β βΒ Β βββ PrivacyPolicy.tsx
βΒ Β βΒ Β βΒ Β βββ Profile.tsx
βΒ Β βΒ Β βΒ Β βββ report
βΒ Β βΒ Β βΒ Β βΒ Β βββ List.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βββ New.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βββ Thread.tsx
βΒ Β βΒ Β βΒ Β βββ TraineeExercise.tsx
βΒ Β βΒ Β βββ redux
βΒ Β βΒ Β βΒ Β βββ features
βΒ Β βΒ Β βΒ Β βΒ Β βββ course
βΒ Β βΒ Β βΒ Β βΒ Β βΒ Β βββ courseSlice.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ courseList
βΒ Β βΒ Β βΒ Β βΒ Β βΒ Β βββ coursesListSlice.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ enrollment
βΒ Β βΒ Β βΒ Β βΒ Β βΒ Β βββ enrollmentSlice.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ profile
βΒ Β βΒ Β βΒ Β βΒ Β βΒ Β βββ profileSlice.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ subjects
βΒ Β βΒ Β βΒ Β βΒ Β βββ subjectSlice.ts
βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βββ store.ts
βΒ Β βΒ Β βββ reportWebVitals.ts
βΒ Β βΒ Β βββ services
βΒ Β βΒ Β βΒ Β βββ auth
βΒ Β βΒ Β βΒ Β βΒ Β βββ changePassword.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ login.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ logout.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ performPasswordReset.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ refresh.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ register.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ sendForgotPasswordRequest.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ validatePasswordResetToken.ts
βΒ Β βΒ Β βΒ Β βββ course
βΒ Β βΒ Β βΒ Β βΒ Β βββ addCourse.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ addPromotion.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ editCourse.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ fetchAllCourses.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ fetchCourseById.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ fetchMyCourses.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ fetchSubjects.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βββ enrollment
βΒ Β βΒ Β βΒ Β βΒ Β βββ downloadCertificate.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ enrollmentServices.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ enrollOnCourse.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ fetchMyEnrollment.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ updateEnrollment.ts
βΒ Β βΒ Β βΒ Β βββ exercise
βΒ Β βΒ Β βΒ Β βΒ Β βββ addExercise.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ fetchEvaluation.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ fetchExerciseById.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ submitExercise.ts
βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βββ instructor
βΒ Β βΒ Β βΒ Β βΒ Β βββ acceptInstructorContract.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ getInstructorContractStatus.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βββ lesson
βΒ Β βΒ Β βΒ Β βΒ Β βββ addLesson.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ editLesson.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ fetchLessonById.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ videoServices.ts
βΒ Β βΒ Β βΒ Β βββ localization
βΒ Β βΒ Β βΒ Β βΒ Β βββ fetchCountryCode.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ getCurrency.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βββ note
βΒ Β βΒ Β βΒ Β βΒ Β βββ addNote.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ downloadPDF.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ editNote.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ fetchMyNote.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ saveAsPDF.ts
βΒ Β βΒ Β βΒ Β βββ payment
βΒ Β βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ payment.ts
βΒ Β βΒ Β βΒ Β βββ profile
βΒ Β βΒ Β βΒ Β βΒ Β βββ editProfile.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ fetchProfile.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βββ request
βΒ Β βΒ Β βΒ Β βΒ Β βββ cancelRefundRequest.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ fetchMyAccessRequest.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ fetchMyRefundRequest.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ sendAccessRequest.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ sendRefundRequest.ts
βΒ Β βΒ Β βΒ Β βββ review
βΒ Β βΒ Β βΒ Β βΒ Β βββ addCourseReview.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ addInstructorReview.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ fetchCourseReviews.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ fetchMyReviewForCourse.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ fetchMyReviewForInstructor.tsx
βΒ Β βΒ Β βΒ Β βΒ Β βββ fetchMyReviews.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ updateCourseReview.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ updateInstructorReview.ts
βΒ Β βΒ Β βΒ Β βββ settlements
βΒ Β βΒ Β βΒ Β βββ fetchMySettlements.ts
βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βββ types
βΒ Β βΒ Β βΒ Β βββ AccessRequest.ts
βΒ Β βΒ Β βΒ Β βββ auth
βΒ Β βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ login.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ register.ts
βΒ Β βΒ Β βΒ Β βββ Country.ts
βΒ Β βΒ Β βΒ Β βββ Course.ts
βΒ Β βΒ Β βΒ Β βββ Enrollment.ts
βΒ Β βΒ Β βΒ Β βββ enums
βΒ Β βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ ReportStatus.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ ReportType.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ UserType.ts
βΒ Β βΒ Β βΒ Β βββ Evaluation.ts
βΒ Β βΒ Β βΒ Β βββ Exercise.ts
βΒ Β βΒ Β βΒ Β βββ FormProps.ts
βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βββ Instructor.ts
βΒ Β βΒ Β βΒ Β βββ Lesson.ts
βΒ Β βΒ Β βΒ Β βββ Note.ts
βΒ Β βΒ Β βΒ Β βββ Profile.ts
βΒ Β βΒ Β βΒ Β βββ Promotion.ts
βΒ Β βΒ Β βΒ Β βββ Question.ts
βΒ Β βΒ Β βΒ Β βββ RefundRequest.ts
βΒ Β βΒ Β βΒ Β βββ report
βΒ Β βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ ReportFormProps.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ ReportThread.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ Report.ts
βΒ Β βΒ Β βΒ Β βββ ReviewSubmission.ts
βΒ Β βΒ Β βΒ Β βββ Review.ts
βΒ Β βΒ Β βΒ Β βββ User.ts
βΒ Β βΒ Β βββ utils
βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βββ validateFormData.ts
βΒ Β βββ tsconfig.json
βΒ Β βββ tsconfig.paths.json
βββ contributing.md
βββ docs
βΒ Β βββ AdminDashboard.png
βΒ Β βββ APIDocs.png
βββ LICENSE
βββ README.md
βββ server
βββ babel.config.js
βββ jest.config.ts
βββ package.json
βββ package-lock.json
βββ public < -- public static files (images, fonts, etc.)
βΒ Β βββ admin
βΒ Β βΒ Β βββ css
βΒ Β βΒ Β βββ dashboard.css
βΒ Β βββ assets
βΒ Β βΒ Β βββ qr.png
βΒ Β βΒ Β βββ winners.png
βΒ Β βββ certificates
βΒ Β βΒ Β βββ 63a5dd8a26d81baf0958bb2e.pdf
βΒ Β βΒ Β βββ 63a6000d6828d41508671a8d.pdf
βΒ Β βΒ Β βββ 63a6050cd7ed49254b880181.pdf
βΒ Β βββ fonts
βΒ Β βΒ Β βββ NotoSansJP-Bold.otf
βΒ Β βΒ Β βββ NotoSansJP-Light.otf
βΒ Β βΒ Β βββ NotoSansJP-Regular.otf
βΒ Β βββ notes
βΒ Β βββ 63a225e117897bfd964a8417.pdf
βΒ Β βββ 63a89405c0fa640e7e80b26f.pdf
βββ src
βΒ Β βββ admin
βΒ Β βΒ Β βββ components
βΒ Β βΒ Β βΒ Β βββ AddPromotion.tsx
βΒ Β βΒ Β βΒ Β βββ dashboard.tsx
βΒ Β βΒ Β βββ config.ts
βΒ Β βΒ Β βββ hooks
βΒ Β βΒ Β βΒ Β βββ hashPasswordInPayload.ts
βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βββ locale
βΒ Β βΒ Β βΒ Β βββ en
βΒ Β βΒ Β βΒ Β βββ index.ts
βΒ Β βΒ Β βΒ Β βββ report.json
βΒ Β βΒ Β βββ resources
βΒ Β βΒ Β βββ AccessRequest.ts
βΒ Β βΒ Β βββ Admin.ts
βΒ Β βΒ Β βββ CorporateTrainee.ts
βΒ Β βΒ Β βββ Course.ts
βΒ Β βΒ Β βββ IndividualTrainee.ts
βΒ Β βΒ Β βββ Instructor.ts
βΒ Β βΒ Β βββ RefundRequest.ts
βΒ Β βΒ Β βββ Report.ts
βΒ Β βΒ Β βββ User.ts
βΒ Β βββ config
βΒ Β βΒ Β βββ config.ts
βΒ Β βββ controllers <--- API Controllers
βΒ Β βΒ Β βββ AccessRequest.ts
βΒ Β βΒ Β βββ Auth.ts
βΒ Β βΒ Β βββ CorporateTrainee.ts
βΒ Β βΒ Β βββ CourseRating.ts
βΒ Β βΒ Β βββ Course.ts
βΒ Β βΒ Β βββ Currency.ts
βΒ Β βΒ Β βββ Enrollment.ts
βΒ Β βΒ Β βββ Exercise.ts
βΒ Β βΒ Β βββ IndividualTrainee.ts
βΒ Β βΒ Β βββ InstructorRating.ts
βΒ Β βΒ Β βββ Instructor.ts
βΒ Β βΒ Β βββ Lesson.ts
βΒ Β βΒ Β βββ Note.ts
βΒ Β βΒ Β βββ PasswordResetToken.ts
βΒ Β βΒ Β βββ Payment.ts
βΒ Β βΒ Β βββ Profile.ts
βΒ Β βΒ Β βββ Promotion.ts
βΒ Β βΒ Β βββ RefundRequest.ts
βΒ Β βΒ Β βββ Report.ts
βΒ Β βΒ Β βββ Settlement.ts
βΒ Β βΒ Β βββ UserType.ts
βΒ Β βββ enums
βΒ Β βΒ Β βββ UserTypes.ts
βΒ Β βββ media
βΒ Β βΒ Β βββ country-currency.json
βΒ Β βΒ Β βββ currency-rates.json
βΒ Β βββ middleware <----------------- Middlewares are here
βΒ Β βΒ Β βββ logger.ts
βΒ Β βΒ Β βββ permissions <----------------- Middlewares Permissions are here
βΒ Β βΒ Β βΒ Β βββ isAuthenticated.ts
βΒ Β βΒ Β βΒ Β βββ isAuthorized.ts
βΒ Β βΒ Β βΒ Β βββ isCourseOwner.ts
βΒ Β βΒ Β βΒ Β βββ isEnrolled.ts
βΒ Β βΒ Β βΒ Β βββ isOwnerOrEnrolled.ts
βΒ Β βΒ Β βΒ Β βββ isRatingOwner.ts
βΒ Β βΒ Β βββ rateLimiter.ts
βΒ Β βββ models <----------------- Models are here
βΒ Β βΒ Β βββ AccessRequest.ts
βΒ Β βΒ Β βββ Admin.ts
βΒ Β βΒ Β βββ Answer.ts
βΒ Β βΒ Β βββ CorporateTrainee.ts
βΒ Β βΒ Β βββ Course.ts
βΒ Β βΒ Β βββ Enrollment.ts
βΒ Β βΒ Β βββ Exercise.ts
βΒ Β βΒ Β βββ IndividualTrainee.ts
βΒ Β βΒ Β βββ Instructor.ts
βΒ Β βΒ Β βββ Lesson.ts
βΒ Β βΒ Β βββ Note.ts
βΒ Β βΒ Β βββ PasswordResetToken.ts
βΒ Β βΒ Β βββ Promotion.ts
βΒ Β βΒ Β βββ Rating.ts
βΒ Β βΒ Β βββ RefundRequest.ts
βΒ Β βΒ Β βββ ReportThread.ts
βΒ Β βΒ Β βββ Report.ts
βΒ Β βΒ Β βββ Settlement.ts
βΒ Β βΒ Β βββ Trainee.ts
βΒ Β βΒ Β βββ User.ts
βΒ Β βββ routes <----------------- Routes are here
βΒ Β βΒ Β βββ Auth.ts
βΒ Β βΒ Β βββ CorporateTrainee.ts
βΒ Β βΒ Β βββ Course.ts
βΒ Β βΒ Β βββ Currency.ts
βΒ Β βΒ Β βββ Enrollment.ts
βΒ Β βΒ Β βββ IndividualTrainee.ts
βΒ Β βΒ Β βββ Instructor.ts
βΒ Β βΒ Β βββ Me.ts
βΒ Β βΒ Β βββ Payment.ts
βΒ Β βΒ Β βββ Promotion.ts
βΒ Β βΒ Β βββ UserType.ts
βΒ Β βββ server.ts
βΒ Β βββ services
βΒ Β βΒ Β βββ certificateService.ts
βΒ Β βΒ Β βββ CourseServices.ts
βΒ Β βΒ Β βββ emails <----------------- Email services are here
βΒ Β βΒ Β βΒ Β βββ accessRequests
βΒ Β βΒ Β βΒ Β βΒ Β βββ sendAccessRequestApprovalEmail.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ sendAccessRequestCreationEmail.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ sendAccessRequestRejectionEmail.ts
βΒ Β βΒ Β βΒ Β βββ refundRequests
βΒ Β βΒ Β βΒ Β βΒ Β βββ sendRefundRequestApprovalEmail.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ sendRefundRequestCreationEmail.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ sendRefundRequestRejectionEmail.ts
βΒ Β βΒ Β βΒ Β βββ sendCertificateEmail.ts
βΒ Β βΒ Β βΒ Β βββ sendEnrollmentEmail.ts
βΒ Β βΒ Β βΒ Β βββ sendMailService.ts
βΒ Β βΒ Β βΒ Β βββ sendPasswordResetEmail.ts
βΒ Β βΒ Β βΒ Β βββ templates <----------------- Email templates are here
βΒ Β βΒ Β βΒ Β βββ accessRequestApproval.html
βΒ Β βΒ Β βΒ Β βββ accessRequestCreation.html
βΒ Β βΒ Β βΒ Β βββ accessRequestRejection.html
βΒ Β βΒ Β βΒ Β βββ certificateUponCompletion.html
βΒ Β βΒ Β βΒ Β βββ instructorCredit.html
βΒ Β βΒ Β βΒ Β βββ partials
βΒ Β βΒ Β βΒ Β βΒ Β βββ footer.html
βΒ Β βΒ Β βΒ Β βΒ Β βββ header.html
βΒ Β βΒ Β βΒ Β βββ passwordResetEmail.html
βΒ Β βΒ Β βΒ Β βββ refundRequestApproval.html
βΒ Β βΒ Β βΒ Β βββ refundRequestCreation.html
βΒ Β βΒ Β βΒ Β βββ refundRequestRejection.html
βΒ Β βΒ Β βββ EnrollmentCreateServices.ts
βΒ Β βΒ Β βββ PasswordResetTokenServices.ts
βΒ Β βΒ Β βββ SettlementService.ts
βΒ Β βΒ Β βββ UserServices.ts
βΒ Β βΒ Β βββ videoServices.ts
βΒ Β βββ start.ts
βΒ Β βββ swagger.json
βΒ Β βββ swagger.ts <------------------ Swagger Generation ------------------
βΒ Β βββ tasks
βΒ Β βΒ Β βββ cacheCurrencyRates.ts
βΒ Β βββ tests <------------------ Tests ------------------
βΒ Β βΒ Β βββ test_apis <------------------ API Tests ------------------
βΒ Β βΒ Β βΒ Β βββ course
βΒ Β βΒ Β βΒ Β βΒ Β βββ course.test.ts
βΒ Β βΒ Β βΒ Β βββ course_ratings
βΒ Β βΒ Β βΒ Β βΒ Β βββ rating.test.ts
βΒ Β βΒ Β βΒ Β βββ example.test.ts
βΒ Β βΒ Β βΒ Β βββ instructor
βΒ Β βΒ Β βΒ Β βΒ Β βββ instructor.test.ts
βΒ Β βΒ Β βΒ Β βββ instructor_ratings
βΒ Β βΒ Β βΒ Β βΒ Β βββ instructor_ratings.test.ts
βΒ Β βΒ Β βΒ Β βββ trainee
βΒ Β βΒ Β βΒ Β βββ corporateTrainee.test.ts
βΒ Β βΒ Β βΒ Β βββ individualTrainee.test.ts
βΒ Β βΒ Β βββ test_models <------------------ Model Tests ------------------
βΒ Β βΒ Β βΒ Β βββ answer
βΒ Β βΒ Β βΒ Β βΒ Β βββ answer.test.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ factory.ts <------------------ Factory ------------------
βΒ Β βΒ Β βΒ Β βββ course
βΒ Β βΒ Β βΒ Β βΒ Β βββ course.test.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ factory.ts
βΒ Β βΒ Β βΒ Β βββ enrollment
βΒ Β βΒ Β βΒ Β βΒ Β βββ factory.ts
βΒ Β βΒ Β βΒ Β βββ exercise
βΒ Β βΒ Β βΒ Β βΒ Β βββ exercise.test.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ factory.ts
βΒ Β βΒ Β βΒ Β βββ instructor
βΒ Β βΒ Β βΒ Β βΒ Β βββ factory.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ instructor.test.ts
βΒ Β βΒ Β βΒ Β βββ lesson
βΒ Β βΒ Β βΒ Β βΒ Β βββ factory.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ lesson.test.ts
βΒ Β βΒ Β βΒ Β βββ rating
βΒ Β βΒ Β βΒ Β βΒ Β βββ factory.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ rating.test.ts
βΒ Β βΒ Β βΒ Β βββ trainee
βΒ Β βΒ Β βΒ Β βΒ Β βββ factory.ts
βΒ Β βΒ Β βΒ Β βΒ Β βββ trainee.test.ts
βΒ Β βΒ Β βΒ Β βββ userFactory.ts
βΒ Β βΒ Β βββ test_services <------------------ Service Tests ------------------
βΒ Β βΒ Β βΒ Β βββ CourseService.test.ts
βΒ Β βΒ Β βββ test_utils
βΒ Β βΒ Β βββ modelUtilities.test.ts
βΒ Β βββ utils
βΒ Β βββ auth
βΒ Β βΒ Β βββ token.ts
βΒ Β βββ loadModelsUtil.ts
βΒ Β βββ parseQueryParams.ts
βΒ Β βββ populateTestDb.ts
βΒ Β βββ testUtilities.ts
βββ tsconfig.jsonThe software is open source under the GPL.3 License.
how to run stripe in development mode
- update your .env file in both the client and server bu following the .env.example files
- install the stripe cli
sudo apt install stripe # for linux
brew install stripe/stripe-cli/stripe # for macyou can refer to this documentation for more information
- login to to stripe cli using stripe api key
stripe login --api-key sk_test_example
# contact the team for the api key or use your own- run the stripe cli
stripe listen --forward-to localhost:PORT/payment/stripe-webhook
# PORT is the port you are running the server onAccess the admin dashboard by going to the following URL
http://localhost:PORT/admin
> npm run generate-docs- Clean code
- RESTful Web API Patterns and Practices Cookbook
- Designing Data Intensive Applications
- Mongoose docs
- Express docs
- ReactJs docs
- Redux docs
- NodeJs docs
If you have any feedback, please reach out to us at ibrahim.abouelenein@student.guc.edu.eg















