@@ -9,8 +9,18 @@ import { Filters } from "@/components/filters";
99import { FiltersProvider } from "@/components/filters/context" ;
1010import { Variables } from "@/components/variables" ;
1111import { VariablesProvider } from "@/components/variables/context" ;
12+ import { Input } from "@/components/ui/input" ;
13+ import {
14+ Select ,
15+ SelectContent ,
16+ SelectItem ,
17+ SelectTrigger ,
18+ SelectValue ,
19+ } from "@/components/ui/select" ;
1220import type { Variables as VariablesType } from "@/lib/types" ;
21+ import { Status } from "@/lib/types" ;
1322import { useCallback } from "react" ;
23+ import { Search , RotateCcw , Check , X } from "lucide-react" ;
1424
1525type EnvClientProps = {
1626 readonly variables : VariablesType ;
@@ -160,7 +170,7 @@ const CodePreview = () => {
160170 </ h2 >
161171
162172 < div className = "sticky top-0 max-h-screen overflow-auto py-4" >
163- < div className = "bg-muted/20 overflow-hidden rounded-xl border" >
173+ < div className = "bg-muted/50 overflow-hidden rounded-xl border" >
164174 < CodeEditor
165175 lineClassName = "hover:bg-muted rounded-md"
166176 code = { envFileContent }
@@ -172,9 +182,11 @@ const CodePreview = () => {
172182 ) ;
173183} ;
174184
175- // Environment selector section component
176- const EnvironmentSelectorSection = ( ) => {
185+ // Combined environment selector and filters component
186+ const EnvironmentSelectorAndFilters = ( ) => {
177187 const { environment, updateVariables } = useEnvironment ( ) ;
188+ const { query, setQuery, status, setStatus } = useFilters ( ) ;
189+ const { variables, issues } = useVariables ( ) ;
178190
179191 const handleEnvironmentChange = (
180192 newEnvironment : any ,
@@ -183,12 +195,89 @@ const EnvironmentSelectorSection = () => {
183195 updateVariables ( newVariables ) ;
184196 } ;
185197
198+ const allCount = Object . keys ( variables ) . length ;
199+ const validCount = Object . keys ( variables ) . filter (
200+ ( key ) => ! issues . some ( ( issue ) => issue . path ?. includes ( key ) )
201+ ) . length ;
202+ const invalidCount = allCount - validCount ;
203+
204+ const handleStatusChange = ( value : string ) => {
205+ switch ( value ) {
206+ case "all" :
207+ setStatus ( Status . ALL ) ;
208+ break ;
209+ case "valid" :
210+ setStatus ( Status . VALID ) ;
211+ break ;
212+ case "invalid" :
213+ setStatus ( Status . INVALID ) ;
214+ break ;
215+ }
216+ } ;
217+
218+ const getStatusValue = ( ) => {
219+ switch ( status ) {
220+ case Status . ALL :
221+ return "all" ;
222+ case Status . VALID :
223+ return "valid" ;
224+ case Status . INVALID :
225+ return "invalid" ;
226+ default :
227+ return "all" ;
228+ }
229+ } ;
230+
186231 return (
187- < div className = "rounded-lg border bg-white p-4" >
188- < EnvironmentSelector
189- currentEnvironment = { environment }
190- onEnvironmentChange = { handleEnvironmentChange }
191- />
232+ < div className = "bg-background rounded-lg border p-4" >
233+ < div className = "space-y-4" >
234+ { /* Filters Row */ }
235+ < div className = "flex flex-row items-center gap-4" >
236+ < EnvironmentSelector
237+ currentEnvironment = { environment }
238+ onEnvironmentChange = { handleEnvironmentChange }
239+ />
240+
241+ { /* Status Filter Select */ }
242+ < Select value = { getStatusValue ( ) } onValueChange = { handleStatusChange } >
243+ < SelectTrigger className = "w-48" >
244+ < SelectValue placeholder = "Filter by status" />
245+ </ SelectTrigger >
246+ < SelectContent >
247+ < SelectItem value = "all" >
248+ < div className = "flex items-center gap-2" >
249+ < RotateCcw className = "h-3 w-3" />
250+ All ({ allCount } )
251+ </ div >
252+ </ SelectItem >
253+ < SelectItem value = "valid" >
254+ < div className = "flex items-center gap-2" >
255+ < Check className = "h-3 w-3 text-green-600" />
256+ Valid ({ validCount } )
257+ </ div >
258+ </ SelectItem >
259+ < SelectItem value = "invalid" >
260+ < div className = "flex items-center gap-2" >
261+ < X className = "h-3 w-3 text-red-600" />
262+ Invalid ({ invalidCount } )
263+ </ div >
264+ </ SelectItem >
265+ </ SelectContent >
266+ </ Select >
267+
268+ { /* Search Input */ }
269+ < div className = "relative flex-1" >
270+ < Search className = "absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-gray-400" />
271+ < Input
272+ type = "text"
273+ placeholder = "Search environment variables..."
274+ value = { query }
275+ onChange = { ( e ) => setQuery ( e . target . value ) }
276+ className = "pl-10"
277+ />
278+ </ div >
279+ </ div >
280+ </ div >
192281 </ div >
193282 ) ;
194283} ;
@@ -197,17 +286,16 @@ export const Client = ({ variables }: EnvClientProps) => {
197286 const { query, status } = useFilters ( ) ;
198287 const { variables : envVariables } = useEnvironment ( ) ;
199288 const currentVariables = getCurrentVariables ( envVariables , variables ) ;
200-
289+
201290 return (
202291 < VariablesProvider
203292 variables = { currentVariables }
204293 searchQuery = { query }
205294 statusFilter = { status }
206295 >
207296 < div className = "mx-auto max-w-7xl space-y-6" >
208- < EnvironmentSelectorSection />
209- < Filters />
210-
297+ < EnvironmentSelectorAndFilters />
298+
211299 < div className = "grid grid-cols-1 gap-4 lg:grid-cols-2" >
212300 < Variables />
213301 < CodePreview />
0 commit comments