Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>MBTips</title>
<title>MBTips_MBTI AI 대화 시뮬레이션</title>
</head>
<body>
<div id="root"></div>
Expand Down
45 changes: 42 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-ga4": "^2.1.0",
"react-helmet": "^6.1.0",
"react-router-dom": "^7.1.5",
"tailwindcss": "^4.0.3",
"zustand": "^5.0.3"
Expand All @@ -27,6 +28,7 @@
"@types/node": "^22.13.13",
"@types/react": "^18.3.18",
"@types/react-dom": "^18.3.5",
"@types/react-helmet": "^6.1.11",
"@vitejs/plugin-react": "^4.3.4",
"eslint": "^9.19.0",
"eslint-config-prettier": "^10.0.1",
Expand Down
Binary file added public/image/og_image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
useLocation
} from "react-router-dom";
import { initGA, trackPageView } from "@/libs/analytics";
import { Helmet } from "react-helmet";
import Home from "@/pages/Home";
import SelectInfo from "@/pages/SelectInfo";
import Chat from "@/pages/Chat";
Expand Down Expand Up @@ -102,6 +103,18 @@ const App = () => {
onClose={() => setToastMessage("")}
/>
)}

<Helmet>
<meta property="og:title" content="MBTips_MBTI AI 대화 시뮬레이션" />
<meta property="og:image" content="%PUBLIC_URL%/image/og_image.png" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content="MBTips_MBTI AI 대화 시뮬레이션" />
<meta
property="twitter:image"
content="%PUBLIC_URL%/image/og_image.png"
/>
</Helmet>

<Routes>
<Route path="/" element={<Home />} />
<Route path="/select-info" element={<SelectInfo />} />
Expand Down
93 changes: 51 additions & 42 deletions src/pages/Chat.tsx
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
import { useEffect, useRef, useState, ChangeEvent, KeyboardEvent } from "react";
import { useLocation } from "react-router-dom";
import { Helmet } from "react-helmet";
import { authInstance } from "@/api/axios";
import { trackEvent } from "@/libs/analytics";
import IntroGuide from "@/components/IntroGuide";
import Header from "@/components/header/Header";
import ChatMessage from "@/components/ChatMessage";
import ChatActionBar from "@/components/ChatActionBar";
import TipsMenuContainer from "@/components/tips/TipsMenuContainer";
import pickMbtiImage from "@/utils/pickMbtiImage";
import { authInstance } from "@/api/axios";
import { trackEvent } from "@/libs/analytics";

interface Message {
role: "user" | "assistant";
Expand Down Expand Up @@ -135,49 +136,57 @@ const Chat = () => {
};

return (
<div className="flex h-screen w-[360px] flex-col bg-white md:w-[375px] lg:w-[500px]">
<Header title={chatTitle} showShareIcon={false} />

<div className="flex-1 space-y-4 overflow-y-auto px-[20px] pt-6">
<IntroGuide />
{/* 메시지 리스트 */}
{messages.map((msg, idx) => (
<div
key={idx}
className={`flex ${msg.role === "user" ? "justify-end" : "justify-start"} items-start`}
>
{/* 캐릭터 아이콘 */}
{msg.role === "assistant" && (
<img
src={assistantImgUrl}
alt="MBTI ICON"
className="mr-[9px] h-[36px] w-[36px] shrink-0 rounded-full border border-gray-200 object-cover"
/>
)}
{/* 채팅 메시지 */}
<div className="mt-3.5">
<ChatMessage
message={msg.content}
myMessage={msg.role === "user"}
/>
<>
<Helmet>
<meta name="description" content={`${mbti}와의 대화창`} />
<meta property="og:description" content={`${mbti}와의 대화창`} />
<meta property="twitter:description" content={`${mbti}와의 대화창`} />
</Helmet>

<div className="flex h-screen w-[360px] flex-col bg-white md:w-[375px] lg:w-[500px]">
<Header title={chatTitle} showShareIcon={false}/>

<div className="flex-1 space-y-4 overflow-y-auto px-[20px] pt-6">
<IntroGuide />
{/* 메시지 리스트 */}
{messages.map((msg, idx) => (
<div
key={idx}
className={`flex ${msg.role === "user" ? "justify-end" : "justify-start"} items-start`}
>
{/* 캐릭터 아이콘 */}
{msg.role === "assistant" && (
<img
src={assistantImgUrl}
alt="MBTI ICON"
className="mr-[9px] h-[36px] w-[36px] shrink-0 rounded-full border border-gray-200 object-cover"
/>
)}
{/* 채팅 메시지 */}
<div className="mt-3.5">
<ChatMessage
message={msg.content}
myMessage={msg.role === "user"}
/>
</div>
</div>
</div>
))}
))}

<div ref={bottomRef} />
</div>
<div ref={bottomRef} />
</div>

<ChatActionBar
isOpen={isOpen}
setIsOpen={handleToggleTips}
value={input}
onChange={handleChange}
onKeyUp={handleKeyup}
onSend={() => handleSend(input)}
/>

<ChatActionBar
isOpen={isOpen}
setIsOpen={handleToggleTips}
value={input}
onChange={handleChange}
onKeyUp={handleKeyup}
onSend={() => handleSend(input)}
/>

{isOpen && <TipsMenuContainer conversationId={id} mbti={mbti} />}
</div>
{isOpen && <TipsMenuContainer conversationId={id} mbti={mbti} />}
</div>
</>
);
};

Expand Down
39 changes: 24 additions & 15 deletions src/pages/ChatRecommend.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { useParams } from "react-router-dom";
import { Helmet } from "react-helmet";
import { Mbti } from "@/types/mbti";
import { chatRecommend } from "@/mock/chatRecommend";
import Header from "@/components/header/Header";
Expand All @@ -18,22 +19,30 @@ const ChatRecommend = () => {
} else return <Error statusCode="404" />;

return (
<div>
<Header
title="대화 주제 추천"
showPreviousIcon={true}
showShareIcon={true}
/>
<main className="mx-auto flex h-screen flex-col px-5 py-6">
<img
src={mbtiImage}
alt="mbti 이미지"
className="h-auto w-full rounded-2xl"
<>
<Helmet>
<meta name="description" content="대화 주제 추천" />
<meta property="og:description" content="대화 주제 추천" />
<meta property="twitter:description" content="대화 주제 추천" />
</Helmet>

<div>
<Header
title="대화 주제 추천"
showPreviousIcon={true}
showShareIcon={true}
/>
<h1 className="mt-9 text-xl font-bold">{title}</h1>
<span className="mt-6 whitespace-pre-wrap">{description}</span>
</main>
</div>
<main className="mx-auto flex h-screen flex-col px-5 py-6">
<img
src={mbtiImage}
alt="mbti 이미지"
className="h-auto w-full rounded-2xl"
/>
<h1 className="mt-9 text-xl font-bold">{title}</h1>
<span className="mt-6 whitespace-pre-wrap">{description}</span>
</main>
</div>
</>
);
};

Expand Down
55 changes: 34 additions & 21 deletions src/pages/ChatTemperature.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { useEffect, useState } from "react";
import { useParams } from "react-router-dom";
import { Helmet } from "react-helmet";
import instance from "@/api/axios";
import Header from "@/components/header/Header";

Expand Down Expand Up @@ -31,28 +32,40 @@ const ChatTemperature = () => {
}, []);

return (
<div>
<Header title="대화 온도" showPreviousIcon={true} showShareIcon={true} />
<main className="mx-auto flex h-screen flex-col px-5 py-6">
<img
src={"/image/image_온도.png"}
alt="mbti 온도 이미지"
className="h-auto w-full rounded-2xl"
<>
<Helmet>
<meta name="description" content="대화의 온도" />
<meta property="og:description" content="대화의 온도" />
<meta property="twitter:description" content="대화의 온도" />
</Helmet>

<div>
<Header
title="대화 온도"
showPreviousIcon={true}
showShareIcon={true}
/>
<h1 className="mt-9 text-xl font-bold">
방금까지 나눈 대화로 온도를 측정했어요!
</h1>
{temperature ? (
<span className="mt-6 whitespace-pre-wrap">
현재까지 나눈 대화의 온도는 {temperature}도에요
</span>
) : (
<span className="mt-6 whitespace-pre-wrap">
...대화의 온도를 불러오는 중
</span>
)}
</main>
</div>
<main className="mx-auto flex h-screen flex-col px-5 py-6">
<img
src={"/image/image_온도.png"}
alt="mbti 온도 이미지"
className="h-auto w-full rounded-2xl"
/>
<h1 className="mt-9 text-xl font-bold">
방금까지 나눈 대화로 온도를 측정했어요!
</h1>
{temperature ? (
<span className="mt-6 whitespace-pre-wrap">
현재까지 나눈 대화의 온도는 {temperature}도에요
</span>
) : (
<span className="mt-6 whitespace-pre-wrap">
...대화의 온도를 불러오는 중
</span>
)}
</main>
</div>
</>
);
};

Expand Down
Loading