-
4. Chat UI사이드프로젝트 2024. 7. 22. 14:02
https://www.youtube.com/watch?v=-xXASlyU0Ck&t=2007s
이 동영상을 보며 만드는 챗 웹 실습예제
다음으로 이어서 채팅 UI를 만든다.
import ChatHeader from "@/components/ChatHeader"; import { Button } from "@/components/ui/button"; import InitUser from "@/lib/store/InitUser"; import { createClient } from "@/utils/supabase/server"; // supabase 객체 불러오기. // 서버 컴포넌트니깐 서버에서 임포트해온다. import React from "react"; const page = async () => { const supabase = createClient(); // supabase 객체 불러오기. // const session = await supabase.auth.getSession(); // console.log(session.data.session?.user); const user = (await supabase.auth.getUser()).data.user; // console.log("user: ", user); return ( <> <div className="max-w-3xl mx-auto md:py-10 h-screen"> <div className="h-full border rounded-md flex flex-col"> <ChatHeader user={user} /> {/* 이제 zustand를 통해 user의 state management를 하기 때문에 ChatHeader에 user props를 안넘겨줘도 되지만, 굳이 지울 필요도 없으므로 남겨준다. */} <div className="flex-1 bg-slate-500"></div> // 새로 추가 <div className="p-5"></div> // 새로 추가 </div> </div> <InitUser user={user} /> {/* user state 관리를 시작할 수 있도록. */} </> ); }; export default page;
저번까지 만들었던 app/page.tsx 에 div 두개를 추가해줬다.
그리고, Input을 추가해주기 위해 shadCn에서 Input을 검색해, 인스톨 명령어를 복사해주고 설치해준다.
npx shadcn-ui@latest add input
이제 좀 꾸며준다. 아직 DB랑 연결을 시켜서 뭘 한다거나 그러진 않고, 퍼블리싱을 해준다.
import ChatHeader from "@/components/ChatHeader"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import InitUser from "@/lib/store/InitUser"; import { createClient } from "@/utils/supabase/server"; // supabase 객체 불러오기. // 서버 컴포넌트니깐 서버에서 임포트해온다. import React from "react"; const page = async () => { const supabase = createClient(); // supabase 객체 불러오기. // const session = await supabase.auth.getSession(); // console.log(session.data.session?.user); const user = (await supabase.auth.getUser()).data.user; // console.log("user: ", user); return ( <> <div className="max-w-3xl mx-auto md:py-10 h-screen"> <div className="h-full border rounded-md flex flex-col"> <ChatHeader user={user} /> {/* 이제 zustand를 통해 user의 state management를 하기 때문에 ChatHeader에 user props를 안넘겨줘도 되지만, 굳이 지울 필요도 없으므로 남겨준다. */} <div className="flex-1 flex flex-col p-5"> <div className="flex-1"></div> <div> <div className="flex gap-2"> <div className="h-10 w-10 bg-green-500 rounded-full"></div> <div className="flex-1"> <div className="flex items-center gap-1"> <h1 className="font-bold">Jaehyeon</h1> <h1 className="text-sm text-gray-400"> {new Date().toDateString()} </h1> </div> <p className="text-gray-300"> Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quisquam minus dolorum voluptatibus perferendis nesciunt ex odit rem est a maiores! </p> </div> </div> </div> </div> <div className="p-5"> <Input placeholder="send message" /> </div> </div> </div> <InitUser user={user} /> {/* user state 관리를 시작할 수 있도록. */} </> ); }; export default page;
이렇게 하면 이런 화면이 나온다.
잘 나온다. 그럼 메세지를 여러개 만들어본다.
html을 복사해서 여러개 붙여넣는 게 아니라, DB에서 배열로 받아와서 map으로 뿌려줄거기때문에 위에서 만든 div를 배열로 여러개로 뿌려줘본다.
그리고 추가로 css 몇개 추가해줬다.
import ChatHeader from "@/components/ChatHeader"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import InitUser from "@/lib/store/InitUser"; import { createClient } from "@/utils/supabase/server"; // supabase 객체 불러오기. // 서버 컴포넌트니깐 서버에서 임포트해온다. import React from "react"; const page = async () => { const supabase = createClient(); // supabase 객체 불러오기. // const session = await supabase.auth.getSession(); // console.log(session.data.session?.user); const user = (await supabase.auth.getUser()).data.user; // console.log("user: ", user); return ( <> <div className="max-w-3xl mx-auto md:py-10 h-screen"> <div className="h-full border rounded-md flex flex-col"> <ChatHeader user={user} /> {/* 이제 zustand를 통해 user의 state management를 하기 때문에 ChatHeader에 user props를 안넘겨줘도 되지만, 굳이 지울 필요도 없으므로 남겨준다. */} <div className="flex-1 flex flex-col p-5 h-full overflow-y-auto"> <div className="flex-1"></div> <div className="space-y-7"> {Array.from({ length: 15 }, (v, i) => i).map((value) => { return ( <div className="flex gap-2" key={value}> <div className="h-10 w-10 bg-green-500 rounded-full"></div> <div className="flex-1"> <div className="flex items-center gap-1"> <h1 className="font-bold">Jaehyeon</h1> <h1 className="text-sm text-gray-400"> {new Date().toDateString()} </h1> </div> <p className="text-gray-300"> Lorem ipsum dolor, sit amet consectetur adipisicing elit. Quisquam minus dolorum voluptatibus perferendis nesciunt ex odit rem est a maiores! </p> </div> </div> ); })} </div> </div> <div className="p-5"> <Input placeholder="send message" /> </div> </div> </div> <InitUser user={user} /> {/* user state 관리를 시작할 수 있도록. */} </> ); }; export default page;
ChatHeader.tsx
"use client"; import React from "react"; import { Button } from "./ui/button"; import { createClient } from "@/utils/supabase/client"; import { User } from "@supabase/supabase-js"; import { useRouter } from "next/navigation"; // 주의할 점. next/navigation에서 임포트한다. const ChatHeader = ({ user }: { user: User | null }) => { const router = useRouter(); // props로 UserResponse를 받는다. const handleLoginWithGithub = () => { const supabase = createClient(); supabase.auth.signInWithOAuth({ provider: "github", options: { redirectTo: location.origin + "/auth/callback", }, }); }; const handleLogout = async () => { const supabase = createClient(); await supabase.auth.signOut(); // const { error } = await supabase.auth.signOut(); router.refresh(); }; return ( <div className="h-20"> <div className="p-5 border-b flex items-center justify-between h-full"> <div> <h1 className="text-xl font-bold">Daily Chat</h1> <div className="flex items-center gap-1"> <div className="h-4 w-4 bg-green-500 rounded-full animate-pulse"></div> <h1 className="text-sm text-gray-400">2 Online</h1> </div> </div> {user ? ( // user가 있으면 (로그인했으면) 로그아웃 버튼 표시, 없으면 (로그인 안했으면) 로그인 버튼 표시 <Button onClick={handleLogout}>Logout</Button> ) : ( <Button onClick={handleLoginWithGithub}>Login</Button> )} </div> </div> ); }; export default ChatHeader;
Github : https://github.com/Wunhyeon/Next-Supabase-Chat/tree/4.ChatUI
'사이드프로젝트' 카테고리의 다른 글
6. 메세지 리스트 표시하기 (4) 2024.07.22 5. Message 보내기. - 메세지 테이블 만들기, Policy 생성, type 생성 (8) 2024.07.22 NextJS + Supabase 채팅 앱 만들기 - 3. 로그아웃, 유저 상태관리 (Zustand), OAuth User생성 Trigger를 통해 public Schema에도 유저 생성해주기 (1) 2024.07.22 NextJS + Supabase 채팅 앱 만들기 - 2. Supabase 기본설정 + Github Oauth 로그인 1 (0) 2024.07.20 NextJS + Supabase 채팅 앱 만들기 - 1. 기본 설정 + 첫 페이지 (0) 2024.07.19