components#Header JavaScript Examples
The following examples show how to use
components#Header.
You can vote up the ones you like or vote down the ones you don't like,
and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: 404.jsx From emprezzo with MIT License | 6 votes |
ErrorPage = center => (
<Layout>
<Helmet title={'404'} />
<Header title="404" />
<Container center={center}>
<h1>Woops, something went wrong.</h1>
<h3>This page does not exist or is no longer reachable.</h3>
<h3>
You can return to the <Link to="/">Homepage</Link>.
</h3>
</Container>
</Layout>
)
Example #2
Source File: App.jsx From crypto-manager with MIT License | 6 votes |
render() {
const { classes, ...rest } = this.props;
return (
<div className={classes.wrapper}>
<Sidebar
routes={appRoutes}
logoText={"Crypto Manager"}
logo={logo}
image={image}
handleDrawerToggle={this.handleDrawerToggle}
open={this.state.mobileOpen}
color="blue"
{...rest}
/>
<div className={classes.mainPanel} ref="mainPanel">
<Header
routes={appRoutes}
handleDrawerToggle={this.handleDrawerToggle}
{...rest}
/>
{this.getRoute() ? (
<div className={classes.content}>
<div className={classes.container}>{switchRoutes}</div>
</div>
) : (
<div className={classes.map}>{switchRoutes}</div>
)}
{this.getRoute() ? <Footer /> : null}
</div>
</div>
);
}
Example #3
Source File: tags.jsx From emprezzo with MIT License | 6 votes |
Tags = ({ pageContext }) => {
const { tags } = pageContext;
return (
<Layout>
<Header title="all tags">all tags</Header>
<Container>
<TagsBlock list={tags} />
</Container>
</Layout>
);
}
Example #4
Source File: success.jsx From emprezzo with MIT License | 6 votes |
SuccessPage = () => (
<Layout>
<Helmet title={'Thanks for your submission'} />
<Header title="Thanks for your submission">? Discover exceptional retailers & innovative brands<br/>? Shop direct to support independent businesses</Header>
<Container center={{center:"true"}}>
<h3>Thanks for your submission!</h3>
<p>We will email you once we've had a chance to manually review your submission.</p>
</Container>
</Layout>
)
Example #5
Source File: submit_shop.jsx From emprezzo with MIT License | 6 votes |
Submit = () => (
<Layout>
<Helmet title={'Submit Shop'} />
<Header title="Submit a Shop">? Submit a new independent shop to add to the emprezzo database! </Header>
<Container center={{center:"true"}}>
<form id="submit_shop" action="/success" method="post" role="form" data-netlify="true" data-netlify-honeypot="bot-field">
<input type="hidden" name="form-name" value="submit_shop" />
Submit a new independent shop to add to the emprezzo database! <br/>All submissions will be manually reviewed for inclusion. <br/><br/>
Contact info
<div className="pair"><label><input type="text" name="name" placeholder="Your name" required /></label></div>
<div className="pair"><label><input type="email" name="email" placeholder="[email protected]" required /></label></div>
<br/>Shop details
<div className="pair"><label><input type="text" placeholder="Shop name" name="shop_name" required /></label></div>
<div className="pair"><label><input type="text" placeholder="Category" name="shop_category" required /></label></div>
<div className="pair"><label><input type="text" placeholder="example.com" name="shop_website" required /></label></div>
<div className="pair"><label><textarea name="message" placeholder="What makes this shop a good addition?" required></textarea></label></div>
<input type="submit" value="Submit" />
</form>
</Container>
</Layout>
)
Example #6
Source File: shopifytest.jsx From emprezzo with MIT License | 6 votes |
ShopifyTest = () => {
const [globalState, globalActions] = useGlobal();
const testuser = {
"email": "[email protected]",
"password": "HiZqFuDvDdQ7",
}
//globalActions.addToSavedShops();
React.useEffect(() => {
globalActions.getSavedShops();
}, [globalState.cfSavedStoresList]);
return (
<Layout>
<Helmet title={'Shopify Test'} />
<Header title="Shopify Test Page"></Header>
<Container>
</Container>
</Layout>
)
}
Example #7
Source File: savedstores.jsx From emprezzo with MIT License | 6 votes |
SavedStores = () => {
const [globalState, globalActions] = useGlobal();
return (
<Layout>
<Helmet title={'Saved Stores and Products'} />
<Header title="Saved Stores and Products"></Header>
{globalState.authenticated &&
<AuthWrapper>
<button className="button" onClick={globalActions.signoutUser}>LogOut</button>
</AuthWrapper>
}
{!globalState.authenticated &&
<AuthWrapper>
<button className="button" onClick={globalActions.openRegisterDialog}>Signup</button>
<button className="button" onClick={globalActions.openAuthDialog}>Login</button>
<ShopifyAuthentication />
</AuthWrapper>
}
<Section>
<DisplaySavedProducts />
<DisplaySavedStores />
</Section>
</Layout>
)
}
Example #8
Source File: gift-cards.jsx From emprezzo with MIT License | 6 votes |
GiftCard = (props) => {
return (
<Layout title={'Shop gift cards from hundreds of direct to consumer brands and indepdent retailers'} description="Discover and shop for digital gift cards and gift certificates from hundreds of amazing online stores. ">
<Header title="Shop gift cards" subtitle="Shop gift cards from hundreds of great shops" />
<SearchWrapper>
{/* <ShopifyCheckout uniqueComponentID="6155771576495" buttonText="BUY GIFT CARD" /> */}
<AlgoliaProductList
defaultSearchTerm={'gift card'}
facetsToShow={'category,brands,prices'}
showSearchBox={true}
hideCTAButton={false}
showClearFilter={true}
location={props.location}
/>
</SearchWrapper>
</Layout>
);
}
Example #9
Source File: contact.jsx From emprezzo with MIT License | 6 votes |
Submit = () => (
<Layout>
<Helmet title={'Contact emprezzo'} />
<Header title="Contact emprezzo">Submit questions, suggestions, partnership requests, etc</Header>
<Container center={{center:"true"}}>
<form id="contact" action="/success" method="post" role="form" data-netlify="true" data-netlify-honeypot="bot-field">
<input type="hidden" name="form-name" value="contact" />
emprezzo <br/>329 Primrose #117181<br/> Burlingame, CA 94402
<div className="pair"><label><input type="text" name="name" placeholder="Your name" required /></label></div>
<div className="pair"><label><input type="email" name="email" placeholder="[email protected]" required /></label></div>
<div className="pair"><label><textarea name="message" placeholder="message" required></textarea></label></div>
<input type="submit" value="Submit" />
</form>
</Container>
</Layout>
)
Example #10
Source File: chat.jsx From emprezzo with MIT License | 6 votes |
Chat = () => (
<Layout>
<Helmet title={'Chat'} />
<Header></Header>
<Container>
<ChatWidget />
</Container>
</Layout>
)
Example #11
Source File: singleitem.jsx From ecomloop.github.io with MIT License | 6 votes |
SingleItem = ({ data, pageContext }) => {
const { name, date, url, category, tags, amazonlink, sociallink, about, country, state, city, like } = data.googleSheetListRow
return (
<Layout>
<SEO
title={name}
description={about || ' '}
pathname={url}
/>
<Header title={name} date={date} />
<Container>
<br/ >URL = <Content input={url} />
<br/ >Category = <Content input={category} />
<br/ >Tags = <Content input={tags} />
<br/ >AmazonLink = <Content input={amazonlink} />
<br/ >SocialLink = <Content input={sociallink} />
<br/ >Country = <Content input={country} />
<br/ >City = <Content input={city} />
<br/ >State = <Content input={state} />
<br/ >Like = <Content input={like} />
</Container>
</Layout>
);
}
Example #12
Source File: blog.jsx From emprezzo with MIT License | 6 votes |
Blog = ({ data }) => {
const { edges } = data.allMarkdownRemark;
return (
<Layout>
<Helmet title={'Blog Page'} />
<Header title="Blog Page">Gatsby Tutorial Starter</Header>
{edges.map(({ node }) => (
<BlogList
key={node.id}
cover={node.frontmatter.cover.childImageSharp.fluid}
path={node.frontmatter.path}
title={node.frontmatter.title}
date={node.frontmatter.date}
tags={node.frontmatter.tags}
excerpt={node.excerpt}
/>
))}
</Layout>
);
}
Example #13
Source File: about.jsx From emprezzo with MIT License | 6 votes |
About = center => (
<Layout>
<Helmet title={'About'} />
<Header title="About">? Discover exceptional retailers & innovative brands<br/>? Shop direct to support independent businesses</Header>
<Container center={center}>
<p>
We help consumers discover, support& shop independent brands & retailers.
</p> <p>
Large platforms like Amazon and Target control an increasily large share of ecommerce sales. Platforms are convenient and great for deliveing basic goods. They are not good for find discovering the very best products.
</p> <p>
Support innovation among indepndenent brands by shopping directly.
</p> <p>
The list of shops is intended to grow over time, as is the functionality of the site. New submissions are always welcome.
</p>
</Container>
</Layout>
)
Example #14
Source File: authtest.jsx From emprezzo with MIT License | 6 votes |
About = center => (
<Layout>
<Helmet title={'Auth Test'} />
<Header title="Auth Test Page">? Discover exceptional retailers & innovative brands<br/>? Shop direct to support independent businesses</Header>
<Container center={center}>
<Authentication />
</Container>
</Layout>
)
Example #15
Source File: categories.jsx From emprezzo with MIT License | 5 votes |
Products = ({ data, pageContext }) => {
const { category } = pageContext;
const categoryHeading = category + " Shops";
const categoryGroup = data.allMysqlMainView.group;
//console.log(categoryGroup)
const rowProductsEdges = data.allMysqlShopifyView.edges;
const checkEdgesInProductView = (allEdges) => {
const filteredProducts = [];
allEdges.map((edge)=>{
const inputID = edge.node.UserName;
let result = _.filter(rowProductsEdges, ({ node }) => node.UserName == inputID)
//console.log(result)
if(result.length>0) filteredProducts.push(result[0]);
});
return filteredProducts;
}
const getProductVariant = (node) => {
let productVariant = null;
//if(node.VariantTitle && node.VariantTitle!=="Default Title") productVariant = node.VariantTitle;
return productVariant;
}
const getProductImage = (node) => {
let productImage = node.VariantImageURL;
if (!productImage) productImage = node.ImageURL;
return productImage;
}
const getPath = (node) => {
let path = node.VendorURL; // if there is no shop with instagram id then path will be vendor URL
//checking if the shop exists corresponding to this instagram id
const inputInstaID = node.UserName;
var result = _.filter(rowProductsEdges, ({ node }) => node.UserName == inputInstaID)
if (result.length > 0) path = "/shops/" + result[0].node.slug;
return path;
}
return (
<Layout title={'Top Shopify Products'} description="A mini shopify marketplace. Discover the best Shopify products from hundreds of stores in one place.">
<Header title="Top Shopify Products" />
{categoryGroup.map((category, index) => {
const allEdges = category.edges;
//console.log(allEdges)
//console.log("****** filtered")
const filteredProducts = checkEdgesInProductView(allEdges)
//console.log(filteredProducts)
//console.log("******* top 5")
const listEdges = _.slice(filteredProducts,0,5)
//console.log(listEdges)
return (
<div key={index}>
{listEdges.length>0 && category.fieldValue &&
<CategoryHeading>{category.fieldValue}</CategoryHeading>
}
<CategoryWrapper>
{category.fieldValue && listEdges.map(({ node }) => (
<ProductList
key={getProductImage(node)}
cover={getProductImage(node)}
path={getPath(node)}
vendorname={node.VendorName}
title={node.Title}
variant={getProductVariant(node)}
price={node.Price}
/>
))}
</CategoryWrapper>
</div>
)})}
</Layout>
);
}
Example #16
Source File: AppMain.jsx From crypto-manager with MIT License | 5 votes |
render() {
const { classes, ...rest } = this.props;
const path = this.props.location.pathname;
return (
<div>
{
path === "/signup" || path === "/login" ?
<div className={classes.content}>
<div className={classes.container}>{switchRoutes}</div>
</div> :
<div className={classes.wrapper}>
<Sidebar
routes={navRoutes}
logoText={"Crypto Manager"}
logo={logo}
image={image}
handleDrawerToggle={this.handleDrawerToggle}
open={this.state.mobileOpen}
color="blue"
{...rest}
/>
<div className={classes.mainPanel} ref="mainPanel">
<Header
routes={navRoutes}
handleDrawerToggle={this.handleDrawerToggle}
{...rest}
/>
{this.getRoute() ? (
<div className={classes.content}>
<div className={classes.container}>{switchRoutes}</div>
</div>
) : (
<div className={classes.map}>{switchRoutes}</div>
)}
{this.getRoute() ? <Footer /> : null}
</div>
</div>
}
</div>
);
}
Example #17
Source File: tag.jsx From emprezzo with MIT License | 5 votes |
Tag = ({ data, pageContext }) => {
const { posts, tagName } = pageContext;
const upperTag = tagName.charAt(0).toUpperCase() + tagName.slice(1);
const title = "Tag: " + tagName;
const description = `Discover the most popular direct to consumer ${tagName} stores on emprezzo.`
const listEdges = [];
const maxItems = 15;
const [limit, setLimit] = React.useState(maxItems);
const [showMore, setShowMore] = React.useState(true);
const increaseLimit = () => {
setLimit(limit + maxItems);
}
//Now sorting (desc) based on FollowerRate
var sortedEdges = _.sortBy(posts, obj => -obj.FollowerRate)
//filtering as per limit
sortedEdges.map((node) => {
if (listEdges.length < limit) {
listEdges.push(node);
}
})
const rowDataViewEdges = data.allMysqlDataView.edges;
const rowPages = data.allMysqlPages.edges;
const filteredPage = _.filter(rowPages, ({node}) => _.kebabCase(node.topic).trim()==tagName.trim())
const TagDescription = filteredPage && filteredPage.length>0?filteredPage[0].node.topicDescription : "";
return (
<Layout>
<SEO
title={`${title} | ${config.title}`}
description={description}
/>
<Header title={upperTag}>
{description}
</Header>
<TagWrapper>
<h3>{TagDescription}</h3>
{listEdges.map((node) => (
<PostList
key={node.UserName}
title={node.name}
excerpt={node.about}
path={`/shops/${node.UserName}/`}
mysqldataview={rowDataViewEdges}
instagramname={node.UserName}
/>
))}
</TagWrapper>
{showMore && listEdges.length > 0 && listEdges.length < posts.length &&
<div className="center">
<button className="button" onClick={increaseLimit}>
Load More
</button>
</div>
}
</Layout>
);
}
Example #18
Source File: post.jsx From emprezzo with MIT License | 5 votes |
Post = ({ data, pageContext }) => {
const { next, prev } = pageContext;
const {html, frontmatter, excerpt } = data.markdownRemark
const {date, title, tags, path, description} = frontmatter
const image = frontmatter.cover.childImageSharp.fluid;
return (
<Layout>
<SEO
title={title}
description={description || excerpt || ' '}
banner={image}
pathname={path}
article
/>
<Header title={title} date={date} cover={image} />
<Container>
<Content input={html} />
<TagsBlock list={tags || []} />
</Container>
<SuggestionBar>
<PostSuggestion>
{prev && (
<Link to={prev.frontmatter.path}>
Previous
<h3>{prev.frontmatter.title}</h3>
</Link>
)}
</PostSuggestion>
<PostSuggestion>
{next && (
<Link to={next.frontmatter.path}>
Next
<h3>{next.frontmatter.title}</h3>
</Link>
)}
</PostSuggestion>
</SuggestionBar>
</Layout>
);
}
Example #19
Source File: category.jsx From emprezzo with MIT License | 5 votes |
Category = ({ data, pageContext }) => {
const { category } = pageContext;
const categoryHeading = category + " Shops";
const { edges } = data.allMysqlMainView;
const listEdges = [];
const maxItems = 12;
const [limit, setLimit] = React.useState(maxItems);
const [showMore, setShowMore] = React.useState(true);
const increaseLimit = () => {
setLimit(limit + maxItems);
}
//filtering items as per limit
edges.map((edge) => {
if (listEdges.length < limit) {
listEdges.push(edge);
}
})
const rowDataViewEdges = data.allMysqlDataView.edges;
const getDetailsFromDataView = (AlexaURL) => {
const filteredDataView = _.filter(rowDataViewEdges, ({ node }) => node.AlexaURL == AlexaURL)
const firstRowDataView = filteredDataView && filteredDataView.length ? filteredDataView[0] : null;
return firstRowDataView
}
const getFullNameFromDataView = (AlexaURL) => {
const firstRowDataView = getDetailsFromDataView(AlexaURL)
return firstRowDataView && firstRowDataView.node.FullName;
}
const getBiographyFromDataView = (AlexaURL) => {
const firstRowDataView = getDetailsFromDataView(AlexaURL)
return firstRowDataView && firstRowDataView.node.Biography;
}
return (
<Layout title={'Shop Independent ' + categoryHeading + ' | Discover direct-to-consumer' + categoryHeading } >
<Header title={categoryHeading} subtitle={`discover exceptional independent ${categoryHeading}`} />
<CategoryWrapper>
{listEdges.map(({ node }) => (
<PostList
key={getFullNameFromDataView(node.AlexaURL,"FullName")}
path={`/shops/${node.UserName}/`}
title={getFullNameFromDataView(node.AlexaURL,"FullName")}
excerpt={getBiographyFromDataView(node.AlexaURL,"Biography") && getBiographyFromDataView(node.AlexaURL,"Biography").substring(0,40)+"..."}
mysqldataview={rowDataViewEdges}
instagramname={node.UserName}
/>
))}
</CategoryWrapper>
{showMore && listEdges.length > 0 && listEdges.length < edges.length &&
<div className="center">
<button className="button" onClick={increaseLimit}>
Load More
</button>
</div>
}
</Layout>
);
}
Example #20
Source File: alltags.jsx From emprezzo with MIT License | 5 votes |
Tags = ({ pageContext, data }) => {
const { tags } = pageContext;
const { edges } = data.allMysqlMainView;
const [countFilter, setCountFilter] = React.useState()
const title = "All Tags Page";
const lowerList = _.mapValues(tags, _.method('toLowerCase'));
const trimedList = _.mapValues(lowerList, _.method('trim'))
const uniqueList = _.uniq(Object.values(trimedList))
const orderdList = _.orderBy(uniqueList)
//remove blank tags
const filteredList = _.filter(orderdList, (tag) => (tag != null && tag.trim().length > 0))
const getPostsByTag = (tag) => {
//filter from trimmed and lowercase
const filteredPosts = _.filter(edges, ({ node }) => node.tags && node.tags.toLowerCase().indexOf(tag) >= 0)
return filteredPosts
}
//creating map of tags and its posts counts
let tagList = [];
const countList = [];
filteredList.map((tag) => {
const count = getPostsByTag(tag.trim()).length;
const newItem = {
tag: tag,
count: count
}
tagList.push(newItem)
countList.push(count)
});
const finalCountList = _.orderBy(_.uniq(countList))
const handleChange = (event) => {
let selectedOption = event.target.value;
setCountFilter(selectedOption)
//console.log(`Option selected:`, selectedOption);
}
//if countFilter is set then filter finaltag list
if (countFilter && countFilter.length > 0) {
tagList = _.filter(tagList, (item) => item.count == countFilter)
}
return (
<Layout>
<SEO
title={`${title} | ${config.title}`}
/>
<Header title={title}>All Tags</Header>
<Container>
<div style={{ display: "flex", verticalAlign: "middle" }}>
Filter based on count : {` `}
<select style={{ padding: "0.5rem" }} onChange={event => handleChange(event)}>
<option value=""></option>
{finalCountList.map((count) =>
<option key={count}>{count}</option>
)}
</select>
</div>
<TagsContainer>
{tagList && tagList.map((item, index) => {
//const upperTag = tag.charAt(0).toUpperCase() + tag.slice(1);
return (
<Link key={index} to={`/tags/${_.kebabCase(item.tag.trim())}`}>
<span>{item.tag} - </span><span className="count">{item.count}</span>
</Link>
);
})}
</TagsContainer>
</Container>
</Layout>
);
}
Example #21
Source File: index.jsx From emprezzo with MIT License | 5 votes |
Index = ({ data, location }) => {
return (
<Layout title={'emprezzo | Discover great independent online stores'} description="Discover the best online storess & direct-to-consumer brands" >
<Header title="Discover great online stores" subtitle="shop direct & support independent business"></Header>
{/* <p className="center"><a href ="/randomshop" className="button button">Discover a shop</a></p> */}
{/* <div className="center">
<a href="/randomshop/" className="button ">Discover a new shop</a>
</div>
<CheckoutWrapper>
<center style={{width: "-webkit-fill-available"}}><BuyGiftCard /></center>
</CheckoutWrapper>
*/}
<LazyLoad height={200} once offset={[-200, 0]}>
<ShopWrapper>
<AlgoliaProductList
facetsToShow={'category,prices,storeoffers,brands,payments,gifimage'}
showSearchBox={true}
hideCTAButton={true}
showSearchSuggestions={true}
showClearFilter={true}
enableCart={true}
enableShopProductSwitch={true}
searchIndexName={'uncommonry'}
location={location}
/>
</ShopWrapper>
</LazyLoad>
<ShopWrapper>
<h3>Discover the best independent shopping sites</h3>
<p>Shopping is heavily dominated by major retailers. As commerce increasingly shifts from physical to digital means, this balance has shifted more in favor of a small number of mega-retailers with one site making up nearly 50% of all online shopping. This isn't the way the internet was meant to be.</p>
<p>Consumers have shifted behaviours from shopping in a relatively open physical world to an environment where results beyond the first page or two are rarely seen. Rather than yielding fewer opportunities, digital commerce should open opportunities for a multitude of focused brands to make exceptional products for a physically widespread audience. </p>
<p>Major online retailers and marketplaces are convenient, but often don't feature the best brands and products. They charge high fees, sell knockoffs, and favor fast & cheap over innovative & enduring.</p>
<p>There are hundreds of brands that sell directly to consumers on their own sites. Many offer free shipping, discounts to new customers, and other perks of shopping directly. We developed a database of 500+ shops and 20,000+ products that can be searched and filtered by keywords, free shipping offers, price, return policies, etc. The database is constantly growing and updated with new data.</p>
<p>Help support independent business. Before making a purchase from a major retail site, search for an independent shopping alternative at emprezzo.</p>
</ShopWrapper>
</Layout >
);
}
Example #22
Source File: cart.jsx From emprezzo with MIT License | 5 votes |
Cart = () => (
<Layout>
<Helmet title={'Saved Products'} />
<Header>Saved Products</Header>
<DisplayCart />
</Layout>
)
Example #23
Source File: amazon-alternatives.jsx From emprezzo with MIT License | 4 votes |
AmazonAlternatives = ({ data }) => {
const { edges } = data.allMysqlMainView;
const maxItems = 12;
const [limit, setLimit] = React.useState(maxItems);
const [showMore, setShowMore] = React.useState(true);
const isMobile = useMediaQuery({ query: '(max-width: 600px)' })
const increaseLimit = () => {
setLimit(limit + maxItems);
}
const rowDataViewEdges = data.allMysqlDataView.edges;
const combinedEdges = [];
//Creating a new dataset with original nodes and required columns from DataView
edges.map((edge) => {
const inputID = edge.node.AlexaURL;
//filter to show only shops with DataView . AlexaCountry = United States
var resultData = _.filter(rowDataViewEdges, ({ node }) => (node.AlexaURL == inputID && node.AlexaCountry == "United States"))
var firstDataRow = null;
if (resultData.length > 0) {
firstDataRow = resultData[0]
let newNode = {
...edge.node,
...firstDataRow.node
}
combinedEdges.push(newNode);
}
})
//Now sorting (asc) based on LocalRank
var sortedEdges = _.sortBy(combinedEdges, obj => -obj.FollowerRate)
//Now limiting the items as per limit
const listEdges = _.slice(sortedEdges, 0, limit)
const defaultImageOnError = (e) => { e.target.src = "https://source.unsplash.com/100x100/?abstract," + (Math.random() * 1000) }
const renderProfilePicURL = (node) => {
if (node.mysqlImages && node.mysqlImages.length > 0) {
return (
<Image fluid={node.mysqlImages[0].childImageSharp.fluid} style={{ width: "50px", margin: '0px' }} title={node.about} alt={node.about} />
);
} else if (node.ProfilePicURL) {
return (
<img src={node.ProfilePicURL} className="profileimage" onError={defaultImageOnError} style={{ width: "50px", margin: '0px' }} title={node.about} alt={node.about} />
);
} else {
return (
<img src={"https://source.unsplash.com/100x100/?abstract," + (Math.random() * 1000)} className="profileimage" style={{ width: "50px", margin: '0px' }} title={node.about} alt={node.about} />
);
}
}
return (
<Layout title={'Amazon Alternatives for Online Shopping'} description='Discover amazing alternatives to the Amazon marketplace. Find amazon alernatives. Shop directly to support independent online stores.' >
<Header title="? Discover great Amazon alternatives for online shopping" subtitle=""></Header>
<ShopsWrapper>
<div className="intro_text">
<h3>Browse shopping alternatives to Amazon</h3>
<p>Independent online shops offer great amazon alternatives for shopping directly</p>
</div>
<TableWrapper>
<StickyTableWrapper>
<TableStickyHeader>
<thead>
<tr>
<th>#</th>
<th>Store</th>
{!isMobile &&
<>
<th></th>
<th>TrafficRank</th>
</>
}
<th>FollowerRate</th>
{!isMobile &&
<>
<th>Pinterest</th>
<th>Instagram</th>
<th>Twitter</th>
<th>Facebook</th>
<th>Tiktok</th>
<th>Youtube</th>
</>
}
</tr>
</thead>
<tbody>
{listEdges.map((node, index) => (
<tr key={index} id={`post-${index}`}>
<td>{index + 1}</td>
<td>
<Link to={`/shops/${node.UserName}/`}>
{renderProfilePicURL(node)}
</Link>
</td>
{!isMobile &&
<>
<td><Link to={`/shops/${node.UserName}/`}>{node.name}</Link></td>
<td>{node.LocalRank}</td>
</>
}
<td>{node.FollowerRate}</td>
{!isMobile &&
<>
<td>{node.PinFollowers || "-"}</td>
<td>{node.FollowersCount || "-"}</td>
<td>{node.TwitterFollowers || "-"}</td>
<td>{node.FBLikes || "-"}</td>
<td>{node.TTFollowers || "-"}</td>
<td>{node.YTSubs || "-"}</td>
</>
}
</tr>
))}
</tbody>
</TableStickyHeader>
</StickyTableWrapper>
</TableWrapper>
</ShopsWrapper>
{showMore && listEdges.length > 0 && listEdges.length < edges.length &&
<div className="center">
<button className="button" onClick={increaseLimit}>
Load More
</button>
</div>
}
<ShopsWrapper>
<div className="intro_text">
<h3>Discover the best Amazon marketplace alternatives for shoppping online</h3>
<p>Find some of the best anti-amazon shops and avoid the hassle of looking for amazon customer service.</p><p>Search for great Amazon shopping alternatives in header or <a href="/randomshop">discover a shop</a>.</p>
<h3>What makes a great alternative to the Amazon marketplace?</h3>
<p>The shops on this list are sell directly to customers via their online stores. Most offer free shipping, which is one of the major Amazon prime beneifts.</p>
<h3>How are the stores ranked?</h3>
<p>The stores are ranked based upon their SocialScore and overall web rank. The social score is derived from factors such as followers, fans, and activity on social media accounts. Web rank is based upon the websites estimated search engine ranking, as well as average time on site by visitors.</p>
<h3>Is this an anti-Amazon shopping list?</h3>
<p>This list of shopping alternatives is not intended to be anti-Amazon, per se. It exists to help find alternatives that consumers may not yet be aware.</p>
</div>
</ShopsWrapper>
</Layout>
);
}
Example #24
Source File: stores-that-accept-paypal.jsx From emprezzo with MIT License | 4 votes |
StoresWithPaypal = ({ data }) => {
const { edges } = data.allMysqlMainView;
const maxItems = 12;
const [limit, setLimit] = React.useState(maxItems);
const [showMore, setShowMore] = React.useState(true);
const isMobile = useMediaQuery({ query: '(max-width: 600px)' })
const increaseLimit = () => {
setLimit(limit + maxItems);
}
const rowRankViewEdges = data.allMysqlRankViewPaypal.edges;
const combinedEdges = [];
//Creating a new dataset with original nodes and required columns from DataView
edges.map((edge) => {
const inputID = edge.node.AlexaURL;
var resultRankView = _.filter(rowRankViewEdges, ({ node }) => node.AlexaURL == inputID)
if (resultRankView.length > 0) {
//now finding corresponding data from RankView
let newNode = {
...edge.node,
...resultRankView[0].node
}
combinedEdges.push(newNode);
}
})
//Now sorting (desc) based on activity
var sortedEdges = _.sortBy(combinedEdges, obj => -obj.FollowerRate)
//Now limiting the items as per limit
const listEdges = _.slice(sortedEdges, 0, limit)
return (
<Layout title={'Stores that accept PayPal | Shop sites that accept PayPal'} description='Stores that accept PayPal make it easy to checkout when shopping. Venmo and Paypal users can checkout quickly on sites that accept PayPal.'>
<Header title="? Discover top Shopify stores" subtitle=""></Header>
<ShopsWrapper>
<div className="intro_text">
<h3>Stores that accept PayPal</h3>
<p>Stores that accept PayPal make it easy to checkout</p>
</div>
<TableWrapper>
<StickyTableWrapper>
<TableStickyHeader>
<thead>
<tr>
<th>#</th>
<th>Store</th>
{!isMobile &&
<>
<th></th>
<th>TrafficRank</th>
</>
}
<th>FollowerRate</th>
{!isMobile &&
<>
<th>Pinterest</th>
<th>Instagram</th>
<th>Twitter</th>
<th>Facebook</th>
<th>Tiktok</th>
<th>Youtube</th>
</>
}
</tr>
</thead>
<tbody>
{listEdges.map((node, index) => (
<tr key={index} id={`post-${index}`}>
<td>{index + 1}</td>
<td>
{node.ProfilePicURL &&
<Link to={`/shops/${node.UserName}/`}>
<img src={node.ProfilePicURL} className="profileimage" style={{ width: "50px", margin: '0px' }} title={node.about} alt={node.about} />
</Link>
}
</td>
{!isMobile &&
<>
<td><Link to={`/shops/${node.UserName}/`} title={node.name}>{node.name}</Link></td>
<td>{node.GlobalRank}</td>
</>
}
<td>{node.FollowerRate}</td>
{!isMobile &&
<>
<td>{node.PinFollowers || "-"}</td>
<td>{node.InstaFollowers || "-"}</td>
<td>{node.TwitterFollowers || "-"}</td>
<td>{node.FBLikes || "-"}</td>
<td>{node.TTFollowers || "-"}</td>
<td>{node.YTSubs || "-"}</td>
</>
}
</tr>
))}
</tbody>
</TableStickyHeader>
</StickyTableWrapper>
</TableWrapper>
</ShopsWrapper>
{showMore && listEdges.length > 0 && listEdges.length < edges.length &&
<div className="center">
<button className="button" onClick={increaseLimit}>
Load More
</button>
</div>
}
<ShopsWrapper>
<div className="intro_text">
<h3>Discover stores that accept PayPal on Emprezzo</h3>
<p>Find stores that accept PayPal by traffic & social media activity. See some of the best PayPal stores.</p>
<h3>How is the list of stores that accept PayPal ranked?</h3>
<p>The stores are ranked based upon their SocialScore and overall web rank. The social score is derived from factors such as followers, fans, and activity on social media accounts. Web rank is based upon the websites estimated search engine ranking, as well as average time on site by visitors.</p>
</div>
</ShopsWrapper>
</Layout>
);
}
Example #25
Source File: top-shopify-stores.jsx From emprezzo with MIT License | 4 votes |
TopShopifyStores = ({ data }) => {
const { edges } = data.allMysqlMainView;
const maxItems = 20;
const [limit, setLimit] = React.useState(maxItems);
const [showMore, setShowMore] = React.useState(true);
const [showDialog, setShowDialog] = React.useState(false);
const [dialogText, setDialogText] = React.useState();
const [filterPaypalShopID, setFilterPaypalShopID] = React.useState(false);
const [filterFreeShipText, setFilterFreeShipText] = React.useState(false);
const [filterPayPalVenmoSupport, setFilterPayPalVenmoSupport] = React.useState(false);
const [filterBuyNowPayLater, setFilterBuyNowPayLater] = React.useState(false);
const [filterText, setFilterText] = React.useState("");
const [sliderAvgPrice, setSliderAvgPrice] = React.useState([0, 0]);
const [sliderPriceRange, setSliderPriceRange] = React.useState([0, 0]);
const [sortBy, setSortBy] = React.useState("GlobalRank_Change");
const changeSortBy = (e) => { setSortBy(e.target.value) }
const isMobile = useMediaQuery({ query: '(max-width: 600px)' })
const increaseLimit = () => {
setLimit(limit + maxItems);
}
let combinedEdges = [];
//Creating a new dataset with original nodes and required columns from PayNShip and allMysqlShopifyProductSummary
edges.map((edge) => {
let newNode = {
name: edge.node.name,
slug: edge.node.UserName,
...edge.node
}
const inputID = edge.node.AlexaURL;
const rowDataViewEdges = data.allMysqlDataView.edges;
var filteredDataView = _.filter(rowDataViewEdges, ({ node }) => (node.AlexaURL == inputID))
if (filteredDataView.length > 0) {
newNode = {
...newNode,
...filteredDataView[0].node
}
}
const rowPayNShipEdges = data.allMysqlPayNShip.edges;
var filteredPayNShip = _.filter(rowPayNShipEdges, ({ node }) => (node.URL == inputID))
if (filteredPayNShip.length > 0) {
newNode = {
...newNode,
...filteredPayNShip[0].node
}
}
const rowShopifyProductSummaryEdges = data.allMysqlShopifyProductSummary.edges;
var filteredShopifyProductSummary = _.filter(rowShopifyProductSummaryEdges, ({ node }) => (node.VendorURL == inputID))
if (filteredShopifyProductSummary.length > 0) {
newNode = {
...newNode,
...filteredShopifyProductSummary[0].node
}
}
combinedEdges.push(newNode);
})
if (sliderAvgPrice[0] == 0 && sliderAvgPrice[1] == 0) {
var minPriceAvg = _.minBy(combinedEdges, 'PriceAvg')
var maxPriceAvg = _.maxBy(combinedEdges, 'PriceAvg')
if(minPriceAvg && maxPriceAvg) {setSliderAvgPrice([minPriceAvg.PriceAvg, maxPriceAvg.PriceAvg])}
}
combinedEdges = _.filter(combinedEdges, item => sliderAvgPrice[0] <= item.PriceAvg && item.PriceAvg <= sliderAvgPrice[1])
if (sliderPriceRange[0] == 0 && sliderPriceRange[1] == 0 && combinedEdges.length > 0) {
var minPriceRange = _.minBy(combinedEdges, 'PriceMin')
var maxPriceRange = _.maxBy(combinedEdges, 'PriceMax')
if(minPriceRange && maxPriceRange) {setSliderPriceRange([minPriceRange.PriceMin, maxPriceRange.PriceMax])}
}
combinedEdges = _.filter(combinedEdges, item => sliderPriceRange[0] <= item.PriceMax && item.PriceMax <= sliderPriceRange[1])
const handerSliderAvgPriceChange = (event, newValue) => {
setSliderAvgPrice(newValue);
}
const handerSliderPriceRangeChange = (event, newValue) => {
setSliderPriceRange(newValue);
}
//Now sorting (desc) based on TotalFollowers
let listEdges = _.sortBy(combinedEdges, obj => sortBy == "GlobalRank" ? obj[sortBy] : -obj[sortBy])
//Apply filters if any of them is checked
if (filterPaypalShopID) {
listEdges = _.filter(listEdges, item => item.PaypalShopID != null)
}
if (filterFreeShipText) {
listEdges = _.filter(listEdges, item => item.FreeShipText != null && item.FreeShipText.trim().length > 0)
}
if (filterPayPalVenmoSupport) {
listEdges = _.filter(listEdges, item => item.PaypalVenmoSupport != null)
}
if (filterBuyNowPayLater) {
listEdges = _.filter(listEdges, item => item.AfterPay || item.Klarna || item.Affirm)
}
if (filterText && filterText.length > 0) {
listEdges = _.filter(listEdges, item =>
(item.name && item.name.toLowerCase().indexOf(filterText.toLowerCase()) >= 0)
|| (item.about && item.about.toLowerCase().indexOf(filterText.toLowerCase()) >= 0)
|| (item.tags && item.tags.toLowerCase().indexOf(filterText.toLowerCase()) >= 0)
|| (item.category && item.category.toLowerCase().indexOf(filterText.toLowerCase()) >= 0)
)
}
//Now limiting the items as per limit
listEdges = _.slice(listEdges, 0, limit)
const openMoreDialog = (node) => {
let dialogContent = "";
dialogContent += "<h1>" + node.name + "</h1>";
dialogContent += "<p>" + (node.about || "No Description Available") + "</p>";
dialogContent += "<p>" + (node.tags || "") + "</p>";
dialogContent += "<a href='" + node.AlexaURL + "'>Go to " + node.name + "</a><br/><br/>";
setDialogText(dialogContent);
setShowDialog(true);
}
const closeMoreDialog = () => setShowDialog(false);
const defaultImageOnError = (e) => { e.target.src = "https://source.unsplash.com/100x100/?abstract," + (Math.random() * 1000) }
const renderProfilePicURL = (node) => {
if (node.mysqlImages && node.mysqlImages.length > 0) {
return (
<Image fluid={node.mysqlImages[0].childImageSharp.fluid} style={{ width: "50px", margin: '0px' }} title={node.about} alt={node.about} />
);
} else if (node.ProfilePicURL) {
return (
<img src={node.ProfilePicURL} className="profileimage" onError={defaultImageOnError} style={{ width: "50px", margin: '0px' }} title={node.about} alt={node.about} />
);
} else {
return (
<img src={"https://source.unsplash.com/100x100/?abstract," + (Math.random() * 1000)} className="profileimage" style={{ width: "50px", margin: '0px' }} title={node.about} alt={node.about} />
);
}
}
return (
<Layout title={'Top Shopify Stores | Shop the most popular stores'} description='Discover top Shopify stores. Shop the best and most popular Shopify shop on emprezzo.'>
<Header title="? Discover top Shopify stores" subtitle=""></Header>
<Dialog isOpen={showDialog} onDismiss={closeMoreDialog}>
<span dangerouslySetInnerHTML={{ __html: dialogText }} />
<button onClick={closeMoreDialog}>
Close
</button>
</Dialog>
<ShopsWrapper>
<div className="intro_text">
<h3>Browse top Shopify stores</h3>
<p>Discover top Shopify sellers based upon organic search traffic and social media activity.</p>
</div>
<div style={{ display: "flex", width: "100%" }}>
<label>Filter Results:
<input type="text"
value={filterText}
onChange={(e) => setFilterText(e.target.value)}
/>
</label>
</div>
<div style={{ display: "flex", width: "100%" }}>
<label>
<input type="checkbox" style={{ margin: "0.5rem" }}
checked={filterPaypalShopID}
onChange={() => setFilterPaypalShopID(!filterPaypalShopID)}
/>
PayPal
</label>
<label>
<input type="checkbox" style={{ margin: "0.5rem" }}
checked={filterFreeShipText}
onChange={() => setFilterFreeShipText(!filterFreeShipText)}
/>
Free Shipping
</label>
<label>
<input type="checkbox" style={{ margin: "0.5rem" }}
checked={filterPayPalVenmoSupport}
onChange={() => setFilterPayPalVenmoSupport(!filterPayPalVenmoSupport)}
/>
Venmo
</label>
<label>
<input type="checkbox" style={{ margin: "0.5rem" }}
checked={filterBuyNowPayLater}
onChange={() => setFilterBuyNowPayLater(!filterBuyNowPayLater)}
/>
Buy now, pay later
</label>
</div>
<div style={{ width: "100%", display: "flex", justifyContent: "flex-end" }}>
Display by
<select value={sortBy} onChange={changeSortBy}>
<option value="GlobalRank">Traffic rank</option>
<option value="GlobalRank_Change">Rank change</option>
<option value="TotalFollowers">Total fans</option>
</select>
</div>
<div style={{ width: "80%", display: "flex" }}>
<span style={{ width: "20%" }}>Average Price : </span>
<Slider
value={sliderAvgPrice}
onChange={handerSliderAvgPriceChange}
min={0}
max={sliderAvgPrice[1] + 50}
valueLabelDisplay="auto"
aria-labelledby="range-slider-avg"
/>
</div>
<div style={{ width: "80%", display: "flex" }}>
<span style={{ width: "20%" }}>Price Range : </span>
<Slider
value={sliderPriceRange}
onChange={handerSliderPriceRangeChange}
min={0}
max={sliderPriceRange[1] + 50}
valueLabelDisplay="auto"
aria-labelledby="range-slider-range"
/>
</div>
<TableWrapper>
<StickyTableWrapper>
<TableStickyHeader>
<thead>
<tr>
<th style={{ width: "3%" }}><strong>#</strong></th>
<th style={{ width: "3%" }}></th>
<th><strong>Store</strong></th>
{!isMobile &&
<>
<th style={{ width: "20%" }}></th>
<th><strong>TrafficRank</strong></th>
</>
}
<th><strong>TotalFollowers</strong></th>
{!isMobile &&
<>
<th><strong>Avg Price</strong></th>
<th><strong>Price Range</strong></th>
<th><strong>Rank Change</strong></th>
</>
}
</tr>
</thead>
<tbody>
{listEdges.map((node, index) => (
<tr key={index} id={`post-${index}`}>
<td>{index + 1}</td>
<td><a href="javascript:void(0)" onClick={() => openMoreDialog(node)}>>></a></td>
<td>
<Link to={`/shops/${node.UserName}/`}>
{renderProfilePicURL(node)}
</Link>
</td>
{!isMobile &&
<>
<td><Link to={`/shops/${node.UserName}/`} title={node.name}>{node.name}</Link></td>
<td>{node.GlobalRank}</td>
</>
}
<td>{node.TotalFollowers}</td>
{!isMobile &&
<>
<td>${(node.PriceAvg || 0)}</td>
<td>${(node.PriceMin || 0)}{" - "}${(node.PriceMax || 0)}</td>
<td>{node.GlobalRank_Change}</td>
</>
}
</tr>
))}
</tbody>
</TableStickyHeader>
</StickyTableWrapper>
</TableWrapper>
</ShopsWrapper >
{ showMore && listEdges.length > 0 && listEdges.length < edges.length &&
<div className="center">
<button className="button" onClick={increaseLimit}>
Load More
</button>
</div>
}
<ShopsWrapper>
<div className="intro_text">
<h3>Discover top Shopify stores of 2020</h3>
<p>Find the top Shopify stores by traffic & social media activity. See some of the best Shopify store examples.</p><p>Search in header for more Shopify stores or <a href="/randomshop">discover a shop</a></p>
<h3>How is the list of top Shopify stores ranked?</h3>
<p>The stores are ranked based upon their SocialScore and overall web rank. The social score is derived from factors such as followers, fans, and activity on social media accounts. Web rank is based upon the websites estimated search engine ranking, as well as average time on site by visitors.</p>
<h3>What are some great Shopify stores examples? </h3>
<p>This list is an excellent resource for seeing examples of Shopify stores. These are some of the most popular Shopify stores and are great for getting ideas for your own store.</p>
<h3>What are Shopify stores?</h3>
<p>Shpoify stores are online stores running on the Shopify ecommece platorm. They are typically indpendent businesses selling directly to customers. The sites are hosted by Shopify, which generally handles the payment as well, making Shopify sites safe and secure.</p>
<h3>How many Shopify stores are there?</h3>
<p>As of July 2020, there are approximately 1,422,815 live Shopify sites. 3.6% of the top 1M sites are powerd by Shopify. 5.29% of the top 10k sites are powered by Shopify. </p>
</div>
</ShopsWrapper>
</Layout >
);
}
Example #26
Source File: shops.jsx From emprezzo with MIT License | 4 votes |
TopShopifyStores = ({ location, data }) => {
const { edges } = data.allMysqlMainView;
const maxItems = 20;
const [limit, setLimit] = React.useState(maxItems);
const [showMore, setShowMore] = React.useState(true);
const [showDialog, setShowDialog] = React.useState(false);
const [dialogText, setDialogText] = React.useState();
const [filterPaypalShopID, setFilterPaypalShopID] = React.useState(false);
const [filterFreeShipText, setFilterFreeShipText] = React.useState(false);
const [filterPayPalVenmoSupport, setFilterPayPalVenmoSupport] = React.useState(false);
const [filterBuyNowPayLater, setFilterBuyNowPayLater] = React.useState(false);
const [filterText, setFilterText] = React.useState("");
const [sliderAvgPrice, setSliderAvgPrice] = React.useState([0, 0]);
const [sliderPriceRange, setSliderPriceRange] = React.useState([0, 0]);
const [sortBy, setSortBy] = React.useState("GlobalRank_Change");
const [categoryFilter, setCategoryFilter] = React.useState("");
const changeSortBy = (e) => { setSortBy(e.target.value) }
const changeCategoryFilter = (e) => { setCategoryFilter(e.target.value) }
const allCategories = _.orderBy(_.uniq(Object.values(_.mapValues(edges, ({ node }) => node.category))))
const isMobile = useMediaQuery({ query: '(max-width: 600px)' })
const increaseLimit = () => {
setLimit(limit + maxItems);
}
React.useEffect(() => {
//checking if tag filter is present
if (location && location.search) {
const { tag } = queryString.parse(location.search);
setFilterText(tag.trim())
}
}, []);
let combinedEdges = [];
//Creating a new dataset with original nodes and required columns from PayNShip and allMysqlShopifyProductSummary
edges.map((edge) => {
let newNode = {
name: edge.node.name,
slug: edge.node.UserName,
...edge.node
}
const inputID = edge.node.AlexaURL;
const rowDataViewEdges = data.allMysqlDataView.edges;
var filteredDataView = _.filter(rowDataViewEdges, ({ node }) => (node.AlexaURL == inputID))
if (filteredDataView.length > 0) {
newNode = {
...newNode,
...filteredDataView[0].node
}
}
const rowPayNShipEdges = data.allMysqlPayNShip.edges;
var filteredPayNShip = _.filter(rowPayNShipEdges, ({ node }) => (node.URL == inputID))
if (filteredPayNShip.length > 0) {
newNode = {
...newNode,
...filteredPayNShip[0].node
}
}
const rowShopifyProductSummaryEdges = data.allMysqlShopifyProductSummary.edges;
var filteredShopifyProductSummary = _.filter(rowShopifyProductSummaryEdges, ({ node }) => (node.VendorURL == inputID))
if (filteredShopifyProductSummary.length > 0) {
newNode = {
...newNode,
...filteredShopifyProductSummary[0].node
}
}
combinedEdges.push(newNode);
})
if (sliderAvgPrice[0] == 0 && sliderAvgPrice[1] == 0) {
var minPriceAvg = _.minBy(combinedEdges, 'PriceAvg')
var maxPriceAvg = _.maxBy(combinedEdges, 'PriceAvg')
if (minPriceAvg && maxPriceAvg) { setSliderAvgPrice([minPriceAvg.PriceAvg, maxPriceAvg.PriceAvg]) }
}
combinedEdges = _.filter(combinedEdges, item => sliderAvgPrice[0] <= item.PriceAvg && item.PriceAvg <= sliderAvgPrice[1])
if (sliderPriceRange[0] == 0 && sliderPriceRange[1] == 0 && combinedEdges.length > 0) {
var minPriceRange = _.minBy(combinedEdges, 'PriceMin')
var maxPriceRange = _.maxBy(combinedEdges, 'PriceMax')
if (minPriceRange && maxPriceRange) { setSliderPriceRange([minPriceRange.PriceMin, maxPriceRange.PriceMax]) }
}
combinedEdges = _.filter(combinedEdges, item => sliderPriceRange[0] <= item.PriceMax && item.PriceMax <= sliderPriceRange[1])
const handerSliderAvgPriceChange = (event, newValue) => {
setSliderAvgPrice(newValue);
}
const handerSliderPriceRangeChange = (event, newValue) => {
setSliderPriceRange(newValue);
}
const sliderValueText = (value) => {
return value;
}
//Now sorting (desc) based on TotalFollowers
let listEdges = _.sortBy(combinedEdges, obj => sortBy == "GlobalRank" ? obj[sortBy] : -obj[sortBy])
//Apply filters if any of them is checked
if (filterPaypalShopID) {
listEdges = _.filter(listEdges, item => item.PaypalShopID != null)
}
if (filterFreeShipText) {
listEdges = _.filter(listEdges, item => item.FreeShipText != null && item.FreeShipText.trim().length > 0)
}
if (filterPayPalVenmoSupport) {
listEdges = _.filter(listEdges, item => item.PaypalVenmoSupport != null)
}
if (filterBuyNowPayLater) {
listEdges = _.filter(listEdges, item => item.AfterPay || item.Klarna || item.Affirm)
}
//applying category filter
if(categoryFilter.length>0) {
listEdges = _.filter(listEdges, item => item.category == categoryFilter)
}
if (filterText && filterText.length > 0) {
listEdges = _.filter(listEdges, item =>
(item.name && item.name.toLowerCase().indexOf(filterText.toLowerCase()) >= 0)
|| (item.about && item.about.toLowerCase().indexOf(filterText.toLowerCase()) >= 0)
|| (item.tags && item.tags.toLowerCase().indexOf(filterText.toLowerCase()) >= 0)
|| (item.category && item.category.toLowerCase().indexOf(filterText.toLowerCase()) >= 0)
)
}
//Now limiting the items as per limit
listEdges = _.slice(listEdges, 0, limit)
const openMoreDialog = (node) => {
let dialogContent = "";
dialogContent += "<h1>" + node.name + "</h1>";
dialogContent += "<p>" + (node.about || "No Description Available") + "</p>";
dialogContent += "<p>" + (node.tags || "") + "</p>";
dialogContent += "<a href='" + node.AlexaURL + "'>Go to " + node.name + "</a><br/><br/>";
setDialogText(dialogContent);
setShowDialog(true);
}
const closeMoreDialog = () => setShowDialog(false);
const defaultImageOnError = (e) => { e.target.src = "https://source.unsplash.com/100x100/?abstract," + (Math.random() * 1000) }
const renderProfilePicURL = (node) => {
if (node.mysqlImages && node.mysqlImages.length > 0) {
return (
<Image fluid={node.mysqlImages[0].childImageSharp.fluid} style={{ width: "50px", margin: '0px' }} title={node.about} alt={node.about} />
);
} else if (node.ProfilePicURL) {
return (
<img src={node.ProfilePicURL} className="profileimage" onError={defaultImageOnError} style={{ width: "50px", margin: '0px' }} title={node.about} alt={node.about} />
);
} else {
return (
<img src={"https://source.unsplash.com/100x100/?abstract," + (Math.random() * 1000)} className="profileimage" style={{ width: "50px", margin: '0px' }} title={node.about} alt={node.about} />
);
}
}
return (
<Layout title={'Discover great independent online stores'} description='Discover great independent online stores. Search hundreds of independent shops and direct-to-consumer brands. Filter by average price, free shipping, and more.'>
<Header title="Discover great independent online stores" subtitle="Search hundreds of independent shops and direct-to-consumer brands "></Header>
<ShopsWrapper>
<AlgoliaProductList
facetsToShow={'category,pricerangeslider,brands,storeoffers'}
showSearchBox={true}
showClearFilter={true}
searchIndexName={`uncommonry`}
location={location}
/>
</ShopsWrapper>
{/* <Dialog isOpen={showDialog} onDismiss={closeMoreDialog}>
<span dangerouslySetInnerHTML={{ __html: dialogText }} />
<button onClick={closeMoreDialog}>
Close
</button>
</Dialog>
<ShopsWrapper>
<div className="intro_text">
<h3>Discover Great Online Shops</h3>
<p>Discover popular independent stores and direct to consumer brands</p>
</div>
<div style={{ display: "flex", width: "100%", paddingBottom: "10px" }}>
<label>Filter by Category:
<select value={categoryFilter} onChange={changeCategoryFilter}>
<option value="">-</option>
{allCategories && allCategories.map(item => (
<option value={item}>{item}</option>
))}
</select>
</label>
</div>
<div style={{ display: "flex", width: "100%" }}>
<label>Filter Results:
<input type="text"
value={filterText}
onChange={(e) => setFilterText(e.target.value)}
/>
</label>
</div>
<div style={{ display: "flex", width: "100%" }}>
<label>
<input type="checkbox" style={{ margin: "0.5rem" }}
checked={filterPaypalShopID}
onChange={() => setFilterPaypalShopID(!filterPaypalShopID)}
/>
PayPal
</label>
<label>
<input type="checkbox" style={{ margin: "0.5rem" }}
checked={filterFreeShipText}
onChange={() => setFilterFreeShipText(!filterFreeShipText)}
/>
Free Shipping
</label>
<label>
<input type="checkbox" style={{ margin: "0.5rem" }}
checked={filterPayPalVenmoSupport}
onChange={() => setFilterPayPalVenmoSupport(!filterPayPalVenmoSupport)}
/>
Venmo
</label>
<label>
<input type="checkbox" style={{ margin: "0.5rem" }}
checked={filterBuyNowPayLater}
onChange={() => setFilterBuyNowPayLater(!filterBuyNowPayLater)}
/>
Buy now, pay later
</label>
</div>
<div style={{ width: "100%", display: "flex", justifyContent: "flex-end" }}>
Display by
<select value={sortBy} onChange={changeSortBy}>
<option value="GlobalRank">Traffic rank</option>
<option value="GlobalRank_Change">Rank change</option>
<option value="TotalFollowers">Total fans</option>
</select>
</div>
<div style={{ width: "80%", display: "flex" }}>
<span style={{ width: "20%" }}>Average Price : </span>
<Slider
value={sliderAvgPrice}
onChange={handerSliderAvgPriceChange}
min={0}
max={sliderAvgPrice[1] + 50}
valueLabelDisplay="auto"
aria-labelledby="range-slider-avg"
/>
</div>
<div style={{ width: "80%", display: "flex" }}>
<span style={{ width: "20%" }}>Price Range : </span>
<Slider
value={sliderPriceRange}
onChange={handerSliderPriceRangeChange}
min={0}
max={sliderPriceRange[1] + 50}
valueLabelDisplay="auto"
aria-labelledby="range-slider-range"
/>
</div>
<TableWrapper>
<StickyTableWrapper>
<TableStickyHeader>
<thead>
<tr>
<th style={{ width: "3%" }}><strong>#</strong></th>
<th style={{ width: "3%" }}></th>
<th><strong>Store</strong></th>
{!isMobile &&
<>
<th style={{ width: "20%" }}></th>
<th><strong>TrafficRank</strong></th>
</>
}
<th><strong>TotalFollowers</strong></th>
{!isMobile &&
<>
<th><strong>Avg Price</strong></th>
<th><strong>Price Range</strong></th>
<th><strong>Rank Change</strong></th>
</>
}
</tr>
</thead>
<tbody>
{listEdges.map((node, index) => (
<tr key={index} id={`post-${index}`}>
<td>{index + 1}</td>
<td><a href="javascript:void(0)" onClick={() => openMoreDialog(node)}>>></a></td>
<td>
<Link to={`/shops/${node.UserName}/`}>
{renderProfilePicURL(node)}
</Link>
</td>
{!isMobile &&
<>
<td><Link to={`/shops/${node.UserName}/`} title={node.name}>{node.name}</Link></td>
<td>{node.GlobalRank}</td>
</>
}
<td>{node.TotalFollowers}</td>
{!isMobile &&
<>
<td>${(node.PriceAvg || 0)}</td>
<td>${(node.PriceMin || 0)}{" - "}${(node.PriceMax || 0)}</td>
<td>{node.GlobalRank_Change}</td>
</>
}
</tr>
))}
</tbody>
</TableStickyHeader>
</StickyTableWrapper>
</TableWrapper>
</ShopsWrapper >
{ showMore && listEdges.length > 0 && listEdges.length < edges.length &&
<div className="center">
<button className="button" onClick={increaseLimit}>
Load More
</button>
</div>
} */}
<ShopsWrapper>
</ShopsWrapper>
</Layout >
);
}
Example #27
Source File: buynow-paylater-stores.jsx From emprezzo with MIT License | 4 votes |
StoresWithPaylater = ({ data }) => {
const { edges } = data.allMysqlMainView;
const maxItems = 12;
const [limit, setLimit] = React.useState(maxItems);
const [showMore, setShowMore] = React.useState(true);
const isMobile = useMediaQuery({ query: '(max-width: 600px)' })
const increaseLimit = () => {
setLimit(limit + maxItems);
}
const rowRankViewEdges = data.allMysqlRankViewPayLater.edges;
const combinedEdges = [];
//Creating a new dataset with original nodes and required columns from DataView
edges.map((edge) => {
const inputID = edge.node.AlexaURL;
var resultRankView = _.filter(rowRankViewEdges, ({ node }) => node.AlexaURL == inputID)
if (resultRankView.length > 0) {
//now finding corresponding data from RankView
let newNode = {
...edge.node,
...resultRankView[0].node
}
combinedEdges.push(newNode);
}
})
//Now sorting (desc) based on activity
var sortedEdges = _.sortBy(combinedEdges, obj => -obj.FollowerRate)
//Now limiting the items as per limit
const listEdges = _.slice(sortedEdges, 0, limit)
const defaultImageOnError = (e) => { e.target.src = "https://source.unsplash.com/100x100/?abstract,"+(Math.random()*1000) }
return (
<Layout title={'Buy now, pay later stores | Find online stores that accept layaway payments'} description='Find online stores that offer buy now, pay later payment options like Klarna, Afteray, Affirm. Shop stores with layaway payment plans and flexible payment options. '>
<Header title="? Buy now, pay later stores" subtitle=""></Header>
<ShopsWrapper>
<div className="intro_text">
<h3>Find Buy now, pay later stores</h3>
<p>Discover buy now, pay later stores that accept layaway payments like Klarna, Afterpay, Affirm </p>
</div>
<TableWrapper>
<StickyTableWrapper>
<TableStickyHeader>
<thead>
<tr>
<th>#</th>
<th>Store</th>
{!isMobile &&
<>
<th></th>
<th>TrafficRank</th>
</>
}
<th>FollowerRate</th>
{!isMobile &&
<>
<th>Pinterest</th>
<th>Instagram</th>
<th>Twitter</th>
<th>Facebook</th>
<th>Tiktok</th>
<th>Youtube</th>
</>
}
</tr>
</thead>
<tbody>
{listEdges.map((node, index) => (
<tr key={index} id={`post-${index}`}>
<td>{index + 1}</td>
<td>
{node.ProfilePicURL &&
<Link to={`/shops/${node.UserName}/`}>
<img src={node.ProfilePicURL} className="profileimage" onError={defaultImageOnError} style={{ width: "50px", margin: '0px' }} title={node.about} alt={node.about} />
</Link>
}
</td>
{!isMobile &&
<>
<td><Link to={`/shops/${node.UserName}/`} title={node.name}>{node.name}</Link></td>
<td>{node.GlobalRank}</td>
</>
}
<td>{node.FollowerRate}</td>
{!isMobile &&
<>
<td>{node.PinFollowers || "-"}</td>
<td>{node.InstaFollowers || "-"}</td>
<td>{node.TwitterFollowers || "-"}</td>
<td>{node.FBLikes || "-"}</td>
<td>{node.TTFollowers || "-"}</td>
<td>{node.YTSubs || "-"}</td>
</>
}
</tr>
))}
</tbody>
</TableStickyHeader>
</StickyTableWrapper>
</TableWrapper>
</ShopsWrapper>
{showMore && listEdges.length > 0 && listEdges.length < edges.length &&
<div className="center">
<button className="button" onClick={increaseLimit}>
Load More
</button>
</div>
}
<ShopsWrapper>
<div className="intro_text">
<h3>Discover sites with buy now, pay later payment options</h3>
<p>Find online stores that offer buy now, pay later payment options like Klarna, Afteray, Affirm. Shop stores with layaway payment plans and flexible payment options. </p>
<h3>How is the list of stores with buy now, pay later ranked?</h3>
<p>The stores are ranked based upon their SocialScore and overall web rank. The social score is derived from factors such as followers, fans, and activity on social media accounts. Web rank is based upon the websites estimated search engine ranking, as well as average time on site by visitors.</p>
<h3>WHat are some examples of buy now, pay later payment options?</h3>
<p>Klarna, Affirm, and Afterpay are some examples of buy now, pay later.</p>
</div>
</ShopsWrapper>
</Layout>
);
}
Example #28
Source File: products.jsx From emprezzo with MIT License | 4 votes |
Products = ({ data, pageContext, location }) => {
const rowallMysqlShopifyProductsAllEdges = data.allMysqlShopifyProductsAll ? data.allMysqlShopifyProductsAll.edges : [];
const mainViewEdges = data.allMysqlMainView.edges;
const maxFeaturedItems = 15;
const maxProducts = 25;
const [limit, setLimit] = React.useState(maxFeaturedItems);
const [showMore, setShowMore] = React.useState(true);
const [filter, setFilter] = React.useState([]);
const isMobile = useMediaQuery({ query: '(max-width: 600px)' })
const maxItems = 25;
const [sortBy, setSortBy] = React.useState("UpdateDate");
const [sortOrder, setSortOrder] = React.useState("DESC");
const [categoryFilter, setCategoryFilter] = React.useState("");
const [priceRangeMin, setPriceRangeMin] = React.useState();
const [priceRangeMax, setPriceRangeMax] = React.useState();
const changeSortBy = (e) => { setSortBy(e.target.value) }
const changeSortOrder = (e) => { setSortOrder(e.target.value) }
const changeCategoryFilter = (e) => { setCategoryFilter(e.target.value) }
const allCategories = _.orderBy(_.uniq(Object.values(_.mapValues(mainViewEdges, ({ node }) => node.category))))
const responsive = {
desktop: {
breakpoint: { max: 3000, min: 1024 },
items: 5,
slidesToSlide: 5 // optional, default to 1.
},
tablet: {
breakpoint: { max: 1024, min: 464 },
items: 2,
slidesToSlide: 2 // optional, default to 1.
},
mobile: {
breakpoint: { max: 464, min: 0 },
items: 1,
slidesToSlide: 1 // optional, default to 1.
}
};
const checkEdgesInProductView = (allEdges) => {
let filteredProducts = [];
allEdges.map((edge) => {
const inputID = edge.node.AlexaURL;
const result = _.filter(rowallMysqlShopifyProductsAllEdges, ({ node }) => node.VendorURL == inputID && node.Price > 20 && node.Title.toLowerCase().indexOf("gift") < 0 && node.Title.toLowerCase().indexOf("test") < 0 && node.Title.toLowerCase().indexOf("shipping") < 0)
const sortedResult = _.sortBy(result, ({ node }) => -node.PublishedDate);
const max2Results = _.slice(sortedResult, 0, 2);//max 2 products from a store
//add shop details to products
let combinedMax2Results = [];
max2Results.map((maxedge) => {
combinedMax2Results.push({
node: {
...maxedge.node,
...edge.node,
}
});
})
filteredProducts = _.union(filteredProducts, combinedMax2Results)
});
return filteredProducts;
}
const getProductVariant = (node) => {
let productVariant = null;
//if(node.VariantTitle && node.VariantTitle!=="Default Title") productVariant = node.VariantTitle;
return productVariant;
}
const getProductImage = (node) => {
let productImage = node.VariantImageURL;
if (!productImage) productImage = node.ImageURL;
return productImage;
}
//get featured shops
const featuredShopEdges = _.filter(mainViewEdges, ({ node }) => node.tags && node.tags.indexOf("featured") >= 0)
//if filter is present then filter and show from all products, else just show products from featured shops
const filteredFeaturedProducts = (filter && filter.length > 3) ? checkEdgesInProductView(mainViewEdges) : checkEdgesInProductView(featuredShopEdges);
//Now limiting the featured items as per limit
const visibleFeaturedProducts = _.slice(filteredFeaturedProducts, 0, maxFeaturedItems);
const filteredProducts = checkEdgesInProductView(mainViewEdges);
//Now limiting the featured items as per limit
const visibleProducts = _.slice(filteredProducts, 0, maxItems);
const increaseLimit = () => {
setLimit(limit + maxItems);
}
let listShopifyProductsAllEdges = [];
//Creating a new dataset with original product nodes and shop columns from MainView
rowallMysqlShopifyProductsAllEdges.map((edge) => {
let newNode = {
...edge.node
}
const inputID = edge.node.VendorURL;
var filteredMainViewEdges = _.filter(mainViewEdges, ({ node }) => (node.AlexaURL == inputID))
if (filteredMainViewEdges.length > 0) {
newNode = {
...newNode,
...filteredMainViewEdges[0].node
}
}
listShopifyProductsAllEdges.push({
node: {
...newNode
}
});
})
//Extracting sale products
const filteredShopifySaleProducts = _.sortBy(_.filter(listShopifyProductsAllEdges, ({ node }) => node.DiscountPct > 0.20 && node.DiscountPct < 1), ({ node }) => -node.UpdateDate);
const listShopifySaleProducts = _.slice(filteredShopifySaleProducts, 0, maxProducts);
//Extracting gift cards
const filteredShopifyGiftCards = _.sortBy(_.filter(listShopifyProductsAllEdges, ({ node }) => node.Title.toLowerCase().indexOf("gift card") >= 0), ({ node }) => -node.UpdateDate);
const listShopifyGiftCards = _.slice(filteredShopifyGiftCards, 0, maxProducts);
//applying category filter
if (categoryFilter.length > 0) {
listShopifyProductsAllEdges = _.filter(listShopifyProductsAllEdges, ({ node }) => node.category == categoryFilter)
}
//apply filter for slider on price
if (priceRangeMin) {
listShopifyProductsAllEdges = _.filter(listShopifyProductsAllEdges, ({ node }) => priceRangeMin <= node.Price)
}
if (priceRangeMax) {
listShopifyProductsAllEdges = _.filter(listShopifyProductsAllEdges, ({ node }) => node.Price <= priceRangeMax)
}
//apply filtertext if its greater than 3 characters
if (filter && filter.length > 3) {
listShopifyProductsAllEdges = _.filter(listShopifyProductsAllEdges, ({ node }) => node.VendorName.toLowerCase().indexOf(filter.toLowerCase()) >= 0 || node.Title.toLowerCase().indexOf(filter.toLowerCase()) >= 0)
}
//Now applying sorting
listShopifyProductsAllEdges = _.sortBy(listShopifyProductsAllEdges, ({ node }) => sortOrder != "DESC" ? node[sortBy] : -node[sortBy])
//Now limiting the items as per limit
listShopifyProductsAllEdges = _.slice(listShopifyProductsAllEdges, 0, limit)
if (listShopifyProductsAllEdges.length >= rowallMysqlShopifyProductsAllEdges.length) setShowMore(false);
return (
<Layout title={'Discover great products from independent brands'} description="Search thousands of products from independent stores and direct-to-consumer brands. Shop the emprezzo marketplace alternative to discover great products support independent businesses.">
<Header title="emprezzo product marketplace" description="? Discover great products from independent brands" />
<div>
<CategoryHeading>Discover great products</CategoryHeading>
<SearchWrapper>
<AlgoliaProductList
facetsToShow={'category,brands,storeoffers'}
showSearchBox={true}
showClearFilter={true}
location={location}
/>
</SearchWrapper>
</div>
</Layout>
);
}
Example #29
Source File: shop.jsx From emprezzo with MIT License | 4 votes |
SingleItem = ({ data, pageContext }) => {
const { next, prev } = pageContext;
//Extracting Posts from MySQL Data
const maxPosts = 3;
const listPostEdges = [];
const rowDataViewEdges = data.allMysqlDataView.edges;
//filtering top 3 for current instagram id
rowDataViewEdges.map((edge) => {
if (listPostEdges.length < maxPosts) {
listPostEdges.push(edge);
}
})
const firstRowDataView = listPostEdges && listPostEdges.length ? listPostEdges[0] : null;
//Now filtering instagram posts if the image or caption is not present
const listInstaPostEdges = [];
listPostEdges.map((edge) => {
if (edge.node.PhotoLink && edge.node.Caption) {
listInstaPostEdges.push(edge);
}
})
//Extracting Products from MySQL Data
const maxProducts = 5;
const listProductEdges = [];
const rowShopifyViewEdges = data.allMysqlShopifyView.edges;
//filtering top 3 for current instagram id
rowShopifyViewEdges.map((edge) => {
if (listProductEdges.length < maxProducts) {
listProductEdges.push(edge);
}
})
const subtitle = ((firstRowDataView && firstRowDataView.node.AlexaCountry) || "")
const about = ((firstRowDataView && firstRowDataView.node.Biography) || "")
const name = ((firstRowDataView && firstRowDataView.node.FullName) || "")
const url = ((firstRowDataView && firstRowDataView.node.AlexaURL) || "")
const image = (firstRowDataView && firstRowDataView.node.ProfilePicURL);
//Creating Social IDs Data to pass to header for displaying
let socialDetails = {
"InstagramLink": (firstRowDataView && firstRowDataView.node.Instagram) ? "https://www.instagram.com/" + (firstRowDataView && firstRowDataView.node.Instagram) : null,
"FacebookLink": (firstRowDataView && firstRowDataView.node.Facebook) ? "https://www.facebook.com/" + (firstRowDataView && firstRowDataView.node.Facebook) : null,
"PinterestLink": (firstRowDataView && firstRowDataView.node.Pinterest) ? "https://www.pinterest.com/" + (firstRowDataView && firstRowDataView.node.Pinterest) : null,
"TikTokLink": (firstRowDataView && firstRowDataView.node.TikTok) ? "https://www.tiktok.com/" + (firstRowDataView && firstRowDataView.node.TikTok) : null,
"TwitterLink": (firstRowDataView && firstRowDataView.node.Twitter) ? "https://www.twitter.com/" + (firstRowDataView && firstRowDataView.node.Twitter) : null,
"YouTubeLink": (firstRowDataView && firstRowDataView.node.YouTube) ? "https://www.youtube.com/c/" + (firstRowDataView && firstRowDataView.node.YouTube) : null
}
const defaultImageOnError = (e) => { e.target.src = "https://source.unsplash.com/100x100/?abstract," + (Math.random() * 1000) }
const renderProfilePicURL = (node, name) => {
if (node.mysqlImages && node.mysqlImages.length > 0) {
return (
<Image fluid={node.mysqlImages[0].childImageSharp.fluid} style={{ width: '100px', height: '100px' }} title={name} alt={name} />
);
} else if (node.ProfilePicURL) {
return (
<img src={node.ProfilePicURL} className="profileimage" onError={defaultImageOnError} style={{ width: '100px', height: '100px' }} title={name} alt={name} />
);
} else {
return (
<img src={"https://source.unsplash.com/100x100/?abstract," + (Math.random() * 1000)} className="profileimage" style={{ width: '100px', height: '100px' }} title={name} alt={name} />
);
}
}
return (
<Layout>
<SEO
title={name}
description={about || ' '}
banner={image}
pathname={url}
/>
<Header title={name} children={subtitle} socialDetails={socialDetails} />
<Container>
<div className="profileimage" style={{ display: "flex" }}>
{firstRowDataView && renderProfilePicURL(firstRowDataView.node, name)}
<div style={{ paddingLeft: "15px" }}>
<Statistics>
{firstRowDataView && (firstRowDataView.node.activity || firstRowDataView.node.FollowerRate || firstRowDataView.node.PostRate) &&
<StatisticItem><a target="_blank" href={firstRowDataView && firstRowDataView.node.ShortCodeURL}><StatisticIcon src="/instagram_icon.png" alt={instagramname} width="15px" height="15px" max-width="25px" /></a></StatisticItem>
}
{firstRowDataView && firstRowDataView.node.activity &&
<StatisticItem>{firstRowDataView.node.activity} <br /><span className="stat_title" title="Instagram Activity Score">ACTIVITY</span></StatisticItem>
}
{firstRowDataView && firstRowDataView.node.FollowerRate &&
<StatisticItem>{firstRowDataView.node.FollowerRate} <br /><span className="stat_title" title="*Instagram Follower Rate">FFR</span></StatisticItem>
}
{firstRowDataView && firstRowDataView.node.PostRate &&
<StatisticItem>{firstRowDataView.node.PostRate} <br /><span className="stat_title" title="Instagram Post Rate">PFR</span></StatisticItem>
}
</Statistics>
<Statistics>
{firstRowDataView && (firstRowDataView.node.GlobalRank || firstRowDataView.node.LocalRank || firstRowDataView.node.TOS) &&
<StatisticItem><StatisticIcon width="15px" height="15px" max-width="25px" /></StatisticItem>
}
{firstRowDataView && firstRowDataView.node.GlobalRank &&
<StatisticItem>{firstRowDataView.node.GlobalRank} <br /><span className="stat_title" title="Social Score">GLOBAL RANK</span></StatisticItem>
}
{firstRowDataView && firstRowDataView.node.LocalRank &&
<StatisticItem>{firstRowDataView.node.LocalRank} <br /><span className="stat_title" title="">LOCAL RANK</span></StatisticItem>
}
{firstRowDataView && firstRowDataView.node.TOS &&
<StatisticItem>{firstRowDataView.node.TOS} <br /><span className="stat_title" title="Time on Site">TIME ON SITE</span></StatisticItem>
}
</Statistics>
</div>
</div>
<Content input={about} /><br />
{/* List of Products from MySQL View */}
{listProductEdges && listProductEdges.length > 0 && <h3>shop {name}</h3>}
<ViewContainer>
{listProductEdges.map(({ node }) => {
return (
<ViewCard key={node.ProductURL} itemWidth="18%">
<a href={node.ProductURL} target="_blank">
<ViewImage>
<img src={node.ImageURL} style={{ height: "100px" }} />
</ViewImage>
</a>
<small>${node.Price}</small>
<ViewInfo className="info">
<a href={node.ProductURL} target="_blank">
{node.Title && node.Title.substring(0, 50)}
</a>
</ViewInfo>
</ViewCard>
);
})}
<br />
{/* List of Posts from MySQL View */}
{listInstaPostEdges && listInstaPostEdges.length > 0 && <h3>instagram posts</h3>}
<ViewContainer>
{listInstaPostEdges.map(({ node }) => {
return (
<ViewCard key={node.PhotoLink} itemWidth="30%">
<a href={node.ShortCodeURL} target="_blank">
<ViewImage>
<img src={node.PhotoLink} />
</ViewImage>
</a>
<ViewInfo className="info">
{node.Caption && node.Caption.substring(0, 140) + "..."}
</ViewInfo>
</ViewCard>
);
})}
</ViewContainer>
</ViewContainer><br />
<a href="/randomshop" className="button ">Discover another shop</a>
</Container>
<SuggestionBar>
<PostSuggestion>
{prev && (
<Link to={`/shops/${prev.slug}/`}>
<p>< {prev.name}</p>
</Link>
)}
</PostSuggestion>
<PostSuggestion>
{next && (
<Link to={`/shops/${next.slug}/`}>
<p>{next.name} ></p>
</Link>
)}
</PostSuggestion>
</SuggestionBar>
</Layout>
);
}