113 lines
4.4 KiB
TypeScript
113 lines
4.4 KiB
TypeScript
"use client";
|
|
|
|
import { useGetAbout } from "@/app/[name]/(Main)/about/hooks/useAboutData";
|
|
import { useGetProfile } from "@/app/[name]/(Profile)/profile/hooks/userProfileData";
|
|
import { glassSurfaceFlat } from "@/lib/styles/glassSurface";
|
|
import { Send2 } from "iconsax-react";
|
|
import Image from "next/image";
|
|
import { FormEvent, useState } from "react";
|
|
import { useTranslation } from "react-i18next";
|
|
import { AI_SUGGESTIONS } from "./suggestions";
|
|
|
|
type Message = {
|
|
id: string;
|
|
role: "user" | "assistant";
|
|
content: string;
|
|
};
|
|
|
|
function getGreetingKey() {
|
|
const hour = new Date().getHours();
|
|
if (hour >= 5 && hour < 12) return "morning";
|
|
if (hour >= 12 && hour < 14) return "noon";
|
|
if (hour >= 14 && hour < 17) return "afternoon";
|
|
return "evening";
|
|
}
|
|
|
|
function AiPage() {
|
|
const { t } = useTranslation("common", { keyPrefix: "AI" });
|
|
const { data: about } = useGetAbout();
|
|
const { data: profile, isSuccess } = useGetProfile();
|
|
|
|
const [input, setInput] = useState("");
|
|
const [messages, setMessages] = useState<Message[]>([]);
|
|
|
|
const restaurant = about?.data;
|
|
const brandName = restaurant?.name || t("BrandFallback");
|
|
const logoUrl = restaurant?.logo || "/assets/images/danak-logo.png";
|
|
const userName = isSuccess && profile?.data?.firstName ? profile.data.firstName : t("GuestName");
|
|
|
|
const sendMessage = (text: string) => {
|
|
const content = text.trim();
|
|
if (!content) return;
|
|
|
|
setMessages((prev) => [...prev, { id: `u-${Date.now()}`, role: "user", content }, { id: `a-${Date.now()}`, role: "assistant", content: t("MockReply") }]);
|
|
setInput("");
|
|
};
|
|
|
|
const onSubmit = (e: FormEvent<HTMLFormElement>) => {
|
|
e.preventDefault();
|
|
sendMessage(input);
|
|
};
|
|
|
|
return (
|
|
<section className="flex h-[calc(100svh-6.5rem)] flex-col pt-4 xl:h-[calc(100svh-6rem)]">
|
|
<h1 className="shrink-0 text-center text-sm2 font-medium">{t("Heading")}</h1>
|
|
|
|
<div className="mt-6 flex min-h-0 flex-1 flex-col">
|
|
{messages.length > 0 ? (
|
|
<ul className="noscrollbar flex-1 space-y-3 overflow-y-auto pb-4">
|
|
{messages.map((message) => (
|
|
<li
|
|
key={message.id}
|
|
className={message.role === "user" ? "rounded-[20px] rounded-tr-none bg-[#F6F7FA] p-4 dark:bg-gray-700" : "rounded-[20px] rounded-tl-none bg-[#EBEDF5] p-4 dark:bg-gray-600"}
|
|
>
|
|
<p className="text-xs2 leading-5">{message.content}</p>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
) : (
|
|
<div className="flex flex-1 flex-col items-center justify-center gap-8">
|
|
<div className="flex flex-col items-center gap-2">
|
|
<Image src={"/assets/images/logo_ai.svg"} alt={brandName} width={299} height={299} className="w-74.75 h-auto" unoptimized />
|
|
</div>
|
|
|
|
<div className="flex w-full flex-col items-center gap-4">
|
|
<h2 className="text-base font-medium">{t(`Greeting.${getGreetingKey()}`, { name: userName })}</h2>
|
|
|
|
<div className="flex w-full flex-wrap gap-2">
|
|
{AI_SUGGESTIONS.map(({ labelKey, icon: Icon }) => (
|
|
<button
|
|
key={labelKey}
|
|
type="button"
|
|
onClick={() => sendMessage(t(labelKey))}
|
|
className={glassSurfaceFlat("inline-flex items-center gap-1.5 rounded-lg px-3 py-1.5 transition-[filter] active:brightness-95")}
|
|
>
|
|
<Icon size={15} className="stroke-foreground" variant="Bold" />
|
|
<span className="text-xs2">{t(labelKey)}</span>
|
|
</button>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
|
|
<form onSubmit={onSubmit} className={glassSurfaceFlat("mt-3 flex h-12 shrink-0 items-center gap-1 rounded-xl border border-border px-3")}>
|
|
<input
|
|
value={input}
|
|
onChange={(e) => setInput(e.target.value)}
|
|
placeholder={t("InputPlaceholder")}
|
|
autoComplete="off"
|
|
className="h-full w-full bg-transparent text-[11px] outline-none placeholder:text-disabled-text"
|
|
/>
|
|
|
|
<button type="submit" disabled={!input.trim()} className="rounded-full p-1.5 disabled:opacity-40">
|
|
<Send2 size={20} variant="Bold" className="fill-primary text-primary dark:fill-foreground dark:text-foreground" />
|
|
</button>
|
|
</form>
|
|
</div>
|
|
</section>
|
|
);
|
|
}
|
|
|
|
export default AiPage;
|