HEX
Server: LiteSpeed
System: Linux premium283.web-hosting.com 4.18.0-553.45.1.lve.el8.x86_64 #1 SMP Wed Mar 26 12:08:09 UTC 2025 x86_64
User: citaqlmd (746)
PHP: 8.1.33
Disabled: NONE
Upload Files
File: /home/citaqlmd/nt.lmskreators.com/wp-content/plugins/mycred/includes/toolkit/src/admin/App.js
import React, { useState, useEffect } from "react";
import { Box, Grid, Typography, CssBaseline } from "@mui/material";
import { createTheme, ThemeProvider } from "@mui/material/styles";
import { __ } from "@wordpress/i18n";
import "@fontsource/figtree";
import "@fontsource/figtree/700.css";

import Header from "./components/Header";
import UpgradeDialog from "./components/UpgradeDialog";
import AddonCard from "./components/AddonCard";
import FilterSection from "./components/FilterSection";
import Notification from "./components/Notification";
import addOnsData from "./addons.json";

const theme = createTheme({
  palette: {
    primary: { main: "#4A90E2" },
    secondary: { main: "#E64A19" },
  },
  typography: { fontFamily: "Roboto, sans-serif" },
});

const categories = [
  "All",
  "ECommerce",
  "LMS",
  "Community",
  "buyCred Gateways",
  "cashCred Gateways",
  "Others"
];

function contains(data, value) {
  if (Array.isArray(data)) {
    return data.includes(value);
  } else if (data && typeof data === "object") {
    return Object.values(data).includes(value);
  }
  return false;
}

const App = () => {
  const [snackbarOpen, setSnackbarOpen] = useState(false);
  const [snackbarMessage, setSnackbarMessage] = useState("");
  const [snackbarType, setSnackbarType] = useState("success");
  const [loading, setLoading] = useState(true);
  const [Addons, setAddons] = useState([]);
  const [searchTerm, setSearchTerm] = useState("");
  const [selectedCategory, setSelectedCategory] = useState("All");
  const [anchorEl, setAnchorEl] = useState(null);
  const [selectedType, setSelectedType] = useState("all");
  const [open, setOpen] = useState(false);
  const [addonsData, setAddonsData] = useState(addOnsData);

  const handleOpen = () => setOpen(true);
  const handleClose = () => setOpen(false);

  const fetchAddOns = async () => {
    try {
      setLoading(true);
      const siteUrl = `${window.mycredAddonsData.root}mycred-toolkit/v1/get-addons`;

      const response = await fetch(siteUrl, {
        method: "GET",
        headers: {
          'X-WP-Nonce': window.mycredAddonsData.nonce,
          "Content-Type": "application/json",
        },
      });

      if (!response.ok) {
        throw new Error("Network response was not ok");
      }

      const Addons = await response.json();
      setAddons(Addons);
    } catch (error) {
      setSnackbarMessage("Error fetching add-ons: " + error.message);
      setSnackbarOpen(true);
    } finally {
      setLoading(false);
    }
  };

  const checkProaddonsfile = async () => {
    try {
      setLoading(true);
      const siteUrl = `${window.mycredAddonsData.root}mycred-toolkit/v1/check-addons-files`;

      const proAddOns = addonsData.filter((addon) => addon.type === "pro");

      const response = await fetch(siteUrl, {
        method: "POST",
        headers: {
          'X-WP-Nonce': window.mycredAddonsData.nonce,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          proAddOns: proAddOns,
        }),
      });

      if (!response.ok) {
        throw new Error("Network response was not ok");
      }

      const Addons = await response.json();

      addonsData.forEach((addon) => {
        const matchingAddon = Addons.find((item) => item.slug === addon.slug);
        if (matchingAddon) {
          addon.status = matchingAddon.status;
        }
      });
    } catch (error) {
      // console.error("Error fetching add-ons: ", error.message);
    } finally {
      setLoading(false);
    }
  };

  useEffect(() => {
    fetchAddOns();
    checkProaddonsfile();

    if (window.mycredAddonsData && Array.isArray(window.mycredAddonsData.addons)) {
      setAddonsData(window.mycredAddonsData.addons);
    }
  }, []);

  const handleFilterClick = (event) => {
    setAnchorEl(event.currentTarget);
  };

  const handleFilterChange = (type) => {
    setSelectedType(type);
    handleCloseFilter();
  };

  const handleCloseFilter = () => {
    setAnchorEl(null);
  };

  const handleToggleClick = async (addOn) => {
    if (addOn.status === 'locked') {
      handleOpen();
      return;
    }

    if (loading) return;

    setLoading(true);
    try {
      const siteUrl = `${window.mycredAddonsData.root}mycred-toolkit/v1/enable-addon`;

      const response = await fetch(siteUrl, {
        method: "POST",
        headers: {
          'X-WP-Nonce': window.mycredAddonsData.nonce,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          addOnSlug: addOn.slug,
          addOnTitle: addOn.title,
          dependency: addOn.dependency,
          dependencyName: addOn.dependencyName,
        }),
      });

      const result = await response.json();

      // Set notification type based on API response status
      setSnackbarType(result.status);
      setSnackbarMessage(result.message);
      setSnackbarOpen(true);

      // Only fetch addons if the operation was successful
      if (result.status === 'success') {
        fetchAddOns();
      }

    } catch (error) {
      setSnackbarMessage("An error occurred while toggling the addon");
      setSnackbarType("error");
      setSnackbarOpen(true);
    } finally {
      setLoading(false);
    }
  };

  const handleSearchData = (event) => {
    setSearchTerm(event.target.value);
  };

  const handleCategoryChange = (newCategory) => {
    setSelectedCategory(newCategory);
  };

  const renderSVG = (iconSlug, addonType, isProActive) => {
    try {
      const IconComponent = require(`./icons/${iconSlug}.svg`).default;
      return (
        <Box position="relative" display="inline-block">
          {IconComponent.startsWith("data:image/svg+xml") ? (
            <div
              dangerouslySetInnerHTML={{
                __html: atob(IconComponent.split(",")[1]),
              }}
            />
          ) : (
            <IconComponent width={24} height={24} />
          )}
          
          {addonType === "pro" && isProActive && (
            <Box
              sx={{
                position: "absolute",
                top: "-8px",
                right: "-20px",
                display: "inline-flex",
                padding: "2px 6px",
                justifyContent: "center",
                alignItems: "center",
                borderRadius: "3px",
                background: "linear-gradient(248deg, #FFD79C 17.34%, #FFAF39 88.08%)",
                color: "#694214",
                fontSize: "10px",
                fontWeight: 600,
                lineHeight: "normal",
                height: "fit-content"
              }}
            >
              PRO
            </Box>
          )}
        </Box>
      );
    } catch (error) {
      console.error(`SVG not found for icon name: ${iconSlug}`);
      return null;
    }
  };

  const filteredAddons = addonsData
    .filter((addOn) =>
      addOn.title.toLowerCase().includes(searchTerm.toLowerCase())
    )
    .filter(
      (addOn) =>
        selectedCategory === "All" || addOn.category === selectedCategory
    )
    .filter(
      (addOn) =>
        selectedType === "all" || addOn.type === selectedType
    );

  return (
    <ThemeProvider theme={theme}>
      <CssBaseline />

      <Header
        searchTerm={searchTerm}
        handleSearchData={handleSearchData}
        handleOpen={handleOpen}
        upgraded={window.mycredAddonsData.upgraded}
      />

      <UpgradeDialog open={open} handleClose={handleClose} />

      <Box
        sx={{
          padding: 4,
          backgroundColor: "#F0F4FF",
        }}
      >
        <Typography
          variant="h5"
          sx={{
            fontWeight: "500",
            flexGrow: 1,
            display: "flex",
            alignItems: "center",
            gap: "8px",
          }}
        >
          {__("Popular Add-ons, New Possibilities.", "mycred-toolkit")}
        </Typography>
        <br />

        <Typography
          variant="p"
          sx={{
            fontWeight: "400",
            color: "#9698C2",
            flexGrow: 1,
            display: "flex",
            alignItems: "center",
            gap: "8px",
          }}
        >
          {__(
            "myCred is an easy-to-use WordPress gamification plugin. Seamlessly create a daily login rewards",
            "mycred-toolkit"
          )}
          <br />
          {__(
            "program or gamify your website and increase the average customer value with less marketing effort.",
            "mycred-toolkit"
          )}
        </Typography>

        <br />

        <FilterSection
          categories={categories}
          selectedCategory={selectedCategory}
          handleCategoryChange={handleCategoryChange}
          anchorEl={anchorEl}
          handleFilterClick={handleFilterClick}
          handleCloseFilter={handleCloseFilter}
          handleFilterChange={handleFilterChange}
          selectedType={selectedType}
          openFilter={Boolean(anchorEl)}
        />

        <Grid container spacing={3}>
          {filteredAddons.map((addOn) => (
            <Grid item xs={12} sm={6} md={4} key={addOn.slug}>
              <AddonCard
                addOn={addOn}
                loading={loading}
                contains={contains}
                Addons={Addons}
                handleToggleClick={handleToggleClick}
                renderSVG={renderSVG}
              />
            </Grid>
          ))}
        </Grid>
      </Box>

      <Notification
        open={snackbarOpen}
        message={snackbarMessage}
        onClose={() => setSnackbarOpen(false)}
        type={snackbarType}
      />
    </ThemeProvider>
  );
};

export default App;