Reactでカウントダウン/ストップウォッチアプリを作って、不定期的にメンテナンスしています

# はじめに
皆さんは複数の時間のタイマーを使いたい用事はありますか？私にはあります。私のためのアプリを私が作りました。
スマートフォンのネイティブアプリには似たようなものがあることは知っているのですが、PCを利用しつつで使いたいのでWebブラウザから利用できると良いなと思っていました。
また、Reactに触る機会が減っていた時期でもあったので、触る機会を作っておきたいという思惑もありました。

結構前から動いていたのですが、機能の要望を受けたり、見知ったものを使ってみたい欲で増築したり、色々中身が増えてきたので整理も兼ねて記事にしました。

# 作ったもの

https://showichiro.github.io/timer/

## ソースコード
https://github.com/Showichiro/timer/tree/master

# 技術スタック

Reactを使って構築しています。
デザイン周りはtailwindcss(daisyui)を利用しています。カウントダウンの数字の動きがかっこいいのはdaisyuiのおかげ...。
github actionsで自動でgithub pagesにデプロイするようにしています。

# 仕組み

バックエンドはありません。すべてをローカルストレージに保持しています。

# 機能紹介

- タイマー
    - カウントダウン
    カウントダウンします。0になると赤くなって音がなります。
    [![カウントダウンタイマー](https://i.gyazo.com/88b0241b177413ed3c4948312259d4fc.gif)](https://gyazo.com/88b0241b177413ed3c4948312259d4fc)
    [![Image from Gyazo](https://i.gyazo.com/70e2c0252e1d1902dc4598faf831151d.gif)](https://gyazo.com/70e2c0252e1d1902dc4598faf831151d)
    時間表示部分をクリックすることで、時間を編集することができます。
[![タイマーの時間編集](https://i.gyazo.com/011ed1067737f2320380167f3386825f.gif)](https://gyazo.com/011ed1067737f2320380167f3386825f)
    - ストップウォッチ
    [![ストップウォッチ](https://i.gyazo.com/d9e1fc3b89569da7b4edcde8a7445ebe.gif)](https://gyazo.com/d9e1fc3b89569da7b4edcde8a7445ebe)
    - 名前もいじれる
    名前も簡単にいじることができます。
    [![Image from Gyazo](https://i.gyazo.com/a2a34231166a9780e6e97042c054f7cb.gif)](https://gyazo.com/a2a34231166a9780e6e97042c054f7cb)
    - いくつでも増やせる(ローカルストレージの許す限り)
    いくらでも増やせます(ローカルストレージの許す限り)。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619165/a87dd337-58b1-e9d0-e2cf-00d8802238bb.png)
    - URLにタイマー指定をするとそのタイマーを作れる
    さっとほしいタイマーを作れます。
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619165/86bd6828-3d46-6139-4e6a-43cd078bc501.png)
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619165/1cbe95d2-7767-c50a-0d73-12c73e519c63.png)
    ![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619165/8b1f94a5-cb3c-4d75-f2be-078743bf91a0.png)



- テーマカラー
色々なテーマカラーを選択できます。ありがとうdaisyui。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619165/96b307d0-c873-addf-fbbc-77221e4b3fce.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619165/2235fb56-99cf-4596-ca41-6d13e373efe4.png)
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619165/1a4216bc-4cee-43cf-10f9-ef7887a88c0f.png)


# その他

## 使い方説明
初回表示時に使い方を説明してくれます。[react-joyride](https://github.com/gilbarbara/react-joyride)を利用しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619165/8b667a55-2b2e-f09a-6e15-3ec0e1c6b9e4.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/619165/939e1bb1-e650-7da4-3978-f3f00256772e.png)


以下のように表示したいメッセージや表示場所のclass名などを指定すると、程よい場所に説明を表示してくれます。
```ts
{
    target: '.my-other-step',
    content: 'This another awesome feature!',
},
```

## i18n
といいつつ2ヵ国語(日英)のみですが、i18n対応しています(ブラウザ設定依存)。
[react-i18next](https://react.i18next.com/)を利用しています。

configを用意した上で、各言語ごとのファイルを用意し、
例）
```json:src/i18n/ja.json
{
  "title": "タイマー"
}
```

```json:src/i18n/en.json
{
  "title": "Timer"
}
```

`useTranslation`というhooksを利用することでReactのComponent内で言語ごとのテキストを利用できます。
例）
```tsx
import { useTranslation } from "react-i18next";
export const Header: FC = () => {
  const { t } = useTranslation();
  return (
      <div>{t("title")}</div>
  );
};
```


## PWA

PWAに対応しているので、デスクトップ・ネイティブアプリライクに利用できます。
[vite-plugin-pwa](https://vite-pwa-org.netlify.app/)によって実現しています。
`vite.config.ts`で読み込むpluginにPWA用の設定を書いていきます。

## デスクトップアプリ(今は停止中)

PWA対応したことで意義を失ったので停止してますが、[tauri](https://tauri.app/)を利用して、linux/windows/macOSそれぞれで動くデスクトップアプリをビルドしていました。

## Remix版
[Remix](https://remix.run/)を触ってみたかったので同じものを作りました(微妙に機能の相違があるが)。バックエンドには[Supabase](https://supabase.com/)を採用しています。[Cloudflare Pages](https://www.cloudflare.com/ja-jp/developer-platform/pages/)にデプロイする想定です。ソーシャルログインできるので機種やブラウザを跨いでタイマーの設定を引き継ぐことができます。

Remixはformで一通りの操作をするという思想が一貫しておりシンプルでとてもおもしろいフレームワークだと思いました。
また、Supabaseはドキュメントが充実しており、SDKも使いやすいので開発者体験が良いなと思います。(無料でリレーショナルDBが使えるのも嬉しい)。

両者ともサーバサイドやDBレイヤーを必要とするアプリを作る際には積極的に採用していきたいなと思いました。

一時デプロイしていましたが、RemixやSupabase Authを触れて満足したので現在はリソースを削除しています。

### ソースコード
https://github.com/Showichiro/remix-timer