/* eslint-disable */ // ───────────────────────────────────────────────────────────── // searchgg · 클랜홈 섹션 컴포넌트 (브랜드 컬러 고정) // 의존: window.Panel, Icon, RankBadge, Emblem, SA // ───────────────────────────────────────────────────────────── const CLPT = '#48515f'; const CLCH = "'Chakra Petch',sans-serif"; function RoleBadge({ role, theme }) { const map = { '클랜장': { bg: theme, color: '#fff' }, '운영진': { bg: `${theme}22`, color: theme }, '정예': { bg: '#eef0f2', color: '#5b626c' }, '일반': { bg: 'transparent', color: '#949aa3' }, }; const s = map[role] || map['일반']; return {role}; } // ── 멤버 ── function ClanMembers({ clan, onPick }) { const groups = ['클랜장', '운영진', '정예', '일반']; const byRole = (r) => clan.members.filter((m) => m.role === r); return ( {clan.totalMembers} / {clan.memberMax}명} bodyPad="6px 0 6px"> {groups.map((g) => { const list = byRole(g); if (!list.length) return null; return (
{g} · {list.length} 기여도
{list.map((m, i) => ( ))}
); })}
); } // ── 정기전 일정 ── function ClanSchedule({ clan }) { const t = CLPT; const [items, setItems] = React.useState(clan.schedule); const [open, setOpen] = React.useState(false); const [day, setDay] = React.useState('월'); const [time, setTime] = React.useState('21:00'); const [title, setTitle] = React.useState(''); React.useEffect(() => { setItems(clan.schedule); setOpen(false); }, [clan.name]); const register = () => { const name = title.trim(); if (!name) return; setItems(items.map((s) => s.day === day ? { ...s, on: true, time, title: name } : s)); setTitle(''); setOpen(false); }; const remove = (d) => setItems(items.map((s) => s.day === d ? { ...s, on: false, time: '—', title: '휴식' } : s)); const inputStyle = { border: '1px solid var(--line2)', borderRadius: 6, padding: '9px 11px', fontSize: 13, fontFamily: "'Pretendard',sans-serif", fontWeight: 600, color: 'var(--ink)', outline: 'none', boxSizing: 'border-box' }; return ( setOpen(true)} style={{ border: 'none', background: 'transparent', cursor: 'pointer', fontFamily: "'Pretendard',sans-serif", fontWeight: 700, fontSize: 12, color: t, padding: 0 }}>+ 일정 등록 ) : null} bodyPad="12px 14px 14px">
{items.map((s) => (
{s.day}
{s.time}
))}
{items.filter((s) => s.on).map((s) => (
{s.day} {s.time} {s.title} {clan.isMine && ( )}
))} {items.every((s) => !s.on) &&
등록된 일정이 없어요.
}
{/* 일정 등록 모달 */} {open && (
setOpen(false)} style={{ position: 'fixed', inset: 0, zIndex: 260, background: 'rgba(20,22,26,.55)', backdropFilter: 'blur(2px)', display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 20, animation: 'sgFade .18s ease' }}>
e.stopPropagation()} style={{ width: 380, maxWidth: '100%', background: '#fff', borderRadius: 12, overflow: 'hidden', boxShadow: '0 24px 70px rgba(0,0,0,.3)', fontFamily: "'Pretendard',sans-serif" }}>
일정 등록
요일
{items.map((s) => ( ))}
{items.find((s) => s.day === day && s.on) && (
이미 일정이 있는 요일이에요. 등록하면 덮어써요.
)}
시간
setTime(e.target.value)} style={{ ...inputStyle, width: '100%' }} />
일정명
setTitle(e.target.value)} onKeyDown={(e) => { if (e.key === 'Enter') register(); }} placeholder="예: 정기전, 내전 데이" style={{ ...inputStyle, width: '100%' }} />
)}
); } // ── 주간 활동 (접속률) ── function ClanActivity({ clan }) { const days = ['월', '화', '수', '목', '금', '토', '일']; const max = Math.max(...clan.attendance); return ( 접속률} bodyPad="14px 14px 12px">
{clan.attendance.map((v, i) => (
{v}%
{days[i]}
))}
); } // ── 주간 매치 (모드별) ── function ClanWeeklyMatches({ clan }) { const days = ['월', '화', '수', '목', '금', '토', '일']; const acts = clan.activity; const cats = [ ['clanWar', '클랜전', CLPT], ['clanRanked', '클랜 랭크전', '#6b7585'], ['soloRanked', '솔로 랭크전', '#99a1ae'], ['partyRanked', '파티 랭크전', '#cdd2d9'], ]; const sum = (a) => cats.reduce((s, [k]) => s + a[k], 0); const max = Math.max(...acts.map(sum)); const totals = cats.map(([k, label, color]) => [label, acts.reduce((s, a) => s + a[k], 0), color]); return ( 모드별 판수} bodyPad="14px 14px 12px">
{acts.map((a, i) => (
{sum(a)}
{cats.map(([k, label, color]) => (
))}
{days[i]}
))}
{totals.map(([label, n, color]) => ( {label} {n}판 ))}
); } // ── 미니 페이저 ── function ClanPager({ page, total, onPage }) { if (total <= 1) return null; const nav = (dis) => ({ width: 26, height: 26, borderRadius: 5, border: '1px solid var(--line2)', background: '#fff', cursor: dis ? 'default' : 'pointer', opacity: dis ? .4 : 1, display: 'grid', placeItems: 'center' }); return (
{Array.from({ length: total }, (_, i) => i + 1).map((n) => ( ))}
); } // ── 공지 ── function ClanNotices({ clan }) { const PER = 4; const [page, setPage] = React.useState(1); React.useEffect(() => setPage(1), [clan.name]); const total = Math.max(1, Math.ceil(clan.notices.length / PER)); const cur = Math.min(page, total); const rows = clan.notices.slice((cur - 1) * PER, cur * PER); return ( {rows.map((n, i) => (
{n.pin && 고정} {n.title} {n.author} · {n.time}
))} setPage(Math.max(1, Math.min(total, n)))} />
); } // ── 클랜 피드 ── function ClanFeed({ clan }) { const PER = 3; const [items, setItems] = React.useState(clan.feed); const [draft, setDraft] = React.useState(''); const [page, setPage] = React.useState(1); React.useEffect(() => { setItems(clan.feed); setDraft(''); setPage(1); }, [clan.name]); const total = Math.max(1, Math.ceil(items.length / PER)); const cur = Math.min(page, total); const rows = items.slice((cur - 1) * PER, cur * PER); const post = () => { const text = draft.trim(); if (!text) return; setItems([{ author: window.SA.me.name, role: '일반', time: '방금 전', text, likes: 0 }, ...items]); setDraft(''); setPage(1); }; return ( {clan.isMine && (
{window.SA.me.name.slice(0, 1)}
setDraft(e.target.value)} onKeyDown={(e) => { if (e.key === 'Enter') post(); }} placeholder="클랜원들에게 소식을 남겨보세요" style={{ flex: 1, minWidth: 0, border: '1px solid var(--line2)', borderRadius: 6, padding: '9px 12px', fontSize: 13, fontFamily: "'Pretendard',sans-serif", outline: 'none' }} />
)} {rows.map((f, i) => (
{f.author.slice(0, 1)}
{f.author} {f.time}
{f.text}
{f.likes}
))} setPage(Math.max(1, Math.min(total, n)))} />
); } // ── 방명록 ── function ClanGuestbook({ clan }) { const PER = 4; const [items, setItems] = React.useState(clan.guestbook); const [draft, setDraft] = React.useState(''); const [page, setPage] = React.useState(1); React.useEffect(() => { setItems(clan.guestbook); setDraft(''); setPage(1); }, [clan.name]); const total = Math.max(1, Math.ceil(items.length / PER)); const cur = Math.min(page, total); const rows = items.slice((cur - 1) * PER, cur * PER); const post = () => { const text = draft.trim(); if (!text) return; setItems([{ author: window.SA.me.name, text, time: '방금 전' }, ...items]); setDraft(''); setPage(1); }; const [replyAt, setReplyAt] = React.useState(-1); const [replyDraft, setReplyDraft] = React.useState(''); React.useEffect(() => { setReplyAt(-1); setReplyDraft(''); }, [clan.name]); const postReply = (gi) => { const text = replyDraft.trim(); if (!text) return; setItems(items.map((g, idx) => idx === gi ? { ...g, replies: [...(g.replies || []), { author: window.SA.me.name, text, time: '방금 전' }] } : g)); setReplyDraft(''); setReplyAt(-1); }; return ( 클랜원은 답글만 달 수 있어요 : null} bodyPad="10px 14px 14px"> {!clan.isMine && (
setDraft(e.target.value)} onKeyDown={(e) => { if (e.key === 'Enter') post(); }} placeholder="따뜻한 한마디를 남겨보세요" style={{ flex: 1, minWidth: 0, border: '1px solid var(--line2)', borderRadius: 6, padding: '9px 12px', fontSize: 13, fontFamily: "'Pretendard',sans-serif", outline: 'none' }} />
)} {rows.map((g, i) => { const gi = (cur - 1) * PER + i; const replies = g.replies || []; return (
{g.author.slice(0, 1)}
{g.author} {g.time} {clan.isMine && ( )}
{g.text}
{/* 답글 목록 */} {replies.map((rp, j) => (
{rp.author.slice(0, 1)}
{rp.author} 클랜원 {rp.time}
{rp.text}
))} {/* 답글 입력 */} {replyAt === gi && (
setReplyDraft(e.target.value)} onKeyDown={(e) => { if (e.key === 'Enter') postReply(gi); }} placeholder="답글을 남겨보세요" style={{ flex: 1, minWidth: 0, border: '1px solid var(--line2)', borderRadius: 6, padding: '7px 10px', fontSize: 12.5, fontFamily: "'Pretendard',sans-serif", outline: 'none' }} />
)}
); })} setPage(Math.max(1, Math.min(total, n)))} />
); } Object.assign(window, { ClanMembers, ClanSchedule, ClanActivity, ClanWeeklyMatches, ClanNotices, ClanFeed, ClanGuestbook });