Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

560-refactor: Widget principles #636

Merged
merged 10 commits into from
Nov 13, 2024
1 change: 1 addition & 0 deletions dev-data/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ export { mentorshipCourses, mentorshipCoursesDefault } from './mentorship.data';
export { nodejs } from './nodejs.data';
export { picturesSocialMediaLinks } from './pictures.data';
export { preSchoolEn, preSchoolRu } from './preSchool.data';
export { principleCards } from './principle-cards.data.tsx';
export { reactEn } from './react-en.data';
export { reactRu } from './react-ru.data';
export { requirementsData } from './requirements.data';
Expand Down
Original file line number Diff line number Diff line change
@@ -1,23 +1,26 @@
import { PrincipleCardProps } from './ui/principle-card/principle-card';
import { OpenSourcePhilosophyIcon, OpenToEveryoneIcon, TeachItForwardIcon } from '@/shared/icons';
import Image from 'next/image';
import openSourcePhilosophyIcon from '@/shared/assets/svg/openSourcePhilosophyIcon.svg';
import openToEveryoneIcon from '@/shared/assets/svg/openToEveryoneIcon.svg';
import teachItForwardIcon from '@/shared/assets/svg/teachItForwardIcon.svg';
import { PrincipleCard } from '@/widgets/principles';

export const cards: PrincipleCardProps[] = [
export const principleCards: PrincipleCard[] = [
{
title: 'Open to everyone',
description:
'Free courses, no obligations, and no contracts. No age limit. Only students’ time and dedication are required. Students can repeatedly attend courses.',
icon: <OpenToEveryoneIcon />,
icon: <Image src={openToEveryoneIcon} alt="" aria-hidden="true" />,
},
{
title: 'Open source philosophy',
description:
'Our Learning Management System platform and educational materials are publicly available on GitHub and YouTube.',
icon: <OpenSourcePhilosophyIcon />,
icon: <Image src={openSourcePhilosophyIcon} alt="" aria-hidden="true" />,
},
{
title: '"Teach it forward"',
description:
'Students study at school for free, but we request that they return as mentors to pass on their knowledge to the next generation of students.',
icon: <TeachItForwardIcon />,
icon: <Image src={teachItForwardIcon} alt="" aria-hidden="true" />,
},
];
3 changes: 0 additions & 3 deletions src/shared/icons/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,7 @@ export { JavascriptIcon } from './javascript-icon';
export { JetBrainsLogo } from './jetbrains';
export { LinkedInIcon } from './linkedIn';
export { NodeJsIcon } from './nodejs-icon';
export { OpenSourcePhilosophyIcon } from './open-source-philosophy-icon';
export { OpenToEveryoneIcon } from './open-to-everyone-icon';
export { ReactIcon } from './react-icon';
export { TeachItForwardIcon } from './teach-It-forward-icon';
export { TelegramIcon } from './telegram';
export { TextLinkIcon } from './text-link-icon';
export { YouTubeIcon } from './youtube';
6 changes: 0 additions & 6 deletions src/shared/icons/open-source-philosophy-icon.tsx

This file was deleted.

6 changes: 0 additions & 6 deletions src/shared/icons/open-to-everyone-icon.tsx

This file was deleted.

6 changes: 0 additions & 6 deletions src/shared/icons/teach-It-forward-icon.tsx

This file was deleted.

3 changes: 2 additions & 1 deletion src/widgets/principles/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export { Principles } from './ui/principle-card/principles';
export type { PrincipleCard } from './types.ts';
export { Principles } from './ui/principles/principles';
7 changes: 7 additions & 0 deletions src/widgets/principles/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import { ReactNode } from 'react';

export type PrincipleCard = {
title: string;
description: string;
icon: ReactNode;
};
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
.principle-card {
@extend %transition-all;

cursor: default;

position: relative;

overflow: hidden;
display: flex;
flex-flow: column nowrap;
place-content: center flex-start;
align-items: flex-start;
display: grid;
grid-template-columns: max-content 1fr;
column-gap: 16px;

width: 100%;
padding: 24px;
Expand All @@ -20,7 +17,23 @@
border: 1px solid rgb(255 219 32 / 8%);
border-radius: 12px;

& .card-header {
&::after {
content: '';

position: absolute;
z-index: 1;
right: -160px;
bottom: -150px;

width: 310px;
height: 300px;

background-color: rgb(255 219 32 / 20%);
filter: blur(32px);
border-radius: 100%;
}

.card-header {
display: flex;
gap: 16px;
align-items: center;
Expand All @@ -33,43 +46,44 @@
}
}

& .icon-wrapper {
position: relative;
display: flex;
align-items: center;
justify-content: center;
}
.card-description {
z-index: 2;

grid-column: span 2;

& .card-description {
font-size: 18px;
font-weight: $font-weight-regular;
line-height: 1.4;
text-align: left;
letter-spacing: 0;
}

span > img {
width: 44px;
height: 44px;
}
.icon {
display: flex;
justify-content: center;

& .accent {
position: absolute;
z-index: 1;
img {
position: relative;
width: 44px;
height: 44px;
}

display: block;
flex-shrink: 0;
align-self: flex-start;
&::before {
content: '';

width: 20px;
height: 19px;
position: absolute;
z-index: 1;

background-color: rgba($color-yellow, $opacity-80);
filter: blur(8px);
border-radius: 100%;
width: 20px;
height: 20px;

background-color: rgba($color-yellow, $opacity-80);
filter: blur(8px);
border-radius: 100%;
}
}

& .card-title {
.card-title {
align-self: flex-start;

max-width: 265px;
Expand All @@ -96,26 +110,9 @@
width: 100%;
padding: 32px 24px;

& .card-description {
.card-description {
font-size: 16px;
line-height: 24px;
}
}
}

.accent-corner {
position: absolute;
z-index: 1;
right: -160px;
bottom: -150px;

display: block;
flex-shrink: 0;

width: 310px;
height: 300px;

background-color: rgb(255 219 32 / 20%);
filter: blur(32px);
border-radius: 100%;
}
31 changes: 12 additions & 19 deletions src/widgets/principles/ui/principle-card/principle-card.tsx
Original file line number Diff line number Diff line change
@@ -1,23 +1,16 @@
import { ReactNode } from 'react';
import classnames from 'classnames/bind';
import { Paragraph } from '@/shared/ui/paragraph';
import { WidgetTitle } from '@/shared/ui/widget-title';
import type { PrincipleCard as TPrincipleCard } from '@/widgets/principles';

import './principle-card.scss';
import styles from './principle-card.module.scss';

export interface PrincipleCardProps {
title: string;
description: string;
icon: ReactNode;
}
const cx = classnames.bind(styles);

export const PrincipleCard = ({ title, description, icon }: PrincipleCardProps) => (
<div className="principle-card">
<div className="card-header">
<div className="icon-wrapper">
<div className="accent" />
<span>{icon}</span>
</div>
<div className="card-title">{title}</div>
</div>
<div className="card-description">{description}</div>
<div className="accent-corner" />
</div>
export const PrincipleCard = ({ title, description, icon }: TPrincipleCard) => (
<article className={cx('principle-card')} data-testid="principle-card">
<span className={cx('icon')}>{icon}</span>
<WidgetTitle className={cx('card-title')}>{title}</WidgetTitle>
<Paragraph className={cx('card-description')}>{description}</Paragraph>
</article>
);
18 changes: 0 additions & 18 deletions src/widgets/principles/ui/principle-card/principles.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,17 +1,5 @@
.principles {
&.content {
padding: 20px 120px 40px;

@include media-laptop {
padding: 20px 40px 40px;
}

@include media-tablet {
padding: 20px 16px 40px;
}
}

& .cards {
.cards {
gap: 32px;
align-items: stretch;
margin-top: 24px;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import { render, screen } from '@testing-library/react';
import { beforeEach, describe, expect, it } from 'vitest';
import { cards } from './constants';

import { Principles } from './ui/principle-card/principles';
import { Principles } from '@/widgets/principles';
import { principleCards } from 'data';

describe('Principles', () => {
beforeEach(() => {
Expand All @@ -18,7 +17,7 @@ describe('Principles', () => {
});

it('renders PrincipleCards correctly', () => {
cards.forEach(({ title, description }) => {
principleCards.forEach(({ title, description }) => {
const titleElement = screen.getByText(title);
const descriptionElement = screen.getByText(description);

Expand All @@ -28,8 +27,8 @@ describe('Principles', () => {
});

it('renders the correct number of PrincipleCards', () => {
const principleCards = document.getElementsByClassName('principle-card');
const principleCards = screen.getAllByTestId('principle-card');

expect(principleCards).toHaveLength(cards.length);
expect(principleCards).toHaveLength(principleCards.length);
});
});
23 changes: 23 additions & 0 deletions src/widgets/principles/ui/principles/principles.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import classnames from 'classnames/bind';
import { WidgetTitle } from '@/shared/ui/widget-title';
import { PrincipleCard } from '@/widgets/principles/ui/principle-card/principle-card.tsx';
import { principleCards } from 'data';

import styles from './principles.module.scss';

const cx = classnames.bind(styles);

export const Principles = () => (
<section className={cx('principles', 'container')}>
<div className={cx('principles', 'content')}>
<WidgetTitle size="large" mods="lines">
RS School Principles are an ability to complete our mission
</WidgetTitle>
<div className={cx('column-3', 'cards')}>
{principleCards.map(({ title, description, icon }) => (
<PrincipleCard key={title} description={description} icon={icon} title={title} />
))}
</div>
</div>
</section>
);
Loading