mirror of
https://github.com/wasrusgen/wasrusgen1-crm.git
synced 2026-06-03 16:24:47 +00:00
feat: delete client — removes project with all data (messages/models/artifacts/docs)
This commit is contained in:
parent
9f63f3dd46
commit
c37491cbc7
@ -616,6 +616,26 @@ def update_crm():
|
||||
save_artifact(proj["id"], "crm", crm)
|
||||
return jsonify({"ok": True, "crm": crm})
|
||||
|
||||
@app.route("/api/project/delete", methods=["POST"])
|
||||
def delete_project():
|
||||
data = request.get_json(force=True) or {}
|
||||
proj = get_project(data.get("token"))
|
||||
if not proj:
|
||||
return jsonify({"error": "project not found"}), 404
|
||||
pid = proj["id"]
|
||||
con = db()
|
||||
con.execute("DELETE FROM messages WHERE project_id=?", (pid,))
|
||||
con.execute("DELETE FROM models WHERE project_id=?", (pid,))
|
||||
con.execute("DELETE FROM artifacts WHERE project_id=?", (pid,))
|
||||
con.execute("DELETE FROM projects WHERE id=?", (pid,))
|
||||
con.commit()
|
||||
# удалить загруженные документы
|
||||
import shutil
|
||||
pdir = os.path.join(UPLOAD_DIR, proj["token"])
|
||||
if os.path.isdir(pdir):
|
||||
shutil.rmtree(pdir, ignore_errors=True)
|
||||
return jsonify({"ok": True})
|
||||
|
||||
@app.route("/api/project/tasks", methods=["POST"])
|
||||
def update_tasks():
|
||||
data = request.get_json(force=True) or {}
|
||||
|
||||
@ -211,7 +211,7 @@ function renderClient(){
|
||||
<div class="cc-field"><div class="cc-fl">Оплачено</div><input class="cc-fi" id="cpPaid" type="number" value="${crm.paid_amount||''}" placeholder="0" onchange="saveCrm()"></div>
|
||||
<div class="cc-field"><div class="cc-fl">Источник</div><input class="cc-fi" id="cpSrc" value="${esc(crm.source)}" placeholder="откуда пришёл" onchange="saveCrm()"></div>
|
||||
</div>
|
||||
<div class="cc-actions"><button class="btn btn-p" onclick="inviteLink()">🔗 Ссылка клиенту</button><a class="btn btn-g" href="cabinet.html?t=${current}" target="_blank">👁 Открыть кабинет</a></div>
|
||||
<div class="cc-actions"><button class="btn btn-p" onclick="inviteLink()">🔗 Ссылка клиенту</button><a class="btn btn-g" href="cabinet.html?t=${current}" target="_blank">👁 Открыть кабинет</a><button class="btn btn-g" style="margin-left:auto;border-color:#FECACA;color:#DC2626" onclick="deleteClient()">🗑 Удалить клиента</button></div>
|
||||
<div id="tasksBox"></div>
|
||||
<div class="tabs">${TABS.map(t=>`<div class="tab ${t.id===activeTab?'active':''} ${approved(t.id)?'done':''}" onclick="setTab('${t.id}')">${t.icon} ${t.name}</div>`).join("")}</div>
|
||||
<div id="tabContent"></div>`;
|
||||
@ -240,6 +240,12 @@ async function saveCrm(){
|
||||
await loadProjects();
|
||||
}
|
||||
function inviteLink(){const url=`${location.origin}${location.pathname.replace('crm.html','cabinet.html')}?t=${current}`;navigator.clipboard.writeText(url).then(()=>alert("Ссылка скопирована:\n\n"+url)).catch(()=>prompt("Ссылка:",url));}
|
||||
async function deleteClient(){
|
||||
const nm=state.client_name||"клиента";
|
||||
if(!confirm(`Удалить «${nm}» со всеми данными (интервью, анализ, ТЗ, документы)?\n\nЭто действие необратимо.`))return;
|
||||
await fetch(`${API}/api/project/delete`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({token:current})});
|
||||
current=null;await loadProjects();setView("dashboard");
|
||||
}
|
||||
|
||||
function exportSpecPDF(){
|
||||
const s=state.spec;if(!s){alert("ТЗ ещё не собрано");return}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user