ダッシュボード（管理画面）テンプレートをAmplify+Reactでデプロイまでする。

# やりたこと
ネットで見つけたダッシュボードテンプレートをAmplifyにデプロイする。
基本はチュートリアルに沿っていけばできるので、ハマりポイントを記載。

# 環境
* Paper Dashboard PRO React1.2.0
ダッシュボードテンプレート。
自分は有料版を使っているけど、無料版も同じだと思う。
https://www.creative-tim.com/product/paper-dashboard-pro-react

* npm 6.14.8
* Amplify CLI 4.29.3
# 手順

## 基本
基本的には[マニュアル](https://docs.amplify.aws/start/q/integration/react)通り以下でいける。
`amplify`コマンドで対話入力があるが全部デフォルトのままで問題ない。（npm,amplifyインストールなどは省略）
`amplify publish`でURLが表示されるので、それでブラウザ表示できる。

これだけでデプロイまでできるの凄すぎる。（さらにここから認証とかAPIとか作れるのもっとすごい。）

```
cd paper-dashboard-pro-react-v1.2.0/
npm install
npm install aws-amplify @aws-amplify/ui-react
amplify init
amplify hosting add
amplify publish
```

## 上記で問題があった箇所3点
`create-react-app`で作ったまっさらなReactアプリであれば上記で問題ないのだが、今回はテンプレートを利用しているためいくつかの箇所で問題が発生した。

### デプロイ後、真っ白画面になってしまう
ルートの認識がズレている様子。
`package.json`の下記部分を削除して解決した。

```package.json
  "homepage": "https://demos.creative-tim.com/paper-dashboard-pro-react/#/",
```
ちなみに最初に[コチラ](https://www.yoheim.net/blog.php?q=20180418)を見て`./`にしたのだが、真っ白は解決したが画像などのコンテンツの読み込みでルートがずれて取得できずに解決にすごい時間がかかってしまった。。

### URL直指定、ブラウザリロードでAccessDeniedが表示される
[Github](https://github.com/aws-amplify/amplify-js/issues/2545)上で話題になっている通り、以下のようにAmplifyコンソールに入力してあげれば解決する。
これは自動で解決して欲しいと思ったが、調べて見つかったのでとりあえずよかった。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691945/8123fbdb-4a92-9087-225e-b006c4b8461c.png)

[マニュアル](https://docs.aws.amazon.com/amplify/latest/userguide/redirects.html#redirects-for-single-page-web-apps-spa)にも書いてある。

### 認証がうまく動作しない
せっかくのAmplifyなので認証を使いたい。
[マニュアル](https://docs.amplify.aws/start/getting-started/auth/q/integration/react)に従いつつ、App.jsがこのテンプレートに存在しない。

`layouts/admin.js`に`withAuthenticator`を設定してみたところ以下のようなエラーが出てうまくいかない。

```
TypeError: Cannot read property 'pathname' of undefined
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691945/0dc04060-333f-f117-63cd-80d96d7952d8.png)


いろいろ試して、とりあえず動作した方法は以下の２種類。
どちらもとりあえず動作した状態なので不具合あるかもしれない。
自分は１つ目の方法で対応した。

#### App.jsを作成する
テンプレートでは`index.js`から`layouts/xxx.js`を呼び出しているところを新しく`App.js`を作成して、`index.js`から呼び出すようにした。
テンプレートにApp.jsを含めておいて欲しいなと思いつつ対応。
最終的に以下のファイルとなった。

```index.js
/*!

=========================================================
* Paper Dashboard PRO React - v1.2.0
=========================================================

* Product Page: https://www.creative-tim.com/product/paper-dashboard-pro-react
* Copyright 2020 Creative Tim (https://www.creative-tim.com)

* Coded by Creative Tim

=========================================================

* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

*/
import React from "react";
import ReactDOM from "react-dom";
import App from './App';
import Amplify from 'aws-amplify';
import awsExports from './aws-exports';
Amplify.configure(awsExports);

ReactDOM.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
  document.getElementById("root")
);

```

```App.js
import React from 'react';

import {
  BrowserRouter as Router,
  Route,
  Switch,
  Redirect,
} from 'react-router-dom';
import { createBrowserHistory } from 'history';
import AuthLayout from 'layouts/Auth.js';
import AdminLayout from 'layouts/Admin.js';
import { withAuthenticator } from '@aws-amplify/ui-react';

import 'bootstrap/dist/css/bootstrap.css';
import 'assets/scss/paper-dashboard.scss?v=1.2.0';
import 'assets/demo/demo.css';
import 'perfect-scrollbar/css/perfect-scrollbar.css';

const hist = createBrowserHistory();

function App() {
  return (
    <div className='App'>
      <Router history={hist}>
        <Switch>
          <Route path='/auth' render={(props) => <AuthLayout {...props} />} />
          <Route path='/admin' render={(props) => <AdminLayout {...props} />} />
          <Redirect to='/admin/dashboard' />
        </Switch>
      </Router>
    </div>
  );
}

export default withAuthenticator(App);
```

#### aws-amplify-reactを利用する
マニュアルでは`@aws-amplify/ui-react`を利用しているが、`aws-amplify-react`を利用すると動作する。
`@aws-amplify/ui-react`の方が新しいため、`aws-amplify-react`のUIは壊滅的だけど、実際に使うとなったらどっちも使わないよなと思うので、そこは気にしない。

```
npm install aws-amplify-react
```
をした後に

```Admin.js
import { withAuthenticator } from '@aws-amplify/ui-react'
```
を

```Admin.js
import { withAuthenticator } from 'aws-amplify-react'
```
に修正するだけ。
でもこれってAuth.jsも対応する必要があることを考えたらやっぱりApp.jsを作るのが良さそう。

参考のため、以下それぞれのUI。


* aws-amplify-react
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691945/a6aeb1d6-fd79-d6f0-1252-469e7e6393ee.png)

* @aws-amplify/ui-react
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/691945/3f3512b3-08f8-db10-c6ae-7a0e9b303e0f.png)

# 感想
Firebaseも触ったことがなく、Amplifyが初めてのBaasなので、結構ハマってしまったが、認証など簡単に実装できるのは素晴らしいのでどんどん進化して欲しいと思う。

# 参照
https://docs.amplify.aws/start/q/integration/react
https://github.com/aws-amplify/amplify-js/issues/2545