cooronx commented on code in PR #464:
URL: https://github.com/apache/casbin-website/pull/464#discussion_r3071346345


##########
src/components/FooterMoreBadges/index.js:
##########
@@ -0,0 +1,379 @@
+import React, {useEffect, useId, useRef, useState} from "react";
+import styles from "./styles.module.css";
+
+const CACHE_KEY = "casbin-footer-github-stars-v1";
+const CACHE_DURATION_MS = 2 * 60 * 60 * 1000; // 2 hours
+
+const STAR_FORMATTER = new Intl.NumberFormat("en-US", {
+  notation: "compact",
+  compactDisplay: "short",
+  maximumFractionDigits: 1,
+});
+
+const GITHUB_BADGES = [
+  {
+    label: "Casbin",
+    owner: "casbin",
+    repo: "casbin",
+    href: "https://github.com/casbin/casbin";,
+    labelWidth: 64,
+  },
+  {
+    label: "jCasbin",
+    owner: "casbin",
+    repo: "jcasbin",
+    href: "https://github.com/casbin/jcasbin";,
+    labelWidth: 70,
+  },
+  {
+    label: "Node-Casbin",
+    owner: "casbin",
+    repo: "node-casbin",
+    href: "https://github.com/casbin/node-casbin";,
+    labelWidth: 96,
+  },
+  {
+    label: "PHP-Casbin",
+    owner: "php-casbin",
+    repo: "php-casbin",
+    href: "https://github.com/php-casbin/php-casbin";,
+    labelWidth: 90,
+  },
+  {
+    label: "PyCasbin",
+    owner: "casbin",
+    repo: "pycasbin",
+    href: "https://github.com/casbin/pycasbin";,
+    labelWidth: 76,
+  },
+  {
+    label: "Casbin.NET",
+    owner: "casbin",
+    repo: "Casbin.NET",
+    href: "https://github.com/casbin/Casbin.NET";,
+    labelWidth: 88,
+  },
+  {
+    label: "Casbin-CPP",
+    owner: "casbin",
+    repo: "casbin-cpp",
+    href: "https://github.com/casbin/casbin-cpp";,
+    labelWidth: 90,
+  },
+  {
+    label: "Casbin-RS",
+    owner: "casbin",
+    repo: "casbin-rs",
+    href: "https://github.com/casbin/casbin-rs";,
+    labelWidth: 84,
+  },
+];
+
+const DEFAULT_STARS = {
+  "casbin/casbin": 19992,
+  "casbin/jcasbin": 2631,
+  "casbin/node-casbin": 2882,
+  "php-casbin/php-casbin": 1326,
+  "casbin/pycasbin": 1724,
+  "casbin/Casbin.NET": 1309,
+  "casbin/casbin-cpp": 250,
+  "casbin/casbin-rs": 1090,
+};
+
+// github SVG path
+const GITHUB_ICON_PATH =
+  "M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 
11.385.6.113.82-.258.82-.577 
0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 
17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 
1.07 1.835 2.809 1.305 
3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 
0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 
1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 
3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 
5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 
.315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12";
+// X SVG path
+const X_ICON_PATH =
+  "M14.234 10.162 22.977 0h-2.072l-7.591 8.824L7.251 0H.258l9.168 13.343L.258 
24H2.33l8.016-9.318L16.749 24h6.993zm-2.837 3.299-.929-1.329L3.076 
1.56h3.182l5.965 8.532.929 1.329 7.754 11.09h-3.186z";
+
+function getRepoKey(owner, repo) {
+  return `${owner}/${repo}`;
+}
+
+function formatStars(count) {
+  return STAR_FORMATTER.format(count).replace(/\.0(?=[A-Za-z])/u, 
"").toLowerCase();
+}
+
+function getCountWidth(value) {
+  return Math.max(27, 12 + value.length * 4);
+}
+
+function readCachedStars() {
+  if (typeof window === "undefined") {
+    return null;
+  }
+
+  try {
+    const cachedValue = window.localStorage.getItem(CACHE_KEY);
+
+    if (!cachedValue) {
+      return null;
+    }
+
+    const parsedValue = JSON.parse(cachedValue);
+
+    if (!parsedValue || typeof parsedValue.updatedAt !== "number" || 
!parsedValue.stars) {
+      return null;
+    }
+
+    return parsedValue;
+  } catch {
+    return null;
+  }
+}
+
+function writeCachedStars(stars) {
+  if (typeof window === "undefined") {
+    return;
+  }
+
+  try {
+    window.localStorage.setItem(CACHE_KEY, JSON.stringify({
+      updatedAt: Date.now(),
+      stars,
+    }));
+  } catch {
+    // Ignore localStorage write errors.
+  }
+}
+
+async function fetchGithubStars() {
+  const responses = await Promise.all(
+    GITHUB_BADGES.map(async({owner, repo}) => {
+      const response = await 
fetch(`https://api.github.com/repos/${owner}/${repo}`);

Review Comment:
   we dont have a server-side code, pure js



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to