Webinterface: Emojis durch Lucide-Icons ersetzt
Emojis werden vom Betriebssystem gerendert — auf Windows, Mac und Android sehen sie unterschiedlich aus, und sie sind bunt. Im streng zweifarbigen D4RKST3R-Look stachen sie entsprechend heraus. Jetzt kommen die Symbole aus einem einzigen Set (Lucide, dünne Outlines), zentral in src/icons.jsx gebündelt: eine Größe, eine Strichstärke, überall gleich — und sie erben die Textfarbe, sind also Teil der Marke statt Fremdkörper. Betroffen sind Navigation, Startseite, Server, Roadmap, Profil, Level, Galerie, Devlogs, Lightbox, Composer und alle Setup-Tabs. Bewusst Emojis geblieben sind: - die Spiel-Presets der Server (landen als Icon im Discord-Embed) - Rollen-Menü-Emojis und Platzhalter für Discord-Inhalte - beschreibende Hinweise wie „🔔-Button am Post" oder „🟢/🔴 im Embed", die zeigen, wie etwas in Discord aussehen wird - die selbst gepflegten Dienst-Icons im Portal Dazu Detailarbeit: Server-Status als farbiger Punkt statt Emoji, Platz 1–3 der Bestenliste als Pokal in Gold/Silber/Bronze, Pagination mit Chevrons. Bundle wächst um 19 kB (Tree-Shaking greift, nur die ~70 genutzten Icons). Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,11 @@
|
||||
import { useEffect, useRef, useState } from 'react';
|
||||
import { apiGet, apiPut, apiPost, apiDelete } from '../api.js';
|
||||
import EmbedComposer from '../components/EmbedComposer.jsx';
|
||||
import {
|
||||
IconStatus, IconBrand, IconFeeds, IconCommunity, IconRoles, IconSupport,
|
||||
IconApplications, IconComposer, IconServer, IconSystem, IconApi, IconTeam,
|
||||
IconLock, IconBot, IconUpload, IconChevronDown, IconKey,
|
||||
} from '../icons.jsx';
|
||||
|
||||
const API_SCOPES = [
|
||||
{ id: 'message', label: 'message', hint: 'Nachrichten/Embeds in Kanäle posten' },
|
||||
@@ -10,18 +15,18 @@ const API_SCOPES = [
|
||||
];
|
||||
|
||||
const TABS = [
|
||||
{ id: 'status', icon: '📊', label: 'Status' },
|
||||
{ id: 'brand', icon: '🎨', label: 'Brand' },
|
||||
{ id: 'feeds', icon: '📔', label: 'Feeds' },
|
||||
{ id: 'community', icon: '🙌', label: 'Community' },
|
||||
{ id: 'rollen', icon: '🎭', label: 'Rollen' },
|
||||
{ id: 'support', icon: '📬', label: 'Support' },
|
||||
{ id: 'bewerbungen', icon: '📋', label: 'Bewerbungen' },
|
||||
{ id: 'composer', icon: '📝', label: 'Composer' },
|
||||
{ id: 'server', icon: '🎮', label: 'Server' },
|
||||
{ id: 'system', icon: '⚙️', label: 'System' },
|
||||
{ id: 'api', icon: '🔑', label: 'API' },
|
||||
{ id: 'team', icon: '👥', label: 'Team' },
|
||||
{ id: 'status', Icon: IconStatus, label: 'Status' },
|
||||
{ id: 'brand', Icon: IconBrand, label: 'Brand' },
|
||||
{ id: 'feeds', Icon: IconFeeds, label: 'Feeds' },
|
||||
{ id: 'community', Icon: IconCommunity, label: 'Community' },
|
||||
{ id: 'rollen', Icon: IconRoles, label: 'Rollen' },
|
||||
{ id: 'support', Icon: IconSupport, label: 'Support' },
|
||||
{ id: 'bewerbungen', Icon: IconApplications, label: 'Bewerbungen' },
|
||||
{ id: 'composer', Icon: IconComposer, label: 'Composer' },
|
||||
{ id: 'server', Icon: IconServer, label: 'Server' },
|
||||
{ id: 'system', Icon: IconSystem, label: 'System' },
|
||||
{ id: 'api', Icon: IconApi, label: 'API' },
|
||||
{ id: 'team', Icon: IconTeam, label: 'Team' },
|
||||
];
|
||||
|
||||
// Welcher Team-Scope schaltet welchen Tab frei (null = nur Owner)
|
||||
@@ -574,7 +579,7 @@ export default function Settings({ me }) {
|
||||
{header}
|
||||
<section className="content">
|
||||
<div className="notice center">
|
||||
<p>🔒 Nur für den Admin.</p>
|
||||
<p className="with-icon"><IconLock /> Nur für den Admin.</p>
|
||||
{!me.user && <a className="btn" href="/auth/login">Login mit Discord</a>}
|
||||
</div>
|
||||
</section>
|
||||
@@ -622,15 +627,15 @@ export default function Settings({ me }) {
|
||||
<div className="bot-avatar-wrap">
|
||||
{data.status.botAvatar
|
||||
? <img className="bot-avatar" src={data.status.botAvatar} alt="Bot-Avatar" />
|
||||
: <div className="bot-avatar bot-avatar-empty">🤖</div>}
|
||||
: <div className="bot-avatar bot-avatar-empty"><IconBot size={30} /></div>}
|
||||
<span className="bot-dot" style={{ background: statusDot }} />
|
||||
</div>
|
||||
<label className="btn btn-upload">
|
||||
⬆ Bild ändern
|
||||
<IconUpload size={14} /> Bild ändern
|
||||
<input type="file" accept="image/*" hidden onChange={(e) => uploadImage('avatar', e.target.files?.[0])} />
|
||||
</label>
|
||||
<label className="btn btn-upload btn-ghost">
|
||||
🖼 Banner
|
||||
<IconUpload size={14} /> Banner
|
||||
<input type="file" accept="image/*" hidden onChange={(e) => uploadImage('banner', e.target.files?.[0])} />
|
||||
</label>
|
||||
</div>
|
||||
@@ -844,7 +849,7 @@ export default function Settings({ me }) {
|
||||
onClick={distributeKeys}
|
||||
disabled={!alphaKeys || alphaKeys.free === 0 || alphaKeys.playtestersWithout.length === 0}
|
||||
>
|
||||
🎟️ An {alphaKeys?.playtestersWithout?.length ?? 0} Playtester verteilen
|
||||
<IconKey size={14} /> An {alphaKeys?.playtestersWithout?.length ?? 0} Playtester verteilen
|
||||
</button>
|
||||
</div>
|
||||
{alphaKeys?.assigned?.length > 0 && (
|
||||
@@ -937,7 +942,7 @@ export default function Settings({ me }) {
|
||||
<div className="settings-section">
|
||||
<h2 className="settings-title">// Rollen-Menüs</h2>
|
||||
<p className="section-intro">
|
||||
Selbstbedienungs-Rollen wie bei Carl-bot — nur ohne Paywall. 😄 Der Bot postet
|
||||
Selbstbedienungs-Rollen wie bei Carl-bot — nur ohne Paywall. Der Bot postet
|
||||
ein Embed mit Buttons; Klick = Rolle nehmen, nochmal = abgeben. Menüs sind
|
||||
jederzeit editierbar, der Discord-Post zieht automatisch mit.
|
||||
</p>
|
||||
@@ -1712,7 +1717,7 @@ export default function Settings({ me }) {
|
||||
className={`settings-nav-item ${tab === t.id ? 'active' : ''}`}
|
||||
onClick={() => setTab(t.id)}
|
||||
>
|
||||
<span className="settings-nav-icon">{t.icon}</span>
|
||||
<span className="settings-nav-icon"><t.Icon /></span>
|
||||
{t.label}
|
||||
</button>
|
||||
))}
|
||||
|
||||
Reference in New Issue
Block a user