Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import PropTypes from 'prop-types'
- import React from 'react'
- import { swapOptions, validationStatuses } from 'Core/constants'
- import { Select } from '../../../../FormElements'
- import { AddButton } from '../AddButton'
- import { RemoveButton } from '../RemoveButton'
- import { connect } from 'react-redux'
- import { getFlattenCategories } from 'SRC/modules/categories/selectors'
- import { AdsBrandsApi } from 'SRC/modules/ads/brands/api'
- import { AdsProductsApi } from 'SRC/modules/ads/products/api'
- import {
- setFormField,
- unsetFormField,
- setFormForValidationField,
- unsetFormForValidationField,
- setFormFieldValidity
- } from '../../../../../actions'
- import { requiredValidator } from 'Core/validators'
- import { getFieldValidity } from '../../../../../selectors'
- export class Swap extends React.Component {
- constructor (props) {
- super(props)
- this.maxSwapCount = 3
- this.state = {
- swapCounter: 1,
- selectedSwap: null,
- swapps: [this.getDefaultSwapState()]
- }
- }
- getDefaultSwapState = () => ({
- selectedCategory: null,
- categoryOptions: {},
- brands: [],
- isBrandsLoading: true,
- selectedBrand: null,
- products: [],
- isProductsLoading: true,
- selectedProduct: null,
- specificationValues1: [],
- selectedSpecification1: null,
- specificationValues2: [],
- selectedSpecification2: null
- })
- getSwapField = () => ({
- id: 'swapp',
- title: 'Zamjena',
- name: 'swapp',
- options: swapOptions.map(item => ({label: item.title, value: item.value})),
- onChange: this.onSwapChange,
- isRequired: true
- })
- getSwappsArray = () => {
- const swapps = []
- for (let i = 0; i < this.state.swapCounter; i++) {
- swapps.push(i)
- }
- return swapps
- }
- getSwapItem = (index) => {
- const items = []
- if (this.state.swapCounter > 1 && index > 0) {
- items.push({
- type: 'button'
- })
- }
- if (this.state.selectedSwap && this.state.selectedSwap !== 'No') {
- items.push({
- id: `swapps-category-${index}`,
- type: 'select',
- title: 'Kategorija',
- name: 'category',
- options: this.props.categories
- .filter(category => category.swappPresence)
- .map(category => ({label: category.title, value: category.id})),
- isRequired: true,
- onChange: this.onCategoryChange,
- isNeedSaveValueToStore: false,
- isNeedValidate: false,
- onFocus: this.onFocus,
- onBlur: this.onBlur,
- index
- })
- if (this.state.swapps[index] && this.state.swapps[index].selectedCategory) {
- if (this.isBrandAvailableForCategory(this.state.swapps[index].categoryOptions)) {
- items.push({
- id: `swapps-brand-${index}`,
- type: 'select',
- title: 'Proizvođač',
- name: 'brand',
- options: this.state.swapps[index].brands,
- onChange: this.onBrandChange,
- isRequired: true,
- isLoading: this.state.swapps[index].isBrandsLoading,
- isNeedSaveValueToStore: false,
- isNeedValidate: false,
- onFocus: this.onFocus,
- onBlur: this.onBlur,
- index
- })
- }
- if (this.isProductAvailableForCategory(this.state.swapps[index].categoryOptions)) {
- items.push({
- id: `swapps-product-${index}`,
- type: 'select',
- title: 'Model',
- name: 'product',
- options: this.state.swapps[index].products,
- isRequired: true,
- isLoading: this.state.swapps[index].isProductsLoading,
- onChange: this.onProductChange,
- isNeedSaveValueToStore: false,
- isNeedValidate: false,
- onFocus: this.onFocus,
- onBlur: this.onBlur,
- index
- })
- }
- if (this.isSpecificationsAvailableForCategory(this.state.swapps[index].categoryOptions)) {
- if (this.state.swapps[index].categoryOptions.swappSpecification1) {
- items.push({
- id: 'swapps-specification-1',
- type: 'select',
- title: `${this.state.swapps[index].categoryOptions.swappSpecification1.title}`,
- name: 'specification1',
- options: this.state.swapps[index].specificationValues1,
- value: this.state.swapps[index].selectedSpecification1,
- isNeedSaveValueToStore: false,
- isNeedValidate: false,
- onChange: this.onSpecificationChange1,
- index
- })
- }
- if (this.state.swapps[index].categoryOptions.swappSpecification2) {
- items.push({
- id: 'swapps-specification-2',
- type: 'select',
- title: `${this.state.swapps[index].categoryOptions.swappSpecification2.title}`,
- name: 'specification2',
- options: this.state.swapps[index].specificationValues2,
- value: this.state.swapps[index].selectedSpecification2,
- isNeedSaveValueToStore: false,
- isNeedValidate: false,
- onChange: this.onSpecificationChange2,
- index
- })
- }
- }
- }
- }
- return items
- }
- onSwapChange = async e => {
- const value = e.target.value
- await this.setState(prevState => {
- return {
- ...this.state,
- selectedSwap: value,
- swapps: prevState.selectedSwap && prevState.selectedSwap !== 'No' && (value === 'No' || !value) ? [] : prevState.swapps,
- swapCounter: 1
- }
- })
- if (value === 'No' || !value) {
- this.unsetSwappsValuesFromStore()
- this.unsetSwappsFieldsForValidation()
- } else {
- this.setSwappsFieldsForValidation()
- }
- }
- onCategoryChange = async e => {
- const value = Number(e.target.value)
- const index = Number(e.target.dataset.index)
- const filteredCategory = this.props.categories.filter(item => item.id === value)
- let categoryOptions = {}
- if (filteredCategory.length) {
- categoryOptions = {
- requiredAdOptions: filteredCategory[0].requiredAdOptions,
- swappSpecification1: filteredCategory[0].swappSpecification1,
- swappSpecification2: filteredCategory[0].swappSpecification2
- }
- }
- await this.saveSwappsToState(index, {
- selectedCategory: value,
- categoryOptions,
- brands: [],
- selectedBrand: null,
- products: [],
- specificationValues1: [],
- selectedSpecification1: null,
- specificationValues2: [],
- selectedSpecification2: null
- })
- this.setSwappsValuesInStore()
- this.setSwappsFieldsForValidation()
- if (this.isBrandAvailableForCategory(categoryOptions)) {
- await this.loadBrandsToState(value, index)
- }
- if (this.isSpecificationsAvailableForCategory(categoryOptions)) {
- await this.loadSpecificationsToState(index)
- }
- }
- isBrandAvailableForCategory = (category = {}) => {
- return category && (category.requiredAdOptions === 'BrandModel' || category.requiredAdOptions === 'BrandOnly')
- }
- isProductAvailableForCategory = (category = {}) => {
- return category && category.requiredAdOptions === 'BrandModel'
- }
- isSpecificationsAvailableForCategory = (category = {}) => {
- return category &&
- (category.requiredAdOptions === 'BrandOnly' || category.requiredAdOptions === null) &&
- (category.swappSpecification1 || category.swappSpecification2)
- }
- loadBrandsToState = async (category, index) => {
- await this.saveSwappsToState(index, {
- isBrandsLoading: true
- })
- const api = new AdsBrandsApi()
- const brands = await api.getBrandsByCategory(category)
- await this.saveSwappsToState(index, {
- brands: brands.map(brand => ({label: brand.name, value: brand.id})),
- isBrandsLoading: false
- })
- }
- onBrandChange = async e => {
- const value = Number(e.target.value)
- const index = Number(e.target.dataset.index)
- await this.saveSwappsToState(index, {
- selectedBrand: value,
- products: [],
- selectedProduct: null
- })
- this.setSwappsValuesInStore()
- this.setSwappsFieldsForValidation()
- if (this.isProductAvailableForCategory(this.state.swapps[index].categoryOptions)) {
- await this.loadProductsToState(value, index)
- }
- }
- loadProductsToState = async (brand, index) => {
- await this.saveSwappsToState(index, {
- isProductsLoading: true
- })
- const api = new AdsProductsApi()
- const products = await api.fetchProductsByBrand(brand)
- await this.saveSwappsToState(index, {
- products: products.map(product => ({label: product.model, value: product.id})),
- isProductsLoading: false
- })
- }
- onProductChange = async e => {
- const value = Number(e.target.value)
- const index = Number(e.target.dataset.index)
- await this.saveSwappsToState(index, {
- selectedProduct: value
- })
- this.setSwappsValuesInStore()
- this.setSwappsFieldsForValidation()
- }
- onSpecificationChange1 = async e => {
- const value = e.target.value
- const index = Number(e.target.dataset.index)
- await this.saveSwappsToState(index, {
- selectedSpecification1: value
- })
- this.setSwappsValuesInStore()
- this.setSwappsFieldsForValidation()
- }
- onSpecificationChange2 = async e => {
- const value = e.target.value
- const index = Number(e.target.dataset.index)
- await this.saveSwappsToState(index, {
- selectedSpecification2: value
- })
- this.setSwappsValuesInStore()
- this.setSwappsFieldsForValidation()
- }
- loadSpecificationsToState = async (index) => {
- if (this.state.swapps[index] && this.state.swapps[index].categoryOptions) {
- if (
- this.state.swapps[index].categoryOptions.swappSpecification1 &&
- this.state.swapps[index].categoryOptions.swappSpecification1.options
- ) {
- const options = this.state.swapps[index].categoryOptions.swappSpecification1.options.map((item) => ({
- value: item,
- label: item
- }))
- await this.saveSwappsToState(index, {
- specificationValues1: options
- })
- }
- }
- if (
- this.state.swapps[index].categoryOptions.swappSpecification2 &&
- this.state.swapps[index].categoryOptions.swappSpecification2.options
- ) {
- const options = this.state.swapps[index].categoryOptions.swappSpecification2.options.map((item) => ({
- value: item,
- label: item
- }))
- await this.saveSwappsToState(index, {
- specificationValues2: options
- })
- }
- }
- saveSwappsToState = async (index, fields) => {
- await this.setState(prevState => {
- const newSwapps = prevState.swapps
- newSwapps[index] = {...prevState.swapps[index], ...fields}
- return prevState
- })
- }
- onAddSwappsClick = async () => {
- await this.setState(prevState => {
- prevState.swapps.push(this.getDefaultSwapState())
- return {
- ...prevState,
- swapCounter: prevState.swapCounter + 1
- }
- })
- this.setSwappsValuesInStore()
- this.setSwappsFieldsForValidation()
- }
- onRemoveSwappsClick = async e => {
- const index = Number(e.target.dataset.index)
- await this.setState(prevState => {
- const newSwapps = prevState.swapps.filter((item, i) => index !== i)
- return {
- ...prevState,
- swapCounter: prevState.swapCounter - 1,
- swapps: newSwapps
- }
- })
- this.setSwappsValuesInStore()
- this.setSwappsFieldsForValidation()
- }
- isShouldRenderAddButton = () =>
- this.state.swapCounter < this.maxSwapCount &&
- this.state.selectedSwap &&
- this.state.selectedSwap !== 'No'
- setSwappsValuesInStore = () => {
- const swapps = []
- this.state.swapps.forEach(item => {
- const value = {}
- if (item.selectedCategory) {
- value.category = item.selectedCategory
- }
- if (item.selectedBrand) {
- value.brand = item.selectedBrand
- }
- if (item.selectedProduct) {
- value.product = item.selectedProduct
- }
- if (item.selectedSpecification1) {
- value.specificaton1 = item.categoryOptions.swappSpecification1.id
- value.specificatonValue1 = item.selectedSpecification1
- }
- if (item.selectedSpecification2) {
- value.specificaton2 = item.categoryOptions.swappSpecification2.id
- value.specificatonValue2 = item.selectedSpecification2
- }
- if (Object.keys(value).length) {
- swapps.push(value)
- }
- })
- if (swapps.length) {
- this.props.setFormField('swapps', swapps)
- }
- }
- unsetSwappsValuesFromStore = () => {
- this.props.unsetFormField('swapps')
- }
- setSwappsFieldsForValidation = () => {
- const swapps = this.getSwappsFieldForValidation()
- if (swapps.length) {
- this.props.setFormForValidationField('swapps', swapps)
- }
- }
- getSwappsFieldForValidation = () => {
- const swapps = []
- this.state.swapps.forEach(item => {
- const value = {}
- value.category = null
- if (item.selectedCategory && this.isBrandAvailableForCategory(item.categoryOptions)) {
- value.brand = null
- }
- if (item.selectedBrand && this.isProductAvailableForCategory(item.categoryOptions)) {
- value.product = null
- }
- if (Object.keys(value).length) {
- swapps.push(value)
- }
- })
- return swapps
- }
- unsetSwappsFieldsForValidation = () => {
- this.props.unsetFormForValidationField('swapps')
- }
- validate = () => {
- const values = []
- const swapps = this.getSwappsFieldForValidation()
- swapps.map((swapItem, index) => {
- if (Object.keys(swapItem).length) {
- const value = {}
- for (let field in swapItem) {
- if (swapItem.hasOwnProperty(field)) {
- value[field] = requiredValidator(this.getSwappsValueFromState(index, field))
- ? validationStatuses.VALID : validationStatuses.INVALID
- }
- }
- values.push(value)
- }
- })
- return values
- }
- getSwappsValueFromState = (index, field) => {
- if (field) {
- switch (field) {
- case 'category':
- return this.state.swapps[index].selectedCategory
- case 'brand':
- return this.state.swapps[index].selectedBrand
- case 'product':
- return this.state.swapps[index].selectedProduct
- default:
- return null
- }
- } else {
- return null
- }
- }
- onFocus = e => {
- const name = e.target.name
- const index = Number(e.target.dataset.index)
- const swapps = [...this.props.validity]
- swapps[index] = {
- ...swapps[index],
- [name]: validationStatuses.VALID
- }
- this.props.setFormFieldValidity('swapps', swapps)
- }
- onBlur = e => {
- const name = e.target.name
- const index = Number(e.target.dataset.index)
- const value = e.target.value
- const swapps = [...this.props.validity]
- swapps[index] = {
- ...swapps[index],
- [name]: requiredValidator(value) ? validationStatuses.VALID : validationStatuses.INVALID
- }
- this.props.setFormFieldValidity('swapps', swapps)
- }
- render () {
- return [
- <Select {...this.getSwapField()} key='swapp' />,
- this.getSwappsArray().map(
- index => <div
- className={`ads-add__swap-row ${index === 0 ? `ads-add__swap-row_first` : ''}`}
- key={`swapps-row-${index}`}
- >
- {
- this.getSwapItem(index).map(item => {
- const isError = this.props.validity && this.props.validity[index] && this.props.validity[index][item.name]
- ? this.props.validity[index][item.name] === validationStatuses.INVALID
- : false
- return item.type === 'button'
- ? <RemoveButton index={index} onClick={this.onRemoveSwappsClick} key={`remove-swapps-${index}`} />
- : <Select {...item} key={`swapps-${item.id}`} isError={isError} />
- })
- }
- </div>
- ),
- this.isShouldRenderAddButton() ? <AddButton onClick={this.onAddSwappsClick} key='add-swapps' /> : null
- ]
- }
- }
- const mapStateToProps = (state) => ({
- categories: getFlattenCategories(state),
- validity: getFieldValidity(state, 'swapps')
- })
- Swap.propTypes = {
- categories: PropTypes.arrayOf(PropTypes.shape({
- title: PropTypes.string.isRequired,
- id: PropTypes.number.isRequired,
- swappPresence: PropTypes.bool.isRequired,
- requiredAdOptions: PropTypes.oneOf(['BrandModel', 'BrandOnly', 'Services', null]),
- swappSpecification1: PropTypes.shape({
- id: PropTypes.number.isRequired,
- title: PropTypes.string.isRequired,
- options: PropTypes.arrayOf(PropTypes.string)
- }),
- swappSpecification2: PropTypes.shape({
- id: PropTypes.number.isRequired,
- title: PropTypes.string.isRequired,
- options: PropTypes.arrayOf(PropTypes.string)
- })
- })).isRequired,
- setFormField: PropTypes.func.isRequired,
- unsetFormField: PropTypes.func.isRequired,
- setFormForValidationField: PropTypes.func.isRequired,
- unsetFormForValidationField: PropTypes.func.isRequired,
- setFormFieldValidity: PropTypes.func.isRequired,
- validity: PropTypes.any
- }
- Swap.defaultProps = {
- categories: []
- }
- export default connect(
- mapStateToProps,
- {setFormField, unsetFormField, setFormForValidationField, unsetFormForValidationField, setFormFieldValidity},
- null,
- {withRef: true}
- )(Swap)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement