Initial commit: Atomaste website
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
|
||||
<?php return array('dependencies' => array('react', 'react-dom', 'wp-api-fetch', 'wp-components', 'wp-element', 'wp-i18n'), 'version' => '6e12b4be15a57c232c38');
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,76 @@
|
||||
import { __ } from "@wordpress/i18n";
|
||||
import apiFetch from "@wordpress/api-fetch";
|
||||
import DOMPurify from "dompurify";
|
||||
import { classNames, getAstraProTitle, getSpinner } from "@astra-utils/helpers";
|
||||
|
||||
const ProButton = ({
|
||||
className,
|
||||
isLink = false,
|
||||
url = astra_admin.upgrade_url,
|
||||
children = getAstraProTitle(),
|
||||
disableSpinner = false,
|
||||
}) => {
|
||||
const onGetAstraPro = (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
if (!astra_admin.pro_installed_status) {
|
||||
window.open(url, "_blank");
|
||||
}
|
||||
|
||||
e.target.innerHTML = DOMPurify.sanitize(
|
||||
(disableSpinner ? "" : getSpinner()) +
|
||||
astra_admin.plugin_activating_text
|
||||
);
|
||||
e.target.disabled = true;
|
||||
|
||||
const formData = new window.FormData();
|
||||
formData.append("action", "astra_recommended_plugin_activate");
|
||||
formData.append("security", astra_admin.plugin_manager_nonce);
|
||||
formData.append("init", "astra-addon/astra-addon.php");
|
||||
|
||||
apiFetch({
|
||||
url: astra_admin.ajax_url,
|
||||
method: "POST",
|
||||
body: formData,
|
||||
})
|
||||
.then((data) => {
|
||||
if (data.success) {
|
||||
window.open(astra_admin.astra_base_url, "_self");
|
||||
}
|
||||
})
|
||||
.catch((error) => {
|
||||
e.target.innerText = __(
|
||||
"Activation failed. Please try again.",
|
||||
"astra"
|
||||
);
|
||||
e.target.disabled = false;
|
||||
console.error("Error during API request:", error);
|
||||
// Optionally, notify the user about the error or handle it appropriately.
|
||||
});
|
||||
};
|
||||
|
||||
const Tag = isLink ? "a" : "button";
|
||||
|
||||
const linkProps = isLink && {
|
||||
role: "button",
|
||||
href: url,
|
||||
target: "_blank",
|
||||
rel: "noreferrer",
|
||||
};
|
||||
|
||||
return (
|
||||
<Tag
|
||||
className={classNames(
|
||||
"inline-flex items-center disabled:pointer-events-none",
|
||||
className
|
||||
)}
|
||||
onClick={onGetAstraPro}
|
||||
{...linkProps}
|
||||
>
|
||||
{children}
|
||||
</Tag>
|
||||
);
|
||||
};
|
||||
|
||||
export default ProButton;
|
||||
@@ -0,0 +1,60 @@
|
||||
import { classNames } from "@astra-utils/helpers";
|
||||
|
||||
const PromoCard = ({
|
||||
className = "",
|
||||
id,
|
||||
icon,
|
||||
title,
|
||||
description,
|
||||
linkHRef,
|
||||
linkText,
|
||||
children,
|
||||
}) => {
|
||||
return (
|
||||
<section aria-labelledby={`section-${id}-title`}>
|
||||
<h2 className="sr-only" id={`section-${id}-title`}>
|
||||
{title}
|
||||
</h2>
|
||||
<div
|
||||
className={classNames(
|
||||
"relative box-border rounded-md bg-white shadow-sm overflow-hidden transition hover:shadow-hover",
|
||||
className
|
||||
)}
|
||||
>
|
||||
<div className="p-6">
|
||||
{/* Card Icon */}
|
||||
{icon && <span className="inline-block mb-2">{icon}</span>}
|
||||
|
||||
{/* Card Title */}
|
||||
<h3 className="relative flex items-center text-slate-800 text-base font-semibold pb-2">
|
||||
<span className="flex-1">{title}</span>
|
||||
</h3>
|
||||
|
||||
{/* Card Description */}
|
||||
{!children && (
|
||||
<p className="text-slate-500 text-sm pb-5">
|
||||
{description}
|
||||
</p>
|
||||
)}
|
||||
|
||||
{/* Card Content */}
|
||||
{children}
|
||||
|
||||
{/* Card Link */}
|
||||
{linkText && (
|
||||
<a
|
||||
className="text-sm text-astra focus:text-astra focus-visible:text-astra-hover active:text-astra-hover hover:text-astra-hover no-underline"
|
||||
href={linkHRef}
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
{linkText}
|
||||
</a>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
};
|
||||
|
||||
export default PromoCard;
|
||||
@@ -0,0 +1,26 @@
|
||||
const Star = ({ width = 20, height = 20, fill = "#000", className = "" }) => {
|
||||
return (
|
||||
<svg
|
||||
className={className}
|
||||
width={width}
|
||||
height={height}
|
||||
viewBox="0 0 20 20"
|
||||
fill="none"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<g clipPath="url(#clip0_2358_55923)">
|
||||
<path
|
||||
d="M9.04894 2.92705C9.3483 2.00574 10.6517 2.00574 10.9511 2.92705L12.0206 6.21885C12.1545 6.63087 12.5385 6.90983 12.9717 6.90983H16.4329C17.4016 6.90983 17.8044 8.14945 17.0207 8.71885L14.2205 10.7533C13.87 11.0079 13.7234 11.4593 13.8572 11.8713L14.9268 15.1631C15.2261 16.0844 14.1717 16.8506 13.388 16.2812L10.5878 14.2467C10.2373 13.9921 9.7627 13.9921 9.41221 14.2467L6.61204 16.2812C5.82833 16.8506 4.77385 16.0844 5.0732 15.1631L6.14277 11.8713C6.27665 11.4593 6.12999 11.0079 5.7795 10.7533L2.97933 8.71885C2.19562 8.14945 2.59839 6.90983 3.56712 6.90983H7.02832C7.46154 6.90983 7.8455 6.63087 7.97937 6.21885L9.04894 2.92705Z"
|
||||
fill={fill}
|
||||
/>
|
||||
</g>
|
||||
<defs>
|
||||
<clipPath id="clip0_2358_55923">
|
||||
<rect width={width} height={height} fill="white" />
|
||||
</clipPath>
|
||||
</defs>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default Star;
|
||||
@@ -0,0 +1,3 @@
|
||||
import Star from "./Star";
|
||||
|
||||
export { Star };
|
||||
@@ -0,0 +1,4 @@
|
||||
import ProButton from "./ProButton";
|
||||
import PromoCard from "./PromoCard";
|
||||
|
||||
export { ProButton, PromoCard };
|
||||
@@ -0,0 +1,3 @@
|
||||
import useDebounceEffect from "./useDebounceEffect";
|
||||
|
||||
export { useDebounceEffect };
|
||||
@@ -0,0 +1,25 @@
|
||||
import { useEffect } from 'react';
|
||||
import { debounce } from '@astra-utils/helpers';
|
||||
|
||||
/**
|
||||
* A hook that wraps a callback function with a debounce effect.
|
||||
*
|
||||
* This hook is designed to delay the execution of a function until after a specified delay.
|
||||
* It's particularly useful for handling events that occur rapidly, such as typing in a text input.
|
||||
*
|
||||
* @param {Function} callback - The function to debounce.
|
||||
* @param {number} delay - The delay in milliseconds before the function is executed.
|
||||
* @param {Array} dependencies - An array of dependencies that trigger the effect.
|
||||
*/
|
||||
function useDebounceEffect( callback, delay, dependencies ) {
|
||||
useEffect( () => {
|
||||
const debouncedCallback = debounce( callback, delay );
|
||||
|
||||
debouncedCallback();
|
||||
|
||||
// Cleanup on unmount or when dependencies change.
|
||||
return () => debouncedCallback.cancel && debouncedCallback.cancel();
|
||||
}, [ callback, delay, ...dependencies ] );
|
||||
}
|
||||
|
||||
export default useDebounceEffect;
|
||||
@@ -0,0 +1 @@
|
||||
<?php return array('dependencies' => array('react', 'react-dom', 'wp-i18n'), 'version' => '18bae9fc371e45eda5f8');
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -0,0 +1,120 @@
|
||||
import { __ } from "@wordpress/i18n";
|
||||
import apiFetch from '@wordpress/api-fetch';
|
||||
|
||||
/**
|
||||
* Returns the class names.
|
||||
*
|
||||
* @param {...string} classes The class names.
|
||||
*
|
||||
* @return {string} Returns the class names.
|
||||
*/
|
||||
const classNames = (...classes) => classes.filter(Boolean).join(" ");
|
||||
|
||||
/**
|
||||
* Creates a debounced function that delays its execution until after the specified delay.
|
||||
*
|
||||
* The debounce() function can also be used from lodash.debounce package in future.
|
||||
*
|
||||
* @param {Function} func - The function to debounce.
|
||||
* @param {number} delay - The delay in milliseconds before the function is executed.
|
||||
*
|
||||
* @returns {Function} A debounced function.
|
||||
*/
|
||||
const debounce = ( func, delay ) => {
|
||||
let timer;
|
||||
function debounced( ...args ) {
|
||||
clearTimeout( timer );
|
||||
timer = setTimeout( () => func( ...args ), delay );
|
||||
};
|
||||
|
||||
// Attach a `cancel` method to clear the timeout.
|
||||
debounced.cancel = () => {
|
||||
clearTimeout( timer );
|
||||
};
|
||||
|
||||
return debounced;
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the Astra Pro title.
|
||||
*
|
||||
* @return {string} Returns the Astra Pro title.
|
||||
*/
|
||||
const getAstraProTitle = () => {
|
||||
return astra_admin.pro_installed_status
|
||||
? __("Activate Now", "astra")
|
||||
: __("Upgrade Now", "astra");
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns the spinner SVG text.
|
||||
*
|
||||
* @return {string} Returns the spinner SVG text..
|
||||
*/
|
||||
const getSpinner = () => {
|
||||
return `
|
||||
<svg class="animate-spin installer-spinner" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
||||
<circle class="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
|
||||
<path class="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
|
||||
</svg>
|
||||
`;
|
||||
};
|
||||
|
||||
/**
|
||||
* A function to save astra admin settings.
|
||||
*
|
||||
* @function
|
||||
*
|
||||
* @param {string} key - Settings key.
|
||||
* @param {string} value - The data to send.
|
||||
* @param {Function} dispatch - The dispatch function.
|
||||
* @param {Object} abortControllerRef - The ref object with to hold abort controller.
|
||||
*
|
||||
* @return {Promise} Returns a promise representing the processed request.
|
||||
*/
|
||||
const saveSetting = debounce(
|
||||
(key, value, dispatch, abortControllerRef = { current: {} }) => {
|
||||
// Abort any previous request.
|
||||
if (abortControllerRef.current[key]) {
|
||||
abortControllerRef.current[key]?.abort();
|
||||
}
|
||||
|
||||
// Create a new AbortController.
|
||||
const abortController = new AbortController();
|
||||
abortControllerRef.current[key] = abortController;
|
||||
|
||||
const formData = new window.FormData();
|
||||
|
||||
formData.append("action", "astra_update_admin_setting");
|
||||
formData.append("security", astra_admin.update_nonce);
|
||||
formData.append("key", key);
|
||||
formData.append("value", value);
|
||||
|
||||
return apiFetch({
|
||||
url: astra_admin.ajax_url,
|
||||
method: "POST",
|
||||
body: formData,
|
||||
signal: abortControllerRef.current[key]?.signal, // Pass the signal to the fetch request.
|
||||
})
|
||||
.then(() => {
|
||||
dispatch({
|
||||
type: "UPDATE_SETTINGS_SAVED_NOTIFICATION",
|
||||
payload: __("Successfully saved!", "astra"),
|
||||
});
|
||||
})
|
||||
.catch((error) => {
|
||||
// Ignore if it is intentionally aborted.
|
||||
if (error.name === "AbortError") {
|
||||
return;
|
||||
}
|
||||
console.error("Error during API request:", error);
|
||||
dispatch({
|
||||
type: "UPDATE_SETTINGS_SAVED_NOTIFICATION",
|
||||
payload: __("An error occurred while saving.", "astra"),
|
||||
});
|
||||
});
|
||||
},
|
||||
300
|
||||
);
|
||||
|
||||
export { classNames, debounce, getAstraProTitle, getSpinner, saveSetting };
|
||||
Reference in New Issue
Block a user