Compare commits
4 Commits
768c84d6b8
...
766a48f7c0
Author | SHA1 | Date | |
---|---|---|---|
766a48f7c0 | |||
8f217d678a | |||
99fd0577fd | |||
bf3cbe886b |
@ -1,16 +1,38 @@
|
||||
import { Provider } from 'react-redux';
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import EvolutionSpecies from './EvolutionSpecies';
|
||||
import {
|
||||
MockedState,
|
||||
MockStoreProps,
|
||||
mockStore,
|
||||
} from 'features/InfoDialog/infoDialogSlice.storybook';
|
||||
|
||||
const Mockstore: React.FC<MockStoreProps> = ({ InfoDialogState, children }) => (
|
||||
<Provider store={mockStore({ InfoDialogState })}>{children}</Provider>
|
||||
);
|
||||
|
||||
const meta: Meta<typeof EvolutionSpecies> = {
|
||||
title: 'Component/EvolutionSpecies',
|
||||
component: EvolutionSpecies,
|
||||
decorators: [
|
||||
(story: () => React.ReactNode) => (
|
||||
<div style={{ padding: '3rem' }}>{story()}</div>
|
||||
),
|
||||
],
|
||||
tags: ['autodocs'],
|
||||
excludeStories: /.*MockedState$/,
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof EvolutionSpecies>;
|
||||
|
||||
export const Bulbasaur: Story = {
|
||||
decorators: [
|
||||
(story: () => React.ReactNode) => (
|
||||
<Mockstore InfoDialogState={MockedState.infoDialog}>{story()}</Mockstore>
|
||||
),
|
||||
],
|
||||
args: {
|
||||
types: ['grass', 'poison'],
|
||||
image_url:
|
||||
@ -20,6 +42,11 @@ export const Bulbasaur: Story = {
|
||||
};
|
||||
|
||||
export const Magneton: Story = {
|
||||
decorators: [
|
||||
(story: () => React.ReactNode) => (
|
||||
<Mockstore InfoDialogState={MockedState.infoDialog}>{story()}</Mockstore>
|
||||
),
|
||||
],
|
||||
args: {
|
||||
types: ['electric', 'steel'],
|
||||
image_url:
|
||||
|
@ -3,18 +3,22 @@ import { motion } from 'framer-motion';
|
||||
import './EvolutionSpecies.css';
|
||||
import { LazyLoadImage } from 'react-lazy-load-image-component';
|
||||
import { colorTypeGradients } from 'components/utils';
|
||||
import { useAppDispatch } from '../../app/hooks';
|
||||
import { fetchSelectedPokemonInfo } from '../../features/InfoDialog/infoDialogSlice';
|
||||
|
||||
export interface EvolutionSpeciesProps {
|
||||
export type EvolutionSpeciesProps = {
|
||||
types: string[];
|
||||
name: string;
|
||||
image_url: string;
|
||||
}
|
||||
};
|
||||
|
||||
const EvolutionSpecies = ({
|
||||
types,
|
||||
name,
|
||||
image_url,
|
||||
}: EvolutionSpeciesProps) => {
|
||||
const dispatch = useAppDispatch();
|
||||
|
||||
const finalColor = colorTypeGradients(types);
|
||||
|
||||
return (
|
||||
@ -47,6 +51,7 @@ const EvolutionSpecies = ({
|
||||
delayMethod={'debounce'}
|
||||
effect={'blur'}
|
||||
className={'evo_img'}
|
||||
onClick={() => dispatch(fetchSelectedPokemonInfo(name))}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -1,16 +1,38 @@
|
||||
import { Provider } from 'react-redux';
|
||||
import type { Meta, StoryObj } from '@storybook/react';
|
||||
|
||||
import InfoDialogComponent from './InfoDialogComponent';
|
||||
import {
|
||||
MockedState,
|
||||
MockStoreProps,
|
||||
mockStore,
|
||||
} from 'features/InfoDialog/infoDialogSlice.storybook';
|
||||
|
||||
const Mockstore: React.FC<MockStoreProps> = ({ InfoDialogState, children }) => (
|
||||
<Provider store={mockStore({ InfoDialogState })}>{children}</Provider>
|
||||
);
|
||||
|
||||
const meta: Meta<typeof InfoDialogComponent> = {
|
||||
title: 'Component/InfoDialogComponent',
|
||||
component: InfoDialogComponent,
|
||||
decorators: [
|
||||
(story: () => React.ReactNode) => (
|
||||
<div style={{ padding: '3rem' }}>{story()}</div>
|
||||
),
|
||||
],
|
||||
tags: ['autodocs'],
|
||||
excludeStories: /.*MockedState$/,
|
||||
};
|
||||
|
||||
export default meta;
|
||||
type Story = StoryObj<typeof InfoDialogComponent>;
|
||||
|
||||
export const Duduo: Story = {
|
||||
decorators: [
|
||||
(story: () => React.ReactNode) => (
|
||||
<Mockstore InfoDialogState={MockedState.infoDialog}>{story()}</Mockstore>
|
||||
),
|
||||
],
|
||||
args: {
|
||||
openDialog: true,
|
||||
id: 84,
|
||||
|
@ -7,31 +7,18 @@ import { findPokeTypeAsset } from 'components/PokemonTypes';
|
||||
import { colorTypeGradients } from 'components/utils';
|
||||
import GenderRate from 'components/GenderRate';
|
||||
import Delayed from 'components/Delayed';
|
||||
import EvolutionSpecies, {
|
||||
EvolutionSpeciesProps,
|
||||
} from 'components/EvolutionSpecies';
|
||||
import EvolutionSpecies from 'components/EvolutionSpecies';
|
||||
import { InfoDialogDetails } from 'features/InfoDialog/infoDialogSlice';
|
||||
|
||||
export interface Stat {
|
||||
stat__name: string;
|
||||
stat__value: number;
|
||||
}
|
||||
|
||||
export interface InfoDialogComponentProps {
|
||||
export type InfoDialogComponentProps = InfoDialogDetails & {
|
||||
openDialog: boolean;
|
||||
closeDialog: () => void;
|
||||
id: number;
|
||||
name: string;
|
||||
types: string[];
|
||||
genera: string;
|
||||
image: string;
|
||||
height: number;
|
||||
weight: number;
|
||||
genderRatio: number;
|
||||
description: string;
|
||||
abilities: string[];
|
||||
stats: Stat[];
|
||||
evolutionChain: EvolutionSpeciesProps[];
|
||||
}
|
||||
};
|
||||
|
||||
const InfoDialog = ({
|
||||
openDialog,
|
||||
|
48
src/features/InfoDialog/infoDialogSlice.storybook.ts
Normal file
48
src/features/InfoDialog/infoDialogSlice.storybook.ts
Normal file
@ -0,0 +1,48 @@
|
||||
import { InfoDialogStateProps } from './infoDialogSlice';
|
||||
import { configureStore, createSlice } from '@reduxjs/toolkit';
|
||||
|
||||
export const MockedState = {
|
||||
// Copied from Redux DevTools from browser
|
||||
infoDialog: {
|
||||
isOpen: false,
|
||||
InfoDialogDetails: {
|
||||
id: 0,
|
||||
name: '',
|
||||
genera: '',
|
||||
image: '',
|
||||
types: [],
|
||||
height: 0,
|
||||
weight: 0,
|
||||
genderRatio: 0,
|
||||
description: '',
|
||||
abilities: [],
|
||||
stats: [],
|
||||
evolutionChain: [],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export interface MockStoreProps {
|
||||
InfoDialogState: InfoDialogStateProps;
|
||||
children: React.ReactNode;
|
||||
}
|
||||
|
||||
export const mockSlice = (infoDialogState: {
|
||||
InfoDialogState: InfoDialogStateProps;
|
||||
}) => {
|
||||
return createSlice({
|
||||
name: 'infoDialog',
|
||||
initialState: infoDialogState,
|
||||
reducers: {},
|
||||
});
|
||||
};
|
||||
|
||||
export const mockStore = (infoDialogState: {
|
||||
InfoDialogState: InfoDialogStateProps;
|
||||
}) => {
|
||||
return configureStore({
|
||||
reducer: {
|
||||
infoDialog: mockSlice(infoDialogState).reducer,
|
||||
},
|
||||
});
|
||||
};
|
@ -13,7 +13,7 @@ import {
|
||||
PokemonSpeciesResponseData,
|
||||
} from 'types/api';
|
||||
|
||||
type InfoDiaglogDetails = {
|
||||
export type InfoDialogDetails = {
|
||||
id: number;
|
||||
name: string;
|
||||
genera: string;
|
||||
@ -28,7 +28,7 @@ type InfoDiaglogDetails = {
|
||||
evolutionChain: EvolutionSpeciesProps[];
|
||||
};
|
||||
|
||||
const initialInfoDialogDetails: InfoDiaglogDetails = {
|
||||
const initialInfoDialogDetails: InfoDialogDetails = {
|
||||
id: 0,
|
||||
name: '',
|
||||
genera: '',
|
||||
@ -45,7 +45,7 @@ const initialInfoDialogDetails: InfoDiaglogDetails = {
|
||||
|
||||
export type InfoDialogStateProps = {
|
||||
isOpen: boolean;
|
||||
InfoDialogDetails: InfoDiaglogDetails;
|
||||
InfoDialogDetails: InfoDialogDetails;
|
||||
};
|
||||
|
||||
export const initialState: InfoDialogStateProps = {
|
||||
@ -90,7 +90,7 @@ export const constructPokemonInfoFromResponses = (
|
||||
fetchedPokemon: PokemonResponseData,
|
||||
fetchedPokemonSpecies: PokemonSpeciesResponseData,
|
||||
evolutionChain: EvolutionSpeciesProps[],
|
||||
): InfoDiaglogDetails => {
|
||||
): InfoDialogDetails => {
|
||||
return {
|
||||
id: fetchedPokemon.id,
|
||||
name: fetchedPokemon.name,
|
||||
@ -114,12 +114,12 @@ export const constructPokemonInfoFromResponses = (
|
||||
|
||||
export const fetchSelectedPokemonInfo = createAsyncThunk(
|
||||
'infoDialog/fetchSelectedPokemonInfo',
|
||||
async (pokemonId: number, thunkAPI) => {
|
||||
async (pokemonIdOrName: number | string, thunkAPI) => {
|
||||
const dispatch = thunkAPI.dispatch;
|
||||
|
||||
try {
|
||||
const selectedPokemon = await dispatch(
|
||||
pokeApi.endpoints.getPokemon.initiate(pokemonId),
|
||||
pokeApi.endpoints.getPokemon.initiate(pokemonIdOrName),
|
||||
);
|
||||
|
||||
if (selectedPokemon.data) {
|
||||
|
@ -62,31 +62,6 @@ const MockedState = {
|
||||
},
|
||||
],
|
||||
},
|
||||
filter: {
|
||||
regionOptions: [],
|
||||
typeOptions: [],
|
||||
sortOptions: [],
|
||||
selectedRegion: '',
|
||||
selectedType: '',
|
||||
selectedSort: '',
|
||||
searchInput: '',
|
||||
},
|
||||
pokeApi: {
|
||||
queries: {},
|
||||
mutations: {},
|
||||
provided: {},
|
||||
subscriptions: {},
|
||||
config: {
|
||||
online: true,
|
||||
focused: true,
|
||||
middlewareRegistered: false,
|
||||
refetchOnFocus: false,
|
||||
refetchOnReconnect: false,
|
||||
refetchOnMountOrArgChange: false,
|
||||
keepUnusedDataFor: 60,
|
||||
reducerPath: 'pokeApi',
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
interface MockStoreProps {
|
||||
@ -99,11 +74,7 @@ const mockSlice = (pokedexState: PokedexStateProps) => {
|
||||
return createSlice({
|
||||
name: 'pokedex',
|
||||
initialState: pokedexState,
|
||||
reducers: {
|
||||
setIsLoadingPokemons: (state, action) => {
|
||||
state.isLoadingPokemons = action.payload;
|
||||
},
|
||||
},
|
||||
reducers: {},
|
||||
});
|
||||
};
|
||||
const mockStore = (pokedexState: PokedexStateProps) => {
|
||||
|
Loading…
x
Reference in New Issue
Block a user