【個人開発】自分だけのうまくいく方法を見つける目標達成サービス「b-logic」をリリースしました。

# はじめに
突然ですが、目標を立てて達成できたことありますか？
筆者は`英語を喋れるようになる`や`筋肉ムキムキになる`といった目標を人生の中で幾度となく立ててきました。
ほとんど3日坊主で続きません。
なんどもなんども自分はなんて意志力のない人間なんだと嘆きました。
しかし本当にそうでしょうか？
実はやり方がまずいだけなのではないでしょうか？自分だけのうまくいく方法があるはずです。
そう、プログラムのように今まではエラーが起きていて、実は正しいプログラムではなかったのです。
正しいプログラムさえ、正しいやり方さえ見つければどんな目標だって達成できるはず
このような思いから、目標達成を条件ベースで考えていく目標達成サービスを作りました。
# サービス概要
ユーザーは`目標`、`課題`、`タスク`といった３つ観点から目標を計画をします。
達成できない目標はいつだって、具体的な行動が欠けていたり、ひとそれぞれ集中できる環境、タイミングが存在します。（家だと集中できないけど図書館なら集中できるとか）
自分だけのうまくいく方法をサービスを使いながら、見つけていきユーザーへ目標達成を促します。
https://b-logic.herokuapp.com/
# 何がうれしいのか？
目標が3日坊主で終わる原因の大半は見切り発車で、具体的な計画を立てて無いことが原因です。
作成したサービスでは`目標`、`課題`、`タスク`と決まったフォーマットを用意し順番に作成していくことで、自然と計画的な目標を立てることができます。
# 使い方
## 目標新規作成
まず目標を作成します。 `目標新規作成ボタン`をクリックします。
![image](https://i.gyazo.com/9a4bb870a4aeae5b9ac7be1462d95b2d.png)
## 目標登録
`目標名`と`期限`決めます。
目標名は`画像`のように数字で具体的にしましょう。悪い例として`お金持ちになる`という目標はざっくりすぎなのでやめましょう。
![image](https://i.gyazo.com/47322552868022057369726da6bd7d09.png)
`登録ボタン`を押して目標を作成します。
[![Image from Gyazo](https://i.gyazo.com/1854c6755b19afd39d52ddc088e9bd83.gif)](https://gyazo.com/1854c6755b19afd39d52ddc088e9bd83)
## 課題が解除された
鍵が解除されて`課題`という項目が出現しました。
`課題一覧`をクリックして`課題一覧ページ`へ移動しましょう。
[![Image from Gyazo](https://i.gyazo.com/d10c031360f27b797dd17b6e8264b771.gif)](https://gyazo.com/d10c031360f27b797dd17b6e8264b771)
## 課題一覧ページ
`課題一覧ページ`ではすべての`課題`と、作成した`目標別の課題`が表示されています。
左のエリアを見ると、先程作成した`目標名`が表示されていますね。
現状`課題`を作成していないので、作ってみましょう。
`＋ボタン`をクリックします。
[![Image from Gyazo](https://i.gyazo.com/0a2ae234384488e919dea3150eb23d52.gif)](https://gyazo.com/0a2ae234384488e919dea3150eb23d52)
## 課題・解決案作成
`課題名`と`解決策`を決めます。
今回は2つ登録してみました。
課題は現状の`問題点`をあげ、`問題点`に対してどうするかの`方向性を解決策`として登録します。
`お菓子の出費`が激しいのは夜中に`コンビニに行くという習慣`ができてしまっているため、`22時に寝る`
`ECサイトでの出費`が多いのは、`気軽に購入`できてしまうため、踏みとどまれるようにクレジットカードの登録を解除して、`購入に時間をかからせる`。
このように`課題`と`解決策`を登録していきます。
課題は作りすぎても大変なので、2〜3つがベストかと思います。
[![Image from Gyazo](https://i.gyazo.com/939d93b2cffcdaf6cb38934cc310a3b7.gif)](https://gyazo.com/939d93b2cffcdaf6cb38934cc310a3b7)
## タスク鍵解除・タスク一覧ページへ
`タスク`を登録します。
トップページに戻り、`タスク一覧ページ`へ移動します。
[![Image from Gyazo](https://i.gyazo.com/e65a7153b0213c538881f559f79a6105.gif)](https://gyazo.com/e65a7153b0213c538881f559f79a6105)
## タスク作成
左の枠から`タスク`を追加する`課題`を選び`＋ボタン`をクリックします。
[![Image from Gyazo](https://i.gyazo.com/f5664bd2057270f8c425d271f4a2fd3a.gif)](https://gyazo.com/f5664bd2057270f8c425d271f4a2fd3a)
## タスク完了・未完了切り替え
3つ追加してみました。
タスクは解決策を達成するための行動になります。
今回の場合`22時に寝る`ために`お風呂`、`歯磨き`、`布団に入る`というタスクを指定された時間内にしなければ、ならないということです。
またチェックをつけることで、タスクの完了を意味します。
[![Image from Gyazo](https://i.gyazo.com/e2e30d5005b1a3ff7703e9094c15b6fb.gif)](https://gyazo.com/e2e30d5005b1a3ff7703e9094c15b6fb)
## 目標完了
このように`目標`の計画を立てていきます。
`目標`が達成したいこと、`課題`が`目標`を達成する上での`障壁`になるもの、または`現状の問題点`、`タスク`が`解決策を達成`するための`行動`です。
最後に`目標`が達成されたら、`目標一覧ページ`から`達成`ボタンを押すことで、`目標達成`です。
もし`期限内`に`達成`できなかったら、見落としている`課題`があるか、`タスク`の`見直し`をしてみてください。
[![Image from Gyazo](https://i.gyazo.com/bde17dd0abbbd2e6891f36abd2650723.gif)](https://gyazo.com/bde17dd0abbbd2e6891f36abd2650723)


# こだわった点
## UIデザイン
一昔前のレトロPCのようなUIを意識しました。
目標を計画することは大変骨の折れる作業です。
計画している最中に飽きてしまわないよう、デザインで楽しめるようなUIにしました。
## ターミナルを作った
[![Image from Gyazo](https://i.gyazo.com/ddf52e6221d12866aa0ccfd57cff2a23.gif)](https://gyazo.com/ddf52e6221d12866aa0ccfd57cff2a23)
`help(使えるコマンド表示)`、`ls(ファイル表示)`、`open(画面遷移)`、`clear(画面表示削除)`使えるコマンドは少ないですが、ターミナルのような動作をするUIで遊べます。(息抜きにどうぞ)
## エラー画面
目標や、タスクには期限を設定できますが、もし設定した期限をすぎると画面遷移するたびにエラー画面が出現します。
[![Image from Gyazo](https://i.gyazo.com/a2d259433043eec12cdcb6b0dd3ca9fc.png)](https://gyazo.com/a2d259433043eec12cdcb6b0dd3ca9fc)
このサービスは前置きの通り、ユーザーが決めた計画はプログラムと仮定してます。
そのため、期限を過ぎたらエラー画面のような通知で表示させています。
エラーだ！速く直さなくちゃと感じてくれたら幸いです。
## 使用技術
- Rails
- bootstrap
  - モーダル系はすべてbootstrapを使用しています。  
- ターミナルは`coffeescript(js)`で実装しています。  
  - 300行以上あるため、全ては載せませんが、行っていることは押されたキーを取得し、押されたキーによって条件分岐をして処理を分けています。
さらに押されたキーが`enter`キーだった場合は更に処理を追加しています。<br>
基本的には押されたキーの条件分岐、`enter`時は入力されたキーの羅列によって条件分岐しています。

```coffeescript
# 入力keyによって動作を制御
key_control = (i_key, target) ->
  # バグ対応 何故か読み込み時にi_keyがundefindとして発火してしまうため
  if i_key.keyCode == undefined
    false
  # enter key押したとき
  else if i_key.keyCode == 13
    enter(target)
    false
  # backspace押した時
  else if i_key.keyCode == 8
    # 入力文字削除
    word_delete()
  # space key押した時
  else if i_key.keyCode == 32
    # 空白文字追加処理
    word_add_blank target
  # 動作に関係ないkey押した時
  else if not_used_key i_key
    # 表示したくない無いkey排除
    false
  else
    true
```

`enter`時の処理

```coffeescript
# enter時はコマンド実行 別の処理
enter = (target) ->
  # 入力されたコマンド
  cmd = word.join ''
  # コマンド空白 or 未入力時
  if space.test(cmd) || cmd.length == 0
    # 改行して新たなプロンプト出現
    # id削除
    prompt_delete()
    # prompt追加
    prompt_add()
    word = []
  else if ((cmd.match open) || (cmd.match open_name) || (cmd.match open_not_name))
    open_control(cmd)
  else if cmd == 'clear'
    prompt = document.getElementById 'prompt'
    while prompt.lastChild
      prompt.removeChild prompt.lastChild
    add_element()
    word = []
  # 存在しないコマンド
  else if cmd == 'ls'
    ls()
    enter_flug = 1
    prompt_delete()
    prompt_add()
    word = []
  else if cmd == 'help'
    help()
    enter_flug = 1
    prompt_delete()
    prompt_add()
    word = []
  else
    enter_flug = 1
    target.innerHTML = word.join ''
    error_msg()
    prompt_delete()
    prompt_add()
    word = []
```
# 今後の展望
- チュートリアルモード作成
- ターミナルコマンド追加(tab、など...)
- ターミナルエリアクリック時のみコマンド受付(現状キーボードを押すと入力を受け付けている)

# 最後に
ここまで読んでくれてありがとうございました。
使い方がわからないという意見を頂いているので、チュートリアルを作成しより使いやすく改良していきます。
ぜひこのサービスを使い倒し目標達成の助けになればと思います。