見出し画像

筋トレを手軽に記録・分析するWEBアプリの作り方

使ってみたいというお声をいただけたんです!(嬉

筋トレ記録を3,4タップで自分のGoogleスプレッドシートに記録するウェブアプリを作りました。


先日、noteで作った経緯や試行錯誤の過程を紹介しています。

その翌日SUNABACO 八代のLT会で、アプリ画面を見せながら紹介してきました。(その様子はslackのみんなの砂場のリンクから視聴できます。よければぜひ!)

見てくれた方からありがたいことにアプリを使ってみたいという声をいただけました。

せっかくなのですんなり導入してもらえるように+回り道をしてできたアプリの制作過程を自分の中で整理するためにnoteで導入記事を書いてみました。

構成はGitHub PagesにアップしたWEBアプリから筋トレ記録を送信、指定したGoogleスプレッドシートに記録が溜まるというものです。
溜まったデータはグラフにしたりして活用、グラフはWEBアプリから閲覧できます。

記事のボリュームは長いですが、10〜20分程度で作っていただけますので、よければぜひ!

Googleスプレッドシートの準備

まず新規のGoogleスプレッドシートを用意します。

「拡張機能」→「Apps Script」をクリック

下のような別ウインドウが開きます。
function〜と書いてあるところを全選択して

下記のコードに上書きします。

function doPost(e) {
  var sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  
  var date = e.parameter.date;
  var weight = e.parameter.weight;
  var reps = e.parameter.reps;
  var type = e.parameter.type;
  
  Logger.log('Received data - Date: %s, Weight: %s, Reps: %s, Type: %s', date, weight, reps, type);
  
  sheet.appendRow([date, weight, reps, type]);
  
  var result = {
    "result": "success",
    "message": "データが正常に送信されました。"
  };
  
  return ContentService.createTextOutput(JSON.stringify(result)).setMimeType(ContentService.MimeType.JSON);
}

画面右上の「デプロイ」→「新しいデプロイ」をクリック

「歯車マーク」→「ウェブアプリ」をクリック

アクセスできるユーザーを「全員」に変更、デプロイをクリック

認証を求められます。
「アクセスを承認」をクリック

自分のGoogleアカウントをクリック

「Advanced」→「Go to 〜」をクリック

「Allow」をクリック

少し待つとデプロイが完了します。
ウェブアプリのURLを後から使用しますのでコピーしてどこかに一時貼り付けておくといいです。

ウェブページを作成

続いて、下記をコピーしてHTML,CSS,JavaScriptファイルをGitHubにアップロードしてください。

GitHub

新しいリポジトリを作成してください
GitHubのマイページ右上の「+」→「New repository」

好きなリポジトリ名を入力して「Create repository」をクリック

「creating a new file」をクリック

index.htmlと入力して、下には下記コードを貼り付ける。

「Add file」→「Create new file」でstyle.cssを作成。
これを繰り返してscript.jsとgraph.htmlも作成してください。


HTML(index.html)

※8行目、99行目、104行目のコメントのとおり修正してください。
回数や重さ、筋トレの種類など好きに書き換えてください。
※コード下部の<script>~</script>を削除、104行目105行目を追記

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>筋トレ管理アプリ</title>

<!--GitHub Pagesを使う場合、下記のように表記しないとCSSが効かない-->
<link rel="stylesheet" href="https://[githubユーザーネーム].github.io/[リポジトリ名]/style.css"/>

</head>
<body>

<div class="container">
  <h2>筋トレ管理アプリ</h2>
  <form id="workoutForm">
    <label for="date">日付:</label><br>
    <input type="date" id="date" name="date" required><br><br>

<script type="text/javascript">
  window.onload = function () {
    var date = new Date();
    date.setDate(date.getDate());
    var yyyy = date.getFullYear();
    var mm = ("0" + (date.getMonth() + 1)).slice(-2);
    var dd = ("0" + date.getDate()).slice(-2);
    document.getElementById("date").value = yyyy + '-' + mm + '-' + dd;
  }
</script>
    
    
    <label>重さ (kg):</label><br>
    <select id="weight" name="weight" required>
      <option value="" disabled selected>選択してください</option>
      <option value="0">0 kg</option>
      <option value="15">15 kg</option>
      <option value="20">20 kg</option>
      <option value="25">25 kg</option>
      <option value="30">30 kg</option>
      <option value="35">35 kg</option>
      <option value="40">40 kg</option>
      <option value="45">45 kg</option>
      <option value="50">50 kg</option>
      <option value="55">55 kg</option>
      <option value="60">60 kg</option>
      <option value="65">65 kg</option>
      <option value="70">70 kg</option>
      <option value="75">75 kg</option>
      <option value="80">80 kg</option>
      <option value="85">85 kg</option>
      <option value="90">90 kg</option>
      <option value="95">95 kg</option>
      <option value="100">100 kg</option>
    </select><br><br>
    
    <label for="reps">回数:</label><br>
    <select id="reps" name="reps" required>
      <option value="" disabled selected>選択してください</option>
      <option value="0">0 回</option>
      <option value="5">5 回</option>
      <option value="10">10 回</option>
      <option value="15">15 回</option>
      <option value="20">20 回</option>
      <option value="25">25 回</option>
      <option value="30">30 回</option>
      <option value="35">35 回</option>
      <option value="40">40 回</option>
      <option value="45">45 回</option>
      <option value="50">50 回</option>
    </select><br><br>
    
    <label>筋トレの種類:</label><br>
    <div class="radio-container">
      <label>
        <input type="radio" name="type" value="ショルダープレス" required> ショルダープレス
      </label>
      <label>
        <input type="radio" name="type" value="チェストプレス" required> チェストプレス
      </label>
      <label>
        <input type="radio" name="type" value="ラットプルダウン" required> ラットプルダウン
      </label>
      <label>
        <input type="radio" name="type" value="レッグプレス" required> レッグプレス
      </label>
      <label>
        <input type="radio" name="type" value="アブベンチ" required> アブベンチ
      </label>
      <label>
        <input type="radio" name="type" value="トレッドミル" required> トレッドミル
      </label>
    </div><br><br>
    
    <button type="submit">送信</button>
  </form>
  
  <div id="response"></div>

<!--グラフページのURLを指定します-->
  <a href="https://[githubユーザーネーム].github.io/[リポジトリ名]/graph.html" target="_blank"/>グラフはこちら
</a>

</div>
<!--script.jsを指定-->
<script src="https://[githubユーザーネーム].github.io/[リポジトリ名]/script.js"></script>
</body>
</html>

CSS(style.css)

※14行目を修正、27行目を削除

body {
  font-family: Arial, sans-serif;
  background-color: #f0f0f0;
  margin: 0;
  padding: 0;
  display: flex;
  justify-content: center;
  align-items: flex-start; /* 上端に揃える */
  height: 100vh;
}

.container {
  background-color: #fff;
  padding: 0px 20px 20px 20px;
  border-radius: 8px;
  box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
  max-width: 400px;
  width: 100%;
  text-align: center;
}

h2 {
  color: #333;
}

form {
  flex-direction: column;
  align-items: center;
}

label {
  font-weight: bold;
}

input[type="date"],
input[type="text"],
select {
  width: 100%;
  padding: 8px;
  margin: 6px 0;
  box-sizing: border-box;
  border: 1px solid #ccc;
  border-radius: 4px;
}

.radio-container {
  display: flex;
  flex-wrap: wrap;
  justify-content: space-between;
  text-align: left;
}

.radio-container label {
  width: 45%;
  margin: 5px 0;
}

button {
  background-color: #4CAF50;
  color: white;
  padding: 10px 20px;
  border: none;
  border-radius: 4px;
  cursor: pointer;
  font-size: 16px;
}

button:hover {
  background-color: #45a049;
}

#response {
  margin-top: 20px;
  color: #333;
}

.iframe-container {
  display: flex;
  justify-content: center;
  align-items: center;
  height: 100%;
  width: 100%;
}

iframe {
  border: none;
}

JavaScript(script.js)

※15行目のコメントのとおり修正してください。
※4行目5行目を追加(連続入力時にステータスメッセージを一旦クリア)

document.getElementById('workoutForm').addEventListener('submit', function(e) {
  e.preventDefault();

  // メッセージエリアをクリア
  document.getElementById('response').innerText = '';
  
  var date = document.getElementById('date').value;
  var weight = document.getElementById('weight').value;
  var reps = document.getElementById('reps').value;
  var type = document.querySelector('input[name="type"]:checked').value;
  
  var formData = new FormData();
  formData.append('date', date);
  formData.append('weight', weight);
  formData.append('reps', reps);
  formData.append('type', type);
  
<!--Google Apps ScriptのウェブアプリURLを指定します-->
  fetch('https://script.google.com/macros/s/*******/exec', {
    method: 'POST',
    body: formData
  })
  .then(response => response.json())
  .then(data => {
    if (data.result === "success") {
      document.getElementById('response').innerText = "データが正常に送信されました。";
    } else {
      document.getElementById('response').innerText = "エラーが発生しました: " + data.message;
    }
  })
  .catch(error => {
    document.getElementById('response').innerText = 'エラーが発生しました: ' + error.message;
  });
});

グラフページ(graph.html)

※グラフを作成したら12行目のとおりに記入してください。
グラフの作成と公開は下記を参照

<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>筋トレグラフ</title>
<link rel="stylesheet" href="styles.css">

</head>
<body>
<div class="iframe-container">
<!--ここにスプレッドシートで作ったグラフのiframeを埋め込む-->

</div>

</body>
</html>
     


GitHub Pagesへの公開

GitHubのリポジトリを開き、「Settings」→「Pages」→ブランチを「main」に変更→「Save」

デプロイが開始されるので、数分後にページ再読み込みをするとURLが表示されます。

グラフの作成から公開

スプレッドシートの「挿入」→「グラフ」
好きなグラフを作成します。

グラフの右上三点リーダーをクリック→「グラフを公開」をクリック


「埋め込む」→「公開」→「OK」

表示されたiframeタグをgraph.htmlの13行目に貼り付けてください。

以上、お疲れ様でした!

アプリは、項目を入力して送信を押した回数、スプレッドシートに記録されます。送信ごとに項目はクリアされないので複数セットをすぐ送信できます。
入力間違えた場合はスプレドシートからその行を削除するだけです。

項目を変えたり追加したり、グラフを増やしたりして改造してみてください。

お役に立てば幸いです!

いいなと思ったら応援しよう!

この記事が参加している募集