From 93b797c1621a5f9e88fdd0bdd13284b116729ade Mon Sep 17 00:00:00 2001
From: Thuc Pham <51660321+thucpn@users.noreply.github.com>
Date: Mon, 10 Jun 2024 17:02:25 +0700
Subject: [PATCH] refactor: structure fe components (#121)

---
 .../ui/html/chat/{ => hooks}/use-config.ts    |  0
 .../types/streaming/express/package.json      |  2 +-
 .../nextjs/app/components/chat-section.tsx    |  2 +-
 .../app/components/ui/chat/chat-input.tsx     | 24 +++++++++++--------
 .../chat/{ => chat-message}/chat-avatar.tsx   |  0
 .../chat/{ => chat-message}/chat-events.tsx   |  6 ++---
 .../ui/chat/{ => chat-message}/chat-image.tsx |  2 +-
 .../chat/{ => chat-message}/chat-sources.tsx  | 14 +++++++----
 .../ui/chat/{ => chat-message}/chat-tools.tsx |  4 ++--
 .../ui/chat/{ => chat-message}/codeblock.tsx  |  4 ++--
 .../chat/{ => chat-message}/csv-content.tsx   |  4 ++--
 .../index.tsx}                                | 18 +++++++-------
 .../ui/chat/{ => chat-message}/markdown.tsx   |  0
 .../app/components/ui/chat/chat-messages.tsx  |  2 +-
 .../ui/chat/{ => hooks}/use-config.ts         |  0
 .../{ => hooks}/use-copy-to-clipboard.tsx     |  0
 .../components/ui/chat/{ => hooks}/use-csv.ts |  2 +-
 17 files changed, 46 insertions(+), 38 deletions(-)
 rename templates/components/ui/html/chat/{ => hooks}/use-config.ts (100%)
 rename templates/types/streaming/nextjs/app/components/ui/chat/{ => chat-message}/chat-avatar.tsx (100%)
 rename templates/types/streaming/nextjs/app/components/ui/chat/{ => chat-message}/chat-events.tsx (92%)
 rename templates/types/streaming/nextjs/app/components/ui/chat/{ => chat-message}/chat-image.tsx (88%)
 rename templates/types/streaming/nextjs/app/components/ui/chat/{ => chat-message}/chat-sources.tsx (91%)
 rename templates/types/streaming/nextjs/app/components/ui/chat/{ => chat-message}/chat-tools.tsx (86%)
 rename templates/types/streaming/nextjs/app/components/ui/chat/{ => chat-message}/codeblock.tsx (97%)
 rename templates/types/streaming/nextjs/app/components/ui/chat/{ => chat-message}/csv-content.tsx (75%)
 rename templates/types/streaming/nextjs/app/components/ui/chat/{chat-message.tsx => chat-message/index.tsx} (96%)
 rename templates/types/streaming/nextjs/app/components/ui/chat/{ => chat-message}/markdown.tsx (100%)
 rename templates/types/streaming/nextjs/app/components/ui/chat/{ => hooks}/use-config.ts (100%)
 rename templates/types/streaming/nextjs/app/components/ui/chat/{ => hooks}/use-copy-to-clipboard.tsx (100%)
 rename templates/types/streaming/nextjs/app/components/ui/chat/{ => hooks}/use-csv.ts (95%)

diff --git a/templates/components/ui/html/chat/use-config.ts b/templates/components/ui/html/chat/hooks/use-config.ts
similarity index 100%
rename from templates/components/ui/html/chat/use-config.ts
rename to templates/components/ui/html/chat/hooks/use-config.ts
diff --git a/templates/types/streaming/express/package.json b/templates/types/streaming/express/package.json
index b77c2e43..667ecc47 100644
--- a/templates/types/streaming/express/package.json
+++ b/templates/types/streaming/express/package.json
@@ -7,7 +7,7 @@
     "format:write": "prettier --ignore-unknown --write .",
     "build": "tsup index.ts --format cjs --dts",
     "start": "node dist/index.js",
-    "dev": "concurrently \"tsup index.ts --format cjs --dts --watch\" \"nodemon -q dist/index.js\""
+    "dev": "concurrently \"tsup index.ts --format cjs --dts --watch\" \"nodemon --watch dist/index.js\""
   },
   "dependencies": {
     "ai": "^3.0.21",
diff --git a/templates/types/streaming/nextjs/app/components/chat-section.tsx b/templates/types/streaming/nextjs/app/components/chat-section.tsx
index 9a4ea6b9..5703660e 100644
--- a/templates/types/streaming/nextjs/app/components/chat-section.tsx
+++ b/templates/types/streaming/nextjs/app/components/chat-section.tsx
@@ -2,7 +2,7 @@
 
 import { useChat } from "ai/react";
 import { ChatInput, ChatMessages } from "./ui/chat";
-import { useClientConfig } from "./ui/chat/use-config";
+import { useClientConfig } from "./ui/chat/hooks/use-config";
 
 export default function ChatSection() {
   const { chatAPI } = useClientConfig();
diff --git a/templates/types/streaming/nextjs/app/components/ui/chat/chat-input.tsx b/templates/types/streaming/nextjs/app/components/ui/chat/chat-input.tsx
index 8ee4ec37..8a377b49 100644
--- a/templates/types/streaming/nextjs/app/components/ui/chat/chat-input.tsx
+++ b/templates/types/streaming/nextjs/app/components/ui/chat/chat-input.tsx
@@ -8,7 +8,7 @@ import { Input } from "../input";
 import UploadCsvPreview from "../upload-csv-preview";
 import UploadImagePreview from "../upload-image-preview";
 import { ChatHandler } from "./chat.interface";
-import { useCsv } from "./use-csv";
+import { useCsv } from "./hooks/use-csv";
 
 export default function ChatInput(
   props: Pick<
@@ -81,23 +81,27 @@ export default function ChatInput(
 
   const onRemovePreviewImage = () => setImageUrl(null);
 
-  const handleUploadImageFile = async (file: File) => {
-    const base64 = await new Promise<string>((resolve, reject) => {
+  const readContent = async (file: File): Promise<string> => {
+    const content = await new Promise<string>((resolve, reject) => {
       const reader = new FileReader();
-      reader.readAsDataURL(file);
+      if (file.type.startsWith("image/")) {
+        reader.readAsDataURL(file);
+      } else {
+        reader.readAsText(file);
+      }
       reader.onload = () => resolve(reader.result as string);
       reader.onerror = (error) => reject(error);
     });
+    return content;
+  };
+
+  const handleUploadImageFile = async (file: File) => {
+    const base64 = await readContent(file);
     setImageUrl(base64);
   };
 
   const handleUploadCsvFile = async (file: File) => {
-    const content = await new Promise<string>((resolve, reject) => {
-      const reader = new FileReader();
-      reader.readAsText(file);
-      reader.onload = () => resolve(reader.result as string);
-      reader.onerror = (error) => reject(error);
-    });
+    const content = await readContent(file);
     const isSuccess = upload({
       id: uuidv4(),
       content,
diff --git a/templates/types/streaming/nextjs/app/components/ui/chat/chat-avatar.tsx b/templates/types/streaming/nextjs/app/components/ui/chat/chat-message/chat-avatar.tsx
similarity index 100%
rename from templates/types/streaming/nextjs/app/components/ui/chat/chat-avatar.tsx
rename to templates/types/streaming/nextjs/app/components/ui/chat/chat-message/chat-avatar.tsx
diff --git a/templates/types/streaming/nextjs/app/components/ui/chat/chat-events.tsx b/templates/types/streaming/nextjs/app/components/ui/chat/chat-message/chat-events.tsx
similarity index 92%
rename from templates/types/streaming/nextjs/app/components/ui/chat/chat-events.tsx
rename to templates/types/streaming/nextjs/app/components/ui/chat/chat-message/chat-events.tsx
index af306768..3dfad75d 100644
--- a/templates/types/streaming/nextjs/app/components/ui/chat/chat-events.tsx
+++ b/templates/types/streaming/nextjs/app/components/ui/chat/chat-message/chat-events.tsx
@@ -1,12 +1,12 @@
 import { ChevronDown, ChevronRight, Loader2 } from "lucide-react";
 import { useState } from "react";
-import { Button } from "../button";
+import { Button } from "../../button";
 import {
   Collapsible,
   CollapsibleContent,
   CollapsibleTrigger,
-} from "../collapsible";
-import { EventData } from "./index";
+} from "../../collapsible";
+import { EventData } from "../index";
 
 export function ChatEvents({
   data,
diff --git a/templates/types/streaming/nextjs/app/components/ui/chat/chat-image.tsx b/templates/types/streaming/nextjs/app/components/ui/chat/chat-message/chat-image.tsx
similarity index 88%
rename from templates/types/streaming/nextjs/app/components/ui/chat/chat-image.tsx
rename to templates/types/streaming/nextjs/app/components/ui/chat/chat-message/chat-image.tsx
index 05609213..2de28c3d 100644
--- a/templates/types/streaming/nextjs/app/components/ui/chat/chat-image.tsx
+++ b/templates/types/streaming/nextjs/app/components/ui/chat/chat-message/chat-image.tsx
@@ -1,5 +1,5 @@
 import Image from "next/image";
-import { type ImageData } from "./index";
+import { type ImageData } from "../index";
 
 export function ChatImage({ data }: { data: ImageData }) {
   return (
diff --git a/templates/types/streaming/nextjs/app/components/ui/chat/chat-sources.tsx b/templates/types/streaming/nextjs/app/components/ui/chat/chat-message/chat-sources.tsx
similarity index 91%
rename from templates/types/streaming/nextjs/app/components/ui/chat/chat-sources.tsx
rename to templates/types/streaming/nextjs/app/components/ui/chat/chat-message/chat-sources.tsx
index eb51b9aa..a4366436 100644
--- a/templates/types/streaming/nextjs/app/components/ui/chat/chat-sources.tsx
+++ b/templates/types/streaming/nextjs/app/components/ui/chat/chat-message/chat-sources.tsx
@@ -1,10 +1,14 @@
 import { Check, Copy } from "lucide-react";
 import { useMemo } from "react";
-import { Button } from "../button";
-import { HoverCard, HoverCardContent, HoverCardTrigger } from "../hover-card";
-import { SourceData } from "./index";
-import { useCopyToClipboard } from "./use-copy-to-clipboard";
-import PdfDialog from "./widgets/PdfDialog";
+import { Button } from "../../button";
+import {
+  HoverCard,
+  HoverCardContent,
+  HoverCardTrigger,
+} from "../../hover-card";
+import { useCopyToClipboard } from "../hooks/use-copy-to-clipboard";
+import { SourceData } from "../index";
+import PdfDialog from "../widgets/PdfDialog";
 
 const SCORE_THRESHOLD = 0.3;
 
diff --git a/templates/types/streaming/nextjs/app/components/ui/chat/chat-tools.tsx b/templates/types/streaming/nextjs/app/components/ui/chat/chat-message/chat-tools.tsx
similarity index 86%
rename from templates/types/streaming/nextjs/app/components/ui/chat/chat-tools.tsx
rename to templates/types/streaming/nextjs/app/components/ui/chat/chat-message/chat-tools.tsx
index 268b4360..202f9823 100644
--- a/templates/types/streaming/nextjs/app/components/ui/chat/chat-tools.tsx
+++ b/templates/types/streaming/nextjs/app/components/ui/chat/chat-message/chat-tools.tsx
@@ -1,5 +1,5 @@
-import { ToolData } from "./index";
-import { WeatherCard, WeatherData } from "./widgets/WeatherCard";
+import { ToolData } from "../index";
+import { WeatherCard, WeatherData } from "../widgets/WeatherCard";
 
 // TODO: If needed, add displaying more tool outputs here
 export default function ChatTools({ data }: { data: ToolData }) {
diff --git a/templates/types/streaming/nextjs/app/components/ui/chat/codeblock.tsx b/templates/types/streaming/nextjs/app/components/ui/chat/chat-message/codeblock.tsx
similarity index 97%
rename from templates/types/streaming/nextjs/app/components/ui/chat/codeblock.tsx
rename to templates/types/streaming/nextjs/app/components/ui/chat/chat-message/codeblock.tsx
index 014a0fc3..e71a408c 100644
--- a/templates/types/streaming/nextjs/app/components/ui/chat/codeblock.tsx
+++ b/templates/types/streaming/nextjs/app/components/ui/chat/chat-message/codeblock.tsx
@@ -5,8 +5,8 @@ import { FC, memo } from "react";
 import { Prism, SyntaxHighlighterProps } from "react-syntax-highlighter";
 import { coldarkDark } from "react-syntax-highlighter/dist/cjs/styles/prism";
 
-import { Button } from "../button";
-import { useCopyToClipboard } from "./use-copy-to-clipboard";
+import { Button } from "../../button";
+import { useCopyToClipboard } from "../hooks/use-copy-to-clipboard";
 
 // TODO: Remove this when @type/react-syntax-highlighter is updated
 const SyntaxHighlighter = Prism as unknown as FC<SyntaxHighlighterProps>;
diff --git a/templates/types/streaming/nextjs/app/components/ui/chat/csv-content.tsx b/templates/types/streaming/nextjs/app/components/ui/chat/chat-message/csv-content.tsx
similarity index 75%
rename from templates/types/streaming/nextjs/app/components/ui/chat/csv-content.tsx
rename to templates/types/streaming/nextjs/app/components/ui/chat/chat-message/csv-content.tsx
index 1a84d978..dae53cd7 100644
--- a/templates/types/streaming/nextjs/app/components/ui/chat/csv-content.tsx
+++ b/templates/types/streaming/nextjs/app/components/ui/chat/chat-message/csv-content.tsx
@@ -1,5 +1,5 @@
-import { CsvData } from ".";
-import UploadCsvPreview from "../upload-csv-preview";
+import UploadCsvPreview from "../../upload-csv-preview";
+import { CsvData } from "../index";
 
 export default function CsvContent({ data }: { data: CsvData }) {
   if (!data.csvFiles.length) return null;
diff --git a/templates/types/streaming/nextjs/app/components/ui/chat/chat-message.tsx b/templates/types/streaming/nextjs/app/components/ui/chat/chat-message/index.tsx
similarity index 96%
rename from templates/types/streaming/nextjs/app/components/ui/chat/chat-message.tsx
rename to templates/types/streaming/nextjs/app/components/ui/chat/chat-message/index.tsx
index 7d346a7e..bff2d0db 100644
--- a/templates/types/streaming/nextjs/app/components/ui/chat/chat-message.tsx
+++ b/templates/types/streaming/nextjs/app/components/ui/chat/chat-message/index.tsx
@@ -2,13 +2,8 @@ import { Check, Copy } from "lucide-react";
 
 import { Message } from "ai";
 import { Fragment } from "react";
-import { Button } from "../button";
-import ChatAvatar from "./chat-avatar";
-import { ChatEvents } from "./chat-events";
-import { ChatImage } from "./chat-image";
-import { ChatSources } from "./chat-sources";
-import ChatTools from "./chat-tools";
-import CsvContent from "./csv-content";
+import { Button } from "../../button";
+import { useCopyToClipboard } from "../hooks/use-copy-to-clipboard";
 import {
   CsvData,
   EventData,
@@ -18,9 +13,14 @@ import {
   SourceData,
   ToolData,
   getAnnotationData,
-} from "./index";
+} from "../index";
+import ChatAvatar from "./chat-avatar";
+import { ChatEvents } from "./chat-events";
+import { ChatImage } from "./chat-image";
+import { ChatSources } from "./chat-sources";
+import ChatTools from "./chat-tools";
+import CsvContent from "./csv-content";
 import Markdown from "./markdown";
-import { useCopyToClipboard } from "./use-copy-to-clipboard";
 
 type ContentDisplayConfig = {
   order: number;
diff --git a/templates/types/streaming/nextjs/app/components/ui/chat/markdown.tsx b/templates/types/streaming/nextjs/app/components/ui/chat/chat-message/markdown.tsx
similarity index 100%
rename from templates/types/streaming/nextjs/app/components/ui/chat/markdown.tsx
rename to templates/types/streaming/nextjs/app/components/ui/chat/chat-message/markdown.tsx
diff --git a/templates/types/streaming/nextjs/app/components/ui/chat/chat-messages.tsx b/templates/types/streaming/nextjs/app/components/ui/chat/chat-messages.tsx
index e2e81e2d..0fbdc304 100644
--- a/templates/types/streaming/nextjs/app/components/ui/chat/chat-messages.tsx
+++ b/templates/types/streaming/nextjs/app/components/ui/chat/chat-messages.tsx
@@ -5,7 +5,7 @@ import { Button } from "../button";
 import ChatActions from "./chat-actions";
 import ChatMessage from "./chat-message";
 import { ChatHandler } from "./chat.interface";
-import { useClientConfig } from "./use-config";
+import { useClientConfig } from "./hooks/use-config";
 
 export default function ChatMessages(
   props: Pick<
diff --git a/templates/types/streaming/nextjs/app/components/ui/chat/use-config.ts b/templates/types/streaming/nextjs/app/components/ui/chat/hooks/use-config.ts
similarity index 100%
rename from templates/types/streaming/nextjs/app/components/ui/chat/use-config.ts
rename to templates/types/streaming/nextjs/app/components/ui/chat/hooks/use-config.ts
diff --git a/templates/types/streaming/nextjs/app/components/ui/chat/use-copy-to-clipboard.tsx b/templates/types/streaming/nextjs/app/components/ui/chat/hooks/use-copy-to-clipboard.tsx
similarity index 100%
rename from templates/types/streaming/nextjs/app/components/ui/chat/use-copy-to-clipboard.tsx
rename to templates/types/streaming/nextjs/app/components/ui/chat/hooks/use-copy-to-clipboard.tsx
diff --git a/templates/types/streaming/nextjs/app/components/ui/chat/use-csv.ts b/templates/types/streaming/nextjs/app/components/ui/chat/hooks/use-csv.ts
similarity index 95%
rename from templates/types/streaming/nextjs/app/components/ui/chat/use-csv.ts
rename to templates/types/streaming/nextjs/app/components/ui/chat/hooks/use-csv.ts
index afdbacaa..56e1d083 100644
--- a/templates/types/streaming/nextjs/app/components/ui/chat/use-csv.ts
+++ b/templates/types/streaming/nextjs/app/components/ui/chat/hooks/use-csv.ts
@@ -1,7 +1,7 @@
 "use client";
 
 import { useState } from "react";
-import { CsvFile } from ".";
+import { CsvFile } from "../chat";
 
 export function useCsv() {
   const [files, setFiles] = useState<CsvFile[]>([]);
-- 
GitLab