Skip to content

Commit

Permalink
Merge pull request #29 from TiagoM13/feature/details
Browse files Browse the repository at this point in the history
refactoring detail card component
  • Loading branch information
TiagoM13 authored Apr 17, 2023
2 parents 374e673 + 70cea07 commit 9001470
Show file tree
Hide file tree
Showing 16 changed files with 323 additions and 153 deletions.
133 changes: 0 additions & 133 deletions src/components/CardDetails/CardDetails.tsx

This file was deleted.

115 changes: 115 additions & 0 deletions src/components/DetailsCard/DetailsCard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import React from 'react';
import { AiOutlineColumnHeight } from 'react-icons/ai';
import { FaWeightHanging } from 'react-icons/fa';

import { TypeCard } from '@components/TypeCard/TypeCard';
import { ICardDatails } from '@interfaces/cardDatails';
import { getNumberOrderFormat } from '@utils/getNumberOrderFormat';
import {
getTypesToBackgroundColor,
getTypesToIconsTypes,
} from '@utils/getTheme';

import { AbilitiesCard } from './components/AbilitiesCard/AbilitiesCard';
import { BaseStats } from './components/BaseStats/BaseStats';
import { InfoBox } from './components/InfoBox/InfoBox';
import { Tabs } from './components/Tabs/Tabs';

export const DetailsCard = ({
id,
name,
img,
types,
weight,
height,
abilities,
stats,
}: ICardDatails) => {
const [select, setSelect] = React.useState(true);
const [selectTwo, setSelectTwo] = React.useState(false);

const handleClick = () => {
setSelect(!select);
setSelectTwo(!selectTwo);
};

return (
<div className="bg-white w-[400px] mx-auto rounded-2xl border border-zinc-300 overflow-hidden">
{/* image pokémon */}
<div
style={{
backgroundColor: id!
? getTypesToBackgroundColor(types![0].type.name.toUpperCase())
: '#9d9b9b',
}}
className="bg-zinc-500 flex flex-col items-center text-white px-4 py-4 rounded-b-[50%]"
>
<div className="w-[240px] flex justify-center -mb-14">
<img src={img} alt={name} className="w-full" loading="lazy" />
</div>
</div>

{/* name pokémon */}
<div className="w-full flex flex-col justify-between mt-6 px-4">
<strong className="text-2xl font-medium leading-tight capitalize">
{name}
</strong>
<span className="text-sm font-semibold text-zinc-500">
{getNumberOrderFormat(id!)}
</span>
</div>

{/* types pokémon */}
<div className="flex items-center gap-2 py-2 px-4">
{types?.map((type, index) => {
return (
<div
key={`${type.type.name}-${index}`}
className="font-semibold text-white text-[12px]"
>
<TypeCard
type={type.type.name}
icon={`${
type.type.name &&
getTypesToIconsTypes(type.type.name.toUpperCase())
}`}
/>
</div>
);
})}
</div>

{/* nav tabs */}
<Tabs select={select} selectTwo={selectTwo} onSelect={handleClick} />

{select && (
<div className="mb-4">
{/* info pokémon */}
<div className="flex items-center justify-between px-4 my-2">
<InfoBox
text="Peso"
value={weight}
unity="kg"
icon={<FaWeightHanging size={15} className="text-zinc-500" />}
/>

<InfoBox
text="Altura"
value={height}
unity="m"
icon={
<AiOutlineColumnHeight size={15} className="text-zinc-500" />
}
/>
</div>

{/* abilities */}
<AbilitiesCard abilities={abilities} />
</div>
)}

{/* base stats */}
{selectTwo && <BaseStats stats={stats} />}
</div>
);
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from 'react';
import { CgPokemon } from 'react-icons/cg';

import { IAbilitiesCard } from '@interfaces/abilitiesCard';

export const AbilitiesCard = ({ abilities }: IAbilitiesCard) => {
return (
<div className="flex flex-col justify-center items-center pt-2 px-4">
<h3 className="flex items-center text-sm font-semibold text-zinc-500 gap-2 mb-1 uppercase">
<CgPokemon size={20} className="text-zinc-500" />
Abilities
</h3>

<div className="flex gap-2">
{abilities?.map((ability, index) => {
return (
<div key={`${ability.ability.name}-${index}`}>
<div className="text-center border border-zinc-300 rounded-lg py-2 px-3">
<span className="text-base capitalize">
{ability.ability.name}
</span>
</div>
</div>
);
})}
</div>
</div>
);
};
36 changes: 36 additions & 0 deletions src/components/DetailsCard/components/BaseStats/BaseStats.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import React from 'react';
import { ImStatsBars } from 'react-icons/im';

import { IBaseStats } from '@interfaces/baseStats';

import { ProgressBar } from '../ProgressBar/ProgressBar';

export const BaseStats = ({ stats }: IBaseStats) => {
return (
<div className="flex flex-col items-center pt-4 pb-8">
<h3 className="flex items-center text-sm font-semibold text-zinc-500 gap-2 mb-1 uppercase">
<ImStatsBars size={15} className="text-zinc-500" />
Base Stats
</h3>
{stats?.map((stat, index) => {
return (
<div
key={index}
className="w-full justify-between items-center flex gap-2 px-4 text-zinc-700"
>
<div className="w-[200px]">
<span className="text-sm font-semibold">{stat.stat.name}</span>
</div>

{/* progressbar */}
<ProgressBar amount={stat.base_stat} />

<div className="w-11 text-right">
<span className="text-sm font-semibold">{stat.base_stat}</span>
</div>
</div>
);
})}
</div>
);
};
21 changes: 21 additions & 0 deletions src/components/DetailsCard/components/InfoBox/InfoBox.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react';

import { IInfoBox } from '@interfaces/infoBox';
import { formatHeightWeight } from '@utils/formatHeightWeight';

export const InfoBox = ({ text, value, icon, unity }: IInfoBox) => {
return (
<div className="w-full px-2">
<h3 className="flex items-center text-sm font-semibold text-zinc-500 gap-2 mb-1 uppercase">
{icon}
{text}:
</h3>
<div className="text-center border border-zinc-300 rounded-lg py-2 px-3">
<span className="text-base font-medium">
{formatHeightWeight(value)}
{unity}
</span>
</div>
</div>
);
};
32 changes: 32 additions & 0 deletions src/components/DetailsCard/components/ProgressBar/ProgressBar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from 'react';

type IProgressBar = {
amount: number;
};

export const ProgressBar = ({ amount }: IProgressBar) => {
const [progress, setProgress] = React.useState(0);
const maxPercentage = 100;

let percentage = (amount / 100) * maxPercentage;

if (percentage > 100) {
percentage = 100;
}

React.useEffect(() => {
const timer = setTimeout(() => setProgress(percentage), 500);
return () => clearTimeout(timer);
}, [percentage]);

return (
<div role="progressbar" className="h-2 w-full bg-zinc-400 rounded">
<div
className="h-2 rounded-xl bg-green-400 transition-all duration-500"
style={{
width: `${progress}%`,
}}
/>
</div>
);
};
Loading

0 comments on commit 9001470

Please sign in to comment.