diff --git a/src/components/Option/Layout.tsx b/src/components/Option/Layout.tsx
index d85a1a3..1fb6b7c 100644
--- a/src/components/Option/Layout.tsx
+++ b/src/components/Option/Layout.tsx
@@ -4,11 +4,17 @@ import { useLocation, NavLink } from "react-router-dom"
import { Sidebar } from "./Sidebar"
import { Drawer, Layout, Modal, Select, Tooltip } from "antd"
import { useQuery } from "@tanstack/react-query"
-import { getAllModels } from "~services/ollama"
+import { getAllModels } from "~services/ollama"
import { useMessageOption } from "~hooks/useMessageOption"
import { Settings } from "./Settings"
-import { BrainCircuit, ChevronLeft, CogIcon, GithubIcon, PanelLeftIcon, SquarePen } from "lucide-react"
-
+import {
+ Book,
+ BrainCircuit,
+ ChevronLeft,
+ CogIcon,
+ PanelLeftIcon,
+ SquarePen
+} from "lucide-react"
export default function OptionLayout({
children
@@ -83,14 +89,21 @@ export default function OptionLayout({
-
+
+
+
+
+
+ {/*
-
+ */}
{
diff --git a/src/components/Option/Prompt/index.tsx b/src/components/Option/Prompt/index.tsx
new file mode 100644
index 0000000..7e328b3
--- /dev/null
+++ b/src/components/Option/Prompt/index.tsx
@@ -0,0 +1,273 @@
+import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"
+import {
+ Skeleton,
+ Table,
+ Tag,
+ Tooltip,
+ notification,
+ Modal,
+ Input,
+ Form,
+ Switch
+} from "antd"
+import { Trash2, Pen } from "lucide-react"
+import { useState } from "react"
+import {
+ deletePromptById,
+ getAllPrompts,
+ savePrompt,
+ updatePrompt
+} from "~libs/db"
+
+export const PromptBody = () => {
+ const queryClient = useQueryClient()
+ const [open, setOpen] = useState(false)
+ const [openEdit, setOpenEdit] = useState(false)
+ const [editId, setEditId] = useState("")
+ const [createForm] = Form.useForm()
+ const [editForm] = Form.useForm()
+
+ const { data, status } = useQuery({
+ queryKey: ["fetchAllPrompts"],
+ queryFn: getAllPrompts
+ })
+
+ const { mutate: deletePrompt } = useMutation({
+ mutationFn: deletePromptById,
+ onSuccess: () => {
+ queryClient.invalidateQueries({
+ queryKey: ["fetchAllPrompts"]
+ })
+ notification.success({
+ message: "Model Deleted",
+ description: "Model has been deleted successfully"
+ })
+ },
+ onError: (error) => {
+ notification.error({
+ message: "Error",
+ description: error?.message || "Something went wrong"
+ })
+ }
+ })
+
+ const { mutate: savePromptMutation, isPending: savePromptLoading } =
+ useMutation({
+ mutationFn: savePrompt,
+ onSuccess: () => {
+ queryClient.invalidateQueries({
+ queryKey: ["fetchAllPrompts"]
+ })
+ setOpen(false)
+ createForm.resetFields()
+ notification.success({
+ message: "Prompt Added",
+ description: "Prompt has been added successfully"
+ })
+ },
+ onError: (error) => {
+ notification.error({
+ message: "Error",
+ description: error?.message || "Something went wrong"
+ })
+ }
+ })
+
+ const { mutate: updatePromptMutation, isPending: isUpdatingPrompt } =
+ useMutation({
+ mutationFn: async (data: any) => {
+ return await updatePrompt({
+ ...data,
+ id: editId
+ })
+ },
+ onSuccess: () => {
+ queryClient.invalidateQueries({
+ queryKey: ["fetchAllPrompts"]
+ })
+ setOpenEdit(false)
+ editForm.resetFields()
+ notification.success({
+ message: "Prompt Updated",
+ description: "Prompt has been updated successfully"
+ })
+ },
+ onError: (error) => {
+ notification.error({
+ message: "Error",
+ description: error?.message || "Something went wrong"
+ })
+ }
+ })
+
+ return (
+
+
+
+
+
+
+
+
+
+
+ {status === "pending" &&
}
+
+ {status === "success" && (
+
(
+
+ {is_system ? "Yes" : "No"}
+
+ )
+ },
+ {
+ title: "Action",
+ render: (_, record) => (
+
+
+
+
+
+
+
+
+ )
+ }
+ ]}
+ bordered
+ dataSource={data}
+ rowKey={(record) => record.id}
+ />
+ )}
+
+
+ setOpen(false)}
+ footer={null}>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ setOpenEdit(false)}
+ footer={null}>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )
+}
diff --git a/src/libs/db.ts b/src/libs/db.ts
index ff61f26..75d53a6 100644
--- a/src/libs/db.ts
+++ b/src/libs/db.ts
@@ -31,10 +31,22 @@ type Message = {
createdAt: number
}
+
+type Prompt = {
+ id: string
+ title: string
+ content: string
+ is_system: boolean
+ createdBy?: string
+ createdAt: number
+}
+
type MessageHistory = Message[]
type ChatHistory = HistoryInfo[]
+type Prompts = Prompt[]
+
export class PageAssitDatabase {
db: chrome.storage.StorageArea
@@ -102,8 +114,49 @@ export class PageAssitDatabase {
async deleteMessage(history_id: string) {
await this.db.remove(history_id)
}
+
+
+ async getAllPrompts(): Promise {
+ return new Promise((resolve, reject) => {
+ this.db.get("prompts", (result) => {
+ resolve(result.prompts || [])
+ })
+ })
+ }
+
+ async addPrompt(prompt: Prompt) {
+ const prompts = await this.getAllPrompts()
+ const newPrompts = [prompt, ...prompts]
+ this.db.set({ prompts: newPrompts })
+ }
+
+ async deletePrompt(id: string) {
+ const prompts = await this.getAllPrompts()
+ const newPrompts = prompts.filter((prompt) => prompt.id !== id)
+ this.db.set({ prompts: newPrompts })
+ }
+
+ async updatePrompt(id: string, title: string, content: string, is_system: boolean) {
+ const prompts = await this.getAllPrompts()
+ const newPrompts = prompts.map((prompt) => {
+ if (prompt.id === id) {
+ prompt.title = title
+ prompt.content = content
+ prompt.is_system = is_system
+ }
+ return prompt
+ })
+ this.db.set({ prompts: newPrompts })
+ }
+
+ async getPromptById(id: string) {
+ const prompts = await this.getAllPrompts()
+ return prompts.find((prompt) => prompt.id === id)
+ }
+
}
+
const generateID = () => {
return "pa_xxxx-xxxx-xxx-xxxx".replace(/[x]/g, () => {
const r = Math.floor(Math.random() * 16)
@@ -188,3 +241,39 @@ export const removeMessageUsingHistoryId = async (history_id: string) => {
const newChatHistory = chatHistory.slice(0, -1)
await db.db.set({ [history_id]: newChatHistory })
}
+
+
+export const getAllPrompts = async () => {
+ const db = new PageAssitDatabase()
+ return await db.getAllPrompts()
+}
+
+
+export const savePrompt = async ({ content, title, is_system = false }: { title: string, content: string, is_system: boolean }) => {
+ const db = new PageAssitDatabase()
+ const id = generateID()
+ const createdAt = Date.now()
+ const prompt = { id, title, content, is_system, createdAt }
+ await db.addPrompt(prompt)
+ return prompt
+}
+
+
+export const deletePromptById = async (id: string) => {
+ const db = new PageAssitDatabase()
+ await db.deletePrompt(id)
+ return id
+}
+
+
+export const updatePrompt = async ({ content, id, title, is_system }: { id: string, title: string, content: string, is_system: boolean }) => {
+ const db = new PageAssitDatabase()
+ await db.updatePrompt(id, title, content, is_system)
+ return id
+}
+
+
+export const getPromptById = async (id: string) => {
+ const db = new PageAssitDatabase()
+ return await db.getPromptById(id)
+}
\ No newline at end of file
diff --git a/src/routes/index.tsx b/src/routes/index.tsx
index f932315..4abef46 100644
--- a/src/routes/index.tsx
+++ b/src/routes/index.tsx
@@ -4,6 +4,7 @@ import { useDarkMode } from "~hooks/useDarkmode"
import { SidepanelSettings } from "./sidepanel-settings"
import { OptionIndex } from "./option-index"
import { OptionModal } from "./option-model"
+import { OptionPrompt } from "./option-prompt"
export const OptionRouting = () => {
const { mode } = useDarkMode()
@@ -13,6 +14,7 @@ export const OptionRouting = () => {
} />
} />
+ } />
)
diff --git a/src/routes/option-prompt.tsx b/src/routes/option-prompt.tsx
new file mode 100644
index 0000000..2fbd433
--- /dev/null
+++ b/src/routes/option-prompt.tsx
@@ -0,0 +1,10 @@
+import OptionLayout from "~components/Option/Layout"
+import { PromptBody } from "~components/Option/Prompt"
+
+export const OptionPrompt = () => {
+ return (
+
+
+
+ )
+}
diff --git a/src/web/local-google.ts b/src/web/local-google.ts
index cb2193a..e76475a 100644
--- a/src/web/local-google.ts
+++ b/src/web/local-google.ts
@@ -40,7 +40,14 @@ export const localGoogleSearch = async (query: string) => {
(result) => {
const title = result.querySelector("h3")?.textContent
const link = result.querySelector("a")?.getAttribute("href")
- return { title, link }
+ let content = result.querySelector("div[data-sncf='2']")?.textContent
+ if(content === "") {
+ content = result.querySelector("div[data-sncf='1']")?.textContent
+ if(content === "") {
+ content = result.querySelector("div[data-sncf='3']")?.textContent
+ }
+ }
+ return { title, link, content }
}
)
const filteredSearchResults = searchResults