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
1 change: 1 addition & 0 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,5 +168,6 @@ module.exports = removeImports(nextTranslate(withBundleAnalyzer({
DOMAIN_NAME: process.env.DOMAIN_NAME,
BASE_PLAN: process.env.BASE_PLAN,
RIGOBOT_HOST: process.env.RIGOBOT_HOST,
NEXT_PUBLIC_IP_API_KEY: process.env.NEXT_PUBLIC_IP_API_KEY,
},
})));
1 change: 1 addition & 0 deletions public/locales/en/signup.json
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@
"compilation-bundle-title": "Compilation bundle",
"upgrade-a-plan": "Upgrade a plan",
"take-me-there": "Take me there",
"coupon-not-valid": "Coupon {{name}} is not valid",
"prereq-modal": {
"continue-registration": "Continue with registration",
"go-to-page": "Page {{page}}"
Expand Down
1 change: 1 addition & 0 deletions public/locales/es/signup.json
Original file line number Diff line number Diff line change
Expand Up @@ -206,6 +206,7 @@
"upgrade-a-plan": "Mejora un plan",
"compilation-bundle-title": "Paquete de acceso a compilaciones",
"take-me-there": "Comprar plan",
"coupon-not-valid": "El cupón {{name}} no es válido",
"prereq-modal": {
"continue-registration": "Continuar con el registro",
"go-to-page": "Página {{page}}"
Expand Down
56 changes: 48 additions & 8 deletions src/components/CohortPanel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ function CohortPanel({ cohort, modules, mainCohort, certificate, openByDefault,
modules.forEach((module) => {
const assignmentsCount = module.content.reduce((acc, curr) => {
const isApproved = isTaskApproved(curr);
const isRejected = curr.revision_status === 'REJECTED';
const isPendingProject = curr.task_type === 'PROJECT' && curr.revision_status === 'PENDING' && curr.task_status === 'DONE';
if (!(curr.task_type in acc)) {
// Check if any assignment in the module has a pending revision
const pendingRevisionsCount = module.content.filter((assignment) => pendingRevisions.some((task) => task.associated_slug === assignment.slug && task.task_type === curr.task_type)).length;
Expand All @@ -103,24 +105,32 @@ function CohortPanel({ cohort, modules, mainCohort, certificate, openByDefault,
done: curr.task_status === 'DONE' ? 1 : 0,
pendingRevision: pendingRevisionsCount,
approved: isApproved ? 1 : 0,
rejected: isRejected ? 1 : 0,
pending: isPendingProject ? 1 : 0,
};
} else {
acc[curr.task_type].total += 1;
if (curr.task_status === 'DONE') acc[curr.task_type].done += 1;
if (isApproved) acc[curr.task_type].approved += 1;
if (isRejected) acc[curr.task_type].rejected += 1;
if (isPendingProject) acc[curr.task_type].pending += 1;
}
return acc;
}, {});

const typesPerModule = Object.keys(assignmentsCount);
const moduleTotalAssignments = typesPerModule.reduce((acc, curr) => assignmentsCount[curr].total + acc, 0);
const moduleDoneAssignments = typesPerModule.reduce((acc, curr) => assignmentsCount[curr].done + acc, 0);
const moduleApprovedAssignments = typesPerModule.reduce((acc, curr) => assignmentsCount[curr].approved + acc, 0);
const moduleRejectedAssignments = typesPerModule.reduce((acc, curr) => assignmentsCount[curr].rejected + acc, 0);
const hasPendingRevisions = typesPerModule.some((taskType) => assignmentsCount[taskType].pendingRevision > 0);
const isStarted = module.filteredContent.length > 0;

modulesDict[module.id] = {
moduleTotalAssignments,
moduleDoneAssignments,
moduleApprovedAssignments,
moduleRejectedAssignments,
assignmentsCount,
hasPendingRevisions,
isStarted,
Expand All @@ -135,16 +145,18 @@ function CohortPanel({ cohort, modules, mainCohort, certificate, openByDefault,

const allModules = Object.values(modulesProgress);
const totalAssignments = allModules.reduce((acc, curr) => curr.moduleTotalAssignments + acc, 0);
const doneAssignments = allModules.reduce((acc, curr) => curr.moduleDoneAssignments + acc, 0);
const approvedAssignments = allModules.reduce((acc, curr) => curr.moduleApprovedAssignments + acc, 0);
const rejectedAssignments = allModules.reduce((acc, curr) => curr.moduleRejectedAssignments + acc, 0);
const hasPendingRevisions = allModules.some((module) => module.hasPendingRevisions);

const percentage = cohort.cohort_user.educational_status === 'GRADUATED' ? 100 : Math.floor((doneAssignments * 100) / (totalAssignments || 1));
const percentage = cohort.cohort_user.educational_status === 'GRADUATED' ? 100 : Math.ceil((approvedAssignments * 100) / (totalAssignments || 1));

const isCohortStarted = allModules.some((module) => module.isStarted);

return {
totalAssignments,
doneAssignments,
approvedAssignments,
rejectedAssignments,
percentage,
isCohortStarted,
hasPendingRevisions,
Expand Down Expand Up @@ -293,6 +305,8 @@ function CohortPanel({ cohort, modules, mainCohort, certificate, openByDefault,
padding: '16px',
} : {};

console.log(modulesProgress);

return (
<>
<Accordion index={isExpanded ? 0 : -1} onChange={(index) => setIsExpanded(index === 0)} allowToggle>
Expand Down Expand Up @@ -462,7 +476,7 @@ function CohortPanel({ cohort, modules, mainCohort, certificate, openByDefault,
{modules?.map((module) => {
const assignmentsCount = modulesProgress?.[module.id]?.assignmentsCount;
const moduleTotalAssignments = modulesProgress?.[module.id]?.moduleTotalAssignments;
const moduleDoneAssignments = modulesProgress?.[module.id]?.moduleDoneAssignments;
const moduleApprovedAssignments = modulesProgress?.[module.id]?.moduleApprovedAssignments;

const typesPerModule = assignmentsCount ? Object.keys(assignmentsCount) : [];
const moduleLabel = getModuleLabel(module);
Expand Down Expand Up @@ -492,13 +506,13 @@ function CohortPanel({ cohort, modules, mainCohort, certificate, openByDefault,
<Icon icon="play" width="12px" height="12px" color="white" />
</Box>
);
} if (moduleTotalAssignments === moduleDoneAssignments) { // Case 2: Started and Complete
} if (moduleTotalAssignments === moduleApprovedAssignments) { // Case 2: Started and Complete
return (
<Icon icon="verified" width="26px" height="26px" color={hexColor.green} />
);
} // else: Case 3: Started but In Progress (including 0 done)
return (
<CircularProgress color={hexColor.green} size="26px" value={(moduleDoneAssignments * 100) / (moduleTotalAssignments || 1)} />
<CircularProgress color={hexColor.green} size="26px" value={(moduleApprovedAssignments * 100) / (moduleTotalAssignments || 1)} />
);
})()}
</>
Expand All @@ -509,7 +523,7 @@ function CohortPanel({ cohort, modules, mainCohort, certificate, openByDefault,
</Box>
<Box display={{ base: 'none', sm: 'flex' }} alignItems="center" gap="16px">
{typesPerModule.map((taskType) => {
const { icon, total, done, pendingRevision, approved } = assignmentsCount[taskType];
const { icon, total, done, pendingRevision, approved, rejected, pending } = assignmentsCount[taskType];
return (
<Box
key={`${moduleLabel}-${taskType}`}
Expand All @@ -532,7 +546,33 @@ function CohortPanel({ cohort, modules, mainCohort, certificate, openByDefault,
{total}
</Text>
{approved === total && <Icon icon="checked2" color={hexColor.green} />}
{pendingRevision > 0 && (
{rejected > 0 && (
<Box border="5px solid" borderColor="danger" borderRadius="100%" color="danger" position="relative">
<Box
position="absolute"
top="50%"
left="50%"
transform="translate(-50%, -50%)"
borderRadius="full"
border="2px solid"
borderColor={hexColor.white2}
/>
</Box>
)}
{pending > 0 && (
<Box border="5px solid" borderColor="yellow.default" borderRadius="100%" position="relative">
<Box
position="absolute"
top="50%"
left="50%"
transform="translate(-50%, -50%)"
borderRadius="full"
border="2px solid"
borderColor={hexColor.white2}
/>
</Box>
)}
{pendingRevision > 0 && rejected > 0 && (
<Box
position="absolute"
top="18px"
Expand Down
20 changes: 18 additions & 2 deletions src/components/GuidedExperience/ExerciseGuidedExperience.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import Heading from '../Heading';
import Text from '../Text';
import { reportDatalayer } from '../../utils/requests';

function ExerciseGuidedExperience({ currentTask, currentAsset, handleStartLearnpack, iframeURL, learnpackStart, setLearnpackStart }) {
function ExerciseGuidedExperience({ currentTask, currentAsset, handleStartLearnpack, iframeURL, learnpackStart, setLearnpackStart, onCloseExercise }) {
const { t } = useTranslation('syllabus');
const { colorMode } = useStyle();
const [telemetryReport, setTelemetryReport] = useState([]);
Expand Down Expand Up @@ -121,7 +121,21 @@ function ExerciseGuidedExperience({ currentTask, currentAsset, handleStartLearnp
{learnpackStart
? (
<>
<Button color="white" alignSelf="end" _hover="none" _active="none" background="none" onClick={() => setLearnpackStart(false)}>{t('close-exercise')}</Button>
<Button
color="white"
alignSelf="end"
_hover="none"
_active="none"
background="none"
onClick={() => {
setLearnpackStart(false);
if (onCloseExercise) {
onCloseExercise();
}
}}
>
{t('close-exercise')}
</Button>
<Box flexGrow={100}>
<iframe
title="exercise-frame"
Expand Down Expand Up @@ -243,6 +257,7 @@ ExerciseGuidedExperience.propTypes = {
handleStartLearnpack: PropTypes.func,
setLearnpackStart: PropTypes.func,
learnpackStart: PropTypes.bool,
onCloseExercise: PropTypes.func,
};

ExerciseGuidedExperience.defaultProps = {
Expand All @@ -252,6 +267,7 @@ ExerciseGuidedExperience.defaultProps = {
handleStartLearnpack: null,
setLearnpackStart: null,
learnpackStart: false,
onCloseExercise: null,
};

export default ExerciseGuidedExperience;
20 changes: 10 additions & 10 deletions src/components/PrismicComponents/MktHeroSection.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -204,16 +204,6 @@ function MktHeroSection({
onClose={handleCloseModal}
mainImage="/static/images/women-laptop-bubbles.png"
callToActions={[
{
title: t('self-paced-courses'),
titleStyles: {
color: 'green.500',
},
description: t('self-paced-description'),
buttonText: t('see-plan-details'),
titleLeftComponent: <Box p="8px" borderRadius="8px" bg="green.100"><Icon icon="pathToStar" color="#06AB52" /></Box>,
action: () => router.replace({ pathname: '/pricing', query: { view: 'self-paced' } }),
},
{
title: t('immersive-bootcamp'),
titleStyles: {
Expand All @@ -224,6 +214,16 @@ function MktHeroSection({
titleLeftComponent: <Box p="8px" borderRadius="8px" bg="blue.50"><Icon icon="rocketDiagonal" color="#0084FF" /></Box>,
action: () => router.replace({ pathname: '/pricing', query: { view: 'immersive-bootcamps' } }),
},
{
title: t('self-paced-courses'),
titleStyles: {
color: 'green.500',
},
description: t('self-paced-description'),
buttonText: t('see-plan-details'),
titleLeftComponent: <Box p="8px" borderRadius="8px" bg="green.100"><Icon icon="pathToStar" color="#06AB52" /></Box>,
action: () => router.replace({ pathname: '/pricing', query: { view: 'self-paced' } }),
},
]}
/>
</Box>
Expand Down
34 changes: 30 additions & 4 deletions src/components/Timeline.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,34 @@ function Timeline({
: (item?.translations?.[lang]?.title || item?.title);
};

const getAssignmentStatusIndicator = (item) => {
const isProjectPending = item.task_status === 'DONE' && item.revision_status === 'PENDING' && item.task_type === 'PROJECT';
const isProjectRejected = item.task_status === 'DONE' && item.revision_status === 'REJECTED' && item.task_type === 'PROJECT';

if (isProjectPending || isProjectRejected) {
return (
<Box border="9px solid" borderColor={isProjectPending ? 'yellow.default' : 'danger'} borderRadius="100%" position="relative">
<Box
position="absolute"
top="50%"
left="50%"
transform="translate(-50%, -50%)"
borderRadius="full"
border="4px solid"
borderColor={hexColor.white2}
/>
</Box>
);
}
if (item.task_status === 'DONE' && item.task_type !== 'PROJECT') {
return <Icon icon="checked2" color={hexColor.green} />;
}
if (item.task_status === 'DONE' && item.revision_status === 'APPROVED' && item.task_type === 'PROJECT') {
return <Icon icon="checked2" color={hexColor.green} />;
}
return null;
};

if (variant === 'guided-experience') {
return (
<Box display="flex" flexDirection="column" gap="5px" flex="1">
Expand Down Expand Up @@ -110,9 +138,7 @@ function Timeline({
</Flex>
<Text size="sm" fontWeight="400" marginY={0} color={muted ? '#6883B4' : fontColor}>{assignmentTitle}</Text>
</Box>
{item.task_status === 'DONE' && (
<Icon icon="checked2" color={hexColor.green} />
)}
{getAssignmentStatusIndicator(item)}
</Box>
);
}) : (
Expand Down Expand Up @@ -216,7 +242,7 @@ Timeline.defaultProps = {
assignments: [],
technologies: [],
width: '100%',
onClickAssignment: () => {},
onClickAssignment: () => { },
showPendingTasks: false,
variant: '',
};
Expand Down
15 changes: 7 additions & 8 deletions src/context/SessionContext.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import React, { createContext, useEffect, useState } from 'react';
import { useRouter } from 'next/router';
import PropTypes from 'prop-types';
import { isWindow, getQueryString } from '../utils';
import useGoogleMaps from '../hooks/useGoogleMaps';
import useIPGeolocation from '../hooks/useIPGeolocation';
import { error } from '../utils/logging';

const initialUserSession = {
Expand Down Expand Up @@ -35,26 +35,25 @@ function SessionProvider({ children }) {
const router = useRouter();
const [location, setLocation] = useState(null);
const [isLoadingLocation, setIsLoadingLocation] = useState(true);
const GOOGLE_KEY = process.env.GOOGLE_GEO_KEY;
const { gmapStatus, getUserLocation } = useGoogleMaps(
GOOGLE_KEY,
'places',
);
const { status, getUserLocation } = useIPGeolocation();

const initLocation = async () => {
try {
const loc = await getUserLocation();
setLocation(loc);
} catch (e) {
error('function getUserLocation()', e);
setLocation(null);
} finally {
setIsLoadingLocation(false);
}
};

useEffect(() => {
initLocation();
}, [gmapStatus]);
if (status.loaded) {
initLocation();
}
}, [status.loaded]);

const setConversionUrl = () => {
if (isWindow) {
Expand Down
Loading
Loading