From ea7111f14321431b5c0ccadcaeaa8e78144802b4 Mon Sep 17 00:00:00 2001 From: serhat Date: Thu, 23 May 2024 16:56:52 +0300 Subject: [PATCH 1/2] plausible init needs api key --- web-app/package.json | 1 + .../IndexConversationHeader.tsx | 2 ++ .../TabContainer/IndexItemsTab.tsx | 2 ++ .../site/indexes/AskIndexes/index.tsx | 6 +++- web-app/src/context/AppContext.tsx | 2 ++ web-app/src/context/AuthContext.tsx | 2 ++ web-app/src/services/tracker.ts | 28 +++++++++++++++++++ web-app/yarn.lock | 25 +++++++++++++++-- 8 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 web-app/src/services/tracker.ts diff --git a/web-app/package.json b/web-app/package.json index 66c4a0b1..baa8917f 100644 --- a/web-app/package.json +++ b/web-app/package.json @@ -45,6 +45,7 @@ "next": "^14.0.3", "next-plausible": "^3.11.3", "pino-pretty": "^10.3.1", + "plausible-tracker": "^0.3.8", "react": "^18.2.0", "react-dom": "^18.2.0", "react-hot-toast": "^2.4.1", diff --git a/web-app/src/components/sections/IndexConversation/IndexConversationHeader.tsx b/web-app/src/components/sections/IndexConversation/IndexConversationHeader.tsx index 37a8c44f..012a8251 100644 --- a/web-app/src/components/sections/IndexConversation/IndexConversationHeader.tsx +++ b/web-app/src/components/sections/IndexConversation/IndexConversationHeader.tsx @@ -20,6 +20,7 @@ import toast from "react-hot-toast"; import { Indexes } from "types/entity"; import { maskDID } from "utils/helper"; import { useIndexConversation } from "./IndexConversationContext"; +import { ITEM_STARRED, trackEvent } from "@/services/tracker"; export const IndexConversationHeader: FC = () => { const { isOwner } = useRole(); @@ -83,6 +84,7 @@ export const IndexConversationHeader: FC = () => { toast.success( `Index ${value ? "added to" : "removed from"} starred indexes list`, ); + trackEvent(ITEM_STARRED); } else { await api!.ownIndex(session!.did.parent, viewedIndex.id, value); if (value) { diff --git a/web-app/src/components/sections/IndexConversation/TabContainer/IndexItemsTab.tsx b/web-app/src/components/sections/IndexConversation/TabContainer/IndexItemsTab.tsx index 413611a9..6a0a5114 100644 --- a/web-app/src/components/sections/IndexConversation/TabContainer/IndexItemsTab.tsx +++ b/web-app/src/components/sections/IndexConversation/TabContainer/IndexItemsTab.tsx @@ -12,6 +12,7 @@ import { filterValidUrls, isStreamID, removeDuplicates } from "@/utils/helper"; import { useCallback, useEffect, useState } from "react"; import toast from "react-hot-toast"; import { useIndexConversation } from "../IndexConversationContext"; +import { ITEM_ADDED, trackEvent } from "@/services/tracker"; const CONCURRENCY_LIMIT = 10; @@ -128,6 +129,7 @@ export default function IndexItemsTabSection() { const createdItem = await api!.createItem(viewedIndex.id, itemId); setAddedItem(createdItem); + trackEvent(ITEM_ADDED); } catch (error) { console.error("Error adding item", error); toast.error(`Error adding item: ${item}`); diff --git a/web-app/src/components/site/indexes/AskIndexes/index.tsx b/web-app/src/components/site/indexes/AskIndexes/index.tsx index 5dba9d95..25d4c2f0 100644 --- a/web-app/src/components/site/indexes/AskIndexes/index.tsx +++ b/web-app/src/components/site/indexes/AskIndexes/index.tsx @@ -24,6 +24,7 @@ import { toast } from "react-hot-toast"; import { API_ENDPOINTS } from "utils/constants"; import { maskDID } from "utils/helper"; import NoIndexes from "../NoIndexes"; +import { CHAT_STARTED, trackEvent } from "@/services/tracker"; export interface ChatProps extends ComponentProps<"div"> { initialMessages?: Message[]; @@ -44,7 +45,7 @@ const AskIndexes: FC = ({ chatID, sources }) => { const { session } = useAuth(); const { viewedIndex } = useApp(); - const { isIndex, id } = useRouteParams(); + const { isIndex, id, discoveryType } = useRouteParams(); const { ready: apiReady, api } = useApi(); const [editingMessage, setEditingMessage] = useState(); @@ -257,6 +258,9 @@ const AskIndexes: FC = ({ chatID, sources }) => { content: value, role: "user", }); + trackEvent(CHAT_STARTED, { + type: discoveryType, + }); }} isLoading={isLoading} input={input} diff --git a/web-app/src/context/AppContext.tsx b/web-app/src/context/AppContext.tsx index 44a51133..3016bdac 100644 --- a/web-app/src/context/AppContext.tsx +++ b/web-app/src/context/AppContext.tsx @@ -18,6 +18,7 @@ import { AccessControlCondition, Indexes, Users } from "types/entity"; import { DEFAULT_CREATE_INDEX_TITLE } from "utils/constants"; import { v4 as uuidv4 } from "uuid"; import { CancelTokenSource } from "axios"; +import { INDEX_CREATED, trackEvent } from "@/services/tracker"; type AppContextProviderProps = { children: ReactNode; @@ -245,6 +246,7 @@ export const AppContextProvider = ({ children }: AppContextProviderProps) => { } setIndexes((prevIndexes) => [doc, ...prevIndexes]); toast.success("Index created successfully"); + trackEvent(INDEX_CREATED); router.push(`/${doc.id}`); } catch (err: any) { let message = ""; diff --git a/web-app/src/context/AuthContext.tsx b/web-app/src/context/AuthContext.tsx index de7df699..359ef752 100644 --- a/web-app/src/context/AuthContext.tsx +++ b/web-app/src/context/AuthContext.tsx @@ -1,5 +1,6 @@ "use client"; +import { WALLET_CONNECTED, trackEvent } from "@/services/tracker"; import { normalizeAccountId } from "@ceramicnetwork/common"; import { Cacao, SiweMessage } from "@didtools/cacao"; import { getAccountId } from "@didtools/pkh-ethereum"; @@ -166,6 +167,7 @@ export const AuthProvider = ({ children }: any) => { setStatus(AuthStatus.CONNECTED); toast.success("Successfully connected to your wallet."); + trackEvent(WALLET_CONNECTED); } catch (err) { console.error("Error during authentication process:", err); setStatus(AuthStatus.FAILED); diff --git a/web-app/src/services/tracker.ts b/web-app/src/services/tracker.ts new file mode 100644 index 00000000..e6500c8e --- /dev/null +++ b/web-app/src/services/tracker.ts @@ -0,0 +1,28 @@ +import Plausible from "plausible-tracker"; + +const plausible = Plausible({ + domain: "index.network", +}); + +const events = { + WALLET_CONNECTED: "wallet_connected", + INDEX_CREATED: "index_created", + CHAT_STARTED: "chat_started", + ITEM_ADDED: "item_added", + ITEM_STARRED: "item_starred", +}; + +const trackEvent = (name: string, props?: Record) => { + if (process.env.NEXT_PUBLIC_API_URL === "https://index.network/api") { + plausible.trackEvent(name, props); + } + plausible.trackEvent(name, props); +}; + +export const WALLET_CONNECTED = events.WALLET_CONNECTED; +export const INDEX_CREATED = events.INDEX_CREATED; +export const CHAT_STARTED = events.CHAT_STARTED; +export const ITEM_ADDED = events.ITEM_ADDED; +export const ITEM_STARRED = events.ITEM_STARRED; + +export { trackEvent }; diff --git a/web-app/yarn.lock b/web-app/yarn.lock index 2373a3e7..d168ad8a 100644 --- a/web-app/yarn.lock +++ b/web-app/yarn.lock @@ -5096,6 +5096,11 @@ pirates@^4.0.1: resolved "https://registry.yarnpkg.com/pirates/-/pirates-4.0.6.tgz#3018ae32ecfcff6c29ba2267cbf21166ac1f36b9" integrity sha512-saLsH7WeYYPiD25LDuLRRY/i+6HaPYr6G1OUlN39otzkSTxKnubR9RTxS3/Kk50s1g2JTgFwWQDQyplC5/SHZg== +plausible-tracker@^0.3.8: + version "0.3.8" + resolved "https://registry.yarnpkg.com/plausible-tracker/-/plausible-tracker-0.3.8.tgz#9b8b322cc41e0e1d6473869ef234deea365a5a40" + integrity sha512-lmOWYQ7s9KOUJ1R+YTOR3HrjdbxIS2Z4de0P/Jx2dQPteznJl2eX3tXxKClpvbfyGP59B5bbhW8ftN59HbbFSg== + possible-typed-array-names@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz#89bb63c6fada2c3e90adc4a647beeeb39cc7bf8f" @@ -5800,7 +5805,16 @@ streamsearch@^1.1.0: resolved "https://registry.yarnpkg.com/streamsearch/-/streamsearch-1.1.0.tgz#404dd1e2247ca94af554e841a8ef0eaa238da764" integrity sha512-Mcc5wHehp9aXz1ax6bZUyY5afg9u2rv5cqQI3mRrYkGC8rW2hM02jWuwjtL++LS5qinSyhj2QfLyNsuc+VsExg== -"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0: +"string-width-cjs@npm:string-width@^4.2.0": + version "4.2.3" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" + integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== + dependencies: + emoji-regex "^8.0.0" + is-fullwidth-code-point "^3.0.0" + strip-ansi "^6.0.1" + +string-width@^4.1.0: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -5871,7 +5885,14 @@ string_decoder@^1.3.0: dependencies: safe-buffer "~5.2.0" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1", strip-ansi@^6.0.0, strip-ansi@^6.0.1: +"strip-ansi-cjs@npm:strip-ansi@^6.0.1": + version "6.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" + integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== + dependencies: + ansi-regex "^5.0.1" + +strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== From e28411d6ff3f2c7c44bc20accd8984d390657092 Mon Sep 17 00:00:00 2001 From: serhat Date: Thu, 23 May 2024 17:19:32 +0300 Subject: [PATCH 2/2] popover fix --- web-app/public/images/ic_close.svg | 4 +++ .../IndexConversationHeader.tsx | 2 +- .../TabContainer/IndexItemsTab.tsx | 4 +-- .../IndexConversation/TabContainer/index.tsx | 1 - .../site/indexes/AskIndexes/index.tsx | 2 +- .../components/site/input/LinkInput/index.tsx | 33 +++++++++++++++---- web-app/src/utils/yup-validations.ts | 11 ------- 7 files changed, 33 insertions(+), 24 deletions(-) create mode 100644 web-app/public/images/ic_close.svg delete mode 100644 web-app/src/utils/yup-validations.ts diff --git a/web-app/public/images/ic_close.svg b/web-app/public/images/ic_close.svg new file mode 100644 index 00000000..03b06a66 --- /dev/null +++ b/web-app/public/images/ic_close.svg @@ -0,0 +1,4 @@ + + + + diff --git a/web-app/src/components/sections/IndexConversation/IndexConversationHeader.tsx b/web-app/src/components/sections/IndexConversation/IndexConversationHeader.tsx index 012a8251..d97dfaa1 100644 --- a/web-app/src/components/sections/IndexConversation/IndexConversationHeader.tsx +++ b/web-app/src/components/sections/IndexConversation/IndexConversationHeader.tsx @@ -3,6 +3,7 @@ import { useApi } from "@/context/APIContext"; import { useApp } from "@/context/AppContext"; import { useAuth } from "@/context/AuthContext"; import { useRole } from "@/hooks/useRole"; +import { ITEM_STARRED, trackEvent } from "@/services/tracker"; import Avatar from "components/base/Avatar"; import Button from "components/base/Button"; import IconStar from "components/base/Icon/IconStar"; @@ -20,7 +21,6 @@ import toast from "react-hot-toast"; import { Indexes } from "types/entity"; import { maskDID } from "utils/helper"; import { useIndexConversation } from "./IndexConversationContext"; -import { ITEM_STARRED, trackEvent } from "@/services/tracker"; export const IndexConversationHeader: FC = () => { const { isOwner } = useRole(); diff --git a/web-app/src/components/sections/IndexConversation/TabContainer/IndexItemsTab.tsx b/web-app/src/components/sections/IndexConversation/TabContainer/IndexItemsTab.tsx index 6a0a5114..8a7a20a6 100644 --- a/web-app/src/components/sections/IndexConversation/TabContainer/IndexItemsTab.tsx +++ b/web-app/src/components/sections/IndexConversation/TabContainer/IndexItemsTab.tsx @@ -7,12 +7,12 @@ import LinkInput from "@/components/site/input/LinkInput"; import { useApi } from "@/context/APIContext"; import { useApp } from "@/context/AppContext"; import { useRole } from "@/hooks/useRole"; +import { ITEM_ADDED, trackEvent } from "@/services/tracker"; import { IndexItem } from "@/types/entity"; import { filterValidUrls, isStreamID, removeDuplicates } from "@/utils/helper"; import { useCallback, useEffect, useState } from "react"; import toast from "react-hot-toast"; import { useIndexConversation } from "../IndexConversationContext"; -import { ITEM_ADDED, trackEvent } from "@/services/tracker"; const CONCURRENCY_LIMIT = 10; @@ -112,8 +112,6 @@ export default function IndexItemsTabSection() { const items = [...urls, ...indexIds]; - console.log("items", indexIds); - setAddItemLoading(true); setProgress({ current: 0, total: items.length }); diff --git a/web-app/src/components/sections/IndexConversation/TabContainer/index.tsx b/web-app/src/components/sections/IndexConversation/TabContainer/index.tsx index 489e6b02..2798a0f4 100644 --- a/web-app/src/components/sections/IndexConversation/TabContainer/index.tsx +++ b/web-app/src/components/sections/IndexConversation/TabContainer/index.tsx @@ -80,7 +80,6 @@ export default function TabContainer() { flex: 1, display: "flex", height: "100%", - overflow: "hidden", flexDirection: "column", }} > diff --git a/web-app/src/components/site/indexes/AskIndexes/index.tsx b/web-app/src/components/site/indexes/AskIndexes/index.tsx index 25d4c2f0..f0f821f4 100644 --- a/web-app/src/components/site/indexes/AskIndexes/index.tsx +++ b/web-app/src/components/site/indexes/AskIndexes/index.tsx @@ -2,6 +2,7 @@ import { useApi } from "@/context/APIContext"; import { useApp } from "@/context/AppContext"; import { useAuth } from "@/context/AuthContext"; import { useRouteParams } from "@/hooks/useRouteParams"; +import { CHAT_STARTED, trackEvent } from "@/services/tracker"; import { useChat, type Message } from "ai/react"; import { ButtonScrollToBottom } from "components/ai/button-scroll-to-bottom"; import { ChatList } from "components/ai/chat-list"; @@ -24,7 +25,6 @@ import { toast } from "react-hot-toast"; import { API_ENDPOINTS } from "utils/constants"; import { maskDID } from "utils/helper"; import NoIndexes from "../NoIndexes"; -import { CHAT_STARTED, trackEvent } from "@/services/tracker"; export interface ChatProps extends ComponentProps<"div"> { initialMessages?: Message[]; diff --git a/web-app/src/components/site/input/LinkInput/index.tsx b/web-app/src/components/site/input/LinkInput/index.tsx index 69bfe25c..4be3e7fb 100644 --- a/web-app/src/components/site/input/LinkInput/index.tsx +++ b/web-app/src/components/site/input/LinkInput/index.tsx @@ -19,26 +19,28 @@ export interface LinkInputProps extends InputProps { }; } -const Popover = () => { +const Popover = ({ onClose }: { onClose: () => void }) => { return (
{ lineHeight: "17px", }} > +
{ + onClose(); + }} + > + Image +
What you can index?
@@ -113,7 +134,7 @@ const LinkInput: React.FC = ({ }) => { const [url, setUrl] = useState(""); const [showMsg, setShowMsg] = useState(false); - const [showPopover, setShowPopover] = useState(false); + const [showPopover, setShowPopover] = useState(true); const handleAdd = () => { if (url) { @@ -126,7 +147,6 @@ const LinkInput: React.FC = ({ const handleBlur: React.FocusEventHandler = () => { handleAdd(); - setShowPopover(false); }; const handleEnter = (e: any) => { @@ -150,7 +170,7 @@ const LinkInput: React.FC = ({ position: "relative", }} > - {showPopover && } + {showPopover && setShowPopover(false)} />} = ({ } {...inputProps} value={url} - onFocus={() => setShowPopover(true)} onBlur={handleBlur} onChange={handleChange} onKeyDown={handleEnter} diff --git a/web-app/src/utils/yup-validations.ts b/web-app/src/utils/yup-validations.ts deleted file mode 100644 index e7ffb38c..00000000 --- a/web-app/src/utils/yup-validations.ts +++ /dev/null @@ -1,11 +0,0 @@ -import { object, string } from "yup"; - -const yupValidations = { - loginForm: object().shape({ - email: string().email().label("Email").required(), - password: string().label("Password").required(), - }), - -}; - -export default yupValidations;