- Add comprehensive analytics components with export functionality - Implement territory management with manager performance tracking - Add seatmap components for venue layout management - Create customer management features with modal interface - Add advanced hooks for dashboard flags and territory data - Implement seat selection and venue management utilities - Add type definitions for ticketing and seatmap systems 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
482 lines
15 KiB
JavaScript
482 lines
15 KiB
JavaScript
import js from '@eslint/js';
|
|
import reactHooks from 'eslint-plugin-react-hooks';
|
|
import reactRefresh from 'eslint-plugin-react-refresh';
|
|
import react from 'eslint-plugin-react';
|
|
import jsxA11y from 'eslint-plugin-jsx-a11y';
|
|
import importPlugin from 'eslint-plugin-import';
|
|
import tseslint from 'typescript-eslint';
|
|
import prettier from 'eslint-config-prettier';
|
|
|
|
export default tseslint.config(
|
|
{
|
|
ignores: [
|
|
'dist/**',
|
|
'node_modules/**',
|
|
'build/**',
|
|
'coverage/**',
|
|
'public/**',
|
|
'*.config.js',
|
|
'*.config.ts',
|
|
'.vscode/**',
|
|
'.git/**',
|
|
'qa-screenshots/**',
|
|
'claude-logs/**',
|
|
],
|
|
},
|
|
// Configuration for TypeScript files
|
|
{
|
|
extends: [
|
|
js.configs.recommended,
|
|
...tseslint.configs.recommended,
|
|
...tseslint.configs.strict,
|
|
prettier,
|
|
],
|
|
files: ['**/*.{ts,tsx}'],
|
|
languageOptions: {
|
|
ecmaVersion: 2023,
|
|
sourceType: 'module',
|
|
parser: tseslint.parser,
|
|
parserOptions: {
|
|
ecmaFeatures: {
|
|
jsx: true,
|
|
},
|
|
project: './tsconfig.json',
|
|
tsconfigRootDir: import.meta.dirname,
|
|
},
|
|
globals: {
|
|
window: 'readonly',
|
|
document: 'readonly',
|
|
console: 'readonly',
|
|
process: 'readonly',
|
|
Buffer: 'readonly',
|
|
__dirname: 'readonly',
|
|
__filename: 'readonly',
|
|
global: 'readonly',
|
|
},
|
|
},
|
|
plugins: {
|
|
react: react,
|
|
'react-hooks': reactHooks,
|
|
'react-refresh': reactRefresh,
|
|
'jsx-a11y': jsxA11y,
|
|
import: importPlugin,
|
|
},
|
|
settings: {
|
|
react: {
|
|
version: 'detect',
|
|
},
|
|
'import/resolver': {
|
|
typescript: {
|
|
alwaysTryTypes: true,
|
|
project: './tsconfig.json',
|
|
},
|
|
node: {
|
|
extensions: ['.js', '.jsx', '.ts', '.tsx'],
|
|
},
|
|
},
|
|
'import/parsers': {
|
|
'@typescript-eslint/parser': ['.ts', '.tsx'],
|
|
},
|
|
},
|
|
rules: {
|
|
// React Rules - Strict Configuration
|
|
...react.configs.recommended.rules,
|
|
...react.configs['jsx-runtime'].rules,
|
|
...reactHooks.configs.recommended.rules,
|
|
...jsxA11y.configs.strict.rules,
|
|
|
|
// React Refresh
|
|
'react-refresh/only-export-components': [
|
|
'warn',
|
|
{ allowConstantExport: true },
|
|
],
|
|
|
|
// React Specific
|
|
'react/prop-types': 'off', // Using TypeScript for prop validation
|
|
'react/jsx-uses-react': 'off', // Not needed with new JSX transform
|
|
'react/react-in-jsx-scope': 'off', // Not needed with new JSX transform
|
|
'react/jsx-props-no-spreading': [
|
|
'warn',
|
|
{
|
|
html: 'enforce',
|
|
custom: 'ignore',
|
|
explicitSpread: 'ignore',
|
|
},
|
|
],
|
|
'react/jsx-key': [
|
|
'error',
|
|
{
|
|
checkFragmentShorthand: true,
|
|
checkKeyMustBeforeSpread: true,
|
|
warnOnDuplicates: true,
|
|
},
|
|
],
|
|
'react/jsx-no-useless-fragment': ['warn', { allowExpressions: true }],
|
|
'react/self-closing-comp': ['warn', { component: true, html: true }],
|
|
'react/jsx-boolean-value': ['warn', 'never'],
|
|
'react/jsx-curly-brace-presence': [
|
|
'warn',
|
|
{
|
|
props: 'never',
|
|
children: 'never',
|
|
},
|
|
],
|
|
'react/jsx-pascal-case': ['error', { allowAllCaps: true }],
|
|
'react/no-array-index-key': 'warn', // Warn about index keys - use stable IDs when possible
|
|
'react/no-danger': 'error',
|
|
'react/no-deprecated': 'error',
|
|
'react/no-unsafe': 'error',
|
|
'react/hook-use-state': 'warn',
|
|
'react-hooks/exhaustive-deps': 'error', // Strict enforcement of exhaustive deps
|
|
'react/display-name': 'error', // All components must have display names
|
|
|
|
// Accessibility - Additional Strict Rules
|
|
'jsx-a11y/no-autofocus': ['error', { ignoreNonDOM: true }],
|
|
'jsx-a11y/anchor-is-valid': 'error',
|
|
'jsx-a11y/click-events-have-key-events': 'error',
|
|
'jsx-a11y/interactive-supports-focus': 'error',
|
|
'jsx-a11y/label-has-associated-control': 'error',
|
|
'jsx-a11y/media-has-caption': 'error',
|
|
'jsx-a11y/no-static-element-interactions': 'error',
|
|
'jsx-a11y/role-has-required-aria-props': 'error',
|
|
'jsx-a11y/role-supports-aria-props': 'error',
|
|
'jsx-a11y/scope': 'error',
|
|
'jsx-a11y/heading-has-content': 'error',
|
|
'jsx-a11y/img-redundant-alt': 'error',
|
|
|
|
// TypeScript Rules
|
|
'@typescript-eslint/no-unused-vars': [
|
|
'error',
|
|
{
|
|
argsIgnorePattern: '^_',
|
|
varsIgnorePattern: '^_',
|
|
caughtErrorsIgnorePattern: '^_',
|
|
destructuredArrayIgnorePattern: '^_',
|
|
ignoreRestSiblings: true,
|
|
},
|
|
],
|
|
'@typescript-eslint/no-explicit-any': 'error',
|
|
'@typescript-eslint/no-non-null-assertion': 'warn', // Sometimes needed for DOM manipulation
|
|
'@typescript-eslint/prefer-nullish-coalescing': 'error',
|
|
'@typescript-eslint/prefer-optional-chain': 'error',
|
|
'@typescript-eslint/no-unnecessary-condition': 'warn',
|
|
'@typescript-eslint/no-unnecessary-type-assertion': 'error',
|
|
'@typescript-eslint/no-unused-expressions': 'error',
|
|
'@typescript-eslint/prefer-readonly': 'warn',
|
|
'@typescript-eslint/explicit-function-return-type': [
|
|
'warn', // Enforce explicit return types for better documentation
|
|
{
|
|
allowExpressions: true,
|
|
allowTypedFunctionExpressions: true,
|
|
allowHigherOrderFunctions: true,
|
|
allowDirectConstAssertionInArrowFunctions: true,
|
|
allowConciseArrowFunctionExpressionsStartingWithVoid: true,
|
|
},
|
|
],
|
|
'@typescript-eslint/explicit-module-boundary-types': [
|
|
'warn',
|
|
{
|
|
allowArgumentsExplicitlyTypedAsAny: false,
|
|
allowDirectConstAssertionInArrowFunctions: true,
|
|
allowHigherOrderFunctions: true,
|
|
allowTypedFunctionExpressions: true,
|
|
},
|
|
],
|
|
'@typescript-eslint/consistent-type-imports': [
|
|
'error',
|
|
{ prefer: 'type-imports', fixStyle: 'separate-type-imports' },
|
|
],
|
|
'@typescript-eslint/consistent-type-exports': 'error',
|
|
'@typescript-eslint/method-signature-style': ['error', 'property'],
|
|
'@typescript-eslint/array-type': ['error', { default: 'array' }],
|
|
'@typescript-eslint/ban-tslint-comment': 'error',
|
|
'@typescript-eslint/class-literal-property-style': ['error', 'fields'],
|
|
|
|
// Import Rules
|
|
'import/order': [
|
|
'error',
|
|
{
|
|
groups: [
|
|
'builtin',
|
|
'external',
|
|
'internal',
|
|
'parent',
|
|
'sibling',
|
|
'index',
|
|
'type',
|
|
],
|
|
pathGroups: [
|
|
{
|
|
pattern: 'react',
|
|
group: 'builtin',
|
|
position: 'before',
|
|
},
|
|
{
|
|
pattern: 'react-*',
|
|
group: 'external',
|
|
position: 'before',
|
|
},
|
|
{
|
|
pattern: '@/**',
|
|
group: 'internal',
|
|
position: 'before',
|
|
},
|
|
],
|
|
pathGroupsExcludedImportTypes: ['react'],
|
|
'newlines-between': 'always',
|
|
alphabetize: {
|
|
order: 'asc',
|
|
caseInsensitive: true,
|
|
},
|
|
},
|
|
],
|
|
'import/no-unresolved': 'error',
|
|
'import/no-unused-modules': 'warn',
|
|
'import/no-duplicates': 'error',
|
|
'import/no-self-import': 'error',
|
|
'import/no-cycle': ['error', { maxDepth: 10 }],
|
|
'import/prefer-default-export': 'off',
|
|
'import/no-default-export': 'off',
|
|
'import/named': 'error',
|
|
'import/namespace': 'error',
|
|
'import/default': 'off', // React 18 JSX transform doesn't export default
|
|
'import/export': 'error',
|
|
|
|
// General Code Quality - Strict Rules
|
|
'no-console': process.env.NODE_ENV === 'production'
|
|
? ['error', { allow: ['warn', 'error'] }]
|
|
: ['warn', { allow: ['warn', 'error', 'info'] }],
|
|
'prefer-const': 'error',
|
|
'no-debugger': 'error',
|
|
'no-alert': 'error',
|
|
'no-var': 'error',
|
|
'prefer-template': 'error',
|
|
'prefer-arrow-callback': 'error',
|
|
'arrow-body-style': ['warn', 'as-needed'],
|
|
'object-shorthand': ['error', 'always'],
|
|
'no-useless-rename': 'error',
|
|
'no-useless-computed-key': 'error',
|
|
'no-useless-constructor': 'error',
|
|
'no-useless-return': 'error',
|
|
'no-nested-ternary': 'off', // Allow nested ternaries for conditional rendering
|
|
'no-unneeded-ternary': 'error',
|
|
'prefer-destructuring': [
|
|
'warn',
|
|
{
|
|
array: false,
|
|
object: true,
|
|
},
|
|
],
|
|
'spaced-comment': ['error', 'always', { markers: ['/'] }],
|
|
eqeqeq: ['error', 'always', { null: 'ignore' }],
|
|
curly: ['error', 'all'],
|
|
'no-else-return': ['error', { allowElseIf: false }],
|
|
'no-return-assign': 'error',
|
|
'no-return-await': 'error',
|
|
'require-await': 'error',
|
|
'no-async-promise-executor': 'error',
|
|
'no-await-in-loop': 'warn',
|
|
|
|
// Naming Conventions - Strict Standards
|
|
'@typescript-eslint/naming-convention': [
|
|
'error',
|
|
{
|
|
selector: 'variable',
|
|
format: ['camelCase', 'PascalCase', 'UPPER_CASE'],
|
|
leadingUnderscore: 'allow',
|
|
},
|
|
{
|
|
selector: 'function',
|
|
format: ['camelCase', 'PascalCase'],
|
|
},
|
|
{
|
|
selector: 'typeLike',
|
|
format: ['PascalCase'],
|
|
},
|
|
{
|
|
selector: 'interface',
|
|
format: ['PascalCase'],
|
|
},
|
|
{
|
|
selector: 'interface',
|
|
filter: {
|
|
regex: '^.*Props$',
|
|
match: true,
|
|
},
|
|
format: ['PascalCase'],
|
|
suffix: ['Props'],
|
|
},
|
|
{
|
|
selector: 'typeAlias',
|
|
format: ['PascalCase'],
|
|
},
|
|
{
|
|
selector: 'enum',
|
|
format: ['PascalCase'],
|
|
},
|
|
{
|
|
selector: 'enumMember',
|
|
format: ['UPPER_CASE'],
|
|
},
|
|
],
|
|
|
|
// Design System Rules - Prevent hardcoded colors
|
|
'no-restricted-syntax': [
|
|
'error',
|
|
{
|
|
selector: "Literal[value=/^#[0-9a-fA-F]{3,8}$/]",
|
|
message: "Hardcoded hex colors are not allowed. Use design tokens from the theme system instead."
|
|
},
|
|
{
|
|
selector: "Literal[value=/^rgb\\(/]",
|
|
message: "Hardcoded RGB colors are not allowed. Use design tokens from the theme system instead."
|
|
},
|
|
{
|
|
selector: "Literal[value=/^rgba\\(/]",
|
|
message: "Hardcoded RGBA colors are not allowed. Use design tokens from the theme system instead."
|
|
},
|
|
{
|
|
selector: "Literal[value=/^hsl\\(/]",
|
|
message: "Hardcoded HSL colors are not allowed. Use design tokens from the theme system instead."
|
|
},
|
|
{
|
|
selector: "Literal[value=/^hsla\\(/]",
|
|
message: "Hardcoded HSLA colors are not allowed. Use design tokens from the theme system instead."
|
|
},
|
|
{
|
|
selector: "Literal[value*='bg-white']",
|
|
message: "Use semantic color tokens like bg-background-primary instead of hardcoded bg-white."
|
|
},
|
|
{
|
|
selector: "Literal[value*='bg-black']",
|
|
message: "Use semantic color tokens like bg-background-primary instead of hardcoded bg-black."
|
|
},
|
|
{
|
|
selector: "Literal[value*='text-white']",
|
|
message: "Use semantic color tokens like text-primary instead of hardcoded text-white."
|
|
},
|
|
{
|
|
selector: "Literal[value*='text-black']",
|
|
message: "Use semantic color tokens like text-primary instead of hardcoded text-black."
|
|
}
|
|
],
|
|
},
|
|
},
|
|
// Configuration for JavaScript files
|
|
{
|
|
extends: [js.configs.recommended, prettier],
|
|
files: ['**/*.{js,jsx}'],
|
|
languageOptions: {
|
|
ecmaVersion: 2023,
|
|
sourceType: 'module',
|
|
parserOptions: {
|
|
ecmaFeatures: {
|
|
jsx: true,
|
|
},
|
|
},
|
|
globals: {
|
|
window: 'readonly',
|
|
document: 'readonly',
|
|
console: 'readonly',
|
|
process: 'readonly',
|
|
Buffer: 'readonly',
|
|
__dirname: 'readonly',
|
|
__filename: 'readonly',
|
|
global: 'readonly',
|
|
},
|
|
},
|
|
plugins: {
|
|
react: react,
|
|
'react-hooks': reactHooks,
|
|
'react-refresh': reactRefresh,
|
|
'jsx-a11y': jsxA11y,
|
|
import: importPlugin,
|
|
},
|
|
settings: {
|
|
react: {
|
|
version: 'detect',
|
|
},
|
|
'import/resolver': {
|
|
node: {
|
|
extensions: ['.js', '.jsx', '.ts', '.tsx'],
|
|
},
|
|
},
|
|
},
|
|
rules: {
|
|
// React Rules - Strict Configuration
|
|
...react.configs.recommended.rules,
|
|
...react.configs['jsx-runtime'].rules,
|
|
...reactHooks.configs.recommended.rules,
|
|
...jsxA11y.configs.strict.rules,
|
|
|
|
// React Refresh
|
|
'react-refresh/only-export-components': [
|
|
'warn',
|
|
{ allowConstantExport: true },
|
|
],
|
|
|
|
// React Specific
|
|
'react/prop-types': 'off',
|
|
'react/jsx-uses-react': 'off',
|
|
'react/react-in-jsx-scope': 'off',
|
|
'react/jsx-key': [
|
|
'error',
|
|
{
|
|
checkFragmentShorthand: true,
|
|
checkKeyMustBeforeSpread: true,
|
|
warnOnDuplicates: true,
|
|
},
|
|
],
|
|
'react/jsx-no-useless-fragment': ['warn', { allowExpressions: true }],
|
|
'react/self-closing-comp': ['warn', { component: true, html: true }],
|
|
'react/jsx-boolean-value': ['warn', 'never'],
|
|
'react/jsx-curly-brace-presence': [
|
|
'warn',
|
|
{
|
|
props: 'never',
|
|
children: 'never',
|
|
},
|
|
],
|
|
'react/jsx-pascal-case': ['error', { allowAllCaps: true }],
|
|
'react/no-array-index-key': 'warn', // Warn about index keys - use stable IDs when possible
|
|
'react/no-danger': 'error',
|
|
'react/no-deprecated': 'error',
|
|
'react/no-unsafe': 'error',
|
|
|
|
// General Code Quality - Strict Rules
|
|
'no-console': process.env.NODE_ENV === 'production'
|
|
? ['error', { allow: ['warn', 'error'] }]
|
|
: ['warn', { allow: ['warn', 'error', 'info'] }],
|
|
'prefer-const': 'error',
|
|
'no-debugger': 'error',
|
|
'no-alert': 'error',
|
|
'no-var': 'error',
|
|
'prefer-template': 'error',
|
|
'prefer-arrow-callback': 'error',
|
|
'arrow-body-style': ['warn', 'as-needed'],
|
|
'object-shorthand': ['error', 'always'],
|
|
'no-useless-rename': 'error',
|
|
'no-useless-computed-key': 'error',
|
|
'no-useless-constructor': 'error',
|
|
'no-useless-return': 'error',
|
|
'no-nested-ternary': 'off', // Allow nested ternaries for conditional rendering
|
|
'no-unneeded-ternary': 'error',
|
|
'prefer-destructuring': [
|
|
'warn',
|
|
{
|
|
array: false,
|
|
object: true,
|
|
},
|
|
],
|
|
'spaced-comment': ['error', 'always', { markers: ['/'] }],
|
|
eqeqeq: ['error', 'always', { null: 'ignore' }],
|
|
curly: ['error', 'all'],
|
|
'no-else-return': ['error', { allowElseIf: false }],
|
|
'no-return-assign': 'error',
|
|
'require-await': 'error',
|
|
'no-async-promise-executor': 'error',
|
|
'no-await-in-loop': 'warn',
|
|
},
|
|
}
|
|
);
|