feat: setup eslint at root level (#27)

* feat: setup eslint at root level

* chore: disable craco eslint-plugin

* fix: add missing extension to import

* fix: apply review

* chore: use gitignore to exclude files from eslint

* chore: disable eslint step in craco via config rather than env variable

* chore: remove npmrc

* chore: remove `eslint-plugin-react` override
This commit is contained in:
Marco Pasqualetti
2026-01-21 22:48:08 +01:00
committed by GitHub
parent 74b314ab0f
commit dff4bfcecb
30 changed files with 352 additions and 501 deletions
-3
View File
@@ -1,6 +1,3 @@
/* eslint-disable react/jsx-props-no-spreading */
/* eslint-disable react/no-danger */
import React, { useEffect, useRef, useState } from "react";
import PropTypes from "prop-types";
@@ -1,4 +1,3 @@
/* eslint-disable react/jsx-props-no-spreading */
import React from "react";
import PropTypes from "prop-types";
@@ -1,5 +1,3 @@
/* eslint-disable react/no-danger */
import React from "react";
import PropTypes from "prop-types";
@@ -1,5 +1,3 @@
/* eslint-disable react/no-danger */
import React, { useEffect, useRef, useState } from "react";
import PropTypes from "prop-types";
@@ -1,5 +1,3 @@
/* eslint-disable react/no-danger */
import React, { useEffect, useRef, useState } from "react";
import PropTypes from "prop-types";
-1
View File
@@ -1,4 +1,3 @@
/* eslint-disable no-nested-ternary */
export const PROD = false;
export const USE_LOGGER = true;
+9 -3
View File
@@ -21,9 +21,15 @@ import { clearAxiosCache } from "../../axios-override";
function App() {
const toMessage = (input) => {
if (typeof input === "string") return input;
if (input.reason?.message) return input.reason.message;
if (input.message) return input.message;
if (typeof input === "string") {
return input;
}
if (input.reason?.message) {
return input.reason.message;
}
if (input.message) {
return input.message;
}
try {
return JSON.stringify(input);
} catch {
+1 -4
View File
@@ -1,5 +1,4 @@
import React, { useState } from "react";
import { useDispatch } from "react-redux";
import React from "react";
import PropTypes from "prop-types";
import { Link } from "react-router-dom";
@@ -56,8 +55,6 @@ MobileLink.propTypes = propTypes;
MobileLink.defaultProps = defaultProps;
const Header = ({ stage, setStage }) => {
const dispatch = useDispatch();
return (
<>
<div className="text-gray-100 bg-gray-800 shadow-md body-font z-50">
+7 -2
View File
@@ -76,6 +76,8 @@ const HomeScreen = ({ stage, setStage }) => {
const [enableAnimations, setEnableAnimations] = useState(true);
const [usePercent, setUsePercent] = useState(false);
const [theme, setTheme] = useState("default");
const resetCustomization = () => {
if (selectedCard === CardTypes.TOP_LANGS) {
setLangsCount(4);
@@ -204,7 +206,6 @@ const HomeScreen = ({ stage, setStage }) => {
}
// for stage four
const [theme, setTheme] = useState("default");
let themeSuffix = fullSuffix;
if (
@@ -419,6 +420,7 @@ const HomeScreen = ({ stage, setStage }) => {
)}
{stage === 4 && (
<DisplayStage
// eslint-disable-next-line consistent-return
filename={(() => {
switch (selectedCard) {
case CardTypes.STATS:
@@ -432,17 +434,20 @@ const HomeScreen = ({ stage, setStage }) => {
return `${wakatimeUser}_card`;
}
})()}
// eslint-disable-next-line consistent-return
link={(() => {
switch (selectedCard) {
case CardTypes.STATS:
case CardTypes.TOP_LANGS:
return `https://${HOST}/api${themeSuffix}`;
case CardTypes.PIN:
case CardTypes.PIN: {
let myRepo = repo;
if (!myRepo.includes("/")) {
myRepo = `${userId}/${myRepo}`;
}
return `https://github.com/${myRepo}`;
}
case CardTypes.GIST:
return gistUrl;
case CardTypes.WAKATIME:
@@ -13,8 +13,6 @@ import { classnames } from "../../../utils";
import { HOST } from "../../../constants";
const DisplayStage = ({ filename, link, themeSuffix, guestHint }) => {
const card = themeSuffix.split("?")[0];
const downloadPNG = () => {
saveSvgAsPng(
document.getElementById("svgWrapper").shadowRoot.firstElementChild
-1
View File
@@ -7,7 +7,6 @@ const initialState = {
privateAccess: null,
};
// eslint-disable-next-line default-param-last
export default (state = initialState, action) => {
switch (action.type) {
case types.LOGIN:
+6 -2
View File
@@ -4,7 +4,11 @@ import loggerMiddleware from "./logger";
import rootReducer from "./reducers";
import { USE_LOGGER } from "../constants";
export default function configureStore(intialState) {
/**
* @param {unknown?} initialState store initial state
* @returns {import('redux').Store} store
*/
export default function configureStore(initialState) {
let middlewares = [];
if (USE_LOGGER) {
middlewares = [loggerMiddleware];
@@ -14,7 +18,7 @@ export default function configureStore(intialState) {
const enhancers = [middlewareEnhancer];
const composedEnhancers = compose(...enhancers);
const store = createStore(rootReducer, intialState, composedEnhancers);
const store = createStore(rootReducer, initialState, composedEnhancers);
return store;
}
+4
View File
@@ -1,3 +1,7 @@
/**
* @param {Array<string>} args list of class names
* @returns string classname attribute
*/
export function classnames(...args) {
return args.join(" ");
}
+2
View File
@@ -1,6 +1,8 @@
import axios from "axios";
import { HOST } from "./constants";
// See https://github.com/stats-organization/github-stats-extended/pull/27#discussion_r2712184285
// eslint-disable-next-line no-unused-vars
const fetchWakatimeStats = async ({ username, api_domain }) => {
if (!username) {
throw new Error("missing parameter: username");