Skip to content

Commit

Permalink
Merge pull request #1901 from breatheco-de/development
Browse files Browse the repository at this point in the history
Development
  • Loading branch information
tommygonzaleza authored Feb 27, 2025
2 parents 665f075 + bf222c6 commit 75491ac
Show file tree
Hide file tree
Showing 8 changed files with 345 additions and 3 deletions.
2 changes: 2 additions & 0 deletions public/locales/en/common.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
{
"change-language": "Change language",
"reviews": "Ratings",
"course-rating": "Course rating",
"connect-with-github": "Connect with Github",
"see-financing-options": "See financing options",
"your-tutors-in-this-cohort": "Your tutors:",
Expand Down
86 changes: 86 additions & 0 deletions public/locales/en/course.json
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,92 @@
"message": "Is there anything you want to know about the {{title}} program?",
"payment-methods": "- Credit Card. - Contact support for other options"
},
"reviews": {
"full-stack-development": {
"rating": 4.5,
"total_ratings": 1621,
"reviews_numbers": 345,
"reviews": [
{
"name": "Felipe Cespedes",
"avatar": "https://breathecode.herokuapp.com/v1/media/file/felipe-profile-picture-jpg",
"rating": 5,
"date": "1 week ago",
"review": "This course is very flexible and allowed me to learn while doing other things in my life!"
},
{
"name": "Rubi Rimache",
"avatar": "https://breathecode.herokuapp.com/v1/media/file/ruby-profile-picture-jpg",
"rating": 5,
"date": "2 weeks ago",
"review": "I love the program, it's very good and comfortable! I would recommend it for its comfort and the clarity with which things are explained."
},
{
"name": "Brian Hernandes ",
"avatar": "https://example.com/avatar3.jpg",
"rating": 4,
"date": "1 week ago",
"review": "Amazing content and structure. The AI tool is wonderful!"
}
]
},
"deep-dive-into-python": {
"rating": 4.5,
"total_ratings": 1346,
"reviews_numbers": 134,
"reviews": [
{
"name": "Felipe Cespedes",
"avatar": "https://breathecode.herokuapp.com/v1/media/file/felipe-profile-picture-jpg",
"rating": 5,
"date": "1 week ago",
"review": "This course is very flexible and allowed me to learn while doing other things in my life!"
},
{
"name": "Rubi Rimache",
"avatar": "https://breathecode.herokuapp.com/v1/media/file/ruby-profile-picture-jpg",
"rating": 5,
"date": "2 weeks ago",
"review": "I love the program, it's very good and comfortable! I would recommend it for its comfort and the clarity with which things are explained."
},
{
"name": "Brian Hernandes ",
"avatar": "https://example.com/avatar3.jpg",
"rating": 4,
"date": "1 week ago",
"review": "Amazing content and structure. The AI tool is wonderful!"
}
]
},
"data-science-and-ml": {
"rating": 4.5,
"total_ratings": 803,
"reviews_numbers": 98,
"reviews": [
{
"name": "Felipe Cespedes",
"avatar": "https://breathecode.herokuapp.com/v1/media/file/felipe-profile-picture-jpg",
"rating": 5,
"date": "1 week ago",
"review": "This course is very flexible and allowed me to learn while doing other things in my life!"
},
{
"name": "Rubi Rimache",
"avatar": "https://breathecode.herokuapp.com/v1/media/file/ruby-profile-picture-jpg",
"rating": 5,
"date": "2 weeks ago",
"review": "I love the program, it's very good and comfortable! I would recommend it for its comfort and the clarity with which things are explained."
},
{
"name": "Brian Hernandes ",
"avatar": "https://example.com/avatar3.jpg",
"rating": 4,
"date": "1 week ago",
"review": "Amazing content and structure. The AI tool is wonderful!"
}
]
}
},
"featured-bullets": [
{
"title": "Get help from our internally trained AI as you learn to code."
Expand Down
2 changes: 2 additions & 0 deletions public/locales/es/common.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
{
"change-language": "Cambiar idioma",
"reviews": "Reseñas",
"course-rating": "Calificación del curso",
"connect-with-github": "Conéctate con Github",
"see-financing-options": "Ver opciones de financiamiento",
"your-tutors-in-this-cohort": "Tus tutores:",
Expand Down
86 changes: 86 additions & 0 deletions public/locales/es/course.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,92 @@
"message": "¿Hay algo que quieras saber sobre el programa {{title}}?",
"payment-methods": "- Tarjeta de crédito. - Contacta a soporte para mas opciones"
},
"reviews": {
"full-stack-development": {
"rating": 4.5,
"total_ratings": 1621,
"reviews_numbers": 345,
"reviews": [
{
"name": "Felipe Cespedes",
"avatar": "https://breathecode.herokuapp.com/v1/media/file/felipe-profile-picture-jpg",
"rating": 5,
"date": "hace 1 semana",
"review": "Este curso es muy flexible y me permitió aprender mientras hacía otras cosas en mi vida."
},
{
"name": "Rubi Rimache",
"avatar": "https://breathecode.herokuapp.com/v1/media/file/ruby-profile-picture-jpg",
"rating": 5,
"date": "hace 2 semanas",
"review": "Me encanta el programa, es muy bueno y cómodo. Lo recomendaría por su comodidad y la claridad con la que se explican las cosas."
},
{
"name": "Brian Hernandes",
"avatar": "https://example.com/avatar3.jpg",
"rating": 4,
"date": "hace 1 semana",
"review": "Contenido y estructura increíbles. ¡La herramienta de IA es maravillosa!"
}
]
},
"deep-dive-into-python": {
"rating": 4.5,
"total_ratings": 1346,
"reviews_numbers": 134,
"reviews": [
{
"name": "Felipe Cespedes",
"avatar": "https://breathecode.herokuapp.com/v1/media/file/felipe-profile-picture-jpg",
"rating": 5,
"date": "hace 1 semana",
"review": "Este curso es muy flexible y me permitió aprender mientras hacía otras cosas en mi vida."
},
{
"name": "Rubi Rimache",
"avatar": "https://breathecode.herokuapp.com/v1/media/file/ruby-profile-picture-jpg",
"rating": 5,
"date": "hace 2 semanas",
"review": "Me encanta el programa, es muy bueno y cómodo. Lo recomendaría por su comodidad y la claridad con la que se explican las cosas."
},
{
"name": "Brian Hernandes",
"avatar": "https://example.com/avatar3.jpg",
"rating": 4,
"date": "hace 1 semana",
"review": "Contenido y estructura increíbles. ¡La herramienta de IA es maravillosa!"
}
]
},
"data-science-and-ml": {
"rating": 4.5,
"total_ratings": 803,
"reviews_numbers": 98,
"reviews": [
{
"name": "Felipe Cespedes",
"avatar": "https://breathecode.herokuapp.com/v1/media/file/felipe-profile-picture-jpg",
"rating": 5,
"date": "hace 1 semana",
"review": "Este curso es muy flexible y me permitió aprender mientras hacía otras cosas en mi vida."
},
{
"name": "Rubi Rimache",
"avatar": "https://breathecode.herokuapp.com/v1/media/file/ruby-profile-picture-jpg",
"rating": 5,
"date": "hace 2 semanas",
"review": "Me encanta el programa, es muy bueno y cómodo. Lo recomendaría por su comodidad y la claridad con la que se explican las cosas."
},
{
"name": "Brian Hernandes",
"avatar": "https://example.com/avatar3.jpg",
"rating": 4,
"date": "hace 1 semana",
"review": "Contenido y estructura increíbles. ¡La herramienta de IA es maravillosa!"
}
]
}
},
"featured-bullets": [
{
"title": "Obtén ayuda de nuestra IA entrenada internamente mientras aprendes a programar."
Expand Down
2 changes: 1 addition & 1 deletion src/common/components/CustomCarousel.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ function CustomCarousel({ assignmentList }) {

<Flex flex="1" flexDirection="column" gridGap="10px" justifyContent="space-between">
<Flex gridGap="8px" justifyContent="space-between" alignItems="flex-start">
<Flex gap="10px">
<Flex gap="10px" flexWrap="wrap">
{assignmentList[currentSlide].technologies.map((tech) => (
<Box>
{tech.icon_url ? (
Expand Down
19 changes: 17 additions & 2 deletions src/common/components/Icon/set/star.jsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,33 @@
const star = ({
style, width, height, color,
style, width, height, color, secondColor, fill,
}) => (
<svg
style={style}
width={width || '20px'}
height={height || '20px'}
viewBox="0 0 24 24"
viewBox="0 0 20 20"
fill={color || '#007BFF'}
xmlns="http://www.w3.org/2000/svg"
>
<defs>
<clipPath id="halfStar">
<rect width="50%" height="100%" />
</clipPath>
</defs>

<path
d="M9.12885 0.545575C9.51136 -0.133069 10.4886 -0.13307 10.8712 0.545575L13.2667 4.79573C13.4094 5.04891 13.6552 5.22748 13.9401 5.28496L18.7225 6.24991C19.4861 6.40399 19.7881 7.33343 19.2609 7.90693L15.959 11.4986C15.7623 11.7126 15.6685 12.0015 15.7018 12.2902L16.2619 17.1367C16.3514 17.9106 15.5608 18.485 14.8524 18.1608L10.4162 16.1305C10.1519 16.0095 9.8481 16.0095 9.58384 16.1305L5.1476 18.1608C4.43925 18.485 3.64861 17.9106 3.73805 17.1367L4.29818 12.2902C4.33155 12.0015 4.23766 11.7126 4.04098 11.4986L0.739107 7.90693C0.211881 7.33343 0.513875 6.40399 1.27751 6.24991L6.05992 5.28496C6.3448 5.22748 6.59058 5.04891 6.73328 4.79573L9.12885 0.545575Z"
fill={color || '#007BFF'}
stroke={secondColor}
/>

{fill === 'half' && (
<path
d="M9.12885 0.545575C9.51136 -0.133069 10.4886 -0.13307 10.8712 0.545575L13.2667 4.79573C13.4094 5.04891 13.6552 5.22748 13.9401 5.28496L18.7225 6.24991C19.4861 6.40399 19.7881 7.33343 19.2609 7.90693L15.959 11.4986C15.7623 11.7126 15.6685 12.0015 15.7018 12.2902L16.2619 17.1367C16.3514 17.9106 15.5608 18.485 14.8524 18.1608L10.4162 16.1305C10.1519 16.0095 9.8481 16.0095 9.58384 16.1305L5.1476 18.1608C4.43925 18.485 3.64861 17.9106 3.73805 17.1367L4.29818 12.2902C4.33155 12.0015 4.23766 11.7126 4.04098 11.4986L0.739107 7.90693C0.211881 7.33343 0.513875 6.40399 1.27751 6.24991L6.05992 5.28496C6.3448 5.22748 6.59058 5.04891 6.73328 4.79573L9.12885 0.545575Z"
fill={secondColor || '#FFB718'}
clipPath="url(#halfStar)"
/>
)}
</svg>
);

Expand Down
132 changes: 132 additions & 0 deletions src/common/components/Rating.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
import PropTypes from 'prop-types';
import { Flex, Text, Box, Avatar, SimpleGrid } from '@chakra-ui/react';
import useTranslation from 'next-translate/useTranslation';
import { useRouter } from 'next/router';
import useStyle from '../hooks/useStyle';
import Icon from './Icon';

function CommentCard({ review, ...rest }) {
const { backgroundColor, fontColor, borderColor, lightColor } = useStyle();
const roundedRating = Math.round(review.rating) || 0;

return (
<Flex
direction="column"
border="1px solid"
borderColor={borderColor}
borderRadius="md"
p="16px"
bg={backgroundColor}
gap="10px"
{...rest}
>
{/* Avatar y Nombre */}
<Flex alignItems="center" gap="10px">
<Avatar src={review.avatar} name={review.name} size="sm" />
<Box>
<Text fontWeight="bold" fontColor={fontColor}>{review.name}</Text>
<Flex gap="10px" alignItems="center">
<Flex gap="4px">
{Array.from({ length: 5 }).map((_, index) => (
index + 1 <= roundedRating ? (
<Icon icon="star" color="#FFB718" width="12px" />
) : (
<Icon icon="star" color="#FFFFFF" secondColor="#FFB718" width="12px" />
)
))}
</Flex>
<Text fontSize="12px" color="gray.500">{review.date}</Text>
</Flex>
</Box>
</Flex>

<Text fontSize="14px" color={lightColor} mt="8px">
{review.review}
</Text>
</Flex>
);
}
function Rating({ variant, totalRatings, totalReviews, rating, reviews, link, ...rest }) {
const { t } = useTranslation('common');
const router = useRouter();
const roundedRating = Math.round(rating) || 0;

if (variant === 'inline') {
return (
<Flex alignItems="center" gap="8px" {...rest}>
{(rating > 0 && roundedRating > 0) && (
<>
<Text fontSize="14px">{rating}</Text>
<Flex gap="4px">
{Array.from({ length: 5 }).map((_, index) => {
const isFullStar = index + 1 <= Math.floor(rating);
const isHalfStar = index === Math.floor(rating) && rating % 1 >= 0.5;

return (
<Icon
icon="star"
color={isFullStar ? '#FFB718' : '#ffffff'}
secondColor="#FFB718"
width="18px"
fill={isHalfStar ? 'half' : undefined}
/>
);
})}
</Flex>
</>
)}

{totalRatings > 0 && (
<Text onClick={() => router.push(link)} color="blue.default" textDecor="underline" fontWeight="bold" fontSize="14px" cursor="pointer">
{`(${totalRatings} ${t('common:reviews')})`}
</Text>
)}
</Flex>
);
}

return (
<>
{reviews?.length > 0 && (
<Flex direction="column" {...rest}>
<Flex alignItems="center" gap="14px">
<Icon icon="star" color="#FFB718" width="18px" />
<Text fontSize="24px">{`${rating > 0 && rating} ${t('course-rating')} ${totalReviews > 0 && `- ${totalReviews} ${t('comments')}`}`}</Text>
</Flex>
<SimpleGrid
columns={{ base: 1, md: 2, lg: 3 }}
spacing="16px"
marginTop="22px"
>
{reviews.map((review) => (
<CommentCard review={review} />
))}
</SimpleGrid>
</Flex>
)}
</>
);
}

Rating.propTypes = {
variant: PropTypes.string,
totalRatings: PropTypes.string,
totalReviews: PropTypes.string,
rating: PropTypes.string,
reviews: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.string, PropTypes.object])),
link: PropTypes.string,
};

CommentCard.propTypes = {
review: PropTypes.string.isRequired,
};

Rating.defaultProps = {
variant: null,
link: null,
totalRatings: 0,
totalReviews: 0,
rating: 0,
reviews: [],
};
export default Rating;
Loading

0 comments on commit 75491ac

Please sign in to comment.