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

473-fix: Fsd refactor trainers card #492

Merged
merged 8 commits into from
Sep 12, 2024
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 dev-data/angular.data.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import type { Trainer } from '@/entities/trainer';
import aSacca from '@/shared/assets/mentors/a-sacca.webp';

Check warning on line 2 in dev-data/angular.data.ts

View workflow job for this annotation

GitHub Actions / CI

Reaching to "@/shared/assets/mentors/a-sacca.webp" is not allowed
import aSerhiyenia from '@/shared/assets/mentors/a-serhiyenia.webp';

Check warning on line 3 in dev-data/angular.data.ts

View workflow job for this annotation

GitHub Actions / CI

Reaching to "@/shared/assets/mentors/a-serhiyenia.webp" is not allowed
import dKohut from '@/shared/assets/mentors/d-kohut.webp';

Check warning on line 4 in dev-data/angular.data.ts

View workflow job for this annotation

GitHub Actions / CI

Reaching to "@/shared/assets/mentors/d-kohut.webp" is not allowed
import kBritsyn from '@/shared/assets/mentors/k-britsyn.webp';

Check warning on line 5 in dev-data/angular.data.ts

View workflow job for this annotation

GitHub Actions / CI

Reaching to "@/shared/assets/mentors/k-britsyn.webp" is not allowed
import nLoginova from '@/shared/assets/mentors/n-loginova.webp';
import oDuleba from '@/shared/assets/mentors/o-duleba.webp';
import rSaltykov from '@/shared/assets/mentors/r-saltykov.webp';
import type { Trainer } from 'data';

export const angular: Trainer[] = [
{
Expand Down
2 changes: 1 addition & 1 deletion dev-data/aws-devops.data.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Trainer } from '@/entities/trainer';
import awsImg3 from '@/shared/assets/mentors/a-khatseyeva.webp';
import awsImg2 from '@/shared/assets/mentors/ac-danilov.webp';
import awsImg1 from '@/shared/assets/mentors/ac-kustikov.webp';
import type { Trainer } from 'data';

export const awsDevops: Trainer[] = [
{
Expand Down
2 changes: 1 addition & 1 deletion dev-data/awsDev.data.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import type { Trainer } from '@/entities/trainer';
import awsImg3 from '@/shared/assets/mentors/ac-akbarov.webp';
import awsImg6 from '@/shared/assets/mentors/ac-danilov.webp';
import awsImg4 from '@/shared/assets/mentors/ac-konyakhin.webp';
import awsImg5 from '@/shared/assets/mentors/ac-kustikov.webp';
import awsImg2 from '@/shared/assets/mentors/v-antonau.webp';
import awsImg1 from '@/shared/assets/mentors/v-kavaliou.webp';
import type { Trainer } from 'data';

export const awsDev: Trainer[] = [
{
Expand Down
2 changes: 1 addition & 1 deletion dev-data/awsFundamentals.data.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type { Trainer } from '@/entities/trainer';
import awsImg2 from '@/shared/assets/mentors/v-antonau.webp';
import awsImg1 from '@/shared/assets/mentors/v-kavaliou.webp';
import type { Trainer } from 'data';

export const awsFundamentals: Trainer[] = [
{
Expand Down
1 change: 0 additions & 1 deletion dev-data/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
export type { AngularAwsPath, CoursesPath, DataMap, JSPath } from './courses-data.types';
export type { Trainer } from './trainers.types';
export { COURSE_TITLES } from './courseTitles.data';
export { type CourseNames, contentMap } from './training-program.data';
export { type CourseNamesChannels, DISCORD_LINKS, RS_DOCS_COMMUNICATION_LINK, RS_DOCS_TELEGRAM_CHATS_LINK } from './communication.data';
Expand Down
2 changes: 1 addition & 1 deletion dev-data/javascript-ru.data.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import type { Trainer } from '@/entities/trainer';
import annaMusikhinaImg from '@/shared/assets/mentors/a-musikhina.webp';
import margaritaGolubevaImg from '@/shared/assets/mentors/m-golubeva.webp';
import mikhailOleinikImg from '@/shared/assets/mentors/m-oleinik.webp';
import sergeyKoksharovImg from '@/shared/assets/mentors/s-koksharov.webp';
import vadimAntonauImg from '@/shared/assets/mentors/v-antonau.webp';
import vitaliiRogozinImg from '@/shared/assets/mentors/v-rogozin.webp';
import yuliaKursevichImg from '@/shared/assets/mentors/y-kursevich.webp';
import type { Trainer } from 'data';

export const javaScriptRu: Trainer[] = [
{
Expand Down
2 changes: 1 addition & 1 deletion dev-data/nodejs.data.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Trainer } from '@/entities/trainer';
import nodejsImg2 from '@/shared/assets/mentors/a-auchynikau.webp';
import nodejsImg1 from '@/shared/assets/mentors/m-shylau.webp';
import nodejsImg3 from '@/shared/assets/mentors/v-antonau.webp';
import type { Trainer } from 'data';

export const nodejs: Trainer[] = [
{
Expand Down
2 changes: 1 addition & 1 deletion dev-data/preSchool.data.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type { Trainer } from '@/entities/trainer';
import preSchoolImg2 from '@/shared/assets/mentors/a-musikhina.webp';
import preSchoolImg1 from '@/shared/assets/mentors/v-kavaliou.webp';
import preSchoolImg3 from '@/shared/assets/mentors/v-rogozin.webp';
import type { Trainer } from 'data';

export const preSchoolRu: Trainer[] = [
{
Expand Down
2 changes: 1 addition & 1 deletion dev-data/react-en.data.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import type { Trainer } from '@/entities/trainer';
import artsiomParfianenkau from '@/shared/assets/mentors/a-parfianenkau.webp';
import andrejPodlubnyj from '@/shared/assets/mentors/a-podlubnyj.webp';
import dzmitryYarmoshkin from '@/shared/assets/mentors/d-yarmoshkin.png';
import iharKrasiuk from '@/shared/assets/mentors/i-krasiuk.webp';
import marharytaMalets from '@/shared/assets/mentors/m-malets.webp';
import valeryDluski from '@/shared/assets/mentors/v-dluski.webp';
import type { Trainer } from 'data';

export const reactEn: Trainer[] = [
{
Expand Down
2 changes: 1 addition & 1 deletion dev-data/react-ru.data.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type { Trainer } from '@/entities/trainer';
import reactRuImg3 from '@/shared/assets/mentors/d-cebruk.webp';
import reactRuImg2 from '@/shared/assets/mentors/p-razuvalov.webp';
import reactRuImg4 from '@/shared/assets/mentors/s-shalyapin.webp';
import reactRuImg1 from '@/shared/assets/mentors/v-kovalev.webp';
import type { Trainer } from 'data';

export const reactRu: Trainer[] = [
{
Expand Down
2 changes: 2 additions & 0 deletions src/entities/trainer/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export type { Trainer } from './types';
export { TrainerCard } from './ui/trainers-card/trainer-card';
File renamed without changes.
64 changes: 64 additions & 0 deletions src/entities/trainer/ui/trainers-card/trainer-card.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
.trainer-card {
display: flex;
gap: 24px;
align-items: flex-start;
justify-content: space-between;

max-width: 700px;
padding: 40px 32px 40px 32px;

border-radius: 16px;
box-shadow: 0 4px 16px 0 rgb(0 0 0 / 12%);

.card-picture {
max-width: 120px;
max-height: 120px;

img {
width: 100%;
height: auto;
border-radius: 12px;
}
}

.card-text {
width: fit-content;
}

.card-title {
margin: 0;
font-size: 24px;
font-weight: $font-weight-medium;
line-height: 32px;

@include media-tablet {
font-size: 20px;
}
}

.card-subtitle {
margin: 0;
font-size: 18px;
font-weight: $font-weight-medium;
color: $color-gray-500;

@include media-tablet {
font-size: 18px;
}
}

.card-content {
font-size: 16px;
font-weight: $font-weight-regular;
line-height: 24px;
color: $color-gray-600;
}

@include media-tablet-large {
max-width: 100%;
}

@include media-mobile-landscape {
flex-direction: column;
}
}
18 changes: 18 additions & 0 deletions src/entities/trainer/ui/trainers-card/trainer-card.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { screen } from '@testing-library/react';
import { describe, expect, it } from 'vitest';
import { TrainerCard } from './trainer-card';
import { MOCKED_TRAINER } from '@/shared/__tests__/constants';
import { renderWithRouter } from '@/shared/__tests__/utils';

describe('TrainerCard', () => {
const mockProps = MOCKED_TRAINER;

it('should render correctly', () => {
renderWithRouter(<TrainerCard {...mockProps} />);

expect(screen.getByText(mockProps.name)).toBeVisible();
expect(screen.getByText(mockProps.role)).toBeVisible();
expect(screen.getByText(mockProps.bio)).toBeVisible();
expect(screen.getByAltText(`${mockProps.name} ${mockProps.role}`)).toBeVisible();
});
});
24 changes: 24 additions & 0 deletions src/entities/trainer/ui/trainers-card/trainer-card.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import classNames from 'classnames/bind';
import { Trainer } from '../../types';
import { Image } from '@/shared/ui/image';

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

const cx = classNames.bind(styles);

export const TrainerCard = ({ name, bio, role, photo }: Trainer) => {
return (
<article className={cx('trainer-card')}>
<div className={cx('card-picture')}>
<Image src={photo} alt={`${name} ${role}`} />
</div>
<div className={cx('card-text')}>
<header>
<h3 className={cx('card-title')}>{name}</h3>
<h4 className={cx('card-subtitle')}>{role}</h4>
</header>
<p className={cx('card-content')}>{bio}</p>
</div>
</article>
);
};
10 changes: 5 additions & 5 deletions src/shared/__tests__/constants.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import nodejsImg1 from '@/shared/assets/mentors/m-shylau.webp';
import { Trainer } from 'data';
import type { Trainer } from '@/entities/trainer';

export const MOCKED_IMAGE_PATH = 'mocked-image-path.webp';
const MOCKED_TRAINER = {
name: 'Maksim Shylau',
role: 'Senior Software Engineer at Epam',
bio: "Maksim Shylau is a professional with around 6 years of programming experience. Initially a hobby, programming evolved into Maxim's current profession as a full-stack developer (proficient in JavaScript, TypeScript, React, Node.js, and AWS) at EPAM Systems, where he holds the position of Senior Software Engineer. Maksim actively contributes to RS School in his leisure time by leading a Node.js course, delivering lectures, creating educational tasks, and participating in various events. He is committed to continuous learning, constantly exploring new technologies, and extends his passion to helping students master web development.",
export const MOCKED_TRAINER = {
name: 'Max Power',
role: 'Executive Pastry Chef at The Cloud Cafe',
bio: "Max Power is a pastry master with a passion for crafting sweet treats. With over 7 years of experience whipping up delicious pastries and desserts, Max has honed their skills as the Head Pastry Chef on the prestigious Cloud Cafe. When not busy creating new recipes, Max enjoys leading baking classes and participating in friendly cooking competitions.",
photo: nodejsImg1,
};
export const MOCKED_ONE_TRAINER: Trainer[] = [MOCKED_TRAINER];
Expand Down
19 changes: 5 additions & 14 deletions src/widgets/trainers/trainers.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,9 @@ describe('Trainer', () => {

it('renders the trainer info correctly with "nodejs" props', () => {
render(<Trainers trainers={MOCKED_ONE_TRAINER} />);
const trainerNameElement = screen.getByText('Maksim Shylau');
const trainerTitleElement = screen.getByText('Senior Software Engineer at Epam');
const trainerDescriptionElement = screen.getByText(
/Maksim Shylau is a professional with around 6 years/i,
);
const trainerNameElement = screen.getByText(MOCKED_ONE_TRAINER[0].name);
const trainerTitleElement = screen.getByText(MOCKED_ONE_TRAINER[0].role);
const trainerDescriptionElement = screen.getByText(MOCKED_ONE_TRAINER[0].bio);

expect(trainerNameElement).toBeVisible();
expect(trainerTitleElement).toBeVisible();
Expand All @@ -44,15 +42,8 @@ describe('Trainer', () => {

it('renders all the trainers if passed several (8 in items)', () => {
const { container } = render(<Trainers trainers={MOCKED_SEVERAL_TRAINERS} />);
const trainers = container.getElementsByClassName('trainer-card');
const trainers = container.getElementsByClassName('trainers-list')[0];

expect(trainers).toHaveLength(8);
});

it('renders the image with correct alt text', () => {
render(<Trainers trainers={MOCKED_ONE_TRAINER} />);
const imageElement = screen.getByAltText('Maksim Shylau Senior Software Engineer at Epam');

expect(imageElement).toBeInTheDocument();
expect(trainers.childNodes).toHaveLength(8);
});
});
19 changes: 0 additions & 19 deletions src/widgets/trainers/ui/trainers-card/trainer-card.tsx

This file was deleted.

98 changes: 15 additions & 83 deletions src/widgets/trainers/ui/trainers.scss
Original file line number Diff line number Diff line change
@@ -1,88 +1,10 @@
.nodejs-trainer {
& .content {
.trainers {
.trainers-content {
display: flex;
flex-direction: column;
gap: 32px;
padding: 40px 120px;

&.gap {
display: flex;
flex-direction: column;
gap: 32px;
}

.trainers-list {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(450px, 1fr));
gap: 32px;

@include media-tablet-large {
grid-template-columns: 1fr;
}
}

.trainer-card {
display: flex;
gap: 24px;
align-items: flex-start;
justify-content: space-between;

max-width: 700px;
padding: 40px 32px 40px 32px;

border-radius: 16px;
box-shadow: 0 4px 16px 0 rgb(0 0 0 / 12%);

.picture {
max-width: 120px;
max-height: 120px;

img {
width: 100%;
height: auto;
border-radius: 12px;
}
}

.right {
width: fit-content;

& > .card-title {
margin: 0;
font-size: 24px;
font-weight: $font-weight-medium;
line-height: 32px;

@include media-tablet {
font-size: 20px;
}
}

& > .card-subtitle {
margin: 0;
font-size: 18px;
font-weight: $font-weight-medium;
color: $color-gray-500;

@include media-tablet {
font-size: 18px;
}
}

& .card-content {
font-size: 16px;
font-weight: $font-weight-regular;
line-height: 24px;
color: $color-gray-600;
}
}

@include media-tablet-large {
max-width: 100%;
}

@include media-mobile-landscape {
flex-direction: column;
}
}

@include media-laptop {
padding: 40px;
}
Expand All @@ -91,4 +13,14 @@
padding: 40px 16px;
}
}

.trainers-list {
display: grid;
grid-template-columns: repeat(auto-fill, minmax(450px, 1fr));
gap: 32px;

@include media-tablet-large {
grid-template-columns: 1fr;
}
}
}
Loading
Loading