feat: MakerWorld-Anbindung pro Nutzer (eigener Login, eigenes Profil, eigene Daten)

This commit is contained in:
2026-07-11 02:16:20 +02:00
parent 24b40d1284
commit 9b947aeb89
3 changed files with 129 additions and 103 deletions

View File

@@ -198,7 +198,7 @@ function OrdersInPeriod({ fromDate, toDate }) {
}
// MakerWorld Creator-Center Statistik
function MakerworldTab({ isAdmin, toast }) {
function MakerworldTab({ toast }) {
const [state, setState] = useState(null); // { configured, data, error, fetchedAt, needsCode }
const [loading, setLoading] = useState(true);
const [refreshing, setRefreshing] = useState(false);
@@ -219,7 +219,6 @@ function MakerworldTab({ isAdmin, toast }) {
api('/tools/makerworld/stats').then(setState).catch(()=>{}).finally(()=>setLoading(false));
};
const loadLoginStatus = () => {
if (!isAdmin) return;
api('/tools/makerworld/login-status').then(setLoginStatus).catch(()=>{});
};
@@ -260,6 +259,15 @@ function MakerworldTab({ isAdmin, toast }) {
finally { setSavingCreds(false); }
};
const removeCredentials = async () => {
try {
await api('/tools/makerworld/credentials', { method:'DELETE' });
toast?.('Zugangsdaten entfernt');
setState({ configured:false, data:null, error:null, fetchedAt:null, needsCode:false });
loadLoginStatus();
} catch(e) { toast?.(e.message,'error'); }
};
const submitCode = async () => {
if (!codeInput.trim()) return;
setSubmittingCode(true);
@@ -303,7 +311,7 @@ function MakerworldTab({ isAdmin, toast }) {
return (
<div>
{/* Admin: Code-Eingabe hat höchste Priorität, wenn gerade angefordert */}
{isAdmin && state?.needsCode && (
{state?.needsCode && (
<div style={{...S.card,borderColor:'rgba(255,230,109,0.4)',background:'rgba(255,230,109,0.08)'}}>
<div style={{...S.head,color:'#ffe66d'}}>📧 VERIFIZIERUNGSCODE ERFORDERLICH</div>
<div style={{...S.sub,marginBottom:8}}>
@@ -323,9 +331,9 @@ function MakerworldTab({ isAdmin, toast }) {
)}
{/* Admin: Zugangsdaten */}
{isAdmin && !state?.needsCode && (
{!state?.needsCode && (
<div style={S.card}>
<div style={S.head}>MAKERWORLD-LOGIN (ADMIN)</div>
<div style={S.head}>MEINE MAKERWORLD-ZUGANGSDATEN</div>
{loginStatus && (
<div style={{...S.sub,marginBottom:10}}>
{loginStatus.configured
@@ -335,9 +343,10 @@ function MakerworldTab({ isAdmin, toast }) {
</div>
)}
<div style={{...S.sub,marginBottom:8}}>
Wird verschlüsselt gespeichert. Ein echter Browser mit dauerhaftem Profil hält die Session
am Laufen — bei aktiver Nutzung wird ein erneuter Login kaum je nötig. Falls doch, erscheint
hier automatisch die Code-Eingabe.
Wird verschlüsselt gespeichert und nur für deinen eigenen Abruf genutzt — andere Nutzer sehen
weder deine Zugangsdaten noch deine Zahlen. Ein echter Browser mit dauerhaftem Profil hält die
Session am Laufen — bei aktiver Nutzung wird ein erneuter Login kaum je nötig. Falls doch,
erscheint hier automatisch die Code-Eingabe.
</div>
<div style={{display:'flex',gap:8,flexWrap:'wrap',marginBottom:8}}>
<input value={credForm.username} onChange={e=>setCredForm(p=>({...p,username:e.target.value}))}
@@ -358,6 +367,11 @@ function MakerworldTab({ isAdmin, toast }) {
<button onClick={()=>setShowCookieFallback(p=>!p)} style={{...S.btn('#888888')}}>
{showCookieFallback ? '▲ Cookie-Fallback ausblenden' : '⚙ Cookie-Fallback (manuell)'}
</button>
{loginStatus?.configured && (
<button onClick={removeCredentials} style={{...S.btn('#f87171')}}>
🗑 Zugangsdaten entfernen
</button>
)}
</div>
{showCookieFallback && (
@@ -379,14 +393,6 @@ function MakerworldTab({ isAdmin, toast }) {
</div>
)}
{!state?.configured && !isAdmin && (
<div style={S.card}>
<div style={{color:'rgba(255,255,255,0.4)',fontFamily:'monospace',fontSize:12}}>
MakerWorld-Anbindung ist noch nicht eingerichtet.
</div>
</div>
)}
{state?.error && d && (
<div style={{...S.card,borderColor:'rgba(248,113,113,0.3)',background:'rgba(248,113,113,0.06)'}}>
<div style={{color:'#f87171',fontFamily:'monospace',fontSize:11}}>
@@ -754,7 +760,7 @@ export default function Statistik({ mobile, user, toast }) {
{/* ══ MAKERWORLD ══ */}
{tab==='makerworld' && (
<MakerworldTab isAdmin={user?.role==='admin'} toast={toast}/>
<MakerworldTab toast={toast}/>
)}
</div>
);