mirror of
https://github.com/towfiqi/serpbear
synced 2025-06-26 18:15:54 +00:00
- Adds the ability to add domain specific Search Console API Info through the Domain Settings panel. - Adds the ability to add global Search Console API Info through the App Settings Panel. - Adds better Search Console Error logging. - Changes the App Settings Sidebar UI. - Changers the Domain Settings Modal UI. - Replaces html Input field with custom InputField component. - Adds a new /domain api route to get the full domain info which includes the domain level Search console API. closes #59, #146
152 lines
5.9 KiB
TypeScript
152 lines
5.9 KiB
TypeScript
import { useRouter, NextRouter } from 'next/router';
|
|
import toast from 'react-hot-toast';
|
|
import { useMutation, useQuery, useQueryClient } from 'react-query';
|
|
|
|
type UpdatePayload = {
|
|
domainSettings: DomainSettings,
|
|
domain: DomainType
|
|
}
|
|
|
|
export async function fetchDomains(router: NextRouter, withStats:boolean): Promise<{domains: DomainType[]}> {
|
|
const res = await fetch(`${window.location.origin}/api/domains${withStats ? '?withstats=true' : ''}`, { method: 'GET' });
|
|
if (res.status >= 400 && res.status < 600) {
|
|
if (res.status === 401) {
|
|
console.log('Unauthorized!!');
|
|
router.push('/login');
|
|
}
|
|
throw new Error('Bad response from server');
|
|
}
|
|
return res.json();
|
|
}
|
|
|
|
export async function fetchDomain(router: NextRouter, domainName: string): Promise<{domain: DomainType}> {
|
|
if (!domainName) { throw new Error('No Domain Name Provided!'); }
|
|
const res = await fetch(`${window.location.origin}/api/domain?domain=${domainName}`, { method: 'GET' });
|
|
if (res.status >= 400 && res.status < 600) {
|
|
if (res.status === 401) {
|
|
console.log('Unauthorized!!');
|
|
router.push('/login');
|
|
}
|
|
throw new Error('Bad response from server');
|
|
}
|
|
return res.json();
|
|
}
|
|
|
|
export async function fetchDomainScreenshot(domain: string, screenshot_key:string, forceFetch = false): Promise<string | false> {
|
|
const domainThumbsRaw = localStorage.getItem('domainThumbs');
|
|
const domThumbs = domainThumbsRaw ? JSON.parse(domainThumbsRaw) : {};
|
|
if (!domThumbs[domain] || forceFetch) {
|
|
try {
|
|
const screenshotURL = `https://image.thum.io/get/auth/${screenshot_key}/maxAge/96/width/200/https://${domain}`;
|
|
const domainImageRes = await fetch(screenshotURL);
|
|
const domainImageBlob = domainImageRes.status === 200 ? await domainImageRes.blob() : false;
|
|
if (domainImageBlob) {
|
|
const reader = new FileReader();
|
|
await new Promise((resolve, reject) => {
|
|
reader.onload = resolve;
|
|
reader.onerror = reject;
|
|
reader.readAsDataURL(domainImageBlob);
|
|
});
|
|
const imageBase: string = reader.result && typeof reader.result === 'string' ? reader.result : '';
|
|
localStorage.setItem('domainThumbs', JSON.stringify({ ...domThumbs, [domain]: imageBase }));
|
|
return imageBase;
|
|
}
|
|
return false;
|
|
} catch (error) {
|
|
return false;
|
|
}
|
|
} else if (domThumbs[domain]) {
|
|
return domThumbs[domain];
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
export function useFetchDomains(router: NextRouter, withStats:boolean = false) {
|
|
return useQuery('domains', () => fetchDomains(router, withStats));
|
|
}
|
|
|
|
export function useFetchDomain(router: NextRouter, domainName:string, onSuccess: Function) {
|
|
return useQuery('domain', () => fetchDomain(router, domainName), {
|
|
onSuccess: async (data) => {
|
|
console.log('Domain Loaded!!!', data.domain);
|
|
onSuccess(data.domain);
|
|
} });
|
|
}
|
|
|
|
export function useAddDomain(onSuccess:Function) {
|
|
const router = useRouter();
|
|
const queryClient = useQueryClient();
|
|
return useMutation(async (domains:string[]) => {
|
|
const headers = new Headers({ 'Content-Type': 'application/json', Accept: 'application/json' });
|
|
const fetchOpts = { method: 'POST', headers, body: JSON.stringify({ domains }) };
|
|
const res = await fetch(`${window.location.origin}/api/domains`, fetchOpts);
|
|
if (res.status >= 400 && res.status < 600) {
|
|
throw new Error('Bad response from server');
|
|
}
|
|
return res.json();
|
|
}, {
|
|
onSuccess: async (data) => {
|
|
console.log('Domain Added!!!', data);
|
|
const newDomain:DomainType[] = data.domains;
|
|
const singleDomain = newDomain.length === 1;
|
|
toast(`${singleDomain ? newDomain[0].domain : `${newDomain.length} domains`} Added Successfully!`, { icon: '✔️' });
|
|
onSuccess(false);
|
|
if (singleDomain) {
|
|
router.push(`/domain/${newDomain[0].slug}`);
|
|
}
|
|
queryClient.invalidateQueries(['domains']);
|
|
},
|
|
onError: () => {
|
|
console.log('Error Adding New Domain!!!');
|
|
toast('Error Adding New Domain');
|
|
},
|
|
});
|
|
}
|
|
|
|
export function useUpdateDomain(onSuccess:Function) {
|
|
const queryClient = useQueryClient();
|
|
return useMutation(async ({ domainSettings, domain }: UpdatePayload) => {
|
|
const headers = new Headers({ 'Content-Type': 'application/json', Accept: 'application/json' });
|
|
const fetchOpts = { method: 'PUT', headers, body: JSON.stringify(domainSettings) };
|
|
const res = await fetch(`${window.location.origin}/api/domains?domain=${domain.domain}`, fetchOpts);
|
|
const responseObj = await res.json();
|
|
if (res.status >= 400 && res.status < 600) {
|
|
throw new Error(responseObj?.error || 'Bad response from server');
|
|
}
|
|
return responseObj;
|
|
}, {
|
|
onSuccess: async () => {
|
|
console.log('Settings Updated!!!');
|
|
toast('Settings Updated!', { icon: '✔️' });
|
|
onSuccess();
|
|
queryClient.invalidateQueries(['domains']);
|
|
},
|
|
onError: (error) => {
|
|
console.log('Error Updating Domain Settings!!!', error);
|
|
toast('Error Updating Domain Settings', { icon: '⚠️' });
|
|
},
|
|
});
|
|
}
|
|
|
|
export function useDeleteDomain(onSuccess:Function) {
|
|
const queryClient = useQueryClient();
|
|
return useMutation(async (domain:DomainType) => {
|
|
const res = await fetch(`${window.location.origin}/api/domains?domain=${domain.domain}`, { method: 'DELETE' });
|
|
if (res.status >= 400 && res.status < 600) {
|
|
throw new Error('Bad response from server');
|
|
}
|
|
return res.json();
|
|
}, {
|
|
onSuccess: async () => {
|
|
toast('Domain Removed Successfully!', { icon: '✔️' });
|
|
onSuccess();
|
|
queryClient.invalidateQueries(['domains']);
|
|
},
|
|
onError: () => {
|
|
console.log('Error Removing Domain!!!');
|
|
toast('Error Removing Domain', { icon: '⚠️' });
|
|
},
|
|
});
|
|
}
|