11import React , { useState , useEffect } from 'react' ;
22import { Link } from 'react-router-dom' ;
3- import { ArrowLeft , Funnel , XCircle , Info } from '@phosphor-icons/react' ;
3+ import {
4+ ArrowLeftIcon ,
5+ FunnelIcon ,
6+ XCircleIcon ,
7+ InfoIcon ,
8+ SquaresFourIcon ,
9+ ListIcon ,
10+ } from '@phosphor-icons/react' ;
411import { motion , AnimatePresence } from 'framer-motion' ;
512import LogCard from '../components/LogCard' ;
613import useSeo from '../hooks/useSeo' ;
14+ import usePersistentState from '../hooks/usePersistentState' ;
715import colors from '../config/colors' ;
816import { useAchievements } from '../context/AchievementContext' ;
917import piml from 'piml' ;
@@ -39,6 +47,7 @@ const LogsPage = () => {
3947 const [ searchQuery , setSearchQuery ] = useState ( '' ) ;
4048 const [ filteredLogs , setFilteredLogs ] = useState ( [ ] ) ;
4149 const [ isInfoModalOpen , setIsInfoModalOpen ] = useState ( false ) ;
50+ const [ viewMode , setViewMode ] = usePersistentState ( 'fez_logs_view_mode' , 'grid' ) ;
4251 const { unlockAchievement } = useAchievements ( ) ;
4352 const { openSidePanel } = useSidePanel ( ) ;
4453
@@ -110,7 +119,7 @@ const LogsPage = () => {
110119 to = "/"
111120 className = "mb-8 inline-flex items-center gap-2 text-xs font-mono text-gray-500 hover:text-white transition-colors uppercase tracking-widest"
112121 >
113- < ArrowLeft weight = "bold" />
122+ < ArrowLeftIcon weight = "bold" />
114123 < span > Home</ span >
115124 </ Link >
116125
@@ -124,13 +133,32 @@ const LogsPage = () => {
124133 </ p >
125134 </ div >
126135
127- < button
128- onClick = { ( ) => setIsInfoModalOpen ( true ) }
129- className = "text-gray-500 hover:text-emerald-400 transition-colors font-mono text-xs uppercase tracking-widest flex items-center gap-2"
130- >
131- < Info size = { 16 } />
132- < span > Rating System</ span >
133- </ button >
136+ < div className = "flex items-center gap-6" >
137+ < div className = "flex bg-white/5 p-1 rounded-sm border border-white/10" >
138+ < button
139+ onClick = { ( ) => setViewMode ( 'grid' ) }
140+ className = { `p-2 transition-all ${ viewMode === 'grid' ? 'bg-white text-black' : 'text-gray-500 hover:text-white' } ` }
141+ title = "Grid View"
142+ >
143+ < SquaresFourIcon size = { 18 } weight = { viewMode === 'grid' ? 'fill' : 'regular' } />
144+ </ button >
145+ < button
146+ onClick = { ( ) => setViewMode ( 'list' ) }
147+ className = { `p-2 transition-all ${ viewMode === 'list' ? 'bg-white text-black' : 'text-gray-500 hover:text-white' } ` }
148+ title = "List View"
149+ >
150+ < ListIcon size = { 18 } weight = { viewMode === 'list' ? 'fill' : 'regular' } />
151+ </ button >
152+ </ div >
153+
154+ < button
155+ onClick = { ( ) => setIsInfoModalOpen ( true ) }
156+ className = "text-gray-500 hover:text-emerald-400 transition-colors font-mono text-xs uppercase tracking-widest flex items-center gap-2"
157+ >
158+ < InfoIcon size = { 16 } />
159+ < span > Rating System</ span >
160+ </ button >
161+ </ div >
134162 </ div >
135163 </ header >
136164
@@ -150,7 +178,7 @@ const LogsPage = () => {
150178 { /* Filters */ }
151179 < div className = "flex flex-wrap items-center gap-3" >
152180 < div className = "flex items-center gap-2 mr-2 text-gray-600 font-mono text-xs uppercase tracking-widest" >
153- < Funnel size = { 14 } weight = "fill" />
181+ < FunnelIcon size = { 14 } weight = "fill" />
154182 < span > Filter By</ span >
155183 </ div >
156184
@@ -190,39 +218,46 @@ const LogsPage = () => {
190218 } }
191219 className = "ml-auto text-red-500 hover:text-red-400 transition-colors"
192220 >
193- < XCircle size = { 20 } weight = "fill" />
221+ < XCircleIcon size = { 20 } weight = "fill" />
194222 </ button >
195223 ) }
196224 </ div >
197225 </ div >
198226
199227 { /* Content List */ }
200228 { loading ? (
201- < div className = "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6 animate-pulse" >
229+ < div className = { viewMode === 'grid'
230+ ? "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6 animate-pulse"
231+ : "flex flex-col gap-4 animate-pulse"
232+ } >
202233 { [ ...Array ( 8 ) ] . map ( ( _ , i ) => (
203- < div key = { i } className = "h-64 w-full bg-white/5 rounded-sm" />
234+ < div key = { i } className = { viewMode === 'grid' ? "h-64 w-full bg-white/5 rounded-sm" : "h-20 w-full bg-white/5 rounded-sm" } />
204235 ) ) }
205236 </ div >
206237 ) : (
207238 < div className = "pb-32" >
208239 < AnimatePresence mode = "popLayout" >
209240 < motion . div
210241 layout
211- className = "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6"
242+ className = { viewMode === 'grid'
243+ ? "grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-3 xl:grid-cols-4 gap-6"
244+ : "flex flex-col"
245+ }
212246 >
213247 { filteredLogs . map ( ( log ) => (
214248 < motion . div
215249 layout
216250 key = { log . id }
217- initial = { { opacity : 0 , scale : 0.9 } }
251+ initial = { { opacity : 0 , scale : 0.95 } }
218252 animate = { { opacity : 1 , scale : 1 } }
219- exit = { { opacity : 0 , scale : 0.9 } }
253+ exit = { { opacity : 0 , scale : 0.95 } }
220254 transition = { { duration : 0.2 } }
221255 >
222256 < LogCard
223257 log = { log }
224258 index = { log . originalIndex }
225259 totalLogs = { logs . length }
260+ viewMode = { viewMode }
226261 />
227262 </ motion . div >
228263 ) ) }
0 commit comments