Create basic layout and navigation for client
This commit is contained in:
parent
9f77ca5215
commit
c081c6ecc3
|
@ -5,7 +5,9 @@
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"react": "^16.2.0",
|
"react": "^16.2.0",
|
||||||
"react-dom": "^16.2.0",
|
"react-dom": "^16.2.0",
|
||||||
"react-scripts": "1.1.0"
|
"react-router-dom": "^4.2.2",
|
||||||
|
"react-scripts": "1.1.0",
|
||||||
|
"semantic-ui-react": "^0.77.2"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "react-scripts start",
|
"start": "react-scripts start",
|
||||||
|
@ -13,4 +15,4 @@
|
||||||
"test": "react-scripts test --env=jsdom",
|
"test": "react-scripts test --env=jsdom",
|
||||||
"eject": "react-scripts eject"
|
"eject": "react-scripts eject"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,40 +1,43 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||||
<meta name="theme-color" content="#000000">
|
<meta name="theme-color" content="#000000">
|
||||||
<!--
|
<!--
|
||||||
manifest.json provides metadata used when your web app is added to the
|
manifest.json provides metadata used when your web app is added to the
|
||||||
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
|
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
|
||||||
-->
|
-->
|
||||||
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
|
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
|
||||||
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
|
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
|
||||||
<!--
|
<!--
|
||||||
Notice the use of %PUBLIC_URL% in the tags above.
|
Notice the use of %PUBLIC_URL% in the tags above.
|
||||||
It will be replaced with the URL of the `public` folder during the build.
|
It will be replaced with the URL of the `public` folder during the build.
|
||||||
Only files inside the `public` folder can be referenced from the HTML.
|
Only files inside the `public` folder can be referenced from the HTML.
|
||||||
|
|
||||||
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
|
||||||
work correctly both with client-side routing and a non-root public URL.
|
work correctly both with client-side routing and a non-root public URL.
|
||||||
Learn how to configure a non-root public URL by running `npm run build`.
|
Learn how to configure a non-root public URL by running `npm run build`.
|
||||||
-->
|
-->
|
||||||
<title>React App</title>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<noscript>
|
|
||||||
You need to enable JavaScript to run this app.
|
|
||||||
</noscript>
|
|
||||||
<div id="root"></div>
|
|
||||||
<!--
|
|
||||||
This HTML file is a template.
|
|
||||||
If you open it directly in the browser, you will see an empty page.
|
|
||||||
|
|
||||||
You can add webfonts, meta tags, or analytics to this file.
|
<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/semantic-ui/2.2.12/semantic.min.css"></link>
|
||||||
The build step will place the bundled scripts into the <body> tag.
|
|
||||||
|
|
||||||
To begin the development, run `npm start` or `yarn start`.
|
<title>React App</title>
|
||||||
To create a production bundle, use `npm run build` or `yarn build`.
|
</head>
|
||||||
-->
|
<body>
|
||||||
</body>
|
<noscript>
|
||||||
|
You need to enable JavaScript to run this app.
|
||||||
|
</noscript>
|
||||||
|
<div id="root"></div>
|
||||||
|
<!--
|
||||||
|
This HTML file is a template.
|
||||||
|
If you open it directly in the browser, you will see an empty page.
|
||||||
|
|
||||||
|
You can add webfonts, meta tags, or analytics to this file.
|
||||||
|
The build step will place the bundled scripts into the <body> tag.
|
||||||
|
|
||||||
|
To begin the development, run `npm start` or `yarn start`.
|
||||||
|
To create a production bundle, use `npm run build` or `yarn build`.
|
||||||
|
-->
|
||||||
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
|
@ -1,28 +0,0 @@
|
||||||
.App {
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.App-logo {
|
|
||||||
animation: App-logo-spin infinite 20s linear;
|
|
||||||
height: 80px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.App-header {
|
|
||||||
background-color: #222;
|
|
||||||
height: 150px;
|
|
||||||
padding: 20px;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.App-title {
|
|
||||||
font-size: 1.5em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.App-intro {
|
|
||||||
font-size: large;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes App-logo-spin {
|
|
||||||
from { transform: rotate(0deg); }
|
|
||||||
to { transform: rotate(360deg); }
|
|
||||||
}
|
|
|
@ -1,21 +1,89 @@
|
||||||
import React, { Component } from 'react';
|
import React, { Component } from 'react';
|
||||||
import logo from './logo.svg';
|
import Categories from './Categories';
|
||||||
import './App.css';
|
import Category from './Category';
|
||||||
|
import { Container, Dropdown, Header, Icon, Item, Menu, Segment, Input } from 'semantic-ui-react';
|
||||||
|
import { Link, Route } from 'react-router-dom';
|
||||||
|
|
||||||
|
const fakeData = {
|
||||||
|
categories: [
|
||||||
|
{
|
||||||
|
name: "Woodshop",
|
||||||
|
slug: "woodshop",
|
||||||
|
info: "Some info about the woodshop.",
|
||||||
|
photo: "https://i.imgur.com/RIm8aoG.jpg",
|
||||||
|
tools: [
|
||||||
|
{
|
||||||
|
id: 0,
|
||||||
|
name: "White Bandsaw",
|
||||||
|
photo: "http://wiki.protospace.ca/images/thumb/f/f8/105.jpg/146px-105.jpg",
|
||||||
|
notes: "Requires training. Tighten tension lever prior to use / Loosen tension lever after use. Tension lever is on rear.",
|
||||||
|
wikiId: 105,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 1,
|
||||||
|
name: "Jointer",
|
||||||
|
photo: "http://wiki.protospace.ca/images/thumb/6/6f/73.jpg/302px-73.jpg",
|
||||||
|
notes: "Boards must be ABSOLUTELY FREE of nails, staples, screws, or other metal. Check boards thoroughly each and every time, make no presumptions. One mistake will chip the blade and render it useless (drum blades are very expensive).",
|
||||||
|
wikiId: 73,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Metalshop",
|
||||||
|
slug: "metalshop",
|
||||||
|
info: "Some info about the metalshop",
|
||||||
|
photo: "https://i.imgur.com/A2L2ACY.jpg",
|
||||||
|
tools: [
|
||||||
|
{
|
||||||
|
id: 2,
|
||||||
|
name: "Tormach CNC",
|
||||||
|
photo: "http://wiki.protospace.ca/images/thumb/c/cf/49.jpg/320px-49.jpg",
|
||||||
|
notes: "Must complete Shop Safety, Lathe Training, 3D CAD Training, CAM Training, 1 on 1 Project.",
|
||||||
|
wikiID: 49,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
id: 3,
|
||||||
|
name: "Powerfist Bench Grinder",
|
||||||
|
photo: "http://wiki.protospace.ca/images/thumb/c/cd/39.jpg/298px-39.jpg",
|
||||||
|
notes: "A bench grinder is for grinding steels or deburring steel or aluminum (if fitted with a wire wheel).",
|
||||||
|
wikiID: 39,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
class App extends Component {
|
class App extends Component {
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<div className="App">
|
<div>
|
||||||
<header className="App-header">
|
<Menu fixed='top' borderless inverted>
|
||||||
<img src={logo} className="App-logo" alt="logo" />
|
<Menu.Item>
|
||||||
<h1 className="App-title">Welcome to React</h1>
|
<Icon name='bars' size='big' />
|
||||||
</header>
|
</Menu.Item>
|
||||||
<p className="App-intro">
|
<Menu.Item as={Link} to='/'>
|
||||||
To get started, edit <code>src/App.js</code> and save to reload.
|
<Icon name='home' size='big' />
|
||||||
</p>
|
</Menu.Item>
|
||||||
</div>
|
<Menu.Menu position='right'>
|
||||||
);
|
<Menu.Item position='right'>
|
||||||
}
|
<Input transparent inverted placeholder='Search...' icon='search' />
|
||||||
|
</Menu.Item>
|
||||||
|
</Menu.Menu>
|
||||||
|
</Menu>
|
||||||
|
<div style={{height: '54px', display: 'inline-block'}} />
|
||||||
|
|
||||||
|
<Route exact path='/' render={props =>
|
||||||
|
<Categories {...props} data={fakeData} />
|
||||||
|
} />
|
||||||
|
|
||||||
|
<Route exact path='/:category' render={props =>
|
||||||
|
<Category {...props} data={fakeData} />
|
||||||
|
} />
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default App;
|
export default App;
|
||||||
|
|
35
webclient/src/Categories.js
Normal file
35
webclient/src/Categories.js
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
import { Container, Dropdown, Header, Icon, Item, Menu, Segment, Input } from 'semantic-ui-react'
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
|
class Categories extends Component {
|
||||||
|
render() {
|
||||||
|
const data = this.props.data;
|
||||||
|
const match = this.props.match;
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Segment basic>
|
||||||
|
<Header size='large'>Tool Categories</Header>
|
||||||
|
</Segment>
|
||||||
|
|
||||||
|
<Container>
|
||||||
|
<Item.Group link unstackable divided>
|
||||||
|
{data.categories.map((x, n) =>
|
||||||
|
<Item as={Link} to={'/' + x.slug} key={n}>
|
||||||
|
<Item.Image size='tiny' src={x.photo} />
|
||||||
|
<Item.Content>
|
||||||
|
<Item.Header>{x.name}</Item.Header>
|
||||||
|
<Item.Description>{x.info}</Item.Description>
|
||||||
|
<Item.Extra>{x.tools.length} tools</Item.Extra>
|
||||||
|
</Item.Content>
|
||||||
|
</Item>
|
||||||
|
)}
|
||||||
|
</Item.Group>
|
||||||
|
</Container>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Categories;
|
38
webclient/src/Category.js
Normal file
38
webclient/src/Category.js
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
import React, { Component } from 'react';
|
||||||
|
import { Container, Dropdown, Header, Icon, Item, Menu, Segment, Input } from 'semantic-ui-react'
|
||||||
|
import { Link } from 'react-router-dom';
|
||||||
|
|
||||||
|
class Category extends Component {
|
||||||
|
render() {
|
||||||
|
const data = this.props.data;
|
||||||
|
const match = this.props.match;
|
||||||
|
|
||||||
|
const category = data.categories.find((x) =>
|
||||||
|
x.slug == match.params.category
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div>
|
||||||
|
<Segment basic>
|
||||||
|
<Header size='large'>{category.name} Tools</Header>
|
||||||
|
</Segment>
|
||||||
|
|
||||||
|
<Container>
|
||||||
|
<Item.Group link unstackable divided>
|
||||||
|
{category.tools.map((x, n) =>
|
||||||
|
<Item key={n}>
|
||||||
|
<Item.Image size='tiny' src={x.photo} />
|
||||||
|
<Item.Content>
|
||||||
|
<Item.Header>{x.name}</Item.Header>
|
||||||
|
<Item.Extra>Wiki ID: {x.wikiId}</Item.Extra>
|
||||||
|
</Item.Content>
|
||||||
|
</Item>
|
||||||
|
)}
|
||||||
|
</Item.Group>
|
||||||
|
</Container>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default Category;
|
|
@ -3,6 +3,12 @@ import ReactDOM from 'react-dom';
|
||||||
import './index.css';
|
import './index.css';
|
||||||
import App from './App';
|
import App from './App';
|
||||||
import registerServiceWorker from './registerServiceWorker';
|
import registerServiceWorker from './registerServiceWorker';
|
||||||
|
import { BrowserRouter } from 'react-router-dom';
|
||||||
|
|
||||||
|
ReactDOM.render((
|
||||||
|
<BrowserRouter>
|
||||||
|
<App />
|
||||||
|
</BrowserRouter>
|
||||||
|
), document.getElementById('root'));
|
||||||
|
|
||||||
ReactDOM.render(<App />, document.getElementById('root'));
|
|
||||||
registerServiceWorker();
|
registerServiceWorker();
|
||||||
|
|
6705
webclient/yarn.lock
Normal file
6705
webclient/yarn.lock
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user