From 3008bae7313c7bff608edbc353148d70932a5240 Mon Sep 17 00:00:00 2001 From: serhat Date: Tue, 16 Jan 2024 16:23:16 +0300 Subject: [PATCH 1/5] fix create index --- web-app/src/config/index.ts | 4 +- web-app/src/hooks/useApp.tsx | 59 ++++++++++++++++++++--------- web-app/src/services/api-service.ts | 18 +++++++++ web-app/src/types/entity.ts | 2 + web-app/src/utils/constants.ts | 3 ++ 5 files changed, 67 insertions(+), 19 deletions(-) diff --git a/web-app/src/config/index.ts b/web-app/src/config/index.ts index 409abf6d..2a37ea7d 100644 --- a/web-app/src/config/index.ts +++ b/web-app/src/config/index.ts @@ -1,9 +1,9 @@ export const appConfig = { baseUrl: "https://index.network/", - apiUrl: "https://index.network/api", + apiUrl: "https://dev.index.network/api", // TODO: handle better ipfsProxy: "https://indexas.infura-ipfs.io/ipfs", ipfsInfura: "http://localhost:3001/avatar", - defaultCID: "QmRisjM1uZ18wUE22XsREDYEXYdsVuZ6P312XWcMj3Apys", // Empty. + defaultCID: "QmZQ42inuRBMLh65UfUCGhMBWhHCsZtGVEKttV16mbrKrj", // Empty. testNetwork: { chainId: "0x2ac49", chainName: "Chronicle - Lit Protocol Testnet", diff --git a/web-app/src/hooks/useApp.tsx b/web-app/src/hooks/useApp.tsx index 8cdaf8c3..3ee3c23d 100644 --- a/web-app/src/hooks/useApp.tsx +++ b/web-app/src/hooks/useApp.tsx @@ -6,7 +6,7 @@ import CreateModal from "components/site/modal/CreateModal"; import EditProfileModal from "components/site/modal/EditProfileModal"; import ConfirmTransaction from "components/site/modal/Common/ConfirmTransaction"; import LitService from "services/lit-service"; -import CeramicService from "services/ceramic-service"; +import apiService from "services/api-service"; import { Indexes, Users, @@ -19,6 +19,7 @@ import { v4 as uuidv4 } from "uuid"; import { useAppSelector } from "./store"; import { selectProfile } from "../store/slices/profileSlice"; import api, { DidSearchRequestBody, IndexSearchResponse } from "../services/api-service"; +import { DEFAULT_CREATE_INDEX_TITLE } from "utils/constants"; export interface AppContextValue { indexes: MultipleIndexListState @@ -75,24 +76,48 @@ export const AppContextProvider = ({ children } : any) => { indexes: [] as Indexes[], } as IndexListState, }); - const handleCreate = async (title: string) => { - if (title) { - // handleToggleCreateModal(); - setCreateModalVisible(false); - setTransactionApprovalWaiting(true); - const { pkpPublicKey } = await LitService.mintPkp(); - const sessionResponse = await LitService.getPKPSession(pkpPublicKey, appConfig.defaultCID); - const c = new CeramicService(); - c.authenticateUser(sessionResponse.session.did); - const doc = await c.createIndex(pkpPublicKey, { title } as Indexes); - await ceramic.addUserIndex(doc.id, "owner"); - updateUserIndexState({ ...doc, ownerDID: profile } as Indexes, "owner", "add"); - if (doc) { - setTransactionApprovalWaiting(false); - await router.push(`/index/[indexId]`, `/index/${doc.id}`, { shallow: true }); - } + + const handleCreate = async (title: string = DEFAULT_CREATE_INDEX_TITLE) => { + setCreateModalVisible(false); + setTransactionApprovalWaiting(true); + try { + const { pkpPublicKey } = await LitService.mintPkp(); + const sessionResponse = await LitService.getPKPSession(pkpPublicKey, appConfig.defaultCID); + + let personalSession = localStorage.getItem("did"); + if (!personalSession) { + throw Error('No personal session provided') + } + + let pkpSession = sessionResponse.session.serialize(); + if (!pkpSession) { + throw Error('No PKP session provided') + } + + const doc = await apiService.createIndex({ + params: { + title, + signerFunction: appConfig.defaultCID, + signerPublicKey: pkpPublicKey, + }, + pkpSession, + personalSession + }); + + // ASK: why no doc check here, but below instead? + updateUserIndexState({ ...doc, ownerDID: profile } as Indexes, "owner", "add"); + + if (doc) { + setTransactionApprovalWaiting(false); + await router.push(`/index/[indexId]`, `/index/${doc.id}`, { shallow: true }); + } + } catch (err) { + console.error("Couldn't create index", err) + alert("Couldn't create index :/") // TODO: handle better } }; + + const removeIndex = (group : IndexListState, index: Indexes) => { const newIndexes = group.indexes?.filter((i: Indexes) => i.id !== index.id) || []; if (newIndexes?.length < group.indexes!.length) { diff --git a/web-app/src/services/api-service.ts b/web-app/src/services/api-service.ts index 3550b389..00797059 100644 --- a/web-app/src/services/api-service.ts +++ b/web-app/src/services/api-service.ts @@ -97,11 +97,29 @@ export interface LinksCrawlContentRequest { links: Link[]; } +const buildHeaders = (personalSession?: string, pkpSession?: string): any => { + return { + "X-Index-Personal-DID-Session": personalSession, + "X-Index-PKP-DID-Session": pkpSession, + } +} + const apiAxios = axios.create({ baseURL: appConfig.apiUrl, }); class ApiService { + async createIndex({ + params, pkpSession, personalSession + }: { + params: Partial, pkpSession: string, personalSession: string + }): Promise { + const { data } = await apiAxios.post('/indexes', params, { + headers: buildHeaders(personalSession, pkpSession) + }); + return data; + } + async searchIndex(body: DidSearchRequestBody): Promise { try { const { data } = await apiAxios.post(API_ENDPOINTS.SEARCH_DID, body); diff --git a/web-app/src/types/entity.ts b/web-app/src/types/entity.ts index 5919a4c7..4cad9ca2 100644 --- a/web-app/src/types/entity.ts +++ b/web-app/src/types/entity.ts @@ -10,6 +10,8 @@ export type Indexes = { title: string | null collabAction: string pkpPublicKey: string + signerFunction: string + signerPublicKey: string controllerDID: { // This is PKP DID id: string }; diff --git a/web-app/src/utils/constants.ts b/web-app/src/utils/constants.ts index 21ed5bcd..cb10a213 100644 --- a/web-app/src/utils/constants.ts +++ b/web-app/src/utils/constants.ts @@ -23,3 +23,6 @@ export const API_ENDPOINTS = { ZAPIER_TEST_LOGIN: "/zapier/test_login", SUBSCRIBE_TO_NEWSLETTER: "/subscribe", }; + + +export const DEFAULT_CREATE_INDEX_TITLE = "Untitled Index"; \ No newline at end of file From b2439511d0154e198129ff321e325ccaf8beeff2 Mon Sep 17 00:00:00 2001 From: serhat Date: Tue, 16 Jan 2024 17:34:44 +0300 Subject: [PATCH 2/5] fix get all indexes --- .../site/indexes/SearchIndexes/index.tsx | 52 +++--- web-app/src/hooks/useApp.tsx | 165 ++++-------------- web-app/src/services/api-service.ts | 19 +- web-app/src/types/entity.ts | 2 +- web-app/src/utils/constants.ts | 2 +- 5 files changed, 68 insertions(+), 172 deletions(-) diff --git a/web-app/src/components/site/indexes/SearchIndexes/index.tsx b/web-app/src/components/site/indexes/SearchIndexes/index.tsx index a8738550..1372275c 100644 --- a/web-app/src/components/site/indexes/SearchIndexes/index.tsx +++ b/web-app/src/components/site/indexes/SearchIndexes/index.tsx @@ -1,10 +1,9 @@ import Col from "components/layout/base/Grid/Col"; import FlexRow from "components/layout/base/Grid/FlexRow"; -import React, { useCallback } from "react"; +import React, { useCallback, useMemo } from "react"; import List from "components/base/List"; import { useRouter } from "next/router"; import { Indexes } from "types/entity"; -import InfiniteScroll from "react-infinite-scroller"; import { Tabs } from "components/base/Tabs"; import TabPane from "components/base/Tabs/TabPane"; @@ -20,10 +19,9 @@ const SearchIndexes: React.VFC = () => { viewedProfile, section, indexes, - getIndexes, } = useApp(); - const { did, indexId } = router.query; + const { indexId } = router.query; const handleTabChange = useCallback((tabClickValue: string) => { if (viewedProfile && tabClickValue) { @@ -34,39 +32,37 @@ const SearchIndexes: React.VFC = () => { } }, [viewedProfile]); - const sortIndexes = (items: Indexes[]) => items.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()); + const sectionIndexes = useMemo(() => { + if (section === 'all') { + return indexes; + } else { + return indexes.filter( + section === 'owner' ? i => i.isOwner === true : i => i.isStarred === true + ); + } + }, [indexes, section]); return <> - - + i.isOwner === true)?.length} title={`Owned`} /> + i.isStarred === true)?.length} title={`Starred`} /> - - { (indexes[section].totalCount > 0) ? <> - - } - divided={false} - /> - - : + + { (sectionIndexes.length > 0) ?
+ } + divided={false} + /> +
: void - getIndexes: (page?: number, newSearch?: boolean) => void + indexes: Indexes[] + setIndexes: (indexes: Indexes[]) => void + getAllIndexes: () => void section: keyof MultipleIndexListState setSection: (section: keyof MultipleIndexListState) => void setCreateModalVisible: (visible: boolean) => void @@ -51,31 +49,10 @@ export const AppContextProvider = ({ children } : any) => { const [viewedProfile, setViewedProfile] = useState(); const [section, setSection] = useState ("all" as keyof MultipleIndexListState); const router = useRouter(); - const ceramic = useCeramic(); - const { did, indexId } = router.query; + const { did } = router.query; const profile = useAppSelector(selectProfile); - const take = 100; - const [indexes, setIndexes] = useState({ - all: { - skip: 0, - totalCount: 0, - hasMore: true, - indexes: [] as Indexes[], - } as IndexListState, - owner: { - skip: 0, - totalCount: 0, - hasMore: true, - indexes: [] as Indexes[], - } as IndexListState, - starred: { - skip: 0, - totalCount: 0, - hasMore: true, - indexes: [] as Indexes[], - } as IndexListState, - }); + const [indexes, setIndexes] = useState([]); const handleCreate = async (title: string = DEFAULT_CREATE_INDEX_TITLE) => { setCreateModalVisible(false); @@ -105,7 +82,7 @@ export const AppContextProvider = ({ children } : any) => { }); // ASK: why no doc check here, but below instead? - updateUserIndexState({ ...doc, ownerDID: profile } as Indexes, "owner", "add"); + updateUserIndexState({ ...doc, ownerDID: profile } as Indexes, "add"); if (doc) { setTransactionApprovalWaiting(false); @@ -117,116 +94,50 @@ export const AppContextProvider = ({ children } : any) => { } }; - - const removeIndex = (group : IndexListState, index: Indexes) => { - const newIndexes = group.indexes?.filter((i: Indexes) => i.id !== index.id) || []; - if (newIndexes?.length < group.indexes!.length) { - group.totalCount -= 1; - group.skip -= 1; - } - group.indexes = newIndexes; - return group; - }; - const addIndex = (group : IndexListState, index: Indexes) => { - const isExist = group.indexes?.filter((i: Indexes) => i.id === index.id) || []; - if (isExist.length > 0) { - return group; - } - if (group.indexes) { - group.indexes.push(index); - group.indexes.sort((a, b) => new Date(b.createdAt).getSeconds() - new Date(a.createdAt).getSeconds()); - } - group.skip += 1; - group.totalCount += 1; - return group; - }; const updateIndex = (index: Indexes) => { - const newState = { ...indexes }; - Object.keys(indexes).forEach((key) => { - newState[key as keyof MultipleIndexListState].indexes = indexes[key as keyof MultipleIndexListState].indexes?.map( - (i) => (i.id === index.id ? { ...i, ...index } : i), - ); - }); - setIndexes(newState); + const updatedIndexes = indexes + .map((i) => (i.id === index.id ? { ...i, ...index } : i)); + + setIndexes(updatedIndexes); }; - const spreadProfileToIndexes = (p: Users) => { - const newState = { ...indexes }; - Object.keys(indexes).forEach((key) => { - newState[key as keyof MultipleIndexListState].indexes = indexes[key as keyof MultipleIndexListState].indexes?.map( - (i) => (i.ownerDID.id === p.id ? { ...i, ownerDID: p } : i), - ); - }); - setIndexes(newState); + + const spreadProfileToIndexes = (profile: Users) => { + const updatedIndexes = indexes + .map((i) => (i.ownerDID.id === profile.id ? { ...i, ownerDID: profile } : i)); + + setIndexes(updatedIndexes); }; - const updateUserIndexState = (index: Indexes, type: keyof MultipleIndexListState, op: string) => { - const newState = { ...indexes }; - const allIndexes : keyof MultipleIndexListState = "all"; - if (op === "add") { - newState[type]! = addIndex(newState[type]!, index); - newState[allIndexes]! = addIndex(newState[allIndexes]!, index); - } else { - newState[type]! = removeIndex(newState[type]!, index); - if (!index.isStarred && !index.isOwner) { - newState[allIndexes]! = removeIndex(newState[allIndexes]!, index); - } + + const updateUserIndexState = (index: Indexes, op: string) => { + let updatedIndexes = [...indexes]; + + if (op === "add" && !indexes.some(i => i.id === index.id)) { + updatedIndexes.push(index); + } else if (op === "remove") { + updatedIndexes = updatedIndexes.filter(i => i.id !== index.id); } - setIndexes(newState); + + setIndexes(updatedIndexes); }; + const handleTransactionCancel = () => { setTransactionApprovalWaiting(false); }; - const getIndexes = useCallback(async (page?: number, newSearch?: boolean) => { - if (!viewedProfile) return; - const queryParams = { - did: viewedProfile.id, - take, - } as DidSearchRequestBody; - - if (newSearch) { - queryParams.skip = 0; - } else { - queryParams.type = section; - // @ts-ignore - queryParams.skip = indexes[section]?.indexes.length; - } + const getAllIndexes = useCallback(async () => { + if (!viewedProfile || !viewedProfile.id) return; // TODO: handle better maybe? - const res = await api.searchIndex(queryParams) as IndexSearchResponse; - if (res) { - if (newSearch) { - setIndexes({ - all: { - hasMore: res.all?.totalCount! > queryParams.skip + take, - indexes: res.all?.records || [], - totalCount: res.all?.totalCount || 0, - }, - owner: { - hasMore: res.owner?.totalCount! > queryParams.skip + take, - indexes: res.owner?.records || [], - totalCount: res.owner?.totalCount || 0, - }, - starred: { - hasMore: res.starred?.totalCount! > queryParams.skip + take, - indexes: res.starred?.records || [], - totalCount: res.starred?.totalCount || 0, - }, - } as MultipleIndexListState); - } else { - setIndexes({ - ...indexes, - [section]: { - hasMore: res[section]?.totalCount! > queryParams.skip + take, - // eslint-disable-next-line no-unsafe-optional-chaining - indexes: newSearch ? res[section]?.records! : [...(indexes[section]?.indexes || []), ...res[section]?.records!], - totalCount: res[section]?.totalCount, - }, - } as MultipleIndexListState); - } + try { + const res = await api.getAllIndexes(viewedProfile.id); + setIndexes(res); + } catch(err) { + console.error("Couldn't get indexes", err) + alert("Couldn't get indexes :/") // TODO: handle better } }, [viewedProfile?.id]); useEffect(() => { - viewedProfile && getIndexes(1, true); + viewedProfile && getAllIndexes(); }, [viewedProfile?.id]); const activeKey = () => { @@ -257,7 +168,7 @@ export const AppContextProvider = ({ children } : any) => { { - did: string; - skip: number; - take: number; - search?: string; - links_size?: number; - type?: string; -} export interface DidSearchResponse { totalCount: number; records: Indexes[]; @@ -120,13 +112,10 @@ class ApiService { return data; } - async searchIndex(body: DidSearchRequestBody): Promise { - try { - const { data } = await apiAxios.post(API_ENDPOINTS.SEARCH_DID, body); - return data; - } catch (err) { - return null; - } + async getAllIndexes(id: string): Promise { + const url = API_ENDPOINTS.GET_ALL_INDEXES.replace(':id', id); + const { data } = await apiAxios.get(url); + return data; } async getUserIndexes(body: GetUserIndexesRequestBody): Promise { diff --git a/web-app/src/types/entity.ts b/web-app/src/types/entity.ts index 4cad9ca2..790ebe35 100644 --- a/web-app/src/types/entity.ts +++ b/web-app/src/types/entity.ts @@ -93,7 +93,7 @@ export type Link = { * */ export interface Users { - id?: string; + id?: string; // TODO: why is this optional? name?: string; bio?: string; avatar?: CID; diff --git a/web-app/src/utils/constants.ts b/web-app/src/utils/constants.ts index cb10a213..406a8bb8 100644 --- a/web-app/src/utils/constants.ts +++ b/web-app/src/utils/constants.ts @@ -9,7 +9,7 @@ export const BREAKPOINTS = { export const API_ENDPOINTS = { CHAT_STREAM: "/chat_stream", INDEXES: "/indexes", - SEARCH_DID: "/search/did", + GET_ALL_INDEXES: "/dids/:id/indexes", SEARCH_LINKS: "/search/links", GET_USER_INDEXES: "/search/user_indexes", LIT_ACTIONS: "/lit_actions", From 6772308d3cefd56f834cf31a1ab29a68edf6b0e2 Mon Sep 17 00:00:00 2001 From: serhat Date: Tue, 16 Jan 2024 18:16:48 +0300 Subject: [PATCH 3/5] refactor api service --- web-app/src/hooks/useApp.tsx | 41 +++--------- web-app/src/services/api-service.ts | 99 +++++++++++++++++++---------- 2 files changed, 75 insertions(+), 65 deletions(-) diff --git a/web-app/src/hooks/useApp.tsx b/web-app/src/hooks/useApp.tsx index dfdf7280..fdb854b8 100644 --- a/web-app/src/hooks/useApp.tsx +++ b/web-app/src/hooks/useApp.tsx @@ -1,11 +1,9 @@ import { createContext, useState, useContext, useEffect, useCallback, } from "react"; -import { appConfig } from "config"; import CreateModal from "components/site/modal/CreateModal"; import EditProfileModal from "components/site/modal/EditProfileModal"; import ConfirmTransaction from "components/site/modal/Common/ConfirmTransaction"; -import LitService from "services/lit-service"; import apiService from "services/api-service"; import { Indexes, @@ -58,39 +56,18 @@ export const AppContextProvider = ({ children } : any) => { setCreateModalVisible(false); setTransactionApprovalWaiting(true); try { - const { pkpPublicKey } = await LitService.mintPkp(); - const sessionResponse = await LitService.getPKPSession(pkpPublicKey, appConfig.defaultCID); + const doc = await apiService.createIndex(title); - let personalSession = localStorage.getItem("did"); - if (!personalSession) { - throw Error('No personal session provided') - } - - let pkpSession = sessionResponse.session.serialize(); - if (!pkpSession) { - throw Error('No PKP session provided') - } + // ASK: why no doc check here, but below instead? + updateUserIndexState({ ...doc, ownerDID: profile } as Indexes, "add"); - const doc = await apiService.createIndex({ - params: { - title, - signerFunction: appConfig.defaultCID, - signerPublicKey: pkpPublicKey, - }, - pkpSession, - personalSession - }); - - // ASK: why no doc check here, but below instead? - updateUserIndexState({ ...doc, ownerDID: profile } as Indexes, "add"); - - if (doc) { - setTransactionApprovalWaiting(false); - await router.push(`/index/[indexId]`, `/index/${doc.id}`, { shallow: true }); - } + if (doc) { + setTransactionApprovalWaiting(false); + await router.push(`/index/[indexId]`, `/index/${doc.id}`, { shallow: true }); + } } catch (err) { - console.error("Couldn't create index", err) - alert("Couldn't create index :/") // TODO: handle better + console.error("Couldn't create index", err) + alert("Couldn't create index :/") // TODO: handle better } }; diff --git a/web-app/src/services/api-service.ts b/web-app/src/services/api-service.ts index 51c44da5..85b0df29 100644 --- a/web-app/src/services/api-service.ts +++ b/web-app/src/services/api-service.ts @@ -1,10 +1,12 @@ -import axios from "axios"; +import axios, { AxiosInstance } from 'axios'; import { appConfig } from "config"; import { Indexes, IndexLink, Link, UserIndex, } from "types/entity"; -import { API_ENDPOINTS } from "utils/constants"; +import { API_ENDPOINTS, DEFAULT_CREATE_INDEX_TITLE } from "utils/constants"; import { CID } from "multiformats"; +import LitService from "services/lit-service"; + export type HighlightType = T & { highlight?: { [key: string]: string[] } @@ -89,38 +91,69 @@ export interface LinksCrawlContentRequest { links: Link[]; } -const buildHeaders = (personalSession?: string, pkpSession?: string): any => { - return { - "X-Index-Personal-DID-Session": personalSession, - "X-Index-PKP-DID-Session": pkpSession, +class ApiService { + private static instance: ApiService; + private apiAxios: AxiosInstance; + private signerPublicKey: string = ''; + private signerFunction: string = appConfig.defaultCID; + + private constructor() { + this.apiAxios = axios.create({ baseURL: appConfig.apiUrl }); + this.init(); } -} -const apiAxios = axios.create({ - baseURL: appConfig.apiUrl, -}); + public static getInstance(): ApiService { + if (!ApiService.instance) { + ApiService.instance = new ApiService(); + } + return ApiService.instance; + } -class ApiService { - async createIndex({ - params, pkpSession, personalSession - }: { - params: Partial, pkpSession: string, personalSession: string - }): Promise { - const { data } = await apiAxios.post('/indexes', params, { - headers: buildHeaders(personalSession, pkpSession) - }); + buildHeaders = (personalSession?: string, pkpSession?: string): any => { + return { + "X-Index-Personal-DID-Session": personalSession, + "X-Index-PKP-DID-Session": pkpSession, + } + } + + async init(): Promise { + const { pkpPublicKey } = await LitService.mintPkp(); + this.signerPublicKey = pkpPublicKey; + + const sessionResponse = await LitService.getPKPSession(pkpPublicKey, appConfig.defaultCID); + const personalSession = localStorage.getItem("did"); + if (!personalSession) { + throw new Error("No personal session found"); + } + + const pkpSession = sessionResponse.session.serialize(); + if (!pkpSession) { + throw new Error("Couldn't get PKP session"); + } + + this.apiAxios.defaults.headers = this.buildHeaders(personalSession, pkpSession); + } + + async createIndex(title: string = DEFAULT_CREATE_INDEX_TITLE): Promise { + const body = { + title, + signerPublicKey: this.signerPublicKey, + signerFunction: this.signerFunction, + }; + + const { data } = await this.apiAxios.post('/indexes', body); return data; } async getAllIndexes(id: string): Promise { const url = API_ENDPOINTS.GET_ALL_INDEXES.replace(':id', id); - const { data } = await apiAxios.get(url); + const { data } = await this.apiAxios.get(url); return data; } async getUserIndexes(body: GetUserIndexesRequestBody): Promise { try { - const { data } = await apiAxios.post(API_ENDPOINTS.GET_USER_INDEXES, body); + const { data } = await this.apiAxios.post(API_ENDPOINTS.GET_USER_INDEXES, body); return data; } catch (err) { // TODO handle; @@ -128,7 +161,7 @@ class ApiService { } async getIndexById(indexId: string) : Promise { try { - const { data } = await apiAxios.get(`${API_ENDPOINTS.INDEXES}/${indexId}`); + const { data } = await this.apiAxios.get(`${API_ENDPOINTS.INDEXES}/${indexId}`); return data as Indexes; } catch (err: any) { // throw new Error(err.message); @@ -136,7 +169,7 @@ class ApiService { } async crawlLink(url: string): Promise { try { - const { data } = await apiAxios.get(API_ENDPOINTS.CRAWL, { + const { data } = await this.apiAxios.get(API_ENDPOINTS.CRAWL, { params: { url, }, @@ -148,7 +181,7 @@ class ApiService { } async searchLink(body: LinkSearchRequestBody): Promise { try { - const { data } = await apiAxios.post(API_ENDPOINTS.SEARCH_LINKS, body); + const { data } = await this.apiAxios.post(API_ENDPOINTS.SEARCH_LINKS, body); return data; } catch (err) { return null; @@ -156,7 +189,7 @@ class ApiService { } async getLITAction(cid: string): Promise { try { - const { data } = await apiAxios.get(`${API_ENDPOINTS.LIT_ACTIONS}/${cid}`); + const { data } = await this.apiAxios.get(`${API_ENDPOINTS.LIT_ACTIONS}/${cid}`); return data; } catch (err) { return null; @@ -164,7 +197,7 @@ class ApiService { } async postLITAction(conditions: LitActionConditions): Promise { try { - const { data } = await apiAxios.post(`${API_ENDPOINTS.LIT_ACTIONS}`, conditions); + const { data } = await this.apiAxios.post(`${API_ENDPOINTS.LIT_ACTIONS}`, conditions); return data as string; } catch (err) { return null; @@ -173,7 +206,7 @@ class ApiService { async getContract(network: string, address: string, tokenId?: string): Promise { try { // eslint-disable-next-line max-len - const { data } = await apiAxios.get(tokenId ? `${API_ENDPOINTS.NFT_METADATA}/${network}/${address}/${tokenId}` : `${API_ENDPOINTS.NFT_METADATA}/${network}/${address}`); + const { data } = await this.apiAxios.get(tokenId ? `${API_ENDPOINTS.NFT_METADATA}/${network}/${address}/${tokenId}` : `${API_ENDPOINTS.NFT_METADATA}/${network}/${address}`); return data; } catch (err) { return null; @@ -181,7 +214,7 @@ class ApiService { } async getWallet(ensName: string): Promise { try { - const { data } = await apiAxios.get(`${API_ENDPOINTS.ENS}/${ensName}`); + const { data } = await this.apiAxios.get(`${API_ENDPOINTS.ENS}/${ensName}`); return data; } catch (err) { return null; @@ -191,7 +224,7 @@ class ApiService { try { const formData = new FormData(); formData.append("file", file); - const { data } = await apiAxios.post<{ cid: CID }>(API_ENDPOINTS.UPLOAD_AVATAR, formData, { + const { data } = await this.apiAxios.post<{ cid: CID }>(API_ENDPOINTS.UPLOAD_AVATAR, formData, { headers: { "Content-Type": "multipart/form-data", }, @@ -203,7 +236,7 @@ class ApiService { } async zapierTestLogin(email: string, password: string) : Promise { try { - const { data } = await apiAxios.post(`${API_ENDPOINTS.ZAPIER_TEST_LOGIN}`, { email, password }); + const { data } = await this.apiAxios.post(`${API_ENDPOINTS.ZAPIER_TEST_LOGIN}`, { email, password }); return data as any; } catch (err: any) { // throw new Error(err.message); @@ -211,7 +244,7 @@ class ApiService { } async subscribeToNewsletter(email: string) : Promise { try { - const { data } = await apiAxios.post(`${API_ENDPOINTS.SUBSCRIBE_TO_NEWSLETTER}`, { email }); + const { data } = await this.apiAxios.post(`${API_ENDPOINTS.SUBSCRIBE_TO_NEWSLETTER}`, { email }); return data; } catch (err: any) { const errorMessage = err.response && err.response.data && err.response.data.message ? @@ -222,5 +255,5 @@ class ApiService { } } -const api = new ApiService(); -export default api; + +export default ApiService.getInstance(); From 9690746ffef6e1fda5aaf01e86e1fba5cd46e315 Mon Sep 17 00:00:00 2001 From: serhat Date: Tue, 16 Jan 2024 18:18:13 +0300 Subject: [PATCH 4/5] format files tab 2 --- web-app/src/config/index.ts | 176 ++++++++--------- web-app/src/hooks/useApp.tsx | 292 ++++++++++++++-------------- web-app/src/services/api-service.ts | 288 +++++++++++++-------------- 3 files changed, 378 insertions(+), 378 deletions(-) diff --git a/web-app/src/config/index.ts b/web-app/src/config/index.ts index 2a37ea7d..b1325205 100644 --- a/web-app/src/config/index.ts +++ b/web-app/src/config/index.ts @@ -1,92 +1,92 @@ export const appConfig = { - baseUrl: "https://index.network/", - apiUrl: "https://dev.index.network/api", // TODO: handle better - ipfsProxy: "https://indexas.infura-ipfs.io/ipfs", - ipfsInfura: "http://localhost:3001/avatar", - defaultCID: "QmZQ42inuRBMLh65UfUCGhMBWhHCsZtGVEKttV16mbrKrj", // Empty. - testNetwork: { - chainId: "0x2ac49", - chainName: "Chronicle - Lit Protocol Testnet", - nativeCurrency: { - name: "LIT", - symbol: "LIT", - decimals: 18, - }, - rpcUrls: ["https://chain-rpc.litprotocol.com/http"], - blockExplorerUrls: ["https://chain.litprotocol.com"], - }, - chains: { - ethereum: { - value: "ethereum", - label: "Ethereum", - abbreviation: "eth", - logo: "ethLogo.svg", - chainId: 1, - }, - polygon: { - value: "polygon", - label: "Polygon", - abbreviation: "matic", - logo: "polygonLogo.svg", - chainId: 137, + baseUrl: "https://index.network/", + apiUrl: "https://dev.index.network/api", // TODO: handle better + ipfsProxy: "https://indexas.infura-ipfs.io/ipfs", + ipfsInfura: "http://localhost:3001/avatar", + defaultCID: "QmZQ42inuRBMLh65UfUCGhMBWhHCsZtGVEKttV16mbrKrj", // Empty. + testNetwork: { + chainId: "0x2ac49", + chainName: "Chronicle - Lit Protocol Testnet", + nativeCurrency: { + name: "LIT", + symbol: "LIT", + decimals: 18, + }, + rpcUrls: ["https://chain-rpc.litprotocol.com/http"], + blockExplorerUrls: ["https://chain.litprotocol.com"], + }, + chains: { + ethereum: { + value: "ethereum", + label: "Ethereum", + abbreviation: "eth", + logo: "ethLogo.svg", + chainId: 1, + }, + polygon: { + value: "polygon", + label: "Polygon", + abbreviation: "matic", + logo: "polygonLogo.svg", + chainId: 137, - }, - arbitrum: { - value: "arbitrum", - label: "Arbitrum", - abbreviation: "arbitrum", - logo: "arbitrumLogo.svg", - chainId: 42161, - }, - avalanche: { - value: "avalanche", - label: "Avalanche C-Chain", - abbreviation: "avax", - logo: "avalancheLogo.svg", - chainId: 43114, - }, - optimism: { - value: "optimism", - label: "Optimism", - abbreviation: "op", - logo: "optimismLogo.jpeg", - chainId: 10, - }, - celo: { - value: "celo", - label: "Celo", - abbreviation: "celo", - logo: "celoLogo.svg", - chainId: 42220, - }, - fuji: { - value: "fuji", - label: "Avalanche FUJI Testnet", - abbreviation: "avalan", - logo: "avalancheLogo.svg", - chainId: 43113, - }, - mumbai: { - value: "mumbai", - label: "Mumbai", - abbreviation: "mumbai", - logo: "polygonLogo.svg", - chainId: 80001, - }, - goerli: { - value: "goerli", - label: "Goerli", - abbreviation: "goerli", - logo: "goerliLogo.png", - chainId: 5, - }, - aurora: { - value: "aurora", - label: "Aurora", - abbreviation: "aoa", - logo: "auroraLogo.svg", - chainId: 1313161554, - }, - }, + }, + arbitrum: { + value: "arbitrum", + label: "Arbitrum", + abbreviation: "arbitrum", + logo: "arbitrumLogo.svg", + chainId: 42161, + }, + avalanche: { + value: "avalanche", + label: "Avalanche C-Chain", + abbreviation: "avax", + logo: "avalancheLogo.svg", + chainId: 43114, + }, + optimism: { + value: "optimism", + label: "Optimism", + abbreviation: "op", + logo: "optimismLogo.jpeg", + chainId: 10, + }, + celo: { + value: "celo", + label: "Celo", + abbreviation: "celo", + logo: "celoLogo.svg", + chainId: 42220, + }, + fuji: { + value: "fuji", + label: "Avalanche FUJI Testnet", + abbreviation: "avalan", + logo: "avalancheLogo.svg", + chainId: 43113, + }, + mumbai: { + value: "mumbai", + label: "Mumbai", + abbreviation: "mumbai", + logo: "polygonLogo.svg", + chainId: 80001, + }, + goerli: { + value: "goerli", + label: "Goerli", + abbreviation: "goerli", + logo: "goerliLogo.png", + chainId: 5, + }, + aurora: { + value: "aurora", + label: "Aurora", + abbreviation: "aoa", + logo: "auroraLogo.svg", + chainId: 1313161554, + }, + }, }; diff --git a/web-app/src/hooks/useApp.tsx b/web-app/src/hooks/useApp.tsx index fdb854b8..83569db1 100644 --- a/web-app/src/hooks/useApp.tsx +++ b/web-app/src/hooks/useApp.tsx @@ -1,14 +1,14 @@ import { - createContext, useState, useContext, useEffect, useCallback, + createContext, useState, useContext, useEffect, useCallback, } from "react"; import CreateModal from "components/site/modal/CreateModal"; import EditProfileModal from "components/site/modal/EditProfileModal"; import ConfirmTransaction from "components/site/modal/Common/ConfirmTransaction"; import apiService from "services/api-service"; import { - Indexes, - Users, - MultipleIndexListState, + Indexes, + Users, + MultipleIndexListState, } from "types/entity"; import { useRouter } from "next/router"; import { v4 as uuidv4 } from "uuid"; @@ -18,44 +18,44 @@ import api from "../services/api-service"; import { DEFAULT_CREATE_INDEX_TITLE } from "utils/constants"; export interface AppContextValue { - indexes: Indexes[] - setIndexes: (indexes: Indexes[]) => void - getAllIndexes: () => void - section: keyof MultipleIndexListState - setSection: (section: keyof MultipleIndexListState) => void - setCreateModalVisible: (visible: boolean) => void - setTransactionApprovalWaiting: (visible: boolean) => void - leftSidebarOpen: boolean - setLeftSidebarOpen: (visible: boolean) => void - rightSidebarOpen: boolean - setRightSidebarOpen: (visible: boolean) => void - viewedProfile: Users | undefined - setViewedProfile: (profile: Users | undefined) => void - setEditProfileModalVisible: (visible: boolean) => void - updateUserIndexState: (index: Indexes, type: keyof MultipleIndexListState, op: string) => void - updateIndex: (index: Indexes) => void + indexes: Indexes[] + setIndexes: (indexes: Indexes[]) => void + getAllIndexes: () => void + section: keyof MultipleIndexListState + setSection: (section: keyof MultipleIndexListState) => void + setCreateModalVisible: (visible: boolean) => void + setTransactionApprovalWaiting: (visible: boolean) => void + leftSidebarOpen: boolean + setLeftSidebarOpen: (visible: boolean) => void + rightSidebarOpen: boolean + setRightSidebarOpen: (visible: boolean) => void + viewedProfile: Users | undefined + setViewedProfile: (profile: Users | undefined) => void + setEditProfileModalVisible: (visible: boolean) => void + updateUserIndexState: (index: Indexes, type: keyof MultipleIndexListState, op: string) => void + updateIndex: (index: Indexes) => void } export const AppContext = createContext({} as AppContextValue); -export const AppContextProvider = ({ children } : any) => { - const [createModalVisible, setCreateModalVisible] = useState(false); - const [leftSidebarOpen, setLeftSidebarOpen] = useState(false); - const [rightSidebarOpen, setRightSidebarOpen] = useState(false); - const [editProfileModalVisible, setEditProfileModalVisible] = useState(false); - const [transactionApprovalWaiting, setTransactionApprovalWaiting] = useState(false); - const [viewedProfile, setViewedProfile] = useState(); - const [section, setSection] = useState ("all" as keyof MultipleIndexListState); - const router = useRouter(); - const { did } = router.query; - const profile = useAppSelector(selectProfile); - - const [indexes, setIndexes] = useState([]); - - const handleCreate = async (title: string = DEFAULT_CREATE_INDEX_TITLE) => { - setCreateModalVisible(false); - setTransactionApprovalWaiting(true); - try { +export const AppContextProvider = ({ children }: any) => { + const [createModalVisible, setCreateModalVisible] = useState(false); + const [leftSidebarOpen, setLeftSidebarOpen] = useState(false); + const [rightSidebarOpen, setRightSidebarOpen] = useState(false); + const [editProfileModalVisible, setEditProfileModalVisible] = useState(false); + const [transactionApprovalWaiting, setTransactionApprovalWaiting] = useState(false); + const [viewedProfile, setViewedProfile] = useState(); + const [section, setSection] = useState("all" as keyof MultipleIndexListState); + const router = useRouter(); + const { did } = router.query; + const profile = useAppSelector(selectProfile); + + const [indexes, setIndexes] = useState([]); + + const handleCreate = async (title: string = DEFAULT_CREATE_INDEX_TITLE) => { + setCreateModalVisible(false); + setTransactionApprovalWaiting(true); + try { const doc = await apiService.createIndex(title); // ASK: why no doc check here, but below instead? @@ -65,118 +65,118 @@ export const AppContextProvider = ({ children } : any) => { setTransactionApprovalWaiting(false); await router.push(`/index/[indexId]`, `/index/${doc.id}`, { shallow: true }); } - } catch (err) { + } catch (err) { console.error("Couldn't create index", err) alert("Couldn't create index :/") // TODO: handle better - } - }; - - const updateIndex = (index: Indexes) => { - const updatedIndexes = indexes - .map((i) => (i.id === index.id ? { ...i, ...index } : i)); - - setIndexes(updatedIndexes); - }; - - const spreadProfileToIndexes = (profile: Users) => { - const updatedIndexes = indexes - .map((i) => (i.ownerDID.id === profile.id ? { ...i, ownerDID: profile } : i)); - - setIndexes(updatedIndexes); - }; - - const updateUserIndexState = (index: Indexes, op: string) => { - let updatedIndexes = [...indexes]; - - if (op === "add" && !indexes.some(i => i.id === index.id)) { - updatedIndexes.push(index); - } else if (op === "remove") { - updatedIndexes = updatedIndexes.filter(i => i.id !== index.id); - } - - setIndexes(updatedIndexes); - }; - - const handleTransactionCancel = () => { - setTransactionApprovalWaiting(false); - }; - - const getAllIndexes = useCallback(async () => { - if (!viewedProfile || !viewedProfile.id) return; // TODO: handle better maybe? - - try { - const res = await api.getAllIndexes(viewedProfile.id); - setIndexes(res); - } catch(err) { - console.error("Couldn't get indexes", err) - alert("Couldn't get indexes :/") // TODO: handle better - } - }, [viewedProfile?.id]); - - useEffect(() => { - viewedProfile && getAllIndexes(); - }, [viewedProfile?.id]); - - const activeKey = () => { - if (did) { - const url = new URL(`https://index.network${router.asPath}`); - return (url.searchParams.get("section") || "all") as keyof MultipleIndexListState; - } - return section; - }; - - useEffect(() => { - if (!localStorage.getItem("chatterID")) { - localStorage.setItem("chatterID", uuidv4()); - } - }, []); - - useEffect(() => { - setSection(activeKey()); - }, [router.asPath]); - - useEffect(() => { - if (!profile) return; - viewedProfile && profile.id === viewedProfile.id && setViewedProfile(profile); - spreadProfileToIndexes(profile); - }, [profile]); - - return ( - - {children} - {/* eslint-disable-next-line max-len */} - {transactionApprovalWaiting ? : <>} - {/* eslint-disable-next-line max-len */} - {createModalVisible ? setCreateModalVisible(false)} onCreate={handleCreate}> : <>} - {/* eslint-disable-next-line max-len */} - {editProfileModalVisible ? setEditProfileModalVisible(false)}> : <>} - - - ); + } + }; + + const updateIndex = (index: Indexes) => { + const updatedIndexes = indexes + .map((i) => (i.id === index.id ? { ...i, ...index } : i)); + + setIndexes(updatedIndexes); + }; + + const spreadProfileToIndexes = (profile: Users) => { + const updatedIndexes = indexes + .map((i) => (i.ownerDID.id === profile.id ? { ...i, ownerDID: profile } : i)); + + setIndexes(updatedIndexes); + }; + + const updateUserIndexState = (index: Indexes, op: string) => { + let updatedIndexes = [...indexes]; + + if (op === "add" && !indexes.some(i => i.id === index.id)) { + updatedIndexes.push(index); + } else if (op === "remove") { + updatedIndexes = updatedIndexes.filter(i => i.id !== index.id); + } + + setIndexes(updatedIndexes); + }; + + const handleTransactionCancel = () => { + setTransactionApprovalWaiting(false); + }; + + const getAllIndexes = useCallback(async () => { + if (!viewedProfile || !viewedProfile.id) return; // TODO: handle better maybe? + + try { + const res = await api.getAllIndexes(viewedProfile.id); + setIndexes(res); + } catch (err) { + console.error("Couldn't get indexes", err) + alert("Couldn't get indexes :/") // TODO: handle better + } + }, [viewedProfile?.id]); + + useEffect(() => { + viewedProfile && getAllIndexes(); + }, [viewedProfile?.id]); + + const activeKey = () => { + if (did) { + const url = new URL(`https://index.network${router.asPath}`); + return (url.searchParams.get("section") || "all") as keyof MultipleIndexListState; + } + return section; + }; + + useEffect(() => { + if (!localStorage.getItem("chatterID")) { + localStorage.setItem("chatterID", uuidv4()); + } + }, []); + + useEffect(() => { + setSection(activeKey()); + }, [router.asPath]); + + useEffect(() => { + if (!profile) return; + viewedProfile && profile.id === viewedProfile.id && setViewedProfile(profile); + spreadProfileToIndexes(profile); + }, [profile]); + + return ( + + {children} + {/* eslint-disable-next-line max-len */} + {transactionApprovalWaiting ? : <>} + {/* eslint-disable-next-line max-len */} + {createModalVisible ? setCreateModalVisible(false)} onCreate={handleCreate}> : <>} + {/* eslint-disable-next-line max-len */} + {editProfileModalVisible ? setEditProfileModalVisible(false)}> : <>} + + + ); }; // Custom hook to use the Boolean context export const useApp = () => { - const contextValue = useContext(AppContext); - if (contextValue === undefined) { - throw new Error("useAppContext must be used within a AppContextProvider"); - } - return contextValue; + const contextValue = useContext(AppContext); + if (contextValue === undefined) { + throw new Error("useAppContext must be used within a AppContextProvider"); + } + return contextValue; }; diff --git a/web-app/src/services/api-service.ts b/web-app/src/services/api-service.ts index 85b0df29..29a0f214 100644 --- a/web-app/src/services/api-service.ts +++ b/web-app/src/services/api-service.ts @@ -1,7 +1,7 @@ import axios, { AxiosInstance } from 'axios'; import { appConfig } from "config"; import { - Indexes, IndexLink, Link, UserIndex, + Indexes, IndexLink, Link, UserIndex, } from "types/entity"; import { API_ENDPOINTS, DEFAULT_CREATE_INDEX_TITLE } from "utils/constants"; import { CID } from "multiformats"; @@ -9,41 +9,41 @@ import LitService from "services/lit-service"; export type HighlightType = T & { - highlight?: { [key: string]: string[] } + highlight?: { [key: string]: string[] } }; export interface IndexResponse extends Indexes { highlight?: HighlightType; } export interface IndexSearchResponse { - all: { - totalCount: number; - records: Indexes[]; - }, - owner?: { - totalCount: number; - records: Indexes[]; - } - starred?: { - totalCount: number; - records: Indexes[]; - }, + all: { + totalCount: number; + records: Indexes[]; + }, + owner?: { + totalCount: number; + records: Indexes[]; + } + starred?: { + totalCount: number; + records: Indexes[]; + }, } export interface LinkSearchRequestBody extends ApiSearchRequestBody<{}> { - index_id: string; - skip: number; - take: number; - search?: string; + index_id: string; + skip: number; + take: number; + search?: string; } export interface GetUserIndexesRequestBody { - did: string; - index_id: string; + did: string; + index_id: string; } export interface DidSearchResponse { - totalCount: number; - records: Indexes[]; + totalCount: number; + records: Indexes[]; } export interface LitActionConditions { @@ -51,30 +51,30 @@ export interface LitActionConditions { } export interface LinkSearchResponse { - totalCount: number; - records: IndexLink[]; + totalCount: number; + records: IndexLink[]; } export interface UserIndexResponse { - owner?: UserIndex; - starred?: UserIndex; + owner?: UserIndex; + starred?: UserIndex; } export type SortType = "asc" | "desc"; export type ObjectFromKeys = { - [K in keyof T]: V; + [K in keyof T]: V; }; export interface BaseRequestFilterParams { - startDate?: Date; - endDate?: Date; - id?: number[] | string[]; - search?: string; - sort?: ObjectFromKeys; + startDate?: Date; + endDate?: Date; + id?: number[] | string[]; + search?: string; + sort?: ObjectFromKeys; } export interface BaseRequestPaginationParams { - skip?: number; - take?: number; + skip?: number; + take?: number; } export type ApiFilteredRequestBody = T & BaseRequestFilterParams; @@ -83,12 +83,12 @@ export type ApiPaginatedRequestBody = T & BaseRequestPaginationParams; export type ApiSearchRequestBody = Partial> & BaseRequestFilterParams & BaseRequestPaginationParams; export interface IndexesSearchRequestBody extends ApiSearchRequestBody { - // permission: IndexSearchRequestType; + // permission: IndexSearchRequestType; } export interface LinksCrawlContentRequest { - id: string; - links: Link[]; + id: string; + links: Link[]; } class ApiService { @@ -145,114 +145,114 @@ class ApiService { return data; } - async getAllIndexes(id: string): Promise { - const url = API_ENDPOINTS.GET_ALL_INDEXES.replace(':id', id); - const { data } = await this.apiAxios.get(url); - return data; - } + async getAllIndexes(id: string): Promise { + const url = API_ENDPOINTS.GET_ALL_INDEXES.replace(':id', id); + const { data } = await this.apiAxios.get(url); + return data; + } - async getUserIndexes(body: GetUserIndexesRequestBody): Promise { - try { - const { data } = await this.apiAxios.post(API_ENDPOINTS.GET_USER_INDEXES, body); - return data; - } catch (err) { - // TODO handle; - } - } - async getIndexById(indexId: string) : Promise { - try { - const { data } = await this.apiAxios.get(`${API_ENDPOINTS.INDEXES}/${indexId}`); - return data as Indexes; - } catch (err: any) { - // throw new Error(err.message); - } - } - async crawlLink(url: string): Promise { - try { - const { data } = await this.apiAxios.get(API_ENDPOINTS.CRAWL, { - params: { - url, - }, - }); - return data; - } catch (err) { - return null; - } - } - async searchLink(body: LinkSearchRequestBody): Promise { - try { - const { data } = await this.apiAxios.post(API_ENDPOINTS.SEARCH_LINKS, body); - return data; - } catch (err) { - return null; - } - } - async getLITAction(cid: string): Promise { - try { - const { data } = await this.apiAxios.get(`${API_ENDPOINTS.LIT_ACTIONS}/${cid}`); - return data; - } catch (err) { - return null; - } - } - async postLITAction(conditions: LitActionConditions): Promise { - try { - const { data } = await this.apiAxios.post(`${API_ENDPOINTS.LIT_ACTIONS}`, conditions); - return data as string; - } catch (err) { - return null; - } - } - async getContract(network: string, address: string, tokenId?: string): Promise { - try { - // eslint-disable-next-line max-len - const { data } = await this.apiAxios.get(tokenId ? `${API_ENDPOINTS.NFT_METADATA}/${network}/${address}/${tokenId}` : `${API_ENDPOINTS.NFT_METADATA}/${network}/${address}`); - return data; - } catch (err) { - return null; - } - } - async getWallet(ensName: string): Promise { - try { - const { data } = await this.apiAxios.get(`${API_ENDPOINTS.ENS}/${ensName}`); - return data; - } catch (err) { - return null; - } - } - async uploadAvatar(file: File): Promise<{ cid: CID } | null> { - try { - const formData = new FormData(); - formData.append("file", file); - const { data } = await this.apiAxios.post<{ cid: CID }>(API_ENDPOINTS.UPLOAD_AVATAR, formData, { - headers: { - "Content-Type": "multipart/form-data", - }, - }); - return data; - } catch (err) { - return null; - } - } - async zapierTestLogin(email: string, password: string) : Promise { - try { - const { data } = await this.apiAxios.post(`${API_ENDPOINTS.ZAPIER_TEST_LOGIN}`, { email, password }); - return data as any; - } catch (err: any) { - // throw new Error(err.message); - } - } - async subscribeToNewsletter(email: string) : Promise { - try { - const { data } = await this.apiAxios.post(`${API_ENDPOINTS.SUBSCRIBE_TO_NEWSLETTER}`, { email }); - return data; - } catch (err: any) { - const errorMessage = err.response && err.response.data && err.response.data.message ? - err.response.data.message : - err.message; - throw new Error(errorMessage); - } - } + async getUserIndexes(body: GetUserIndexesRequestBody): Promise { + try { + const { data } = await this.apiAxios.post(API_ENDPOINTS.GET_USER_INDEXES, body); + return data; + } catch (err) { + // TODO handle; + } + } + async getIndexById(indexId: string): Promise { + try { + const { data } = await this.apiAxios.get(`${API_ENDPOINTS.INDEXES}/${indexId}`); + return data as Indexes; + } catch (err: any) { + // throw new Error(err.message); + } + } + async crawlLink(url: string): Promise { + try { + const { data } = await this.apiAxios.get(API_ENDPOINTS.CRAWL, { + params: { + url, + }, + }); + return data; + } catch (err) { + return null; + } + } + async searchLink(body: LinkSearchRequestBody): Promise { + try { + const { data } = await this.apiAxios.post(API_ENDPOINTS.SEARCH_LINKS, body); + return data; + } catch (err) { + return null; + } + } + async getLITAction(cid: string): Promise { + try { + const { data } = await this.apiAxios.get(`${API_ENDPOINTS.LIT_ACTIONS}/${cid}`); + return data; + } catch (err) { + return null; + } + } + async postLITAction(conditions: LitActionConditions): Promise { + try { + const { data } = await this.apiAxios.post(`${API_ENDPOINTS.LIT_ACTIONS}`, conditions); + return data as string; + } catch (err) { + return null; + } + } + async getContract(network: string, address: string, tokenId?: string): Promise { + try { + // eslint-disable-next-line max-len + const { data } = await this.apiAxios.get(tokenId ? `${API_ENDPOINTS.NFT_METADATA}/${network}/${address}/${tokenId}` : `${API_ENDPOINTS.NFT_METADATA}/${network}/${address}`); + return data; + } catch (err) { + return null; + } + } + async getWallet(ensName: string): Promise { + try { + const { data } = await this.apiAxios.get(`${API_ENDPOINTS.ENS}/${ensName}`); + return data; + } catch (err) { + return null; + } + } + async uploadAvatar(file: File): Promise<{ cid: CID } | null> { + try { + const formData = new FormData(); + formData.append("file", file); + const { data } = await this.apiAxios.post<{ cid: CID }>(API_ENDPOINTS.UPLOAD_AVATAR, formData, { + headers: { + "Content-Type": "multipart/form-data", + }, + }); + return data; + } catch (err) { + return null; + } + } + async zapierTestLogin(email: string, password: string): Promise { + try { + const { data } = await this.apiAxios.post(`${API_ENDPOINTS.ZAPIER_TEST_LOGIN}`, { email, password }); + return data as any; + } catch (err: any) { + // throw new Error(err.message); + } + } + async subscribeToNewsletter(email: string): Promise { + try { + const { data } = await this.apiAxios.post(`${API_ENDPOINTS.SUBSCRIBE_TO_NEWSLETTER}`, { email }); + return data; + } catch (err: any) { + const errorMessage = err.response && err.response.data && err.response.data.message ? + err.response.data.message : + err.message; + throw new Error(errorMessage); + } + } } From 0b9775c253a24ad865509b74eccb39d13f5b4745 Mon Sep 17 00:00:00 2001 From: serhat Date: Wed, 17 Jan 2024 16:19:59 +0300 Subject: [PATCH 5/5] fix cr --- web-app/src/hooks/useApp.tsx | 12 ++++++------ web-app/src/services/api-service.ts | 30 ++++++----------------------- 2 files changed, 12 insertions(+), 30 deletions(-) diff --git a/web-app/src/hooks/useApp.tsx b/web-app/src/hooks/useApp.tsx index 83569db1..32fe1fab 100644 --- a/web-app/src/hooks/useApp.tsx +++ b/web-app/src/hooks/useApp.tsx @@ -58,13 +58,13 @@ export const AppContextProvider = ({ children }: any) => { try { const doc = await apiService.createIndex(title); - // ASK: why no doc check here, but below instead? - updateUserIndexState({ ...doc, ownerDID: profile } as Indexes, "add"); - - if (doc) { - setTransactionApprovalWaiting(false); - await router.push(`/index/[indexId]`, `/index/${doc.id}`, { shallow: true }); + if (!doc) { + throw new Error("API didn't return a doc"); } + + updateUserIndexState({ ...doc, ownerDID: profile } as Indexes, "add"); + setTransactionApprovalWaiting(false); + await router.push(`/index/[indexId]`, `/index/${doc.id}`, { shallow: true }); } catch (err) { console.error("Couldn't create index", err) alert("Couldn't create index :/") // TODO: handle better diff --git a/web-app/src/services/api-service.ts b/web-app/src/services/api-service.ts index 29a0f214..2b2c71a7 100644 --- a/web-app/src/services/api-service.ts +++ b/web-app/src/services/api-service.ts @@ -14,20 +14,6 @@ export type HighlightType = T & { export interface IndexResponse extends Indexes { highlight?: HighlightType; } -export interface IndexSearchResponse { - all: { - totalCount: number; - records: Indexes[]; - }, - owner?: { - totalCount: number; - records: Indexes[]; - } - starred?: { - totalCount: number; - records: Indexes[]; - }, -} export interface LinkSearchRequestBody extends ApiSearchRequestBody<{}> { index_id: string; @@ -94,8 +80,8 @@ export interface LinksCrawlContentRequest { class ApiService { private static instance: ApiService; private apiAxios: AxiosInstance; - private signerPublicKey: string = ''; - private signerFunction: string = appConfig.defaultCID; + private signerPublicKey: Indexes["signerPublicKey"] = ""; + private signerFunction: Indexes["signerFunction"] = appConfig.defaultCID; private constructor() { this.apiAxios = axios.create({ baseURL: appConfig.apiUrl }); @@ -109,13 +95,6 @@ class ApiService { return ApiService.instance; } - buildHeaders = (personalSession?: string, pkpSession?: string): any => { - return { - "X-Index-Personal-DID-Session": personalSession, - "X-Index-PKP-DID-Session": pkpSession, - } - } - async init(): Promise { const { pkpPublicKey } = await LitService.mintPkp(); this.signerPublicKey = pkpPublicKey; @@ -131,7 +110,10 @@ class ApiService { throw new Error("Couldn't get PKP session"); } - this.apiAxios.defaults.headers = this.buildHeaders(personalSession, pkpSession); + this.apiAxios.defaults.headers = { + "X-Index-Personal-DID-Session": personalSession, + "X-Index-PKP-DID-Session": pkpSession, + } as any; } async createIndex(title: string = DEFAULT_CREATE_INDEX_TITLE): Promise {