/* global React, Icon, Origin, SyncChip, Meter, CB, RoleChip, JobChip, Portrait, Tag, Empty, Seg, Input, useRoute */ // ============================================================ // Screens 8-9: Free Company overview + Settings / sync status // ============================================================ const { useState: useS89, useMemo: useM89 } = React; // Fake-but-plausible FC roster builder function buildFCRoster() { const FIRST = ['Aerith','Korr','Liliane','Yumi','Veska','Olric','Thalia','Imre','Mira','Brennan','Soren','Kael','Nyx','Riven','Zara','Tobin','Marin','Cinder','Vex','Halen','Pia','Jorah','Sable','Ravi','Bram','Lys','Orin','Sage','Tess','Quinn','Hale','Mara','Ennis','Roe','Sienna','Calla','Drake','Petra','Lior','Nova','Faye','Aldric','Bree','Caelan','Demi','Eira','Finn','Gretta','Hilde','Iva']; const LAST = ['Nightsong','Brassbottom','d\'Aubreville','Shiroyama','Voidsong','Stonebreak','Greycloak','Kalvain','Sundwalker','Holt','Caelduin','Vesper','Brightmoor','Kestrel','Wynter','Halewind','Frostbloom','Rookward','Stardrift','Embergale','Aldermoor','Thornwell','Pellgrove','Maris','Crowmere','Silverkin','Faewright','Driftwood','Halcyon','Mosswood','Lockewood','Holloway','Brenholme','Caradine','Mirewood','Penbrook','Lyonette','Vossfeld','Quill','Riverford','Sablewood','Thrushe','Vellichor','Whitlock','Yseult','Zantor','Abernathy','Beauchamp','Cervantes','Dunmoor']; const JOBS = ['PLD','WAR','DRK','GNB','WHM','SCH','AST','SGE','MNK','DRG','NIN','SAM','RPR','VPR','BRD','MCH','DNC','BLM','SMN','RDM','PCT']; const ranks = ['Member','Member','Member','Member','Member','Member','Sergeant','Sergeant','Lieutenant','Master']; const out = []; let seed = 7; const rand = () => { seed = (seed * 9301 + 49297) % 233280; return seed / 233280; }; for (let i = 0; i < 72; i++) { const f = FIRST[Math.floor(rand() * FIRST.length)]; const l = LAST[Math.floor(rand() * LAST.length)]; const mainJob = JOBS[Math.floor(rand() * JOBS.length)]; const capCount = Math.floor(rand() * 14) + 1; const ilvl = Math.floor(680 + rand() * 60); const mounts = Math.floor(40 + rand() * 270); const linked = rand() > 0.42; const priv = !linked && rand() > 0.55; const lastOn = Math.floor(rand() * 14); const rank = ranks[Math.floor(rand() * ranks.length)]; out.push({ name: `${f} ${l}`, mainJob, capCount, ilvl, mounts, linked, priv, lastOn, rank, }); } return out; } const FC_ROSTER = buildFCRoster(); function ScreenFC() { const [sortKey, setSortKey] = useS89('lastOn'); const [filter, setFilter] = useS89('all'); const [q, setQ] = useS89(''); const filtered = useM89(() => { let r = FC_ROSTER.filter(m => { if (filter === 'linked' && !m.linked) return false; if (filter === 'unlinked' && m.linked) return false; if (q && !m.name.toLowerCase().includes(q.toLowerCase())) return false; return true; }); if (sortKey === 'name') r = [...r].sort((a, b) => a.name.localeCompare(b.name)); else if (sortKey === 'ilvl') r = [...r].sort((a, b) => b.ilvl - a.ilvl); else if (sortKey === 'mounts') r = [...r].sort((a, b) => b.mounts - a.mounts); else if (sortKey === 'capCount') r = [...r].sort((a, b) => b.capCount - a.capCount); else r = [...r].sort((a, b) => a.lastOn - b.lastOn); return r; }, [sortKey, filter, q]); const linkedCount = FC_ROSTER.filter(m => m.linked).length; const avgIlvl = Math.round(FC_ROSTER.reduce((a, m) => a + m.ilvl, 0) / FC_ROSTER.length); const totalMounts = FC_ROSTER.reduce((a, m) => a + (m.linked ? m.mounts : 0), 0); return (
| Rank | Main | Source | ||||||
|---|---|---|---|---|---|---|---|---|
|
{m.name}
{!m.linked && (
{m.priv ? 'Private profile · limited data' : 'Not on Aether Hub yet'}
)}
|
{m.rank} | {m.linked ? `${m.capCount}/22` : —} | {m.linked ? m.ilvl : —} |
{m.linked
? {m.mounts} /312
: m.priv ? |
{m.lastOn === 0 ? 'today' : `${m.lastOn}d ago`} |
{m.linked
? |
Aether Hub only reads public data — your Lodestone character page, FFLogs reports you've made public, and a community-maintained item catalog. We never read your game client, never use addons, and never ask for your Square Enix password. We can't see anything that isn't already public.
{c.cmd}