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 src/domains/recommend/components/ChatList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ function ChatList({ messages, userCurrentStep, onSelectedOption }: ChatListProps
<div
ref={chatListRef}
onScroll={handleCheckBottom}
className="absolute top-0 left-0 bottom-18 sm:bottom-21 w-full gap-5 px-3 pt-12 pb-4 flex flex-col items-center overflow-y-auto pr-2"
className="absolute top-8 left-0 bottom-18 sm:bottom-21 w-full gap-5 px-3 pt-7 pb-4 flex flex-col items-center overflow-y-auto pr-2"
>
<div className="max-w-1024 w-full flex flex-col gap-5">
{messages.map((msg, i) => {
Expand Down
7 changes: 6 additions & 1 deletion src/domains/recommend/components/ChatSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import MessageInput from './user/MessageInput';
import { fetchSendStepMessage, fetchSendTextMessage } from '../api/chat';
import { ChatMessage, stepPayload } from '../types/recommend';
import ChatList from './ChatList';
import { useChatInit } from '../hook/useChatInit';
import { useSelectedOptions } from '../hook/useSelectedOptions';
import { useAuthStore } from '@/domains/shared/store/auth';
import { useChatInit } from '../hook/useChatInit';
import { useChatWarning } from '../hook/useChatWarning';

function ChatSection() {
const [messages, setMessages] = useState<ChatMessage[]>([]);
Expand Down Expand Up @@ -121,10 +122,14 @@ function ChatSection() {
};

useChatInit(setMessages);
useChatWarning(messages);

return (
<section className="relative flex-1 flex flex-col items-center w-full">
<h2 className="sr-only">대화 목록 및 입력 창</h2>
<div className="p-2 text-white/80 text-sm text-center">
⚠️ 페이지를 벗어나면 채팅내용이 사라집니다.
</div>
<ChatList
messages={messages}
userCurrentStep={userCurrentStep}
Expand Down
15 changes: 7 additions & 8 deletions src/domains/recommend/components/bot/BotCocktailCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,15 @@ import Link from 'next/link';
import Keep from '@/domains/shared/components/keep/Keep';
import { RecommendationItem } from '../../types/recommend';

function BotCocktailCard({
cocktailId,
cocktailName,
cocktailNameKo,
cocktailImgUrl,
alcoholStrength,
}: RecommendationItem) {
function BotCocktailCard({ cocktailId, cocktailNameKo, cocktailImgUrl }: RecommendationItem) {
return (
<div className="relative flex flex-col w-full min-w-[200px] rounded-2xl overflow-hidden bg-white shadow-[0_0_12px_rgba(255,255,255,0.4)]">
<Link href="/" className="block relative">
<Link
href={`/recipe/${cocktailId}`}
target="_blank"
rel="noopener noreferrer"
className="block relative"
>
<div className="relative w-full h-[200px]">
<Image
src={cocktailImgUrl}
Expand Down
2 changes: 1 addition & 1 deletion src/domains/recommend/components/user/MessageInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ function MessageInput({ onSubmit, disabled }: Props) {
id="chatInput"
name="chatInput"
onInput={(e) => resizeTextarea(e.currentTarget)}
placeholder={disabled ? '옵션을 선택해주세요.' : '칵테일 추천 질문을 입력해주세요.'}
placeholder={disabled ? '옵션 선택' : '칵테일 추천 질문 입력'}
disabled={disabled}
className={`
w-[calc(100%-3rem)] md:w-[calc(100%-3.75rem)] px-4 py-2 md:py-3.5
Expand Down
16 changes: 5 additions & 11 deletions src/domains/recommend/hook/useChatInit.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,18 @@

import { useEffect } from 'react';
import { ChatMessage } from '../types/recommend';
import { fetchChatHistory, fetchGreeting } from '../api/chat';
import { fetchGreeting } from '../api/chat';

// 채팅 기록 불러오기 없으면 greeting api 호출
export function useChatInit(setMessages: React.Dispatch<React.SetStateAction<ChatMessage[]>>) {
useEffect(() => {
const loadChatHistory = async () => {
const loadGreeting = async () => {
try {
const history = await fetchChatHistory();
if (history && history.length > 0) {
setMessages(history.sort((a, b) => Number(a.id) - Number(b.id)));
} else {
const greeting = await fetchGreeting('');
if (greeting) setMessages([greeting]);
}
const greeting = await fetchGreeting('');
if (greeting) setMessages([greeting]);
} catch (err) {
console.error('채팅 초기화 실패:', err);
}
};
loadChatHistory();
loadGreeting();
}, [setMessages]);
}
18 changes: 18 additions & 0 deletions src/domains/recommend/hook/useChatWarning.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
'use client';

import { useEffect } from 'react';
import { ChatMessage } from '../types/recommend';

export function useChatWarning(messages: ChatMessage[]) {
useEffect(() => {
const handleBeforeUnload = (e: BeforeUnloadEvent) => {
if (messages.length > 0) {
e.preventDefault();
e.returnValue = '';
}
};

window.addEventListener('beforeunload', handleBeforeUnload);
return () => window.removeEventListener('beforeunload', handleBeforeUnload);
}, [messages]);
}
4 changes: 2 additions & 2 deletions src/domains/recommend/types/recommend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ export interface StepOption {

export interface RecommendationItem {
cocktailId: number;
cocktailName: string;
cocktailName?: string;
cocktailNameKo: string;
cocktailImgUrl: string;
alcoholStrength: string;
alcoholStrength?: string;
}

export interface StepRecommendation {
Expand Down