Compare commits
33 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f8e48020dc | |||
| d97258e922 | |||
| 35f78c7022 | |||
| dc3cf8b3f0 | |||
| f51a3ab6fa | |||
| 2435200b8c | |||
| 01e89b7ba1 | |||
| bb8bc9980f | |||
| bf21d82702 | |||
| 9a138e53a9 | |||
| d510189905 | |||
| 75730c5053 | |||
| e77a502035 | |||
| a61a5ed701 | |||
| 8ca3a9d677 | |||
| 4ffeb8e6a4 | |||
| 7ff7ad9d87 | |||
| 7a7c99df8b | |||
| 23dfd7a049 | |||
| 43bd65bf31 | |||
| 51f3bc837b | |||
| 2305cffd09 | |||
| 3c6b68ec3a | |||
| e7dcdcea54 | |||
| 979b14f9ef | |||
| f2a58ee3b1 | |||
| 24af7f48c4 | |||
| 51e22921ce | |||
| 2833f79d99 | |||
| f55c694b93 | |||
| 4637905bea | |||
| 70c226f4f0 | |||
| 267eaa66d5 |
@@ -0,0 +1,48 @@
|
|||||||
|
name: Build Action
|
||||||
|
run-name: Test is testing out Gitea Actions 🚀
|
||||||
|
on:
|
||||||
|
# schedule:
|
||||||
|
# - cron: '* * * * *'
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- 'develop'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
Run-Build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Use Node.js 20.x
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 20.11.0
|
||||||
|
- name: Install Yarn
|
||||||
|
run: npm install -g yarn
|
||||||
|
- name: Yarn cache
|
||||||
|
uses: actions/cache@v3
|
||||||
|
id: yarn-cache
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
${{ steps.yarn-cache-dir.outputs.dir }}
|
||||||
|
node_modules
|
||||||
|
*/node_modules
|
||||||
|
*/*/node_modules
|
||||||
|
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/yarn.lock') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-build-${{ env.cache-name }}-
|
||||||
|
${{ runner.os }}-build-
|
||||||
|
${{ runner.os }}-
|
||||||
|
- name: Build App
|
||||||
|
run: |
|
||||||
|
yarn
|
||||||
|
yarn build
|
||||||
|
- name: Deploy
|
||||||
|
uses: SamKirkland/FTP-Deploy-Action@v4.3.5
|
||||||
|
with:
|
||||||
|
server: mycloud.dp.ua
|
||||||
|
username: d.tkachenko
|
||||||
|
port: 2121
|
||||||
|
password: ${{ secrets.FTP_PASSWORD }}
|
||||||
|
local-dir: ./public/
|
||||||
|
server-dir: /web/poc-dev/
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
name: Build Action
|
||||||
|
run-name: Test is testing out Gitea Actions 🚀
|
||||||
|
on:
|
||||||
|
# schedule:
|
||||||
|
# - cron: '* * * * *'
|
||||||
|
push:
|
||||||
|
branches:
|
||||||
|
- 'main'
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
Run-Build:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout code
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
- name: Use Node.js 20.x
|
||||||
|
uses: actions/setup-node@v3
|
||||||
|
with:
|
||||||
|
node-version: 20.11.0
|
||||||
|
- name: Install Yarn
|
||||||
|
run: npm install -g yarn
|
||||||
|
- name: Yarn cache
|
||||||
|
uses: actions/cache@v3
|
||||||
|
id: yarn-cache
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
${{ steps.yarn-cache-dir.outputs.dir }}
|
||||||
|
node_modules
|
||||||
|
*/node_modules
|
||||||
|
*/*/node_modules
|
||||||
|
key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/yarn.lock') }}
|
||||||
|
restore-keys: |
|
||||||
|
${{ runner.os }}-build-${{ env.cache-name }}-
|
||||||
|
${{ runner.os }}-build-
|
||||||
|
${{ runner.os }}-
|
||||||
|
- name: Build App
|
||||||
|
run: |
|
||||||
|
yarn
|
||||||
|
yarn build
|
||||||
|
- name: Deploy
|
||||||
|
uses: SamKirkland/FTP-Deploy-Action@v4.3.5
|
||||||
|
with:
|
||||||
|
server: mycloud.dp.ua
|
||||||
|
username: d.tkachenko
|
||||||
|
port: 2121
|
||||||
|
password: ${{ secrets.FTP_PASSWORD }}
|
||||||
|
local-dir: ./public/
|
||||||
|
server-dir: /web/poc/
|
||||||
@@ -6,7 +6,6 @@ module.exports = {
|
|||||||
siteUrl: 'https://www.yourdomain.tld',
|
siteUrl: 'https://www.yourdomain.tld',
|
||||||
},
|
},
|
||||||
plugins: [
|
plugins: [
|
||||||
'gatsby-plugin-styled-components',
|
|
||||||
'gatsby-plugin-image',
|
'gatsby-plugin-image',
|
||||||
'gatsby-transformer-remark',
|
'gatsby-transformer-remark',
|
||||||
'gatsby-plugin-sharp',
|
'gatsby-plugin-sharp',
|
||||||
|
|||||||
@@ -21,13 +21,14 @@
|
|||||||
"gatsby-plugin-image": "^3.13.1",
|
"gatsby-plugin-image": "^3.13.1",
|
||||||
"gatsby-plugin-sass": "^6.13.1",
|
"gatsby-plugin-sass": "^6.13.1",
|
||||||
"gatsby-plugin-sharp": "^5.13.1",
|
"gatsby-plugin-sharp": "^5.13.1",
|
||||||
"gatsby-plugin-styled-components": "^6.13.1",
|
|
||||||
"gatsby-source-filesystem": "^5.13.1",
|
"gatsby-source-filesystem": "^5.13.1",
|
||||||
"gatsby-transformer-json": "^5.13.1",
|
"gatsby-transformer-json": "^5.13.1",
|
||||||
"gatsby-transformer-remark": "^6.13.1",
|
"gatsby-transformer-remark": "^6.13.1",
|
||||||
"gatsby-transformer-sharp": "^5.13.1",
|
"gatsby-transformer-sharp": "^5.13.1",
|
||||||
|
"lodash": "4.17.21",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
|
"react-dropdown-select": "4.11.3",
|
||||||
"react-slick": "^0.30.2",
|
"react-slick": "^0.30.2",
|
||||||
"react-tooltip": "5.28.0",
|
"react-tooltip": "5.28.0",
|
||||||
"sass": "^1.77.8",
|
"sass": "^1.77.8",
|
||||||
|
|||||||
@@ -2,8 +2,11 @@ import * as React from 'react';
|
|||||||
|
|
||||||
import '../../styles/styles.scss';
|
import '../../styles/styles.scss';
|
||||||
|
|
||||||
function Badge({tag, isSource}) {
|
function Badge({tag, tagObj, isSource, onRemove}) {
|
||||||
return <div className={`badge ${isSource && 'badge--source'}`}>{tag}</div>;
|
return <div className={`badge ${isSource && 'badge--source'} ${tagObj && 'badge--filter'}`}>
|
||||||
|
{tag || tagObj.label}
|
||||||
|
{onRemove ? <span onClick={(() => onRemove(tag || tagObj))} /> : null}
|
||||||
|
</div>;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default Badge;
|
export default Badge;
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {Link} from 'gatsby';
|
import {Link} from 'gatsby';
|
||||||
|
|
||||||
function Breadcrumbs({location, label}) {
|
function Breadcrumbs({location}) {
|
||||||
const paths = location.split('/').filter((i) => i);
|
const paths = location.split('/').filter((i) => i);
|
||||||
const getBreadcrumbTitle = (name) =>
|
const getBreadcrumbTitle = (name) =>
|
||||||
name
|
name
|
||||||
.replace('-', ' ')
|
.replaceAll('-', ' ')
|
||||||
.replace(/(^\w{1})|(\s+\w{1})/g, (letter) => letter.toUpperCase());
|
.replaceAll(/(^\w{1})|(\s+\w{1})/g, (letter) => letter.toUpperCase());
|
||||||
return (
|
return (
|
||||||
<nav className="breadcrumb" aria-label="Breadcrumb">
|
<nav className="breadcrumb" aria-label="Breadcrumb">
|
||||||
<ol className="breadcrumb__list">
|
<ol className="breadcrumb__list">
|
||||||
@@ -26,7 +26,7 @@ function Breadcrumbs({location, label}) {
|
|||||||
<span className="breadcrumb__separator" aria-hidden="true"/>
|
<span className="breadcrumb__separator" aria-hidden="true"/>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<div className="breadcrumb__link">{label}</div>
|
<div className="breadcrumb__link">{getBreadcrumbTitle(path)}</div>
|
||||||
)}
|
)}
|
||||||
</li>
|
</li>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -0,0 +1,53 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import SelectBox from "./SelectBox";
|
||||||
|
import {FILTER_TYPES} from "./constants";
|
||||||
|
import Badge from "../Badge/Badge";
|
||||||
|
|
||||||
|
const _ = require("lodash");
|
||||||
|
|
||||||
|
|
||||||
|
function Filter() {
|
||||||
|
const [tags, setTags] = React.useState([]);
|
||||||
|
|
||||||
|
const updateTags = e => {
|
||||||
|
e.every(i => i.value)
|
||||||
|
? setTags(_.uniqBy([...tags.filter(tag => tag.group !== e[0].group), ...e], 'value'))
|
||||||
|
: setTags(tags.filter(tag => tag.group !== e[0].group))
|
||||||
|
}
|
||||||
|
const removeItem = (e) => {
|
||||||
|
setTags(tags.filter(tag => tag.value !== e.value));
|
||||||
|
}
|
||||||
|
|
||||||
|
const clearFilters = () => {
|
||||||
|
setTags([]);
|
||||||
|
}
|
||||||
|
|
||||||
|
return <div className="filter">
|
||||||
|
<div className="filter__list">
|
||||||
|
{FILTER_TYPES.map((filter, i) => {
|
||||||
|
return <SelectBox
|
||||||
|
key={i}
|
||||||
|
options={filter.values}
|
||||||
|
label={filter.group}
|
||||||
|
setValuesOutside={updateTags}
|
||||||
|
tags={tags}
|
||||||
|
/>
|
||||||
|
})}
|
||||||
|
<div className="filter__input-wrapper">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
className="filter__input"
|
||||||
|
placeholder="Search"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{tags.length
|
||||||
|
? <div className="filter__tags">
|
||||||
|
{tags.map((tag, i) => <Badge tagObj={tag} onRemove={removeItem} key={i}/>)}
|
||||||
|
<span className="filter__tags-close" onClick={clearFilters}>Clear All</span>
|
||||||
|
</div>
|
||||||
|
: null}
|
||||||
|
</div>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Filter;
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import {useEffect} from 'react';
|
||||||
|
import Select from "react-dropdown-select";
|
||||||
|
|
||||||
|
function SelectBox({options, label = "Select", setValuesOutside, tags}) {
|
||||||
|
const [values, setValues] = React.useState([]);
|
||||||
|
const [opts, setOpts] = React.useState([]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setOpts(options.map(opt => ({...opt, group: label})));
|
||||||
|
}, [options, label]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
setValues(tags.filter(tag => tag.group === label));
|
||||||
|
}, [tags, label]);
|
||||||
|
|
||||||
|
const customContentRenderer = ({state}) => {
|
||||||
|
return <div
|
||||||
|
className="selectbox__content">{label} {state.values.length ? `(${state.values.length})` : null}</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
const customDropdownRenderer = (s) => {
|
||||||
|
const {state, methods, props} = s;
|
||||||
|
const regexp = new RegExp(state.search, 'i');
|
||||||
|
|
||||||
|
return <div className="selectbox__dropdown">
|
||||||
|
{options.length > 6
|
||||||
|
? <input type="text"
|
||||||
|
className="selectbox__input"
|
||||||
|
value={state.search}
|
||||||
|
onChange={methods.setSearch}
|
||||||
|
placeholder="Search"
|
||||||
|
/>
|
||||||
|
: null}
|
||||||
|
<div className="selectbox__options">
|
||||||
|
{opts
|
||||||
|
.filter((item) => regexp.test(item[props.searchBy] || item[props.labelField]))
|
||||||
|
.map((option) => {
|
||||||
|
return (
|
||||||
|
<div
|
||||||
|
className="selectbox__option"
|
||||||
|
key={option.value}
|
||||||
|
onClick={option.disabled ? null : () => methods.addItem(option)}>
|
||||||
|
<input
|
||||||
|
type="checkbox"
|
||||||
|
className="selectbox__dropdown-checkbox checkbox"
|
||||||
|
onChange={() => state.values.indexOf(option) !== -1 ? methods.addItem(option) : methods.removeItem(null, option, false)}
|
||||||
|
checked={state.values.indexOf(option) !== -1}
|
||||||
|
/>
|
||||||
|
<label className="selectbox__dropdown-label">{option.label}</label>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
{opts.filter((item) => regexp.test(item[props.searchBy] || item[props.labelField])).length
|
||||||
|
? null
|
||||||
|
: <span className="selectbox__dropdown-label">No Data Found</span>
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
return <Select
|
||||||
|
className={`selectbox ${values.length ? "selectbox--active" : null}`}
|
||||||
|
options={options}
|
||||||
|
multi={true}
|
||||||
|
values={values}
|
||||||
|
onChange={(values) => {
|
||||||
|
setValuesOutside(values.length ? values.map(item => ({...item, group: label})) : [{group: label}])
|
||||||
|
}}
|
||||||
|
contentRenderer={customContentRenderer}
|
||||||
|
dropdownRenderer={customDropdownRenderer}
|
||||||
|
/>
|
||||||
|
}
|
||||||
|
|
||||||
|
export default SelectBox;
|
||||||
@@ -0,0 +1,193 @@
|
|||||||
|
export const FILTER_TYPES = [
|
||||||
|
{
|
||||||
|
group: "Type",
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
value: "Blazers",
|
||||||
|
label: 'Blazers'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Blouses',
|
||||||
|
label: 'Blouses'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Coats',
|
||||||
|
label: 'Coats'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Dresses',
|
||||||
|
label: 'Dresses'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Jackets',
|
||||||
|
label: 'Jackets'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Jeans',
|
||||||
|
label: 'Jeans'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Jumpers & Knitwear',
|
||||||
|
label: 'Jumpers & Knitwear'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Jumpsuits',
|
||||||
|
label: 'Jumpsuits'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Skirts',
|
||||||
|
label: 'Skirts'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Shirts & Topics',
|
||||||
|
label: 'Shirts & Topics'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Shorts & Bermudas',
|
||||||
|
label: 'Shorts & Bermudas'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Stockings & Tights',
|
||||||
|
label: 'Stockings & Tights'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Sweaters',
|
||||||
|
label: 'Sweaters'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Trouser Suits & Costumes',
|
||||||
|
label: 'Trouser Suits & Costumes'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Trousers',
|
||||||
|
label: 'Trousers'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Underwear & Pyjamas',
|
||||||
|
label: 'Underwear & Pyjamas'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Waistcoats',
|
||||||
|
label: 'Waistcoats'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Maternity Wear',
|
||||||
|
label: 'Maternity Wear'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Sportswear',
|
||||||
|
label: 'Sportswear'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Home & Loungewear',
|
||||||
|
label: 'Home & Loungewear'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
group: "Customer",
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
value: 'Gen Alpha',
|
||||||
|
label: 'Gen Alpha'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Gen Z',
|
||||||
|
label: 'Gen Z'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Generation X',
|
||||||
|
label: 'Generation X'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Millennials',
|
||||||
|
label: 'Millennials'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
group: "Market",
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
value: 'Worldwide',
|
||||||
|
label: 'Worldwide'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Europe',
|
||||||
|
label: 'Europe'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Germany',
|
||||||
|
label: 'Germany'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
group: "Fit",
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
value: "Fit",
|
||||||
|
label: 'Fit'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
group: "Brand",
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
value: 'Brand',
|
||||||
|
label: 'Brand'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
group: "Fabric",
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
value: 'Cotton',
|
||||||
|
label: 'Cotton'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Silk',
|
||||||
|
label: 'Silk'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Wool',
|
||||||
|
label: 'Wool'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Polyester',
|
||||||
|
label: 'Polyester'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Denim',
|
||||||
|
label: 'Denim'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Linen',
|
||||||
|
label: 'Linen'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
group: "Season",
|
||||||
|
values: [
|
||||||
|
{
|
||||||
|
value: 'Spring',
|
||||||
|
label: 'Spring'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Summer',
|
||||||
|
label: 'Summer'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Winter',
|
||||||
|
label: 'Winter'
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Autumn',
|
||||||
|
label: 'Autumn'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
@@ -0,0 +1,21 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
import Breadcrumbs from "../Breadcrumbs/Breadcrumbs";
|
||||||
|
import Profile from "../Profile/Profile";
|
||||||
|
|
||||||
|
import '../../styles/styles.scss';
|
||||||
|
|
||||||
|
function Layout({children, breafcrumbs = false}) {
|
||||||
|
return (
|
||||||
|
<main className="layout">
|
||||||
|
{breafcrumbs ?
|
||||||
|
<header className="header">
|
||||||
|
<Breadcrumbs location={breafcrumbs.pathname}/>
|
||||||
|
<Profile/>
|
||||||
|
</header>
|
||||||
|
: null}
|
||||||
|
{children}
|
||||||
|
</main>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Layout;
|
||||||
@@ -23,7 +23,7 @@ const ProductCard = ({product, images}) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="product-card m-t-48 m-b-48">
|
<div className="product-card m-b-48">
|
||||||
<div className="product-card__slider">
|
<div className="product-card__slider">
|
||||||
<Slider {...settings}>
|
<Slider {...settings}>
|
||||||
{product.images.map((image, index) => (
|
{product.images.map((image, index) => (
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
|
||||||
|
function Profile() {
|
||||||
|
return <div className="profile">My Profile</div>
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Profile;
|
||||||
@@ -41,9 +41,7 @@ const SocialMediaTooltips = ({product}) => {
|
|||||||
return {...socialMedia[key], type: key}
|
return {...socialMedia[key], type: key}
|
||||||
})
|
})
|
||||||
.sort((prev, current) => current.Social_Media_Influence - prev.Social_Media_Influence)
|
.sort((prev, current) => current.Social_Media_Influence - prev.Social_Media_Influence)
|
||||||
.map(smi => {
|
.map((smi, i) => smi.found ? (<div className="tooltip__wrapper" key={smi.Social_Media_Influence + name + i}>
|
||||||
if (smi.found) {
|
|
||||||
return (<div className="tooltip__wrapper" key={smi.Social_Media_Influence + name}>
|
|
||||||
<div
|
<div
|
||||||
className={`tooltip__confidence tooltip__confidence--${smi.Social_Media_Influence > SOCIAL_MEDIA_BREAKPOINTS[smi.type] ? "high" : "average"}`}
|
className={`tooltip__confidence tooltip__confidence--${smi.Social_Media_Influence > SOCIAL_MEDIA_BREAKPOINTS[smi.type] ? "high" : "average"}`}
|
||||||
>
|
>
|
||||||
@@ -67,10 +65,10 @@ const SocialMediaTooltips = ({product}) => {
|
|||||||
place="right-end">
|
place="right-end">
|
||||||
<h3 className="tooltip__title">{smi.type}</h3>
|
<h3 className="tooltip__title">{smi.type}</h3>
|
||||||
{SOCIAL_MEDIA_MATRIX[smi.type]
|
{SOCIAL_MEDIA_MATRIX[smi.type]
|
||||||
.map(line => {
|
.map((line, i) => {
|
||||||
return line ? (<div
|
return line ? (<div
|
||||||
className={`tooltip__data tooltip__data--${line}`}
|
className={`tooltip__data tooltip__data--${line}`}
|
||||||
key={line + name}>
|
key={line + name + i}>
|
||||||
<div>{line?.replaceAll("_", " ")} </div>
|
<div>{line?.replaceAll("_", " ")} </div>
|
||||||
<div>
|
<div>
|
||||||
<b>{smi[line].toLocaleString()}{line?.includes("Relative") ? "%" : ""}</b>
|
<b>{smi[line].toLocaleString()}{line?.includes("Relative") ? "%" : ""}</b>
|
||||||
@@ -78,9 +76,7 @@ const SocialMediaTooltips = ({product}) => {
|
|||||||
</div>) : <hr/>
|
</div>) : <hr/>
|
||||||
})}
|
})}
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
</div>);
|
</div>) : null);
|
||||||
}
|
|
||||||
});
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{getTooltips()}</>
|
{getTooltips()}</>
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
import * as React from 'react';
|
||||||
|
|
||||||
|
function Tabs({tabs, activeTabIndex = 0, setActiveTabIndex = () => {}}) {
|
||||||
|
const [activeIndex, setActiveIndex] = React.useState(activeTabIndex);
|
||||||
|
|
||||||
|
const setActiveTab = (e) => {
|
||||||
|
setActiveIndex(e);
|
||||||
|
setActiveTabIndex(e);
|
||||||
|
}
|
||||||
|
return <nav className="tabs">
|
||||||
|
{tabs.map((tab, i) => <div
|
||||||
|
key={i+tab.title}
|
||||||
|
className={`tabs__item ${i === activeIndex ? "tabs__item--active" : null}`}
|
||||||
|
onClick={() => setActiveTab(i)}>{tab.title}</div>)}
|
||||||
|
</nav>;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Tabs;
|
||||||
@@ -1,115 +1,4 @@
|
|||||||
[
|
[
|
||||||
{
|
|
||||||
"name": "Casual Long Shirt",
|
|
||||||
"tags": "Casual, Long",
|
|
||||||
"description": "Effortlessly stylish and comfortable, these long shirts are perfect for everyday wear. They've seen a surge in popularity on social media, with a remarkable 180% increase in reposts on Twitter and a 160% jump in comments on Instagram, making them a popular choice for fashion enthusiasts.",
|
|
||||||
"images": [
|
|
||||||
"4dd5074d31e63021470994c9265ab7cb.jpg",
|
|
||||||
"88e4101d3e4d2e1ddd2a5487a8df3e27.jpg",
|
|
||||||
"9656de311138c38dfe25970279fe26eb.jpg",
|
|
||||||
"65f5dc395334fe598a30dad84eef64e0.jpg",
|
|
||||||
"5521de8fdbef26afc7d8bb560a137401.webp"
|
|
||||||
],
|
|
||||||
"sources": "aninebing, lindatol_, Fendi, PRADA, Fashionista.com, Vogue Magazine, Acne Studios",
|
|
||||||
"socialMedia": {
|
|
||||||
"Twitter": {
|
|
||||||
"found": true,
|
|
||||||
"Social Media Influence": 8.33,
|
|
||||||
"Tweet Views": 53316.0,
|
|
||||||
"Tweet Reposts": 232.0,
|
|
||||||
"Tweet Quotes": 11.0,
|
|
||||||
"Tweet Likes": 609.0,
|
|
||||||
"Tweet Bookmarks": 15.0,
|
|
||||||
"Tweet Views Relative to Average": -14,
|
|
||||||
"Tweet Reposts Relative to Average": 180,
|
|
||||||
"Tweet Quotes Relative to Average": -30,
|
|
||||||
"Tweet Likes Relative to Average": 88,
|
|
||||||
"Tweet Bookmarks Relative to Average": 1
|
|
||||||
},
|
|
||||||
"Instagram": {
|
|
||||||
"found": true,
|
|
||||||
"Social Media Influence": 12.77,
|
|
||||||
"Post Comments": 41.0,
|
|
||||||
"Post Likes": 6115.0,
|
|
||||||
"Post Comments Relative to Average": 160,
|
|
||||||
"Post Likes Relative to Average": 198
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Striped Casual Shirt",
|
|
||||||
"tags": "Striped, Casual",
|
|
||||||
"description": "Effortlessly stylish and versatile, these striped casual shirts are a wardrobe staple. With a 44% increase in views on Twitter and a 75% surge in likes on Instagram, these shirts are clearly a hit with fashion enthusiasts.",
|
|
||||||
"images": [
|
|
||||||
"52aad40ac9ffb17f83de18216af367d1.jpg",
|
|
||||||
"f671add5d3613a579b4dd50bb0733872.jpg",
|
|
||||||
"Hikigawa.webp",
|
|
||||||
"d9fd6326f813a8fa4819028dfeb047b7.jpg",
|
|
||||||
"FSLE-Oversized-Blue-Striped-Casual-Blouse-Shirt-Women-Streetwear-Elegant-Button-Up-Shirt-Female-Long-Sleeve.webp"
|
|
||||||
],
|
|
||||||
"sources": "aninebing, carodaur, heir, lindatol_, rocky_barnes, Fendi, PRADA, Vogue Magazine, Fashionista.com, KENZO",
|
|
||||||
"socialMedia": {
|
|
||||||
"Twitter": {
|
|
||||||
"found": true,
|
|
||||||
"Social Media Influence": 0.64,
|
|
||||||
"Tweet Views": 188015.0,
|
|
||||||
"Tweet Reposts": 329.0,
|
|
||||||
"Tweet Quotes": 11.0,
|
|
||||||
"Tweet Likes": 1195.0,
|
|
||||||
"Tweet Bookmarks": 29.0,
|
|
||||||
"Tweet Views Relative to Average": 44,
|
|
||||||
"Tweet Reposts Relative to Average": 7,
|
|
||||||
"Tweet Quotes Relative to Average": -25,
|
|
||||||
"Tweet Likes Relative to Average": 18,
|
|
||||||
"Tweet Bookmarks Relative to Average": 0
|
|
||||||
},
|
|
||||||
"Instagram": {
|
|
||||||
"found": true,
|
|
||||||
"Social Media Influence": 11.86,
|
|
||||||
"Post Comments": 53.0,
|
|
||||||
"Post Likes": 2697.0,
|
|
||||||
"Post Comments Relative to Average": 57,
|
|
||||||
"Post Likes Relative to Average": 75
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Casual Midi Skirt",
|
|
||||||
"tags": "Casual, Midi",
|
|
||||||
"description": "Effortlessly chic and versatile, this midi skirt is perfect for casual everyday looks. Its flattering silhouette and comfortable fit have resonated with fashion enthusiasts, resulting in a remarkable 284% increase in bookmarks on Twitter, showcasing its popularity among style-conscious individuals.",
|
|
||||||
"images": [
|
|
||||||
"78a0ceda555f73d404ba201355ab4bf3.jpg",
|
|
||||||
"fc8d50c21bd7489651b976bdee4c4ac8.jpg",
|
|
||||||
"bfdf38ece493e8496db53f8c48de9e75.jpg",
|
|
||||||
"fbafefe897b637a7d43d4248c4a5001b.jpg",
|
|
||||||
"81dPkumiz3L_AC_UY1000_.jpg"
|
|
||||||
],
|
|
||||||
"sources": "Fendi, Vogue Magazine, Burberry, Coach, PRADA, brittanyxavier, jaceyduprie, veronikaheilbrunner",
|
|
||||||
"socialMedia": {
|
|
||||||
"Twitter": {
|
|
||||||
"found": true,
|
|
||||||
"Social Media Influence": 9.74,
|
|
||||||
"Tweet Views": 194393.0,
|
|
||||||
"Tweet Reposts": 1514.0,
|
|
||||||
"Tweet Quotes": 68.0,
|
|
||||||
"Tweet Likes": 4686.0,
|
|
||||||
"Tweet Bookmarks": 168.0,
|
|
||||||
"Tweet Views Relative to Average": 38,
|
|
||||||
"Tweet Reposts Relative to Average": 239,
|
|
||||||
"Tweet Quotes Relative to Average": 131,
|
|
||||||
"Tweet Likes Relative to Average": 217,
|
|
||||||
"Tweet Bookmarks Relative to Average": 284
|
|
||||||
},
|
|
||||||
"Instagram": {
|
|
||||||
"found": true,
|
|
||||||
"Social Media Influence": 0.18,
|
|
||||||
"Post Comments": 26.0,
|
|
||||||
"Post Likes": 707.0,
|
|
||||||
"Post Comments Relative to Average": 12,
|
|
||||||
"Post Likes Relative to Average": -9
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
"name": "Casual Dress",
|
"name": "Casual Dress",
|
||||||
"tags": "Casual",
|
"tags": "Casual",
|
||||||
@@ -141,10 +30,10 @@
|
|||||||
"tags": "Casual, Relaxed",
|
"tags": "Casual, Relaxed",
|
||||||
"description": "Super comfortable and stylish, these hoodies are perfect for everyday wear. They've been a huge hit on Twitter, with a massive 2957% increase in reposts and a 3023% increase in bookmarks compared to the average. Get ready to relax in style!",
|
"description": "Super comfortable and stylish, these hoodies are perfect for everyday wear. They've been a huge hit on Twitter, with a massive 2957% increase in reposts and a 3023% increase in bookmarks compared to the average. Get ready to relax in style!",
|
||||||
"images": [
|
"images": [
|
||||||
|
"639a2f2e58e6ffdfff87f6bdb8f9f9c9.jpg",
|
||||||
"10342a0bd0dc9161466a67fc7b94a33d.jpg",
|
"10342a0bd0dc9161466a67fc7b94a33d.jpg",
|
||||||
"a4896b773c816bce6a7c24da45ef658b.jpg",
|
"a4896b773c816bce6a7c24da45ef658b.jpg",
|
||||||
"11ca8a3e353c6cc3444a008779b36174.jpg",
|
"11ca8a3e353c6cc3444a008779b36174.jpg",
|
||||||
"714RvzJjoPL_AC_UY1000_.jpg",
|
|
||||||
"LTTVQM-Quarter-Zip-Hoodie-Womens-Oversized-Half-Zip-Pullover-Long-Sleeve-Sweatshirt-Casual-Solid-Color-Relaxed-Fit-Tops-with-Pocket-Camel-XL_72c61da0-5346-42db-aff1-62517df50eb0.08683914769cd5913e834050a6b8ee86.avif"
|
"LTTVQM-Quarter-Zip-Hoodie-Womens-Oversized-Half-Zip-Pullover-Long-Sleeve-Sweatshirt-Casual-Solid-Color-Relaxed-Fit-Tops-with-Pocket-Camel-XL_72c61da0-5346-42db-aff1-62517df50eb0.08683914769cd5913e834050a6b8ee86.avif"
|
||||||
],
|
],
|
||||||
"sources": "Michael Kors, Vogue France",
|
"sources": "Michael Kors, Vogue France",
|
||||||
@@ -295,10 +184,10 @@
|
|||||||
"tags": "Oversized, Wool",
|
"tags": "Oversized, Wool",
|
||||||
"description": "A classic and timeless piece, this oversized wool suit offers a sophisticated and comfortable look. The suit's popularity is evident in its impressive social media performance, with a staggering 4058% increase in reposts on Twitter, showcasing its appeal to fashion enthusiasts.",
|
"description": "A classic and timeless piece, this oversized wool suit offers a sophisticated and comfortable look. The suit's popularity is evident in its impressive social media performance, with a staggering 4058% increase in reposts on Twitter, showcasing its appeal to fashion enthusiasts.",
|
||||||
"images": [
|
"images": [
|
||||||
|
"e7d6c705f7c1cb859afa8b7ae00757ea.jpg",
|
||||||
"02aa00c9208ffd8496e16b9e5f730945.jpg",
|
"02aa00c9208ffd8496e16b9e5f730945.jpg",
|
||||||
"76f90b11d0dfe4a4fbf9b37677d07ae6.jpg",
|
"76f90b11d0dfe4a4fbf9b37677d07ae6.jpg",
|
||||||
"f0f421a3d256185d7f145f59fb7cc4a9.jpg",
|
"f0f421a3d256185d7f145f59fb7cc4a9.jpg",
|
||||||
"a0f80b35b36c0c0018fddd5c59e8c6a2.jpg",
|
|
||||||
"cf6b5fd2a1a2bd9561f03986d4fcdd3d.jpg"
|
"cf6b5fd2a1a2bd9561f03986d4fcdd3d.jpg"
|
||||||
],
|
],
|
||||||
"sources": "HYPEBEAST, SAINT LAURENT",
|
"sources": "HYPEBEAST, SAINT LAURENT",
|
||||||
@@ -412,6 +301,43 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Casual Long Shirt",
|
||||||
|
"tags": "Casual, Long",
|
||||||
|
"description": "Effortlessly stylish and comfortable, these long shirts are perfect for everyday wear. They've seen a surge in popularity on social media, with a remarkable 180% increase in reposts on Twitter and a 160% jump in comments on Instagram, making them a popular choice for fashion enthusiasts.",
|
||||||
|
"images": [
|
||||||
|
"4dd5074d31e63021470994c9265ab7cb.jpg",
|
||||||
|
"88e4101d3e4d2e1ddd2a5487a8df3e27.jpg",
|
||||||
|
"9656de311138c38dfe25970279fe26eb.jpg",
|
||||||
|
"65f5dc395334fe598a30dad84eef64e0.jpg",
|
||||||
|
"5521de8fdbef26afc7d8bb560a137401.webp"
|
||||||
|
],
|
||||||
|
"sources": "aninebing, lindatol_, Fendi, PRADA, Fashionista.com, Vogue Magazine, Acne Studios",
|
||||||
|
"socialMedia": {
|
||||||
|
"Twitter": {
|
||||||
|
"found": true,
|
||||||
|
"Social Media Influence": 8.33,
|
||||||
|
"Tweet Views": 53316.0,
|
||||||
|
"Tweet Reposts": 232.0,
|
||||||
|
"Tweet Quotes": 11.0,
|
||||||
|
"Tweet Likes": 609.0,
|
||||||
|
"Tweet Bookmarks": 15.0,
|
||||||
|
"Tweet Views Relative to Average": -14,
|
||||||
|
"Tweet Reposts Relative to Average": 180,
|
||||||
|
"Tweet Quotes Relative to Average": -30,
|
||||||
|
"Tweet Likes Relative to Average": 88,
|
||||||
|
"Tweet Bookmarks Relative to Average": 1
|
||||||
|
},
|
||||||
|
"Instagram": {
|
||||||
|
"found": true,
|
||||||
|
"Social Media Influence": 12.77,
|
||||||
|
"Post Comments": 41.0,
|
||||||
|
"Post Likes": 6115.0,
|
||||||
|
"Post Comments Relative to Average": 160,
|
||||||
|
"Post Likes Relative to Average": 198
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Relaxed Casual Long Set",
|
"name": "Relaxed Casual Long Set",
|
||||||
"tags": "Relaxed, Casual, Long",
|
"tags": "Relaxed, Casual, Long",
|
||||||
@@ -443,11 +369,11 @@
|
|||||||
"tags": "Black, Fitted, Formal",
|
"tags": "Black, Fitted, Formal",
|
||||||
"description": "Elegant and sophisticated, these black fitted formal dresses are perfect for special occasions. With a 192% increase in reposts and a 189% rise in bookmarks on Twitter, these dresses are clearly a popular choice for stylish events.",
|
"description": "Elegant and sophisticated, these black fitted formal dresses are perfect for special occasions. With a 192% increase in reposts and a 189% rise in bookmarks on Twitter, these dresses are clearly a popular choice for stylish events.",
|
||||||
"images": [
|
"images": [
|
||||||
"d61eea65fa5505b7a641851a014e36bf.jpg",
|
"e1338a6dcfb1908b9f4d3465d55a801c (1).jpg",
|
||||||
"53f4aa76693158a87d2fc5488ebf94b2.jpg",
|
"c24f0c1565a3fd3c93bfd11ac2e83b40.jpg",
|
||||||
"36b000e685ca3dbf5bad2546944bb765.jpg",
|
"a742f2d2988c45b8b462f36f450b31c8.jpg",
|
||||||
"il_570xN3804692666_3bgx.avif",
|
"400b0754dbf52f7df89cddaf4351b17b.jpg",
|
||||||
"61456_BLACK_3_2048x.jpg"
|
"99dad65e2324d9f0484d8739b05ed330.jpg"
|
||||||
],
|
],
|
||||||
"sources": "Michael Kors, SAINT LAURENT, Fashionista.com, Givenchy, Vogue Magazine",
|
"sources": "Michael Kors, SAINT LAURENT, Fashionista.com, Givenchy, Vogue Magazine",
|
||||||
"socialMedia": {
|
"socialMedia": {
|
||||||
@@ -496,6 +422,43 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Striped Casual Shirt",
|
||||||
|
"tags": "Striped, Casual",
|
||||||
|
"description": "Effortlessly stylish and versatile, these striped casual shirts are a wardrobe staple. With a 44% increase in views on Twitter and a 75% surge in likes on Instagram, these shirts are clearly a hit with fashion enthusiasts.",
|
||||||
|
"images": [
|
||||||
|
"52aad40ac9ffb17f83de18216af367d1.jpg",
|
||||||
|
"f671add5d3613a579b4dd50bb0733872.jpg",
|
||||||
|
"Hikigawa.webp",
|
||||||
|
"d9fd6326f813a8fa4819028dfeb047b7.jpg",
|
||||||
|
"FSLE-Oversized-Blue-Striped-Casual-Blouse-Shirt-Women-Streetwear-Elegant-Button-Up-Shirt-Female-Long-Sleeve.webp"
|
||||||
|
],
|
||||||
|
"sources": "aninebing, carodaur, heir, lindatol_, rocky_barnes, Fendi, PRADA, Vogue Magazine, Fashionista.com, KENZO",
|
||||||
|
"socialMedia": {
|
||||||
|
"Twitter": {
|
||||||
|
"found": true,
|
||||||
|
"Social Media Influence": 0.64,
|
||||||
|
"Tweet Views": 188015.0,
|
||||||
|
"Tweet Reposts": 329.0,
|
||||||
|
"Tweet Quotes": 11.0,
|
||||||
|
"Tweet Likes": 1195.0,
|
||||||
|
"Tweet Bookmarks": 29.0,
|
||||||
|
"Tweet Views Relative to Average": 44,
|
||||||
|
"Tweet Reposts Relative to Average": 7,
|
||||||
|
"Tweet Quotes Relative to Average": -25,
|
||||||
|
"Tweet Likes Relative to Average": 18,
|
||||||
|
"Tweet Bookmarks Relative to Average": 0
|
||||||
|
},
|
||||||
|
"Instagram": {
|
||||||
|
"found": true,
|
||||||
|
"Social Media Influence": 11.86,
|
||||||
|
"Post Comments": 53.0,
|
||||||
|
"Post Likes": 2697.0,
|
||||||
|
"Post Comments Relative to Average": 57,
|
||||||
|
"Post Likes Relative to Average": 75
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Black Formal Silk Dress",
|
"name": "Black Formal Silk Dress",
|
||||||
"tags": "Black, Formal, Silk",
|
"tags": "Black, Formal, Silk",
|
||||||
@@ -504,7 +467,7 @@
|
|||||||
"808491c55bb618ee10ce059d10d16664.jpg",
|
"808491c55bb618ee10ce059d10d16664.jpg",
|
||||||
"c3415cd960426232cc678499875993dd.jpg",
|
"c3415cd960426232cc678499875993dd.jpg",
|
||||||
"Ella-Black-Off-Shoulder-Formal-Dress-1_750x.jpg",
|
"Ella-Black-Off-Shoulder-Formal-Dress-1_750x.jpg",
|
||||||
"08df26ce-6182-42f1-9188-81a8de0bd372c8640bbaf1a957b037364e6d5e02c560.webp",
|
"c586e6853c40655d9597f2ff76d2ffe0.jpg",
|
||||||
"6f5a929f47bb99cd9feb944bcaec5333.jpg"
|
"6f5a929f47bb99cd9feb944bcaec5333.jpg"
|
||||||
],
|
],
|
||||||
"sources": "SAINT LAURENT, Givenchy, Vogue Magazine",
|
"sources": "SAINT LAURENT, Givenchy, Vogue Magazine",
|
||||||
@@ -656,6 +619,43 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Casual Midi Skirt",
|
||||||
|
"tags": "Casual, Midi",
|
||||||
|
"description": "Effortlessly chic and versatile, this midi skirt is perfect for casual everyday looks. Its flattering silhouette and comfortable fit have resonated with fashion enthusiasts, resulting in a remarkable 284% increase in bookmarks on Twitter, showcasing its popularity among style-conscious individuals.",
|
||||||
|
"images": [
|
||||||
|
"78a0ceda555f73d404ba201355ab4bf3.jpg",
|
||||||
|
"fc8d50c21bd7489651b976bdee4c4ac8.jpg",
|
||||||
|
"bfdf38ece493e8496db53f8c48de9e75.jpg",
|
||||||
|
"fbafefe897b637a7d43d4248c4a5001b.jpg",
|
||||||
|
"81dPkumiz3L_AC_UY1000_.jpg"
|
||||||
|
],
|
||||||
|
"sources": "Fendi, Vogue Magazine, Burberry, Coach, PRADA, brittanyxavier, jaceyduprie, veronikaheilbrunner",
|
||||||
|
"socialMedia": {
|
||||||
|
"Twitter": {
|
||||||
|
"found": true,
|
||||||
|
"Social Media Influence": 9.74,
|
||||||
|
"Tweet Views": 194393.0,
|
||||||
|
"Tweet Reposts": 1514.0,
|
||||||
|
"Tweet Quotes": 68.0,
|
||||||
|
"Tweet Likes": 4686.0,
|
||||||
|
"Tweet Bookmarks": 168.0,
|
||||||
|
"Tweet Views Relative to Average": 38,
|
||||||
|
"Tweet Reposts Relative to Average": 239,
|
||||||
|
"Tweet Quotes Relative to Average": 131,
|
||||||
|
"Tweet Likes Relative to Average": 217,
|
||||||
|
"Tweet Bookmarks Relative to Average": 284
|
||||||
|
},
|
||||||
|
"Instagram": {
|
||||||
|
"found": true,
|
||||||
|
"Social Media Influence": 0.18,
|
||||||
|
"Post Comments": 26.0,
|
||||||
|
"Post Likes": 707.0,
|
||||||
|
"Post Comments Relative to Average": 12,
|
||||||
|
"Post Likes Relative to Average": -9
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Casual Lace Short White Top",
|
"name": "Casual Lace Short White Top",
|
||||||
"tags": "Casual, Lace, Short, White",
|
"tags": "Casual, Lace, Short, White",
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
const getConfidence = (media, breakpoint) => {
|
const getConfidence = (media) => {
|
||||||
const best = Object.values(media)
|
const best = Object.values(media)
|
||||||
.filter((med) => med.found)
|
.filter((med) => med.found)
|
||||||
.reduce((prev, current) => {
|
.reduce((prev, current) => {
|
||||||
|
|||||||
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 110 KiB |
|
After Width: | Height: | Size: 52 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 47 KiB |
|
After Width: | Height: | Size: 88 KiB |
|
After Width: | Height: | Size: 34 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 56 KiB |
|
After Width: | Height: | Size: 126 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 76 KiB |
|
After Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 27 KiB |
|
After Width: | Height: | Size: 23 KiB |
|
After Width: | Height: | Size: 51 KiB |
|
After Width: | Height: | Size: 48 KiB |
|
After Width: | Height: | Size: 19 KiB |
|
After Width: | Height: | Size: 31 KiB |
|
After Width: | Height: | Size: 59 KiB |
|
After Width: | Height: | Size: 84 KiB |
|
After Width: | Height: | Size: 117 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 85 KiB |
|
After Width: | Height: | Size: 96 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 171 KiB |
|
After Width: | Height: | Size: 87 KiB |
|
After Width: | Height: | Size: 30 KiB |
|
After Width: | Height: | Size: 76 KiB |
|
After Width: | Height: | Size: 28 KiB |
|
After Width: | Height: | Size: 68 KiB |
|
After Width: | Height: | Size: 102 KiB |
|
After Width: | Height: | Size: 76 KiB |
|
After Width: | Height: | Size: 391 KiB |
|
After Width: | Height: | Size: 43 KiB |
|
After Width: | Height: | Size: 69 KiB |
|
After Width: | Height: | Size: 144 KiB |
|
After Width: | Height: | Size: 58 KiB |
|
After Width: | Height: | Size: 49 KiB |
|
After Width: | Height: | Size: 79 KiB |
|
After Width: | Height: | Size: 100 KiB |
|
After Width: | Height: | Size: 58 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 82 KiB |
|
After Width: | Height: | Size: 50 KiB |
|
After Width: | Height: | Size: 121 KiB |
|
After Width: | Height: | Size: 109 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 72 KiB |
|
After Width: | Height: | Size: 26 KiB |
|
After Width: | Height: | Size: 25 KiB |
|
After Width: | Height: | Size: 97 KiB |
|
After Width: | Height: | Size: 201 KiB |
|
After Width: | Height: | Size: 88 KiB |
|
After Width: | Height: | Size: 29 KiB |
|
After Width: | Height: | Size: 129 KiB |
|
After Width: | Height: | Size: 35 KiB |
|
After Width: | Height: | Size: 17 KiB |
|
After Width: | Height: | Size: 41 KiB |
|
After Width: | Height: | Size: 45 KiB |
|
After Width: | Height: | Size: 32 KiB |
|
After Width: | Height: | Size: 36 KiB |
|
After Width: | Height: | Size: 100 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 108 KiB |
|
After Width: | Height: | Size: 140 KiB |
|
After Width: | Height: | Size: 177 KiB |
|
After Width: | Height: | Size: 104 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 222 KiB |
|
After Width: | Height: | Size: 75 KiB |
|
After Width: | Height: | Size: 58 KiB |
|
After Width: | Height: | Size: 40 KiB |
|
After Width: | Height: | Size: 47 KiB |