1- import React from 'react' ;
1+ import React , { useState } from 'react' ;
22import { Link } from 'react-router-dom' ;
3- import { ArrowLeftIcon , TerminalWindowIcon } from '@phosphor-icons/react ' ;
3+ import { motion , AnimatePresence } from 'framer-motion ' ;
44import useSeo from '../hooks/useSeo' ;
55import { useCommandPalette } from '../context/CommandPaletteContext' ;
6+ import { ArrowLeftIcon , TerminalWindowIcon , CommandIcon } from '@phosphor-icons/react' ;
7+ import GenerativeArt from '../components/GenerativeArt' ;
68
79const commandsData = [
810 {
@@ -342,6 +344,45 @@ const colorClasses = {
342344 } ,
343345} ;
344346
347+ const CommandListItem = ( { cmd, isActive, onHover } ) => {
348+ return (
349+ < motion . div
350+ initial = { { opacity : 0 , x : - 10 } }
351+ whileInView = { { opacity : 1 , x : 0 } }
352+ viewport = { { once : true } }
353+ onMouseEnter = { ( ) => onHover ( cmd ) }
354+ className = "relative pl-6 md:pl-8 py-3 group cursor-pointer"
355+ >
356+ { /* Active Indicator */ }
357+ < div
358+ className = { `absolute left-0 top-0 bottom-0 w-0.5 transition-all duration-300 ${
359+ isActive ? 'bg-emerald-400 h-full' : 'bg-transparent h-0 group-hover:h-full group-hover:bg-white/20'
360+ } `}
361+ />
362+
363+ < div className = "flex items-baseline justify-between pr-4" >
364+ < h3
365+ className = { `text-lg font-playfairDisplay transition-all duration-300 ${
366+ isActive ? 'text-white translate-x-2' : 'text-gray-500 group-hover:text-gray-300'
367+ } `}
368+ >
369+ { cmd . title }
370+ </ h3 >
371+
372+ { isActive && (
373+ < motion . div
374+ initial = { { opacity : 0 , x : - 10 } }
375+ animate = { { opacity : 1 , x : 0 } }
376+ className = "hidden md:block text-emerald-400"
377+ >
378+ < ArrowLeftIcon className = "rotate-180" />
379+ </ motion . div >
380+ ) }
381+ </ div >
382+ </ motion . div >
383+ ) ;
384+ } ;
385+
345386function CommandsPage ( ) {
346387 useSeo ( {
347388 title : 'All Commands | Fezcodex' ,
@@ -357,108 +398,146 @@ function CommandsPage() {
357398 } ) ;
358399
359400 const { togglePalette } = useCommandPalette ( ) ;
401+ const [ activeCommand , setActiveCommand ] = useState ( null ) ;
402+
403+ // Flattened list for random selection if needed, but not used currently
404+ // const allCommands = commandsData.flatMap(c => c.items);
360405
361406 return (
362- < div className = "py-16 sm:py-24" >
363- < div className = "mx-auto max-w-7xl px-6 lg:px-8" >
364- < Link
365- to = "/"
366- className = "group text-primary-400 hover:underline flex items-center justify-center gap-2 text-lg mb-4"
367- >
368- < ArrowLeftIcon className = "text-xl transition-transform group-hover:-translate-x-1" /> { ' ' }
369- Back to Home
370- </ Link >
371- < div className = "mx-auto max-w-2xl text-center" >
372- < h1 className = "text-4xl font-semibold tracking-tight text-white sm:text-6xl flex items-center justify-center" >
373- < TerminalWindowIcon
374- size = { 48 }
375- weight = "fill"
376- className = "mr-4 mt-1 text-gray-100 "
377- />
378- < span className = "text-orange-300" > Command</ span > Palette
407+ < div className = "flex min-h-screen bg-[#050505] text-white overflow-hidden relative selection:bg-emerald-500/30" >
408+
409+ { /* Mobile Background */ }
410+ < div className = "absolute inset-0 lg:hidden opacity-20 pointer-events-none z-0" >
411+ < GenerativeArt seed = "Commands" className = "w-full h-full filter blur-3xl" />
412+ </ div >
413+
414+ { /* LEFT PANEL: The Index */ }
415+ < div className = "w-full lg:w-1/2 lg:max-w-[50vw] relative z-10 flex flex-col min-h-screen py-24 px-6 md:px-20 overflow-y-auto overflow-x-hidden no-scrollbar" >
416+ < header className = "mb-20" >
417+ < Link
418+ to = "/"
419+ className = "mb-8 inline-flex items-center gap-2 text-xs font-mono text-gray-500 hover:text-white transition-colors uppercase tracking-widest"
420+ >
421+ < ArrowLeftIcon weight = "bold" />
422+ < span > Back to Home</ span >
423+ </ Link >
424+ < h1 className = "text-6xl md:text-8xl font-black tracking-tighter text-white mb-4 leading-none" >
425+ CMDS
379426 </ h1 >
380- < p className = "mt-6 text-lg leading-8 text-gray-300 " >
381- See all available commands in Command Palette.
427+ < p className = "text-gray-400 font-mono text-sm max-w-sm " >
428+ { '//' } AVAILABLE INSTRUCTIONS
382429 </ p >
383- </ div >
384- < div className = "flex justify-center items-center mt-16" >
385- < div
386- className = "group bg-[#1A2E1A50] rounded-[0.25rem] border border-neutral-700 shadow-2xl p-6 flex flex-col justify-between relative transform overflow-hidden h-full w-full max-w-4xl"
387- >
388- < div
389- className = "absolute top-0 left-0 w-full h-full opacity-10"
390- style = { {
391- backgroundImage :
392- 'radial-gradient(circle, white 1px, transparent 1px)' ,
393- backgroundSize : '10px 10px' ,
394- } }
395- > </ div >
396- < div className = "relative z-10 p-1 font-mono" >
397- < h1 className = "text-3xl font-playfairDisplay font-normal mb-4 text-lime-200" >
398- Command Palette
399- </ h1 >
400- < hr className = "border-gray-700 mb-4" />
430+ </ header >
401431
402- < div className = "mb-6 ml-4 mr-4" >
403- < p className = "text-gray-200 mb-4" >
404- Press < kbd className = "kbd kbd-sm text-black border rounded-lg px-1 bg-gray-200" > Alt/Ctrl</ kbd > + < kbd className = "kbd kbd-sm text-black border rounded-lg px-1 bg-gray-200" > K</ kbd > to open
405- Commands Palette. It lists all available
406- < code className = "text-red-400" > PAGE</ code > ,
407- < code className = "text-red-400" > POST</ code > ,
408- < code className = "text-red-400" > PROJECT</ code > ,
409- < code className = "text-red-400" > LOG</ code > ,
410- < code className = "text-red-400" > APP</ code > and
411- < code className = "text-red-400" > COMMAND</ code > that can be
412- used/consumed in Fezcodex.
413- < br />
414- < br />
415- You can type{ ' ' }
416- < code className = "text-emerald-300" > COMMAND </ code > to see all
417- available commands.
418- </ p >
419- < button
420- onClick = { togglePalette }
421- className = "border border-gray-200 bg-black/50 hover:bg-gray-50 text-white hover:text-black font-mono py-3 px-4 rounded w-full transition-colors duration-300 flex items-center justify-center gap-2"
422- >
423- < TerminalWindowIcon size = { 24 } />
424- Open Command Palette
425- </ button >
432+ < div className = "flex flex-col pb-32 gap-12" >
433+ { commandsData . map ( ( category , catIndex ) => (
434+ < div key = { catIndex } >
435+ < h2 className = "font-mono text-xs text-emerald-500 uppercase tracking-widest mb-6 border-b border-white/10 pb-2" >
436+ { category . category }
437+ </ h2 >
438+ < div className = "flex flex-col" >
439+ { category . items . map ( ( cmd , cmdIndex ) => (
440+ < CommandListItem
441+ key = { cmd . title }
442+ cmd = { cmd }
443+ isActive = { activeCommand ?. title === cmd . title }
444+ onHover = { setActiveCommand }
445+ />
446+ ) ) }
426447 </ div >
448+ </ div >
449+ ) ) }
450+ </ div >
451+ </ div >
427452
428- < h1 className = "text-3xl font-playfairDisplay font-normal mb-4 text-app" >
429- Available Commands
430- </ h1 >
431- < hr className = "border-gray-700 mb-6" />
453+ { /* RIGHT PANEL: The Stage (Desktop Only) */ }
454+ < div className = "hidden lg:flex fixed right-0 top-0 h-screen w-1/2 bg-neutral-900 overflow-hidden border-l border-white/10 z-20 flex-col" >
432455
433- { commandsData . map ( ( category , catIndex ) => (
434- < div key = { catIndex } className = "mb-8" >
435- < h2 className = "text-2xl font-playfairDisplay font-semibold text-gray-200 mb-4 border-b border-gray-700 pb-2 inline-block" >
436- { category . category }
437- </ h2 >
438- < div className = "grid grid-cols-1 gap-4" >
439- { category . items . map ( ( cmd , cmdIndex ) => {
440- const classes =
441- colorClasses [ cmd . color ] || colorClasses . gray ;
442- return (
443- < div
444- key = { cmdIndex }
445- className = { `${ classes . bg } bg-opacity-30 border ${ classes . border } ${ classes . text } px-4 py-3 rounded relative` }
446- role = "alert"
447- >
448- < strong className = "font-bold" > { cmd . title } :</ strong >
449- < span className = "block sm:inline ml-2" >
450- { cmd . description }
456+ { /* Main Content Area (Grows) */ }
457+ < div className = "flex-1 relative overflow-hidden" >
458+ < AnimatePresence mode = "wait" >
459+ { activeCommand ? (
460+ < motion . div
461+ key = { activeCommand . title }
462+ initial = { { opacity : 0 } }
463+ animate = { { opacity : 1 } }
464+ exit = { { opacity : 0 } }
465+ transition = { { duration : 0.4 } }
466+ className = "absolute inset-0 flex flex-col justify-end p-20 pb-8"
467+ >
468+ { /* Background */ }
469+ < div className = "absolute inset-0 z-0" >
470+ < GenerativeArt seed = { activeCommand . title } className = "w-full h-full opacity-60" />
471+ < div className = "absolute inset-0 bg-gradient-to-t from-[#050505] via-[#050505]/80 to-transparent" />
472+ < div className = "absolute inset-0 bg-noise opacity-10 mix-blend-overlay" />
473+ </ div >
474+
475+ < div className = "relative z-10" >
476+ < div className = "mb-6" >
477+ < span className = { `inline-block px-3 py-1 text-xs font-mono uppercase tracking-wider rounded-full border bg-opacity-20 backdrop-blur-md mb-4 ${
478+ colorClasses [ activeCommand . color ] ?. text || 'text-white'
479+ } ${ colorClasses [ activeCommand . color ] ?. border || 'border-white' } ${ colorClasses [ activeCommand . color ] ?. bg || 'bg-gray-800' } `} >
480+ { activeCommand . color }
451481 </ span >
452482 </ div >
453- ) ;
454- } ) }
455- </ div >
456- </ div >
457- ) ) }
483+
484+ < h2 className = "text-5xl font-playfairDisplay text-white mb-6 leading-tight" >
485+ { activeCommand . title }
486+ </ h2 >
487+
488+ < p className = "text-xl text-gray-300 font-light max-w-xl leading-relaxed" >
489+ { activeCommand . description }
490+ </ p >
491+ </ div >
492+ </ motion . div >
493+ ) : (
494+ < motion . div
495+ key = "default-state"
496+ initial = { { opacity : 0 } }
497+ animate = { { opacity : 1 } }
498+ exit = { { opacity : 0 } }
499+ className = "absolute inset-0 flex items-center justify-center p-12 text-center"
500+ >
501+ < div className = "absolute inset-0 z-0 opacity-20" >
502+ < div className = "w-full h-full bg-[radial-gradient(circle_at_center,_var(--tw-gradient-stops))] from-gray-800 via-black to-black" />
503+ </ div >
504+
505+ < div className = "relative z-10 max-w-lg" >
506+ < TerminalWindowIcon size = { 64 } className = "mx-auto mb-8 text-emerald-500/50" />
507+ < h2 className = "text-4xl font-playfairDisplay text-white mb-6" >
508+ Command Palette
509+ </ h2 >
510+ < p className = "text-gray-400 mb-8 leading-relaxed" >
511+ Access all features and navigations quickly.
512+ < br />
513+ Hover over the list to see details.
514+ </ p >
515+ </ div >
516+ </ motion . div >
517+ ) }
518+ </ AnimatePresence >
519+ </ div >
520+
521+ { /* Persistent Footer (Always Visible) */ }
522+ < div className = "p-8 border-t border-white/10 bg-neutral-900/80 backdrop-blur-md z-30 flex items-center justify-between gap-6" >
523+ < div className = "hidden xl:flex items-center gap-4 text-sm font-mono text-gray-400" >
524+ < div className = "flex gap-1" >
525+ < kbd className = "px-2 py-1 bg-white/10 rounded border border-white/20 text-white" > Ctrl</ kbd >
526+ < span className = "self-center" > +</ span >
527+ < kbd className = "px-2 py-1 bg-white/10 rounded border border-white/20 text-white" > K</ kbd >
528+ </ div >
529+ < span > to open anywhere</ span >
530+ </ div >
531+
532+ < button
533+ onClick = { togglePalette }
534+ className = "flex-1 xl:flex-none group relative inline-flex items-center justify-center gap-3 px-6 py-4 bg-white text-black hover:bg-emerald-400 transition-colors duration-300 font-mono uppercase tracking-widest text-sm"
535+ >
536+ < CommandIcon size = { 20 } />
537+ < span > Open Palette</ span >
538+ </ button >
539+ </ div >
458540 </ div >
459- </ div >
460- </ div >
461- </ div >
462541 </ div >
463542 ) ;
464543}
0 commit comments