🍣

【GPT3.5turbo】NextJsで動くGPT3.5turbo【#6Chat Logs】

2023/04/23に公開

【#6Chat Logs】

YouTube:https://youtu.be/gK-5aoe0ZnA

https://youtu.be/gK-5aoe0ZnA

今回はチャットのやり取りを表示する部分を実装していきます。

今回もコーディングとスタイリングが中心になりますので、
時間がない方は下記コードをコピペしてしまっても大丈夫です。

pages/index.tsx
import { ChangeEvent, SyntheticEvent, useState } from 'react'

interface Log {
  prompt: string
  role: string
  content: string
}

export default function Home() {
  const [prompt, setPropmt] = useState('')
  const [isLoading, setIsLoading] = useState(false)
  const [logs, setLogs] = useState<Log[]>([])

  const handleChange = (e: ChangeEvent<HTMLTextAreaElement>) => {
    setPropmt(e.target.value)
  }

  const handleSubmit = async (e: SyntheticEvent) => {
    e.preventDefault()
    setIsLoading(true)

    const res = await fetch('/api/chat', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({ prompt: prompt }),
    })
    const data = await res.json()
    if (res.status === 200) {
      console.log(data)
      const logData = {
        prompt: prompt,
        ...data.message,
      }
      setLogs([...logs, logData])
      setPropmt('')
      setIsLoading(false)
    } else {
      console.log(data)
      setIsLoading(false)
    }
  }

  return (
    <main className="flex min-h-screen flex-col items-center px-2">
      <h1 className="my-6 text-3xl font-bold tracking-tight text-white sm:text-4xl">
        Hello Chat-GPT
      </h1>
      <div className="max-w-xl overflow-hidden bg-gray-900 py-4 sm:py-6 lg:py-8">
        <div className="mx-auto max-w-3xl px-6 lg:px-8">
          <div>
            <div className="max-w-xl lg:max-w-lg mb-3">
              <h2 className="text-3xl mb-3 font-bold tracking-tight text-white sm:text-4xl">
                Please Enter Your Message.
              </h2>
            </div>
          </div>
          <div>
            <form
              onSubmit={handleSubmit}
              className="flex flex-col items-center justify-center"
            >
              <textarea
                name="prompt"
                value={prompt}
                onChange={handleChange}
                cols={20}
                rows={4}
                className="w-full flex-auto rounded-md border-0 bg-white/5 px-3.5 py-2 text-white shadow-sm ring-1 ring-inset ring-white/10 focus:ring-2 focus:ring-inset focus:ring-indigo-500 sm:text-sm sm:leading-6"
              ></textarea>
              <button
                disabled={isLoading || !prompt}
                type="submit"
                className="flex-none rounded-md bg-indigo-500 mt-3 px-3.5 py-2.5 text-sm font-semibold text-white shadow-sm hover:bg-indigo-400 focus-visible:outline focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-indigo-500"
              >
                Send Message
              </button>
            </form>
          </div>
          <div className="max-w-xl mt-3 p-5 bg-white/5 min-h-[300px] max-h-[300px] text-white overflow-y-scroll break-words">
            <div className="w-full">
              <div className=" flex flex-row-reverse my-6">
                <h3 className=" flex flex-col justify-center items-center">
                  <div className=" w-12 h-12 flex justify-center items-center rounded-full bg-white text-pink-700 font-bold text-[28px]">
                    <p>AI</p>
                  </div>
                  Assistant
                </h3>
                <p className=" mr-3 px-3 py-2 bg-[#000c22] rounded-md">
                  何か御用があれば、入力欄にメッセージをお願いします。
                </p>
              </div>
            </div>
            {logs?.map((log, idx) => (
              <div className="w-full" key={idx}>
                <div className="flex">
                  <h3 className="flex flex-col justify-center items-center">
                    <div className="w-12 h-12 flex justify-center items-center rounded-full bg-white text-blue-700 font-bold text-[28px]">
                      <p>U</p>
                    </div>
                    User
                  </h3>
                  <p className="ml-3 px-3 py-2 bg-[#000c22] rounded-md">
                    {log.prompt}
                  </p>
                </div>
                <div className="flex flex-row-reverse my-6">
                  <h3 className="flex flex-col justify-center items-center">
                    <div className="w-12 h-12 flex justify-center items-center rounded-full bg-white text-pink-700 font-bold text-[28px]">
                      <p>AI</p>
                    </div>
                    Assistant
                  </h3>
                  <p className="mr-3 px-3 py-2 bg-[#000c22] rounded-md">
                    {log.content}
                  </p>
                </div>
              </div>
            ))}
          </div>
        </div>
      </div>
    </main>
  )
}

Discussion