how to draw configurable products in react by its attribute code?

96 Views Asked by At

for 3 days now I have been trying to write a universal code that will allow us to select some options, for example, shirts by their size, color, material, etc., so that if there is no such option, then this button is disabled, but half works. Who can help me, maybe advice or something?? here is my code below.

function ConfigurableFilters ({ handleChangeConfig, configurablesData, state }) {

  const isDisabled = (e, code) => {
    let products = [...e.products];
    for(let attr of configurablesData.attributes) {
      if(attr.code === code) {
        break
      }
      products = products.filter(prod => state.selectedConfigs[attr.code].products.includes(prod))
       state.selectedConfigs[attr.code].id)
    }
    return !products.length
  }


  return (
    <div className="configurable-attributes">
      {
        configurablesData.attributes.map((attr) => {
          if (attr.options.length > 1) {
            if (attr.code !== 'color') {
              return (
                <div className="attr_fms attr_space">
                  <div className="attr_label_size">{attr.label}</div>
                  {
                    attr.code !== 'color'
                    && attr.options.length > 0
                    && !attr.options[0].swatch_value
                    && (
                      <div className="other-list-main-fms">
                        {attr.options.map((e, i) => {
                          return (
                            <label
                              htmlFor={attr.code + e.id}
                              key={i}
                              id={e.id + attr.code}
                            >
                            <span className="other-list__input">
                              <span className="other-radio__body">
                                <input
                                  id={attr.code + e.id}
                                  className="other-radio__input"
                                  type="radio"
                                  name={attr.code}
                                  value={e.id}
                                  checked={state.selectedConfigs[attr.code].id === e.id}
                                  onChange={() => {
                                    handleChangeConfig(
                                      e.products,
                                      attr.id,
                                      attr.code,
                                      e,
                                    )
                                  }}
                                  disabled={isDisabled(e, attr.code)}
                                />
                              </span>
                            </span>
                              <span className="other-list__title">
                              {e.label}
                            </span>
                            </label>
                          )
                        })}
                      </div>
                    )}
                </div>
              )
            } else {
              return (
                <div className="attr_color_fms attr_space">
                  <div className="attr_label_size">{attr.label}</div>
                  {
                    attr.options
                    && attr.options.length > 1
                    && (
                      <div className="color-attr_fm">
                        {
                          attr.options.map((e, i) => {
                            return (
                              <div
                                key={i}
                                className="filter-color__item"
                                id={e.id + attr.code}
                              >
                          <span
                            className={classNames(
                              'filter-color__check input-check-color',
                              {
                                'input-check-color--white':
                                  colorType(e.swatch_value) === 'white',
                                'input-check-color--light':
                                  colorType(e.swatch_value) === 'light',
                              },
                            )}
                            style={{ color: `${e.label}`.toLowerCase() }}
                          >
                            <label className="input-check-color__body">
                              <input
                                id={attr.code + e.id}
                                className="input-check-color__input"
                                name={attr.code}
                                type="radio"
                                value={e.id}
                                checked={state.selectedConfigs[attr.code].id === e.id}
                                onChange={() => {
                                  handleChangeConfig(
                                    e.products,
                                    attr.id,
                                    attr.code,
                                    e,
                                  )
                                }}
                                disabled={isDisabled(e, attr.code)}
                              />
                              <span className="input-check-color__box"/>
                              <Check12x9Svg className="input-check-color__icon"/>
                              <span className="input-check-color__stick"/>
                            </label>
                          </span>
                              </div>
                            )
                          })
                        }
                      </div>
                    )
                  }
                </div>
              )
            }
          }
        })
      }
    </div>
  )
}


export default ConfigurableFilters

here is my example screenshot

this is my standard case

I want to get something like this for each combination, in this situation I dont have <50 & <100, so they are disabled, but it works with bugs, not always works for other products

In this product it is not working... I don't have "M" size, but it is enabled

"M" size must be disabled but it is active

Any suggestions or ideas??

and this is my configurableData

{
  "attributes": [
    {
      "id": 23,
      "code": "color",
      "label": "Color",
      "options": [
        {
          "_id": "6215cd906648a738081c765b",
          "id": 1,
          "admin_name": "Red",
          "attribute_id": 23,
          "sort_order": 1,
          "label": "Red",
          "translations": [
            {
              "locale": "en",
              "name": null
            },
            {
              "locale": "ru",
              "name": null
            }
          ],
          "products": [
            119,
            123,
            125
          ]
        },
        {
          "_id": "6215cd906648a738081c765c",
          "id": 2,
          "admin_name": "Green",
          "attribute_id": 23,
          "sort_order": 2,
          "label": "Green",
          "translations": [
            {
              "locale": "en",
              "name": null
            },
            {
              "locale": "ru",
              "name": null
            }
          ],
          "products": [
            120,
            122,
            124,
            126
          ]
        }
      ],
      "swatch_type": null,
      "product_id": 118
    },
    {
      "id": 24,
      "code": "size",
      "label": "Size",
      "options": [
        {
          "_id": "6215cd906648a738081c7660",
          "id": 6,
          "admin_name": "S",
          "attribute_id": 24,
          "sort_order": 1,
          "label": "S",
          "translations": [
            {
              "locale": "en",
              "name": null
            }
          ],
          "products": [
            119,
            120,
            123,
            124
          ]
        },
        {
          "_id": "6215cd906648a738081c7661",
          "id": 7,
          "admin_name": "M",
          "attribute_id": 24,
          "sort_order": 2,
          "label": "M",
          "translations": [
            {
              "locale": "en",
              "name": null
            }
          ],
          "products": [
            122,
            125,
            126
          ]
        }
      ],
      "swatch_type": null,
      "product_id": 118
    },
    {
      "id": 29,
      "code": "Papertype",
      "label": "Paper type",
      "options": [
        {
          "_id": "6215cd906648a738081c7669",
          "id": 15,
          "admin_name": "Type 1",
          "attribute_id": 29,
          "sort_order": 1,
          "label": "Type 1",
          "translations": [
            {
              "locale": "en",
              "name": null
            }
          ],
          "products": [
            119,
            120,
            122
          ]
        },
        {
          "_id": "6215cd906648a738081c766a",
          "id": 16,
          "admin_name": "Type 2",
          "attribute_id": 29,
          "sort_order": 2,
          "label": "Type 2",
          "translations": [
            {
              "locale": "en",
              "name": null
            }
          ],
          "products": [
            123,
            124,
            125,
            126
          ]
        }
      ],
      "swatch_type": null,
      "product_id": 118
    }
  ],
  "chooseText": "Choose an option",
  "index": {
    "119": {
      "23": "1",
      "24": "6",
      "29": "15"
    },
    "120": {
      "23": "2",
      "24": "6",
      "29": "15"
    },
    "122": {
      "23": "2",
      "24": "7",
      "29": "15"
    },
    "123": {
      "23": "1",
      "24": "6",
      "29": "16"
    },
    "124": {
      "23": "2",
      "24": "6",
      "29": "16"
    },
    "125": {
      "23": "1",
      "24": "7",
      "29": "16"
    },
    "126": {
      "23": "2",
      "24": "7",
      "29": "16"
    }
  }
}
0

There are 0 best solutions below