How to add a selected icon to a .map() function display

Viewed 14

I am trying to create a weekly dinner list in react using zustand as the state-management.

I have successfully added and display the item title into div's when added. But I am needing to add a selected icon to the div.

So the user would type in the title of the item and select a image as well to be displayed

Link to app visual example

Here's where I am storing my source of truth:

import create from 'zustand';

import {devtools, persist} from 'zustand/middleware'

const dinnerStore = (set) => ({
    meals: [],
    addMeal: (meal) => {
        set((state) => ({
            meals: [meal, ...state.meals],
        }))
    },
    removeMeal: (mealId) => {
        set((state) => ({
            meals: state.meals.filter((m) => m.id !== mealId)
        }))
    },
    toggleMealStatus: (mealId) => {
        set((state) => ({
            meals: state.meals.map((meal) => meal.id === mealId ? {...meal, completed: !meal.completed} : meal) //If the meal id we've selected is equal to the corresponding id in the array
        }))
    },
    icons: [],
    addIcon: (icon) => {
        set((state) => ({
            icons: [icon, ...state.icons]
        }))
    }
})

const useDinnerStore = create(
    devtools(
        persist(dinnerStore, {
            name: "meals",
            iconList: "icons"
        })
    )
)


export default useDinnerStore;

Here's the code for dealing with the form submissions:

import React, {useState} from 'react'
import useDinnerStore from '../app/dinnerStore';
import Icon from './Icon';
import $ from 'jquery';

const DinnerForm = () => {

    const addMeal = useDinnerStore((state) => state.addMeal)
    const addIcon = useDinnerStore((state) => state.addIcon)
    const icons = ["1", "2", "3", "4", "5", "6", "7", "8", "9"]

    const [mealTitle, setMealTitle] = useState("")
    console.log("Meal Form Rendererd");

    const [iconName, setIconName] = useState("");

    const [iconDisplay, setIconDisplay] = useState("")

    const handleMealSubmit = () => {
        if (!mealTitle) return alert("Please add a dinner"); //Essentially, if the title is blank on submit
        addMeal({
            id: Math.ceil(Math.random() * 1000000),
            title: mealTitle
        })
        setMealTitle("")
    }

    const handleIconSubmit = () => {
        addIcon({
            id: Math.ceil(Math.random() * 10),
            icon: iconName
        })
        let selectedIcon = $(this).attr("id"); 
        console.log(selectedIcon)
        setIconName("")
    }


    



  return (
    <div className="form-container">
        <input 
        value={mealTitle} //For consistency what connecting this with the title state
        onChange={(e) => {
            setMealTitle(e.target.value)
        }}
        className="form-input" />
        <button 
        onClick={() => {
            handleMealSubmit();
        }}
        className="form-submit-btn">
            Add Dinner
        </button>
        <div className="icon-list">
            {icons.map((icon, i) => {
                return (
                    <React.Fragment key={i}>
                        <input type="image" src="#" name="icon" id={i} className="btn" onClick={() => {
                            handleIconSubmit();
                        }} />
                    </React.Fragment>
                )
            })}
            
        </div>
    </div>
  )
}

export default DinnerForm;

And dealing with the display render

import React from 'react';
import useDinnerStore from '../app/dinnerStore';

function DinnerList() {

    const {meals, removeMeal, toggleMealStatus, icons, addIcon} = useDinnerStore(
        (state) => ({
            meals: state.meals,
            removeMeal: state.removeMeal,
            toggleMealStatus: state.toggleMealStatus,
            icons: state.icons,
            addIcon: state.addIcon
        })
    )
    return (
        <div className="meal-item-container">
            {meals.map((meal, i) => {
                return (
                    <React.Fragment key={i}>
                        <div 
                        className={'meal-item'}
                        style={{
                            backgroundColor: meal.completed ? "#FF0044" : "transparent"
                        }}>
                            <span className="meal-item-col-1"></span>
                            <input
                            checked={meal.completed}
                            type="checkbox" 
                            onChange={(e) => {
                                toggleMealStatus(meal.id)
                            }}
                            />
                            <span>{meal?.title} </span>
                            <button 
                            onClick={() => {
                                removeMeal(meal.id)
                            }}
                            className="delete-btn">X</button>
                             [needing to add selected icon here]
                        </div>
                    </React.Fragment>
                )
            })}
        </div>
    )
}

export default DinnerList;
0 Answers
Related