import React, { useCallback, useEffect, useState } from 'react'; import { api } from './api.js'; import { copyToast } from './toast.js'; import Netdisk from './Netdisk.jsx'; // amerc Mansion β€” a hall of amerc services. First live service: Showcase (reverse proxy). export default function Mansion({ auth, setRoute }) { if (!auth.ready) return

Loading…

; const loggedIn = !!auth.user; const handle = loggedIn ? auth.user.handle.toLowerCase().replace(/[^a-z0-9]/g, '') : 'you'; return (

⚜ Chambers of the estate

); } function RoomShell({ ico, name, tag, status, desc, feats, children }) { return (
{name} {tag}
{status === 'live' ? '● LIVE' : 'SOON'}

{desc}

{feats &&
    {feats.map((f) =>
  • {f}
  • )}
} {children}
); } function SoonRoom(props) { return (
in development
); } // File-mapper: agents publish named files; each download is fetched live from // the broker and piped through β€” nothing is ever stored on amerc. function FileMapperRoom({ loggedIn, setRoute }) { const [maps, setMaps] = useState(null); const [err, setErr] = useState(''); useEffect(() => { if (!loggedIn) return; api('/fm').then((d) => setMaps(d.maps || [])).catch((e) => { setErr(e.message); setMaps([]); }); }, [loggedIn]); return ( {!loggedIn ? (
) : ( <> {err &&

{err}

}

My mapped files

{maps === null ?

loading…

: maps.length ? maps.map((f) => (
{f.name} {f.class_name || `instance #${f.instance_id}`}
)) :

No mapped files yet. Your broker registers one with POST /api/agents/instances/<id>/fm {'{accesskey, name, fileName, size, mime}'} β€” it becomes a stable link instantly.

}
)}
); } // Net-disk: real storage on amerc, 100 MB per account. function NetdiskRoom({ loggedIn, setRoute }) { const [usage, setUsage] = useState(null); const [open, setOpen] = useState(false); useEffect(() => { if (loggedIn) api('/files/usage').then(setUsage).catch(() => {}); }, [loggedIn, open]); const pct = usage ? Math.min(100, Math.round((usage.used / usage.quota) * 100)) : 0; return ( {!loggedIn ? (
) : ( <> {usage && (
90 ? '#ff7a8c' : undefined }} /> {(usage.used / 1048576).toFixed(1)} / 100 MB
)} {open &&
} )}
); } function ShowcaseRoom({ loggedIn, handle, setRoute }) { const [list, setList] = useState([]); const [name, setName] = useState(''); const [created, setCreated] = useState(null); const [err, setErr] = useState(''); const [loaded, setLoaded] = useState(false); const load = useCallback(async () => { if (!loggedIn) return; try { const d = await api('/showcase'); setList(d.showcases || []); } catch (e) { setErr(e.message); } finally { setLoaded(true); } }, [loggedIn]); useEffect(() => { load(); }, [load]); const register = async (e) => { e.preventDefault(); setErr(''); try { const r = await api('/showcase', { method: 'POST', body: { name } }); setCreated(r); setName(''); load(); } catch (e2) { setErr(e2.message); } }; const del = async (id) => { if (!window.confirm('Delete this showcase?')) return; try { await api(`/showcase/${id}`, { method: 'DELETE' }); load(); } catch (e2) { setErr(e2.message); } }; return ( {!loggedIn ? (
show1.{handle}.amerc.ai
) : ( <>
register setName(e.target.value.toLowerCase().replace(/[^a-z0-9-]/g, ''))} required /> .{handle}.amerc.ai
{err &&

{err}

} {created && (

βœ… {created.host} reserved Β· DNS {created.dns}

{created.tls &&

πŸ”’ {created.tls}

}

In the kebab delivery center: connect a broker to the WS with this token, send {`{type:"bind",host:"${created.host}",port:}`}, and your local service is live at the public URL.

)}

My showcases

{!loaded ? ( ) : ( <> {list.map((s) => (
{s.host} registered {new Date(s.created_at).toLocaleDateString()}
))} {!list.length &&

No showcases yet β€” register one above.

} )}
)}
); }