React+TypeScript+GCP+Github Actionsでフロントエンドのポートフォリオを作成しました。

今回は、作成したポートフォリオアプリの紹介です。とは言ってもまだ改善の余地があり(QiitaでいくつもLGTMをもらっている方々のものに比べると全然です...)、「完成した！」と胸を張って言えるというわけではないのですが、一応ひと段落したので記事にします。

## 概要

アプリ名 『start』

[https://start-kokokara.com](https://start-kokokara.com)
[Github](https://github.com/RYOTA-KOBA/MatchingApp)

制作期間 **2ヵ月半**


『start』は経験の浅いエンジニアやデザイナーのために作ったマッチングアプリです。web制作は個人で案件を受注すると案件の単価がかなり低くなってしまいます。そこで制作会社がやっているように、デザイナーとコーダーでチームを組んで案件を受注した方が結果的に一人当たりの単価も高くなると考え作成しました。

#### トップページ
![top.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509690/44aad9aa-75b7-25d0-52e4-9cc2851a0080.png)
ページネーションor無限スクロールは現在実装中です。一度無限スクロールを実装したのですが、query paramaterのところでいろいろ詰まったので後に回すことにしました。

#### トップページ(SPサイズ)
![sp-top.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509690/55674c1d-eb94-c37d-9f67-693ed1a578e3.png)


## 使用技術
- フロントエンド
  - React 16.14.0
  - TypeScript 4.1.2
  - CSS/BootStrap/Material UI
- バックエンド
  - Firebase(Authentication, Firestore, Cloud Storage, Cloud Functions)
- インフラ
  - GCP(Cloud Storage, App Engine)
  - Github Actions
  - Docker 20.10.2 / docker-compose 1.27.4

フロントエンドはReact+TypeScriptで記述しています。デザインにはMaterial UIと一部BootStrapを使用しました。
バックエンドにはFirebaseを使用しており、Firestoreでは画像以外のデータの管理を、Cloud Storageでは画像の管理(+デプロイ時に一時的に使用)をしています。さらに、FirebaseのAuthenticationを用いてログイン、会員登録機能を実現しています。
また、開発環境には、Docker、docker-composeを、さらにGithub Actionsを使用し、pull requestを作成したら自動テストが走り、masterブランチにコードがmergeされると、自動ビルド自動デプロイがされます。デプロイ先はGCPのApp Engineで、オートスケールするようにしています。

## インフラ構成図
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509690/754219e5-b6e7-9cb0-85d8-a95754f5d921.png)

slackのIncoming Webhookを利用して、アプリ内の問い合わせ用モーダルからの問い合わせが開発環境のslackに通知されるようになっています。

#### slackの通知
以下のようにお問い合わせフォームを送信すると、slackにてお問い合わせの内容が表示されます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509690/e8f7bb43-28c8-d2a7-bc62-7555834d2db7.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509690/5db5baf8-82e5-2dc4-f6c3-04ef54d5c6b6.png)

## 機能一覧
- ユーザー関連
  - ユーザー登録機能
  - ログイン、ログアウト
  - ゲストユーザーログイン機能(1クリックでのログインができるもの)
  - フォロー、アンフォロー
- 投稿関連
  - 投稿機能(CRUD)
  - 投稿一覧表示
  - カテゴリーごとの投稿表示
  - フォローしているユーザーの投稿の一覧表示
  - 投稿へのコメント機能
- チャットボット機能
- お問い合わせのslack通知機能
- ブックマーク機能、ブックマークの一覧表示機能　
- プロフィール画像アップロード機能
- レスポンシブデザイン(SPのみ)


## 詳細
#### ログイン画面
ログイン画面を含めて、formは全て`material ui`を利用しています。コードをコピペするだけで綺麗なフォームが作れてとても楽でした:grin:
また、ログイン画面にはゲストユーザー用のログインボタンを配置しています。これは1クリックでお試し利用できるようにしています。
![login.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509690/550632cf-6a05-e94d-4ba6-585f52d53529.png)

また、ゲストユーザーは会員情報の変更ができないようにコードで制御しています。会員情報を編集しようとすると以下の画像のようにアラートが出ます。
![guestuseredit.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509690/fd17e402-e362-9d6b-b708-a875236277d8.png)

#### タグとタイムライン
このアプリでは、新規投稿をする際にカテゴリーを選択することができるようになっており、以下の画像のようにカテゴリーごとの記事を一覧表示することができます。画像はカテゴリーが`フロントエンド`の場合の記事を表示しています。この機能はクエリーパラメータを利用して、投稿の表示を切り替えることで実現しています。

![category.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509690/1a9d49a6-3b59-22ce-0b39-5647ce80ce8e.png)

また、このアプリではユーザーのフォロー機能を実装しています。`タイムライン`をクリックすると自分がフォローしているユーザーの投稿を一覧表示できます。このフォロー機能はいろいろdb設計で悩んだので、それを[記事](https://qiita.com/KOBA-RYOTA/items/9d6a788d4dda23d4b303)にしています。良かったらご覧ください。
![timeline.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509690/c6253f3d-7763-a1b0-dbeb-37dbc8f51e7c.png)

#### ブックマーク機能
ユーザーは気になった投稿をブックマークに保存しておくことができます。

![bookmark.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509690/73cfa246-22dd-c283-b5f1-d7da5127798c.png)

#### チャットボット
webサイトなどでは**よくある質問**としてQ&Aがまとめられていると思いますが、このアプリではよくある質問(想定)をチャット形式で回答するようにしました。また、チャットを作成するうえで[この動画](https://youtube.com/playlist?list=PLX8Rsrpnn3IVOk48awq_nKW0aFP0MGpnn)を参考にさせていただきました。本当に感謝です:pray:

![ezgif.com-gif-maker.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509690/c08a3143-17a6-a5be-c6dc-e426b400890e.gif)


#### プロフィール画面
各ユーザーはプロフィール画面を持っています。自分のプロフィールであれば`EDITボタン`。そうでない場合は`FOLLOWボタン`を配置しています。
![userprofile.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509690/53c123c8-6f98-eea7-a14a-6e01a96aac9b.png)

![userother.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509690/700d09cb-f895-fb78-6e6e-56d7c342e2b1.png)

#### 投稿詳細とコメント機能

投稿詳細画面でコメントをすることができます。コメントはfirestoreの`onSnapshot`を利用することでリアルタイム表示できるようにしています。

![ezgif.com-gif-maker.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/509690/f5b0c15e-4cf1-858d-c6fd-d5429c28c031.gif)

## まとめ
ここまで僕が作成したアプリを紹介してきました。githubのissueにタスクを登録しつつ開発を進めてきましたが、まだまだ解決しないといけないエラーや、実装しておきたい機能(無限スクロールなど)がまだたくさんあります。これからそれらの実装や修正を進めていければなと思っております。ここまでご覧いただきありがとうございました。