From 3b43c71a750f6a9c4c4818d229713763dbfe9766 Mon Sep 17 00:00:00 2001 From: soup-bowl Date: Thu, 3 Aug 2023 08:45:22 +0100 Subject: [PATCH 1/2] WPAPI replaced with Agent --- package-lock.json | 153 +------------------------------- package.json | 4 +- src/api/agent.ts | 121 +++++++++++++++++++++++++ src/components/siteSelector.tsx | 4 +- src/enums.ts | 10 +++ src/interfaces.ts | 11 ++- src/pages/_layout.tsx | 10 +-- src/pages/content.tsx | 17 ++-- src/pages/home.tsx | 15 ++-- src/pages/iterator.tsx | 38 ++++---- src/pages/search.tsx | 11 ++- 11 files changed, 190 insertions(+), 204 deletions(-) create mode 100644 src/api/agent.ts diff --git a/package-lock.json b/package-lock.json index 96103f4..655fefd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -17,7 +17,6 @@ "@types/node": "^20.4.0", "@types/react": "^18.2.14", "@types/react-dom": "^18.0.11", - "@types/wpapi": "^1.1.1", "@typescript-eslint/eslint-plugin": "^6.2.1", "@typescript-eslint/parser": "^6.2.1", "@vitejs/plugin-react-swc": "^3.3.2", @@ -31,8 +30,7 @@ "react-router-dom": "^6.11.2", "typescript": "^5.0.3", "vite": "^4.4.8", - "vite-plugin-pwa": "^0.16.4", - "wpapi": "^1.2.2" + "vite-plugin-pwa": "^0.16.4" } }, "node_modules/@aashutoshrathi/word-wrap": { @@ -2925,11 +2923,6 @@ "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.3.tgz", "integrity": "sha512-NfQ4gyz38SL8sDNrSixxU2Os1a5xcdFxipAFxYEuLUlvU2uDwS4NUpsImcf1//SlWItCVMMLiylsxbmNMToV/g==" }, - "node_modules/@types/wpapi": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/@types/wpapi/-/wpapi-1.1.1.tgz", - "integrity": "sha512-Ek1siuveAaN/iVoRvGbSGWNBg7RXQoz4Am1C3nnoXVA33f/0+9GibJq/xNBWsInZk5mNVqySkeYVco5C1KMqog==" - }, "node_modules/@typescript-eslint/eslint-plugin": { "version": "6.2.1", "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-6.2.1.tgz", @@ -3535,11 +3528,6 @@ "node": ">=4.0.0" } }, - "node_modules/component-emitter": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", - "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==" - }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -3550,11 +3538,6 @@ "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" }, - "node_modules/cookiejar": { - "version": "2.1.4", - "resolved": "https://registry.npmjs.org/cookiejar/-/cookiejar-2.1.4.tgz", - "integrity": "sha512-LDx6oHrK+PhzLKJU9j5S7/Y3jM/mUHvD/DeI1WQmJn652iPC5Y4TBzC9l+5OMOXlyTTA+SmVUPm0HQUwpD5Jqw==" - }, "node_modules/core-js-compat": { "version": "3.32.0", "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.32.0.tgz", @@ -4231,15 +4214,6 @@ "node": ">= 0.12" } }, - "node_modules/formidable": { - "version": "1.2.6", - "resolved": "https://registry.npmjs.org/formidable/-/formidable-1.2.6.tgz", - "integrity": "sha512-KcpbcpuLNOwrEjnbpMC0gS+X8ciDoZE1kkqzat4a8vrprf+s9pKNQ/QIwWfbfs4ltgmFl3MD177SNTkve3BwGQ==", - "deprecated": "Please upgrade to latest, formidable@v2 or formidable@v3! Check these notes: https://bit.ly/2ZEqIau", - "funding": { - "url": "https://ko-fi.com/tunnckoCore/commissions" - } - }, "node_modules/fs-extra": { "version": "9.1.0", "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", @@ -5090,11 +5064,6 @@ "node": ">= 0.8.0" } }, - "node_modules/li": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/li/-/li-1.3.0.tgz", - "integrity": "sha512-z34TU6GlMram52Tss5mt1m//ifRIpKH5Dqm7yUVOdHI+BQCs9qGPHFaCUTIzsWX7edN30aa2WrPwR7IO10FHaw==" - }, "node_modules/lines-and-columns": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz", @@ -5177,14 +5146,6 @@ "node": ">= 8" } }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "engines": { - "node": ">= 0.6" - } - }, "node_modules/micromatch": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", @@ -5197,17 +5158,6 @@ "node": ">=8.6" } }, - "node_modules/mime": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4.0.0" - } - }, "node_modules/mime-db": { "version": "1.52.0", "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz", @@ -5443,14 +5393,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/parse-link-header": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/parse-link-header/-/parse-link-header-1.0.1.tgz", - "integrity": "sha512-Z0gpfHmwCIKDr5rRzjypL+p93aHVWO7e+0rFcUl9E3sC67njjs+xHFenuboSXZGlvYtmQqRzRaE3iFpTUnLmFQ==", - "dependencies": { - "xtend": "~4.0.1" - } - }, "node_modules/path-exists": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", @@ -5699,19 +5641,6 @@ "react-dom": ">=16.6.0" } }, - "node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", - "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" - }, - "engines": { - "node": ">= 6" - } - }, "node_modules/regenerate": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.2.tgz", @@ -6102,14 +6031,6 @@ "node": ">=0.10.0" } }, - "node_modules/string_decoder": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", - "integrity": "sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==", - "dependencies": { - "safe-buffer": "~5.2.0" - } - }, "node_modules/string.prototype.matchall": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz", @@ -6218,40 +6139,6 @@ "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz", "integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==" }, - "node_modules/superagent": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/superagent/-/superagent-4.1.0.tgz", - "integrity": "sha512-FT3QLMasz0YyCd4uIi5HNe+3t/onxMyEho7C3PSqmti3Twgy2rXT4fmkTz6wRL6bTF4uzPcfkUCa8u4JWHw8Ag==", - "deprecated": "Please upgrade to v7.0.2+ of superagent. We have fixed numerous issues with streams, form-data, attach(), filesystem errors not bubbling up (ENOENT on attach()), and all tests are now passing. See the releases tab for more information at .", - "dependencies": { - "component-emitter": "^1.2.0", - "cookiejar": "^2.1.2", - "debug": "^4.1.0", - "form-data": "^2.3.3", - "formidable": "^1.2.0", - "methods": "^1.1.1", - "mime": "^2.4.0", - "qs": "^6.6.0", - "readable-stream": "^3.0.6" - }, - "engines": { - "node": ">= 6.0" - } - }, - "node_modules/superagent/node_modules/qs": { - "version": "6.11.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", - "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -6618,11 +6505,6 @@ "punycode": "^2.1.0" } }, - "node_modules/util-deprecate": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", - "integrity": "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==" - }, "node_modules/uuid": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", @@ -7115,44 +6997,11 @@ "workbox-core": "7.0.0" } }, - "node_modules/wpapi": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/wpapi/-/wpapi-1.2.2.tgz", - "integrity": "sha512-lkgi8Gjav3SArrCkNpG61ZnmCyamXKB+SjaR8tAoHhSZbJRTeabIlsdqUUAN3JGbVY3ht8p+EGdpCFIaanI5+w==", - "dependencies": { - "li": "^1.3.0", - "parse-link-header": "^1.0.1", - "qs": "^6.6.0", - "superagent": "^4.0.0" - } - }, - "node_modules/wpapi/node_modules/qs": { - "version": "6.11.2", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.2.tgz", - "integrity": "sha512-tDNIz22aBzCDxLtVH++VnTfzxlfeK5CbqohpSqpJgj1Wg/cQbStNAz3NuqCs5vV+pjBsK4x4pN9HlVh7rcYRiA==", - "dependencies": { - "side-channel": "^1.0.4" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, - "node_modules/xtend": { - "version": "4.0.2", - "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", - "integrity": "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ==", - "engines": { - "node": ">=0.4" - } - }, "node_modules/yallist": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", diff --git a/package.json b/package.json index f5fd70a..1d1d9ae 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,6 @@ "@types/node": "^20.4.0", "@types/react": "^18.2.14", "@types/react-dom": "^18.0.11", - "@types/wpapi": "^1.1.1", "@typescript-eslint/eslint-plugin": "^6.2.1", "@typescript-eslint/parser": "^6.2.1", "@vitejs/plugin-react-swc": "^3.3.2", @@ -26,8 +25,7 @@ "react-router-dom": "^6.11.2", "typescript": "^5.0.3", "vite": "^4.4.8", - "vite-plugin-pwa": "^0.16.4", - "wpapi": "^1.2.2" + "vite-plugin-pwa": "^0.16.4" }, "scripts": { "start": "npm run dev", diff --git a/src/api/agent.ts b/src/api/agent.ts new file mode 100644 index 0000000..d72cd84 --- /dev/null +++ b/src/api/agent.ts @@ -0,0 +1,121 @@ +import { EPostType, ETagType } from "../enums"; +import { IPost, IPostCollection, ISearch, ISearchCollection, ISiteInfo, ITag } from "../interfaces"; + +interface Construct { + endpoint: string; +} + +class WordPressApi { + private baseUrl: string; + + constructor({ endpoint }: Construct) { + this.baseUrl = endpoint; + } + + async fetchInfo(): Promise { + const url = this.baseUrl; + + try { + const response = await fetch(url); + if (!response.ok) { + throw new Error('Network response was not ok'); + } + + const data = await response.json(); + + return data as ISiteInfo; + } catch (error) { + console.error('Error fetching info:', error); + throw error; + } + } + + async fetchPosts(type: EPostType, page: number = 1, perPage: number = 12, byCategory: number = 0, byTag: number = 0): Promise { + const arg = (byCategory > 0) ? `&categories=${byTag}` : (byTag > 0) ? `&tags=${byTag}` : ''; + const url = `${this.baseUrl}/wp/v2/${(type === EPostType.Post ? 'posts' : 'pages')}?_embed=true&page=${page}&per_page=${perPage}${arg}`; + + try { + const response = await fetch(url); + if (!response.ok) { + throw new Error('Network response was not ok'); + } + + const headers = response.headers; + const data = await response.json(); + + return { + posts: data as IPost[], + pagination: { + total: parseInt(headers.get('X-Wp-Total') ?? '0'), + totalPages: parseInt(headers.get('X-Wp-Totalpages') ?? '0'), + } + }; + } catch (error) { + console.error('Error fetching posts:', error); + throw error; + } + } + + async fetchPost(id: number, type: EPostType): Promise { + const url = `${this.baseUrl}/wp/v2/${(type === EPostType.Post ? 'posts' : 'pages')}/${id}?_embed=true`; + + try { + const response = await fetch(url); + if (!response.ok) { + throw new Error('Network response was not ok'); + } + + const data = await response.json(); + + return data as IPost; + } catch (error) { + console.error('Error fetching post:', error); + throw error; + } + } + + async searchPosts(search: string, page: number = 1, perPage: number = 12): Promise { + const url = `${this.baseUrl}/wp/v2/search?_embed=true&page=${page}&per_page=${perPage}&search=${search}`; + + try { + const response = await fetch(url); + if (!response.ok) { + throw new Error('Network response was not ok'); + } + + const headers = response.headers; + const data = await response.json(); + + return { + results: data as ISearch[], + pagination: { + total: parseInt(headers.get('X-Wp-Total') ?? '0'), + totalPages: parseInt(headers.get('X-Wp-Totalpages') ?? '0'), + } + }; + } catch (error) { + console.error('Error searching posts:', error); + throw error; + } + } + + async fetchTag(id: number, type: ETagType): Promise { + const url = `${this.baseUrl}/wp/v2/${(type === ETagType.Category ? 'categories' : 'tags')}/${id}`; + + try { + const response = await fetch(url); + if (!response.ok) { + throw new Error('Network response was not ok'); + } + + const data = await response.json(); + + return data as ITag; + } catch (error) { + console.error('Error fetching post:', error); + throw error; + } + } +} + +export default WordPressApi; diff --git a/src/components/siteSelector.tsx b/src/components/siteSelector.tsx index 2b5cfc9..0cb8e32 100644 --- a/src/components/siteSelector.tsx +++ b/src/components/siteSelector.tsx @@ -5,12 +5,12 @@ import { import { ChangeEvent, useEffect, useRef, useState } from "react"; import { useNavigate } from "react-router-dom"; import { AppDialog } from "."; -import WPAPI from "wpapi"; import { useLocalStorageJSON } from "../localStore"; import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos'; import StarIcon from '@mui/icons-material/Star'; import DeleteIcon from '@mui/icons-material/Delete'; +import WordPressApi from "../api/agent"; export const localStorageRefs = { history: 'URLHistory', @@ -55,7 +55,7 @@ export const SiteSelectorDialog = ({ open, onClose, disableInput = false }: Site } searchTimeout.current = setTimeout(() => { - new WPAPI({ endpoint: `https://${searchValue}/wp-json` }).root().get() + new WordPressApi({ endpoint: `https://${searchValue}/wp-json` }).fetchInfo() .then(() => { setWP(true); setSearchValueValidated(searchValue); diff --git a/src/enums.ts b/src/enums.ts index 8a69b6d..3204d4d 100644 --- a/src/enums.ts +++ b/src/enums.ts @@ -3,3 +3,13 @@ export enum EStatus { Complete, Error } + +export enum EPostType { + Post, + Page +} + +export enum ETagType { + Category, + Tag +} diff --git a/src/interfaces.ts b/src/interfaces.ts index 6c83e04..17e5ab6 100644 --- a/src/interfaces.ts +++ b/src/interfaces.ts @@ -109,9 +109,18 @@ export interface IStorage { export interface IWPIndexing { total: number; totalPages: number; - links: IWPIndexingLinks; } export interface IWPIndexingLinks { next: string; } + +export interface IPostCollection { + posts: IPost[]; + pagination: IWPIndexing; +} + +export interface ISearchCollection { + results: ISearch[]; + pagination: IWPIndexing; +} diff --git a/src/pages/_layout.tsx b/src/pages/_layout.tsx index 3de72dc..c6b0354 100644 --- a/src/pages/_layout.tsx +++ b/src/pages/_layout.tsx @@ -8,18 +8,18 @@ import { import { createContext, FormEvent, useEffect, useMemo, useState } from "react"; import { ISiteInfo } from "../interfaces"; import { Loading, MenuItems, PrincipalAPIError } from "../components"; -import WPAPI from "wpapi"; import { EStatus } from "../enums"; import { useLocalStorage } from "../localStore"; import ColorThief from "colorthief"; import MenuIcon from '@mui/icons-material/Menu'; import SearchIcon from '@mui/icons-material/Search'; +import WordPressApi from "../api/agent"; const drawerWidth = 240; export const ColorModeContext = createContext({ toggleColorMode: () => { } }); -export const WordPressContext = createContext(new WPAPI({ endpoint: '' })); +export const WordPressContext = createContext(new WordPressApi({ endpoint: '' })); declare module '@mui/material/styles' { interface Theme { @@ -139,7 +139,7 @@ export const Layout = ({ simple = false }: Props) => { const [apiState, setApiState] = useState(EStatus.Loading); const [apiError, setApiError] = useState(''); const [primaryColor, setPrimaryColor] = useState('#3858e9'); - const wp = new WPAPI({ endpoint: `https://${inputURL}/wp-json` }); + const wp = new WordPressApi({ endpoint: `https://${inputURL}/wp-json` }); const [mode, setMode] = useLocalStorage('ColourPref', 'dark'); const colorMode = useMemo(() => ({ @@ -216,8 +216,8 @@ export const Layout = ({ simple = false }: Props) => { useEffect(() => { setApiState(EStatus.Loading); - wp.root().get() - .then((response: any) => { + wp.fetchInfo() + .then((response: ISiteInfo) => { setApiError(''); setMainInfo({ name: response.name ?? 'N/A', diff --git a/src/pages/content.tsx b/src/pages/content.tsx index cadb0ac..b3c41ff 100644 --- a/src/pages/content.tsx +++ b/src/pages/content.tsx @@ -7,6 +7,7 @@ import { } from "../components"; import { IPost } from "../interfaces"; import { WordPressContext } from "./_layout"; +import { EPostType } from "../enums"; const StyledStack = styled(Stack)(({ theme }) => ({ [theme.breakpoints.down('sm')]: { @@ -30,10 +31,10 @@ const Content = ({ posts, pages }: Props) => { const [apiError, setApiError] = useState(''); const wp = useContext(WordPressContext); - const saveResponse = (p: any) => { - setPost(p as IPost); + const saveResponse = (p: IPost) => { + setPost(p); - if (p.type === 'page') { + /*if (p.type === 'page') { wp.pages().param('parent', p.id).embed().get() .then((c: any) => { delete c['_paging']; @@ -46,7 +47,7 @@ const Content = ({ posts, pages }: Props) => { setParent(c as IPost); }); } - } + }*/ setLoadingContent(false); } @@ -60,14 +61,14 @@ const Content = ({ posts, pages }: Props) => { setLoadingContent(true); if (posts && postID !== undefined) { - wp.posts().embed().id(parseInt(postID)).get() - .then((post: any) => saveResponse(post)) + wp.fetchPost(parseInt(postID), EPostType.Post) + .then((post: IPost) => saveResponse(post)) .catch((err: any) => errResponse(err)); } if (pages && postID !== undefined) { - wp.pages().embed().id(parseInt(postID)).get() - .then((post: any) => saveResponse(post)) + wp.fetchPost(parseInt(postID), EPostType.Page) + .then((post: IPost) => saveResponse(post)) .catch((err: any) => errResponse(err)); } // eslint-disable-next-line react-hooks/exhaustive-deps diff --git a/src/pages/home.tsx b/src/pages/home.tsx index fd68cf0..b33806a 100644 --- a/src/pages/home.tsx +++ b/src/pages/home.tsx @@ -6,11 +6,12 @@ import { useNavigate, useOutletContext, useParams } from 'react-router-dom'; import { IPost, ISiteInfo, IWPAPIError } from '../interfaces'; import { CardDisplay, CardLoad, GeneralAPIError, SiteSelectorDialog, localStorageRefs } from '../components'; import { WordPressContext } from './_layout'; -import WPAPI from 'wpapi'; import { useLocalStorageJSON } from '../localStore'; import GitHubIcon from '@mui/icons-material/GitHub'; import "@fontsource/eb-garamond"; +import WordPressApi from '../api/agent'; +import { EPostType } from '../enums'; export const MainHome = () => { const navigate = useNavigate(); @@ -52,7 +53,7 @@ export const MainHome = () => { } searchTimeout.current = setTimeout(() => { - new WPAPI({ endpoint: `https://${searchValue}/wp-json` }).root().get() + new WordPressApi({ endpoint: `https://${searchValue}/wp-json` }).fetchInfo() .then(() => { setWP(true); setSearchValueValidated(searchValue); @@ -131,13 +132,11 @@ export const AppHome = () => { useEffect(() => { Promise.all([ - wp.posts().perPage(3).embed().get(), - wp.pages().perPage(3).embed().get(), + wp.fetchPosts(EPostType.Post, 1, 3), + wp.fetchPosts(EPostType.Page, 1, 3), ]).then(values => { - delete values[0]['_paging']; - delete values[1]['_paging']; - setPostCollection(values[0]); - setPageCollection(values[1]); + setPostCollection(values[0].posts); + setPageCollection(values[1].posts); setLoadingContent(false); }).catch((err:IWPAPIError) => { setApiError(`[${err.code}] ${err.message}`); diff --git a/src/pages/iterator.tsx b/src/pages/iterator.tsx index f3d1f3f..ee4c2b3 100644 --- a/src/pages/iterator.tsx +++ b/src/pages/iterator.tsx @@ -2,8 +2,9 @@ import { Box, Typography } from "@mui/material"; import { useContext, useEffect, useState } from "react"; import { useOutletContext, useParams } from "react-router-dom"; import { CardDisplay, CardLoad, GeneralAPIError } from "../components"; -import { IPost, ISiteInfo, ITag, IWPAPIError, IWPIndexing } from "../interfaces"; +import { IPost, IPostCollection, ISiteInfo, ITag, IWPAPIError, IWPIndexing } from "../interfaces"; import { WordPressContext } from "./_layout"; +import { EPostType, ETagType } from "../enums"; const displayedLimit: number = 12; @@ -26,18 +27,17 @@ export const PostListings = ({ posts = false, pages = false, categories = false, const wp = useContext(WordPressContext); const CommonInterface = { - posts: () => wp.posts().perPage(displayedLimit).page(parseInt(pageID ?? '1')).embed().get(), - postsByCategory: (cat: number) => wp.posts().categories(cat).perPage(displayedLimit).page(parseInt(pageID ?? '1')).embed().get(), - postsByTag: (cat: number) => wp.posts().tags(cat).perPage(displayedLimit).page(parseInt(pageID ?? '1')).embed().get(), - pages: () => wp.pages().perPage(displayedLimit).page(parseInt(pageID ?? '1')).embed().get(), - pagesByCategory: (cat: number) => wp.pages().categories(cat).perPage(displayedLimit).page(parseInt(pageID ?? '1')).embed().get(), - pagesByTag: (cat: number) => wp.pages().tags(cat).perPage(displayedLimit).page(parseInt(pageID ?? '1')).embed().get(), + posts: () => wp.fetchPosts(EPostType.Post, parseInt(pageID ?? '1'), displayedLimit), + postsByCategory: (cat: number) => wp.fetchPosts(EPostType.Post, parseInt(pageID ?? '1'), displayedLimit, cat, 0), + postsByTag: (cat: number) => wp.fetchPosts(EPostType.Post, parseInt(pageID ?? '1'), displayedLimit, 0, cat), + pages: () => wp.fetchPosts(EPostType.Page, parseInt(pageID ?? '1'), displayedLimit), + pagesByCategory: (cat: number) => wp.fetchPosts(EPostType.Page, parseInt(pageID ?? '1'), displayedLimit, cat, 0), + pagesByTag: (cat: number) => wp.fetchPosts(EPostType.Page, parseInt(pageID ?? '1'), displayedLimit, 0, cat), } - const saveResponse = (posts: any) => { - setPaging(posts._paging); - delete posts['_paging']; - setPostCollection(posts); + const saveResponse = (posts: IPostCollection) => { + setPaging(posts.pagination); + setPostCollection(posts.posts); setLoadingContent(false); } @@ -54,17 +54,17 @@ export const PostListings = ({ posts = false, pages = false, categories = false, if (categories) { setPagingURL(`/${inputURL}/posts/category/${searchID}`); CommonInterface.postsByCategory(parseInt(searchID ?? '0')) - .then((posts: any) => saveResponse(posts)) + .then((posts: IPostCollection) => saveResponse(posts)) .catch((err: IWPAPIError) => errResponse(err)); } else if (tax) { setPagingURL(`/${inputURL}/posts/tag/${searchID}`); CommonInterface.postsByTag(parseInt(searchID ?? '0')) - .then((posts: any) => saveResponse(posts)) + .then((posts: IPostCollection) => saveResponse(posts)) .catch((err: IWPAPIError) => errResponse(err)); } else { setPagingURL(`/${inputURL}/posts`); CommonInterface.posts() - .then((posts: any) => saveResponse(posts)) + .then((posts: IPostCollection) => saveResponse(posts)) .catch((err: IWPAPIError) => errResponse(err)); } } @@ -74,17 +74,17 @@ export const PostListings = ({ posts = false, pages = false, categories = false, if (categories) { setPagingURL(`/${inputURL}/pages/category/${searchID}`); CommonInterface.pagesByCategory(parseInt(searchID ?? '0')) - .then((posts: any) => saveResponse(posts)) + .then((posts: IPostCollection) => saveResponse(posts)) .catch((err: IWPAPIError) => errResponse(err)); } else if (tax) { setPagingURL(`/${inputURL}/pages/tag/${searchID}`); CommonInterface.pagesByTag(parseInt(searchID ?? '0')) - .then((posts: any) => saveResponse(posts)) + .then((posts: IPostCollection) => saveResponse(posts)) .catch((err: IWPAPIError) => errResponse(err)); } else { setPagingURL(`/${inputURL}/pages`); CommonInterface.pages() - .then((posts: any) => saveResponse(posts)) + .then((posts: IPostCollection) => saveResponse(posts)) .catch((err: IWPAPIError) => errResponse(err)); } } @@ -93,12 +93,12 @@ export const PostListings = ({ posts = false, pages = false, categories = false, useEffect(() => { if (categories && searchID !== undefined) { - wp.categories().id(parseInt(searchID)).get() + wp.fetchTag(parseInt(searchID), ETagType.Category) .then((catdef: ITag) => setIterDef(catdef.name ?? iterDef)); } if (tax && searchID !== undefined) { - wp.tags().id(parseInt(searchID)).get() + wp.fetchTag(parseInt(searchID), ETagType.Tag) .then((catdef: ITag) => setIterDef(catdef.name ?? iterDef)); } // eslint-disable-next-line react-hooks/exhaustive-deps diff --git a/src/pages/search.tsx b/src/pages/search.tsx index 1519199..d9204c4 100644 --- a/src/pages/search.tsx +++ b/src/pages/search.tsx @@ -2,7 +2,7 @@ import { Box, Typography } from "@mui/material"; import { useContext, useEffect, useState } from "react"; import { useParams } from "react-router-dom"; import { CardDisplay, CardLoad, GeneralAPIError } from "../components"; -import { IPost, ISearch, IWPAPIError, IWPIndexing } from "../interfaces"; +import { IPost, ISearch, ISearchCollection, IWPAPIError, IWPIndexing } from "../interfaces"; import { WordPressContext } from "./_layout"; const displayedLimit: number = 12; @@ -18,12 +18,11 @@ const Search = () => { useEffect(() => { setLoadingContent(true); - wp.search().search(seachTerms ?? '').perPage(displayedLimit).page(parseInt(pageID ?? '1')).embed().get() - .then((response: any) => { - setPaging(response._paging); - delete response['_paging']; + wp.searchPosts(seachTerms ?? '', parseInt(pageID ?? '1'), displayedLimit) + .then((response: ISearchCollection) => { + setPaging(response.pagination); const collection: IPost[] = []; - response.forEach((e: ISearch) => collection.push(e._embedded.self[0])); + response.results.forEach((e: ISearch) => collection.push(e._embedded.self[0])); setPagingURL(`/${inputURL}/search/${seachTerms}`); setSearchResults(collection); setLoadingContent(false); From 96b6463540aa708c6968e379737a2835fc4ea73d Mon Sep 17 00:00:00 2001 From: soup-bowl Date: Thu, 3 Aug 2023 12:45:41 +0100 Subject: [PATCH 2/2] Moved WP Calls to dedicated class. --- src/api/agent.ts | 121 --------------------- src/api/enums.ts | 9 ++ src/api/index.ts | 3 + src/{ => api}/interfaces.ts | 26 +++++ src/api/wordpress.ts | 179 ++++++++++++++++++++++++++++++++ src/components/cards.tsx | 2 +- src/components/siteSelector.tsx | 2 +- src/components/tags.tsx | 2 +- src/enums.ts | 10 -- src/pages/_layout.tsx | 3 +- src/pages/content.tsx | 20 ++-- src/pages/home.tsx | 10 +- src/pages/info.tsx | 2 +- src/pages/iterator.tsx | 15 ++- src/pages/search.tsx | 4 +- 15 files changed, 242 insertions(+), 166 deletions(-) delete mode 100644 src/api/agent.ts create mode 100644 src/api/enums.ts create mode 100644 src/api/index.ts rename src/{ => api}/interfaces.ts (82%) create mode 100644 src/api/wordpress.ts diff --git a/src/api/agent.ts b/src/api/agent.ts deleted file mode 100644 index d72cd84..0000000 --- a/src/api/agent.ts +++ /dev/null @@ -1,121 +0,0 @@ -import { EPostType, ETagType } from "../enums"; -import { IPost, IPostCollection, ISearch, ISearchCollection, ISiteInfo, ITag } from "../interfaces"; - -interface Construct { - endpoint: string; -} - -class WordPressApi { - private baseUrl: string; - - constructor({ endpoint }: Construct) { - this.baseUrl = endpoint; - } - - async fetchInfo(): Promise { - const url = this.baseUrl; - - try { - const response = await fetch(url); - if (!response.ok) { - throw new Error('Network response was not ok'); - } - - const data = await response.json(); - - return data as ISiteInfo; - } catch (error) { - console.error('Error fetching info:', error); - throw error; - } - } - - async fetchPosts(type: EPostType, page: number = 1, perPage: number = 12, byCategory: number = 0, byTag: number = 0): Promise { - const arg = (byCategory > 0) ? `&categories=${byTag}` : (byTag > 0) ? `&tags=${byTag}` : ''; - const url = `${this.baseUrl}/wp/v2/${(type === EPostType.Post ? 'posts' : 'pages')}?_embed=true&page=${page}&per_page=${perPage}${arg}`; - - try { - const response = await fetch(url); - if (!response.ok) { - throw new Error('Network response was not ok'); - } - - const headers = response.headers; - const data = await response.json(); - - return { - posts: data as IPost[], - pagination: { - total: parseInt(headers.get('X-Wp-Total') ?? '0'), - totalPages: parseInt(headers.get('X-Wp-Totalpages') ?? '0'), - } - }; - } catch (error) { - console.error('Error fetching posts:', error); - throw error; - } - } - - async fetchPost(id: number, type: EPostType): Promise { - const url = `${this.baseUrl}/wp/v2/${(type === EPostType.Post ? 'posts' : 'pages')}/${id}?_embed=true`; - - try { - const response = await fetch(url); - if (!response.ok) { - throw new Error('Network response was not ok'); - } - - const data = await response.json(); - - return data as IPost; - } catch (error) { - console.error('Error fetching post:', error); - throw error; - } - } - - async searchPosts(search: string, page: number = 1, perPage: number = 12): Promise { - const url = `${this.baseUrl}/wp/v2/search?_embed=true&page=${page}&per_page=${perPage}&search=${search}`; - - try { - const response = await fetch(url); - if (!response.ok) { - throw new Error('Network response was not ok'); - } - - const headers = response.headers; - const data = await response.json(); - - return { - results: data as ISearch[], - pagination: { - total: parseInt(headers.get('X-Wp-Total') ?? '0'), - totalPages: parseInt(headers.get('X-Wp-Totalpages') ?? '0'), - } - }; - } catch (error) { - console.error('Error searching posts:', error); - throw error; - } - } - - async fetchTag(id: number, type: ETagType): Promise { - const url = `${this.baseUrl}/wp/v2/${(type === ETagType.Category ? 'categories' : 'tags')}/${id}`; - - try { - const response = await fetch(url); - if (!response.ok) { - throw new Error('Network response was not ok'); - } - - const data = await response.json(); - - return data as ITag; - } catch (error) { - console.error('Error fetching post:', error); - throw error; - } - } -} - -export default WordPressApi; diff --git a/src/api/enums.ts b/src/api/enums.ts new file mode 100644 index 0000000..fff177f --- /dev/null +++ b/src/api/enums.ts @@ -0,0 +1,9 @@ +export enum EPostType { + Post, + Page +} + +export enum ETagType { + Category, + Tag +} diff --git a/src/api/index.ts b/src/api/index.ts new file mode 100644 index 0000000..0efd920 --- /dev/null +++ b/src/api/index.ts @@ -0,0 +1,3 @@ +export { default as WordPressApi } from './wordpress'; +export * from './interfaces'; +export * from './enums'; diff --git a/src/interfaces.ts b/src/api/interfaces.ts similarity index 82% rename from src/interfaces.ts rename to src/api/interfaces.ts index 17e5ab6..0953cdf 100644 --- a/src/interfaces.ts +++ b/src/api/interfaces.ts @@ -1,3 +1,29 @@ +// Interaction Interfaces + +import { EPostType } from "."; + +export interface IInnnerConstruct { + endpoint: string; +} + +export interface IndexableInput { + page?: number; + perPage?: number; + byCategory?: number; + byTag?: number; +} + +export interface FetchInput extends IndexableInput { + type: EPostType; + parent?: number; +} + +export interface SearchInput extends IndexableInput { + search: string; +} + +// Data Interfaces + export interface IWPAPIError { code: string; message: string; diff --git a/src/api/wordpress.ts b/src/api/wordpress.ts new file mode 100644 index 0000000..332e20b --- /dev/null +++ b/src/api/wordpress.ts @@ -0,0 +1,179 @@ +import { + EPostType, ETagType, FetchInput, IInnnerConstruct, IPost, IPostCollection, + ISearch, ISearchCollection, ISiteInfo, ITag, SearchInput +} from "."; + +class WordPressApi { + /** + * The base URL of the WordPress REST API. + */ + private baseUrl: string; + + /** + * Creates an instance of the WordPressApi. + * @constructor + * @param {Construct} options - The options to configure the WordPressApi. + * @param {string} options.endpoint - The base URL of the WordPress REST API. + */ + constructor({ endpoint }: IInnnerConstruct) { + this.baseUrl = endpoint; + } + + /** + * Fetches site information from the WordPress site. + * @async + * @function + * @returns {Promise} A Promise that resolves to the site information. + * @throws {Error} If the network response is not ok or an error occurs during the fetch. + */ + async fetchInfo(): Promise { + const url = this.baseUrl; + + try { + const response = await fetch(url); + if (!response.ok) { + throw new Error('Network response was not ok'); + } + + const data = await response.json(); + + return data as ISiteInfo; + } catch (error) { + console.error('Error fetching info:', error); + throw error; + } + } + + /** + * Fetches a collection of posts or pages from the WordPress site. + * @async + * @function + * @param {FetchInput} options - The options to configure the fetch. + * @param {EPostType} options.type - The type of the content to fetch (post or page). + * @param {number} [options.page] - The page number for pagination (default is 1). + * @param {number} [options.perPage] - The number of results per page (default is 12). + * @param {number} [options.byCategory] - The ID of the category to filter by (default is 0, no filter). + * @param {number} [options.byTag] - The ID of the tag to filter by (default is 0, no filter). + * @param {number} [options.parent] - The ID of the parent page (for hierarchical content, default is 0, no filter). + * @returns {Promise} A Promise that resolves to the collection of posts or pages. + * @throws {Error} If the network response is not ok or an error occurs during the fetch. + */ + async fetchPosts({ type, page = 1, perPage = 12, byCategory = 0, byTag = 0, parent = 0 }: FetchInput): Promise { + const arg = (byCategory > 0) ? `&categories=${byCategory}` : (byTag > 0) ? `&tags=${byTag}` : ''; + const pnt = (parent > 0) ? `&parent=${parent}` : ''; + const url = `${this.baseUrl}/wp/v2/${(type === EPostType.Post ? 'posts' : 'pages')}?_embed=true&page=${page}&per_page=${perPage}${arg}${pnt}`; + + try { + const response = await fetch(url); + if (!response.ok) { + throw new Error('Network response was not ok'); + } + + const headers = response.headers; + const data = await response.json(); + + return { + posts: data as IPost[], + pagination: { + total: parseInt(headers.get('X-Wp-Total') ?? '0'), + totalPages: parseInt(headers.get('X-Wp-Totalpages') ?? '0'), + } + }; + } catch (error) { + console.error('Error fetching posts:', error); + throw error; + } + } + + /** + * Fetches a single post or page from the WordPress site. + * @async + * @function + * @param {number} id - The ID of the post or page to fetch. + * @param {EPostType} type - The type of the content to fetch (post or page). + * @returns {Promise} A Promise that resolves to the fetched post or page. + * @throws {Error} If the network response is not ok or an error occurs during the fetch. + */ + async fetchPost(id: number, type: EPostType): Promise { + const url = `${this.baseUrl}/wp/v2/${(type === EPostType.Post ? 'posts' : 'pages')}/${id}?_embed=true`; + + try { + const response = await fetch(url); + if (!response.ok) { + throw new Error('Network response was not ok'); + } + + const data = await response.json(); + + return data as IPost; + } catch (error) { + console.error('Error fetching post:', error); + throw error; + } + } + + /** + * Searches for posts or pages on the WordPress site based on the given search query. + * @async + * @function + * @param {SearchInput} options - The options to configure the search. + * @param {string} options.search - The search query to look for in the posts/pages. + * @param {number} [options.page] - The page number for pagination (default is 1). + * @param {number} [options.perPage] - The number of results per page (default is 12). + * @returns {Promise} A Promise that resolves to the search results and pagination info. + * @throws {Error} If the network response is not ok or an error occurs during the fetch. + */ + async searchPosts({ search, page = 1, perPage = 12 }: SearchInput): Promise { + const url = `${this.baseUrl}/wp/v2/search?_embed=true&page=${page}&per_page=${perPage}&search=${search}`; + + try { + const response = await fetch(url); + if (!response.ok) { + throw new Error('Network response was not ok'); + } + + const headers = response.headers; + const data = await response.json(); + + return { + results: data as ISearch[], + pagination: { + total: parseInt(headers.get('X-Wp-Total') ?? '0'), + totalPages: parseInt(headers.get('X-Wp-Totalpages') ?? '0'), + } + }; + } catch (error) { + console.error('Error searching posts:', error); + throw error; + } + } + + /** + * Fetches a single tag or category from the WordPress site. + * @async + * @function + * @param {number} id - The ID of the tag or category to fetch. + * @param {ETagType} type - The type of the taxonomy term to fetch (category or tag). + * @returns {Promise} A Promise that resolves to the fetched tag or category. + * @throws {Error} If the network response is not ok or an error occurs during the fetch. + */ + async fetchTag(id: number, type: ETagType): Promise { + const url = `${this.baseUrl}/wp/v2/${(type === ETagType.Category ? 'categories' : 'tags')}/${id}`; + + try { + const response = await fetch(url); + if (!response.ok) { + throw new Error('Network response was not ok'); + } + + const data = await response.json(); + + return data as ITag; + } catch (error) { + console.error('Error fetching post:', error); + throw error; + } + } +} + +export default WordPressApi; diff --git a/src/components/cards.tsx b/src/components/cards.tsx index 667f1e9..969ded3 100644 --- a/src/components/cards.tsx +++ b/src/components/cards.tsx @@ -1,6 +1,6 @@ import { Box, Card, CardActionArea, CardContent, CardMedia, Grid, Pagination, Skeleton, Typography } from "@mui/material"; import { useNavigate, useParams } from "react-router-dom"; -import { IPost, IWPIndexing } from "../interfaces"; +import { IPost, IWPIndexing } from "../api"; interface Props { posts: IPost[]; diff --git a/src/components/siteSelector.tsx b/src/components/siteSelector.tsx index 0cb8e32..3396323 100644 --- a/src/components/siteSelector.tsx +++ b/src/components/siteSelector.tsx @@ -10,7 +10,7 @@ import { useLocalStorageJSON } from "../localStore"; import ArrowForwardIosIcon from '@mui/icons-material/ArrowForwardIos'; import StarIcon from '@mui/icons-material/Star'; import DeleteIcon from '@mui/icons-material/Delete'; -import WordPressApi from "../api/agent"; +import { WordPressApi } from "../api"; export const localStorageRefs = { history: 'URLHistory', diff --git a/src/components/tags.tsx b/src/components/tags.tsx index 12d8430..70361c9 100644 --- a/src/components/tags.tsx +++ b/src/components/tags.tsx @@ -1,6 +1,6 @@ import { Chip, Typography } from "@mui/material"; import { useNavigate } from "react-router-dom"; -import { ITag } from "../interfaces"; +import { ITag } from "../api"; interface TagProps { tags: ITag[]; diff --git a/src/enums.ts b/src/enums.ts index 3204d4d..8a69b6d 100644 --- a/src/enums.ts +++ b/src/enums.ts @@ -3,13 +3,3 @@ export enum EStatus { Complete, Error } - -export enum EPostType { - Post, - Page -} - -export enum ETagType { - Category, - Tag -} diff --git a/src/pages/_layout.tsx b/src/pages/_layout.tsx index c6b0354..e2bc55b 100644 --- a/src/pages/_layout.tsx +++ b/src/pages/_layout.tsx @@ -6,7 +6,7 @@ import { createTheme, PaletteMode, Chip, Avatar, Badge } from '@mui/material'; import { createContext, FormEvent, useEffect, useMemo, useState } from "react"; -import { ISiteInfo } from "../interfaces"; +import { ISiteInfo, WordPressApi } from "../api"; import { Loading, MenuItems, PrincipalAPIError } from "../components"; import { EStatus } from "../enums"; import { useLocalStorage } from "../localStore"; @@ -14,7 +14,6 @@ import ColorThief from "colorthief"; import MenuIcon from '@mui/icons-material/Menu'; import SearchIcon from '@mui/icons-material/Search'; -import WordPressApi from "../api/agent"; const drawerWidth = 240; diff --git a/src/pages/content.tsx b/src/pages/content.tsx index b3c41ff..3bf7bc9 100644 --- a/src/pages/content.tsx +++ b/src/pages/content.tsx @@ -5,9 +5,8 @@ import { useParams } from "react-router-dom"; import { Author, CardDisplay, CreatedDate, degubbins, GeneralAPIError, NativeShare, OriginalContentLink, TagGrid } from "../components"; -import { IPost } from "../interfaces"; +import { EPostType, IPost, IPostCollection } from "../api"; import { WordPressContext } from "./_layout"; -import { EPostType } from "../enums"; const StyledStack = styled(Stack)(({ theme }) => ({ [theme.breakpoints.down('sm')]: { @@ -34,20 +33,15 @@ const Content = ({ posts, pages }: Props) => { const saveResponse = (p: IPost) => { setPost(p); - /*if (p.type === 'page') { - wp.pages().param('parent', p.id).embed().get() - .then((c: any) => { - delete c['_paging']; - setChildren(c); - }); + if (p.type === 'page') { + wp.fetchPosts({ type: EPostType.Page, parent: p.id }) + .then((c: IPostCollection) => setChildren(c.posts)); if (p.parent !== undefined && p.parent !== 0) { - wp.pages().id(p.parent).embed().get() - .then((c: any) => { - setParent(c as IPost); - }); + wp.fetchPost(p.parent, EPostType.Page) + .then((c: IPost) => setParent(c)); } - }*/ + } setLoadingContent(false); } diff --git a/src/pages/home.tsx b/src/pages/home.tsx index b33806a..ef3a4b3 100644 --- a/src/pages/home.tsx +++ b/src/pages/home.tsx @@ -3,15 +3,13 @@ import { } from '@mui/material'; import { ChangeEvent, useContext, useEffect, useRef, useState } from 'react'; import { useNavigate, useOutletContext, useParams } from 'react-router-dom'; -import { IPost, ISiteInfo, IWPAPIError } from '../interfaces'; import { CardDisplay, CardLoad, GeneralAPIError, SiteSelectorDialog, localStorageRefs } from '../components'; +import { EPostType, IPost, ISiteInfo, IWPAPIError, WordPressApi } from '../api'; import { WordPressContext } from './_layout'; import { useLocalStorageJSON } from '../localStore'; import GitHubIcon from '@mui/icons-material/GitHub'; import "@fontsource/eb-garamond"; -import WordPressApi from '../api/agent'; -import { EPostType } from '../enums'; export const MainHome = () => { const navigate = useNavigate(); @@ -132,13 +130,13 @@ export const AppHome = () => { useEffect(() => { Promise.all([ - wp.fetchPosts(EPostType.Post, 1, 3), - wp.fetchPosts(EPostType.Page, 1, 3), + wp.fetchPosts({ type: EPostType.Post, page: 1, perPage: 3 }), + wp.fetchPosts({ type: EPostType.Page, page: 1, perPage: 3 }), ]).then(values => { setPostCollection(values[0].posts); setPageCollection(values[1].posts); setLoadingContent(false); - }).catch((err:IWPAPIError) => { + }).catch((err: IWPAPIError) => { setApiError(`[${err.code}] ${err.message}`); setLoadingContent(false); }); diff --git a/src/pages/info.tsx b/src/pages/info.tsx index 3b2fbd5..5cc350d 100644 --- a/src/pages/info.tsx +++ b/src/pages/info.tsx @@ -1,6 +1,6 @@ import { Box, Button, Chip, Link, Stack, Typography } from "@mui/material"; import { useEffect, useState } from "react"; -import { IStorage } from "../interfaces"; +import { IStorage } from "../api"; import GitHubIcon from '@mui/icons-material/GitHub'; import CachedIcon from '@mui/icons-material/Cached'; diff --git a/src/pages/iterator.tsx b/src/pages/iterator.tsx index ee4c2b3..3e5b13f 100644 --- a/src/pages/iterator.tsx +++ b/src/pages/iterator.tsx @@ -2,9 +2,8 @@ import { Box, Typography } from "@mui/material"; import { useContext, useEffect, useState } from "react"; import { useOutletContext, useParams } from "react-router-dom"; import { CardDisplay, CardLoad, GeneralAPIError } from "../components"; -import { IPost, IPostCollection, ISiteInfo, ITag, IWPAPIError, IWPIndexing } from "../interfaces"; +import { EPostType, ETagType, IPost, IPostCollection, ISiteInfo, ITag, IWPAPIError, IWPIndexing } from '../api'; import { WordPressContext } from "./_layout"; -import { EPostType, ETagType } from "../enums"; const displayedLimit: number = 12; @@ -27,12 +26,12 @@ export const PostListings = ({ posts = false, pages = false, categories = false, const wp = useContext(WordPressContext); const CommonInterface = { - posts: () => wp.fetchPosts(EPostType.Post, parseInt(pageID ?? '1'), displayedLimit), - postsByCategory: (cat: number) => wp.fetchPosts(EPostType.Post, parseInt(pageID ?? '1'), displayedLimit, cat, 0), - postsByTag: (cat: number) => wp.fetchPosts(EPostType.Post, parseInt(pageID ?? '1'), displayedLimit, 0, cat), - pages: () => wp.fetchPosts(EPostType.Page, parseInt(pageID ?? '1'), displayedLimit), - pagesByCategory: (cat: number) => wp.fetchPosts(EPostType.Page, parseInt(pageID ?? '1'), displayedLimit, cat, 0), - pagesByTag: (cat: number) => wp.fetchPosts(EPostType.Page, parseInt(pageID ?? '1'), displayedLimit, 0, cat), + posts: () => wp.fetchPosts({ type: EPostType.Post, page: parseInt(pageID ?? '1'), perPage: displayedLimit }), + postsByCategory: (cat: number) => wp.fetchPosts({ type: EPostType.Post, page: parseInt(pageID ?? '1'), perPage: displayedLimit, byCategory: cat }), + postsByTag: (cat: number) => wp.fetchPosts({ type: EPostType.Post, page: parseInt(pageID ?? '1'), perPage: displayedLimit, byTag: cat }), + pages: () => wp.fetchPosts({ type: EPostType.Page, page: parseInt(pageID ?? '1'), perPage: displayedLimit }), + pagesByCategory: (cat: number) => wp.fetchPosts({ type: EPostType.Page, page: parseInt(pageID ?? '1'), perPage: displayedLimit, byCategory: cat }), + pagesByTag: (cat: number) => wp.fetchPosts({ type: EPostType.Page, page: parseInt(pageID ?? '1'), perPage: displayedLimit, byTag: cat }), } const saveResponse = (posts: IPostCollection) => { diff --git a/src/pages/search.tsx b/src/pages/search.tsx index d9204c4..76e53bd 100644 --- a/src/pages/search.tsx +++ b/src/pages/search.tsx @@ -2,7 +2,7 @@ import { Box, Typography } from "@mui/material"; import { useContext, useEffect, useState } from "react"; import { useParams } from "react-router-dom"; import { CardDisplay, CardLoad, GeneralAPIError } from "../components"; -import { IPost, ISearch, ISearchCollection, IWPAPIError, IWPIndexing } from "../interfaces"; +import { IPost, ISearch, ISearchCollection, IWPAPIError, IWPIndexing } from '../api'; import { WordPressContext } from "./_layout"; const displayedLimit: number = 12; @@ -18,7 +18,7 @@ const Search = () => { useEffect(() => { setLoadingContent(true); - wp.searchPosts(seachTerms ?? '', parseInt(pageID ?? '1'), displayedLimit) + wp.searchPosts({ search: seachTerms ?? '', page: parseInt(pageID ?? '1'), perPage: displayedLimit }) .then((response: ISearchCollection) => { setPaging(response.pagination); const collection: IPost[] = [];