File: /var/www/vhosts/uyarreklam.com.tr/httpdocs/hooks.tar
useAxios.ts 0000644 00000002530 15154035723 0006721 0 ustar 00 import { useMemo } from 'react'
import axios from 'axios'
import type { AxiosInstance, AxiosResponse, CreateAxiosDefaults } from 'axios'
export interface AxiosAPI {
get: <T>(url: string) => Promise<AxiosResponse<T, never>>
post: <T, D>(url: string, data?: D) => Promise<AxiosResponse<T, D>>
del: <T>(url: string) => Promise<AxiosResponse<T, never>>
axiosInstance: AxiosInstance
}
const debugRequest = async <T, D = never>(
method: 'GET' | 'POST' | 'PUT' | 'DELETE',
url: string,
doRequest: Promise<AxiosResponse<T, D>>,
data?: D
): Promise<AxiosResponse<T, D>> => {
console.debug(`${method} ${url}`, ...data ? [data] : [])
const response = await doRequest
console.debug('Response', response)
return response
}
export const useAxios = (defaultConfig: CreateAxiosDefaults): AxiosAPI => {
const axiosInstance = useMemo(() => axios.create(defaultConfig), [defaultConfig])
return useMemo((): AxiosAPI => ({
get: <T>(url: string): Promise<AxiosResponse<T, never>> =>
debugRequest('GET', url, axiosInstance.get<T, AxiosResponse<T, never>, never>(url)),
post: <T, D>(url: string, data?: D) =>
debugRequest('POST', url, axiosInstance.post<T, AxiosResponse<T, D>, D>(url, data), data),
del: <T>(url: string) =>
debugRequest('DELETE', url, axiosInstance.delete<T, AxiosResponse<T, never>, never>(url)),
axiosInstance
}), [axiosInstance])
}
useSnippetForm.tsx 0000644 00000006520 15154035723 0010277 0 ustar 00 import { isAxiosError } from 'axios'
import React, { createContext, useCallback, useContext, useMemo, useState } from 'react'
import { isLicensed } from '../utils/general'
import { isProSnippet } from '../utils/snippets'
import { useSnippetSubmit } from './useSnippetSubmit'
import type { Dispatch, PropsWithChildren, SetStateAction} from 'react'
import type { ScreenNotice } from '../types/ScreenNotice'
import type { Snippet } from '../types/Snippet'
import type { CodeEditorInstance } from '../types/WordPressCodeEditor'
export interface SnippetFormContext {
snippet: Snippet
setSnippet: Dispatch<SetStateAction<Snippet>>
updateSnippet: Dispatch<SetStateAction<Snippet>>
isReadOnly: boolean
isWorking: boolean
setIsWorking: Dispatch<SetStateAction<boolean>>
currentNotice: ScreenNotice | undefined
setCurrentNotice: Dispatch<SetStateAction<ScreenNotice | undefined>>
codeEditorInstance: CodeEditorInstance | undefined
setCodeEditorInstance: Dispatch<SetStateAction<CodeEditorInstance | undefined>>
handleRequestError: (error: unknown, message?: string) => void
submitSnippet: () => Promise<Snippet | undefined>
submitAndActivateSnippet: () => Promise<Snippet | undefined>
submitAndDeactivateSnippet: () => Promise<Snippet | undefined>
}
const SnippetFormContext = createContext<SnippetFormContext | undefined>(undefined)
export const useSnippetForm = () => {
const value = useContext(SnippetFormContext)
if (value === undefined) {
throw Error('useSnippetForm can only be used within a SnippetForm context provider')
}
return value
}
export interface WithSnippetFormContextProps extends PropsWithChildren {
initialSnippet: () => Snippet
}
export const WithSnippetFormContext: React.FC<WithSnippetFormContextProps> = ({ children, initialSnippet }) => {
const [snippet, setSnippet] = useState<Snippet>(initialSnippet)
const [isWorking, setIsWorking] = useState(false)
const [currentNotice, setCurrentNotice] = useState<ScreenNotice>()
const [codeEditorInstance, setCodeEditorInstance] = useState<CodeEditorInstance>()
const submitSnippet = useSnippetSubmit(setSnippet, setIsWorking, setCurrentNotice)
const isReadOnly = useMemo(() => !isLicensed() && isProSnippet(snippet.scope), [snippet.scope])
const handleRequestError = useCallback((error: unknown, message?: string) => {
console.error('Request failed', error)
setIsWorking(false)
setCurrentNotice(['error', [message, isAxiosError(error) ? error.message : ''].filter(Boolean).join(' ')])
}, [setIsWorking, setCurrentNotice])
const updateSnippet: Dispatch<SetStateAction<Snippet>> = useCallback((value: SetStateAction<Snippet>) => {
setSnippet(previous => {
const updated = 'object' === typeof value ? value : value(previous)
codeEditorInstance?.codemirror.setValue(updated.code)
window.tinymce?.activeEditor.setContent(updated.desc)
return updated
})
}, [codeEditorInstance?.codemirror])
const value: SnippetFormContext = {
snippet,
setSnippet,
updateSnippet,
isReadOnly,
isWorking,
setIsWorking,
currentNotice,
setCurrentNotice,
codeEditorInstance,
setCodeEditorInstance,
handleRequestError,
submitSnippet: () => submitSnippet(snippet),
submitAndActivateSnippet: () => submitSnippet(snippet, true),
submitAndDeactivateSnippet: () => submitSnippet(snippet, false)
}
return <SnippetFormContext.Provider value={value}>{children}</SnippetFormContext.Provider>
}
useSnippetSubmit.ts 0000644 00000005210 15154035723 0010442 0 ustar 00 import { __ } from '@wordpress/i18n'
import { addQueryArgs } from '@wordpress/url'
import { isAxiosError } from 'axios'
import { useCallback } from 'react'
import { useSnippetsAPI } from './useSnippets'
import type { Dispatch, SetStateAction } from 'react'
import type { ScreenNotice } from '../types/ScreenNotice'
import type { Snippet } from '../types/Snippet'
const getSuccessNotice = (request: Snippet, response: Snippet, active: boolean | undefined) => {
if (active === undefined) {
return 0 === request.id
? __('Snippet created.', 'code-snippets')
: __('Snippet updated.', 'code-snippets')
}
if (0 === request.id && active) {
return __('Snippet created and activated.', 'code-snippets')
}
if (active) {
return 'single-use' === response.scope
? __('Snippet updated and executed.', 'code-snippets')
: __('Snippet updated and activated.', 'code-snippets')
} else {
return __('Snippet updated and deactivated')
}
}
export const useSnippetSubmit = (
setSnippet: Dispatch<SetStateAction<Snippet>>,
setIsWorking: Dispatch<SetStateAction<boolean>>,
setCurrentNotice: Dispatch<SetStateAction<ScreenNotice | undefined>>
): (snippet: Snippet, active?: boolean) => Promise<Snippet | undefined> => {
const api = useSnippetsAPI()
return useCallback(async (snippet: Snippet, active?: boolean) => {
setIsWorking(true)
setCurrentNotice(undefined)
const result = await (async (): Promise<Snippet | string | undefined> => {
try {
const requestData: Snippet = { ...snippet, active: active ?? snippet.active }
const { data } = await (0 === snippet.id ? api.create(requestData) : api.update(requestData))
setIsWorking(false)
return data.id ? data : undefined
} catch (error) {
setIsWorking(false)
return isAxiosError(error) ? error.message : undefined
}
})()
if (undefined === result || 'string' === typeof result) {
const message = [
snippet.id
? __('Could not create snippet.', 'code-snippets')
: __('Could not update snippet.', 'code-snippets'),
result ?? __('The server did not send a valid response.', 'code-snippets')
]
setCurrentNotice(['error', message.filter(Boolean).join(' ')])
return undefined
} else {
setSnippet({ ...result })
setCurrentNotice(['updated', getSuccessNotice(snippet, result, active)])
if (snippet.id && result.id) {
window.document.title = window.document.title.replace(
__('Add New Snippet', 'code-snippets'),
__('Edit Snippet', 'code-snippets')
)
window.history.replaceState({}, '', addQueryArgs(window.CODE_SNIPPETS?.urls.edit, { id: result.id }))
}
return result
}
}, [api, setCurrentNotice, setIsWorking, setSnippet])
}
useSnippets.ts 0000644 00000005120 15154035723 0007441 0 ustar 00 import { useEffect, useMemo, useState } from 'react'
import { addQueryArgs } from '@wordpress/url'
import { handleUnknownError } from '../utils/errors'
import { isNetworkAdmin } from '../utils/general'
import { useAxios } from './useAxios'
import type { Snippet } from '../types/Snippet'
import type { SnippetsExport } from '../types/SnippetsExport'
import type { AxiosResponse, CreateAxiosDefaults } from 'axios'
const ROUTE_BASE = window.CODE_SNIPPETS?.restAPI.snippets
const AXIOS_CONFIG: CreateAxiosDefaults = {
headers: { 'X-WP-Nonce': window.CODE_SNIPPETS?.restAPI.nonce }
}
export interface SnippetsAPI {
fetchAll: (network?: boolean | null) => Promise<AxiosResponse<Snippet[]>>
fetch: (snippetId: number, network?: boolean | null) => Promise<AxiosResponse<Snippet>>
create: (snippet: Snippet) => Promise<AxiosResponse<Snippet>>
update: (snippet: Snippet) => Promise<AxiosResponse<Snippet>>
delete: (snippet: Snippet) => Promise<AxiosResponse<void>>
activate: (snippet: Snippet) => Promise<AxiosResponse<Snippet>>
deactivate: (snippet: Snippet) => Promise<AxiosResponse<Snippet>>
export: (snippet: Snippet) => Promise<AxiosResponse<SnippetsExport>>
exportCode: (snippet: Snippet) => Promise<AxiosResponse<string>>
}
const buildURL = ({ id, network }: Snippet, action?: string) =>
addQueryArgs(
[ROUTE_BASE, id, action].filter(Boolean).join('/'),
{ network: network ? true : undefined }
)
export const useSnippetsAPI = (): SnippetsAPI => {
const { get, post, del } = useAxios(AXIOS_CONFIG)
return useMemo((): SnippetsAPI => ({
fetchAll: network =>
get<Snippet[]>(addQueryArgs(ROUTE_BASE, { network })),
fetch: (snippetId, network) =>
get<Snippet>(addQueryArgs(`${ROUTE_BASE}/${snippetId}`, { network })),
create: snippet =>
post<Snippet, Snippet>(`${ROUTE_BASE}`, snippet),
update: snippet =>
post<Snippet, Snippet>(buildURL(snippet), snippet),
delete: (snippet: Snippet) =>
del(buildURL(snippet)),
activate: snippet =>
post<Snippet, never>(buildURL(snippet, 'activate')),
deactivate: snippet =>
post<Snippet, never>(buildURL(snippet, 'deactivate')),
export: snippet =>
get<SnippetsExport>(buildURL(snippet, 'export')),
exportCode: snippet =>
get<string>(buildURL(snippet, 'export-code'))
}), [get, post, del])
}
export const useSnippets = (): Snippet[] | undefined => {
const api = useSnippetsAPI()
const [snippets, setSnippets] = useState<Snippet[]>()
useEffect(() => {
if (!snippets) {
api.fetchAll(isNetworkAdmin())
.then(response => setSnippets(response.data))
.catch(handleUnknownError)
}
}, [api, snippets])
return snippets
}