Skip to content

Commit f03ace4

Browse files
feat: BrowserStack demo ecommerce app
1 parent 5ab496a commit f03ace4

File tree

103 files changed

+9321
-424
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

103 files changed

+9321
-424
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
# misc
1919
.DS_Store
2020
*.pem
21+
/.vscode/
2122

2223
# debug
2324
npm-debug.log*

.vscode/launch.json

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"type": "node",
3+
"request": "launch",
4+
"name": "Launch via NPM",
5+
"runtimeExecutable": "${workspaceFolder}\\node_modules\\.bin\\next",
6+
"port": 9229,
7+
"env": {
8+
"NODE_OPTIONS": "--inspect"
9+
}
10+
}

Dockerfile

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
# Install dependencies only when needed
2+
FROM node:12 AS deps
3+
4+
WORKDIR /opt/app
5+
COPY package.json yarn.lock ./
6+
RUN yarn install --frozen-lockfile
7+
8+
# Rebuild the source code only when needed
9+
FROM node:12 AS builder
10+
11+
ENV NODE_ENV=production
12+
WORKDIR /opt/app
13+
COPY . .
14+
COPY --from=deps /opt/app/node_modules ./node_modules
15+
RUN yarn build
16+
17+
# Production image, copy all the files and run next
18+
FROM node:12 AS runner
19+
20+
ARG X_TAG
21+
WORKDIR /opt/app
22+
ENV NODE_ENV=production
23+
COPY --from=builder /opt/app/next.config.js ./
24+
COPY --from=builder /opt/app/public ./public
25+
COPY --from=builder /opt/app/.next ./.next
26+
COPY --from=builder /opt/app/node_modules ./node_modules
27+
CMD ["node_modules/.bin/next", "start"]

README.md

+9-6
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,20 @@ This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next
22

33
## Getting Started
44

5-
First, run the development server:
5+
First, Install docker:
66

77
```bash
8-
npm run dev
9-
# or
10-
yarn dev
8+
https://docs.docker.com/engine/install/
119
```
1210

13-
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
11+
## Run below command to build and start the server
12+
```bash
13+
docker build -t client . && docker run --name CLIENT_CONTAINER -p 0.0.0.0:5000:3000 client
14+
```
1415

15-
You can start editing the page by modifying `pages/index.js`. The page auto-updates as you edit the file.
16+
```bash
17+
visit http://localhost:5000/
18+
```
1619

1720
## Learn More
1821

next.config.js

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
const optimizedImages = require('next-optimized-images');
2+
const withStyles = require('@webdeb/next-styles')
3+
const withPlugins = require('next-compose-plugins');
4+
const webpack = require('webpack');
5+
6+
const sassConfig = {
7+
sass: true, // use .scss files
8+
modules: true // style.(m|module).css & style.(m|module).scss for module files
9+
}
10+
11+
const optimizedImagesConfig = {
12+
inlineImageLimit: 8192,
13+
imagesFolder: 'images',
14+
imagesName: '[name]-[hash].[ext]',
15+
optimizeImagesInDev: false,
16+
mozjpeg: {
17+
quality: 80
18+
},
19+
optipng: {
20+
optimizationLevel: 3
21+
},
22+
pngquant: false,
23+
gifsicle: {
24+
interlaced: true,
25+
optimizationLevel: 3
26+
},
27+
svgo: {
28+
// enable/disable svgo plugins here
29+
},
30+
webp: {
31+
preset: 'default',
32+
quality: 75
33+
}
34+
};
35+
36+
const nextConfiguration = {
37+
webpack: config => {
38+
config.plugins.push(
39+
new webpack.DefinePlugin({
40+
PC: JSON.stringify('pc')
41+
})
42+
);
43+
return config;
44+
},
45+
};
46+
47+
module.exports = withPlugins([
48+
[withStyles, sassConfig],
49+
[optimizedImages, optimizedImagesConfig],
50+
], nextConfiguration);

package.json

+24-1
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,31 @@
88
"start": "next start"
99
},
1010
"dependencies": {
11+
"@material-ui/core": "^4.11.0",
12+
"@material-ui/icons": "^4.9.1",
13+
"@webdeb/next-styles": "^1.1.1",
14+
"@zeit/next-sass": "^1.0.1",
15+
"autoprefixer": "^10.0.2",
16+
"axios": "^0.18.0",
17+
"concurrently": "^4.0.1",
18+
"cors": "^2.8.5",
19+
"express": "^4.16.4",
20+
"imagemin-mozjpeg": "^9.0.0",
21+
"moxios": "^0.4.0",
1122
"next": "10.0.1",
23+
"next-compose-plugins": "^2.2.1",
24+
"next-optimized-images": "^2.6.2",
25+
"postcss-import": "^13.0.0",
26+
"postcss-preset-env": "^6.7.0",
27+
"prop-types": "15.7.2",
1228
"react": "17.0.1",
13-
"react-dom": "17.0.1"
29+
"react-dom": "17.0.1",
30+
"react-redux": "^5.1.1",
31+
"redux": "^4.0.1",
32+
"redux-thunk": "^2.3.0",
33+
"sass": "^1.29.0",
34+
"store2": "^2.12.0",
35+
"tailwindcss": "^1.9.6",
36+
"webpack": "^4.0.0"
1437
}
1538
}

pages/_app.js

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import '../styles/globals.css'
1+
import Root from '../src/Root';
2+
import '../styles/globals.scss';
23

34
function MyApp({ Component, pageProps }) {
4-
return <Component {...pageProps} />
5-
}
5+
return <Root><Component {...pageProps} /></Root>;
6+
};
67

7-
export default MyApp
8+
export default MyApp;

pages/api/checkout.js

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import { isValidUser } from '../../src/constants/users';
2+
3+
export default (req, res) => {
4+
const userName = req.body['userName'];
5+
if (isValidUser(userName)) {
6+
res.statusCode = 200;
7+
res.json({});
8+
} else {
9+
res.statusCode = 422;
10+
res.json({ });
11+
}
12+
};

pages/api/hello.js

-6
This file was deleted.

pages/api/offers.js

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import offersData from '../../src/constants/offers.json';
2+
3+
export default (req, res) => {
4+
const userName = req.query['userName'];
5+
const latitude = parseInt(req.query['latitude'], 10);
6+
const longitude = parseInt(req.query['longitude'], 10);
7+
let city = '';
8+
9+
const citiesCoords = {
10+
mumbai: {
11+
lat: 19,
12+
lon: 72
13+
},
14+
london: {
15+
lat: 51,
16+
lon: 0
17+
},
18+
"san francisco": {
19+
lat: 37,
20+
lon: 122
21+
},
22+
singapore: {
23+
lat: 1,
24+
lon: 103
25+
},
26+
sydney: {
27+
lat: 33,
28+
lon: 101
29+
}
30+
}
31+
const citiesKeys = Object.keys(citiesCoords);
32+
citiesKeys.forEach((cityName) => {
33+
const cityCoords = citiesCoords[cityName];
34+
const hasMatchingLat = latitude >= cityCoords.lat - 1 && latitude <= cityCoords.lat + 1;
35+
const hasMatchingLon = longitude >= cityCoords.lon - 1 && longitude <= cityCoords.lon + 1;
36+
if(hasMatchingLat && hasMatchingLon) {
37+
city = cityName;
38+
}
39+
});
40+
41+
if (city) {
42+
res.statusCode = 200;
43+
res.json({ offersData });
44+
} else {
45+
res.statusCode = 404;
46+
res.json({ cityName: city });
47+
}
48+
};

pages/api/orders.js

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import ordersData from '../../src/constants/orders.json';
2+
3+
export default (req, res) => {
4+
const userName = req.query['userName'];
5+
6+
// Set 5 product as fav
7+
if (userName === 'existing_orders_user') {
8+
const orders = ordersData.orders
9+
res.statusCode = 200;
10+
res.json({ orders });
11+
} else {
12+
res.statusCode = 404;
13+
res.json({ message: 'No orders found' });
14+
}
15+
};

pages/api/products.js

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
import productsData from '../../src/constants/products.json';
2+
3+
export default (req, res) => {
4+
const userName = req.query['userName'];
5+
6+
// Set 5 product as fav
7+
if (userName === 'fav_user') {
8+
const products = productsData.products;
9+
const favProducts = products.slice(0, 5).map((product) => product.isFav = true);
10+
res.statusCode = 200;
11+
res.json({ products: products.map(itm => ({
12+
...favProducts.find((item) => (item.id === itm.id) && item),
13+
...itm
14+
}))});
15+
} else {
16+
res.statusCode = 200;
17+
res.json(productsData);
18+
}
19+
};

pages/api/signin.js

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
import { isValidUser, isValidPassword, isLockedUser } from '../../src/constants/users';
2+
3+
export default (req, res) => {
4+
const userName = req.body['userName'];
5+
const password = req.body['password'];
6+
if (isValidUser(userName) && isValidPassword(password)) {
7+
res.statusCode = 200;
8+
res.json({});
9+
} else {
10+
let errorMessage = '';
11+
if (!isValidUser(userName)) {
12+
errorMessage = 'Invalid Username';
13+
} else if (!isValidPassword(password)) {
14+
errorMessage = 'Invalid Password';
15+
} else {
16+
errorMessage = 'Something went wrong';
17+
}
18+
19+
if (isLockedUser(userName)) {
20+
errorMessage = 'Your account has been locked.'
21+
}
22+
23+
res.statusCode = 422;
24+
res.json({ errorMessage });
25+
}
26+
};

0 commit comments

Comments
 (0)