Skip to content

Commit

Permalink
Merge branch 'development' into development-lumi-7752
Browse files Browse the repository at this point in the history
  • Loading branch information
tommygonzaleza authored Sep 10, 2024
2 parents 337c79f + bf237f4 commit f9c2ad9
Show file tree
Hide file tree
Showing 20 changed files with 251 additions and 335 deletions.
2 changes: 1 addition & 1 deletion public/locales/en/exercises.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"access-solution": "Now you can access the solution",
"similar-projects": "Now you can access similar projects",
"open-tutorial": "OPEN TUTORIAL ONLINE",
"open-learnpack": "Open with LearnPack",
"open-learnpack": "OPEN WITH LEARNPACK",
"clone": "CLONE LOCALLY",
"clone-tooltip": "Clone repository",
"how-to-clone": "Read more about cloning a project",
Expand Down
2 changes: 1 addition & 1 deletion public/locales/en/footer.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"copyright": "©{{name}} LLC 2019",
"copyright": "©{{name}} LLC {{year}}",
"search":"Search in 4Geeks",
"subscribe": "Subscribe for more!",
"newsletter": {
Expand Down
2 changes: 1 addition & 1 deletion public/locales/es/exercises.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@
"access-solution": "Ahora puedes acceder a la solucion",
"similar-projects": "Ahora puedes acceder a proyectos similares",
"open-tutorial": "Abrir tutorial online",
"open-learnpack": "Abrir con LearnPack",
"open-learnpack": "ABRIR CON LEARNPACK",
"clone": "Clonar localmente",
"clone-tooltip": "Clonar repositorio",
"how-to-clone": "Leer más sobre cómo clonar un proyecto",
Expand Down
8 changes: 4 additions & 4 deletions scripts/prepare-asset-data.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@ async function prepareAssetData() {

console.time('Time fetching data');

const lessons = await getAsset('LESSON,ARTICLE', { exclude_category: excludeCagetoriesFor.lessons, expand: 'technologies' }, 'lesson');
const excersises = await getAsset('EXERCISE', { expand: 'technologies' }, 'excersise');
const projects = await getAsset('PROJECT', { expand: 'technologies' }, 'project');
const howTos = await getAsset('LESSON,ARTICLE', { category: categoriesFor.howTo, expand: 'technologies' }, 'how-to');
const lessons = await getAsset('LESSON,ARTICLE', { exclude_category: excludeCagetoriesFor.lessons, expand: 'technologies,readme' }, 'lesson');
const excersises = await getAsset('EXERCISE', { expand: 'technologies,readme' }, 'excersise');
const projects = await getAsset('PROJECT', { expand: 'technologies,readme' }, 'project');
const howTos = await getAsset('LESSON,ARTICLE', { category: categoriesFor.howTo, expand: 'technologies,readme' }, 'how-to');
const events = await getEvents();
const landingTechnologies = await getLandingTechnologies([...lessons, ...projects, ...excersises, ...howTos]);

Expand Down
2 changes: 1 addition & 1 deletion src/common/components/AttendanceModal/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -449,7 +449,7 @@ AttendanceModal.defaultProps = {
title: '',
message: '',
isOpen: true,
onClose: () => {},
onClose: () => { },
};

export default AttendanceModal;
30 changes: 3 additions & 27 deletions src/common/components/Footer.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ import AlertMessage from './AlertMessage';
import useStyle from '../hooks/useStyle';
import useAuth from '../hooks/useAuth';
import bc from '../services/breathecode';
import logoData from '../../../public/logo.json';
import { GithubIcon, LogoIcon, YoutubeIcon } from './Icon/components';
import { log } from '../../utils/logging';
import FooterTC from './FooterTC';

function Footer({ pageProps }) {
const captcha = useRef(null);
Expand All @@ -34,14 +34,12 @@ function Footer({ pageProps }) {
const [formStatus, setFormStatus] = useState('');
const { isAuthenticated } = useAuth();

const copyrightName = pageProps?.existsWhiteLabel ? logoData.name : '4Geeks';
const actualYear = new Date().getFullYear();
const iconogram = t('iconogram', {}, { returnObjects: true });

const hideDivider = pageProps?.hideDivider === true;
if (pageProps?.previewMode) return null;

if (isAuthenticated) return <Container as="footer" mt="3rem" />;
if (isAuthenticated) return <FooterTC pageProps={pageProps} />;

return (
<Container background={hexColor.backgroundColor} as="footer" maxW="none" padding="20px" position="absolute" top="100%">
Expand Down Expand Up @@ -345,29 +343,7 @@ function Footer({ pageProps }) {
<Divider borderBottomWidth="2px" />
</>
)}
<Flex
key="copyright"
padding="20px 20px 0 20px"
justifyContent={['center', 'center', 'space-between', 'space-between']}
wrap={['wrap', 'wrap', 'nowrap', 'nowrap']}
// alignItems="center"
textAlign="center"
>
<Text marginBottom={['20px', '20px', '0', '0']} fontSize="sm">{t('copyright', { name: copyrightName, year: actualYear })}</Text>
<Flex
wrap={['wrap', 'wrap', 'nowrap', 'nowrap']}
justifyContent={['center', 'center', 'space-between', 'space-between']}
width={['100%', '100%', '35%', '25%']}
// alignItems="center"
>
<NextChakraLink href={t('terms.href')}>
<Text fontSize="sm">{t('terms.label')}</Text>
</NextChakraLink>
<NextChakraLink href={t('privacy.href')}>
<Text fontSize="sm">{t('privacy.label')}</Text>
</NextChakraLink>
</Flex>
</Flex>
<FooterTC />
</Container>
);
}
Expand Down
63 changes: 63 additions & 0 deletions src/common/components/FooterTC.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import React from 'react';
import {
Container,
Text,
Flex,
Divider,
} from '@chakra-ui/react';
import PropTypes from 'prop-types';
import useTranslation from 'next-translate/useTranslation';
import { useRouter } from 'next/router';
import logoData from '../../../public/logo.json';
import NextChakraLink from './NextChakraLink';
import useAuth from '../hooks/useAuth';

function FooterTC({ pageProps }) {
const { t } = useTranslation('footer');
const { isAuthenticated } = useAuth();
const copyrightName = pageProps?.existsWhiteLabel ? logoData.name : '4Geeks';
const actualYear = new Date().getFullYear();
const router = useRouter();
const noFooterRoutes = ['/cohort/[cohortSlug]/[slug]/[version]', '/syllabus/[cohortSlug]/[lesson]/[lessonSlug]'];

if (noFooterRoutes.includes(router.pathname)) {
return null;
}

return (
<Container as={isAuthenticated && 'footer'} maxW>
<Divider borderBottomWidth="2px" marginTop={isAuthenticated && '50px'} />
<Flex
key="copyright"
padding="20px 20px 5px 20px"
justifyContent={['center', 'center', 'space-between', 'space-between']}
wrap={['wrap', 'wrap', 'nowrap', 'nowrap']}
textAlign="center"
>
<Text marginBottom={['20px', '20px', '0', '0']} fontSize="sm">{t('copyright', { name: copyrightName, year: actualYear })}</Text>
<Flex
wrap={['wrap', 'wrap', 'nowrap', 'nowrap']}
justifyContent={['center', 'center', 'space-between', 'space-between']}
width={['100%', '100%', '35%', '25%']}
>
<NextChakraLink href={t('terms.href')}>
<Text fontSize="sm">{t('terms.label')}</Text>
</NextChakraLink>
<NextChakraLink href={t('privacy.href')}>
<Text fontSize="sm">{t('privacy.label')}</Text>
</NextChakraLink>
</Flex>
</Flex>
</Container>
);
}

FooterTC.propTypes = {
pageProps: PropTypes.oneOfType([PropTypes.func, PropTypes.object]),
};

FooterTC.defaultProps = {
pageProps: {},
};

export default FooterTC;
49 changes: 42 additions & 7 deletions src/common/components/Forms/Signup.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import useTranslation from 'next-translate/useTranslation';
import { useRouter } from 'next/router';
import NextChakraLink from '../NextChakraLink';
import FieldForm from './FieldForm';
import { email as emailRe } from '../../../utils/regex';
import { email as emailRe, phone as phoneRe } from '../../../utils/regex';
import useEmailValidation from './useEmailValidation';
import PhoneInput from '../PhoneInput';
import Text from '../Text';
Expand All @@ -34,6 +34,14 @@ function SignupForm({
}) {
const { userSession } = useSession();
const { t, lang } = useTranslation('signup');
const extraFieldsNames = extraFields.reduce((extra, field) => {
const name = typeof field === 'string' ? field : field.name;
const newValues = { ...extra };
newValues[name] = '';

return newValues;
}, {});

const BREATHECODE_HOST = modifyEnv({ queryString: 'host', env: process.env.BREATHECODE_HOST });
const { emailValidation, thriggerValidation } = useEmailValidation();
const { hexColor, featuredColor } = useStyle();
Expand All @@ -46,6 +54,7 @@ function SignupForm({
phone: '',
email: '',
confirm_email: '',
...extraFieldsNames,
});
const [isChecked, setIsChecked] = useState(false);
const [showAlreadyMember, setShowAlreadyMember] = useState(false);
Expand All @@ -60,6 +69,22 @@ function SignupForm({

const { syllabus } = router.query;

const extraFieldsValidations = extraFields.reduce((extra, field) => {
const isString = typeof field === 'string';
const name = isString ? field : field.name;
let validator = Yup;

if (isString || field.type === 'text' || field.type === 'phone') validator = validator.string();

if (field === 'phone' || field.type === 'phone') validator = validator.matches(phoneRe, field?.error || t('validators.invalid-phone'));

if (isString || field.required) validator = validator.required(field?.error || 'Required');

const validations = { ...extra };
validations[name] = validator;
return validations;
}, {});

// const defaultPlanSlug = planSlug || BASE_PLAN;
const signupValidation = Yup.object().shape({
first_name: Yup.string()
Expand All @@ -73,7 +98,7 @@ function SignupForm({
email: Yup.string()
.matches(emailRe, t('validators.invalid-email'))
.required(t('validators.email-required')),
phone: Yup.string(),
...extraFieldsValidations,
// .matches(phone, t('validators.invalid-phone')),
// confirm_email: Yup.string()
// .oneOf([Yup.ref('email'), null], t('validators.confirm-email-not-match'))
Expand Down Expand Up @@ -229,25 +254,35 @@ function SignupForm({
/>
</Box>
</Box>
{extraFields.includes('phone') && (
{extraFields.map((field) => (field === 'phone' || field?.type === 'phone' ? (
<Box
display="flex"
flex={1}
flexDirection="column"
fontSize="12px"
color="blue.default2"
gridGap="4px"
>
<PhoneInput
inputStyle={{ height: '50px' }}
setVal={setFormProps}
placeholder={t('common:phone')}
formData={formProps}
required={false}
required
{...field}
/>
{t('phone-info')}
</Box>
)}
) : (
<Box display="flex" gridGap="18px" flexDirection={{ base: 'column', md: 'row' }}>
<Box display="flex" flexDirection={{ base: 'column', sm: columnLayout ? 'column' : 'row' }} gridGap="18px" flex={1}>
<FieldForm
type="text"
formProps={formProps}
setFormProps={setFormProps}
{...field}
/>
</Box>
</Box>
)))}
<Box display="flex" flexDirection={{ base: 'column', sm: 'row' }} gridGap="18px">
<Box
display="flex"
Expand Down
10 changes: 9 additions & 1 deletion src/common/components/Instructors.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,18 @@ import { adjustNumberBeetwenMinMax } from '../../utils';
import Heading from './Heading';
import Icon from './Icon';

function orderArrayByRole(array) {
return array.sort((a, b) => {
if (a.role === 'TEACHER') return -1;
if (b.role === 'TEACHER') return 1;
return 0;
});
}

function Instructors({ isLoading, list, limit, ...rest }) {
const { t } = useTranslation('common');
const { featuredColor } = useStyle();
const intructorsToShow = list.length > limit ? list.slice(0, limit) : list;
const intructorsToShow = list.length > limit ? orderArrayByRole(list.slice(0, limit)) : orderArrayByRole(list);
const restInstructors = list.length - limit;

return (
Expand Down
7 changes: 4 additions & 3 deletions src/common/components/LiveEvent/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -233,15 +233,16 @@ function LiveEvent({

useEffect(() => {
let intervalVar;
// applyFilters();
updateTimes();

setTimeout(() => {
const timeoutId = setTimeout(() => {
updateTimes();
intervalVar = setInterval(updateTimes(), 60 * 1000);
intervalVar = setInterval(updateTimes, 60 * 1000);
}, secondsToNextMinute * 1000);

return () => {
clearInterval(intervalVar);
clearTimeout(timeoutId);
};
}, [mainClasses, otherEvents]);

Expand Down
4 changes: 2 additions & 2 deletions src/common/components/MktRecommendedCourses.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -154,9 +154,9 @@ function MktRecommendedCourses({ id, technologies, background, gridColumn, endpo
});
}}
href={course?.course_translation?.landing_url}
programName={course.course_translation.title}
programName={course.course_translation?.title}
programSlug={course.slug}
programDescription={course.course_translation.description}
programDescription={course.course_translation?.description}
// flexShrink="0"
/>
))}
Expand Down
8 changes: 8 additions & 0 deletions src/common/components/ShowOnSignup.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,14 @@ function ShowOnSignUp({
subscribeValues={subscribeValues}
conversionTechnologies={conversionTechnologies}
buttonStyles={{ background: hexColor.greenLight, ...buttonStyles }}
textAlign="left"
extraFields={[{
name: 'phone',
required: true,
type: 'phone',
label: '',
error: t('validators.invalid-phone'),
}]}
onHandleSubmit={(data) => {
onSubmit();
handleSubscribeToPlan({ slug: defaultPlan, accessToken: data?.access_token, disableRedirects: true })
Expand Down
2 changes: 1 addition & 1 deletion src/common/store/actions/signupAction.js
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,7 @@ const useSignup = () => {
value: selectedPlanCheckoutData?.price,
currency,
payment_type: 'Credit card',
plan: selectedPlanCheckoutData?.slug,
plan: selectedPlanCheckoutData?.plan_slug,
period_label: selectedPlanCheckoutData?.period_label,
items: simplePlans,
},
Expand Down
1 change: 0 additions & 1 deletion src/js_modules/checkout/ContactInformation.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ function ContactInformation({
showVerifyEmail={false}
courseChoosed={courseChoosed}
extraFields={['phone']}
// maxWidth="490px"
maxWidth={{ base: 'auto', lg: '490px' }}
onHandleSubmit={(data) => {
setVerifyEmailProps({
Expand Down
1 change: 1 addition & 0 deletions src/pages/checkout/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,7 @@ function Checkout() {
reportDatalayer({
dataLayer: {
event: 'begin_checkout',
plan: defaultPlan,
path: '/checkout',
conversion_info: userSession,
},
Expand Down
11 changes: 0 additions & 11 deletions src/pages/cohort/[cohortSlug]/[slug]/[version]/index.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ import {
includesToLowerCase,
getStorageItem,
sortToNearestTodayDate,
syncInterval,
getBrowserSize,
calculateDifferenceDays,
adjustNumberBeetwenMinMax,
Expand Down Expand Up @@ -266,16 +265,6 @@ function Dashboard() {
},
});
});
syncInterval(() => {
setLiveClasses((prev) => {
const validatedEventList = prev?.length > 0
? prev?.filter((l) => isValidDate(l?.starting_at) && isValidDate(l?.ending_at))
: [];
const sortDateToLiveClass = sortToNearestTodayDate(validatedEventList, TwelveHours);
const existentLiveClasses = sortDateToLiveClass?.filter((l) => l?.hash && l?.starting_at && l?.ending_at);
return existentLiveClasses;
});
});
}, []);

// Fetch cohort data with pathName structure
Expand Down
Loading

0 comments on commit f9c2ad9

Please sign in to comment.