Skip to content

Commit

Permalink
refactor: Update CourseCard and PaymentRecordELements components
Browse files Browse the repository at this point in the history
  • Loading branch information
Mohamed-Ramadan1 committed May 25, 2024
1 parent d3d9819 commit 5f20d2f
Show file tree
Hide file tree
Showing 9 changed files with 349 additions and 124 deletions.
2 changes: 0 additions & 2 deletions src/components/courses/coursesOverview/CourseCard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ const CourseCard = ({ course }) => {
/>
</Link>
</div>

{/* Details Course */}
<Link to={`/courses/${course._id}`}>
<div className="content flex flex-col items-start gap-[5px]">
Expand Down Expand Up @@ -73,7 +72,6 @@ const CourseCard = ({ course }) => {
</div>
</div>
</Link>

<WishlistComponent courseId={course._id} />
</div>
);
Expand Down
6 changes: 3 additions & 3 deletions src/components/dashboard/PaymentRecordELements.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import TableBodyCell from "./shard/TableBodyCell";
const PaymentRecordELements = ({ payment }) => {
const {
_id,
name,
user,
email,
paymentVerified,
paymentAmount,
Expand All @@ -17,8 +17,8 @@ const PaymentRecordELements = ({ payment }) => {
return (
<TableBody>
<TableBodyCell>{_id}</TableBodyCell>
<TableBodyCell>{name}</TableBodyCell>
<TableBodyCell>{email}</TableBodyCell>
<TableBodyCell>{user.name}</TableBodyCell>
<TableBodyCell>{user.email}</TableBodyCell>
<TableBodyCell>{isPaymentVerified}</TableBodyCell>
<TableBodyCell>{paymentAmount} $</TableBodyCell>
<TableBodyCell>{paymentStatus}</TableBodyCell>
Expand Down
5 changes: 5 additions & 0 deletions src/components/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export { default as CourseEnrollmentDetails } from "./courses/courseDetails/Cour

export { default as CoursesPageIntro } from "./courses/coursesOverview/CoursesPageIntro";
export { default as CourseCard } from "./courses/coursesOverview/CourseCard";

export { default as FilterCourses } from "./courses/coursesOverview/FilterCourses";

//Blog
Expand Down Expand Up @@ -84,5 +85,9 @@ export { default as StatsContainer } from "./dashboard/StatsContainer";
export { default as NavigationLink } from "./dashboard/shard/NavigationLink";
export { default as NavBarLink } from "./dashboard/shard/NavBarLink";

//Payment
export { default as OrderDetails } from "./payment/OrderDetails";
export { default as PaymentForm } from "./payment/PaymentForm";

//Global
export { default as Pagination } from "./common/Pagination";
13 changes: 13 additions & 0 deletions src/components/payment/InfoItem.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import React from "react";

const InfoItem = ({ infoTitle, infoDetails }) => {
return (
<div className="flex flex-col mx-3 mt-6">
<span className="font-bold ">
{infoTitle} : <span className="font-normal ">{infoDetails}</span>
</span>
</div>
);
};

export default InfoItem;
59 changes: 59 additions & 0 deletions src/components/payment/OrderDetails.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import InfoItem from "./InfoItem";

const OrderDetails = ({ course }) => {
return (
<div className="w-[100%] sm:w-[50%] ml-5 ">
<div className="mb-6">
<h3 className="text-center font-bold text-xl italic">
payment details
</h3>
</div>
<div className="flex justify-between">
<div className="flex flex-col justify-center">
<InfoItem infoTitle="Course Name" infoDetails={course?.title} />
<InfoItem
infoTitle="Course Price"
infoDetails={`${course?.price} $`}
/>
<InfoItem
infoTitle="Course Duration"
infoDetails={`${course?.duration} h`}
/>
<InfoItem
infoTitle="Course Category"
infoDetails={course?.category}
/>
<InfoItem
infoTitle="Course Language"
infoDetails={course?.language}
/>
<InfoItem infoTitle="Course Level" infoDetails={course?.skillLevel} />
<InfoItem
infoTitle="Course Rating"
infoDetails={course?.averageRating}
/>
</div>
<div>
{/* price ,taxes ,descount , total payment-amount */}
<div className="flex flex-col justify-center">
<InfoItem infoTitle="Price" infoDetails={`${course?.price} $`} />
<InfoItem infoTitle="Taxes" infoDetails={`0 $`} />
<InfoItem
infoTitle="Discount"
infoDetails={`${course?.discount} $`}
/>
<InfoItem
infoTitle="Total Payment Amount"
infoDetails={`${(course
? course.price - course.discount
: 0
).toFixed(2)} $`}
/>
</div>
</div>
</div>
</div>
);
};

export default OrderDetails;
112 changes: 112 additions & 0 deletions src/components/payment/PaymentForm.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
import { useNavigate } from "react-router-dom";
import { useSelector, useDispatch } from "react-redux";
import { Formik, Form } from "formik";
import { toast } from "react-toastify";
import { enrollUserToCourse } from "../../store/courseEnrollmentsSlice";
import { customFetch } from "../../utils/customFetch";
import CustomInput from "../../components/forms/CustomInput";

const PaymentForm = ({ coursePrice, courseDiscount, courseId }) => {
const dispatch = useDispatch();
const navigate = useNavigate();
const { token } = useSelector((state) => state.userReducers);
return (
<div className="w-[100%] sm:w-[50%]">
<div className="mb-6">
<h3 className="text-center font-bold text-xl italic">
Payment method
</h3>
</div>
<Formik
initialValues={{
cardName: "",
cardNumber: "",
cardCvv: "",
cardExpiryDate: "",
}}
onSubmit={async (values, actions) => {
try {
await customFetch.post(
"paymentRecords",
{
...values,
paymentAmount: (coursePrice - courseDiscount).toFixed(2),
course: courseId,
},
{
headers: {
Authorization: `Bearer ${token}`,
},
}
);

dispatch(enrollUserToCourse({ course: courseId }));
toast.success("Payment and enrollment Successfull");
navigate(`/myPaiedCourse/${courseId}`);
window.location.reload();
} catch (error) {
console.log(error);
toast.error("Payment and enrollment Failed");
}
actions.setSubmitting(false);
actions.resetForm();
}}
>
{({ handleSubmit, isSubmitting }) => (
<Form onSubmit={handleSubmit}>
<div className="mt-5">
<CustomInput
name="cardName"
type="text"
placeholder="Name on Card"
label="Name on the card"
required
/>

<CustomInput
name="cardNumber"
type="text"
placeholder="Visa Card Number"
label="Card Number"
required
/>
</div>

<div className="mt-5">
<CustomInput
name="cardExpiryDate"
type="month"
placeholder="Card Expiry Date"
label="Card Expiry Date"
requireds
/>
</div>

<div className="mt-5">
<CustomInput
name="cardCvv"
type="text"
placeholder="Card Cvv 123"
label="Card CVV Number"
required
pattern="[0-9]{3}"
/>
</div>

<div class="mt-2 flex justify-end">
<button
disabled={isSubmitting}
type="submit"
class="mt-5 w-full font-bold bg-blue-500 text-white px-4 py-2 hover:bg-blue-800 dark:text-white text-center"
>
Complete payment
</button>
</div>
</Form>
)}
</Formik>
</div>
);
};

export default PaymentForm;
114 changes: 113 additions & 1 deletion src/lefted.text
Original file line number Diff line number Diff line change
Expand Up @@ -182,4 +182,116 @@
</button>
</Form>
)}
</Formik>
</Formik>


<div className="w-[100%] sm:w-[50%]">
<div className="mb-6">
<h3 className="text-center font-bold text-xl italic">
Payment method
</h3>
</div>
<Formik
initialValues={{
name: "",
email: "",
cardNumber: "",
cardCvv: "",
cardExpiryDate: "",
paymentAmount: "",
}}
onSubmit={async (values, actions) => {
try {
await customFetch.post(
"paymentRecords",
{
...values,
course: courseId,
},
{
headers: {
Authorization: `Bearer ${token}`,
},
}
);

dispatch(enrollUserToCourse({ course: courseId }));
toast.success("Payment and enrollment Successfull");
navigate(`/courses/${courseId}`);
} catch (error) {
console.log(error);
toast.error("Payment and enrollment Failed");
}
actions.setSubmitting(false);
actions.resetForm();
}}
>
{({ handleSubmit, isSubmitting }) => (
<Form onSubmit={handleSubmit}>
<div className="mt-5">
<CustomInput
name="cardNumber"
type="text"
mask="9999 9999 9999 9999"
placeholder="Visa Card Number"
label="Card Number"
required
/>
</div>

<div className="mt-5">
<CustomInput
name="cardExpiryDate"
type="month"
placeholder="Card Expiry Date"
label="Card Expiry Date"
requireds
/>
</div>

<div className="mt-5">
<CustomInput
name="cardCvv"
type="text"
placeholder="Card Cvv 123"
label="Card CVV Number"
required
pattern="[0-9]{3}"
/>
</div>

<div className="mt-5">
<CustomInput
name="paymentAmount"
type="number"
placeholder="Amount"
label="Amount"
required
/>
</div>

<div class="mt-2 flex justify-end">
<button
disabled={isSubmitting}
type="submit"
class="mt-5 w-full font-bold bg-blue-500 text-white px-4 py-2 hover:bg-blue-800 dark:text-white text-center"
>
Complete payment
</button>
</div>
</Form>
)}
</Formik>
</div>












Loading

0 comments on commit 5f20d2f

Please sign in to comment.