fix(lint): clear lib/config baseline and make CI lint blocking. (#63)

Lazy-init theme from localStorage, hoist checkAuth with useCallback,
named config exports for PostCSS/Tailwind, and remove the non-blocking
|| true wrapper from ci.yml (requires #61 + #62 merged first).

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
varutasu 2026-06-02 01:03:42 -05:00 committed by GitHub
parent c32bbd19b6
commit 81bed51369
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 64 additions and 59 deletions

View file

@ -36,19 +36,7 @@ jobs:
node-version: ${{ env.NODE_VERSION }} node-version: ${{ env.NODE_VERSION }}
cache: npm cache: npm
- run: npm ci - run: npm ci
# TODO(fix-lint-baseline): drop the `|| true` wrapper once .convoys/fix-lint-baseline - run: npm run lint --if-present
# lands. The codebase has ~100 pre-existing ESLint errors (conditional React
# hooks, unescaped entities, etc.). For now lint runs and posts output as a
# warning annotation so the PR check stays green while the debt is visible.
- name: Lint (non-blocking until fix-lint-baseline)
run: |
set +e
npm run lint --if-present
status=$?
if [ "$status" -ne 0 ]; then
echo "::warning title=Lint errors (non-blocking)::ESLint reported errors above. Tracked in .convoys/ship-readiness.md as P1 #11.5 (fix-lint-baseline). Remove the wrapper in .github/workflows/ci.yml after baseline is fixed."
fi
exit 0
schema-map-fresh: schema-map-fresh:
name: Schema map up to date name: Schema map up to date

View file

@ -2,15 +2,17 @@ import { createContext, useContext, useEffect, useState } from 'react';
const ThemeContext = createContext(); const ThemeContext = createContext();
function readThemeFromStorage() {
if (typeof window === 'undefined') return 'light';
return localStorage.getItem('theme') || 'light';
}
export function ThemeProvider({ children }) { export function ThemeProvider({ children }) {
const [theme, setTheme] = useState('light'); const [theme, setTheme] = useState(readThemeFromStorage);
useEffect(() => { useEffect(() => {
// Check for saved theme preference or default to light document.documentElement.setAttribute('data-theme', theme);
const savedTheme = localStorage.getItem('theme') || 'light'; }, [theme]);
setTheme(savedTheme);
document.documentElement.setAttribute('data-theme', savedTheme);
}, []);
const toggleTheme = () => { const toggleTheme = () => {
const newTheme = theme === 'light' ? 'dark' : 'light'; const newTheme = theme === 'light' ? 'dark' : 'light';

View file

@ -1,45 +1,56 @@
import { useState, useEffect } from 'react'; import { useState, useEffect, useCallback } from 'react';
export function useAuth() { async function verifyAuthFromStorage() {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
checkAuth();
}, []);
const checkAuth = async () => {
try {
// Get token from localStorage
const token = localStorage.getItem('auth_token'); const token = localStorage.getItem('auth_token');
const headers = { const headers = {
'Content-Type': 'application/json', 'Content-Type': 'application/json',
}; };
// Add authorization header if token exists
if (token) { if (token) {
headers.Authorization = `Bearer ${token}`; headers.Authorization = `Bearer ${token}`;
} }
try {
const response = await fetch('/api/auth/verify', { headers }); const response = await fetch('/api/auth/verify', { headers });
if (response.ok) { if (response.ok) {
const userData = await response.json(); return await response.json();
setUser(userData); }
} else {
setUser(null);
// Clear invalid token
if (token) { if (token) {
localStorage.removeItem('auth_token'); localStorage.removeItem('auth_token');
} }
} return null;
} catch (error) { } catch (error) {
console.error('Auth check failed:', error); console.error('Auth check failed:', error);
setUser(null); return null;
} finally {
setLoading(false);
} }
}
export function useAuth() {
const [user, setUser] = useState(null);
const [loading, setLoading] = useState(true);
useEffect(() => {
let active = true;
void (async () => {
const verifiedUser = await verifyAuthFromStorage();
if (!active) return;
setUser(verifiedUser);
setLoading(false);
})();
return () => {
active = false;
}; };
}, []);
const refreshAuth = useCallback(async () => {
const verifiedUser = await verifyAuthFromStorage();
setUser(verifiedUser);
setLoading(false);
}, []);
const logout = () => { const logout = () => {
localStorage.removeItem('auth_token'); localStorage.removeItem('auth_token');
@ -50,6 +61,6 @@ export function useAuth() {
user, user,
loading, loading,
logout, logout,
refreshAuth: checkAuth refreshAuth,
}; };
} }

View file

@ -1,6 +1,8 @@
export default { const config = {
plugins: { plugins: {
tailwindcss: {}, tailwindcss: {},
autoprefixer: {}, autoprefixer: {},
}, },
} };
export default config;

View file

@ -1,5 +1,5 @@
/** @type {import('tailwindcss').Config} */ /** @type {import('tailwindcss').Config} */
export default { const config = {
content: [ content: [
'./pages/**/*.{js,ts,jsx,tsx,mdx}', './pages/**/*.{js,ts,jsx,tsx,mdx}',
'./components/**/*.{js,ts,jsx,tsx,mdx}', './components/**/*.{js,ts,jsx,tsx,mdx}',
@ -29,4 +29,6 @@ export default {
}, },
}, },
plugins: [], plugins: [],
} };
export default config;