Skip to content

Instantly share code, notes, and snippets.

/AdminPanel.js Secret

Created January 1, 2018 18:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/f63476535216edfca981c9f0968e4437 to your computer and use it in GitHub Desktop.
Save anonymous/f63476535216edfca981c9f0968e4437 to your computer and use it in GitHub Desktop.
My small react application
import React from 'react';
import PropTypes from 'prop-types';
const AdminPanel = ({onShowBooksClick, onShowMembersClick, onAddBookEntryClick, onAddMemberEntryClick, onRentBookClick}) =>{
return (
<div className="container">
<div className="buttonBar row">
<button type="button" id="btnShowBookList" className="btn btn-info col-sm-2 sm-margin" onClick={onShowBooksClick}>Show a list of books</button>
<button type="button" id="btnShowMembers" className="btn btn-info col-sm-2 sm-margin" onClick={onShowMembersClick}>Show a list of members</button>
<button type="button" id="btnAddBook" className="btn btn-info col-sm-2 sm-margin" onClick={onAddBookEntryClick}>Add a new book</button>
<button type="button" id="btnAddMember" className="btn btn-info col-sm-2 sm-margin" onClick={onAddMemberEntryClick}>Add a new member</button>
<button type="button" id="btnRentBook" className="btn btn-info col-sm-2 sm-margin" onClick={onRentBookClick}>Rent a book</button>
</div>
</div>
);
};
AdminPanel.propTypes = {
onShowBooksClick: PropTypes.func.isRequired,
onShowMembersClick: PropTypes.func.isRequired,
onAddBookEntryClick: PropTypes.func.isRequired,
onAddMemberEntryClick: PropTypes.func.isRequired,
onRentBookClick: PropTypes.func.isRequired
}
export default AdminPanel;
import React from 'react';
import PropTypes from 'prop-types';
import Header from './Header';
import AdminPanel from './AdminPanel';
import BookList from './BookList';
import MemberList from './MemberList';
import AddBookEntry from './AddBookEntry';
import AddMemberEntry from './AddMemberEntry';
import BookRent from './BookRent';
import * as api from '../api';
class App extends React.Component {
//Since we configured stage-2 in our .babelrc we can just use the class properties directly
state = {
books: null,
members: null,
checkoutInformation: null,
renderAddBookEntryForm: false,
renderAddMemberEntryForm: false
};
//Computing the header name depending on the current state
pageHeader = () => {
if (this.state.books != null) {
return 'Book list';
} else if (this.state.members != null) {
return 'Member list';
} else if (this.state.checkoutInformation != null){
return 'Rent a book'
}else if (this.state.renderAddBookEntryForm) {
return 'Add a new book';
} else if (this.state.renderAddMemberEntryForm) {
return 'Add a new member';
} else {
return 'Welcome to the library';
}
};
getBookList = () => {
api.getBookList().then(books => {
this.setState({
books: books,
members: null,
checkoutInformation: null,
renderAddBookEntryForm: false,
renderAddMemberEntryForm: false,
});
}).catch(console.error);
};
getMemberList = () => {
api.getMemberList().then(members => {
this.setState({
members: members,
books: null,
checkoutInformation: null,
renderAddBookEntryForm: false,
renderAddMemberEntryForm: false,
});
}).catch(console.error);
};
addNewBookEntry = (newName, newAuthor, newDescription) => {
api.addNewBookEntry(newName, newAuthor, newDescription)
.then(books => {
this.setState({
books: books,
renderAddBookEntryForm: false,
});
}).catch(console.error);
};
addNewMemberEntry = (newFirstName, newLastName, newRole) => {
api.addNewMemberEntry(newFirstName, newLastName, newRole)
.then(members => {
this.setState({
members: members,
renderAddMemberEntryForm: false
});
}).catch(console.error);
};
saveRentInformation = (bookId, memberId) => {
api.rentABook(bookId, memberId)
.then(rentedBook => {
//TODO: Find a way to do this cleaner, i don't want to call the same functions twice when it's probably possible to do it in one call
this.setState((prevState, rentedBook) => ({
books: prevState.checkoutInformation.books,
checkoutInformation: null
}));
this.setState({
books: {
...this.state.books,
[rentedBook._id]: rentedBook
},
});
}).catch(console.error);
};
showAddBookEntryForm = () => {
this.setState({
books: null,
members: null,
checkoutInformation: null,
renderAddBookEntryForm: true,
renderAddMemberEntryForm: false
});
};
showAddMemberEntryForm = () => {
this.setState({
books: null,
members: null,
checkoutInformation: null,
renderAddBookEntryForm: false,
renderAddMemberEntryForm: true
});
};
getCheckoutInformation = () => {
api.getCheckoutInformation().then(checkoutInformation => {
this.setState({
books: null,
members: null,
checkoutInformation: checkoutInformation,
renderAddBookEntryForm: false,
renderAddMemberEntryForm: false
});
}).catch(console.error);
};
//Handling content rendering depending on the state
currentBookListContent = () => {
if (this.state.books == null) {
return;
}
return <BookList books={this.state.books} />;
};
currentMemberListContent = () => {
if (this.state.members == null) {
return;
}
return <MemberList members={this.state.members} />;
};
currentAddBookEntryContent = () => {
if(this.state.renderAddBookEntryForm){
return <AddBookEntry addNewBookEntry = {this.addNewBookEntry} />;
}
return;
};
currentAddMemberEntryContent = () => {
if (this.state.renderAddMemberEntryForm) {
return <AddMemberEntry addNewMemberEntry = {this.addNewMemberEntry} />;
}
return;
};
currentRentBookContent = () => {
if(this.state.checkoutInformation != null){
return <BookRent bookInformation = {this.state.checkoutInformation.books}
memberInformation = {this.state.checkoutInformation.members}
saveRentInformation = {this.saveRentInformation}/>
}
return;
};
render() {
return (
<div className="App ">
<Header message={this.pageHeader()} />
<AdminPanel onShowBooksClick = {this.getBookList}
onShowMembersClick = {this.getMemberList}
onAddBookEntryClick= {this.showAddBookEntryForm}
onAddMemberEntryClick = {this.showAddMemberEntryForm}
onRentBookClick = {this.getCheckoutInformation} />
{this.currentBookListContent()}
{this.currentMemberListContent()}
{this.currentAddBookEntryContent()}
{this.currentAddMemberEntryContent()}
{this.currentRentBookContent()}
</div>
);
};
};
App.propTypes = {
books: PropTypes.object,
members: PropTypes.object
};
export default App;
<%- include('header') -%>
<div id="root"><%- initialMarkup -%></div>
<%- include('footer') -%>
import React from 'react';
import ReactDOM from 'react-dom';
import App from './components/App';
ReactDOM.render(
<App />,
document.getElementById('root')
);
import config from './config';
import apiRouter from './api';
import sassMiddleware from 'node-sass-middleware';
import path from 'path';
import bodyParser from 'body-parser';
import mongoose from 'mongoose';
mongoose.Promise = global.Promise;
mongoose.connect(config.mongodbUri, { useMongoClient: true })
.then(()=> {
console.log('Successfully connected to database at: ' + config.mongodbUri);
},
err => {
throw new Error('Unable to connect to database at: ' + config.mongodbUri);
}
);
import express from 'express';
const server = express();
server.use(bodyParser.json());
server.use(sassMiddleware({
src: path.join(__dirname, 'sass'),
dest: path.join(__dirname, 'public')
}));
//Set view engine for templating
server.set('view engine', 'ejs');
import serverRender from './serverRender';
//Rendering the app component on an ejs template on the root level
server.get('/', (req, res) => {
res.render('index', serverRender());
});
server.use('/api', apiRouter);
//Express static middleware used to serve static assets
server.use(express.static('public'));
server.listen(config.port, config.host, ()=>{
console.info('Express listening on port', config.port);
});
import React from 'react';
import ReactDomServer from 'react-dom/server';
import App from './src/components/App';
import config from './config';
const serverRender = () => {
return {
initialMarkup: ReactDomServer.renderToString(
<App />
)
}
}
export default serverRender;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment