Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -16,22 +16,22 @@ type Story = StoryObj<typeof Exercise>;
*/
export const Default: Story = {
args: {
title: 'The Coldest Sunset Festival',
subText:
'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptatibus quia, nulla! Maiores et perferendis eaque, exercitationem praesentium nihil.',
ctaText: '#festival',
ctaUrl: '/',
imageAltText: 'DJ playing at a festival',
imageUrlMobile:
'https://images.unsplash.com/photo-1493676304819-0d7a8d026dcf?w=767&h=640&fit=crop',
imageUrlTablet:
'https://images.unsplash.com/photo-1493676304819-0d7a8d026dcf?w=1024&h=640&fit=crop',
imageUrlDesktop:
'https://images.unsplash.com/photo-1493676304819-0d7a8d026dcf?w=1600&h=900&fit=crop',
containerClassName: 'containerClassName',
titleClassName: 'titleClassName',
subTextClassName: 'subTextClassName',
ctaClassName: 'ctaClassName',
imageClassName: 'imageClassName'
pokemonName: 'Charizard',
pokemonType: 'Fire/Flying',
pokemonHp: 180,
pokemonLevel: 55,
attackName: 'Fire Blast',
attackDamage: 120,
attackDescription: 'A powerful fire attack that may leave the target with a burn.',
imageAltText: 'Charizard breathing fire',
imageUrlSmall: 'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/6.png',
imageUrlMedium: 'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/6.png',
imageUrlLarge: 'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/6.png',
cardClassName: 'shadow-xl',
nameClassName: 'text-red-600',
typeClassName: 'bg-red-500',
hpClassName: 'text-red-700',
attackClassName: 'border-red-400',
imageClassName: 'hover:scale-105 transition-transform'
}
};
147 changes: 86 additions & 61 deletions src/course/02-lessons/01-Bronze/PropsCombination/exercise/exercise.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,104 +2,129 @@ import classnames from 'classnames';

/*

1a👨🏻💻 group the following together:
1a👨🏻💻 group the following together:

* image - imageAltText, imageUrlMobile, imageUrlTablet, imageUrlDesktop
* cta - ctaText, ctaUrl
* classNames - containerClassName, titleClassName, subTextClassName, ctaClassName, imageClassName
* pokemon - pokemonName, pokemonType, pokemonHp, pokemonLevel
* attack - attackName, attackDamage, attackDescription
* image - imageAltText, imageUrlSmall, imageUrlMedium, imageUrlLarge
* styling - cardClassName, nameClassName, typeClassName, hpClassName, attackClassName, imageClassName

*/
interface IExerciseProps {
title: string;
subText: string;
ctaText: string;
ctaUrl: string;
interface IPokemonCardProps {
pokemonName: string;
pokemonType: string;
pokemonHp: number;
pokemonLevel: number;
attackName: string;
attackDamage: number;
attackDescription: string;
imageAltText: string;
imageUrlMobile: string;
imageUrlTablet: string;
imageUrlDesktop: string;
containerClassName?: string;
titleClassName?: string;
subTextClassName?: string;
ctaClassName?: string;
imageUrlSmall: string;
imageUrlMedium: string;
imageUrlLarge: string;
cardClassName?: string;
nameClassName?: string;
typeClassName?: string;
hpClassName?: string;
attackClassName?: string;
imageClassName?: string;
}

/*
1b👨🏻💻 Update the props to match the new types defined above.
1b👨🏻💻 Update the props to match the new grouped types defined above.
*/
export const Exercise = ({
title,
subText,
ctaText,
ctaUrl,
pokemonName,
pokemonType,
pokemonHp,
pokemonLevel,
attackName,
attackDamage,
attackDescription,
imageAltText,
imageUrlMobile,
imageUrlTablet,
imageUrlDesktop,
containerClassName,
titleClassName,
subTextClassName,
ctaClassName,
imageUrlSmall,
imageUrlMedium,
imageUrlLarge,
cardClassName,
nameClassName,
typeClassName,
hpClassName,
attackClassName,
imageClassName
}: IExerciseProps) => {
}: IPokemonCardProps) => {
/*
2a 🤔 Could we destructure the image to be [mobile, tablet, desktop]?
2a 🤔 Could we destructure the image to be [small, medium, large]?
*/
/*
1c👨🏻💻 Update the props in the jsx
1c👨🏻💻 Update the props in the jsx to use the grouped structure
*/
return (
<article
className={classnames(
'max-w-sm rounded overflow-hidden shadow-lg',
containerClassName
'max-w-sm rounded-lg overflow-hidden shadow-lg bg-gradient-to-b from-yellow-100 to-yellow-200 border-2 border-yellow-400',
cardClassName
)}
>
<picture>
{/* ✍🏻 picture elements are a great way to display responsive images */}
{/* ✍🏻 Using rem instead of pixels will change the image when you zoom in the page */}
{/* ✍🏻 Link: https://web.dev/learn/design/picture-element */}
<source srcSet={imageUrlDesktop} media="(min-width: 62rem)" />
<source srcSet={imageUrlTablet} media="(min-width: 40rem)" />
<source srcSet={imageUrlMobile} media="(min-width: 32rem)" />
<div className="bg-blue-600 text-white p-2 text-center">
<span className="text-xs font-bold">
⭐ Level {pokemonLevel}
</span>
</div>

<picture className="block p-4">
<source srcSet={imageUrlLarge} media="(min-width: 62rem)" />
<source srcSet={imageUrlMedium} media="(min-width: 40rem)" />
<source srcSet={imageUrlSmall} media="(min-width: 32rem)" />
<img
src={imageUrlDesktop}
src={imageUrlLarge}
alt={imageAltText}
className={classnames(
'w-full object-cover h-full',
'w-full h-48 object-contain rounded-lg',
imageClassName
)}
/>
</picture>

<div className="px-6 py-4">
<h3
className={classnames(
'font-bold text-xl mb-2',
titleClassName
'font-bold text-2xl mb-2 text-center',
nameClassName
)}
>
{title}
{pokemonName}
</h3>
<p
className={classnames(
'text-gray-700 text-base',
subTextClassName
)}
>
{subText}
</p>
</div>
<div className="px-6 pt-4 pb-2">
<a
href={ctaUrl}

<div className="flex justify-between items-center mb-4">
<span
className={classnames(
'inline-block bg-blue-500 text-white rounded-full px-3 py-1 text-sm font-semibold',
typeClassName
)}
>
{pokemonType} Type
</span>
<span
className={classnames(
'text-red-600 font-bold text-lg',
hpClassName
)}
>
❤️ {pokemonHp} HP
</span>
</div>

<div
className={classnames(
'inline-block bg-gray-200 hover:bg-gray-300 transition-colors rounded-full px-3 py-1 text-sm font-semibold text-gray-700 mr-2 mb-2',
ctaClassName
'bg-gray-100 rounded-lg p-3 border-l-4 border-orange-400',
attackClassName
)}
>
{ctaText}
</a>
<h4 className="font-bold text-orange-600 mb-1">
⚡ {attackName} - {attackDamage} damage
</h4>
<p className="text-gray-700 text-sm">{attackDescription}</p>
</div>
</div>
</article>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,27 +16,32 @@ type Story = StoryObj<typeof Final>;
*/
export const Default: Story = {
args: {
title: 'The Coldest Sunset Festival',
subText:
'Lorem ipsum dolor sit amet, consectetur adipisicing elit. Voluptatibus quia, nulla! Maiores et perferendis eaque, exercitationem praesentium nihil.',
cta: {
text: '#festival',
url: '/'
pokemon: {
name: 'Pikachu',
type: 'Electric',
hp: 120,
level: 25
},
attack: {
name: 'Thunderbolt',
damage: 90,
description: 'A strong electric blast that may paralyze the target.'
},
image: {
alt: 'DJ playing at a festival',
images: [
'https://images.unsplash.com/photo-1493676304819-0d7a8d026dcf?w=767&h=640&fit=crop',
'https://images.unsplash.com/photo-1493676304819-0d7a8d026dcf?w=1024&h=640&fit=crop',
'https://images.unsplash.com/photo-1493676304819-0d7a8d026dcf?w=1600&h=900&fit=crop'
alt: 'Pikachu with electric sparks',
sources: [
'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/25.png',
'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/25.png',
'https://raw.githubusercontent.com/PokeAPI/sprites/master/sprites/pokemon/other/official-artwork/25.png'
]
},
classNames: {
container: 'container',
title: 'title',
subText: 'subText',
cta: 'cta',
image: 'image'
styling: {
card: 'shadow-xl border-yellow-400',
name: 'text-yellow-600',
type: 'bg-yellow-500',
hp: 'text-yellow-700',
attack: 'border-yellow-400',
image: 'hover:scale-105 transition-transform'
}
}
};
Loading
Loading