Altus Empire's live link https://altusempire.herokuapp.com/#/
The MERN stack was utilized to create altus-empire
. These include MongoDB Atlas as NoSQL database, Express.js as a framework for Node.js, and React/Redux for state management. Also, Google Maps API allows an embedded interactive map, and Amazon Web Services S3 allows for dispensary image storage and display.
Altus Empire includes an interactive search bar for users to query the dispensary database. This is done by setting a local state within a SearchBar
class and setting functions to update this state accordingly.
When you set the state with this.setState()
it creates another render of the component. This caused the dispensaries to be fetched repeatedly causing an extra re-render on the map. Debounce is utilized to solve the issue of repeated re-rendering and prevent instant state change.
class SearchBar extends React.Component {
constructor(props) {
super(props)
this.state = {
query: "",
focus: false
}
this.handleSubmit = this.handleSubmit.bind(this)
this.update = this.update.bind(this)
this.handleFocus = this.handleFocus.bind(this)
this.handleBlur = this.handleBlur.bind(this)
this.storeKeyWord = debounce(this.props.storeKeyWord, 200)
}
update(e) {
this.setState({ query: e.target.value }, this.handleSubmit);
}
handleFocus() {
this.setState({ focus: true })
}
handleBlur() {
this.setState({ focus: false })
}
handleSubmit(e) {
if (this.state.query === "") {
this.props.fetchDispensaries();
} else this.props.fetchSearchByNameDispensary(this.state.query)
}
render() {
const { results } = this.props
return (
<div className="search-bar" onFocus={this.handleFocus} onBlur={this.handleBlur}>
<form onSubmit={this.handleSubmit} className="search-input">
<FontAwesomeIcon icon={faSearch} />
<input type="text" placeholder="Find a dispensary near you" onChange={this.update} />
<button className="map-search-button" onClick={this.handleSubmit}>Search</button>
</form>
</div>
)
}
}
On line 85, we ensured that users would not be able to register with the same e-mail. This would ensure users to not be able to create more than one account per e-mail. A status 400 on line 88 would be returned, otherwise, the user would be created if all the credentials were entered correctly. Bcrypt is used for the authentication process.
router.post('/register', (req, res) => {
const { errors, isValid } = validateRegisterInput(req.body);
if (!isValid) {
return res.status(400).json(errors);
}
User.findOne({ email: req.body.email })
.then(user => {
85 if (user) {
return res.status(400).json({ email: "A user has already registered with this address" })
} else {
88 const newUser = new User({
username: req.body.username,
email: req.body.email,
password: req.body.password,
dob: req.body.dob,
})
bcrypt.genSalt(10, (err, salt) => {
bcrypt.hash(newUser.password, salt, (err, hash) => {
if (err) throw err;
newUser.password = hash;
newUser.save()
.then(user => {
const payload = { id: user.id, username: user.username };
jwt.sign(payload, keys.secretOrKey, { expiresIn: 3600 }, (err, token) => {
res.json({
success: true,
token: "Bearer " + token
});
});
})
.catch(err => res.send(err));
})
})
}
})
})
To install altus-empire
, follow these steps for Linux and macOS:
# Clone repository:
git clone https://github.com/gretahayes19/altus-empire.git
# Run the following command in both the root directory and frontend directory:
npm install
To contribute to altus-empire
, follow these steps:
- Fork this repository.
- Create a branch:
git checkout -b <branch_name>
. - Make your changes and commit them:
git commit -m '<commit_message>'
- Push to the original branch:
git push origin altus-empire/<location>
- Create the pull request.
Alternatively, see the GitHub documentation on creating a pull request.
Thanks to the following people who have contributed to this project:
- @gretahayes19 📖🐛 Team Lead
- @kevinxmao 📖🐛 Flex Lead
- @yangc95 📖🐛 Frontend Lead
- @hankc97 📖🐛 Backend Lead
(Left to right) Christine Yang, Greta Hayes, Hank Chen, Kevin Mao