Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions .eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
{
"extends": ["airbnb", "prettier", "prettier/react"],
"plugins": ["prettier"],
"rules": {
"react/jsx-filename-extension": [
1,
{
"extensions": [".js", ".jsx"]
}
],
"react/prop-types": 0,
"no-underscore-dangle": 0,
"import/imports-first": ["error", "absolute-first"],
"import/newline-after-import": "error"
},
"globals": {
"window": true,
"document": true,
"localStorage": true,
"FormData": true,
"FileReader": true,
"Blob": true,
"navigator": true
},
"parser": "babel-eslint"
}
12 changes: 12 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
logs
*.log
npm-debug.log*
.DS_Store

coverage
node_modules
build
.env.local
.env.development.local
.env.test.local
.env.production.local
15,969 changes: 15,969 additions & 0 deletions package-lock.json

Large diffs are not rendered by default.

56 changes: 56 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
{
"name": "my-razzle-app",
"version": "0.1.0",
"license": "MIT",
"scripts": {
"start": "razzle start",
"build": "razzle build",
"test": "razzle test --env=jsdom",
"start:prod": "set NODE_ENV=production && node build/server.js",
"precommit": "set NODE_ENV=production lint-staged"
},
"lint-staged": {
"*.{js,jsx}": [
"pretty-quick --staged",
"eslint src/ --fix",
"git add"
]
},
"dependencies": {
"ab-testing": "^3.1.2",
"axios": "^0.18.0",
"body-parser": "^1.18.3",
"compression": "^1.7.3",
"cookie-parser": "^1.4.4",
"cors": "^2.8.4",
"express": "4.16.4",
"flag": "^3.0.0-1",
"helmet": "^3.16.0",
"lazysizes": "^4.1.6",
"localforage": "^1.7.3",
"md5": "^2.2.1",
"minify-css-string": "^1.0.0",
"razzle": "2.4.1",
"react": "16.8.3",
"react-dom": "16.8.3",
"react-redux": "^5.0.7",
"react-router-dom": "4.3.1",
"react-swipeable-views": "^0.13.0",
"react-swipeable-views-utils": "^0.13.0",
"serialize-javascript": "^1.4.0",
"uniqid": "^5.0.3"
},
"devDependencies": {
"eslint": "^5.16.0",
"eslint-config-airbnb": "^17.1.0",
"eslint-config-prettier": "^4.3.0",
"eslint-plugin-import": "^2.17.3",
"eslint-plugin-jsx-a11y": "^6.2.1",
"eslint-plugin-prettier": "^3.1.0",
"eslint-plugin-react": "^7.13.0",
"husky": "^2.4.1",
"lint-staged": "^8.2.1",
"prettier": "^1.18.2",
"pretty-quick": "^1.11.1"
}
}
Binary file added public/assets/flight/fl1.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/assets/flight/fl2.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/assets/flight/fl3.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/assets/flight/fl4.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added public/favicon.ico
Binary file not shown.
2 changes: 2 additions & 0 deletions public/robots.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
User-agent: *

138 changes: 138 additions & 0 deletions src/api/getContents.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,138 @@
import axios from "axios";
import search from "./search";
import { getProductDetails } from "./getProductDetails";

const getContents = () => {
return new Promise((resolve, reject) => {
const query = {
constant_score: {
filter: {
bool: {
should: [
{
term: {
type: "flights"
}
}
]
}
}
}
};
const aggs = {
price_ranges: {
range: {
field: "offerPrice",
ranges: [
{ to: 999.0 },
{ from: 1000.0, to: 1999.0 },
{ from: 2000.0, to: 2999.0 },
{ from: 3000.0, to: 3999.0 }
]
}
}
};
axios
.post("http://localhost:9200/offers/_search?", { query, aggs })
.then(res => {
if (res.data && res.data.hits) {
return resolve(res.data);
}
throw new Error(false);
})
.catch(err => {
reject(err);
});
});
};

const getStores = () => {
return new Promise((resolve, reject) => {
const query = {
bool: {
must: [
{
term: {
type: "stores"
}
}
]
}
};
const aggs = {
stores: {
terms: {
field: "name.keyword"
}
}
};

axios
.post("http://localhost:9200/offers/_search?", { size: 10, query, aggs })
.then(res => {
if (res.data && res.data.hits) {
return resolve(res.data);
}
throw new Error(false);
})
.catch(err => {
reject(err);
});
});
};

const getResults = () => {
return new Promise(resolve => {
console.log("==>", search);
resolve(search);
});
};

// eslint-disable-next-line import/prefer-default-export
export const getSiteContents = req => {
return new Promise(resolve => {
if (req.path === "/") {
axios
.all([getContents(req.path), getStores()])
.then(
axios.spread((offers, stores) => {
resolve({
offers,
stores
});
})
)
.catch(err => {
console.log(err);
});
} else if (req.path.indexOf("search") >= 0) {
axios
.all([getResults()])
.then(
axios.spread(result => {
resolve({
results: result[req.query.q]
});
})
)
.catch(err => {
console.log(err);
});
} else if (req.path.indexOf("pdp") >= 0) {
axios
.all([getProductDetails(req.query.brand, req.query.sku)])
.then(
axios.spread((details, images) => {
const detailsInstance = details;
detailsInstance.s7Images = images;
resolve({
details: detailsInstance
});
})
)
.catch(err => {
console.log(err);
});
}
});
};
23 changes: 23 additions & 0 deletions src/api/getProductDetails.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import axios from 'axios';

export const getProductDetails = (brand, sku) => {
return new Promise((resolve, reject) => {
axios.get('<API>',{
params: {
op: 'getProductDetails',
data: {
"brand":brand,
"sku": sku.toUpperCase(),
}
}
})
.then(res => {
if(res.data) {
resolve(res.data);
} else reject(false);
})
.catch(err => {
reject(err);
})
})
}
8 changes: 8 additions & 0 deletions src/api/search.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
export default {
"shirt": {
"records": [{
"id": "1133007",
"sku": "FD110ER",
}]
}
}
28 changes: 28 additions & 0 deletions src/client.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import React from 'react';
import { hydrate } from 'react-dom';
import App from './shared/App';
import { BrowserRouter as Router } from 'react-router-dom';

require('lazysizes');

class Main extends React.Component {

constructor() {
super();
(() => {
const elem = document.getElementById("ssr-spinner");
if(elem) elem.parentElement.removeChild(elem);
})();
}

render() {
return <App apiData={window.__INITIAL_DATA__} isBrowser={true}/>;
}
}

hydrate(
<Router>
<Main />
</Router>,
document.getElementById('app')
);
44 changes: 44 additions & 0 deletions src/config/abTesting.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
import uniqid from 'uniqid'
import config from './config.js'
import configFunction from './configFunction.js'
import mockData from './mockData'
export const abTesting = (req, res, next) => {

/***** For setting unique id for each browser *****/
const __uid = req.cookies.__unique_id__;
let __user = req.cookies.__user__;
if(!__uid) {
const uid = uniqid();
res.cookie('__unique_id__', uid, { maxAge: 1000*60*60*24, httpOnly: true });
}

if(!__user) {
const userflag = (Math.floor(Math.random() * 1000) % 2) === 0 ? 'a' : 'b';
res.cookie('__user__', userflag, { maxAge: 1000*60*60*24, httpOnly: true });
__user = userflag;
}

return new Promise(resolve => {
const random = Math.floor(Math.random() * 4999);
const user = mockData[random];
const username = __user;

const testingKeys = {
uuid: user.uuid,
username: username
};

let flags = {}, funcRes = [];
config.forEach(conf => {
if(conf.enabled) {
const func = conf.strategy.type;
const keyName = conf.strategy.filter;
funcRes.push(configFunction[func](testingKeys, conf));
}
})
Promise.all(funcRes).then(values => {
flags = Object.assign({}, flags, ...values);
resolve(Object.assign({}, flags, { "defaultFlag": true }));
});
})
}
Loading