Log Portfolio is a single-page React application that simulates a Windows 98-era operating system shell entirely in the browser. Rather than navigating between pages, users interact with draggable, resizable windows that open on a persistent desktop — just like a real OS. The entire application is built with React and Vite, using Framer Motion for window animations and Tailwind CSS for the retro Win98 styling.Documentation Index
Fetch the complete documentation index at: https://mintlify.com/apursley2012/log-portfolio/llms.txt
Use this file to discover all available pages before exploring further.
Three-Layer Architecture
The app is organized into three distinct layers that sit on top of each other, each with a clearly scoped responsibility.Context Layer
WindowProvider in contexts/WindowContext.js holds all window state — which windows are open, their positions, z-indices, minimize/maximize flags, and which window is currently active. Every other component reads from and writes to this single source of truth.Shell Layer
Desktop and Taskbar are always rendered and never unmount. The Desktop renders desktop icons from the app registry. The Taskbar reflects currently open windows as buttons and provides a Start-menu-style clock area.Window Layer
Individual
Window components are spawned on demand inside a React Portal targeting the DOM root. Each window is a Framer Motion motion.div with drag, resize, and animation behavior wired to WindowContext actions.Component Relationships
The table below shows how each major piece fits into the hierarchy and what it depends on.| Component / Module | Layer | Depends On | Responsibility |
|---|---|---|---|
WindowProvider | Context | React useState, useCallback | Owns all window state; exposes openWindow, closeWindow, minimizeWindow, restoreWindow, maximizeWindow, focusWindow |
useWindows() | Context | WindowContext | Custom hook; provides context values to any consumer; throws if used outside WindowProvider |
Desktop | Shell | useWindows(), app registry array | Renders the desktop icon grid; calls openWindow() on double-click |
Taskbar | Shell | useWindows() | Renders a button per open window; calls restoreWindow() / focusWindow() |
Window | Window | useWindows(), Framer Motion, React Portal | Renders a single draggable/resizable window frame with title bar controls |
Data Flow: Opening a Window
User double-clicks a desktop icon
The
Desktop component’s onDoubleClick handler fires, calling openWindow() from useWindows() with the full window descriptor: { id, title, icon, content, defaultSize }.WindowContext updates state
openWindow() checks whether a window with that id already exists in the windows array. If it does, it focuses the existing window instead of creating a duplicate. If not, it appends a new entry to windows with isOpen: true, isMinimized: false, isMaximized: false, and a fresh zIndex.Window component mounts with animation
Because
Window wraps its output in Framer Motion’s AnimatePresence, newly added windows animate in with a scale: 0.8 → 1 and opacity: 0 → 1 spring transition. Exit animations play the reverse — scaling down and sliding to y: 100vh — before the component unmounts.Title bar interactions update context
Once open, every title bar button calls back into
WindowContext: the – button calls minimizeWindow(id), the □ button calls maximizeWindow(id), the ✕ button calls closeWindow(id), and clicking anywhere in the window body calls focusWindow(id) to bring it to the front.The Desktop App Registry
The single source of truth for what applications exist in the portfolio lives in theapps array defined in Desktop.js. Each entry fully describes one desktop icon and the window it opens.
openWindow() on double-click.
Static Pages
Thepages/ directory contains one standalone HTML file per app route. Each file bootstraps the same Vite bundle but sets window.__STATIC_PAGE_ROUTE__ before the React app mounts, which tells the hash router to navigate directly to that app’s route. This means a shareable URL like pages/AboutPage.html opens the browser with the About Me window already in focus.
Further Reading
Window Management System
Deep-dive into
WindowContext — every exported function, the WindowData shape, and how the Window component handles drag, resize, and animation.Routing and Static Pages
How hash-based routing works, what
window.__STATIC_PAGE_ROUTE__ does, and step-by-step instructions for adding a new static page route.