From 5a9b47c9f20ee43f18c3b80559d3d7fb4f15596e Mon Sep 17 00:00:00 2001 From: Harun CAN Date: Mon, 23 Mar 2026 01:19:37 +0300 Subject: [PATCH] main --- src/components/Admin.tsx | 242 +++++++++++++++++++++++++++++++------ src/components/Clients.tsx | 14 ++- 2 files changed, 211 insertions(+), 45 deletions(-) diff --git a/src/components/Admin.tsx b/src/components/Admin.tsx index 99f81b9..576d261 100644 --- a/src/components/Admin.tsx +++ b/src/components/Admin.tsx @@ -32,8 +32,15 @@ export default function Admin({ forceOpen = false }: { forceOpen?: boolean }) { // Client state const [newClientName, setNewClientName] = useState(''); + const [newClientWebsite, setNewClientWebsite] = useState(''); const [clientUploading, setClientUploading] = useState(false); + const [editingClientId, setEditingClientId] = useState(null); + const [editingClientName, setEditingClientName] = useState(''); + const [editingClientWebsite, setEditingClientWebsite] = useState(''); + const [clientSaving, setClientSaving] = useState(false); + const [clientLogoUploading, setClientLogoUploading] = useState(null); const clientFileRef = useRef(null); + const clientLogoChangeRef = useRef(null); // Audit Logs state const [auditLogs, setAuditLogs] = useState([]); @@ -168,9 +175,10 @@ export default function Admin({ forceOpen = false }: { forceOpen?: boolean }) { throw new Error('Sunucu görsel URL\'sini döndüremedi. Lütfen tekrar deneyin.'); } - await api.createClient({ name: newClientName.trim(), logo: logoUrl }); + await api.createClient({ name: newClientName.trim(), logo: logoUrl, website: newClientWebsite.trim() || undefined }); await refreshClients(); setNewClientName(''); + setNewClientWebsite(''); showMessage('Marka eklendi', 'success'); } catch (err: any) { showMessage(err.message || 'Marka eklenemedi', 'error'); @@ -516,8 +524,8 @@ export default function Admin({ forceOpen = false }: { forceOpen?: boolean }) {

YENİ MARKA EKLE

-
-
+
+
-
+
+ { - const file = e.target.files?.[0]; - if (file) await handleAddClient(file); - e.target.value = ''; - }} + type="url" + value={newClientWebsite} + onChange={(e) => setNewClientWebsite(e.target.value)} + className="w-full bg-slate-950 border border-white/10 px-4 py-2.5 text-white focus:border-[#FF5733] outline-none transition-colors text-sm rounded-sm" + placeholder="https://www.netflix.com" /> -
+
+ { + const file = e.target.files?.[0]; + if (file) await handleAddClient(file); + e.target.value = ''; + }} + /> + + {newClientWebsite && ( + 🔗 SEO backlink aktif + )} +
-
- {data.clients.map((client) => ( -
- {client.name} - {client.name} - -
- ))} + {/* Hidden file input for logo change */} + { + const file = e.target.files?.[0]; + if (file && editingClientId) { + setClientLogoUploading(editingClientId); + try { + const response = await api.uploadFile(file); + const media = (response as any).data || response; + let logoUrl = ''; + if (media && typeof media === 'object') { + if (media.url) logoUrl = media.url; + else if (media.filename) logoUrl = `/uploads/${media.filename}`; + } + if (!logoUrl) throw new Error('Görsel URL alınamadı'); + await api.updateClient(editingClientId, { logo: logoUrl }); + await refreshClients(); + showMessage('Logo güncellendi', 'success'); + } catch (err: any) { + showMessage(err.message || 'Logo güncellenemedi', 'error'); + } finally { + setClientLogoUploading(null); + } + } + e.target.value = ''; + }} + /> + +
+ {data.clients.map((client) => { + const isEditing = editingClientId === client.id; + return ( +
+ {/* Logo area */} +
+ {client.name} + {clientLogoUploading === client.id && ( + Yükleniyor... + )} + {isEditing && clientLogoUploading !== client.id && ( + + )} +
+ + {/* Content area */} + {isEditing ? ( +
+
+ + setEditingClientName(e.target.value)} + className="w-full bg-slate-950 border border-white/10 px-3 py-1.5 text-sm text-white focus:border-[#FF5733] outline-none rounded-sm" + /> +
+
+ + setEditingClientWebsite(e.target.value)} + className="w-full bg-slate-950 border border-white/10 px-3 py-1.5 text-sm text-white focus:border-[#FF5733] outline-none rounded-sm" + placeholder="https://www.example.com" + /> +
+
+ + +
+
+ ) : ( + <> + {client.name} + + {client.website ? `🔗 ${client.website.replace(/^https?:\/\/(www\.)?/, '').replace(/\/$/, '')}` : 'Web sitesi yok'} + + + )} + + {/* Action buttons (visible on hover when not editing) */} + {!isEditing && ( +
+ + +
+ )} +
+ ); + })}
)} diff --git a/src/components/Clients.tsx b/src/components/Clients.tsx index 6e76d68..df95bca 100644 --- a/src/components/Clients.tsx +++ b/src/components/Clients.tsx @@ -30,16 +30,18 @@ export default function Clients() { {duplicated.map((client, index) => ( { if (!client.website) e.preventDefault(); }} > {client.name}