Skip to content

Instantly share code, notes, and snippets.

@luismec90
Created March 14, 2019 23:31
Show Gist options
  • Save luismec90/58ad84e34cea6dcbdbf9b7da883a1db0 to your computer and use it in GitHub Desktop.
Save luismec90/58ad84e34cea6dcbdbf9b7da883a1db0 to your computer and use it in GitHub Desktop.
import React, { useState, useEffect } from 'react';
import gql from 'graphql-tag';
import { Query } from 'react-apollo';
import { sortable } from 'react-sortable';
import SelectAutoComplete from '../../../common/SelectAutoComplete';
import { ButtonSmall } from '../../../styles/theme';
const GET_ALL_CATEGORIES = gql`
query getAllCategories {
getAllCategories {
id
name
}
}
`;
const CATEGORY_BY_ID = gql`
query categoryById($id: ID!) {
categoryById(id: $id) {
id
name
frames {
id
name
featuredProducts {
id
name
images {
path
}
}
products {
id
name
images {
path
}
}
}
}
}
`;
function Frame(props) {
return <div {...props}>{props.children}</div>;
}
function FeaturedProduct(props) {
return (
<div className="col-md-4" {...props}>
{props.children}
</div>
);
}
const SortableFrame = sortable(Frame);
const SortableFeaturedProduct = sortable(FeaturedProduct);
function CustomizeCategory(props) {
const [frames, setFrames] = useState([]);
const [categoryId, setCategoryId] = useState(null);
useEffect(() => {
console.log({ frames });
}, [frames]);
const handleSelectCategoriesChange = selectedCategory => {
setFrames([]);
setCategoryId(selectedCategory.id);
};
const handleSelectProductsChange = (selectedProduct, payload) => {
const newFrames = frames.map(frame => {
if (frame.id != payload.frameId) {
return frame;
}
const product = frame.products.find(
product => selectedProduct.id == product.id
);
console.log([...frame.featuredProducts, product]);
const newFrame = {
...frame,
featuredProducts: [...frame.featuredProducts, product]
};
return newFrame;
});
setFrames(newFrames);
};
const removeFeaturedProduct = (frameId, featuredProductId) => {
const newFrames = frames.map(frame => {
if (frame.id != frameId) {
return frame;
}
const featuredProducts = frame.featuredProducts.filter(
featuredProduct => featuredProduct.id != featuredProductId
);
const newFrame = {
...frame,
featuredProducts: featuredProducts
};
return newFrame;
});
setFrames(newFrames);
};
const getNotFeaturedProducts = (products, featuredProducts) => {
return products.filter(product => {
const exist = featuredProducts.find(
featuredProduct => product.id == featuredProduct.id
);
return !exist;
});
};
const onSortFrames = frames => {
setFrames([...frames]);
};
const onSortFeaturedProducts = (frameId, featuredProducts) => {
featuredProducts = featuredProducts.filter(
featuredProduct => !!featuredProduct
);
const newFrames = frames.map(frame => {
if (frame.id != frameId) {
return frame;
}
const newFrame = {
...frame,
featuredProducts: featuredProducts
};
return newFrame;
});
setFrames(newFrames);
};
const sortableFrames = frames => {
console.log({ sortableFrames: frames });
return frames.map((frame, i) => {
return (
<SortableFrame
key={i}
onSortItems={items => onSortFrames(items)}
items={frames}
sortId={i}
>
<div key={frame.id}>
<h4 className="text-left mt-3">{frame.name}</h4>
<div className="row mb-3">
<div className="col-md-3">
<SelectAutoComplete
data={getNotFeaturedProducts(
frame.products,
frame.featuredProducts
)}
payload={{
frameId: frame.id
}}
cleanInputAfterSelection={true}
handleChange={handleSelectProductsChange}
/>
</div>
</div>
{frame.products && (
<div className="row mb-5 sortable-list">
{sortableFeaturedProducts(frame.id, frame.featuredProducts)}
</div>
)}
</div>
</SortableFrame>
);
});
};
const sortableFeaturedProducts = (frameId, featuredProducts) =>
featuredProducts.map((featuredProduct, i) => {
return (
<SortableFeaturedProduct
key={i}
onSortItems={items => onSortFeaturedProducts(frameId, items)}
items={featuredProducts}
sortId={i}
>
<div key={featuredProduct.id}>
<div className="card">
<div
id={`carousel-product-${featuredProduct.id}`}
className="carousel slide"
data-ride="carousel"
>
<div className="carousel-inner">
{featuredProduct.images.map((image, index) => {
return (
<div
key={index}
className={`carousel-item ${
index == 0 ? 'active' : ''
}`}
>
<img
src={image.path}
className="d-block w-100"
alt={featuredProduct.name}
/>
</div>
);
})}
</div>
<a
className="carousel-control-prev"
href={`#carousel-product-${featuredProduct.id}`}
role="button"
data-slide="prev"
>
<span
className="carousel-control-prev-icon"
aria-hidden="true"
/>
<span className="sr-only">Previous</span>
</a>
<a
className="carousel-control-next"
href={`#carousel-product-${featuredProduct.id}`}
role="button"
data-slide="next"
>
<span
className="carousel-control-next-icon"
aria-hidden="true"
/>
<span className="sr-only">Next</span>
</a>
</div>
<div className="card-body p-3">
<h5 className="card-title mb-0">{featuredProduct.name}</h5>
<ButtonSmall
type="button"
danger
onClick={() => {
removeFeaturedProduct(frameId, featuredProduct.id);
}}
>
Remove
</ButtonSmall>
</div>
</div>
</div>
</SortableFeaturedProduct>
);
});
console.log({ frames });
return (
<div>
<h3 className="mb-4">Customize Categories</h3>
<div className="row">
<div className="col-md-3">
<SelectAutoComplete
query={GET_ALL_CATEGORIES}
queryName="getAllCategories"
handleChange={handleSelectCategoriesChange}
/>
</div>
</div>
{categoryId && (
<div className="row">
<div className="col-md-12">
<Query
query={CATEGORY_BY_ID}
variables={{ id: categoryId }}
fetchPolicy="network-only"
>
{({ loading, error, data }) => {
if (loading) return null;
if (error) return `Error!: ${error}`;
if (frames.length == 0) {
setFrames(data.categoryById.frames);
}
return <div className="mt-4">{sortableFrames(frames)}</div>;
}}
</Query>
</div>
</div>
)}
</div>
);
}
export default CustomizeCategory;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment