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 }}
cache: npm
- run: npm ci
# TODO(fix-lint-baseline): drop the `|| true` wrapper once .convoys/fix-lint-baseline
# 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
- run: npm run lint --if-present
schema-map-fresh:
name: Schema map up to date

View file

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

View file

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

View file

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

View file

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