Skip to main content

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.

Desktop is the persistent background layer of the portfolio. It renders a grid of clickable icons positioned in the top-left of the screen, each one representing an application. Double-clicking any icon calls openWindow() from WindowContext, which registers the window in global state and brings it to the front. The component itself holds no per-icon open/close state — that is entirely managed by the context.

What It Renders

The component mounts an absolutely-positioned container that fills the full viewport behind all windows (z-0). Inside it, icons are laid out with flex flex-col flex-wrap gap-6 content-start so they stack vertically in columns from top-left. The bottom padding pb-12 ensures icons do not overlap the 40 px taskbar. Each icon is a div with the class w-20 flex flex-col items-center gap-1 cursor-pointer group. On double-click, openWindow() is called with the matching entry from the app registry.

App Registry

The app registry is a plain array of objects defined at the module level in Desktop.js. Each entry describes one desktop icon and the window it opens.

AboutMe.txt

id: about
Icon: FileText (Lucide)
Default size: 500 × 400 px
Opens a simulated Notepad window with a personal bio written in retro plain-text style.

My Computer

id: projects
Icon: Folder (Lucide, yellow fill)
Default size: 600 × 450 px
Opens a Windows Explorer-style file browser listing project files with Large Icons, List, and Details views.

Control Panel

id: skills
Icon: Settings (Lucide)
Default size: 450 × 500 px
Opens a Control Panel window with animated skill progress bars that fill on mount.

Internet Explorer

id: blog
Icon: Globe (Lucide, blue)
Default size: 700 × 550 px
Opens a GeoCities-inspired blog page with marquee text, a visitor counter, and retro HTML nostalgic content.

MSN Messenger

id: testimonials
Icon: MessageSquare (Lucide, green fill)
Default size: 350 × 500 px
Opens a chat-window UI that replays pre-seeded messages at 2-second intervals and accepts user input.

Outlook Express

id: contact
Icon: Mail (Lucide, blue)
Default size: 550 × 450 px
Opens an email compose form. Submitting shows a “Message sent to Outbox” confirmation dialog.
The raw registry array looks like this in source:
const apps = [
  {
    id: "about",
    title: "AboutMe.txt",
    icon: <FileText size={32} className="text-white drop-shadow-md" />,
    component: <AboutContent />,
    defaultSize: { width: 500, height: 400 },
  },
  {
    id: "projects",
    title: "My Computer",
    icon: <Folder size={32} className="text-yellow-400 fill-yellow-400 drop-shadow-md" />,
    component: <ProjectsContent />,
    defaultSize: { width: 600, height: 450 },
  },
  {
    id: "skills",
    title: "Control Panel",
    icon: <Settings size={32} className="text-gray-300 drop-shadow-md" />,
    component: <SkillsContent />,
    defaultSize: { width: 450, height: 500 },
  },
  {
    id: "blog",
    title: "Internet Explorer",
    icon: <Globe size={32} className="text-blue-400 drop-shadow-md" />,
    component: <BlogContent />,
    defaultSize: { width: 700, height: 550 },
  },
  {
    id: "testimonials",
    title: "MSN Messenger",
    icon: <MessageSquare size={32} className="text-green-400 fill-green-400 drop-shadow-md" />,
    component: <TestimonialsContent />,
    defaultSize: { width: 350, height: 500 },
  },
  {
    id: "contact",
    title: "Outlook Express",
    icon: <Mail size={32} className="text-blue-300 drop-shadow-md" />,
    component: <ContactContent />,
    defaultSize: { width: 550, height: 450 },
  },
];

Icon Hover State

Each icon responds to hover with a soft blue highlight:
  • The icon image wrapper gains group-hover:bg-blue-500/30 rounded border border-transparent group-hover:border-blue-300/50 transition-colors
  • The text label below the icon gains group-hover:bg-blue-900/80 px-1 rounded
This mirrors the classic Windows 98 icon-selection style without needing any click state — the visual is entirely CSS driven via the Tailwind group / group-hover utilities.

Opening Windows

Double-click dispatches to useWindows().openWindow() with a cloned icon at 16 px (for the title bar) and the full content component:
onDoubleClick={() =>
  openWindow({
    id: app.id,
    title: app.title,
    icon: React.cloneElement(app.icon, { size: 16 }),
    content: app.component,
    defaultSize: app.defaultSize,
  })
}
cloneElement is used so that the 32 px desktop icon and the 16 px title-bar icon share the same React element definition without duplication.

Adding a New Desktop Icon

1

Create the content component

Build your new window content as a standard React component, for example ResumeContent.jsx.
2

Add an entry to the apps array

Append a new object to the registry in Desktop.js:
{
  id: "resume",
  title: "Resume.pdf",
  icon: <FileText size={32} className="text-yellow-300 drop-shadow-md" />,
  component: <ResumeContent />,
  defaultSize: { width: 600, height: 500 },
}
3

Verify layout

Because icons use flex-wrap and content-start, the new icon will automatically appear below existing ones in the first column. No positioning changes are needed.
See the Adding Windows guide for details on registering a window in WindowContext and controlling its default position.

Layout Classes Reference

ClassPurpose
absolute inset-0Fills the full viewport behind windows
p-4 pb-12Padding on all sides; extra bottom padding clears the taskbar
flex flex-col flex-wrap gap-6 content-startStacks icons vertically, wraps into new columns
z-0Ensures the desktop sits behind all windows and the taskbar

Build docs developers (and LLMs) love