From 4c8bcf07b377588bc40d94aab2e943ea488d01e3 Mon Sep 17 00:00:00 2001 From: Sergey Elpashev Date: Wed, 8 Jan 2025 16:35:14 +0300 Subject: [PATCH] Feat: redux for images in tier list --- bun.lockb | Bin 107774 -> 111017 bytes package.json | 4 +++- src/App.tsx | 43 +++++++++++++++++++++++++++++++-------- src/components/Image.tsx | 2 +- src/components/Tier.tsx | 12 ++++++++++- src/hooks.ts | 5 +++++ src/main.tsx | 16 +++++++++------ src/store.ts | 33 ++++++++++++++++++++++++++++++ 8 files changed, 98 insertions(+), 17 deletions(-) create mode 100644 src/hooks.ts create mode 100644 src/store.ts diff --git a/bun.lockb b/bun.lockb index 545166e5b613ff08ba4c1c75e1a15b70d1feddc1..9b061fb4b96bdf749ef533912a4a9fd6af21eadb 100755 GIT binary patch delta 21033 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 DZpd-) diff --git a/package.json b/package.json index 6a5f5de..22c7a7a 100644 --- a/package.json +++ b/package.json @@ -11,8 +11,10 @@ }, "dependencies": { "@dnd-kit/core": "^6.3.1", + "@reduxjs/toolkit": "^2.5.0", "react": "^18.3.1", - "react-dom": "^18.3.1" + "react-dom": "^18.3.1", + "react-redux": "^9.2.0" }, "devDependencies": { "@eslint/js": "^9.17.0", diff --git a/src/App.tsx b/src/App.tsx index b6685fe..a85fef6 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -1,7 +1,9 @@ -import { useEffect, useRef, useState } from 'react'; +import { useEffect, useRef } from 'react'; import './App.css'; import { TierImage } from './components/Image'; import { Tier, TierProps } from './components/Tier'; +import { useAppDispatch, useAppSelector } from './hooks'; +import { addTierImage } from './store'; const default_tier_levels: TierProps[] = [ { @@ -21,17 +23,36 @@ const default_tier_levels: TierProps[] = [ }, ]; +interface tierImage { + name: string; + url: string; + category: string; +} + function App() { - const [images, setImages] = useState([]); + const images = useAppSelector(state => state.tierImages); + const dispatch = useAppDispatch(); useEffect(() => { console.log(images); }, [images]); + const uploadBtn = useRef(null); const clickUpload = () => { if (uploadBtn.current) uploadBtn.current.click(); }; + const getRandomCategoryName = () => { + const categoryNames = default_tier_levels.flatMap(category => category.name); + return categoryNames[Math.floor(Math.random() * categoryNames.length)]; + }; + + const handleAdd = (images: tierImage[]) => { + images.forEach(image => { + dispatch(addTierImage(image)); + }); + }; + return ( <>
@@ -45,9 +66,11 @@ function App() { ))}
- {images.map((image, index) => ( - - ))} + {images + .filter(image => image.category === '') + .map((image, index) => ( + + ))}
Upload @@ -60,12 +83,16 @@ function App() { onChange={event => { console.log(event.target.files); if (event.target.files) { - const upload_images: string[] = []; + const upload_images: tierImage[] = []; for (let i = 0; i < event.target.files.length; i++) { const url = URL.createObjectURL(event.target.files[i]); - upload_images.push(url); + upload_images.push({ + url: url, + name: event.target.files[i].name.replace('.jpeg', ''), + category: getRandomCategoryName(), + }); } - setImages(prev => [...prev, ...upload_images]); + handleAdd(upload_images); } }} /> diff --git a/src/components/Image.tsx b/src/components/Image.tsx index 3a518cf..cb32811 100644 --- a/src/components/Image.tsx +++ b/src/components/Image.tsx @@ -6,7 +6,7 @@ interface ImageProps { export const TierImage = ({ image, name }: ImageProps) => { return (
-
+
{name}
{name}
diff --git a/src/components/Tier.tsx b/src/components/Tier.tsx index 26969a5..63c5c2d 100644 --- a/src/components/Tier.tsx +++ b/src/components/Tier.tsx @@ -1,3 +1,6 @@ +import { useAppSelector } from '../hooks'; +import { TierImage } from './Image'; + export interface TierProps { color: 'red' | 'yellow' | 'green'; name: string; @@ -6,6 +9,7 @@ export interface TierProps { export const Tier = ({ color, name, textColor }: TierProps) => { let color_code = ''; let text_color_code = ''; + const tierImages = useAppSelector(state => state.tierImages); switch (color) { case 'green': color_code = '#00b894'; @@ -38,7 +42,13 @@ export const Tier = ({ color, name, textColor }: TierProps) => { >

{name}

-
+
+ {tierImages + .filter(image => image.category === name) + .map((image, index) => ( + + ))} +

diff --git a/src/hooks.ts b/src/hooks.ts new file mode 100644 index 0000000..956153f --- /dev/null +++ b/src/hooks.ts @@ -0,0 +1,5 @@ +import { useDispatch, useSelector } from 'react-redux'; +import { AppDispatch, RootState } from './store'; + +export const useAppDispatch = useDispatch.withTypes(); +export const useAppSelector = useSelector.withTypes(); diff --git a/src/main.tsx b/src/main.tsx index bef5202..dbac8e5 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,10 +1,14 @@ -import { StrictMode } from 'react' -import { createRoot } from 'react-dom/client' -import './index.css' -import App from './App.tsx' +import { StrictMode } from 'react'; +import { createRoot } from 'react-dom/client'; +import { Provider } from 'react-redux'; +import App from './App.tsx'; +import './index.css'; +import store from './store.ts'; createRoot(document.getElementById('root')!).render( - + + + , -) +); diff --git a/src/store.ts b/src/store.ts new file mode 100644 index 0000000..4c17dd7 --- /dev/null +++ b/src/store.ts @@ -0,0 +1,33 @@ +import { configureStore, createSlice, PayloadAction } from '@reduxjs/toolkit'; + +interface tierImage { + name: string; + url: string; + category: string; +} + +const tierImages = createSlice({ + name: 'images', + initialState: [] as tierImage[], + reducers: { + addTierImage: (state, action: PayloadAction) => { + state.push(action.payload); + }, + removeTierImage: (state, action: PayloadAction) => { + return state.filter(image => image.name !== action.payload); + }, + }, +}); + +export const { addTierImage, removeTierImage } = tierImages.actions; + +const store = configureStore({ + reducer: { + tierImages: tierImages.reducer, + }, +}); + +export type RootState = ReturnType; +export type AppDispatch = typeof store.dispatch; + +export default store;