320 lines
15 KiB
Markdown
320 lines
15 KiB
Markdown
---
|
|
layout: default
|
|
title: Meu Perfil - MMPSearch
|
|
permalink: /perfil/
|
|
---
|
|
|
|
<main class="main-content">
|
|
<div class="publication">
|
|
<div class="container">
|
|
<br />
|
|
|
|
<div class="tabs is-centered is-boxed is-medium mb-6">
|
|
{% include sidebar.html %}
|
|
</div>
|
|
|
|
<div class="box p-0" style="overflow: hidden; border-radius: 12px; position: relative;">
|
|
<div id="cover-container" style="height: 200px; background-color: #ddd; background-size: cover; background-position: center; position: relative;">
|
|
<button class="button is-small is-white is-rounded" style="position: absolute; top: 10px; right: 10px; opacity: 0.8;" onclick="document.getElementById('cover-input').click()">
|
|
<i class="fa-solid fa-camera mr-1"></i> Alterar Capa
|
|
</button>
|
|
<input type="file" id="cover-input" class="is-hidden" accept="image/*">
|
|
</div>
|
|
|
|
<div class="p-5" style="position: relative;">
|
|
<div style="position: absolute; top: -60px; left: 30px;">
|
|
<figure class="image is-128x128">
|
|
<img id="avatar-img" class="is-rounded" src="https://bulma.io/images/placeholders/128x128.png" style="border: 4px solid white; background: white; object-fit: cover;">
|
|
</figure>
|
|
<button class="button is-small is-rounded is-light" style="position: absolute; bottom: 0; right: 0;" onclick="document.getElementById('avatar-input').click()">
|
|
<i class="fa-solid fa-pencil"></i>
|
|
</button>
|
|
<input type="file" id="avatar-input" class="is-hidden" accept="image/*">
|
|
</div>
|
|
|
|
<div class="columns" style="margin-top: 50px;">
|
|
<div class="column is-8">
|
|
<h1 class="title is-3" id="display-username">Carregando...</h1>
|
|
<p class="subtitle is-6 has-text-grey" id="display-bio">...</p>
|
|
<div class="tags mt-3" id="display-tags"></div>
|
|
</div>
|
|
<div class="column is-4 has-text-right">
|
|
<button class="button is-info is-outlined" id="btn-edit-profile">
|
|
<i class="fa-solid fa-edit mr-2"></i> Editar Perfil
|
|
</button>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="edit-form-box" class="box is-hidden has-background-light">
|
|
<h3 class="title is-5"><i class="fa-solid fa-user-cog"></i> Editar Informações</h3>
|
|
<form id="profile-form">
|
|
<div class="field">
|
|
<label class="label">Nome de Usuário</label>
|
|
<div class="control has-icons-left">
|
|
<input class="input" type="text" name="username" id="input-username" required>
|
|
<span class="icon is-small is-left"><i class="fa-solid fa-user"></i></span>
|
|
</div>
|
|
</div>
|
|
<div class="field">
|
|
<label class="label">Bio (Max 240)</label>
|
|
<div class="control">
|
|
<textarea class="textarea" name="bio" id="input-bio" maxlength="240" rows="2"></textarea>
|
|
</div>
|
|
<p class="help has-text-right" id="char-count">0/240</p>
|
|
</div>
|
|
<div class="field">
|
|
<label class="label">Tags</label>
|
|
<div class="control has-icons-left">
|
|
<input class="input" type="text" name="tags" id="input-tags" placeholder="Ex: Trap, Dark, Samples">
|
|
<span class="icon is-small is-left"><i class="fa-solid fa-hashtag"></i></span>
|
|
</div>
|
|
</div>
|
|
<div class="field is-grouped">
|
|
<div class="control"><button type="submit" class="button is-success">Salvar</button></div>
|
|
<div class="control"><button type="button" class="button is-light" id="btn-cancel-edit">Cancelar</button></div>
|
|
</div>
|
|
<div id="update-msg" class="notification is-hidden mt-2"></div>
|
|
</form>
|
|
</div>
|
|
|
|
<div class="box mt-5">
|
|
<div class="tabs is-boxed">
|
|
<ul>
|
|
<li class="is-active" data-tab="projects-tab"><a><span class="icon"><i class="fa-solid fa-folder"></i></span> <span>Projetos</span></a></li>
|
|
<li data-tab="samples-tab"><a><span class="icon"><i class="fa-solid fa-music"></i></span> <span>Samples</span></a></li>
|
|
</ul>
|
|
</div>
|
|
|
|
<div id="projects-tab" class="content-tab-content">
|
|
<div class="table-container">
|
|
<table class="table is-fullwidth is-hoverable is-striped">
|
|
<thead><tr><th>Nome do Projeto</th><th>Data</th><th class="has-text-right">Ações</th></tr></thead>
|
|
<tbody id="projects-list"></tbody>
|
|
</table>
|
|
<p id="no-projects" class="has-text-grey is-hidden has-text-centered p-4">Nenhum projeto encontrado.</p>
|
|
</div>
|
|
</div>
|
|
|
|
<div id="samples-tab" class="content-tab-content is-hidden">
|
|
<div class="table-container">
|
|
<table class="table is-fullwidth is-hoverable is-striped">
|
|
<thead><tr><th>Nome do Sample</th><th>Categoria</th><th>Data</th><th class="has-text-right">Ações</th></tr></thead>
|
|
<tbody id="samples-list"></tbody>
|
|
</table>
|
|
<p id="no-samples" class="has-text-grey is-hidden has-text-centered p-4">Nenhum sample enviado.</p>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
|
|
<div id="preview-modal" class="modal">
|
|
<div class="modal-background"></div>
|
|
<div class="modal-card" style="width: 90%; max-width: 900px;">
|
|
<header class="modal-card-head" style="background-color: #f0f8ff; border-bottom: 1px solid #cfe8fc;">
|
|
<p class="modal-card-title" id="modal-title" style="color: #205081; font-weight: bold;">Preview</p>
|
|
<button class="delete" aria-label="close"></button>
|
|
</header>
|
|
|
|
<section class="modal-card-body p-0" style="background-color: #fff; min-height: 200px; display: flex; align-items: center; justify-content: center;">
|
|
|
|
<iframe id="preview-iframe" class="is-hidden" src="" style="width: 100%; height: 60vh; border: none;"></iframe>
|
|
|
|
<div id="audio-player-container" class="is-hidden p-5 has-text-centered" style="width: 100%;">
|
|
<div class="icon is-large has-text-info mb-4">
|
|
<i class="fa-solid fa-music fa-3x"></i>
|
|
</div>
|
|
<h4 id="audio-name" class="title is-5 mb-2"></h4>
|
|
<audio id="preview-audio" controls style="width: 80%;"></audio>
|
|
</div>
|
|
|
|
</section>
|
|
|
|
<footer class="modal-card-foot" style="justify-content: flex-end; background-color: #fff; border-top: 1px solid #cfe8fc;">
|
|
<button class="button" id="close-modal-btn">Fechar</button>
|
|
<a href="#" id="full-edit-btn" target="_blank" class="button is-info">
|
|
<span>Abrir / Baixar</span>
|
|
<span class="icon is-small ml-1"><i class="fa-solid fa-up-right-from-square"></i></span>
|
|
</a>
|
|
</footer>
|
|
</div>
|
|
</div>
|
|
|
|
<script>
|
|
document.addEventListener('DOMContentLoaded', () => {
|
|
// Referências DOM
|
|
const els = {
|
|
username: document.getElementById('display-username'),
|
|
bio: document.getElementById('display-bio'),
|
|
tags: document.getElementById('display-tags'),
|
|
projectList: document.getElementById('projects-list'),
|
|
sampleList: document.getElementById('samples-list'),
|
|
|
|
formBox: document.getElementById('edit-form-box'),
|
|
form: document.getElementById('profile-form'),
|
|
inpUser: document.getElementById('input-username'),
|
|
inpBio: document.getElementById('input-bio'),
|
|
inpTags: document.getElementById('input-tags'),
|
|
msg: document.getElementById('update-msg'),
|
|
|
|
btnEdit: document.getElementById('btn-edit-profile'),
|
|
btnCancel: document.getElementById('btn-cancel-edit')
|
|
};
|
|
|
|
// Referências Modal
|
|
const modal = document.getElementById('preview-modal');
|
|
const iframe = document.getElementById('preview-iframe');
|
|
const audioContainer = document.getElementById('audio-player-container');
|
|
const audioPlayer = document.getElementById('preview-audio');
|
|
const audioName = document.getElementById('audio-name');
|
|
const modalTitle = document.getElementById('modal-title');
|
|
const fullEditBtn = document.getElementById('full-edit-btn');
|
|
|
|
// --- FUNÇÃO DE MODAL INTELIGENTE ---
|
|
window.openModal = (type, url, title, fullLink) => {
|
|
modalTitle.textContent = title;
|
|
fullEditBtn.href = fullLink || url;
|
|
|
|
// Resetar
|
|
iframe.classList.add('is-hidden');
|
|
audioContainer.classList.add('is-hidden');
|
|
iframe.src = "";
|
|
audioPlayer.pause();
|
|
|
|
if (type === 'project') {
|
|
iframe.classList.remove('is-hidden');
|
|
iframe.src = url;
|
|
// Tenta esconder menu do iframe
|
|
iframe.onload = () => {
|
|
try {
|
|
const doc = iframe.contentDocument || iframe.contentWindow.document;
|
|
const style = doc.createElement('style');
|
|
style.textContent = ".tabs, .navbar, footer { display: none !important; } body { overflow: auto !important; }";
|
|
doc.head.appendChild(style);
|
|
} catch(e){}
|
|
};
|
|
} else if (type === 'audio') {
|
|
audioContainer.classList.remove('is-hidden');
|
|
audioName.textContent = title.replace('Ouvir: ', '');
|
|
audioPlayer.src = url;
|
|
audioPlayer.play();
|
|
}
|
|
|
|
modal.classList.add('is-active');
|
|
document.documentElement.classList.add('is-clipped');
|
|
};
|
|
|
|
function closeModal() {
|
|
modal.classList.remove('is-active');
|
|
document.documentElement.classList.remove('is-clipped');
|
|
iframe.src = "";
|
|
audioPlayer.pause();
|
|
}
|
|
|
|
document.querySelectorAll('.modal-background, .modal-card-head .delete, #close-modal-btn').forEach(el => el.onclick = closeModal);
|
|
|
|
// --- CARREGAR DADOS ---
|
|
async function loadProfile() {
|
|
try {
|
|
const res = await fetch('/api/user/profile');
|
|
if (res.status === 401) { window.location.href = '/login/'; return; }
|
|
const data = await res.json();
|
|
|
|
// Header
|
|
els.username.textContent = data.username;
|
|
els.bio.textContent = data.bio || "Sem bio definida.";
|
|
els.tags.innerHTML = '';
|
|
if(data.tags) data.tags.split(',').forEach(t => {
|
|
if(t.trim()) els.tags.innerHTML += `<span class="tag is-info is-light mr-1">${t.trim()}</span>`;
|
|
});
|
|
|
|
// Forms Values
|
|
els.inpUser.value = data.username;
|
|
els.inpBio.value = data.bio || "";
|
|
els.inpTags.value = data.tags || "";
|
|
|
|
// 1. Projetos
|
|
els.projectList.innerHTML = '';
|
|
if (data.projects && data.projects.length > 0) {
|
|
data.projects.forEach(p => {
|
|
const slug = p.filename.replace('.mmp', '').replace('.mmpz', '');
|
|
const pageUrl = `/mmpSearch/projetos/${slug}.html`;
|
|
const editorUrl = `/mmpSearch/creation.html?project=${p.filename}&embed=true`;
|
|
|
|
els.projectList.innerHTML += `
|
|
<tr>
|
|
<td style="vertical-align: middle;">
|
|
<a href="${pageUrl}" class="has-text-weight-bold" style="color: #205081;">
|
|
<span class="icon is-small mr-1"><i class="fa-solid fa-music"></i></span>${p.display_name}
|
|
</a>
|
|
</td>
|
|
<td style="vertical-align: middle;">${p.created_at}</td>
|
|
<td class="has-text-right">
|
|
<button class="button is-small is-info is-light" onclick="openModal('project', '${pageUrl}', 'Detalhes: ${p.display_name}', '${pageUrl}')"><i class="fa-solid fa-eye"></i></button>
|
|
<button class="button is-small is-warning is-light" onclick="openModal('project', '${editorUrl}', 'Editor: ${p.display_name}', '${editorUrl}')"><i class="fa-solid fa-sliders"></i></button>
|
|
<a href="${p.download_link}" class="button is-small is-primary is-light"><i class="fa-solid fa-download"></i></a>
|
|
<button class="button is-small is-danger is-light" onclick="deleteItem('project', ${p.id})"><i class="fa-solid fa-trash"></i></button>
|
|
</td>
|
|
</tr>`;
|
|
});
|
|
} else {
|
|
document.getElementById('no-projects').classList.remove('is-hidden');
|
|
}
|
|
|
|
// 2. Samples
|
|
els.sampleList.innerHTML = '';
|
|
if (data.samples && data.samples.length > 0) {
|
|
data.samples.forEach(s => {
|
|
els.sampleList.innerHTML += `
|
|
<tr>
|
|
<td style="vertical-align: middle;"><strong>${s.display_name}</strong></td>
|
|
<td style="vertical-align: middle;"><span class="tag is-light">${s.category}</span></td>
|
|
<td style="vertical-align: middle;">${s.created_at}</td>
|
|
<td class="has-text-right">
|
|
<button class="button is-small is-success is-light" onclick="openModal('audio', '${s.download_link}', 'Ouvir: ${s.display_name}', '${s.download_link}')"><i class="fa-solid fa-play"></i></button>
|
|
<a href="${s.download_link}" download class="button is-small is-primary is-light"><i class="fa-solid fa-download"></i></a>
|
|
<button class="button is-small is-danger is-light" onclick="deleteItem('sample', ${s.id})"><i class="fa-solid fa-trash"></i></button>
|
|
</td>
|
|
</tr>`;
|
|
});
|
|
} else {
|
|
document.getElementById('no-samples').classList.remove('is-hidden');
|
|
}
|
|
|
|
} catch(e) { console.error(e); }
|
|
}
|
|
|
|
// Handlers de Edição
|
|
els.btnEdit.onclick = () => els.formBox.classList.remove('is-hidden');
|
|
els.btnCancel.onclick = () => els.formBox.classList.add('is-hidden');
|
|
els.form.onsubmit = async (e) => {
|
|
e.preventDefault();
|
|
const payload = { username: els.inpUser.value, bio: els.inpBio.value, tags: els.inpTags.value };
|
|
const res = await fetch('/api/user/update', { method: 'POST', headers: {'Content-Type':'application/json'}, body: JSON.stringify(payload)});
|
|
if(res.ok) { els.formBox.classList.add('is-hidden'); loadProfile(); }
|
|
};
|
|
|
|
// Função Delete Genérica
|
|
window.deleteItem = async (type, id) => {
|
|
if(!confirm("Tem certeza que deseja apagar?")) return;
|
|
const res = await fetch(`/api/${type}/${id}`, { method: 'DELETE' });
|
|
if(res.ok) loadProfile();
|
|
};
|
|
|
|
// Inicializa
|
|
loadProfile();
|
|
|
|
// Abas
|
|
document.querySelectorAll('.tabs li').forEach(tab => {
|
|
tab.addEventListener('click', () => {
|
|
document.querySelectorAll('.tabs li').forEach(t => t.classList.remove('is-active'));
|
|
tab.classList.add('is-active');
|
|
document.querySelectorAll('.content-tab-content').forEach(c => c.classList.add('is-hidden'));
|
|
document.getElementById(tab.dataset.tab).classList.remove('is-hidden');
|
|
});
|
|
});
|
|
});
|
|
</script> |