mirror of
https://github.com/kjanat/livedash-node.git
synced 2026-02-13 12:55:42 +01:00
refactor: apply React best practices and migrate to ESLint CLI
- Dynamic import for WordCloud component (code splitting) - Fix waterfall in handleRefresh with Promise.all - Memoize data prep functions in overview page (7 useMemo hooks) - Replace useState+useEffect with useMemo in CountryDisplay/LanguageDisplay - Memoize navigationCards and class getters in dashboard page - Extract inline handlers with useCallback - Fix missing index parameter in TopQuestionsChart map - Migrate from next lint to ESLint CLI (Next.js 16 deprecation)
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { useMemo } from "react";
|
||||
import { getLocalizedCountryName } from "../lib/localization";
|
||||
|
||||
interface CountryDisplayProps {
|
||||
@@ -16,16 +16,11 @@ export default function CountryDisplay({
|
||||
countryCode,
|
||||
className,
|
||||
}: CountryDisplayProps) {
|
||||
const [countryName, setCountryName] = useState<string>(
|
||||
countryCode || "Unknown"
|
||||
// Compute directly - Intl.DisplayNames is synchronous
|
||||
const countryName = useMemo(
|
||||
() => (countryCode ? getLocalizedCountryName(countryCode) : "Unknown"),
|
||||
[countryCode]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
// Only run in the browser and if we have a valid code
|
||||
if (typeof window !== "undefined" && countryCode) {
|
||||
setCountryName(getLocalizedCountryName(countryCode));
|
||||
}
|
||||
}, [countryCode]);
|
||||
|
||||
return <span className={className}>{countryName}</span>;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useState } from "react";
|
||||
import { useMemo } from "react";
|
||||
import { getLocalizedLanguageName } from "../lib/localization";
|
||||
|
||||
interface LanguageDisplayProps {
|
||||
@@ -16,16 +16,11 @@ export default function LanguageDisplay({
|
||||
languageCode,
|
||||
className,
|
||||
}: LanguageDisplayProps) {
|
||||
const [languageName, setLanguageName] = useState<string>(
|
||||
languageCode || "Unknown"
|
||||
// Compute directly - Intl.DisplayNames is synchronous
|
||||
const languageName = useMemo(
|
||||
() => (languageCode ? getLocalizedLanguageName(languageCode) : "Unknown"),
|
||||
[languageCode]
|
||||
);
|
||||
|
||||
useEffect(() => {
|
||||
// Only run in the browser and if we have a valid code
|
||||
if (typeof window !== "undefined" && languageCode) {
|
||||
setLanguageName(getLocalizedLanguageName(languageCode));
|
||||
}
|
||||
}, [languageCode]);
|
||||
|
||||
return <span className={className}>{languageName}</span>;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ export default function TopQuestionsChart({
|
||||
</CardHeader>
|
||||
<CardContent>
|
||||
<div className="space-y-4">
|
||||
{data.map((question) => {
|
||||
{data.map((question, index) => {
|
||||
const percentage =
|
||||
maxCount > 0 ? (question.count / maxCount) * 100 : 0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user