# Meteor Tutorial: Creating a basic UI

Step 1: Import Todos collection in server/main.js

Now that we have defined our Todos collection in imports/api/todos.js, let us import this file into our server's main.js. Add this line to your server/main.js before importing the routes.js file:


/**
 * File: server/main.js
 */

// ...some lines skipped...

import './setup-plugins';

import '../imports/api/todos.js';
import routes from '../imports/routes';

// ...some lines skipped...


Step 2: Create imports/components/Todo.js

Let's now define our basic Todo component.

Every Todo item that is stored in our todos collection has the following schema:

Todo {
  _id: ObjectID,
  todo: String,
  completed: Boolean
}

Create a file imports/components/Todo.js and paste the following code:


/**
 * File: imports/components/Todo.js
 */

import React from 'react';
import { Meteor } from 'meteor/meteor';
import { withRouter } from 'react-router';

import {
  Col,
  Row,
  Grid,
  Icon,
  Button,
  Checkbox,
  ButtonGroup,
} from '@sketchpixy/rubix';

@withRouter
export default class Todo extends React.Component {
  toggleCompletion() {
    let { _id } = this.props.todo;
    let completed = this.input.checked;

    Meteor.call('todos.setChecked', _id, completed);
  }

  removeTodo() {
    let { _id } = this.props.todo;

    Meteor.call('todos.remove', _id);
  }

  editTodo() {
    this.props.router.push(`/todo/edit/${this.props.todo._id}`);
  }

  render() {
    let { todo, completed } = this.props.todo;
    let style = {
      textDecoration: completed ? 'line-through' : null
    };

    return (
      <Grid>
        <Row className='todo-item'>
          <Col sm={8}>
            <Checkbox onChange={::this.toggleCompletion} style={style} inputRef={(input) => { this.input = input; }} checked={completed} >
              {todo}
            </Checkbox>
          </Col>
          <Col sm={4} className='text-right'>
            <Button bsStyle='red' className='remove-sm' onClick={::this.removeTodo} style={{marginRight: 12.5}}>Remove</Button>
            <Button bsStyle='green' className='remove-sm' onlyOnHover onClick={::this.editTodo}>Edit</Button>
          </Col>
        </Row>
      </Grid>
    );
  }
}

The above code defines a Todo component that has a Checkbox for toggling the completion state of the Todo item (which also includes the todo text), a Button to remove the todo item and another Button to edit the todo item.

Three methods are defined in the Todo component. One to handle the completion state (toggleCompletion), one to remove the todo (removeTodo) and another to edit the todo item (editTodo). Both toggleCompletion and removeTodo invoke the Meteor.call RPC to modify the Todo item in our database.


Step 3: Create imports/components/TodoForm.js

Let's now define a TodoForm component that creates a new Todo item in our database.

Create a file imports/components/TodoForm.js and paste the following code:


/**
 * File: imports/components/TodoForm.js
 */

import React from 'react';
import ReactDOM from 'react-dom';
import { Meteor } from 'meteor/meteor';

import {
  Row,
  Col,
  Grid,
  Form,
  Alert,
  Button,
  Checkbox,
  FormGroup,
  FormControl } from '@sketchpixy/rubix';

export default class TodoForm extends React.Component {
  state = {
    errors: [],
  };

  createTodo(e) {
    e.preventDefault();

    let input = ReactDOM.findDOMNode(this.input);

    let todo = input.value;

    Meteor.call('todos.create', todo, (err, res) => {
      if (err) {
        this.setState({
          errors: [].concat(err),
        });
        return;
      }

      this.setState({ errors: [] });
    });

    input.value = '';
  }

  render() {
    let errors = this.state.errors.length ?
      (
        <Alert danger dismissible>
          {this.state.errors.map(({ message }, i) => {
            return <div key={i}>{message}</div>
          })}
        </Alert>
      ) : null;

    return (
      <div>
        {errors}

        <Form horizontal onSubmit={::this.createTodo}>
          <FormGroup>
            <Col sm={10}>
              <FormControl type='text' placeholder='A todo item...' ref={(input) => this.input = input} autoFocus />
            </Col>
            <Col sm={2} collapseLeft>
              <br className='visible-xs' />
              <Button type='submit' bsStyle='blue' block onlyOnHover>Create Todo</Button>
            </Col>
          </FormGroup>
        </Form>
      </div>
    );
  }
}

The above code implements a TodoForm component that renders a form to create Todo items. It implements a createTodo method that is called when the form is submitted. The createTodo method executes the RPC Meteor.call('todos.create', todo) which in turn creates a new Todo item in the todos collection. Recall these RPC methods were defined in the imports/api/todos.js file.