【個人開発】楽に旅行プランを立てることができるアプリを開発しました🔆

## はじめに
初めまして、[honoka](https://x.com/maru1795062)と申します！
未経験からWebエンジニアを目指して学習中です。
この度、「[Tripot Share](http://tripot-share.com/)」というアプリをリリースいたしました！
このアプリは、旅行メンバーとそれぞれの行きたいスポットを共有しながら簡単に旅行プランをつくることができるサービスとなっております。

<br>

![tripot_share.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641620/38430a09-db08-2ca7-1610-a97fad42f28f.png)

▼ サービスURL
http://tripot-share.com/
ゲストログインもできますので、ぜひお試しください。

▼Github
https://github.com/maru973/Tripot_Share

## 開発背景
**・旅行を共にするメンバーと行きたい場所をまとめるのが大変...**
　友達とそれぞれの行きたい場所をリストアップして送り合い、それを検索して内容を把握し計画を立てていました。これがもう少し**楽になったらいいな**と思っていました。
 　特に代表的な観光地以外の場所を訪れる際は、計画を一から立てる必要があります。 この手間を解消し、メンバーの行きたい場所を**一括で表示できるようにしたい**と考えました。
  
**・行きたい場所同士の位置関係がわからない...**
　旅行先の地理に詳しいわけではないため、行きたい場所を網羅する**最適なルートを考えることが難しい**と感じています。 出発地から到着地までの最適なルートを自動で生成してくれるものがあれば、より簡単かつ柔軟なオリジナルの旅行計画を立てることができると考えました。

 ### これらの課題を解決するものが、「[Tripot Share](http://tripot-share.com/)」になります！
<details><summary>なんで「Tripot」？</summary>

 「Trip(旅行)」 ＋ 「Spot(場所)」　で「Tripot」(音も軽くて旅行のワクワク感にはピッタリ🥰)
 今回のアプリのメイン機能が共有することなので、そこに「Share(共有する)」をつけて「Tripot Share」としました。
</details>
 
## 機能紹介
| 会員登録・ログイン | プラン一覧 |
| ---- | ---- |
|![68f238180723fd3be84e24de10f8818d.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641620/9e98e0c9-81e5-6e6c-a849-8a23279449ab.png)|![c4286fe00e7651a58615382783fce7da.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641620/ec83ebb7-ad2e-f094-ff6a-1897ce6fa81b.png)|
| `devise`で会員登録・ログイン機能を実装しました。メールアドレスとLINEでのログインをユーザーが選択できるようになっています。| みんなのプランページでは他の人のプランも参考にすることができます。`ransack`を使用して見たいプランをすぐに検索できるようにしています。 |

| プラン作成 | プラン編集 |
| ---- | ---- |
| ![5bf75f89d932c951626f540ac7de7b62.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641620/c11a5aaf-55c8-1879-1984-2015a279e6e3.gif)| ![9ed132335c1ae5b7e0a5794751ea638e.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641620/f53c2351-4091-a0ba-bb98-4b0ce44ad72e.gif)|
| 旅行先の都道府県を選択すると地図が生成されたときに、その都道府県にズームされた地図が表示されます。 | プラン情報の編集は`TurboStream`を使用して非同期でできるようにしました。マイプランページとみんなのプランページからのみ編集できます。 |

| スポット登録 | スポット詳細情報 |
| ---- | ---- |
|　![094729461d286ded30c3b8b0f7dfdb76.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641620/be67d1b4-5a56-a2b2-fe3e-e24490ecc20c.gif)| ![71b154f289f439699a624b644b25969b.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641620/5a99e580-e628-1115-35f4-c7119442e7fe.gif)|
| スポットを入力するとオートコンプリートで入力候補を表示します。登録するとリストとマーカーが非同期で表示されます。 | 各スポット名をクリックすると詳細情報がモーダルで表示されます。ℹ️をクリックすると現在の曜日が表示され、営業時間の確認を促すようにしました。 |

| プラン・スポット削除 | メンバー招待 |
| ---- | ---- |
| ![4ebc40b3981cfdf81ee1266cfcdf41c7.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641620/070ced9c-f779-5533-48f4-757478b3f228.gif)| ![36eec3270f9a79f8893b719617c425d2.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641620/bfe5504e-a907-f935-f8c7-7fa43290140f.gif)|
| スポット削除は`TurboStream`を使用しました。意図していないものを削除してしまうことを防ぐため、詳細ページからのみプラン削除ができるようにしました。 | 各プランにメンバーを招待できます。招待メールを送信するかリンクを共有する方法から選択できます。招待リンクはボタンをクリックするとコピーができるようにしました。 |

| ランキング投票 | ランキング |
| ---- | ---- |
| ![a995ffe443a756d1384a48ae5f9441ed.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641620/6024b187-c4c9-001f-d955-a2dab51467af.gif)| ![7d28a6f70841846294de841fc3a7408f.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641620/6fc4de16-09be-78e3-7ea9-662f866648a9.png)|
| プランに登録した全スポットに対してメンバーはそれぞれ行きたい度合いを0~4ポイントの中から選択し投票をします。 | ポイントを自動集計し、上位６位までのスポットを詳細ページのランキングタブに表示します。 |

| ルート作成 | ルート再検索 |
| ---- | ---- |
| ![d2f48ca8ed967b6aab3c8a9b11224586.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641620/b1141eb7-afa7-e2e2-71b3-40b8ea084d5c.gif)| ![a6703e0a9b5cded20ed57792f2602d5c.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641620/eca85c25-9a01-66cb-618d-998143b6aa68.gif)|
| ランキングの上位６スポットを経由して、出発地から到着地までの最適なルートを自動で検索します。 | スポットを並び替えて再度ルート検索ができます。並び替えは`sortablejs`を使用しました。 |

| 初回モーダル | ゲストログイン |
| ---- | ---- |
| ![92642eb3f7c1706fcccf65bf700b435a.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641620/e7f8af28-08fd-4f8e-517b-cf75523fcd90.gif)| ![f1c35cb83f72480baeafbcfce3698a4a.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641620/c51590d7-9612-1823-0208-927550652b9d.gif)|
| 作成or参加したプランの詳細ページに遷移した最初の一回のみメンバー招待を促すモーダルを表示するようにしました。 | 会員登録なしでもゲストとしてログインできるようにしました。ゲストユーザーはアカウントの削除、編集、招待機能は使用できないようになっています。 |  


## 使用技術
| カテゴリー | 技術 |
| ---- | ---- |
|フロントエンド|	TailwindCSS（daisyUI）　/　JavaScript　/　Hotwire|
|バックエンド|	Ruby 3.2.2　/　Ruby on Rails 7.1.3|
|データベース|	PostgreSQL|
|CI/CL|	GitHubActions|
|インフラ| Fly.io　/　AmazonS3|
| API | Google Maps JavaScript API　/　Google Places API　/　Google Geocoding API　/　Google Directions API |
| その他 | Docker　/　Devise |

## 選定理由
### フロントエンド
　TailwindCSSの柔軟性の高さとコードを貼り付けるだけで使用できる部分にメリットを感じました。またdaisyUIのテーマをカスタマイズして使用することで、コードをより簡単に書けるため開発スピードの向上につながると思いました。
 
### バックエンド
　プログラミングスクールでRuby on Railsをメインに学んでいたため、キャッチアップの時間を短縮できると考えました。またRailsのHotwireを駆使して開発することでどのくらいUX向上に貢献できるのか知りたいと思いました。

### インフラ・開発環境
**自動デプロイ**
　Fly.ioへのデプロイは、デフォルトだと手動でのデプロイが必要になります。GitHubActionsを導入して自動デプロイにすることで開発の効率化を図りました。

**Fly.io**
　今までアプリを制作した時はRenderを使っており、他のデプロイ先も使ってみたいと思いました。そこで運用コストも低く、公式ドキュメントもしっかりしているFly.ioを選択しました。

**Docker**
　スクラップ&ビルドが容易で、開発環境を段階的に構築してたり、修正を加えたりしやすいと考え、Dockerを用いて開発を行うようにしました。


## ER図
![卒業制作.drawio.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641620/868bed3e-9ebe-08af-cd5a-21f74a1a64cc.png)


## 画面遷移図
https://www.figma.com/design/lBu251dgQyLeiJrADJ3aS6/Untitled?node-id=0-1&t=Z2uGjcwkOcIezMo7-0

## 工夫ポイント🌟
**ログイン機能**
　日常のやり取りをするツールの中でシェアの高いLINEでのログインを使用しました。そうすることで旅行の話が話題に挙がった際、そのままURLを共有してすぐログインできるのでUXの向上につながると思いました。
　しかしながら他のアプリと連携させることに不安を感じる方もいるため、メールアドレスでのログイン方法も選択できるようにしました。

**カードデザイン**
　学校での旅のしおりをイメージにして、旅行に対するワクワク感を演出できるデザインにしました。画面サイズによってデザインを変えることで、それぞれの画面上で違和感がないようにしました。
| PC画面 |
| ---- |
|![c4286fe00e7651a58615382783fce7da.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641620/ec83ebb7-ad2e-f094-ff6a-1897ce6fa81b.png)|

| スマホ画面 |
| ---- |
|![index.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3641620/4e0e1d03-5c5e-c656-6d82-3c391032ae6a.png)|

**スポット詳細情報**
　旅行で必要な情報をモーダルで表示しすぐに確認できるようにしました。ウェブサイトを載せることで遷移すれば、すぐにどんな場所なのかがわかるので、自ら調べる手間を減らす工夫をしました。
　特に当日目的地に行って休業日だったということがないように、営業時間の確認は旅行する上で重要になると思いました。ℹ️をクリックすると現在の曜日が表示され、営業時間の確認を促すようにしました。

**メンバー招待**
　メンバー招待の方法は２種類用意してユーザーの使いやすい方を選択できるようにしました。
　招待リンクを生成する方はボタンをクリックするだけでコピーができるようにして、ユーザーの手間を減らしました。
 
**ランキング**
　行きたいスポットを共有したらどこを一番に周るかなどを決めなくてはいけません。投票機能を追加することで、自動でメンバーのより行きたい場所を集計して、ランキングを作成することにしました。それぞれのメンバーが時間を見つけて投票をしておけば、予定を合わせて打ち合わせをする時間が減り、時間の効率化につながると考えました。

**初回モーダル**
　作成したプランの詳細ページに初めて遷移した場合、メンバー招待についてのモーダルを表示するようにしました。モーダルによって次にやることが明確にわかるのと同時に、追加メニューボタンの位置が自然に認識されるようにしました。

## 今後の展望
**リアルタイム編集機能の実現（action cable）**
　メンバー同士がリアルタイムでスポット登録できるようになれば、よりUX向上になるとつながると考えています。

**国外旅行先の対応**
　現在プラン作成時に選択できる旅行先が国内だけなので、国外の選択肢も追加していきたいと思っています。

**RSpec**
　テストコードが書けていないので、バグやエラーを早期発見できるようにしたいです。追加機能をデプロイした際に、今までの機能が動かないといったことがないようにしたいと考えています。

## おわりに
最初にイメージしていた通りにアプリを開発することができて嬉しかったです。
このアプリを作成するにあたって、相談に乗ってくださった方、使ってくださった方、ありがとうございました。
自分一人では完成させることができなかったので、本当に感謝しています。
今回のアプリ開発を通して、今の自分に足りない部分も見えてきました。今後はアプリの改善と共に、その部分を補えるような学習をしていきたいです。


最後までお読みいただきありがとうございました！