# Creating a Kazana app

Kazana is a generic data warehouse framework which first and foremost provides
a simple-to-use backend. A frontend can be as simple as a static HTML app
that is perfectly suited for the respective use case. The HTML app can be
hosted on a different host and use the Kazana backend remotely, or it can be
added into a folder which can be set in the
[public option of the kazana manifest](../api/kazana-manifest.md#public).

## Create HTML app

Create `public/index.html` with the following content:

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>My App</title>
  </head>
  <body>
    <h1>My App</h1>
  </body>
</html>
```

Add the `public` option to `index.js`

```js
module.exports = {
  name: 'myapp',
  version: '1.0.0',
  public: 'public'
}
```

Now start the app with

```
$ npm start
```

And open your app at http://localhost:5000. You should see a big **My App**
in your browser.

## Add a Login form

Add a login form, bootstrap styling and scripts for jQuery and `app.js`
to `public/index.html`

```html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <title>My App</title>

    <link rel="stylesheet" type="text/css" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
  </head>
  <body class="container">
    <h1>My App</h1>

    <form id="loginForm" action="/kazana/account/api/session" class="form-inline">
      <div class="form-group">
        <label>Email</label>
        <input type="text" class="form-control" name="email" value="" placeholder="john@example.com">
      </div>
      <div class="form-group">
        <label>Password</label>
        <input type="password" class="form-control" name="password" value="">
      </div>
      <button type="submit" class="btn btn-primary">Sign in</button>
    </form>

    <script src="http://code.jquery.com/jquery-2.1.4.min.js"></script>
    <script src="app.js"></script>
  </body>
</html>

```

Then add `public/app.js` with the following content

```js
var $accountForm = $('#loginForm')
$accountForm.on('submit', handleSignInFormSubmit)

function handleSignInFormSubmit (event) {
  // avoid page reload on form submit
  event.preventDefault()

  // get values from inputs
  var email = $('[name="email"]').val()
  var password = $('[name="password"]').val()

  // send AJAX request against the account REST API
  $.ajax({
    type: 'post',
    url: '/kazana/account/api/session',
    contentType: 'application/json',
    data: JSON.stringify({
      name: email,
      password: password
    })
  })

  .done(function (response) {
    alert('Hello, ' + response.name)
  })

  .fail(function (xhr, status, error) {
    alert(error)
  })
}
```

Create a user at http://localhost:4999/_utils/#/database/_users/new
Enter this content and save the document.

```json
{
    "_id": "org.couchdb.user:test@example.com",
    "type": "user",
    "name": "test@example.com",
    "roles": [
        "kazana-id:uuid123",
        "kazana-data-provider"
    ],
    "password": "secret",
    "createdAt": "2016-01-01T00:00:00.000Z",
    "fullname": "Test Admin"
}
```

Now open http://localhost:5000. Enter `test@example.com` into the email input
and `secret` into the password input. Press the `Sign in` button. You should
see a welcome message.

## Persist login state

Replace the `<form>...</form>` in `public/index.html` to add a welcome message and a
sign out link if the user is signed in

```html
<div id="account">
  <form id="loginForm" data-show="signed-out" action="/kazana/account/api/session" class="form-inline">
    <div class="form-group">
      <label>Email</label>
      <input type="text" class="form-control" name="email" placeholder="john@example.com">
    </div>
    <div class="form-group">
      <label>Password</label>
      <input type="password" class="form-control" name="password">
    </div>
    <button type="submit" class="btn btn-primary">Sign in</button>
  </form>
  <p data-show="signed-in" >
    Welcome back,<br>
    <strong id="username"></strong>
    (<a id="logoutButton" href="signOut">sign out</a>)
  </p>
</div>
```

And set the default app state to signed out by replacing the `<body>` tag with

```html
<body class="container" data-account-state="signed-out">
```

And load `app.css` by adding below the existing `<link>` tag:

```html
<link rel="stylesheet" type="text/css" href="app.css">
```

Create `public/app.css` with the following content. That will hide all tags
with `data-show="signed-out"` if the `data-account-state` on the `<body>` tag
is set to `signed-in`, and vice versa.

```css
[data-show] {
  display: none;
}
[data-account-state="signed-out"] [data-show="signed-out"],
[data-account-state="signed-in"] [data-show="signed-in"] {
  display: block;
}
```

To persist a user session, we store the session id and username in localStorage.
In `public/app.js`, replace the `handleSignInFormSubmit` function  with the extra
code in the `.done` handler

```js
function handleSignInFormSubmit (event) {
  // avoid page reload on form submit
  event.preventDefault()

  // get values from inputs
  var email = $('[name="email"]').val()
  var password = $('[name="password"]').val()

  // send AJAX request against the account REST API
  $.ajax({
    type: 'post',
    url: '/kazana/account/api/session',
    contentType: 'application/json',
    data: JSON.stringify({
      name: email,
      password: password
    })
  })

  .done(function (response) {
    // reset form
    $accountForm.find('input').val('')
    // set app state to signed in
    $(document.body).attr('data-account-state', 'signed-in')
    // persist username & session token
    localStorage.setItem('username', response.name)
    localStorage.setItem('bearerToken', response.bearerToken)
    // set username in page
    $('#username').text(response.name)
  })

  .fail(function (xhr, status, error) {
    alert(error)
  })
}
```

On the initial page load, we want to check if the user is logged in and if
their session is still valid. Add this to `public/app.js`

```js
// send bearer token if present
$.ajaxSetup({
  beforeSend: function (xhr) {
    var token = localStorage.getItem('bearerToken')
    if (!token) return
    xhr.setRequestHeader('authorization', 'Bearer ' + token)
  }
})

checkSession()

function checkSession () {
  var token = localStorage.getItem('bearerToken')
  var username = localStorage.getItem('username')

  if (!token || !username) {
    return $(document.body).attr('data-account-state', 'signed-out')
  }

  $(document.body).attr('data-account-state', 'signed-in')
  $('#username').text(username)

  $.getJSON('/kazana/account/api/session')
    .fail(function () {
      $(document.body).attr('data-account-state', 'signed-out')
      localStorage.clear()
    })
}
```

Now we still need to add the sign out handler. Add this to `public/app.js`

```js
$('#signout').on('click', function (event) {
  function handleSignOutClick (event) {
    event.preventDefault()

    $.ajax({
      type: 'delete',
      url: '/kazana/account/api/session'
    })
      .done(function () {
        localStorage.clear()
        checkSession()
      })
      .fail(function (xhr, status, error) {
        alert(error)
      })
  }
})
```

## Submit raw data reports

Add a new div below `<div id="account">...</div>` to `public/index.html`

```html
<div data-show="signed-in">
  <form id="reportForm" action="/kazana/raw-data/api/submissions">
    <h2>Submit / Update report</h2>
    <div class="form-group">
      <input name="name" class="form-control" placeholder="report name">
    </div>
    <div class="form-group">
      <p class="help-block">
        Add one line per income/expense, in the format
        "+123.40 category"
      </p>

      <textarea name="data" class="form-control"></textarea>
    </div>

    <button type="submit" class="btn btn-primary">Submit</button>
  </form>

  <h2>Submitted Reports</h2>
  <ul id="reports"></ul>

  <h2>Expenses by category</h2>
  <pre id="expenses"></pre>
</div>
```

Add the following code to `app.js` to `public/index.html`

```js
var $dataReportForm = $('#reportForm')
$dataReportForm.on('submit', handleDataReportFormSubmit)

function handleDataReportFormSubmit (event) {
  event.preventDefault()

  var action = $dataReportForm.attr('action')
  var name = $('[name="name"]').val()
  var data = $('[name="data"]').val()

  $.ajax({
    type: 'post',
    url: action,
    contentType: 'application/json',
    data: JSON.stringify({
      sourceId: 'bookkeeping',
      name: name,
      data: data
    })
  })
    .done(function () {
      alert('submitted')
      $dataReportForm[0].reset()
    })
    .fail(function (xhr, status, error) {
      alert(error)
    })
}
```

That will upload new raw data reports, but nothing will happen with them, until
you define a transform script for them. Follow the
[transform tutorial](transform.md) for more details.
