Skip to content

Commit

Permalink
Merge pull request #15 from alexlee-dev/v0.5.0
Browse files Browse the repository at this point in the history
📦 v0.5.0
  • Loading branch information
Alex Lee authored Jun 5, 2020
2 parents 142f49a + 54edd06 commit c332411
Show file tree
Hide file tree
Showing 23 changed files with 556 additions and 9 deletions.
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,24 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [0.5.0] - 2020-06-05

### 🍻 Beers in the DB

### Added

- Beers Database [#10](https://github.com/alexlee-dev/create-mern-application/issues/10)

### Changed

- Add application name to `App.js` / `App.tsx`

### Removed

### Fixed

- No assets being served by server

## [0.4.0] - 2020-06-04

### 🧪 Testing
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "create-mern-application",
"version": "0.4.0",
"version": "0.5.0",
"description": "A bootstrapper for creating a MERN application.",
"bin": {
"create-mern-application": "./index.js"
Expand Down
4 changes: 2 additions & 2 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ const pkg = require("../package.json");
Sentry.init({
dsn:
"https://44111e696abc456c959aef6dfc97f6a7@o202486.ingest.sentry.io/5262339",
release: "0.4.0",
release: "0.5.0",
});

import {
Expand Down Expand Up @@ -42,7 +42,7 @@ const main = async (): Promise<void> => {
* The program that parses the initial user input
*/
const program = new commander.Command("create-mern-application")
.version("0.4.0")
.version("0.5.0")
.arguments("<application-name>")
.usage(`${chalk.blueBright("<application-name>")} [options]`)
.action((name) => {
Expand Down
6 changes: 6 additions & 0 deletions src/init.ts
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,12 @@ export const replaceTemplateValues = async (
path.join(root, "/src/server/assets/site.webmanifest"),
];

if (language === "js") {
replaceFiles.push(path.join(root, "/src/client/App.js"));
} else {
replaceFiles.push(path.join(root, "/src/client/App.tsx"));
}

// * Apply real values to template files
await Promise.all(
valueReplacer(
Expand Down
21 changes: 20 additions & 1 deletion src/template/js/src/client/App.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,29 @@
import * as React from "react";
import logo from "./logo.svg";
import BeerDisplayer from "./components/BeerDisplayer";
import { initializeStarterBeers, getBeers } from "./api/beer";

const App = () => {
const [beers, setBeers] = React.useState([]);

React.useEffect(() => {
const initializeData = async () => {
try {
let currentBeers = await getBeers();
if (currentBeers.length === 0) {
await initializeStarterBeers();
currentBeers = await getBeers();
}
setBeers(currentBeers);
} catch (error) {}
};
initializeData();
}, []);

return (
<div id="app">
<img alt="Logo" id="logo" src={logo} />
<h1>create-mern-application</h1>
<h1>___APP NAME___</h1>
<p>
Edit <code>src/client/App.tsx</code> and save to reload.
</p>
Expand All @@ -16,6 +34,7 @@ const App = () => {
>
View Documentation
</a>
<BeerDisplayer beers={beers} />
</div>
);
};
Expand Down
35 changes: 35 additions & 0 deletions src/template/js/src/client/api/beer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { starterBeers } from "../constants";

export const initializeStarterBeers = async () => {
try {
starterBeers.forEach(async ({ abv, brewer, description, name, type }) => {
await fetch("/beer", {
body: JSON.stringify({
abv,
brewer,
description,
name,
type,
}),
headers: {
"Content-Type": "application/json",
},
method: "POST",
});
});

return;
} catch (error) {
console.error(error);
}
};

export const getBeers = async () => {
try {
const response = await fetch("/beers");
const beers = await response.json();
return beers;
} catch (error) {
console.error(error);
}
};
28 changes: 28 additions & 0 deletions src/template/js/src/client/components/BeerDisplayer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import * as React from "react";

const BeerDisplayer = ({ beers }) => (
<table>
<thead>
<tr>
<th className="column1">ABV</th>
<th>Brewer</th>
<th>Description</th>
<th>Name</th>
<th className="column5">Type</th>
</tr>
</thead>
<tbody>
{beers.map((beer) => (
<tr key={beer._id}>
<td className="column1">{beer.abv}</td>
<td>{beer.brewer}</td>
<td>{beer.description}</td>
<td>{beer.name}</td>
<td className="column5">{beer.type}</td>
</tr>
))}
</tbody>
</table>
);

export default BeerDisplayer;
30 changes: 30 additions & 0 deletions src/template/js/src/client/constants.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
export const starterBeers = [
{
abv: 7.0,
brewer: "Cool Guy Brewing",
description: "A very IPA-y beer!",
name: "Tank Top",
type: "IPA",
},
{
abv: 4.2,
brewer: "America Light",
description: "Not quite pee water, but it's cheap.",
name: "Light Me Up",
type: "Light Beer",
},
{
abv: 6.3,
brewer: "Hip Ship",
description: "It tastes like gold!",
name: "El Dorado",
type: "Amber Ale",
},
{
abv: 14.4,
brewer: "Grim Reaper",
description: "Good god, I'm drunk.",
name: "End Times",
type: "Mead?",
},
];
32 changes: 32 additions & 0 deletions src/template/js/src/client/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,40 @@ body {
flex-direction: column;
justify-content: center;
min-height: 100vh;
padding: 25px;
}

#logo {
height: 300px;
}

table {
border-collapse: collapse;
border-radius: 10px;
margin-top: 25px;
overflow: hidden;
}

table thead tr {
background-color: #39374d;
color: white;
height: 50px;
}

td,
th {
padding: 8px;
text-align: left;
}

.column1 {
padding-left: 30px;
}

.column5 {
padding-right: 30px;
}

tbody tr:nth-child(even) {
background-color: #e9ecef;
}
13 changes: 12 additions & 1 deletion src/template/js/src/server/controllers/assets.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,18 @@ import path from "path";
class AssetsController {
router = express.Router();

static assetList = [];
static assetList = [
"android-chrome-192x192.png",
"android-chrome-512x512.png",
"apple-touch-icon.png",
"browserconfig.xml",
"favicon-16x16.png",
"favicon-32x32.png",
"favicon.ico",
"mstile-150x150.png",
"safari-pinned-tab.svg",
"site.webmanifest",
];

constructor() {
this.initializeRoutes();
Expand Down
61 changes: 61 additions & 0 deletions src/template/js/src/server/controllers/beer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import express from "express";
import Beer from "../models/Beer";

class BeerController {
router = express.Router();

constructor() {
this.initializeRoutes();
}

initializeRoutes() {
this.router.get("/beers", async (req, res) => {
try {
const beers = await Beer.find();

res.send(beers);
} catch (error) {
res.status(500).send({ error });
}
});

this.router.post("/beer", async (req, res) => {
try {
const newBeer = new Beer({
abv: req.body.abv,
brewer: req.body.brewer,
description: req.body.description,
name: req.body.name,
type: req.body.type,
});

await newBeer.save();

res.status(201).send(newBeer);
} catch (error) {
res.status(500).send({ error: error.message });
}
});

this.router.patch("/beer/:id", async (req, res) => {
try {
const beer = await Beer.findById(req.params.id);

if (!beer) {
return res.status(404).send();
}

const updates = Object.keys(req.body);
updates.forEach((update) => (beer[update] = req.body[update]));

await beer.save();

res.send(beer);
} catch (error) {
res.status(500).send({ error });
}
});
}
}

export default BeerController;
3 changes: 2 additions & 1 deletion src/template/js/src/server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import chalk from "chalk";

import App from "./app";
import AssetsController from "./controllers/assets";
import BeerController from "./controllers/beer";
import ScriptsController from "./controllers/scripts";
import { checkIfMongoDBIsRunning } from "./util";

Expand All @@ -27,7 +28,7 @@ const main = async () => {
}

const app = new App(
[new AssetsController(), new ScriptsController()],
[new AssetsController(), new BeerController(), new ScriptsController()],
process.env.PORT
);

Expand Down
37 changes: 37 additions & 0 deletions src/template/js/src/server/models/Beer.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import mongoose from "mongoose";

const beerSchema = new mongoose.Schema(
{
abv: {
required: true,
type: Number,
},
brewer: {
required: true,
type: String,
},
description: {
required: true,
type: String,
},
name: {
required: true,
type: String,
},
type: {
required: true,
type: String,
},
},
{ timestamps: true }
);

function applicationToJSON() {
return this.toObject();
}

beerSchema.methods.toJSON = applicationToJSON;

const Beer = mongoose.model("Beer", beerSchema);

export default Beer;
Loading

0 comments on commit c332411

Please sign in to comment.