forked from aws-samples/amplify-next-template
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #269 from cabcookie:add-ai-features
Implementiere einen einfachen Chatbot ohne Spezialwissen
- Loading branch information
Showing
10 changed files
with
1,544 additions
and
1,314 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
import { cn } from "@/lib/utils"; | ||
import { FC } from "react"; | ||
|
||
interface ConversationNameProps { | ||
name?: string; | ||
className?: string; | ||
} | ||
|
||
const ConversationName: FC<ConversationNameProps> = ({ name, className }) => ( | ||
<h2 | ||
className={cn( | ||
"text-xl md:text-2xl md:text-center font-semibold", | ||
className | ||
)} | ||
> | ||
{name || "New chat"} | ||
</h2> | ||
); | ||
|
||
export default ConversationName; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { FC } from "react"; | ||
|
||
interface ErrorsProps { | ||
hasError?: boolean; | ||
errors?: { message?: string }[]; | ||
} | ||
|
||
const Errors: FC<ErrorsProps> = ({ hasError, errors }) => | ||
hasError && | ||
errors?.map((error, index) => ( | ||
<div key={index} className="text-sm p-2 text-red-600 font-semibold"> | ||
{error.message} | ||
</div> | ||
)); | ||
|
||
export default Errors; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { User } from "@/api/useUser"; | ||
import { ConversationMessage } from "@aws-amplify/ui-react-ai"; | ||
import { FC } from "react"; | ||
import ReactMarkdown from "react-markdown"; | ||
import MessageAvatar from "./MessageAvatar"; | ||
|
||
interface MessageProps { | ||
message: ConversationMessage & { isLoading?: boolean }; | ||
user?: User; | ||
} | ||
|
||
const Message: FC<MessageProps> = ({ message, user }) => ( | ||
<div key={message.id} className="w-full space-y-4"> | ||
<MessageAvatar | ||
messageDate={message.createdAt} | ||
role={message.role} | ||
user={user} | ||
/> | ||
|
||
{message.content.map((content, index) => ( | ||
<ReactMarkdown key={index}>{content.text}</ReactMarkdown> | ||
))} | ||
</div> | ||
); | ||
|
||
export default Message; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
import { User } from "@/api/useUser"; | ||
import { differenceInHours, format, formatDistanceToNow } from "date-fns"; | ||
import { Bot } from "lucide-react"; | ||
import { FC } from "react"; | ||
import CircleProfileImg from "../profile/CircleProfileImg"; | ||
|
||
interface MessageAvatarProps { | ||
user?: User; | ||
role: "user" | "assistant"; | ||
messageDate: string | Date; | ||
} | ||
|
||
const MessageAvatar: FC<MessageAvatarProps> = ({ user, role, messageDate }) => ( | ||
<div className="flex flex-row gap-2 items-center"> | ||
{role === "user" ? ( | ||
<CircleProfileImg user={user} fallbackInitials="US" className="w-8 h-8" /> | ||
) : ( | ||
<div className="w-8 h-8 rounded-full bg-[--context-color] p-1"> | ||
<Bot className="w-6 h-6 text-slate-600" /> | ||
</div> | ||
)} | ||
|
||
<div className="flex flex-row gap-2 items-baseline"> | ||
<div className="font-semibold"> | ||
{role === "user" ? (user?.userName ?? "User") : "Assistant"} | ||
</div> | ||
<div className="text-muted-foreground text-xs"> | ||
{differenceInHours(new Date(), messageDate) < 4 | ||
? formatDistanceToNow(messageDate, { addSuffix: true }) | ||
: format(messageDate, "p")} | ||
</div> | ||
</div> | ||
</div> | ||
); | ||
|
||
export default MessageAvatar; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
import { cn } from "@/lib/utils"; | ||
import { | ||
format, | ||
isSameISOWeek, | ||
isToday, | ||
isYesterday, | ||
startOfToday, | ||
} from "date-fns"; | ||
import { FC } from "react"; | ||
|
||
interface MessageDateProps { | ||
date: string | Date; | ||
className?: string; | ||
} | ||
|
||
const MessageDate: FC<MessageDateProps> = ({ date, className }) => ( | ||
<div className={cn(className)}> | ||
{isToday(date) | ||
? "Today" | ||
: isYesterday(date) | ||
? "Yesterday" | ||
: format(date, isSameISOWeek(date, startOfToday()) ? "eeee" : "PPP")} | ||
</div> | ||
); | ||
|
||
export default MessageDate; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,50 @@ | ||
import { cn } from "@/lib/utils"; | ||
import { JSONContent } from "@tiptap/core"; | ||
import { ArrowUp } from "lucide-react"; | ||
import { FC, useState } from "react"; | ||
import { emptyDocument } from "../ui-elements/editors/helpers/document"; | ||
import { getTextFromJsonContent } from "../ui-elements/editors/helpers/text-generation"; | ||
import InboxEditor from "../ui-elements/editors/inbox-editor/InboxEditor"; | ||
import { Button } from "../ui/button"; | ||
|
||
interface MessageInputProps { | ||
id: string; | ||
onSend: (prompt: string) => void; | ||
className?: string; | ||
} | ||
|
||
const MessageInput: FC<MessageInputProps> = ({ id, onSend, className }) => { | ||
const [prompt, setPrompt] = useState<JSONContent>(emptyDocument); | ||
|
||
const handleSend = () => { | ||
onSend(getTextFromJsonContent(prompt)); | ||
setPrompt(emptyDocument); | ||
}; | ||
|
||
return ( | ||
<div className={cn(className)}> | ||
<div className="w-full h-8 bg-gradient-to-t from-background/95 via-background/80 to-background/0" /> | ||
|
||
<div className="relativ bg-white/95 pb-2"> | ||
<InboxEditor | ||
key={id} | ||
notes={prompt} | ||
saveNotes={(editor) => setPrompt(editor.getJSON())} | ||
autoFocus | ||
placeholder="Send a message" | ||
saveAtCmdEnter={handleSend} | ||
showSaveStatus={false} | ||
className="pb-12 max-h-60 md:max-h-80 overflow-y-auto" | ||
/> | ||
<Button | ||
className="rounded-full w-10 h-10 absolute bottom-3 right-1" | ||
onClick={handleSend} | ||
> | ||
<ArrowUp /> | ||
</Button> | ||
</div> | ||
</div> | ||
); | ||
}; | ||
|
||
export default MessageInput; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,45 @@ | ||
import useCurrentUser from "@/api/useUser"; | ||
import { ConversationMessage } from "@aws-amplify/ui-react-ai"; | ||
import { format } from "date-fns"; | ||
import { flow, identity, map, uniq } from "lodash/fp"; | ||
import { FC, useEffect, useState } from "react"; | ||
import Message from "./Message"; | ||
import MessageDate from "./MessageDate"; | ||
|
||
interface MessagesProps { | ||
messages: ConversationMessage[]; | ||
} | ||
|
||
const Messages: FC<MessagesProps> = ({ messages }) => { | ||
const [messageDates, setMessageDates] = useState<string[]>([]); | ||
const { user } = useCurrentUser(); | ||
|
||
useEffect(() => { | ||
flow( | ||
identity<typeof messages>, | ||
map("createdAt"), | ||
map((date) => format(date, "yyyy-MM-dd")), | ||
uniq, | ||
setMessageDates | ||
)(messages); | ||
}, [messages]); | ||
|
||
return messageDates?.map((date) => ( | ||
<div key={date} className="flex flex-col items-center space-y-2"> | ||
<MessageDate | ||
date={date} | ||
className="flex text-center text-xs text-muted-foreground bg-bgTransparent w-fit rounded-xl py-0.5 px-2 sticky top-[8rem] md:top-[7rem]" | ||
/> | ||
|
||
<div className="space-y-8"> | ||
{messages | ||
.filter((m) => format(m.createdAt, "yyyy-MM-dd") === date) | ||
.map((message) => ( | ||
<Message key={message.id} message={message} user={user} /> | ||
))} | ||
</div> | ||
</div> | ||
)); | ||
}; | ||
|
||
export default Messages; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.