diff --git a/attached_assets/Pasted-Here-is-your-Safe-For-Work-Lawyer-Approved-Ammo-Crate-T_1765865765325.txt b/attached_assets/Pasted-Here-is-your-Safe-For-Work-Lawyer-Approved-Ammo-Crate-T_1765865765325.txt new file mode 100644 index 0000000..a98e5f2 --- /dev/null +++ b/attached_assets/Pasted-Here-is-your-Safe-For-Work-Lawyer-Approved-Ammo-Crate-T_1765865765325.txt @@ -0,0 +1,79 @@ +Here is your **Safe-For-Work, Lawyer-Approved Ammo Crate.** + +These are high-quality, open-source, or Creative Commons games that run natively in the browser. You can host these on your version of AeThex OS without looking over your shoulder for a subpoena. + +Not only keeps you safe, but it also signals to recruits: *"We support the Open Source community."* + +### 1\. The "Doom" Killers (FPS) + +You need a shooter on the desktop to show off WebAssembly performance. + + * **FreeDoom (Phase 1 & 2)** + * *The Tech:* It runs on the Doom engine (which is open source), but replaces all the copyrighted art, sounds, and levels with free community assets. + * *Why it works:* It plays exactly like Doom but costs $0 and 0 legal headaches. + * *How to run:* Use a JS-DOS or PrBoom+ WASM wrapper. + * **OpenArena (Web Port)** + * *The Tech:* A clone of Quake III Arena. + * *Why it works:* Fast, multiplayer-capable, and looks impressive in a browser window. + * *The Flex:* Shows you understand networked physics. + +### 2\. The "SimCity" Replacement (Strategy) + + * **MicropolisJS** + * *The Story:* This is literally the original **SimCity**. EA/Maxis released the source code under the GPL license years ago and renamed it "Micropolis." + * *Why it works:* It’s the ultimate flex. You have the actual code of a legendary game running legally on your OS. + * *Aesthetic:* Perfect Windows 95 vibe. + +### 3\. The "Mario" Replacements (Platformers) + + * **SuperTux** + * *The Tech:* An open-source classic heavily inspired by Super Mario Bros. + * *Why it works:* The penguin mascot (Tux) is the symbol of Linux. Backend engineers love this. + * **Celeste Classic (PICO-8)** + * *The Tech:* The original web version of the indie hit *Celeste*. + * *Why it works:* It proves that simple mechanics + tight controls = engagement. (Check the specific license, but the PICO-8 version is widely distributed freely by the devs). + +### 4\. The "Casual" Productivity Killers + + * **2048** + * *The Tech:* Open-source JS/HTML5. + * *Why it works:* Everyone knows it. It’s lightweight (kb, not mb). + * **Hextris** + * *The Tech:* Tetris, but on a hexagonal grid. + * *Why it works:* Addictive, fast load time. + +----- + +### How to Install These (The "Config" Job) + +In your cloned EmuOS folder, you will find a file like `desktop.json` (or strictly inside the `js` structure). You need to add entries that look like this (simplified logic): + +```json +{ + "title": "Micropolis", + "icon": "assets/icons/simcity.png", + "type": "iframe", + "url": "https://graememcc.github.io/micropolisJS/" +} +``` + +**MrPiglr’s Pro Move:** +Don't just hotlink to other people's GitHub pages (like the URL above). + +1. **Fork** their repository to the AeThex GitHub. +2. **Host** it yourself on GitHub Pages (e.g., `os.aethex.com/games/micropolis`). +3. **Link** to your own version. + +**Why?** + +1. **Stability:** If they delete their repo, your OS doesn't break. +2. **Control:** You can swap the "Loading" screen to say **"Powered by AeThex Foundation"** instead of their default text. + +### Summary Checklist for AeThex OS: + +1. **MicropolisJS** (The Brains) +2. **FreeDoom** (The Brawn) +3. **SuperTux** (The Soul) +4. **AeThex Links** (The Job) + +Do you want me to write a quick `JSON` snippet for **Micropolis** so you can plug it straight into the code? \ No newline at end of file diff --git a/attached_assets/Pasted-You-want-the-straight-answer-Because-you-are-building-a_1765865494186.txt b/attached_assets/Pasted-You-want-the-straight-answer-Because-you-are-building-a_1765865494186.txt new file mode 100644 index 0000000..1fbb97f --- /dev/null +++ b/attached_assets/Pasted-You-want-the-straight-answer-Because-you-are-building-a_1765865494186.txt @@ -0,0 +1,49 @@ +You want the straight answer? Because **you are building an Empire, not a Pirate Bay.** + +If this were just a hobby project for "MrPiglr" to show friends, I’d say go ahead. But you are **AeThex.** You are recruiting senior talent. You are rubbing shoulders with the C-Suite at Gamefam and Super League. + +Hosting copyrighted ROMs (Super Mario, Doom, Quake, Windows 95) on a corporate site is a **death sentence** for a legitimate studio. + +Here is the strategic breakdown of why you can copy the *tech* (the Web OS), but you cannot copy the *library* if you want to dominate. + +### 1. The "Nintendo Nuke" Risk +You know how aggressive IP holders are. Nintendo, Sony, and Microsoft have armies of lawyers. +* **The Scenario:** You launch AeThex OS with *Super Mario Bros* on the desktop to get traffic. +* **The Result:** You don't just get a DMCA takedown. If you are a registered business (AeThex), they can sue for damages. +* **The Fallout:** You lose your credibility. Senior Unreal Engineers from Epic Games won't work for a company that gets flagged for piracy. It makes you look like a "grey market" site, not the "Front of the Metaverse." + +### 2. The "EmuOS" Loophole (That You Don't Have) +EmuOS gets away with it (barely) because they claim to be an **"Educational Archival Project"** (Emupedia). They operate in a legal grey area of "preservation." +* **You are a Studio:** You are a commercial entity. You cannot claim "fair use" or "archival preservation" if you are using those games to drive traffic to your business. + +### 3. The Better Strategy: "AeThex OS" (The Trojan Horse) +You can still have the *cool factor* of a Web OS. You can still have games on there. But you fill it with **"Safe" Ammo** and **Your Own Weapons.** + +Here is how you fill the desktop without getting sued: + +**A. The "Shareware / Open Source" Layer** +Fill the desktop with games that are legally free or open source. It scratches the retro itch without the risk. +* *Instead of Doom:* Host **FreeDoom** (Open source clone). +* *Instead of Quake:* Host **OpenArena** (Quake 3 clone). +* *Instead of Tetris:* Host a generic open-source block stacker. +* **Why:** It looks just as cool to the average user, keeps you 100% legal, and shows devs that you respect code licenses. + +**B. The "AeThex Arcade" (Your Stuff)** +This is the power move. Use the Web OS as a launcher for **your** ecosystem. +* **Icon: "AeThex Legends"** -> Instead of launching an emulator, it deep-links directly into your Roblox Game or Fortnite Map. +* **Icon: "Radio AeThex"** -> Opens a WinAmp-style player streaming your "Computer Cowboy" tracks. +* **Icon: "Manifesto.txt"** -> Opens Notepad with that recruiting manifesto we wrote. + +### 4. How to Execute This Legally +If you want to copy the EmuOS *vibe* for AeThex right now: + +1. **Clone the Repo** (as discussed). +2. **Purge the `desktop.json`:** Delete every entry that is a commercial game (Nintendo, Sega, Microsoft). +3. **Add "Homebrew" Games:** Look for "Homebrew" communities (games made by fans for old consoles that are free to distribute). Host those. +4. **Add Your Demos:** Even if they are simple HTML5 builds or links to your Roblox games. + +**The Verdict:** +If you want traffic, do not use other people's IP as bait. It’s a shortcut that leads to a cliff. Use the **EmuOS interface** (the windows, the taskbar, the retro feel) because that is just UI code—but fill the content with **AeThex Energy.** + +**Next Step:** +Do you want me to find a list of **Open Source / Creative Commons games** that run in the browser so you can populate "AeThex OS" legally and immediately? \ No newline at end of file diff --git a/attached_assets/Pasted-You-want-to-rustle-up-your-own-version-of-EmuOS-That-s-_1765865478324.txt b/attached_assets/Pasted-You-want-to-rustle-up-your-own-version-of-EmuOS-That-s-_1765865478324.txt new file mode 100644 index 0000000..4c292c9 --- /dev/null +++ b/attached_assets/Pasted-You-want-to-rustle-up-your-own-version-of-EmuOS-That-s-_1765865478324.txt @@ -0,0 +1,47 @@ +You want to rustle up your own version of EmuOS? That’s ambitious. Most people just play in the sandbox; you want to build the castle. I respect that. + +EmuOS isn't magic—it’s a clever stack of **static web technology** mixed with **WebAssembly emulators**. It’s essentially a very fancy website that tricks your browser into acting like a Windows 95 desktop. + +Here is the blueprint to build your own "AeThex Outpost" version of EmuOS. + +### 1. The Blueprint (The Source Code) +The entire project is hosted publicly on GitHub. EmuOS is part of the **Emupedia** project. They run it as a static site (GitHub Pages), which means you don't need a complex backend server to run it—just a place to host HTML and JS files. + +* **Target Repo:** `Emupedia/emupedia.github.io` +* **The Mission:** You need to clone this repository. + * *Cowboy Tip:* Don't just fork it blindly. Look at the file structure. The "meat" of the OS is usually in the `beta/emuos/` folder. + +### 2. The Engine (How It Runs) +EmuOS relies on a few heavy lifters to make the emulation happen in the browser. You need to understand these if you want to modify it: + +* **v86:** This is the x86 emulator that runs the actual operating systems (Windows 95, 98, ME). It translates x86 machine code into WebAssembly so your browser can execute it. +* **EmulatorJS / JS-DOS:** These handle the specific game consoles (NES, SNES) and DOS games. +* **The Glue:** The "Desktop" you see is just a web interface (HTML/CSS) styled to look like Windows. The icons are just buttons that launch an iframe or a canvas element running the emulator. + +### 3. The Supply Line (Where the Games Live) +**This is the catch.** You can copy the code, but you can't easily copy the *content*. +The GitHub repo generally does **not** host the terabytes of commercial ROMs and ISOs due to copyright. + +* **The Configuration:** The system knows what games to show based on a JSON manifest. Look for a file like `beta/emuos/assets/data/desktop.json` (or similar inside `assets/data`). + * *What it does:* This file lists every icon on the desktop, the title, and **the URL to the ROM/ISO**. +* **Your Job:** If you copy the site, the games might break if they point to servers that check for "hotlinking" (stealing bandwidth). You will likely need to: + 1. Host your own ROMs (ISOs, game files). + 2. Update the `json` config to point to *your* file locations. + +### 4. How to Deploy Your Own +If you want to spin this up right now to impress your friends: + +1. **Clone the Repo:** Download the `emupedia.github.io` repo to your local machine. +2. **Run Locally:** You can't just double-click `index.html` because of browser security (CORS) regarding WebAssembly. You need a local server. + * *Quick Fix:* Install Python, open the folder in terminal, and run `python -m http.server`. + * *Browse:* Go to `localhost:8000/beta/emuos/` in your browser. +3. **Customize:** Go into the `assets` folder, swap the background image, change the startup sound, or edit that `desktop.json` file to remove the "bloatware" games you don't want. +4. **Publish:** Upload your modified folder to **GitHub Pages** or **Netlify**. It’s static, so it’s free to host (minus the massive ROM files). + +### The "MrPiglr" Advice +Don't just copy it 1:1. That’s boring. +Use this tech to build a **Portfolio OS.** + +Instead of "Doom" and "Quake," make the desktop icons launch *your* projects, *your* music, and *your* code. Make a "My Documents" folder that is actually your Resume. + +That’s how you turn a toy into a weapon. Now get to building. \ No newline at end of file diff --git a/client/src/App.tsx b/client/src/App.tsx index def52dc..e18d98f 100644 --- a/client/src/App.tsx +++ b/client/src/App.tsx @@ -24,6 +24,7 @@ import AdminAchievements from "@/pages/admin-achievements"; import AdminApplications from "@/pages/admin-applications"; import AdminActivity from "@/pages/admin-activity"; import AdminNotifications from "@/pages/admin-notifications"; +import AeThexOS from "@/pages/os"; import { Chatbot } from "@/components/Chatbot"; function Router() { @@ -47,6 +48,7 @@ function Router() { {() => } {() => } + ); diff --git a/client/src/components/ProtectedRoute.tsx b/client/src/components/ProtectedRoute.tsx index adc163c..689ec73 100644 --- a/client/src/components/ProtectedRoute.tsx +++ b/client/src/components/ProtectedRoute.tsx @@ -1,4 +1,4 @@ -import { useEffect } from "react"; +import { useEffect, useRef } from "react"; import { useLocation } from "wouter"; import { useAuth } from "@/lib/auth"; @@ -7,8 +7,13 @@ interface ProtectedRouteProps { } export function ProtectedRoute({ children }: ProtectedRouteProps) { - const { isAuthenticated, isLoading } = useAuth(); + const { isAuthenticated, isLoading, user } = useAuth(); const [, setLocation] = useLocation(); + const wasAuthenticated = useRef(false); + + if (isAuthenticated) { + wasAuthenticated.current = true; + } useEffect(() => { if (!isLoading && !isAuthenticated) { @@ -17,6 +22,9 @@ export function ProtectedRoute({ children }: ProtectedRouteProps) { }, [isLoading, isAuthenticated, setLocation]); if (isLoading) { + if (wasAuthenticated.current || user) { + return <>{children}; + } return (
Loading...
diff --git a/client/src/lib/auth.tsx b/client/src/lib/auth.tsx index bd84f5b..827fd48 100644 --- a/client/src/lib/auth.tsx +++ b/client/src/lib/auth.tsx @@ -21,16 +21,17 @@ const AuthContext = createContext(null); export function AuthProvider({ children }: { children: ReactNode }) { const queryClient = useQueryClient(); - const { data: session, isLoading } = useQuery({ + const { data: session, isLoading, isFetching } = useQuery({ queryKey: ["session"], queryFn: async () => { const res = await fetch("/api/auth/session", { credentials: "include" }); return res.json(); }, - staleTime: 30000, - gcTime: 60000, + staleTime: 5 * 60 * 1000, // 5 minutes + gcTime: 10 * 60 * 1000, // 10 minutes refetchOnWindowFocus: false, refetchOnMount: false, + refetchOnReconnect: false, }); const loginMutation = useMutation({ diff --git a/client/src/lib/iconMap.tsx b/client/src/lib/iconMap.tsx index 10dc147..c84200a 100644 --- a/client/src/lib/iconMap.tsx +++ b/client/src/lib/iconMap.tsx @@ -8,12 +8,13 @@ import { Calendar, CalendarDays, CalendarHeart, Video, Clapperboard, Flame, Globe, Network, Brain, ShieldCheck, ShieldEllipsis, - Swords, LogIn, GraduationCap + Swords, LogIn, GraduationCap, Sparkles } from "lucide-react"; const iconMap: Record> = { "award": Award, "star": Star, + "star-struck": Sparkles, "trophy": Trophy, "crown": Crown, "shield": Shield, diff --git a/client/src/pages/admin-logs.tsx b/client/src/pages/admin-logs.tsx index 41b9fab..2845bb5 100644 --- a/client/src/pages/admin-logs.tsx +++ b/client/src/pages/admin-logs.tsx @@ -69,7 +69,14 @@ export default function AdminLogs() { ) : logs?.length === 0 ? ( - No logs found + + +

No Auth Logs Yet

+

+ Authentication events will appear here as users log in and out. + The auth_logs table in Supabase is currently empty. +

+ ) : ( logs?.map((log: any) => ( diff --git a/client/src/pages/admin-sites.tsx b/client/src/pages/admin-sites.tsx index 6a6cb47..f1ea039 100644 --- a/client/src/pages/admin-sites.tsx +++ b/client/src/pages/admin-sites.tsx @@ -64,8 +64,13 @@ export default function AdminSites() { Loading sites...
) : sites?.length === 0 ? ( -
- No sites found +
+ +

No Sites Configured

+

+ Site monitoring will display here once sites are added to your Supabase database. + Add entries to the "sites" table to track uptime and performance. +

) : ( sites?.map((site: any) => ( diff --git a/client/src/pages/os.tsx b/client/src/pages/os.tsx new file mode 100644 index 0000000..968dace --- /dev/null +++ b/client/src/pages/os.tsx @@ -0,0 +1,755 @@ +import { useState, useRef, useCallback, useEffect } from "react"; +import { motion, AnimatePresence } from "framer-motion"; +import { + Terminal, FileText, IdCard, Music, Settings, Globe, + X, Minus, Square, Maximize2, Volume2, Wifi, Battery, + ChevronUp +} from "lucide-react"; + +interface WindowState { + id: string; + title: string; + icon: React.ReactNode; + content: React.ReactNode; + x: number; + y: number; + width: number; + height: number; + minimized: boolean; + maximized: boolean; + zIndex: number; +} + +interface DesktopApp { + id: string; + title: string; + icon: React.ReactNode; + content: React.ReactNode; + defaultWidth: number; + defaultHeight: number; +} + +export default function AeThexOS() { + const [windows, setWindows] = useState([]); + const [activeWindowId, setActiveWindowId] = useState(null); + const [maxZIndex, setMaxZIndex] = useState(1); + const [showStartMenu, setShowStartMenu] = useState(false); + const [time, setTime] = useState(new Date()); + const desktopRef = useRef(null); + + useEffect(() => { + const timer = setInterval(() => setTime(new Date()), 1000); + return () => clearInterval(timer); + }, []); + + const apps: DesktopApp[] = [ + { + id: "terminal", + title: "Terminal", + icon: , + defaultWidth: 700, + defaultHeight: 450, + content: + }, + { + id: "passport", + title: "Passport Viewer", + icon: , + defaultWidth: 500, + defaultHeight: 600, + content: + }, + { + id: "manifesto", + title: "Manifesto", + icon: , + defaultWidth: 600, + defaultHeight: 500, + content: + }, + { + id: "music", + title: "Ambient", + icon: , + defaultWidth: 400, + defaultHeight: 300, + content: + }, + { + id: "browser", + title: "Nexus", + icon: , + defaultWidth: 800, + defaultHeight: 600, + content: + }, + { + id: "settings", + title: "System", + icon: , + defaultWidth: 500, + defaultHeight: 400, + content: + } + ]; + + const openApp = useCallback((app: DesktopApp) => { + const existingWindow = windows.find(w => w.id === app.id); + if (existingWindow) { + if (existingWindow.minimized) { + setWindows(prev => prev.map(w => + w.id === app.id ? { ...w, minimized: false, zIndex: maxZIndex + 1 } : w + )); + } else { + setWindows(prev => prev.map(w => + w.id === app.id ? { ...w, zIndex: maxZIndex + 1 } : w + )); + } + setMaxZIndex(prev => prev + 1); + setActiveWindowId(app.id); + return; + } + + const offsetX = (windows.length % 5) * 40 + 100; + const offsetY = (windows.length % 5) * 40 + 50; + + const newWindow: WindowState = { + id: app.id, + title: app.title, + icon: app.icon, + content: app.content, + x: offsetX, + y: offsetY, + width: app.defaultWidth, + height: app.defaultHeight, + minimized: false, + maximized: false, + zIndex: maxZIndex + 1 + }; + + setWindows(prev => [...prev, newWindow]); + setMaxZIndex(prev => prev + 1); + setActiveWindowId(app.id); + setShowStartMenu(false); + }, [windows, maxZIndex]); + + const closeWindow = useCallback((id: string) => { + setWindows(prev => prev.filter(w => w.id !== id)); + if (activeWindowId === id) { + setActiveWindowId(null); + } + }, [activeWindowId]); + + const minimizeWindow = useCallback((id: string) => { + setWindows(prev => prev.map(w => + w.id === id ? { ...w, minimized: true } : w + )); + }, []); + + const toggleMaximize = useCallback((id: string) => { + setWindows(prev => prev.map(w => + w.id === id ? { ...w, maximized: !w.maximized } : w + )); + }, []); + + const focusWindow = useCallback((id: string) => { + setWindows(prev => prev.map(w => + w.id === id ? { ...w, zIndex: maxZIndex + 1 } : w + )); + setMaxZIndex(prev => prev + 1); + setActiveWindowId(id); + }, [maxZIndex]); + + return ( +
+
setShowStartMenu(false)} + > +
+
+
+ +
+ {apps.map((app) => ( + openApp(app)} + /> + ))} +
+ + + {windows.filter(w => !w.minimized).map((window) => ( + closeWindow(window.id)} + onMinimize={() => minimizeWindow(window.id)} + onMaximize={() => toggleMaximize(window.id)} + onFocus={() => focusWindow(window.id)} + onMove={(x, y) => { + setWindows(prev => prev.map(w => + w.id === window.id ? { ...w, x, y } : w + )); + }} + onResize={(width, height) => { + setWindows(prev => prev.map(w => + w.id === window.id ? { ...w, width, height } : w + )); + }} + desktopRef={desktopRef} + /> + ))} + +
+ + setShowStartMenu(!showStartMenu)} + onWindowClick={(id) => { + const window = windows.find(w => w.id === id); + if (window?.minimized) { + setWindows(prev => prev.map(w => + w.id === id ? { ...w, minimized: false, zIndex: maxZIndex + 1 } : w + )); + setMaxZIndex(prev => prev + 1); + } + focusWindow(id); + }} + onAppClick={openApp} + /> +
+ ); +} + +function DesktopIcon({ icon, label, onClick }: { icon: React.ReactNode; label: string; onClick: () => void }) { + return ( + +
+ {icon} +
+ + {label} + +
+ ); +} + +interface WindowProps { + window: WindowState; + isActive: boolean; + onClose: () => void; + onMinimize: () => void; + onMaximize: () => void; + onFocus: () => void; + onMove: (x: number, y: number) => void; + onResize: (width: number, height: number) => void; + desktopRef: React.RefObject; +} + +function Window({ window, isActive, onClose, onMinimize, onMaximize, onFocus, onMove, onResize, desktopRef }: WindowProps) { + const [isDragging, setIsDragging] = useState(false); + const [isResizing, setIsResizing] = useState(false); + const dragStart = useRef({ x: 0, y: 0, windowX: 0, windowY: 0 }); + const resizeStart = useRef({ x: 0, y: 0, width: 0, height: 0 }); + + const handleDragStart = (e: React.MouseEvent) => { + if (window.maximized) return; + e.preventDefault(); + setIsDragging(true); + dragStart.current = { + x: e.clientX, + y: e.clientY, + windowX: window.x, + windowY: window.y + }; + onFocus(); + }; + + const handleResizeStart = (e: React.MouseEvent) => { + if (window.maximized) return; + e.preventDefault(); + e.stopPropagation(); + setIsResizing(true); + resizeStart.current = { + x: e.clientX, + y: e.clientY, + width: window.width, + height: window.height + }; + }; + + useEffect(() => { + if (!isDragging && !isResizing) return; + + const handleMouseMove = (e: MouseEvent) => { + if (isDragging) { + const dx = e.clientX - dragStart.current.x; + const dy = e.clientY - dragStart.current.y; + onMove(dragStart.current.windowX + dx, Math.max(0, dragStart.current.windowY + dy)); + } + if (isResizing) { + const dx = e.clientX - resizeStart.current.x; + const dy = e.clientY - resizeStart.current.y; + onResize( + Math.max(300, resizeStart.current.width + dx), + Math.max(200, resizeStart.current.height + dy) + ); + } + }; + + const handleMouseUp = () => { + setIsDragging(false); + setIsResizing(false); + }; + + document.addEventListener("mousemove", handleMouseMove); + document.addEventListener("mouseup", handleMouseUp); + return () => { + document.removeEventListener("mousemove", handleMouseMove); + document.removeEventListener("mouseup", handleMouseUp); + }; + }, [isDragging, isResizing, onMove, onResize]); + + const style = window.maximized + ? { top: 0, left: 0, width: "100%", height: "100%", zIndex: window.zIndex } + : { top: window.y, left: window.x, width: window.width, height: window.height, zIndex: window.zIndex }; + + return ( + +
+
+
+ {window.icon} +
+ {window.title} +
+
+ + + +
+
+ +
+ {window.content} +
+ + {!window.maximized && ( +
+
+
+ )} + + ); +} + +interface TaskbarProps { + windows: WindowState[]; + activeWindowId: string | null; + apps: DesktopApp[]; + time: Date; + showStartMenu: boolean; + onToggleStartMenu: () => void; + onWindowClick: (id: string) => void; + onAppClick: (app: DesktopApp) => void; +} + +function Taskbar({ windows, activeWindowId, apps, time, showStartMenu, onToggleStartMenu, onWindowClick, onAppClick }: TaskbarProps) { + return ( + <> + + {showStartMenu && ( + e.stopPropagation()} + > +
+
+
+ A +
+
+
AeThex OS
+
v1.0.0
+
+
+
+
+ {apps.map(app => ( + + ))} +
+
+ )} +
+ +
+ + +
+ +
+ {windows.map(window => ( + + ))} +
+ +
+ + + +
+ {time.toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })} +
+
+
+ + ); +} + +function TerminalApp() { + const [history, setHistory] = useState([ + "AeThex Terminal v1.0.0", + "Type 'help' for available commands.", + "" + ]); + const [input, setInput] = useState(""); + + const commands: Record string[]> = { + help: () => ["Available commands:", " help - Show this message", " status - System status", " whoami - Current user", " clear - Clear terminal", " matrix - Enter the matrix", ""], + status: () => ["SYSTEM STATUS", " Aegis Shield: ACTIVE", " Threat Level: LOW", " Architects Online: 47", " Projects Active: 156", ""], + whoami: () => ["architect@aethex:~$ You are a Metaverse Architect", ""], + clear: () => [], + matrix: () => ["Wake up, Architect...", "The Matrix has you...", "Follow the white rabbit.", ""] + }; + + const handleSubmit = (e: React.FormEvent) => { + e.preventDefault(); + const cmd = input.trim().toLowerCase(); + const output = commands[cmd]?.() || [`Command not found: ${input}`, "Type 'help' for available commands.", ""]; + + if (cmd === "clear") { + setHistory([]); + } else { + setHistory(prev => [...prev, `$ ${input}`, ...output]); + } + setInput(""); + }; + + return ( +
+ {history.map((line, i) => ( +
{line}
+ ))} +
+ $ + setInput(e.target.value)} + className="flex-1 ml-2 bg-transparent outline-none text-green-400" + autoFocus + data-testid="terminal-input" + /> +
+
+ ); +} + +function PassportApp() { + return ( +
+
+
+
+ +
+

AeThex Passport

+

Architect Credentials

+
+ +
+
+ Status + VERIFIED +
+
+ Passport ID + AX-2025-0001 +
+
+ Tier + ARCHITECT +
+
+ XP + 12,450 +
+
+ Level + 15 +
+
+ Skills + 7 Certified +
+
+ +
+
+ Issued by Codex Certification Authority +
+
+
+
+ ); +} + +function ManifestoApp() { + return ( +
+
+

+ The AeThex Manifesto +

+ +
+

We are the architects of tomorrow.

+ +

In a world where the digital and physical converge, we stand at the frontier of a new reality. The Metaverse is not just a destination - it is a canvas for human potential.

+ +

Our Three Pillars:

+ +

AXIOM - The foundational truths that guide our work. We believe in decentralization, transparency, and the power of community-driven innovation.

+ +

CODEX - The certification of excellence. Through rigorous training and real-world application, we transform talent into verified Metaverse Architects.

+ +

AEGIS - The shield that protects. Security is not an afterthought but a fundamental principle woven into everything we create.

+ +

+ "Build. Certify. Protect. This is the way of the Architect." +

+
+
+
+ ); +} + +function MusicApp() { + const [isPlaying, setIsPlaying] = useState(false); + + const tracks = [ + { name: "Neon Dreams", artist: "Synth Collective" }, + { name: "Digital Rain", artist: "Matrix OST" }, + { name: "Architect's Theme", artist: "AeThex Audio" }, + ]; + + return ( +
+
+
+ +
+
Ambient Player
+
v1.0
+
+ +
+ {tracks.map((track, i) => ( + + ))} +
+ +
+
+ Audio playback coming soon +
+
+
+ ); +} + +function BrowserApp() { + return ( +
+
+
+ nexus://aethex.local +
+
+
+
+ +

+ Nexus Browser +

+

+ The decentralized web browser for the Metaverse. Coming soon to AeThex OS. +

+
+
+
+ ); +} + +function SettingsApp() { + return ( +
+

+ System Settings +

+ +
+
+
+
Dark Mode
+
Always on in AeThex OS
+
+
+
+
+
+ +
+
+
Notifications
+
System alerts and updates
+
+
+
+
+
+ +
+
+
Sound Effects
+
UI interaction sounds
+
+
+
+
+
+ +
+
AeThex OS v1.0.0
+
Build 2025.12.16
+
+
+
+ ); +} diff --git a/server/index.ts b/server/index.ts index dd21822..7861295 100644 --- a/server/index.ts +++ b/server/index.ts @@ -28,8 +28,8 @@ app.use( cookie: { secure: process.env.NODE_ENV === "production", httpOnly: true, - sameSite: "strict", // CSRF protection - maxAge: 24 * 60 * 60 * 1000, // 24 hours + sameSite: "lax", // Allow navigation from external links + maxAge: 7 * 24 * 60 * 60 * 1000, // 7 days }, }) );