【Day16】インスタ用のキャプションを生成する（前編）

## はじめに

勉強とアウトプットを兼ねて、Webアプリ開発の記録を記事にしてみます。

個人のメモ的な側面が強いです。
Web開発初心者すぎて至らぬところだらけだと思いますが、暖かい目で見ていただければ幸いです。

↓ これまでの内容 ↓
[【Day0】アプリが完成するまで毎日投稿](https://qiita.com/midorigame/items/f9b9a445c945b4a837b1)
[【Day1】開発環境を考える](https://qiita.com/midorigame/items/e26344599e2ffaa22033)
[【Day2】開発環境を構築する、、、はずでした](https://qiita.com/midorigame/items/3f57f2691a8e1074adb8)
[【Day3】まずはフロントだけ開発環境を構築する](https://qiita.com/midorigame/items/9de27ba72aaef504a833)
[【Day4】バックエンドの開発環境を整えつつ、マルチコンテナ対応のDevcontainerにする](https://qiita.com/midorigame/items/5b95374cd85f715a6498)
[【Day5】お試し実装！ファイルをアップロードしてバックエンドで処理する](https://qiita.com/midorigame/items/9663f0063b95b501c08a)
[【Day6】Docker Desktopが起動しなくなり泣きながら原因調査する](https://qiita.com/midorigame/items/d07df1caf05267d0609d)
[【Day7】画像にフレームとExif情報を付けてみる](https://qiita.com/midorigame/items/e2d85ce8dd7a5bcb5daf)
[【Day8】フロントに表示する画像のサイズを小さくする](https://qiita.com/midorigame/items/f7f5f9b14fb79259c716)
[【Day9】フロントエンドとバックエンドをそれぞれデプロイする](https://qiita.com/midorigame/items/4c8037024e667ff1105b)
[【Day10】結局コンテナ1つで開発する方が楽かもしれない](https://qiita.com/midorigame/items/60b484b2007c3aab474b)
[【Day11】アプリが一通り完成！！](https://qiita.com/midorigame/items/38ddccc09f0625aaebd6)
[【Day12】FastAPIのコードをリファクタリングする](https://qiita.com/midorigame/items/72ed91ff9add5504fab9)
[【Day13】機能実装！フレームに記載するExif情報を編集できるようにする（前編）](https://qiita.com/midorigame/items/790b0fcd54620f9fb573)
[【Day14】ReactのリファクタリングとUI変更を同時にやった](https://qiita.com/midorigame/items/b492ae717e59fb137b70)
[【Day15】機能実装！フレームに記載するExif情報を編集できるようにする（後編）](https://qiita.com/midorigame/items/9a649aa2a0a17d1db552)

## 前回やったこと

追加機能として、画像のアップロード前にExif情報を手入力できる機能を実装しました！
実はまだ入力値のバリデーションなどなど不完全なのは内緒！！

## 今回やったこと

次は画像のExif情報から自動的にインスタ用のキャプションを作成する機能を実装します！

今回はその先駆けとして、まずはフロント側にキャプションを表示させるエリアを作成しました。

### キャプション表示エリア

こんな感じで画像の下に表示させてます！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307348/0febb7d6-d6cf-4ab5-8e04-ae361dabe784.png)

そんでもって、今回のこだわりポイントはコピーボタンを押下するとポップアップとともに自動的にクリップボードにキャプションがコピーされることです！！

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/307348/b4f46a03-4f60-4a74-b38d-042a8d22a03f.png)

### ポップアップを出す方法

今回はReactの`react-toastify`というライブラリを使用しました。

https://www.npmjs.com/package/react-toastify


まずはApp.tsxに`ToastContainer`を追加します。このときにどういうポップアップを出すかの設定もできます。

```react:App.tsx
import "./App.css";
import ImageUploader from "./features/imageUploader/components/ImageUploader";
import Titel from "./components/Title";
import Viewer from "./features/imageUploader/components/ResultArea";
import { useState } from "react";
import "react-toastify/dist/ReactToastify.css";
import { ToastContainer } from "react-toastify";

function App() {
  const [processedImage, setProcessedImage] = useState<string | null>(null);
  const [statusMessage, setStatusMessage] = useState<string | null>("");

  return (
    <>
      <div className="app-container">
        <ToastContainer
          position="top-center"
          autoClose={1000}
          hideProgressBar
          newestOnTop
          closeOnClick
          pauseOnHover
          draggable
        />
        <Titel />
        <ImageUploader
          setProcessedImage={setProcessedImage}
          setStatusMessage={setStatusMessage}
        />
        <Viewer statusMessage={statusMessage} processedImage={processedImage} />
      </div>
    </>
  );
}

export default App;
```

その後、このコピーボタンのクリック時に実行される関数内で`toast.success("キャプションをコピーしました！");`のように使うとポップアップが表示されるようになります。

```react:CopyText.tsx
import React from "react";
import { toast } from "react-toastify";
import "./CopyText.css";

type Props = {
  text: string;
};

const CopyText: React.FC<Props> = ({ text }) => {
  const handleCopy = async () => {
    try {
      await navigator.clipboard.writeText(text);
      toast.success("キャプションをコピーしました！");
    } catch (err) {
      console.error("コピーに失敗しました:", err);
      toast.error("コピーに失敗しました");
    }
  };

  return (
    <div className="caption-box">
      <textarea className="caption-text" value={text} readOnly />
      <button className="caption-copy-button" onClick={handleCopy}>
        コピー
      </button>
    </div>
  );
};

export default CopyText;
```

## おわりに

今回はダミーテキストでキャプションを作成して、コピーまでできるようにしました！
コピーは良い感じのポップアップを表示させることでUXがちょっと上がったかも！！

ちなみにこのポップアップはChat GPTが提案してくれたんですよ！！すごい！！！！優秀！！！！！！
クリックorタップ時にコピーさせたい、しか聞いてないのに！！！！！！！！！

次回はAPIのレスポンスにキャプション用のテキストを追加して、キャプションを完全に自動生成させます！