Skip to content

Commit 55efaa4

Browse files
committed
refactor: senior architectural enhancements (zod env, query client, dynamic css)
- Cleanup obsolete HSL/OKLCH theme redundancy in globals.css - Implement strict env validation via zod in env.ts to prevent runtime errors - Isolate QueryClient within useState to prevent Fast Refresh leaks - Add real-time OS preference event listener to theme-provider.tsx - Replace hardcoded React App title with dynamic VITE_APP_TITLE - Remove invalid ignoreDeprecations 6.0 value from tsconfig.app.json
1 parent b30f4a3 commit 55efaa4

10 files changed

Lines changed: 46 additions & 72 deletions

File tree

.env.example

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,2 @@
1-
VITE_API_URL=http://localhost:3000/api
1+
VITE_APP_TITLE="Template React Sênior"
2+
VITE_API_URL="http://localhost:3000/api"

biome.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,8 @@
77
},
88
"files": {
99
"ignoreUnknown": false,
10-
"includes": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.js", "src/**/*.jsx"]
10+
"includes": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.js", "src/**/*.jsx"],
11+
"ignore": ["src/routeTree.gen.ts"]
1112
},
1213
"formatter": {
1314
"enabled": true,

index.html

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
<meta charset="UTF-8" />
55
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
66
<link rel="icon" type="image/svg+xml" href="/favicon.svg" />
7-
<title>React App</title>
7+
<title>%VITE_APP_TITLE%</title>
88
</head>
99
<body>
1010
<div id="root"></div>
Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
11
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
2-
import type { ReactNode } from 'react';
3-
4-
const queryClient = new QueryClient({
5-
defaultOptions: {
6-
queries: {
7-
refetchOnWindowFocus: false,
8-
staleTime: 5 * 60 * 1000, // 5 minutes cache
9-
},
10-
},
11-
});
2+
import { type ReactNode, useState } from 'react';
123

134
export function AppQueryProvider({ children }: { children: ReactNode }) {
5+
const [queryClient] = useState(
6+
() =>
7+
new QueryClient({
8+
defaultOptions: {
9+
queries: {
10+
refetchOnWindowFocus: false,
11+
staleTime: 5 * 60 * 1000, // 5 minutes cache
12+
},
13+
},
14+
})
15+
);
16+
1417
return <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>;
1518
}

src/components/providers/theme-provider.tsx

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,18 +33,26 @@ export function ThemeProvider({
3333
useEffect(() => {
3434
const root = window.document.documentElement;
3535

36-
root.classList.remove('light', 'dark');
36+
const applyTheme = (currentTheme: Theme) => {
37+
root.classList.remove('light', 'dark');
38+
if (currentTheme === 'system') {
39+
const systemTheme = window.matchMedia('(prefers-color-scheme: dark)').matches
40+
? 'dark'
41+
: 'light';
42+
root.classList.add(systemTheme);
43+
return;
44+
}
45+
root.classList.add(currentTheme);
46+
};
47+
48+
applyTheme(theme);
3749

3850
if (theme === 'system') {
39-
const systemTheme = window.matchMedia('(prefers-color-scheme: dark)').matches
40-
? 'dark'
41-
: 'light';
42-
43-
root.classList.add(systemTheme);
44-
return;
51+
const mediaQuery = window.matchMedia('(prefers-color-scheme: dark)');
52+
const handleChange = () => applyTheme('system');
53+
mediaQuery.addEventListener('change', handleChange);
54+
return () => mediaQuery.removeEventListener('change', handleChange);
4555
}
46-
47-
root.classList.add(theme);
4856
}, [theme]);
4957

5058
const value = {

src/env.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { z } from 'zod';
2+
3+
const envSchema = z.object({
4+
VITE_API_URL: z.string().url('A variável VITE_API_URL deve ser uma URL válida.'),
5+
VITE_APP_TITLE: z.string().default('Template React Sênior'),
6+
});
7+
8+
export const env = envSchema.parse(import.meta.env);

src/globals.css

Lines changed: 0 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -88,52 +88,6 @@
8888
}
8989
}
9090

91-
@layer base {
92-
:root {
93-
--background: 0 0% 100%;
94-
--foreground: 222.2 84% 4.9%;
95-
--card: 0 0% 100%;
96-
--card-foreground: 222.2 84% 4.9%;
97-
--popover: 0 0% 100%;
98-
--popover-foreground: 222.2 84% 4.9%;
99-
--primary: 222.2 47.4% 11.2%;
100-
--primary-foreground: 210 40% 98%;
101-
--secondary: 210 40% 96.1%;
102-
--secondary-foreground: 222.2 47.4% 11.2%;
103-
--muted: 210 40% 96.1%;
104-
--muted-foreground: 215.4 16.3% 46.9%;
105-
--accent: 210 40% 96.1%;
106-
--accent-foreground: 222.2 47.4% 11.2%;
107-
--destructive: 0 84.2% 60.2%;
108-
--destructive-foreground: 210 40% 98%;
109-
--border: 214.3 31.8% 91.4%;
110-
--input: 214.3 31.8% 91.4%;
111-
--ring: 222.2 84% 4.9%;
112-
--radius: 0.5rem;
113-
}
114-
115-
.dark {
116-
--background: 222.2 84% 4.9%;
117-
--foreground: 210 40% 98%;
118-
--card: 222.2 84% 4.9%;
119-
--card-foreground: 210 40% 98%;
120-
--popover: 222.2 84% 4.9%;
121-
--popover-foreground: 210 40% 98%;
122-
--primary: 210 40% 98%;
123-
--primary-foreground: 222.2 47.4% 11.2%;
124-
--secondary: 217.2 32.6% 17.5%;
125-
--secondary-foreground: 210 40% 98%;
126-
--muted: 217.2 32.6% 17.5%;
127-
--muted-foreground: 215 20.2% 65.1%;
128-
--accent: 217.2 32.6% 17.5%;
129-
--accent-foreground: 210 40% 98%;
130-
--destructive: 0 62.8% 30.6%;
131-
--destructive-foreground: 210 40% 98%;
132-
--border: 217.2 32.6% 17.5%;
133-
--input: 217.2 32.6% 17.5%;
134-
--ring: 212.7 26.8% 83.9%;
135-
}
136-
}
13791

13892
@layer base {
13993
body {

src/lib/api.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import axios from 'axios';
2+
import { env } from '@/env';
23

34
export const api = axios.create({
4-
// Utiliza a variável de ambiente, garantindo que o TypeScript conheça através do vite-env.d.ts
5-
baseURL: import.meta.env.VITE_API_URL,
5+
baseURL: env.VITE_API_URL,
66
timeout: 10000,
77
headers: {
88
'Content-Type': 'application/json',

src/vite-env.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
interface ImportMetaEnv {
44
readonly VITE_API_URL: string;
5-
// adicione outras variáveis de ambiente aqui
5+
readonly VITE_APP_TITLE: string;
66
}
77

88
interface ImportMeta {

tsconfig.app.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828

2929
/* Base and Path Aliases */
3030
"baseUrl": ".",
31-
"ignoreDeprecations": "6.0",
3231
"paths": {
3332
"@/*": ["./src/*"]
3433
}

0 commit comments

Comments
 (0)