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
2 changes: 1 addition & 1 deletion src/components/Checkout/ServiceSummary.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ function ServiceSummary({ service }) {
},
});
}
const resp = await bc.payment().addCard(values);
const resp = await bc.payment().addCard({ ...values, academy: service.academy.id });
const data = await resp.json();
setIsSubmittingCard(false);
if (resp.ok) {
Expand Down
1 change: 1 addition & 0 deletions src/components/MktOneColumnSection/ImageOnTopVariation.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ function ImageOnTopVariation({
src={image.url}
alt={image.alt || title || 'Section image'}
objectFit="cover"
objectPosition="50% 10%"
width="100%"
height={{ base: '271px', md: '365px' }}
/>
Expand Down
22 changes: 9 additions & 13 deletions src/components/Navbar/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,7 @@ import { getAllMySubscriptions } from '../../handlers/subscriptions';

function Navbar({ translations, pageProps }) {
const [uniqueLanguages, setUniqueLanguages] = useState([]);
const { userSession, location } = useSession();
const isUtmMediumAcademy = userSession?.utm_medium === 'academy';
const { location, isLoadingLocation } = useSession();
const { isAuthenticated, isLoading, user, logout, cohorts } = useAuth();
const [navbarItems, setNavbarItems] = useState([]);
const [mktCourses, setMktCourses] = useState([]);
Expand Down Expand Up @@ -131,26 +130,23 @@ function Navbar({ translations, pageProps }) {

setMktCourses(coursesStruct || []);
} catch (error) {
console.error(error);
console.error(`Error fetching mkt courses: ${error}`);
}
};

useEffect(() => {
fetchMktCourses();
}, [locale]);
if (!isLoadingLocation) {
fetchMktCourses();
}
}, [locale, isLoadingLocation]);

useEffect(() => {
if (pageProps?.existsWhiteLabel) {
setNavbarItems(whiteLabelitems);
} else if (!isLoading && user?.id) {
setNavbarItems(preDefinedItems.filter((item) => (item.disabled !== true && item.hide_on_auth !== true)));
} else {
const preFilteredItems = preDefinedItems.filter(
(item) => (isUtmMediumAcademy ? item.id !== 'bootcamps' : true) && (item.id === 'bootcamps' ? location?.countryShort !== 'ES' : true),
);
if (!isLoading && user?.id) {
setNavbarItems(preFilteredItems.filter((item) => (item.disabled !== true && item.hide_on_auth !== true)));
} else {
setNavbarItems(preFilteredItems.filter((item) => item.disabled !== true));
}
setNavbarItems(preDefinedItems.filter((item) => item.disabled !== true));
}
}, [user, cohorts, isLoading, cohortSession, mktCourses, router.locale, location]);

Expand Down
95 changes: 11 additions & 84 deletions src/pages/bootcamp/[course_slug].jsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
/* eslint-disable camelcase */
/* eslint-disable no-unused-vars */
import axios from 'axios';
import PropTypes from 'prop-types';
import { Box, Button, Flex, Image, SkeletonText, Badge } from '@chakra-ui/react';
import { useEffect, useState, useRef } from 'react';
import useTranslation from 'next-translate/useTranslation';
import { useRouter } from 'next/router';
import Head from 'next/head';
import { parseQuerys } from '../../utils/url';
import { BREATHECODE_HOST, ORIGIN_HOST, WHITE_LABEL_ACADEMY, BASE_COURSE } from '../../utils/variables';
import { BREATHECODE_HOST, ORIGIN_HOST, BASE_COURSE } from '../../utils/variables';
import Icon from '../../components/Icon';
import Text from '../../components/Text';
import GridContainer from '../../components/GridContainer';
Expand Down Expand Up @@ -48,75 +46,10 @@ import useCustomToast from '../../hooks/useCustomToast';
import { usePlanPrice } from '../../utils/getPriceWithDiscount';
import useSession from '../../hooks/useSession';

export async function getStaticPaths({ locales }) {
const mktQueryString = parseQuerys({
featured: true,
academy: WHITE_LABEL_ACADEMY,
});

const getAllCourses = await Promise.all(locales.map(async (locale) => {
const resp = await axios.get(`${BREATHECODE_HOST}/v1/marketing/course${mktQueryString}&lang=${locale}`);
return resp?.data;
}));

const filterByTranslations = getAllCourses.flat().filter((item) => item?.course_translation !== null);
const paths = filterByTranslations.flatMap((course) => {
const locale = course?.course_translation?.lang?.split('-')[0];
return course?.slug && ({
params: {
course_slug: course?.slug,
},
locale,
});
});

return {
fallback: false,
paths,
};
}
export async function getStaticProps({ locale, locales, params }) {
const { course_slug: courseSlug } = params;

const endpoint = `/v1/marketing/course/${courseSlug}?lang=${locale}`;
const resp = await axios.get(`${BREATHECODE_HOST}${endpoint}`);
const data = resp?.data;

if (resp?.status >= 400) {
console.error(`ERROR with /bootcamp/course/${courseSlug}: something went wrong fetching "${endpoint}"`);
return {
notFound: true,
};
}

const syllabusSlug = data.syllabus[0]?.slug;

const respSyll = await axios.get(`${BREATHECODE_HOST}/v1/admissions/syllabus/version?slug=${syllabusSlug}`);
const syllabus = respSyll?.data[0];

return {
props: {
seo: {
title: data.course_translation.title,
description: data.course_translation.description,
image: data?.course_translation?.preview_url || `${ORIGIN_HOST}/static/images/4geeks.png`,
locales,
locale,
disableStaticCanonical: true,
disableHreflangs: true,
url: `/bootcamp/${data.slug}`,
pathConnector: '/bootcamp',
card: 'default',
},
data,
syllabus,
},
};
}

function CoursePage({ data, syllabus }) {
function CoursePage() {
const { state, getPriceWithDiscount, getSelfAppliedCoupon, applyDiscountCouponsToPlans } = useSignup();
const [coupon] = usePersistentBySession('coupon', '');
const [data, setData] = useState({});
const { selfAppliedCoupon } = state;
const showBottomCTA = useRef(null);
const [isCtaVisible, setIsCtaVisible] = useState(false);
Expand Down Expand Up @@ -146,6 +79,7 @@ function CoursePage({ data, syllabus }) {
const cohortId = data?.cohort?.id;
const isVisibilityPublic = data.visibility === 'PUBLIC';
const courseColor = data?.color;
const { course_slug: courseSlug } = router.query;

const structuredData = data?.course_translation ? {
'@context': 'https://schema.org',
Expand Down Expand Up @@ -203,7 +137,7 @@ function CoursePage({ data, syllabus }) {
const country_code = location?.countryShort;

useEffect(() => {
if (isRigoInitialized && data.course_translation && !initialDataIsFetching && planData?.slug) {
if (isRigoInitialized && data?.course_translation && !initialDataIsFetching && planData?.slug) {
// const context = document.body.innerText;

const plans = applyDiscountCouponsToPlans(planData.planList, selfAppliedCoupon);
Expand All @@ -215,8 +149,8 @@ function CoursePage({ data, syllabus }) {
period: ${plan.period_label}
${plan.lastPrice ? `original price: ${plan.lastPrice}\n discount: ${discount}\n` : ''}
`);
const syllabusContext = syllabus?.json
? syllabus.json.days
const syllabusContext = cohortData?.cohortSyllabus?.syllabus?.json
? cohortData.cohortSyllabus.syllabus.json.days
.map(({ label, description }) => `- Title: ${typeof label === 'object' ? (label[lang] || label.us) : label}, Description: ${typeof description === 'object' ? (description[lang] || description.us) : description}`)
: '';

Expand Down Expand Up @@ -355,7 +289,10 @@ function CoursePage({ data, syllabus }) {

const getInitialData = async () => {
setInitialDataIsFetching(true);
const cohortSyllabus = await generateCohortSyllabusModules(cohortId);
const { data: courseData } = await bc.marketing({ lang, country_code }).getCourse(courseSlug);
setData(courseData);

const cohortSyllabus = await generateCohortSyllabusModules(courseData?.cohort?.id);

const getModulesInfo = async () => {
try {
Expand Down Expand Up @@ -1105,14 +1042,4 @@ function CoursePage({ data, syllabus }) {
);
}

CoursePage.propTypes = {
data: PropTypes.objectOf(PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.array])),
syllabus: PropTypes.objectOf(PropTypes.oneOfType([PropTypes.any])),
};

CoursePage.defaultProps = {
data: {},
syllabus: null,
};

export default CoursePage;
1 change: 1 addition & 0 deletions src/services/breathecode.js
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,7 @@ const breathecode = {
return {
lead: (data) => axios.post(`${url}/lead${qs}`, data),
courses: () => axios.get(`${url}/course${qs}`),
getCourse: (courseSlug) => axios.get(`${url}/course/${courseSlug}${qs}`),
};
},

Expand Down