@@ -11,9 +11,13 @@ import {
1111 MenuItem ,
1212} from "@mui/material" ;
1313import { useHomepage } from "Contexts/HomepageContext" ;
14- import { useState } from "react" ;
14+ import { useState , useEffect } from "react" ;
1515import { useAcademyTheme } from "Contexts/AcademyThemeContext" ;
1616
17+ // SessionStorage keys
18+ const FILTER_STORAGE_KEY = "ra_home_filters_v1" ;
19+ const SEARCH_STORAGE_KEY = "ra_home_search_v1" ;
20+
1721// Estilos
1822const Search = styled ( "div" ) ( ( { roundness } : { roundness : number } ) => ( {
1923 position : "relative" ,
@@ -85,13 +89,67 @@ const StyledMenu = styled(Menu)(
8589 } )
8690) ;
8791
92+ // Filter persistance structure
93+ type FilterState = {
94+ tags : boolean ;
95+ description : boolean ;
96+ status : boolean ;
97+ } ;
98+
99+ const DEFAULT_FILTER_STATE : FilterState = {
100+ tags : true ,
101+ description : false ,
102+ status : false ,
103+ } ;
104+
88105// Componente FilterMenu
89106const FilterMenu = ( ) => {
90107 const { appendFilterItem } = useHomepage ( ) ;
91108 const theme = useAcademyTheme ( ) ;
92109 const [ anchorEl , setAnchorEl ] = useState < null | HTMLElement > ( null ) ;
93110 const open : boolean = Boolean ( anchorEl ) ;
94111
112+ const [ filterState , setFilterState ] = useState < FilterState > (
113+ DEFAULT_FILTER_STATE
114+ ) ;
115+
116+ // Restore session filter state
117+ useEffect ( ( ) => {
118+ if ( typeof window === "undefined" ) return ;
119+
120+ try {
121+ const raw = window . sessionStorage . getItem ( FILTER_STORAGE_KEY ) ;
122+ if ( ! raw ) return ;
123+
124+ const parsed = JSON . parse ( raw ) as Partial < FilterState > ;
125+ const persisted : FilterState = {
126+ tags :
127+ typeof parsed . tags === "boolean"
128+ ? parsed . tags
129+ : DEFAULT_FILTER_STATE . tags ,
130+ description :
131+ typeof parsed . description === "boolean"
132+ ? parsed . description
133+ : DEFAULT_FILTER_STATE . description ,
134+ status :
135+ typeof parsed . status === "boolean"
136+ ? parsed . status
137+ : DEFAULT_FILTER_STATE . status ,
138+ } ;
139+
140+ setFilterState ( persisted ) ;
141+
142+ // Sync context with persisted values
143+ ( [ "tags" , "description" , "status" ] as const ) . forEach ( ( key ) => {
144+ if ( persisted [ key ] !== DEFAULT_FILTER_STATE [ key ] ) {
145+ appendFilterItem ( key ) ;
146+ }
147+ } ) ;
148+ } catch ( err ) {
149+ console . error ( "Failed to restore filter state" , err ) ;
150+ }
151+ } , [ appendFilterItem ] ) ;
152+
95153 const handleClick = ( event : React . MouseEvent < HTMLButtonElement > ) => {
96154 setAnchorEl ( event . currentTarget ) ;
97155 } ;
@@ -100,9 +158,33 @@ const FilterMenu = () => {
100158 setAnchorEl ( null ) ;
101159 } ;
102160
103- const handleFilterList = ( e : any ) => {
104- const item = e . target . name ;
105- appendFilterItem ( item ) ;
161+ // Toggle and persist filter values
162+ const handleFilterCheckboxChange = (
163+ e : React . ChangeEvent < HTMLInputElement >
164+ ) => {
165+ const name = e . target . name as keyof FilterState ;
166+
167+ setFilterState ( ( prev ) => {
168+ const updated : FilterState = {
169+ ...prev ,
170+ [ name ] : ! prev [ name ] ,
171+ } ;
172+
173+ if ( typeof window !== "undefined" ) {
174+ try {
175+ window . sessionStorage . setItem (
176+ FILTER_STORAGE_KEY ,
177+ JSON . stringify ( updated )
178+ ) ;
179+ } catch ( err ) {
180+ console . error ( "Failed to save filter state" , err ) ;
181+ }
182+ }
183+
184+ return updated ;
185+ } ) ;
186+
187+ appendFilterItem ( name ) ;
106188 } ;
107189
108190 return (
@@ -127,29 +209,36 @@ const FilterMenu = () => {
127209 checkboxColor = { theme . palette . text ! }
128210 roundness = { theme . roundness ! }
129211 >
212+ { /* Name always active and not persisted */ }
130213 < MenuItem >
131214 < Checkbox defaultChecked disabled size = "small" name = "name" />
132215 Name
133216 </ MenuItem >
134217 < MenuItem >
135218 < Checkbox
136- defaultChecked
137219 size = "small"
138- onClick = { handleFilterList }
139220 name = "tags"
221+ checked = { filterState . tags }
222+ onChange = { handleFilterCheckboxChange }
140223 />
141224 Tags
142225 </ MenuItem >
143226 < MenuItem >
144227 < Checkbox
145228 size = "small"
146- onClick = { handleFilterList }
147229 name = "description"
230+ checked = { filterState . description }
231+ onChange = { handleFilterCheckboxChange }
148232 />
149233 Description
150234 </ MenuItem >
151235 < MenuItem >
152- < Checkbox size = "small" onClick = { handleFilterList } name = "status" />
236+ < Checkbox
237+ size = "small"
238+ name = "status"
239+ checked = { filterState . status }
240+ onChange = { handleFilterCheckboxChange }
241+ />
153242 Status
154243 </ MenuItem >
155244 </ StyledMenu >
@@ -162,9 +251,39 @@ const SearchBar = () => {
162251 const { setSearchBarText } = useHomepage ( ) ;
163252 const theme = useAcademyTheme ( ) ;
164253
254+ const [ searchValue , setSearchValue ] = useState < string > ( "" ) ;
255+
256+ // Restore session filter state
257+ useEffect ( ( ) => {
258+ if ( typeof window === "undefined" ) return ;
259+
260+ try {
261+ const saved = window . sessionStorage . getItem ( SEARCH_STORAGE_KEY ) ;
262+ if ( saved ) {
263+ setSearchValue ( saved ) ;
264+
265+ setSearchBarText ( saved . toLowerCase ( ) ) ;
266+ }
267+ } catch ( err ) {
268+ console . error ( "Failed to restore search text" , err ) ;
269+ }
270+ } , [ setSearchBarText ] ) ;
271+
272+ // Update sessionStorage + context
165273 const inputHandler = ( e : React . ChangeEvent < HTMLInputElement > ) => {
166- const lowerCase = e . target . value . toLowerCase ( ) ;
274+ const value = e . target . value ;
275+ setSearchValue ( value ) ;
276+
277+ const lowerCase = value . toLowerCase ( ) ;
167278 setSearchBarText ( lowerCase ) ;
279+
280+ if ( typeof window !== "undefined" ) {
281+ try {
282+ window . sessionStorage . setItem ( SEARCH_STORAGE_KEY , value ) ;
283+ } catch ( err ) {
284+ console . error ( "Failed to save search text" , err ) ;
285+ }
286+ }
168287 } ;
169288
170289 return (
@@ -181,6 +300,7 @@ const SearchBar = () => {
181300 </ SearchIconWrapper >
182301 < StyledInputBase
183302 placeholder = "Search…"
303+ value = { searchValue }
184304 onChange = { inputHandler }
185305 textColor = { theme . palette . text ! }
186306 inputProps = { { "aria-label" : "search" } }
@@ -192,3 +312,4 @@ const SearchBar = () => {
192312} ;
193313
194314export default SearchBar ;
315+
0 commit comments