Skip to content

Commit

Permalink
Merge pull request #510 from EscolaLMS/feature/REK-56
Browse files Browse the repository at this point in the history
Feature/rek 56
  • Loading branch information
victazzz authored Nov 21, 2024
2 parents a6998a9 + acb2ae4 commit d4c159c
Show file tree
Hide file tree
Showing 13 changed files with 886 additions and 1,072 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
"@capacitor/ios": "^5.7.3",
"@capacitor/local-notifications": "^5.0.7",
"@capacitor/status-bar": "^5.0.7",
"@escolalms/components": "^0.0.156",
"@escolalms/components": "^0.0.157",
"@escolalms/h5p-react": "^0.2.19",
"@escolalms/sdk": "^0.6.2",
"@escolalms/ts-models": "^0.0.35",
Expand Down
7 changes: 4 additions & 3 deletions src/components/Cart/CartContent/stripe.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { useState } from "react";
import { useContext, useState } from "react";
import { Link } from "react-router-dom";
import { useTranslation } from "react-i18next";
import Layout from "@/components/_App/Layout";
Expand All @@ -13,7 +13,7 @@ import { isMobile } from "react-device-detect";
import Preloader from "@/components/_App/Preloader";
import Collapse from "@/components/Common/Collapse";
import PaymentForm from "@/components/Cart/PaymentForm";

import { EscolaLMSContext } from "@escolalms/sdk/lib/react/context";
import {
useStripe,
useElements,
Expand All @@ -38,7 +38,6 @@ const StripeContent = ({ stripeKey }: { stripeKey: string }) => {
discountStatus,
fetchCart,
payByStripe,
removeFromCart,
courses,
cart,
location,
Expand All @@ -47,6 +46,8 @@ const StripeContent = ({ stripeKey }: { stripeKey: string }) => {
setDiscountStatus,
} = usePayment();

const { removeFromCart } = useContext(EscolaLMSContext);

const { t } = useTranslation();

const stripe = useStripe();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,6 @@ const JitsyMeeting: React.FC<Props> = ({

setTimeout(() => {
if (hasCameraAccess && isMeetingActive && isStudent) {
console.log("Show modal");
setShowModal(true);
}
}, 5000);
Expand Down
40 changes: 33 additions & 7 deletions src/components/Consultations/ConsultationCard/index.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
import React, { useState } from "react";
import styled from "styled-components";
import { CourseCard } from "@escolalms/components/lib/components/molecules/CourseCard/CourseCard";
import { NewCourseCard } from "@escolalms/components/lib/index";
import { API } from "@escolalms/sdk/lib";
import BookTermModal from "@/components/Book/BookTermModal";
import ConsultationCardButtons from "./Buttons";
import { Link, useHistory } from "react-router-dom";
import ConsultationCardContent from "./Content";
import { Title } from "@escolalms/components/lib/components/atoms/Typography/Title";
import ConsultationCardImage from "./Image";
import CategoriesBreadCrumbs from "@/components/Categories/CategoriesBreadCrumbs";
import { useHistory } from "react-router-dom";

import { useTranslation } from "react-i18next";
import ProductPrices from "@/components/ProductPrices";
const ConsultationCardStyles = styled.div`
.course-card-buttons-group {
margin: 0;
Expand All @@ -23,16 +25,18 @@ const ConsultationCardStyles = styled.div`

interface ConsultationCardProps {
consultation: API.Consultation;
showPrice?: boolean;
}

const ConsultationCard: React.FC<ConsultationCardProps> = (props) => {
const { consultation } = props;
const { consultation, showPrice = false } = props;
const [showBookTerm, setShowBookTerm] = useState(false);
const history = useHistory();
const { t } = useTranslation();

return (
<ConsultationCardStyles>
<CourseCard
<NewCourseCard
id={consultation.id}
categories={
<CategoriesBreadCrumbs
Expand All @@ -43,14 +47,36 @@ const ConsultationCard: React.FC<ConsultationCardProps> = (props) => {
/>
}
image={<ConsultationCardImage consultation={consultation} />}
title={`${consultation.name}`}
footer={<ConsultationCardContent consultation={consultation} />}
title={
<Link to={`/consultations/${consultation.id}`}>
<Title level={3} as="h3" className="title">
{consultation.name}
</Title>
</Link>
}
actions={
<ConsultationCardButtons
consultation={consultation}
showBookTerm={(value) => setShowBookTerm(value)}
/>
}
footer={<ConsultationCardContent consultation={consultation} />}
price={
showPrice && (
<>
{/* @ts-ignore TODO: missed in sdk */}
{consultation.public ? (
<div className="course-price">{t("FREE")}</div>
) : (
<ProductPrices
price={consultation.product?.price}
oldPrice={consultation.product?.price_old}
taxRate={consultation.product?.tax_rate}
/>
)}
</>
)
}
/>
{/* Book term modal */}
<BookTermModal
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ interface Props {
}

const ConsultationsContainerItem = ({ consultation }: Props) => {
return <ConsultationCard consultation={consultation} />;
return <ConsultationCard consultation={consultation} showPrice />;
};

export default ConsultationsContainerItem;
101 changes: 65 additions & 36 deletions src/components/Courses/Course/Context/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ interface CourseContext {
}

const Context = React.createContext<CourseContext>({});
export const UnknownTopicId = "-1";

export const useCoursePanel = () => useContext(Context);

Expand Down Expand Up @@ -170,50 +171,78 @@ const CoursePanelProvider: React.FC<React.PropsWithChildren> = ({
[currentCourseProgress]
);

const availableTopicsIds = useMemo(() => {
const activeLessonsFlatTopics = useMemo(() => {
const activeLessons = (currentCourseProgram?.lessons ?? []).filter(
(l) =>
l.active_from === null ||
(l.active_from && isAfter(new Date(), new Date(l.active_from)))
);

const activeLessonsFlatTopics = getFlatTopics(activeLessons);

const { incomplete, in_progress, complete } =
activeLessonsFlatTopics.reduce<{
in_progress: number[];
complete: number[];
incomplete: number[];
}>(
(acc, t) => {
const el = (currentCourseProgress?.value ?? []).find(
({ topic_id }) => topic_id === t.id
);
if (!el) return acc;

const statusMap = {
[API.CourseProgressItemElementStatus.INCOMPLETE]: "incomplete",
[API.CourseProgressItemElementStatus.COMPLETE]: "complete",
[API.CourseProgressItemElementStatus.IN_PROGRESS]: "in_progress",
} as const;

return {
...acc,
[statusMap[el.status]]: [...acc[statusMap[el.status]], t.id],
};
},
{
in_progress: [],
incomplete: [],
complete: [],
}
);
return getFlatTopics(activeLessons);
}, [currentCourseProgram]);

const findClosestIncompleteTopicId = useCallback(
(topicId: number | undefined) => {
const topic = activeLessonsFlatTopics.find((t) => t.id === topicId);
if (!topic) return null;

if (in_progress.length) return [...in_progress, ...complete];
const index = activeLessonsFlatTopics.indexOf(topic);
const nextTopic = activeLessonsFlatTopics[index + 1];
if (!nextTopic) return null;

const firstInCompletedLessonId = incomplete?.[0] ? [incomplete[0]] : [];
return [...complete, ...firstInCompletedLessonId];
}, [currentCourseProgram?.lessons, currentCourseProgress?.value]);
return nextTopic.id;
},
[activeLessonsFlatTopics]
);

const availableTopicsIds = useMemo(() => {
const { in_progress, complete } = activeLessonsFlatTopics.reduce<{
in_progress: number[];
complete: number[];
incomplete: number[];
}>(
(acc, t) => {
const el = (currentCourseProgress?.value ?? []).find(
({ topic_id }) => topic_id === t.id
);
if (!el) return acc;

const statusMap = {
[API.CourseProgressItemElementStatus.INCOMPLETE]: "incomplete",
[API.CourseProgressItemElementStatus.COMPLETE]: "complete",
[API.CourseProgressItemElementStatus.IN_PROGRESS]: "in_progress",
} as const;

return {
...acc,
[statusMap[el.status]]: [...acc[statusMap[el.status]], t.id],
};
},
{
in_progress: [],
incomplete: [],
complete: [],
}
);

const firstInCompletedLessonId = findClosestIncompleteTopicId(
currentTopic?.id
);

if (in_progress.length)
return [...in_progress, ...complete, firstInCompletedLessonId].filter(
(id): id is number => id !== null
);

return [...complete, firstInCompletedLessonId].filter(
(id): id is number => id !== null
);
}, [
currentCourseProgress?.value,
currentTopic?.id,
findClosestIncompleteTopicId,
activeLessonsFlatTopics,
]);

const currentLessonParentsIds: number[] = useMemo(() => {
if (!currentLesson) return [];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,18 +51,25 @@ export const QuestionnairesModal = ({

const { isStudent, isTutor } = useRoles();

const questionnaires = useMemo(
() =>
questionnairesList.filter((questionaire) =>
questionaire.models.some(
(model) =>
model.model_type_title === entityModel && // @ts-ignore add to sdk
((isStudent && model.target_group === "user") || // @ts-ignore add to sdk
(isTutor && model.target_group === "author"))
)
),
[questionnairesList, isStudent, isTutor, entityModel]
);
const questionnaires = useMemo(() => {
return questionnairesList.filter((questionnaire) =>
questionnaire.models.some((model) => {
if (model.model_type_title === entityModel) {
if (model.model_type_title === QuestionnaireModelType.CONSULTATION) {
// Additional filters for "consultation"
return (
// @ts-ignore add to sdk
(isStudent && model.target_group === "user") || // @ts-ignore add to sdk
(isTutor && model.target_group === "author")
);
}

return true;
}
return false;
})
);
}, [questionnairesList, isStudent, isTutor, entityModel]);

const categorizedQuestionnaires = useCallback(() => {
if (!questionnaires) return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,27 +62,17 @@ export const CoursePanelFinishPage = () => {
}));
}, []);

const handleModalChange = useCallback((value: boolean) => {
setState((prev) => ({ ...prev, showModal: value }));
}, []);

const onNextClick = useCallback(() => {
if (state.isAnyQuestionnaire) {
handleModalChange(true);
onFinish();
return;
}
if (state.certificates && state.certificates.length > 0) {
onFinish();
return;
}
history.push(routeRoutes.myProfile);
}, [
handleModalChange,
history,
onFinish,
state.certificates,
state.isAnyQuestionnaire,
]);
}, [history, onFinish, state.certificates, state.isAnyQuestionnaire]);

const onSuccesGetQuestionnaires = useCallback(
(isAnyQuestionnaire: boolean) => {
Expand All @@ -106,8 +96,6 @@ export const CoursePanelFinishPage = () => {
entityId={Number(courseId)}
entityModel={QuestionnaireModelType.COURSE}
showModal={state.showModal}
onClose={() => handleModalChange(false)}
onFinish={onFinish}
onSuccesGetQuestionnaires={onSuccesGetQuestionnaires}
/>
</CongratsWrapper>
Expand Down
Loading

0 comments on commit d4c159c

Please sign in to comment.