@moontra/moonui-pro 2.18.3 → 2.18.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs
CHANGED
|
@@ -61374,6 +61374,12 @@ var AdvancedForms = ({ className, ...props }) => {
|
|
|
61374
61374
|
|
|
61375
61375
|
// src/components/github-stars/github-api.ts
|
|
61376
61376
|
var cache = /* @__PURE__ */ new Map();
|
|
61377
|
+
var isDocsMode = () => {
|
|
61378
|
+
return typeof window !== "undefined" && (window.location.pathname.includes("/docs/") || window.location.pathname.includes("/components/"));
|
|
61379
|
+
};
|
|
61380
|
+
var getCacheDuration = (defaultDuration) => {
|
|
61381
|
+
return isDocsMode() ? 18e5 : defaultDuration;
|
|
61382
|
+
};
|
|
61377
61383
|
var LANGUAGE_COLORS = {
|
|
61378
61384
|
JavaScript: "#f7df1e",
|
|
61379
61385
|
TypeScript: "#3178c6",
|
|
@@ -61441,8 +61447,8 @@ async function getRateLimitInfo(token) {
|
|
|
61441
61447
|
cache.set(cacheKey, {
|
|
61442
61448
|
data: rateLimitInfo,
|
|
61443
61449
|
timestamp: Date.now(),
|
|
61444
|
-
expiresAt: Date.now() + 6e4
|
|
61445
|
-
//
|
|
61450
|
+
expiresAt: Date.now() + getCacheDuration(6e4)
|
|
61451
|
+
// Docs modunda daha uzun cache
|
|
61446
61452
|
});
|
|
61447
61453
|
return rateLimitInfo;
|
|
61448
61454
|
}
|
|
@@ -61462,8 +61468,8 @@ async function fetchUserRepositories(username, token, options) {
|
|
|
61462
61468
|
cache.set(cacheKey, {
|
|
61463
61469
|
data: repos,
|
|
61464
61470
|
timestamp: Date.now(),
|
|
61465
|
-
expiresAt: Date.now() + 3e5
|
|
61466
|
-
//
|
|
61471
|
+
expiresAt: Date.now() + getCacheDuration(3e5)
|
|
61472
|
+
// Docs modunda 30 dakika
|
|
61467
61473
|
});
|
|
61468
61474
|
return repos;
|
|
61469
61475
|
}
|
|
@@ -61478,8 +61484,8 @@ async function fetchRepository(owner, repo, token) {
|
|
|
61478
61484
|
cache.set(cacheKey, {
|
|
61479
61485
|
data: repository,
|
|
61480
61486
|
timestamp: Date.now(),
|
|
61481
|
-
expiresAt: Date.now() + 3e5
|
|
61482
|
-
//
|
|
61487
|
+
expiresAt: Date.now() + getCacheDuration(3e5)
|
|
61488
|
+
// Docs modunda 30 dakika
|
|
61483
61489
|
});
|
|
61484
61490
|
return repository;
|
|
61485
61491
|
}
|
|
@@ -61502,8 +61508,8 @@ async function fetchContributorsCount(owner, repo, token) {
|
|
|
61502
61508
|
cache.set(cacheKey, {
|
|
61503
61509
|
data: count4,
|
|
61504
61510
|
timestamp: Date.now(),
|
|
61505
|
-
expiresAt: Date.now() + 36e5
|
|
61506
|
-
//
|
|
61511
|
+
expiresAt: Date.now() + getCacheDuration(36e5)
|
|
61512
|
+
// Docs modunda 30 dakika
|
|
61507
61513
|
});
|
|
61508
61514
|
return count4;
|
|
61509
61515
|
}
|
|
@@ -61513,8 +61519,8 @@ async function fetchContributorsCount(owner, repo, token) {
|
|
|
61513
61519
|
cache.set(cacheKey, {
|
|
61514
61520
|
data: count3,
|
|
61515
61521
|
timestamp: Date.now(),
|
|
61516
|
-
expiresAt: Date.now() + 36e5
|
|
61517
|
-
//
|
|
61522
|
+
expiresAt: Date.now() + getCacheDuration(36e5)
|
|
61523
|
+
// Docs modunda 30 dakika
|
|
61518
61524
|
});
|
|
61519
61525
|
return count3;
|
|
61520
61526
|
} catch (error) {
|
|
@@ -61676,8 +61682,13 @@ function useGitHubData({
|
|
|
61676
61682
|
onError,
|
|
61677
61683
|
onDataUpdate,
|
|
61678
61684
|
onMilestoneReached,
|
|
61679
|
-
milestones = [10, 50, 100, 500, 1e3, 5e3, 1e4]
|
|
61685
|
+
milestones = [10, 50, 100, 500, 1e3, 5e3, 1e4],
|
|
61686
|
+
docsMode = false,
|
|
61687
|
+
mockDataFallback = true,
|
|
61688
|
+
forceMockData = false
|
|
61680
61689
|
}) {
|
|
61690
|
+
const isDocsMode2 = docsMode || typeof window !== "undefined" && (window.location.pathname.includes("/docs/") || window.location.pathname.includes("/components/"));
|
|
61691
|
+
const effectiveAutoRefresh = isDocsMode2 ? false : autoRefresh;
|
|
61681
61692
|
const [repos, setRepos] = useState([]);
|
|
61682
61693
|
const [stats, setStats] = useState(null);
|
|
61683
61694
|
const [loading, setLoading] = useState(true);
|
|
@@ -61687,7 +61698,9 @@ function useGitHubData({
|
|
|
61687
61698
|
const refreshTimeoutRef = useRef();
|
|
61688
61699
|
const previousStarsRef = useRef(/* @__PURE__ */ new Map());
|
|
61689
61700
|
const errorCountRef = useRef(0);
|
|
61690
|
-
const maxErrorCount = 2;
|
|
61701
|
+
const maxErrorCount = isDocsMode2 ? 1 : 2;
|
|
61702
|
+
const hasInitialFetchedRef = useRef(false);
|
|
61703
|
+
const docsDataCacheRef = useRef(null);
|
|
61691
61704
|
const milestonesRef = useRef(milestones);
|
|
61692
61705
|
const onMilestoneReachedRef = useRef(onMilestoneReached);
|
|
61693
61706
|
useEffect(() => {
|
|
@@ -61716,10 +61729,36 @@ function useGitHubData({
|
|
|
61716
61729
|
});
|
|
61717
61730
|
}, []);
|
|
61718
61731
|
const fetchData = useCallback(async () => {
|
|
61732
|
+
if (forceMockData) {
|
|
61733
|
+
console.log("[Mock Mode] Using mock data");
|
|
61734
|
+
const mockData = getMockGitHubData(username, repository, repositories);
|
|
61735
|
+
setRepos(mockData);
|
|
61736
|
+
const calculatedStats = calculateStats(mockData);
|
|
61737
|
+
setStats(calculatedStats);
|
|
61738
|
+
setError(null);
|
|
61739
|
+
setLoading(false);
|
|
61740
|
+
return;
|
|
61741
|
+
}
|
|
61742
|
+
if (isDocsMode2 && hasInitialFetchedRef.current && docsDataCacheRef.current) {
|
|
61743
|
+
console.log("[Docs Mode] Returning cached data, skipping API request");
|
|
61744
|
+
setRepos(docsDataCacheRef.current);
|
|
61745
|
+
const calculatedStats = calculateStats(docsDataCacheRef.current);
|
|
61746
|
+
setStats(calculatedStats);
|
|
61747
|
+
setLoading(false);
|
|
61748
|
+
return;
|
|
61749
|
+
}
|
|
61719
61750
|
if (errorCountRef.current >= maxErrorCount) {
|
|
61720
61751
|
console.warn("Maximum error count reached. Stopping requests.");
|
|
61752
|
+
if (isDocsMode2 && mockDataFallback) {
|
|
61753
|
+
const mockData = getMockGitHubData(username, repository, repositories);
|
|
61754
|
+
setRepos(mockData);
|
|
61755
|
+
const calculatedStats = calculateStats(mockData);
|
|
61756
|
+
setStats(calculatedStats);
|
|
61757
|
+
setError(null);
|
|
61758
|
+
} else {
|
|
61759
|
+
setError("Maximum retry limit exceeded. Please check your configuration.");
|
|
61760
|
+
}
|
|
61721
61761
|
setLoading(false);
|
|
61722
|
-
setError("Maximum retry limit exceeded. Please check your configuration.");
|
|
61723
61762
|
return;
|
|
61724
61763
|
}
|
|
61725
61764
|
const hasValidInput = username && repository || // Tek repository modu
|
|
@@ -61812,12 +61851,25 @@ function useGitHubData({
|
|
|
61812
61851
|
}
|
|
61813
61852
|
setLastUpdated(/* @__PURE__ */ new Date());
|
|
61814
61853
|
errorCountRef.current = 0;
|
|
61854
|
+
if (isDocsMode2) {
|
|
61855
|
+
hasInitialFetchedRef.current = true;
|
|
61856
|
+
docsDataCacheRef.current = enhancedRepos;
|
|
61857
|
+
}
|
|
61815
61858
|
} catch (err) {
|
|
61816
61859
|
const errorMessage = err instanceof Error ? err.message : "Failed to fetch data";
|
|
61817
61860
|
setError(errorMessage);
|
|
61818
61861
|
errorCountRef.current += 1;
|
|
61819
61862
|
console.error(`GitHub API error (${errorCountRef.current}/${maxErrorCount}):`, errorMessage);
|
|
61820
|
-
if (
|
|
61863
|
+
if (isDocsMode2 && mockDataFallback && !hasInitialFetchedRef.current) {
|
|
61864
|
+
console.warn("[Docs Mode] API failed, using mock data");
|
|
61865
|
+
const mockData = getMockGitHubData(username, repository, repositories);
|
|
61866
|
+
setRepos(mockData);
|
|
61867
|
+
const calculatedStats = calculateStats(mockData);
|
|
61868
|
+
setStats(calculatedStats);
|
|
61869
|
+
setError(null);
|
|
61870
|
+
hasInitialFetchedRef.current = true;
|
|
61871
|
+
docsDataCacheRef.current = mockData;
|
|
61872
|
+
} else if (onError) {
|
|
61821
61873
|
onError(err instanceof Error ? err : new Error(errorMessage));
|
|
61822
61874
|
}
|
|
61823
61875
|
} finally {
|
|
@@ -61834,7 +61886,10 @@ function useGitHubData({
|
|
|
61834
61886
|
checkMilestones,
|
|
61835
61887
|
// Artık stable
|
|
61836
61888
|
onDataUpdate,
|
|
61837
|
-
onError
|
|
61889
|
+
onError,
|
|
61890
|
+
isDocsMode2,
|
|
61891
|
+
mockDataFallback,
|
|
61892
|
+
forceMockData
|
|
61838
61893
|
]);
|
|
61839
61894
|
useEffect(() => {
|
|
61840
61895
|
const hasValidInput = username && repository || username && repositories && repositories.length > 0 || repositories && repositories.length > 0 && repositories.every((r2) => r2.includes("/")) || username;
|
|
@@ -61845,7 +61900,7 @@ function useGitHubData({
|
|
|
61845
61900
|
}
|
|
61846
61901
|
}, [fetchData]);
|
|
61847
61902
|
useEffect(() => {
|
|
61848
|
-
if (!
|
|
61903
|
+
if (!effectiveAutoRefresh)
|
|
61849
61904
|
return;
|
|
61850
61905
|
const scheduleRefresh = () => {
|
|
61851
61906
|
refreshTimeoutRef.current = setTimeout(() => {
|
|
@@ -61859,15 +61914,19 @@ function useGitHubData({
|
|
|
61859
61914
|
clearTimeout(refreshTimeoutRef.current);
|
|
61860
61915
|
}
|
|
61861
61916
|
};
|
|
61862
|
-
}, [
|
|
61917
|
+
}, [effectiveAutoRefresh, refreshInterval, fetchData]);
|
|
61863
61918
|
const refresh = useCallback(() => {
|
|
61919
|
+
if (isDocsMode2 && hasInitialFetchedRef.current) {
|
|
61920
|
+
console.warn("[Docs Mode] Refresh disabled after initial fetch");
|
|
61921
|
+
return Promise.resolve();
|
|
61922
|
+
}
|
|
61864
61923
|
if (errorCountRef.current >= maxErrorCount) {
|
|
61865
61924
|
console.warn("Cannot refresh: maximum error count reached");
|
|
61866
61925
|
return Promise.resolve();
|
|
61867
61926
|
}
|
|
61868
61927
|
clearCache();
|
|
61869
61928
|
return fetchData();
|
|
61870
|
-
}, [fetchData]);
|
|
61929
|
+
}, [fetchData, isDocsMode2]);
|
|
61871
61930
|
return {
|
|
61872
61931
|
repos,
|
|
61873
61932
|
stats,
|
|
@@ -61907,6 +61966,64 @@ function useGitHubNotifications(enabled = true) {
|
|
|
61907
61966
|
);
|
|
61908
61967
|
return { permission, notify };
|
|
61909
61968
|
}
|
|
61969
|
+
function getMockGitHubData(username, repository, repositories) {
|
|
61970
|
+
const defaultRepos = [
|
|
61971
|
+
{
|
|
61972
|
+
id: 1,
|
|
61973
|
+
name: repository || "awesome-project",
|
|
61974
|
+
full_name: `${username || "moonui"}/${repository || "awesome-project"}`,
|
|
61975
|
+
description: "An amazing open source project with great features",
|
|
61976
|
+
html_url: `https://github.com/${username || "moonui"}/${repository || "awesome-project"}`,
|
|
61977
|
+
homepage: "https://awesome-project.dev",
|
|
61978
|
+
stargazers_count: 12453,
|
|
61979
|
+
watchers_count: 543,
|
|
61980
|
+
forks_count: 2341,
|
|
61981
|
+
language: "TypeScript",
|
|
61982
|
+
topics: ["react", "ui", "components", "typescript"],
|
|
61983
|
+
created_at: "2022-01-15T10:30:00Z",
|
|
61984
|
+
updated_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
61985
|
+
pushed_at: (/* @__PURE__ */ new Date()).toISOString(),
|
|
61986
|
+
size: 4567,
|
|
61987
|
+
open_issues_count: 23,
|
|
61988
|
+
license: {
|
|
61989
|
+
key: "mit",
|
|
61990
|
+
name: "MIT License",
|
|
61991
|
+
spdx_id: "MIT",
|
|
61992
|
+
url: "https://api.github.com/licenses/mit"
|
|
61993
|
+
},
|
|
61994
|
+
owner: {
|
|
61995
|
+
login: username || "moonui",
|
|
61996
|
+
avatar_url: `https://github.com/${username || "moonui"}.png`,
|
|
61997
|
+
html_url: `https://github.com/${username || "moonui"}`,
|
|
61998
|
+
type: "Organization"
|
|
61999
|
+
},
|
|
62000
|
+
contributors_count: 89
|
|
62001
|
+
}
|
|
62002
|
+
];
|
|
62003
|
+
if (repositories && repositories.length > 0) {
|
|
62004
|
+
return repositories.map((repo, index2) => {
|
|
62005
|
+
const [owner, name] = repo.includes("/") ? repo.split("/") : [username || "moonui", repo];
|
|
62006
|
+
return {
|
|
62007
|
+
...defaultRepos[0],
|
|
62008
|
+
id: index2 + 1,
|
|
62009
|
+
name,
|
|
62010
|
+
full_name: `${owner}/${name}`,
|
|
62011
|
+
html_url: `https://github.com/${owner}/${name}`,
|
|
62012
|
+
stargazers_count: Math.floor(Math.random() * 2e4) + 1e3,
|
|
62013
|
+
forks_count: Math.floor(Math.random() * 3e3) + 100,
|
|
62014
|
+
watchers_count: Math.floor(Math.random() * 1e3) + 50,
|
|
62015
|
+
language: ["TypeScript", "JavaScript", "Python", "Go", "Rust"][index2 % 5],
|
|
62016
|
+
owner: {
|
|
62017
|
+
login: owner,
|
|
62018
|
+
avatar_url: `https://github.com/${owner}.png`,
|
|
62019
|
+
html_url: `https://github.com/${owner}`,
|
|
62020
|
+
type: "Organization"
|
|
62021
|
+
}
|
|
62022
|
+
};
|
|
62023
|
+
});
|
|
62024
|
+
}
|
|
62025
|
+
return defaultRepos;
|
|
62026
|
+
}
|
|
61910
62027
|
var MinimalVariant = ({ repos, stats, className }) => {
|
|
61911
62028
|
if (!stats)
|
|
61912
62029
|
return null;
|
|
@@ -62393,6 +62510,7 @@ var GitHubStarsInternal = ({
|
|
|
62393
62510
|
repository,
|
|
62394
62511
|
repositories,
|
|
62395
62512
|
token,
|
|
62513
|
+
useMockData = false,
|
|
62396
62514
|
variant = "card",
|
|
62397
62515
|
layout = "grid",
|
|
62398
62516
|
showDescription = true,
|
|
@@ -62429,7 +62547,15 @@ var GitHubStarsInternal = ({
|
|
|
62429
62547
|
size: size4 = "md",
|
|
62430
62548
|
customColors
|
|
62431
62549
|
}) => {
|
|
62432
|
-
const
|
|
62550
|
+
const hasValidProps = useMockData || username || repositories && repositories.length > 0;
|
|
62551
|
+
if (!useMockData && !hasValidProps) {
|
|
62552
|
+
return null;
|
|
62553
|
+
}
|
|
62554
|
+
const isDocsMode2 = typeof window !== "undefined" && (window.location.pathname.includes("/docs/") || window.location.pathname.includes("/components/"));
|
|
62555
|
+
const effectiveAutoRefresh = isDocsMode2 ? false : autoRefresh;
|
|
62556
|
+
const effectiveNotifications = isDocsMode2 ? false : enableNotifications;
|
|
62557
|
+
const effectiveRefreshInterval = isDocsMode2 ? 36e5 : refreshInterval;
|
|
62558
|
+
const { notify } = useGitHubNotifications(effectiveNotifications);
|
|
62433
62559
|
const handleMilestoneReached = t__default.useCallback((milestone) => {
|
|
62434
62560
|
if (celebrateAt?.includes(milestone.count)) {
|
|
62435
62561
|
confetti({
|
|
@@ -62457,14 +62583,20 @@ var GitHubStarsInternal = ({
|
|
|
62457
62583
|
repository,
|
|
62458
62584
|
repositories,
|
|
62459
62585
|
token,
|
|
62460
|
-
autoRefresh,
|
|
62461
|
-
refreshInterval,
|
|
62586
|
+
autoRefresh: effectiveAutoRefresh,
|
|
62587
|
+
refreshInterval: effectiveRefreshInterval,
|
|
62462
62588
|
sortBy,
|
|
62463
62589
|
maxItems,
|
|
62464
62590
|
onError,
|
|
62465
62591
|
onDataUpdate,
|
|
62466
62592
|
onMilestoneReached: handleMilestoneReached,
|
|
62467
|
-
milestones
|
|
62593
|
+
milestones,
|
|
62594
|
+
docsMode: isDocsMode2,
|
|
62595
|
+
// Docs mode flag'ini gönder
|
|
62596
|
+
mockDataFallback: true,
|
|
62597
|
+
// Docs modunda mock data kullan
|
|
62598
|
+
forceMockData: useMockData
|
|
62599
|
+
// Force mock data if true
|
|
62468
62600
|
});
|
|
62469
62601
|
const handleExport = t__default.useCallback((format7) => {
|
|
62470
62602
|
if (!enableExport)
|
|
@@ -62613,12 +62745,13 @@ var GitHubStarsInternal = ({
|
|
|
62613
62745
|
className: cn("w-full", className),
|
|
62614
62746
|
children: [
|
|
62615
62747
|
renderVariant(),
|
|
62616
|
-
rateLimitInfo && rateLimitInfo.remaining < 10 && /* @__PURE__ */ jsx("div", { className: "mt-4 p-3 bg-yellow-50 dark:bg-yellow-900/20 rounded-md text-sm", children: /* @__PURE__ */ jsxs("p", { className: "text-yellow-800 dark:text-yellow-200", children: [
|
|
62748
|
+
!isDocsMode2 && rateLimitInfo && rateLimitInfo.remaining < 10 && /* @__PURE__ */ jsx("div", { className: "mt-4 p-3 bg-yellow-50 dark:bg-yellow-900/20 rounded-md text-sm", children: /* @__PURE__ */ jsxs("p", { className: "text-yellow-800 dark:text-yellow-200", children: [
|
|
62617
62749
|
"\u26A0\uFE0F Low API rate limit: ",
|
|
62618
62750
|
rateLimitInfo.remaining,
|
|
62619
62751
|
" requests remaining.",
|
|
62620
62752
|
token ? "" : " Consider adding a GitHub token for higher limits."
|
|
62621
|
-
] }) })
|
|
62753
|
+
] }) }),
|
|
62754
|
+
isDocsMode2 && true && /* @__PURE__ */ jsx("div", { className: "mt-2 text-xs text-muted-foreground text-center", children: "\u{1F4DA} Docs Mode: API istekleri optimize edildi" })
|
|
62622
62755
|
]
|
|
62623
62756
|
}
|
|
62624
62757
|
);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@moontra/moonui-pro",
|
|
3
|
-
"version": "2.18.
|
|
3
|
+
"version": "2.18.5",
|
|
4
4
|
"description": "Premium React components for MoonUI - Advanced UI library with 50+ pro components including performance, interactive, and gesture components",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.mjs",
|
|
@@ -3,6 +3,19 @@ import { GitHubRepository, GitHubStats, GitHubActivity, LanguageStats, RateLimit
|
|
|
3
3
|
// Cache management
|
|
4
4
|
const cache = new Map<string, { data: any; timestamp: number; expiresAt: number }>()
|
|
5
5
|
|
|
6
|
+
// Docs mode detection
|
|
7
|
+
const isDocsMode = () => {
|
|
8
|
+
return typeof window !== "undefined" &&
|
|
9
|
+
(window.location.pathname.includes("/docs/") ||
|
|
10
|
+
window.location.pathname.includes("/components/"))
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
// Get cache duration based on mode
|
|
14
|
+
const getCacheDuration = (defaultDuration: number) => {
|
|
15
|
+
// Docs modunda cache süresini 30 dakikaya çıkar
|
|
16
|
+
return isDocsMode() ? 1800000 : defaultDuration // 30 dakika : default
|
|
17
|
+
}
|
|
18
|
+
|
|
6
19
|
// Language colors
|
|
7
20
|
export const LANGUAGE_COLORS: Record<string, string> = {
|
|
8
21
|
JavaScript: "#f7df1e",
|
|
@@ -86,7 +99,7 @@ export async function getRateLimitInfo(token?: string): Promise<RateLimitInfo> {
|
|
|
86
99
|
cache.set(cacheKey, {
|
|
87
100
|
data: rateLimitInfo,
|
|
88
101
|
timestamp: Date.now(),
|
|
89
|
-
expiresAt: Date.now() + 60000, //
|
|
102
|
+
expiresAt: Date.now() + getCacheDuration(60000), // Docs modunda daha uzun cache
|
|
90
103
|
})
|
|
91
104
|
|
|
92
105
|
return rateLimitInfo
|
|
@@ -121,7 +134,7 @@ export async function fetchUserRepositories(
|
|
|
121
134
|
cache.set(cacheKey, {
|
|
122
135
|
data: repos,
|
|
123
136
|
timestamp: Date.now(),
|
|
124
|
-
expiresAt: Date.now() + 300000, //
|
|
137
|
+
expiresAt: Date.now() + getCacheDuration(300000), // Docs modunda 30 dakika
|
|
125
138
|
})
|
|
126
139
|
|
|
127
140
|
return repos
|
|
@@ -146,7 +159,7 @@ export async function fetchRepository(
|
|
|
146
159
|
cache.set(cacheKey, {
|
|
147
160
|
data: repository,
|
|
148
161
|
timestamp: Date.now(),
|
|
149
|
-
expiresAt: Date.now() + 300000, //
|
|
162
|
+
expiresAt: Date.now() + getCacheDuration(300000), // Docs modunda 30 dakika
|
|
150
163
|
})
|
|
151
164
|
|
|
152
165
|
return repository
|
|
@@ -180,7 +193,7 @@ export async function fetchContributorsCount(
|
|
|
180
193
|
cache.set(cacheKey, {
|
|
181
194
|
data: count,
|
|
182
195
|
timestamp: Date.now(),
|
|
183
|
-
expiresAt: Date.now() + 3600000, //
|
|
196
|
+
expiresAt: Date.now() + getCacheDuration(3600000), // Docs modunda 30 dakika
|
|
184
197
|
})
|
|
185
198
|
return count
|
|
186
199
|
}
|
|
@@ -193,7 +206,7 @@ export async function fetchContributorsCount(
|
|
|
193
206
|
cache.set(cacheKey, {
|
|
194
207
|
data: count,
|
|
195
208
|
timestamp: Date.now(),
|
|
196
|
-
expiresAt: Date.now() + 3600000, //
|
|
209
|
+
expiresAt: Date.now() + getCacheDuration(3600000), // Docs modunda 30 dakika
|
|
197
210
|
})
|
|
198
211
|
|
|
199
212
|
return count
|
|
@@ -233,7 +246,7 @@ export async function fetchStarHistory(
|
|
|
233
246
|
cache.set(cacheKey, {
|
|
234
247
|
data: history,
|
|
235
248
|
timestamp: Date.now(),
|
|
236
|
-
expiresAt: Date.now() + 3600000, //
|
|
249
|
+
expiresAt: Date.now() + getCacheDuration(3600000), // Docs modunda 30 dakika
|
|
237
250
|
})
|
|
238
251
|
|
|
239
252
|
return history
|
|
@@ -29,6 +29,10 @@ interface UseGitHubDataOptions {
|
|
|
29
29
|
onDataUpdate?: (stats: GitHubStats) => void
|
|
30
30
|
onMilestoneReached?: (milestone: Milestone) => void
|
|
31
31
|
milestones?: number[]
|
|
32
|
+
// Docs mode optimizasyonları için
|
|
33
|
+
docsMode?: boolean
|
|
34
|
+
mockDataFallback?: boolean
|
|
35
|
+
forceMockData?: boolean // Force mock data instead of API
|
|
32
36
|
}
|
|
33
37
|
|
|
34
38
|
export function useGitHubData({
|
|
@@ -44,7 +48,17 @@ export function useGitHubData({
|
|
|
44
48
|
onDataUpdate,
|
|
45
49
|
onMilestoneReached,
|
|
46
50
|
milestones = [10, 50, 100, 500, 1000, 5000, 10000],
|
|
51
|
+
docsMode = false,
|
|
52
|
+
mockDataFallback = true,
|
|
53
|
+
forceMockData = false,
|
|
47
54
|
}: UseGitHubDataOptions) {
|
|
55
|
+
// Docs mode tespiti
|
|
56
|
+
const isDocsMode = docsMode || (typeof window !== "undefined" &&
|
|
57
|
+
(window.location.pathname.includes("/docs/") ||
|
|
58
|
+
window.location.pathname.includes("/components/")))
|
|
59
|
+
|
|
60
|
+
// Docs modunda autoRefresh'i devre dışı bırak
|
|
61
|
+
const effectiveAutoRefresh = isDocsMode ? false : autoRefresh
|
|
48
62
|
const [repos, setRepos] = useState<GitHubRepository[]>([])
|
|
49
63
|
const [stats, setStats] = useState<GitHubStats | null>(null)
|
|
50
64
|
const [loading, setLoading] = useState(true)
|
|
@@ -55,7 +69,9 @@ export function useGitHubData({
|
|
|
55
69
|
const refreshTimeoutRef = useRef<NodeJS.Timeout>()
|
|
56
70
|
const previousStarsRef = useRef<Map<string, number>>(new Map())
|
|
57
71
|
const errorCountRef = useRef<number>(0) // Hata sayısını takip et
|
|
58
|
-
const maxErrorCount = 2 //
|
|
72
|
+
const maxErrorCount = isDocsMode ? 1 : 2 // Docs modunda daha az deneme
|
|
73
|
+
const hasInitialFetchedRef = useRef(false) // İlk fetch yapıldı mı?
|
|
74
|
+
const docsDataCacheRef = useRef<GitHubRepository[] | null>(null) // Docs mode cache
|
|
59
75
|
|
|
60
76
|
// checkMilestones fonksiyonunu ref olarak sakla - bu şekilde her render'da yeniden oluşturulmaz
|
|
61
77
|
const milestonesRef = useRef(milestones)
|
|
@@ -93,11 +109,44 @@ export function useGitHubData({
|
|
|
93
109
|
}, []) // Boş dependency array - fonksiyon asla yeniden oluşturulmaz
|
|
94
110
|
|
|
95
111
|
const fetchData = useCallback(async () => {
|
|
112
|
+
// If forceMockData is true, always return mock data
|
|
113
|
+
if (forceMockData) {
|
|
114
|
+
console.log("[Mock Mode] Using mock data")
|
|
115
|
+
const mockData = getMockGitHubData(username, repository, repositories)
|
|
116
|
+
setRepos(mockData)
|
|
117
|
+
const calculatedStats = calculateStats(mockData)
|
|
118
|
+
setStats(calculatedStats)
|
|
119
|
+
setError(null)
|
|
120
|
+
setLoading(false)
|
|
121
|
+
return
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Docs modunda ve daha önce fetch yapıldıysa, cache'den döndür
|
|
125
|
+
if (isDocsMode && hasInitialFetchedRef.current && docsDataCacheRef.current) {
|
|
126
|
+
console.log("[Docs Mode] Returning cached data, skipping API request")
|
|
127
|
+
setRepos(docsDataCacheRef.current)
|
|
128
|
+
const calculatedStats = calculateStats(docsDataCacheRef.current)
|
|
129
|
+
setStats(calculatedStats)
|
|
130
|
+
setLoading(false)
|
|
131
|
+
return
|
|
132
|
+
}
|
|
133
|
+
|
|
96
134
|
// Hata limiti aşıldıysa istek yapma
|
|
97
135
|
if (errorCountRef.current >= maxErrorCount) {
|
|
98
136
|
console.warn("Maximum error count reached. Stopping requests.")
|
|
137
|
+
|
|
138
|
+
// Docs modunda ve mockDataFallback aktifse mock data göster
|
|
139
|
+
if (isDocsMode && mockDataFallback) {
|
|
140
|
+
const mockData = getMockGitHubData(username, repository, repositories)
|
|
141
|
+
setRepos(mockData)
|
|
142
|
+
const calculatedStats = calculateStats(mockData)
|
|
143
|
+
setStats(calculatedStats)
|
|
144
|
+
setError(null)
|
|
145
|
+
} else {
|
|
146
|
+
setError("Maximum retry limit exceeded. Please check your configuration.")
|
|
147
|
+
}
|
|
148
|
+
|
|
99
149
|
setLoading(false)
|
|
100
|
-
setError("Maximum retry limit exceeded. Please check your configuration.")
|
|
101
150
|
return
|
|
102
151
|
}
|
|
103
152
|
|
|
@@ -222,6 +271,12 @@ export function useGitHubData({
|
|
|
222
271
|
setLastUpdated(new Date())
|
|
223
272
|
// Başarılı olduğunda hata sayacını sıfırla
|
|
224
273
|
errorCountRef.current = 0
|
|
274
|
+
|
|
275
|
+
// Docs modunda başarılı veriyi cache'le
|
|
276
|
+
if (isDocsMode) {
|
|
277
|
+
hasInitialFetchedRef.current = true
|
|
278
|
+
docsDataCacheRef.current = enhancedRepos
|
|
279
|
+
}
|
|
225
280
|
} catch (err) {
|
|
226
281
|
const errorMessage = err instanceof Error ? err.message : "Failed to fetch data"
|
|
227
282
|
setError(errorMessage)
|
|
@@ -230,7 +285,17 @@ export function useGitHubData({
|
|
|
230
285
|
errorCountRef.current += 1
|
|
231
286
|
console.error(`GitHub API error (${errorCountRef.current}/${maxErrorCount}):`, errorMessage)
|
|
232
287
|
|
|
233
|
-
|
|
288
|
+
// Docs modunda ve mockDataFallback aktifse mock data göster
|
|
289
|
+
if (isDocsMode && mockDataFallback && !hasInitialFetchedRef.current) {
|
|
290
|
+
console.warn("[Docs Mode] API failed, using mock data")
|
|
291
|
+
const mockData = getMockGitHubData(username, repository, repositories)
|
|
292
|
+
setRepos(mockData)
|
|
293
|
+
const calculatedStats = calculateStats(mockData)
|
|
294
|
+
setStats(calculatedStats)
|
|
295
|
+
setError(null)
|
|
296
|
+
hasInitialFetchedRef.current = true
|
|
297
|
+
docsDataCacheRef.current = mockData
|
|
298
|
+
} else if (onError) {
|
|
234
299
|
onError(err instanceof Error ? err : new Error(errorMessage))
|
|
235
300
|
}
|
|
236
301
|
} finally {
|
|
@@ -246,6 +311,9 @@ export function useGitHubData({
|
|
|
246
311
|
checkMilestones, // Artık stable
|
|
247
312
|
onDataUpdate,
|
|
248
313
|
onError,
|
|
314
|
+
isDocsMode,
|
|
315
|
+
mockDataFallback,
|
|
316
|
+
forceMockData,
|
|
249
317
|
])
|
|
250
318
|
|
|
251
319
|
// Initial fetch
|
|
@@ -266,7 +334,8 @@ export function useGitHubData({
|
|
|
266
334
|
|
|
267
335
|
// Auto-refresh
|
|
268
336
|
useEffect(() => {
|
|
269
|
-
|
|
337
|
+
// Docs modunda auto-refresh'i tamamen devre dışı bırak
|
|
338
|
+
if (!effectiveAutoRefresh) return
|
|
270
339
|
|
|
271
340
|
const scheduleRefresh = () => {
|
|
272
341
|
refreshTimeoutRef.current = setTimeout(() => {
|
|
@@ -282,9 +351,15 @@ export function useGitHubData({
|
|
|
282
351
|
clearTimeout(refreshTimeoutRef.current)
|
|
283
352
|
}
|
|
284
353
|
}
|
|
285
|
-
}, [
|
|
354
|
+
}, [effectiveAutoRefresh, refreshInterval, fetchData])
|
|
286
355
|
|
|
287
356
|
const refresh = useCallback(() => {
|
|
357
|
+
// Docs modunda refresh'i sınırla
|
|
358
|
+
if (isDocsMode && hasInitialFetchedRef.current) {
|
|
359
|
+
console.warn("[Docs Mode] Refresh disabled after initial fetch")
|
|
360
|
+
return Promise.resolve()
|
|
361
|
+
}
|
|
362
|
+
|
|
288
363
|
// Hata limiti aşıldıysa refresh yapma
|
|
289
364
|
if (errorCountRef.current >= maxErrorCount) {
|
|
290
365
|
console.warn("Cannot refresh: maximum error count reached")
|
|
@@ -293,7 +368,7 @@ export function useGitHubData({
|
|
|
293
368
|
|
|
294
369
|
clearCache()
|
|
295
370
|
return fetchData()
|
|
296
|
-
}, [fetchData])
|
|
371
|
+
}, [fetchData, isDocsMode])
|
|
297
372
|
|
|
298
373
|
return {
|
|
299
374
|
repos,
|
|
@@ -372,4 +447,70 @@ export function useGitHubNotifications(enabled: boolean = true) {
|
|
|
372
447
|
)
|
|
373
448
|
|
|
374
449
|
return { permission, notify }
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
// Mock data generator for docs mode
|
|
453
|
+
function getMockGitHubData(
|
|
454
|
+
username?: string,
|
|
455
|
+
repository?: string,
|
|
456
|
+
repositories?: string[]
|
|
457
|
+
): GitHubRepository[] {
|
|
458
|
+
const defaultRepos: GitHubRepository[] = [
|
|
459
|
+
{
|
|
460
|
+
id: 1,
|
|
461
|
+
name: repository || "awesome-project",
|
|
462
|
+
full_name: `${username || "moonui"}/${repository || "awesome-project"}`,
|
|
463
|
+
description: "An amazing open source project with great features",
|
|
464
|
+
html_url: `https://github.com/${username || "moonui"}/${repository || "awesome-project"}`,
|
|
465
|
+
homepage: "https://awesome-project.dev",
|
|
466
|
+
stargazers_count: 12453,
|
|
467
|
+
watchers_count: 543,
|
|
468
|
+
forks_count: 2341,
|
|
469
|
+
language: "TypeScript",
|
|
470
|
+
topics: ["react", "ui", "components", "typescript"],
|
|
471
|
+
created_at: "2022-01-15T10:30:00Z",
|
|
472
|
+
updated_at: new Date().toISOString(),
|
|
473
|
+
pushed_at: new Date().toISOString(),
|
|
474
|
+
size: 4567,
|
|
475
|
+
open_issues_count: 23,
|
|
476
|
+
license: {
|
|
477
|
+
key: "mit",
|
|
478
|
+
name: "MIT License",
|
|
479
|
+
spdx_id: "MIT",
|
|
480
|
+
url: "https://api.github.com/licenses/mit",
|
|
481
|
+
},
|
|
482
|
+
owner: {
|
|
483
|
+
login: username || "moonui",
|
|
484
|
+
avatar_url: `https://github.com/${username || "moonui"}.png`,
|
|
485
|
+
html_url: `https://github.com/${username || "moonui"}`,
|
|
486
|
+
type: "Organization",
|
|
487
|
+
},
|
|
488
|
+
contributors_count: 89,
|
|
489
|
+
},
|
|
490
|
+
]
|
|
491
|
+
|
|
492
|
+
if (repositories && repositories.length > 0) {
|
|
493
|
+
return repositories.map((repo, index) => {
|
|
494
|
+
const [owner, name] = repo.includes('/') ? repo.split('/') : [username || "moonui", repo]
|
|
495
|
+
return {
|
|
496
|
+
...defaultRepos[0],
|
|
497
|
+
id: index + 1,
|
|
498
|
+
name: name,
|
|
499
|
+
full_name: `${owner}/${name}`,
|
|
500
|
+
html_url: `https://github.com/${owner}/${name}`,
|
|
501
|
+
stargazers_count: Math.floor(Math.random() * 20000) + 1000,
|
|
502
|
+
forks_count: Math.floor(Math.random() * 3000) + 100,
|
|
503
|
+
watchers_count: Math.floor(Math.random() * 1000) + 50,
|
|
504
|
+
language: ["TypeScript", "JavaScript", "Python", "Go", "Rust"][index % 5],
|
|
505
|
+
owner: {
|
|
506
|
+
login: owner,
|
|
507
|
+
avatar_url: `https://github.com/${owner}.png`,
|
|
508
|
+
html_url: `https://github.com/${owner}`,
|
|
509
|
+
type: "Organization",
|
|
510
|
+
},
|
|
511
|
+
}
|
|
512
|
+
})
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
return defaultRepos
|
|
375
516
|
}
|
|
@@ -24,6 +24,7 @@ const GitHubStarsInternal: React.FC<GitHubStarsProps> = ({
|
|
|
24
24
|
repository,
|
|
25
25
|
repositories,
|
|
26
26
|
token,
|
|
27
|
+
useMockData = false,
|
|
27
28
|
variant = "card",
|
|
28
29
|
layout = "grid",
|
|
29
30
|
showDescription = true,
|
|
@@ -60,7 +61,24 @@ const GitHubStarsInternal: React.FC<GitHubStarsProps> = ({
|
|
|
60
61
|
size = "md",
|
|
61
62
|
customColors,
|
|
62
63
|
}) => {
|
|
63
|
-
|
|
64
|
+
// Docs mode tespiti
|
|
65
|
+
// Check if component has valid props to render
|
|
66
|
+
const hasValidProps = useMockData || username || (repositories && repositories.length > 0)
|
|
67
|
+
|
|
68
|
+
// If useMockData is false and no valid data props, don't render
|
|
69
|
+
if (!useMockData && !hasValidProps) {
|
|
70
|
+
return null
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const isDocsMode = typeof window !== "undefined" &&
|
|
74
|
+
(window.location.pathname.includes("/docs/") ||
|
|
75
|
+
window.location.pathname.includes("/components/"))
|
|
76
|
+
|
|
77
|
+
// Docs modunda bazı özellikleri override et
|
|
78
|
+
const effectiveAutoRefresh = isDocsMode ? false : autoRefresh
|
|
79
|
+
const effectiveNotifications = isDocsMode ? false : enableNotifications
|
|
80
|
+
const effectiveRefreshInterval = isDocsMode ? 3600000 : refreshInterval // Docs modunda 1 saat
|
|
81
|
+
const { notify } = useGitHubNotifications(effectiveNotifications)
|
|
64
82
|
|
|
65
83
|
// onMilestoneReached callback'ini memoize et
|
|
66
84
|
const handleMilestoneReached = React.useCallback((milestone: any) => {
|
|
@@ -96,14 +114,17 @@ const GitHubStarsInternal: React.FC<GitHubStarsProps> = ({
|
|
|
96
114
|
repository,
|
|
97
115
|
repositories,
|
|
98
116
|
token,
|
|
99
|
-
autoRefresh,
|
|
100
|
-
refreshInterval,
|
|
117
|
+
autoRefresh: effectiveAutoRefresh,
|
|
118
|
+
refreshInterval: effectiveRefreshInterval,
|
|
101
119
|
sortBy,
|
|
102
120
|
maxItems,
|
|
103
121
|
onError,
|
|
104
122
|
onDataUpdate,
|
|
105
123
|
onMilestoneReached: handleMilestoneReached,
|
|
106
124
|
milestones,
|
|
125
|
+
docsMode: isDocsMode, // Docs mode flag'ini gönder
|
|
126
|
+
mockDataFallback: true, // Docs modunda mock data kullan
|
|
127
|
+
forceMockData: useMockData, // Force mock data if true
|
|
107
128
|
})
|
|
108
129
|
|
|
109
130
|
const handleExport = React.useCallback((format: "json" | "csv") => {
|
|
@@ -296,8 +317,8 @@ const GitHubStarsInternal: React.FC<GitHubStarsProps> = ({
|
|
|
296
317
|
>
|
|
297
318
|
{renderVariant()}
|
|
298
319
|
|
|
299
|
-
{/* Rate limit warning */}
|
|
300
|
-
{rateLimitInfo && rateLimitInfo.remaining < 10 && (
|
|
320
|
+
{/* Rate limit warning - Docs modunda gösterme */}
|
|
321
|
+
{!isDocsMode && rateLimitInfo && rateLimitInfo.remaining < 10 && (
|
|
301
322
|
<div className="mt-4 p-3 bg-yellow-50 dark:bg-yellow-900/20 rounded-md text-sm">
|
|
302
323
|
<p className="text-yellow-800 dark:text-yellow-200">
|
|
303
324
|
⚠️ Low API rate limit: {rateLimitInfo.remaining} requests remaining.
|
|
@@ -305,6 +326,13 @@ const GitHubStarsInternal: React.FC<GitHubStarsProps> = ({
|
|
|
305
326
|
</p>
|
|
306
327
|
</div>
|
|
307
328
|
)}
|
|
329
|
+
|
|
330
|
+
{/* Docs mode indicator - sadece development modunda göster */}
|
|
331
|
+
{isDocsMode && process.env.NODE_ENV === "development" && (
|
|
332
|
+
<div className="mt-2 text-xs text-muted-foreground text-center">
|
|
333
|
+
📚 Docs Mode: API istekleri optimize edildi
|
|
334
|
+
</div>
|
|
335
|
+
)}
|
|
308
336
|
</motion.div>
|
|
309
337
|
)
|
|
310
338
|
}
|
|
@@ -83,6 +83,7 @@ export interface GitHubStarsProps {
|
|
|
83
83
|
repository?: string // For single repo mode
|
|
84
84
|
repositories?: string[] // For multiple repos
|
|
85
85
|
token?: string // GitHub token for higher rate limits
|
|
86
|
+
useMockData?: boolean // Force mock data instead of API requests
|
|
86
87
|
|
|
87
88
|
// Display options
|
|
88
89
|
variant?: DisplayVariant
|