Full Stack - Time tracking app utilizing Ruby on Rails, PostgreSQL, React, Redux, and D3.js
TimeKeeper is a web application inspired by Toggl.com built using Ruby on Rails and React/Redux. It offers features for users to search and create projects, track time of each tasks, and data visualization of these tasks.
TimeKeeper is a personal project of Raymond Lee.
Users can securely create accounts using BCrypt to securely hash and salt passwords before storing them in the database so that raw passwords are never stored.
Users can create tasks and track time for each action.
Users can search for projects and create tags.
lodash's debounce
method was utilized for the search so that ajax requests are not sent off while a user is actively typing. It waits until the user has stopped typing for 150ms before sending off the request.
const mapDispatchToProps = dispatch => ({
searchProjects: _.debounce(search => dispatch(searchProjects(search)), 150)
});
<form className="projects-search">
<div className="form-group">
<input type="text"
onChange={this.updateSearchTerm}
onClick={this.updateProjectTitle}
placeholder="Search Project"
value={this.state.searchTerm} />
<ul style={{ display: this.state.searchTerm.length && !this.state.projectTitle ? 'block' : 'none' }}>
<li style={{ display: (!this.props.searchResults && this.state.searchTerm) || this.props.searchResults.length === 0 ? 'list-item' : 'none' }}>
No search results
</li>
{ this.props.searchResults ?
Object.keys(this.props.searchResults).map( (id) =>
<li key={id}
onClick={() => {
this.props.handleSearchProject(this.props.searchResults[id].id);
this.updateProjectTitle();
this.setState({searchTerm: this.props.searchResults[id].title});
}}>
{this.props.searchResults[id].title}
</li> ) : ""
}
</ul>
</div>
</form>
Users can create and view projects.
Users have access to analyzed data of their projects and tasks with time spent in pie chart and bar graphs.
D3 was used to develop live piechart with legends and hover effects.
class DataSeries extends React.Component {
render() {
const color = this.props.colors;
const data = this.props.data;
const width = this.props.width;
const height = this.props.height;
const pie = d3.layout.pie().padAngle(.02);
const result = data.map(item => item.count);
const names = data.map(item => item.name);
const sum = result.reduce(((memo, num) => memo + num), 0);
const position = "translate(" + (width)/2 + "," + (height)/2 + ")";
const bars = (pie(result)).map((point, i) => {
return (
<Sector data={point}
key={i}
ikey={i}
name={names[i]}
colors={color}
total={sum}
width={width}
height={height}/>
);
});
return (
<g transform={position}>{bars}</g>
);
}
}
Recharts was used to create barchart with animation.
TimeKeeper was built in two weeks including creating the development plan. The development plan includes the estimated timeline, planned database schema, along with the original wireframes and other planning documents.
TimeKeeper utilizes Ruby on Rails for the back end API and React.js for the front end.
TimeKeeper is a single page app.
The following is a list of some of the technologies used to create the TimeKeeper front end.
TimeKeeper makes asynchronous http requests to the back end to create, fetch, update, and delete data.
The following is a list of some of the technologies used to create the TimeKeeper back end.
There are many features planned for TimeKeeper, including the following: