` 要素は空で、コンテンツを追加するまで何も表示されません。また、JavaScript で簡単に取得できるように `id` を与えています。
+
+ファイル `app.js` に戻り、新しいヘルパー関数 `updateElement` を作成します。
+
+```js
+function updateElement(id, text) {
+ const element = document.getElementById(id);
+ element.textContent = text;
+}
+```
+
+これは非常に簡単で、要素 *id* と *text* が与えられると、一致する `id` で DOM 要素のテキスト内容を更新します。このメソッドを `login` 関数の先ほどのエラーメッセージの代わりに使ってみましょう。
+
+```js
+if (data.error) {
+ return updateElement('loginError', data.error);
+}
+```
+
+無効なアカウントでログインしようとすると、このように表示されるはずです。
+
+![ログイン中に表示されるエラーメッセージを示すスクリーンショット](../images/login-error.png)
+
+これで、視覚的にはエラーテキストが表示されるようになりましたが、スクリーンリーダーで試してみると、何もアナウンスされないことに気づくでしょう。ページに動的に追加されたテキストをスクリーンリーダーでアナウンスするには、[ライブリージョン](https://developer.mozilla.org/ja/docs/Web/Accessibility/ARIA/ARIA_Live_Regions) と呼ばれるものを使用する必要があります。ここでは、アラートと呼ばれる特定のタイプのライブリージョンを使用するつもりです。
+
+```html
+
+```
+
+`register` 関数のエラーに対しても同様の動作を実装する (HTML の更新を忘れずに)。
+
+## ダッシュボードに情報を表示する
+
+先ほど見たのと同じテクニックを使って、ダッシュボード・ページにアカウント情報を表示してみましょう。
+
+サーバから受け取ったアカウントオブジェクトはこんな感じです。
+
+```json
+{
+ "user": "test",
+ "currency": "$",
+ "description": "Test account",
+ "balance": 75,
+ "transactions": [
+ { "id": "1", "date": "2020-10-01", "object": "Pocket money", "amount": 50 },
+ { "id": "2", "date": "2020-10-03", "object": "Book", "amount": -10 },
+ { "id": "3", "date": "2020-10-04", "object": "Sandwich", "amount": -5 }
+ ],
+}
+```
+
+> 注: 生活を楽にするためには、すでにデータが登録されている `test` アカウントを使用することができます。
+
+### タスク
+
+まずは HTML の「バランス」の部分を置き換えてプレースホルダ要素を追加してみましょう。
+
+```html
+
+```
+
+また、アカウントの説明を表示するためのセクションをすぐ下に追加します。
+
+```html
+
+```
+
+✅ アカウントの説明は、その下にあるコンテンツのタイトルとして機能するため、意味的には見出しとしてマークアップされます。アクセシビリティにとって[見出し構造](https://www.nomensa.com/blog/2017/how-structure-headings-web-accessibility)がどのように重要であるかについて詳しく知り、他に何が見出しになり得るかを判断するためにページを批判的に見てみましょう。
+
+次に、プレースホルダを埋めるための新しい関数を `app.js` に作成します。
+
+```js
+function updateDashboard() {
+ if (!account) {
+ return navigate('/login');
+ }
+
+ updateElement('description', account.description);
+ updateElement('balance', account.balance.toFixed(2));
+ updateElement('currency', account.currency);
+}
+```
+
+まず、先に進む前に必要なアカウントデータがあることを確認します。次に、先ほど作成した `updateElement()` 関数を使って HTML を更新します。
+
+> 残高表示をよりきれいにするために、メソッド [`toFixed(2)`](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed) を使用して、小数点以下2桁の値を強制的に表示します。
+
+これで、ダッシュボードがロードされるたびに `updateDashboard()` 関数を呼び出す必要があります。既に [レッスン1の課題] (../../1-template-route/translations/README.ja.md) を終了している場合は簡単ですが、そうでない場合は以下の実装を使用することができます。
+
+このコードを `updateRoute()` 関数の最後に追加します。
+
+```js
+if (typeof route.init === 'function') {
+ route.init();
+}
+```
+
+ルート定義を更新します。
+
+```js
+const routes = {
+ '/login': { templateId: 'login' },
+ '/dashboard': { templateId: 'dashboard', init: updateDashboard }
+};
+```
+
+この変更により、ダッシュボードページが表示されるたびに関数 `updateDashboard()` が呼び出されるようになりました。ログインすると、アカウントの残高、通貨、説明が表示されるようになります。
+
+## HTML テンプレートを使用してテーブルの行を動的に作成
+
+[最初のレッスン](../../1-template-route/translations/README.ja.md)では、アプリのナビゲーションを実装するために HTML テンプレートを [`appendChild()`](https://developer.mozilla.org/ja/docs/Web/API/Node/appendChild) メソッドと一緒に使用しました。テンプレートは小さくして、ページの繰り返し部分を動的に埋め込むために使用することもできます。
+
+同様のアプローチを使用して、HTML テーブルにトランザクションのリストを表示します。
+
+### タスク
+
+HTML `` に新しいテンプレートを追加します。
+
+```html
+
+
+ |
+ |
+ |
+
+
+```
+
+このテンプレートは1つのテーブル行を表し、3つのカラムを入力します。*日付*、*オブジェクト*、トランザクションの*金額*です。
+
+次に、この `id` プロパティをダッシュボードテンプレート内のテーブルの `
` 要素に追加すると、JavaScript を使って見つけやすくなります。
+
+```html
+
+```
+
+HTML の準備ができたので、JavaScript のコードに切り替えて新しい関数 `createTransactionRow` を作成しましょう。
+
+```js
+function createTransactionRow(transaction) {
+ const template = document.getElementById('transaction');
+ const transactionRow = template.content.cloneNode(true);
+ const tr = transactionRow.querySelector('tr');
+ tr.children[0].textContent = transaction.date;
+ tr.children[1].textContent = transaction.object;
+ tr.children[2].textContent = transaction.amount.toFixed(2);
+ return transactionRow;
+}
+```
+
+この関数はその名前が示す通りのことを行います。先ほど作成したテンプレートを使って新しいテーブルの行を作成し、トランザクションデータを使ってその内容を埋めます。先ほど作成したテンプレートを使って新しいテーブル行を作成し、トランザクションデータを使って内容を埋めます。
+
+```js
+const transactionsRows = document.createDocumentFragment();
+for (const transaction of account.transactions) {
+ const transactionRow = createTransactionRow(transaction);
+ transactionsRows.appendChild(transactionRow);
+}
+updateElement('transactions', transactionsRows);
+```
+
+ここでは [`document.createDocumentFragment()`](https://developer.mozilla.org/ja/docs/Web/API/Document/createDocumentFragment) というメソッドを使用しています。これは新しい DOM フラグメントを作成し、その上で作業を行い、最終的にそれを HTML テーブルにアタッチする前のものです。
+
+このコードが動作する前に、もう一つやらなければならないことがあります。というのは、現在のところ `updateElement()` 関数はテキストコンテンツのみをサポートしているからです。コードを少し変更してみましょう。
+
+```js
+function updateElement(id, textOrNode) {
+ const element = document.getElementById(id);
+ element.textContent = ''; // Removes all children
+ element.append(textOrNode);
+}
+```
+
+私たちは [`append()`](https://developer.mozilla.org/en-US/docs/Web/API/ParentNode/append) メソッドを使用しています。これにより、テキストや [DOM Nodes](https://developer.mozilla.org/ja/docs/Web/API/Node) を親要素にアタッチすることができ、すべてのユースケースに最適です。
+
+`test` アカウントを使ってログインしてみると、ダッシュボード上にトランザクションリストが表示されるはずです 🎉。
+
+---
+
+## 🚀 チャレンジ
+
+ダッシュボードページを実際の銀行アプリのように見せるために一緒に作業しましょう。すでにアプリのスタイルを設定している場合は、[メディアクエリ](https://developer.mozilla.org/ja/docs/Web/CSS/Media_queries)を使用して、デスクトップとモバイルデバイスの両方でうまく機能する[レスポンシブデザイン](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps/Responsive/responsive_design_building_blocks)を作成してみてください。
+
+ダッシュボードページのスタイリング例です。
+
+![スタイリング後のダッシュボードの結果例のスクリーンショット](../images/screen2.png)
+
+## レッスン後の小テスト
+
+[レッスン後の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/46)
+
+## 課題
+
+[コードのリファクタとコメント](assignment.ja.md)
diff --git a/7-bank-project/3-data/translations/assignment.ja.md b/7-bank-project/3-data/translations/assignment.ja.md
new file mode 100644
index 00000000..478cf5c8
--- /dev/null
+++ b/7-bank-project/3-data/translations/assignment.ja.md
@@ -0,0 +1,15 @@
+# コードのリファクタとコメント
+
+## 説明書
+
+コードベースが大きくなってくると、読みやすく保守性の高いコードを維持するために、頻繁にリファクタリングを行うことが重要になってきます。コメントを追加して `app.js` をリファクタリングし、コードの品質を向上させましょう。
+
+- サーバー API のベース URL のような定数を抽出します
+- 類似したコードの因数分解: 例えば、`sendRequest()` 関数を作成して `createAccount()` と `getAccount()` の両方で使用するコードを再グループ化することができます
+- 読みやすいようにコードを再編成し、コメントを追加します
+
+## ルーブリック
+
+| 基準 | 模範的な例 | 適切な | 改善が必要 |
+| -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------- |
+| | コードはコメントされており、さまざまなセクションでよく整理されており、読みやすくなっています。定数が抽出され、因数分解された `sendRequest()` 関数が作成されています。 | コードはクリーンですが、より多くのコメント、定数抽出、因数分解などで改善することができます。 | コードは乱雑で、コメントされておらず、定数は抽出されておらず、コードは因数分解されていません。 |
diff --git a/7-bank-project/4-state-management/translations/README.ja.md b/7-bank-project/4-state-management/translations/README.ja.md
new file mode 100644
index 00000000..7e1a8548
--- /dev/null
+++ b/7-bank-project/4-state-management/translations/README.ja.md
@@ -0,0 +1,281 @@
+# バンキングアプリを作ろう その 4: 状態管理の概念
+
+## レッスン前の小テスト
+
+[レッスン前の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/47)
+
+### イントロダクション
+
+Web アプリケーションが成長するにつれて、すべてのデータの流れを追跡することが難しくなります。どのコードがデータを取得し、どのページがデータを消費し、どこでいつ更新する必要があるのか...メンテナンスが難しい厄介なコードになってしまいがちです。これは、ユーザーデータなど、アプリの異なるページ間でデータを共有する必要がある場合に特に当てはまります。*状態管理*の概念は、あらゆる種類のプログラムに常に存在していますが、Web アプリの複雑さが増すにつれ、開発中に考えるべき重要なポイントになってきています。
+
+この最後のパートでは、状態の管理方法を再考するために構築したアプリを見ていきます。任意の時点でのブラウザの更新をサポートし、ユーザーセッション間でのデータの永続化を可能にします。
+
+### 前提条件
+
+このレッスンでは、Web アプリの[データ取得](./././3-data/translations/README.ja.md)の部分が完了している必要があります。また、アカウントデータを管理するためには、ローカルに [Node.js](https://nodejs.org/ja) をインストールし、[サーバー API を実行する](.../../api/translations/README.ja.md)をインストールする必要があります。
+
+ターミナルでこのコマンドを実行することで、サーバーが正常に動作しているかどうかをテストすることができます。
+
+```sh
+curl http://localhost:5000/api
+# -> 結果として "Bank API v1.0.0" を返す必要があります。
+```
+
+---
+
+## 状態管理を再考する
+
+[前回のレッスン](../../3-data/translations/README.ja.md)では、現在ログインしているユーザーの銀行データを含むグローバル変数 `account` を使って、アプリの基本的な状態の概念を紹介しました。しかし、現在の実装にはいくつかの欠陥があります。ダッシュボード上でページをリフレッシュしてみてください。何が起こるのでしょうか?
+
+現在のコードには3つの問題があります。
+
+- ブラウザをリフレッシュするとログインページに戻るため、状態は保持されません
+- 状態を変更する関数が複数あります。アプリが大きくなると、変更を追跡するのが難しくなり、1つの更新を忘れがちになります
+- 状態が片付かず、*Logout* をクリックしてもログインページになってもアカウントデータが残っています
+
+これらの問題に一つずつ対処するためにコードを更新することもできますが、コードの重複が多くなり、アプリがより複雑になり、メンテナンスが難しくなります。あるいは、数分間小休止して、戦略を再考することもできます。
+
+> ここで本当に解決しようとしている問題は何か?
+
+[状態管理](https://en.wikipedia.org/wiki/State_management)は、この2つの特定の問題を解決するための良いアプローチを見つけることがすべてです。
+
+- アプリ内のデータフローをわかりやすく保つには?
+- アプリ内のデータフローを理解しやすい状態に保つには?
+
+これらの問題を解決したら、他の問題はすでに解決されているか、簡単に解決できるようになっているかもしれません。これらの問題を解決するための多くの可能なアプローチがありますが、ここでは、**データとそれを変更する方法**を集中化することで構成される一般的な解決策を採用します。データの流れは次のようになります。
+
+![HTML、ユーザーアクション、状態間のデータフローを示すスキーマ](../images/data-flow.png)
+
+> ここでは、データが自動的にビューの更新のトリガーとなる部分は、[Reactive Programming](https://en.wikipedia.org/wiki/Reactive_programming)のより高度な概念に関連しているので、ここでは取り上げません。深く掘り下げたい方には良いフォローアップテーマになるでしょう。
+
+✅ 状態管理へのさまざまなアプローチを持つライブラリはたくさんありますが、[Redux](https://redux.js.org) は人気のあるオプションです。大規模な Web アプリケーションで直面する可能性のある問題や、それをどのように解決できるかを学ぶための良い方法として、使用されている概念やパターンを見てみましょう。
+
+### タスク
+
+まずは少しリファクタリングをしてみましょう。`account` 宣言を置換します。
+
+```js
+let account = null;
+```
+
+このようにします。
+
+```js
+let state = {
+ account: null
+};
+```
+
+このアイデアは、単一のステートオブジェクトにすべてのアプリデータを*中央集権化することです。今のところは `account` があるだけなので、あまり変化はありませんが、進化のためのパスを作成します。
+
+また、これを使って関数を更新しなければなりません。関数 `register()` と `login()` において、`account = ...` を `state.account = ...` に置き換えてください。
+
+関数 `updateDashboard()` の先頭に以下の行を追加します。
+
+```js
+const account = state.account;
+```
+
+今回のリファクタリングだけではあまり改善は見られませんでしたが、次の変更のための基礎を固めようと考えたのです。
+
+## データ変更の追跡
+
+データを保存するために `state` オブジェクトを配置したので、次のステップは更新を一元化することです。目的は、いつ変更があったのか、いつ変更が発生したのかを簡単に把握できるようにすることです。
+
+`state` オブジェクトに変更が加えられないようにするためには、`state` オブジェクトを [*immutable*](https://en.wikipedia.org/wiki/Immutable_object) と考えるのも良い方法です。これはまた、何かを変更したい場合には新しいステートオブジェクトを作成しなければならないことを意味します。このようにすることで、潜在的に望ましくない[副作用](https://en.wikipedia.org/wiki/Side_effect_(computer_science)についての保護を構築し、アンドゥ/リドゥの実装のようなアプリの新機能の可能性を開くと同時に、デバッグを容易にします。例えば、ステートに加えられたすべての変更をログに記録し、バグの原因を理解するために変更の履歴を保持することができます。
+
+JavaScript では、[`Object.freeze()`](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze) を使って、オブジェクトの不変バージョンを作成することができます。不変オブジェクトに変更を加えようとすると例外が発生します。
+
+✅ *浅い*不変オブジェクトと*深い*不変オブジェクトの違いを知っていますか? それについては [こちら](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Object/freeze#What_is_shallow_freeze) を参照してください。
+
+### タスク
+
+新しい `updateState()` 関数を作成してみましょう。
+
+```js
+function updateState(property, newData) {
+ state = Object.freeze({
+ ...state,
+ [property]: newData
+ });
+}
+```
+
+この関数では、新しいステートオブジェクトを作成し、[*spread (`...`) operator*](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Operators/Spread_syntax#spread_in_object_literals) を使用して前のステートからデータをコピーしています。次に、[ブラケット表記](https://developer.mozilla.org/ja/docs/Web/JavaScript/Guide/Working_with_Objects#objects_and_properties) `[property]` を使用して、ステートオブジェクトの特定のプロパティを新しいデータでオーバーライドします。最後に、`Object.freeze()`を使ってオブジェクトをロックし、変更を防ぎます。今のところ、`account` プロパティだけがステートに保存されていますが、この方法では必要なだけのプロパティをステートに追加することができます。
+
+また、`state` の初期化を更新して初期状態も凍結されるようにします。
+
+```js
+let state = Object.freeze({
+ account: null
+});
+```
+
+その後、`state.account = result;` の代入を `state.account = result;` に置き換えて `register` 関数を更新します。
+
+```js
+updateState('account', result);
+```
+
+同じことを `login` 関数で行い、`state.account = data;` に置き換えます。
+
+```js
+updateState('account', data);
+```
+
+ここで、ユーザーが *Logout* をクリックしたときにアカウントデータがクリアされない問題を修正します。
+
+新しい関数 `logout()` を作成します。
+
+```js
+function logout() {
+ updateState('account', null);
+ navigate('/login');
+}
+```
+
+`updateDashboard()` で、リダイレクト `return navigate('/login');` を `return logout()` に置き換えてください。
+
+新しいアカウントを登録して、ログアウトとログインを繰り返してみて、すべてが正常に動作することを確認してください。
+
+> ヒント: `updateState()` の下部に `console.log(state)` を追加し、ブラウザの開発ツールでコンソールを開くことで、すべての状態の変化を見ることができます。
+
+## 状態を維持する
+
+ほとんどの Web アプリは、データを保持しておかないと正常に動作しません。すべての重要なデータは通常、データベースに保存され、サーバー API を介してアクセスされます。しかし、時には、より良いユーザーエクスペリエンスや読み込みパフォーマンスを向上させるために、ブラウザ上で実行されているクライアントアプリのデータを永続化することも興味深いことです。
+
+ブラウザにデータを永続化する場合、いくつかの重要な質問があります。
+
+- *データは機密性の高いものでしょうか?* ユーザーパスワードなどの機密性の高いデータをクライアントに保存することは避けるべきです
+- *このデータをどのくらいの期間保存する必要がありますか?* このデータにアクセスするのは現在のセッションのためだけですか、それとも永遠に保存したいですか?
+
+Web アプリ内の情報を保存する方法は、目的に応じて複数あります。例えば、URL を使用して検索クエリを保存し、ユーザー間で共有できるようにすることができます。また、[認証](https://en.wikipedia.org/wiki/Authentication)情報のように、データをサーバーと共有する必要がある場合は、[HTTP クッキー](https://developer.mozilla.org/ja/docs/Web/HTTP/Cookies)を使用することもできます。
+
+もう一つの選択肢は、データを保存するための多くのブラウザ API のうちの一つを使用することです。その中でも特に興味深いものが2つあります。
+
+- [`localStorage`](https://developer.mozilla.org/ja/docs/Web/API/Window/localStorage): [Key/Value ストア](https://en.wikipedia.org/wiki/Key%E2%80%93value_database)は、異なるセッションにまたがって現在の Web サイトに固有のデータを永続化することができます。保存されたデータは期限切れになることはありません
+- [`sessionStorage`](https://developer.mozilla.org/ja/docs/Web/API/Window/sessionStorage): これは `localStorage` と同じように動作しますが、保存されたデータはセッションの終了時(ブラウザが閉じられた時)に消去されます
+
+これらの API はどちらも[文字列](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/String)しか保存できないことに注意してください。複雑なオブジェクトを格納したい場合は、[`JSON.stringify()`](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/JSON/stringify) を使って [JSON](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/JSON) 形式にシリアライズする必要があります。
+
+✅ サーバーで動作しない Web アプリを作成したい場合は、[`IndexedDB` API](https://developer.mozilla.org/ja/docs/Web/API/IndexedDB_API) を使用してクライアント上にデータベースを作成することも可能です。これは高度なユースケースや、かなりの量のデータを保存する必要がある場合には、使用するのがより複雑になるため、予約されています。
+
+### タスク
+
+ユーザーが明示的に *Logout* ボタンをクリックするまでログインしたままにしたいので、`localStorage` を使ってアカウントデータを保存します。まず、データを保存するためのキーを定義しましょう。
+
+```js
+const storageKey = 'savedAccount';
+```
+
+そして、この行を `updateState()` 関数の最後に追加します。
+
+```js
+localStorage.setItem(storageKey, JSON.stringify(state.account));
+```
+
+これで、以前はすべての状態の更新を一元化していたので、ユーザーアカウントのデータは永続化され、常に最新の状態になります。ここからが、以前のすべてのリファクタリングの恩恵を受け始めるところです 🙂。
+
+データが保存されているので、アプリが読み込まれたときに復元することにも気を配らなければなりません。初期化コードが増えてくるので、`app.js` の下部に以前のコードも含めた `init` 関数を新たに作成しておくといいかもしれません。
+
+```js
+function init() {
+ const savedAccount = localStorage.getItem(storageKey);
+ if (savedAccount) {
+ updateState('account', JSON.parse(savedAccount));
+ }
+
+ // 前回の初期化コード
+ window.onpopstate = () => updateRoute();
+ updateRoute();
+}
+
+init();
+```
+
+ここでは保存されたデータを取得し、もしあればそれに応じて状態を更新します。ページの更新中に状態に依存するコードがあるかもしれないので、ルートを更新する前にこれを行うことが重要です。
+
+アカウントデータを保持しているので、*ダッシュボード* ページをアプリケーションのデフォルトページにすることもできます。データが見つからない場合は、ダッシュボードが *ログイン* ページにリダイレクトします。`updateRoute()` で、フォールバックの `return navigate('/login');` を `return navigate('dashboard');` に置き換えます。
+
+アプリでログインしてページを更新してみてください。このアップデートで初期の問題はすべて解決しました。
+
+## データの更新
+
+...しかし、我々はまた、新しいものを作ったかもしれません。おっと!
+
+`test` アカウントを使ってダッシュボードに行き、ターミナルで以下のコマンドを実行して新しいトランザクションを作成します。
+
+```sh
+curl --request POST \
+ --header "Content-Type: application/json" \
+ --data "{ \"date\": \"2020-07-24\", \"object\": \"Bought book\", \"amount\": -20 }" \
+ http://localhost:5000/api/accounts/test/transactions
+```
+
+ダッシュボードのページをブラウザで更新してみてください。どうなりますか?新しいトランザクションが表示されましたか?
+
+この状態は `localStorage` のおかげで無期限に保持されますが、アプリからログアウトして再度ログインするまで更新されません。
+
+これを修正するために考えられる戦略の1つは、ダッシュボードがロードされるたびにアカウントデータをリロードして、データのストールを回避することです。
+
+### タスク
+
+新しい関数 `updateAccountData` を作成します。
+
+```js
+async function updateAccountData() {
+ const account = state.account;
+ if (!account) {
+ return logout();
+ }
+
+ const data = await getAccount(account.user);
+ if (data.error) {
+ return logout();
+ }
+
+ updateState('account', data);
+}
+```
+
+このメソッドは現在ログインしているかどうかをチェックし、サーバからアカウントデータをリロードします。
+
+`refresh` という名前の別の関数を作成します。
+
+```js
+async function refresh() {
+ await updateAccountData();
+ updateDashboard();
+}
+```
+
+これはアカウントデータを更新し、ダッシュボードページの HTML を更新する処理を行います。ダッシュボードルートがロードされたときに呼び出す必要があるものです。これでルート定義を更新します。
+
+```js
+const routes = {
+ '/login': { templateId: 'login' },
+ '/dashboard': { templateId: 'dashboard', init: refresh }
+};
+```
+
+ダッシュボードをリロードしてみると、更新されたアカウントデータが表示されるはずです。
+
+---
+
+## 🚀 チャレンジ
+
+ダッシュボードがロードされるたびにアカウントデータをリロードするようになりましたが、すべてのアカウントデータを保持する必要があると思いますか?
+
+アプリが動作するために絶対に必要なものだけを含むように、`localStorage` から保存およびロードされるものを変更するために、一緒に作業してみてください。
+
+## レッスン後の小テスト
+
+[レッスン後の小テスト](https://nice-beach-0fe9e9d0f.azurestaticapps.net/quiz/48)
+
+## 課題
+
+[「トランザクションの追加」ダイアログの実装](assignment.ja.md)
+
+課題を終えた後の結果の一例です。
+
+![「トランザクションの追加」ダイアログの例を示すスクリーンショット](../images/dialog.png)
diff --git a/7-bank-project/4-state-management/translations/assignment.ja.md b/7-bank-project/4-state-management/translations/assignment.ja.md
new file mode 100644
index 00000000..f1b25f22
--- /dev/null
+++ b/7-bank-project/4-state-management/translations/assignment.ja.md
@@ -0,0 +1,25 @@
+# 「トランザクションの追加」ダイアログの実装
+
+## 説明書
+
+私たちの銀行アプリには、1つの重要な機能がまだありません。
+前の4つのレッスンで学んだことをすべて使って、「トランザクションの追加」ダイアログを実装します。
+
+- ダッシュボードページに「トランザクションの追加」ボタンを追加します
+- HTML テンプレートで新しいページを作成するか、JavaScript を使用してダッシュボード・ページを離れることなくダイアログの HTML を表示/非表示にするかのいずれかを選択します (そのためには [`hidden`](https://developer.mozilla.org/ja/docs/Web/HTML/Global_attributes/hidden) プロパティを使用するか、CSS クラスを使用することができます)
+- ダイアログの [キーボードとスクリーンリーダーのアクセシビリティ] (https://developer.paciellogroup.com/blog/2018/06/the-current-state-of-modal-dialog-accessibility/) が処理されていることを確認します
+- 入力データを受け取るための HTML フォームを実装する
+- フォームデータから JSON データを作成して API に送る
+- ダッシュボードページを新しいデータで更新する
+
+[サーバー API の仕様](./.../.../api/translations/README.ja.md)を見て、どの API を呼び出す必要があるか、期待される JSON 形式は何かを確認してください。
+
+以下は、課題を完了した後の結果の例です。
+
+![「トランジションの追加」ダイアログの例を示すスクリーンショット](../../images/dialog.png)
+
+## ルーブリック
+
+| 基準 | 模範的な例 | 適切な | 改善が必要 |
+| -------- | ------------------------------------------------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------- | --------------------------------------------|
+| | トランザクションの追加は、レッスンで見たすべてのベストプラクティスに従って完全に実装されています。 | トランザクションを追加することは実装されていますが、レッスンで見たベストプラクティスに従っていなかったり、部分的にしか動作しなかったりします。 | トランザクションを追加しても全く機能しません。 |
diff --git a/7-bank-project/api/translations/README.ja.md b/7-bank-project/api/translations/README.ja.md
new file mode 100644
index 00000000..37c080a9
--- /dev/null
+++ b/7-bank-project/api/translations/README.ja.md
@@ -0,0 +1,33 @@
+# 銀行 API
+
+> 銀行 API は [Node.js](https://nodejs.org/ja/) + [Express](https://expressjs.com/ja/) で構築されています。
+
+API はすでにあなたのために構築されており、演習の一部ではありません。
+
+しかし、このような API の構築方法に興味があるのであれば、このシリーズのビデオを見ることができます: https://aka.ms/NodeBeginner (ビデオ 17 から 21 では、この API を正確にカバーしています)。
+
+また、こちらのインタラクティブなチュートリアルもご覧ください: https://aka.ms/learn/express-api
+
+## サーバーの実行
+
+[Node.js](https://nodejs.org/ja/) がインストールされていることを確認してください。
+
+1. このリポジトリを Git でクローンします
+2. `api` フォルダでターミナルを開き、`npm install` を実行します
+3. `npm start` を実行します
+
+サーバーは `5000` ポートで待ち受けを開始するはずです。
+
+> 注意: すべてのエントリはメモリに保存され、永続化されないので、サーバを停止するとすべてのデータが失われます。
+
+## API の詳細
+
+ルート | 説明
+---------------------------------------------|------------------------------------
+GET /api/ | サーバー情報を取得します
+POST /api/accounts/ | アカウントを作成します。例: `{ user: 'Yohan', description: 'My budget', currency: 'EUR', balance: 100 }`
+GET /api/accounts/:user | 指定したアカウントのすべてのデータを取得します
+DELETE /api/accounts/:user | 指定したアカウントを削除します
+POST /api/accounts/:user/transactions | トランザクションを追加します。例: `{ date: '2020-07-23T18:25:43.511Z', object: 'Bought a book', amount: -20 }`
+DELETE /api/accounts/:user/transactions/:id | 指定されたトランザクションを削除します
+
diff --git a/7-bank-project/solution/translations/README.ja.md b/7-bank-project/solution/translations/README.ja.md
new file mode 100644
index 00000000..87970d20
--- /dev/null
+++ b/7-bank-project/solution/translations/README.ja.md
@@ -0,0 +1,13 @@
+# 銀行アプリ
+
+> バニラ HTML5、CSS、JavaScript で構築された銀行アプリプロジェクトのソリューション例 (フレームワークやライブラリは使用していません)。
+
+## アプリの実行
+
+まず、[API サーバー](../../api/translations/README.ja.md)が起動していることを確認します。
+
+アプリの実行にはどの Web サーバーを使用しても構いませんが、API を実行するためには [Node.js](https://nodejs.org/ja) がインストールされている必要があるので、以下のようにします。
+
+1. このレポを Git でクローンします
+2. ターミナルを開き、`npx lite-server solution` を実行します。これで、`3000` ポートで開発用ウェブサーバが起動します
+3. ブラウザで `http://localhost:3000` を開いてアプリを実行します
diff --git a/7-bank-project/translations/README.ja.md b/7-bank-project/translations/README.ja.md
new file mode 100644
index 00000000..2df873f7
--- /dev/null
+++ b/7-bank-project/translations/README.ja.md
@@ -0,0 +1,21 @@
+# :dollar: 銀行を作る
+
+このプロジェクトでは、架空の銀行を構築する方法を学びます。これらのレッスンでは、Web アプリのレイアウト方法やルートの提供、フォームの構築、状態の管理、銀行のデータを API からフェッチする方法などを説明します。
+
+| ![Screen1](../images/screen1.png) | ![Screen2](../images/screen2.png) |
+|--------------------------------|--------------------------------|
+
+## レッスン
+
+1. [Web アプリの HTML テンプレートとルート](../1-template-route/translations/README.ja.md)
+2. [ログインと登録フォームの構築](../2-forms/translations/README.ja.md)
+3. [データの取得と利用方法](../3-data/translations/README.ja.md)
+4. [状態管理の概念](../4-state-management/translations/README.ja.md)
+
+### クレジット
+
+These lessons were written with :hearts: by [Yohan Lasorsa](https://twitter.com/sinedied).
+
+これらのレッスンで使用した [server API](../api/translations/README.ja) の構築方法を学びたい方は、[このシリーズの動画](https://aka.ms/NodeBeginner) をご覧ください (特に動画17~21)。
+
+また、[このインタラクティブな学習チュートリアル](https://aka.ms/learn/express-api) もご覧ください。
\ No newline at end of file