Skip to content

Commit

Permalink
Redesign course card
Browse files Browse the repository at this point in the history
  • Loading branch information
xjahic committed Jul 16, 2023
1 parent 771b05f commit 9ee0760
Show file tree
Hide file tree
Showing 6 changed files with 119 additions and 54 deletions.
2 changes: 2 additions & 0 deletions src/components/CircullarProgressWithLabel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Text from '../components/core/Text'
import styled from 'styled-components'

type Props = {
className?: string
value: number
// width and height (i.e: 50px)
size?: string
Expand All @@ -26,6 +27,7 @@ const CircullarProgressWithLabel = ({
sx={{position: 'relative', display: 'inline-flex'}}
size={size || '50px'}
accentColor={accentColor}
className={props.className}
>
<StyledCircullarProgress variant="determinate" value={value} {...props} />
<Box
Expand Down
5 changes: 5 additions & 0 deletions src/components/core/Heading.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type Props = {
withAccentUnderline?: boolean
noWrap?: boolean
maxWidth?: string
uppercase?: boolean
} & HTMLAttributes<HTMLElement>

type Variant = 'h1' | 'h2' | 'h3' | 'h4' | 'h5' | 'h6'
Expand All @@ -29,6 +30,7 @@ const Heading = ({
withAccentUnderline,
noWrap,
maxWidth,
uppercase,
...props
}: Props) => {
const headingProps: Props = {
Expand All @@ -41,6 +43,7 @@ const Heading = ({
withAccentUnderline,
noWrap,
maxWidth,
uppercase,
}

if (variant === 'h1') {
Expand Down Expand Up @@ -134,6 +137,7 @@ const headingStyle = css<{
withAccentUnderline?: boolean
noWrap?: boolean
maxWidth?: string
uppercase?: boolean
}>`
display: ${(props) => (props.inline ? 'inline' : 'block')};
Expand All @@ -145,6 +149,7 @@ const headingStyle = css<{
props.withAccentUnderline ? `4px solid var(--color-accent)` : 'unset'};
white-space: ${(props) => (props.noWrap ? 'nowrap' : 'unset')};
max-width: ${(props) => props.maxWidth && props.maxWidth};
text-transform: ${(props) => (props.uppercase ? 'uppercase' : 'unset')};
@media ${device.XL} {
font-size: ${(props) =>
Expand Down
160 changes: 106 additions & 54 deletions src/components/domain/course/CourseCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -57,12 +57,31 @@ const CourseCard = ({
justifyContent="space-between"
className={className}
>
<Flex justifyContent="space-between" alignSelf="stretch">
<PriceTag>
<Text uppercase weight="bold" color="primary">
ZADARMO
</Text>
</PriceTag>
<RatingDesktopWrapper
readOnly
value={course.reviewsOverview.averageRating}
customSize="28px"
/>
<RatingMobileWrapper
readOnly
value={course.reviewsOverview.averageRating}
customSize="22px"
/>
</Flex>
<Flex direction="column" gap="24px">
<Flex direction="column" gap="8px">
<Heading variant="h5" align="center" normalWeight>
<Heading variant="h5" align="center" color="accent" uppercase>
{course.name}
</Heading>
<Text align="center">{course.shortDescription}</Text>
<Text align="center" size="small">
{course.shortDescription}
</Text>
</Flex>
<Flex direction="column" gap="12px">
<CourseIconImageWrapper>
Expand All @@ -73,7 +92,6 @@ const CourseCard = ({
priority
/>
</CourseIconImageWrapper>
<Rating readOnly value={course.reviewsOverview.averageRating} />
</Flex>
</Flex>

Expand All @@ -86,93 +104,121 @@ const CourseCard = ({
>
<CourseInfoItem>
<DifficultyIcon difficultyLevel={course.difficulty.skillLevel} />
<Text size="small">{course.difficulty?.name}</Text>
<Text size="very-small">{course.difficulty?.name}</Text>
</CourseInfoItem>
<CourseInfoItem>
<AiOutlineClockCircle />
<Text size="small">{courseDuration}</Text>
<Text size="very-small">{courseDuration}</Text>
</CourseInfoItem>
</CourseInfoItemsWrapper>
<CourseInfoItemsWrapper
direction="column"
alignItems="flex-start"
alignSelf="flex-start"
gap="12px"
>
<CourseInfoItem>
<AiOutlineVideoCamera />
<Text size="small">
<Text size="very-small">
{lecturesCount} {numOfLecturesText(lecturesCount)}
</Text>
</CourseInfoItem>
{quizzesCount > 0 && (
<CourseInfoItem>
<AiOutlineQuestionCircle />
<Text size="small">
<Text size="very-small">
{quizzesCount} {numOfQuizzesText(quizzesCount)}
</Text>
</CourseInfoItem>
)}
</CourseInfoItemsWrapper>
<Flex
direction="column"
alignItems="flex-end"
justifyContent="space-between"
alignSelf="stretch"
gap="12px"
>
<CourseInfoItem>
<Avatar
altName={course.author?.name}
src={course.author?.imageUrl}
sizePx={25}
/>
<Text size="small">{course.author?.name}</Text>
</CourseInfoItem>
{progressValuePercent && (
<CircullarProgressWithLabel
value={progressValuePercent}
accentColor
/>
)}
{!progressValuePercent && (
<Text uppercase color="accent" weight="bold">
zadarmo
</Text>
)}
</Flex>
</Flex>
<Flex
direction="column"
alignItems="center"
justifyContent="space-between"
alignSelf="stretch"
gap="12px"
>
<CourseInfoItem authorItem>
<Avatar
altName={course.author?.name}
src={course.author?.imageUrl}
sizePx={25}
/>
<Text size="very-small">{course.author?.name}</Text>
</CourseInfoItem>
{progressValuePercent && (
<ProgressWrapper value={progressValuePercent} accentColor />
)}
</Flex>
</WrapperFlex>
)
}

const PriceTag = styled.div`
padding: 4px 12px;
border-top-right-radius: 16px;
border-bottom-right-radius: 16px;
background-color: var(--color-accent);
margin-left: -28px;
@media ${device.S} {
margin-left: -22px;
}
`
const RatingDesktopWrapper = styled(Rating)`
display: inline-flex;
@media ${device.S} {
display: none;
}
`

const RatingMobileWrapper = styled(Rating)`
display: none;
@media ${device.S} {
display: inline-flex;
}
`

const WrapperFlex = styled(Flex)`
width: 300px;
aspect-ratio: 1 / 1.5;
aspect-ratio: 1 / 1.55;
padding: 1em 0.5em;
border: var(--color-accent) 2px solid;
border-radius: 22px;
padding: 32px 24px;
border-right: var(--color-accent) 4px solid;
border-left: var(--color-accent) 4px solid;
box-shadow: 0px 2px 2px var(--color-shadow), 0px -2px 2px var(--color-shadow);
border-radius: 16px;
transition: 250ms ease-in-out;
&:hover {
transform: scale(1.1);
transform: scale(1.05);
transition: 250ms ease-in-out;
box-shadow: 1px 8px 20px var(--color-shadow);
box-shadow: 0px 4px 10px var(--color-shadow),
0px -4px 10px var(--color-shadow);
}
@media ${device.S} {
width: 250px;
aspect-ratio: 1 / 1.6;
&:hover {
transform: unset;
transition: unset;
box-shadow: unset;
}
padding: 26px 18px;
aspect-ratio: 1 / 1.65;
}
`

const ProgressWrapper = styled(CircullarProgressWithLabel)`
margin-top: 4px;
`

const CourseIconImageWrapper = styled.div`
position: relative;
width: 100px;
width: 80px;
aspect-ratio: 1;
@media ${device.S} {
width: 75px;
width: 60px;
}
`

Expand All @@ -182,15 +228,21 @@ const CourseInfoItemsWrapper = styled(Flex)`
}
`

const CourseInfoItem = styled.div`
const CourseInfoItem = styled.div<{authorItem?: boolean}>`
display: flex;
gap: 12px;
gap: 8px;
align-items: center;
* {
color: ${(props) =>
props.authorItem
? 'var(--color-secondary)'
: 'var(--color-course-info-icon)'};
}
svg {
width: 25px;
height: 25px;
color: var(--color-secondary);
width: 28px;
height: 28px;
}
`

Expand Down
1 change: 1 addition & 0 deletions src/hooks/useTheme.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ const updateCSSThemeVariables = (theme: ThemeType) => {
theme.footerBackgroundColor,
)
root.style.setProperty('--color-shadow', theme.shadowColor)
root.style.setProperty('--color-course-info-icon', theme.courseInfoIconColor)
}

const determineTheme = (
Expand Down
2 changes: 2 additions & 0 deletions src/pages/_document.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,7 @@ export default class MyDocument extends Document {
root.style.setProperty('--color-success', '#4CBF6B')
root.style.setProperty('--color-footer-background', '#212121')
root.style.setProperty('--color-shadow', 'rgba(0,0,0,0.2)')
root.style.setProperty('--color-course-info-icon', '#58595B')
} else {
root.style.setProperty('--initial-theme-type', theme)
root.style.setProperty('--color-primary', '#212121')
Expand All @@ -106,6 +107,7 @@ export default class MyDocument extends Document {
root.style.setProperty('--color-success', '#4CBF6B')
root.style.setProperty('--color-footer-background', '#efefef')
root.style.setProperty('--color-shadow', 'rgba(255,255,255,0.2)')
root.style.setProperty('--color-course-info-icon', '#BCBEC0')
}
})()
`
Expand Down
3 changes: 3 additions & 0 deletions src/theme/theme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export type ThemeType = {
successColor: string // i.e correct quiz question
footerBackgroundColor: string
shadowColor: string
courseInfoIconColor: string
}

export const lightTheme: ThemeType = {
Expand All @@ -24,6 +25,7 @@ export const lightTheme: ThemeType = {
successColor: '#4CBF6B',
footerBackgroundColor: '#212121',
shadowColor: 'rgba(0,0,0,0.2)',
courseInfoIconColor: '#58595B',
}

export const darkTheme: ThemeType = {
Expand All @@ -36,4 +38,5 @@ export const darkTheme: ThemeType = {
successColor: '#4CBF6B',
footerBackgroundColor: '#efefef',
shadowColor: 'rgba(255,255,255,0.2)',
courseInfoIconColor: '#BCBEC0',
}

0 comments on commit 9ee0760

Please sign in to comment.