Skip to content

Commit

Permalink
Refactor: Eslint + Small bugs (#16)
Browse files Browse the repository at this point in the history
* Fix all errors and warnings by eslint

* Fix import order

* Remove obsolete unused code

* Fix layout shift on mobile devices

* Added accept language for each request header

* Remove useless logs
  • Loading branch information
moiskillnadne authored Oct 28, 2024
1 parent 040888f commit 878e3e0
Show file tree
Hide file tree
Showing 96 changed files with 1,338 additions and 1,403 deletions.
2 changes: 1 addition & 1 deletion .prettierrc
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"singleQuote": true,
"jsxSingleQuote": false,
"trailingComma": "all",
"semi": true,
"semi": false,
"printWidth": 100,
"tabWidth": 2,
"useTabs": false,
Expand Down
29 changes: 29 additions & 0 deletions eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import tsParser from '@typescript-eslint/parser';
import prettier from 'eslint-plugin-prettier';
import prettierConfig from 'eslint-config-prettier';
import airbnb from 'eslint-config-airbnb';
import importPlugin from 'eslint-plugin-import';

export default [
{
Expand All @@ -31,13 +32,41 @@ export default [
'react-hooks': reactHooks,
'@typescript-eslint': ts,
prettier,
import: importPlugin,
},
rules: {
...ts.configs.recommended.rules,
...react.configs.recommended.rules,
...airbnb.rules,
'prettier/prettier': 'warn', // Prettier as ESLint
'react/react-in-jsx-scope': 'off',
'react-hooks/exhaustive-deps': 'warn',
'import/order': [
'error',
{
groups: [['external', 'builtin'], 'internal', ['sibling', 'parent'], 'index'],

pathGroups: [
{
pattern: '@(react)',
group: 'external',
position: 'before',
},
{
pattern: '@(~app|~shared|~features|~pages|~entities)/**',
group: 'internal',
},
],

pathGroupsExcludedImportTypes: ['internal', 'react'],
'newlines-between': 'always',

alphabetize: {
order: 'asc',
caseInsensitive: true,
},
},
],
},
settings: {
react: {
Expand Down
41 changes: 21 additions & 20 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,40 +12,41 @@
},
"dependencies": {
"@simplewebauthn/browser": "^11.0.0",
"@tanstack/react-query": "^5.56.2",
"@tanstack/react-query": "^5.59.16",
"autoprefixer": "^10.4.20",
"axios": "^1.7.7",
"date-fns": "^3.6.0",
"i18next": "^23.14.0",
"i18next": "^23.16.4",
"i18next-browser-languagedetector": "^8.0.0",
"postcss": "^8.4.42",
"postcss": "^8.4.47",
"react": "^18.3.1",
"react-dom": "^18.3.1",
"react-i18next": "^15.0.1",
"react-router-dom": "^6.26.1",
"tailwindcss": "^3.4.10",
"react-i18next": "^15.1.0",
"react-router-dom": "^6.27.0",
"tailwindcss": "^3.4.14",
"zod": "^3.23.8"
},
"devDependencies": {
"@simplewebauthn/types": "^11.0.0",
"@tanstack/eslint-plugin-query": "^5.58.1",
"@types/react": "^18.3.3",
"@types/react-dom": "^18.3.0",
"@typescript-eslint/eslint-plugin": "^8.7.0",
"@typescript-eslint/parser": "^8.7.0",
"@vitejs/plugin-react": "^4.3.1",
"eslint": "^9.11.1",
"@tanstack/eslint-plugin-query": "^5.59.7",
"@types/node": "^22.8.1",
"@types/react": "^18.3.12",
"@types/react-dom": "^18.3.1",
"@typescript-eslint/eslint-plugin": "^8.11.0",
"@typescript-eslint/parser": "^8.11.0",
"@vitejs/plugin-react": "^4.3.3",
"eslint": "^9.13.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-prettier": "^9.1.0",
"eslint-plugin-import": "^2.30.0",
"eslint-plugin-import": "^2.31.0",
"eslint-plugin-prettier": "^5.2.1",
"eslint-plugin-react": "^7.37.0",
"eslint-plugin-react-hooks": "^4.6.2",
"eslint-plugin-react-refresh": "^0.4.12",
"globals": "^15.9.0",
"eslint-plugin-react": "^7.37.2",
"eslint-plugin-react-hooks": "^5.0.0",
"eslint-plugin-react-refresh": "^0.4.14",
"globals": "^15.11.0",
"prettier": "^3.3.3",
"typescript": "^5.5.3",
"vite": "^5.4.1",
"typescript": "^5.6.3",
"vite": "^5.4.10",
"vite-plugin-mkcert": "^1.17.6",
"vite-plugin-pwa": "^0.20.5"
},
Expand Down
2 changes: 1 addition & 1 deletion postcss.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@ export default {
tailwindcss: {},
autoprefixer: {},
},
};
}
34 changes: 17 additions & 17 deletions public/service-worker.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
// service-worker.ts

async function getAssetsFromManifest() {
const manifest = await fetch('/manifest.json').then((response) => response.json());
const assets = Object.values(manifest).map((entry) => entry.file);
return assets;
const manifest = await fetch('/manifest.json').then((response) => response.json())
const assets = Object.values(manifest).map((entry) => entry.file)
return assets
}

self.addEventListener('install', (event) => {
event.waitUntil(
(async () => {
const cache = await caches.open('app-cache');
const assets = await getAssetsFromManifest();
cache.addAll(['/', '/index.html', ...assets]);
const cache = await caches.open('app-cache')
const assets = await getAssetsFromManifest()
cache.addAll(['/', '/index.html', ...assets])
})(),
);
});
)
})

self.addEventListener('fetch', (event) => {
const url = new URL(event.request.url);
const url = new URL(event.request.url)

// Static resources are cached
const isStaticResource =
Expand All @@ -27,9 +27,9 @@ self.addEventListener('fetch', (event) => {
url.pathname.endsWith('.png') ||
url.pathname.endsWith('.jpg') ||
url.pathname.endsWith('.svg') ||
url.pathname.endsWith('.ico');
url.pathname.endsWith('.ico')

const isApiRequest = url.pathname.startsWith('/api/');
const isApiRequest = url.pathname.startsWith('/api/')

if (isStaticResource && !isApiRequest) {
event.respondWith(
Expand All @@ -38,12 +38,12 @@ self.addEventListener('fetch', (event) => {
cachedResponse ||
fetch(event.request).then((networkResponse) => {
return caches.open('static-cache').then((cache) => {
cache.put(event.request, networkResponse.clone());
return networkResponse;
});
cache.put(event.request, networkResponse.clone())
return networkResponse
})
})
);
)
}),
);
)
}
});
})
20 changes: 11 additions & 9 deletions src/app/App.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import ApplicationRouter from '../pages';
import i18nManager from './system/i18n.manager';
import { useVisitorId } from '../shared/hooks';
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'

void i18nManager.initialize();
import i18nManager from './system/i18n.manager'

export const queryClient = new QueryClient();
import ApplicationRouter from '~/pages'
import { useVisitorId } from '~/shared/hooks'

void i18nManager.initialize()

export const queryClient = new QueryClient()

function App() {
useVisitorId();
useVisitorId()

return (
<QueryClientProvider client={queryClient}>
<ApplicationRouter />
</QueryClientProvider>
);
)
}

export default App;
export default App
20 changes: 11 additions & 9 deletions src/app/main.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import { StrictMode, Suspense } from 'react';
import { createRoot } from 'react-dom/client';
import App from './App';
import './index.css';
import { StrictMode, Suspense } from 'react'

import { createRoot } from 'react-dom/client'

import App from './App'
import './index.css'

if ('serviceWorker' in navigator) {
window.addEventListener('load', () => {
navigator.serviceWorker
.register('/service-worker.js')
.then((registration) => {
console.log('Service Worker registered with scope:', registration.scope);
console.info('Service Worker registered with scope:', registration.scope)
})
.catch((error) => {
console.error('Service Worker registration failed:', error);
});
});
console.error('Service Worker registration failed:', error)
})
})
}

createRoot(document.getElementById('root')!).render(
Expand All @@ -22,4 +24,4 @@ createRoot(document.getElementById('root')!).render(
<App />
</Suspense>
</StrictMode>,
);
)
2 changes: 1 addition & 1 deletion src/app/system/constant.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
export type SupportableLanguageKeys = keyof typeof SupportableLanguage;
export type SupportableLanguageKeys = keyof typeof SupportableLanguage

export enum SupportableLanguage {
EN = 'en',
Expand Down
18 changes: 9 additions & 9 deletions src/app/system/i18n.manager.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import i18n from 'i18next';
import LanguageDetector from 'i18next-browser-languagedetector';
import { initReactI18next } from 'react-i18next';
import i18n from 'i18next'
import LanguageDetector from 'i18next-browser-languagedetector'
import { initReactI18next } from 'react-i18next'

import enResources from '../../i18n/en/translation.json';
import ruResources from '../../i18n/ru/translation.json';
import enResources from '../../i18n/en/translation.json'
import ruResources from '../../i18n/ru/translation.json'

const i18nManager = {
async initialize() {
Expand All @@ -22,12 +22,12 @@ const i18nManager = {
},
joinArrays: '\n',
debug: import.meta.env.NODE_ENV !== 'production',
});
})
},

addResources(language: string, namespace: string, resources: Record<string, string>) {
i18n.addResources(language, namespace, resources);
i18n.addResources(language, namespace, resources)
},
};
}

export default i18nManager;
export default i18nManager
2 changes: 1 addition & 1 deletion src/entity/user/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export * from './lib/useAuthenticated';
export * from './lib/useAuthenticated'
31 changes: 16 additions & 15 deletions src/entity/user/lib/useAuthenticated.ts
Original file line number Diff line number Diff line change
@@ -1,38 +1,39 @@
import { useQuery } from '@tanstack/react-query';
import { accountService, UserDTO } from '../../../shared/api/account.service';
import { AxiosError } from 'axios';
import { useQuery } from '@tanstack/react-query'
import { AxiosError } from 'axios'

import { accountService, UserDTO } from '~/shared/api/account.service'

type Return = {
isLoading: boolean;
isAuthenticated: boolean;
isLoading: boolean
isAuthenticated: boolean

user: UserDTO | null;
};
user: UserDTO | null
}

export const useAuthenticated = (): Return => {
const query = useQuery({
queryKey: ['/protected/me'],
queryFn: accountService.getAccountInfo,
select(data) {
return data.data.details;
return data.data.details
},
retry(failureCount, error) {
console.log(error);
console.log(error)

const axiosError = error as AxiosError;
const axiosError = error as AxiosError

if (axiosError.response?.status === 401) {
return false;
return false
}

return failureCount < 4;
return failureCount < 4
},
});
})

return {
isLoading: query.isLoading,
isAuthenticated: !!query.data?.user.email,

user: query.data?.user ?? null,
};
};
}
}
25 changes: 0 additions & 25 deletions src/feature/AuthorizePasskeys/AuthorizePasskeys.tsx

This file was deleted.

1 change: 1 addition & 0 deletions src/feature/AuthorizePasskeys/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './lib/useAuthenticateViaPasskeys'
Loading

0 comments on commit 878e3e0

Please sign in to comment.