Initial commit: existing turf_saas codebase
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
205
crm_simple.html
Executable file
205
crm_simple.html
Executable file
@@ -0,0 +1,205 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="fr">
|
||||
<head>
|
||||
<meta charset="UTF-8">
|
||||
<title>CRM H3R7</title>
|
||||
<style>
|
||||
*{margin:0;padding:0;box-sizing:border-box}
|
||||
body{font-family:-apple-system,sans-serif;background:#1a1a2e;color:#eee;padding:20px}
|
||||
header{background:linear-gradient(90deg,#e94560,#7b2cbf);padding:20px;text-align:center;margin:-20px -20px 20px}
|
||||
h1{font-size:28px}
|
||||
.stats{display:grid;grid-template-columns:repeat(4,1fr);gap:15px;margin-bottom:20px}
|
||||
.stat-card{background:#16213e;padding:20px;border-radius:12px;text-align:center}
|
||||
.stat-num{font-size:32px;color:#00d9ff}
|
||||
.stat-label{color:#aaa;font-size:14px}
|
||||
.prospects-grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:15px}
|
||||
.prospect-card{background:#16213e;padding:15px;border-radius:12px;border-left:4px solid #00d9ff}
|
||||
.prospect-card.nouveau{border-left-color:#ffd700}
|
||||
.prospect-card.contacte{border-left-color:#00d9ff}
|
||||
.prospect-card.rdv{border-left-color:#ff6b6b}
|
||||
.prospect-card.proposition{border-left-color:#7b2cbf}
|
||||
.prospect-card.gagne{border-left-color:#00ff88}
|
||||
.prospect-card.perdu{border-left-color:#e94560}
|
||||
.prospect-name{font-size:18px;font-weight:bold}
|
||||
.prospect-entreprise{color:#aaa;font-size:14px}
|
||||
.prospect-info{font-size:13px;color:#888;margin:3px 0}
|
||||
.actions{margin-top:10px;display:flex;gap:5px}
|
||||
.btn-edit,.btn-delete{padding:5px 10px;border:none;border-radius:5px;cursor:pointer;font-size:12px}
|
||||
.btn-edit{background:#7b2cbf;color:#fff}
|
||||
.btn-delete{background:#e94560;color:#fff}
|
||||
.filter-bar{margin-bottom:15px;display:flex;gap:10px;flex-wrap:wrap}
|
||||
.filter-btn{padding:8px 15px;background:#0f3460;border:none;border-radius:8px;color:#fff;cursor:pointer}
|
||||
.filter-btn.active{background:#00d9ff;color:#000}
|
||||
select{padding:8px;background:#0f3460;color:#fff;border:1px solid #333;border-radius:8px}
|
||||
.modal{display:none;position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.8);z-index:1000}
|
||||
.modal.show{display:block}
|
||||
.modal-content{background:#16213e;padding:30px;border-radius:12px;width:90%;max-width:500px;margin:50px auto}
|
||||
.form-group{margin-bottom:15px}
|
||||
.form-group label{display:block;color:#aaa;margin-bottom:5px}
|
||||
.form-group input,.form-group select,.form-group textarea{width:100%;padding:10px;background:#0f3460;border:1px solid #333;border-radius:8px;color:#fff}
|
||||
.modal-buttons{display:flex;gap:10px;margin-top:20px}
|
||||
.modal-buttons button{flex:1;padding:12px;border:none;border-radius:8px;cursor:pointer;font-weight:bold}
|
||||
.btn-save{background:#00d9ff;color:#000}
|
||||
.btn-cancel{background:#666;color:#fff}
|
||||
.btn-delete-modal{background:#e94560;color:#fff}
|
||||
|
||||
.home-btn{position:fixed;top:10px;left:10px;z-index:9999;background:linear-gradient(135deg,#00d9ff,#7b2cbf);color:#fff;border:none;border-radius:8px;padding:10px 15px;font-size:14px;cursor:pointer;text-decoration:none;display:flex;align-items:center;gap:8px;box-shadow:0 2px 10px rgba(0,217,255,0.3);transition:all 0.3s;font-family:-apple-system,BlinkMacSystemFont,sans-serif}.home-btn:hover{transform:translateY(-2px);box-shadow:0 4px 15px rgba(0,217,255,0.5)}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<a href="https://portal-kolifee.duckdns.org/" class="home-btn" title="Retour au portail"><span style="font-size:18px">🏠</span><span>Accueil</span></a>
|
||||
<header><h1 id="title">CRM H3R7</h1></header>
|
||||
<div class="stats">
|
||||
<div class="stat-card"><div class="stat-num" id="total">0</div><div class="stat-label">Total</div></div>
|
||||
<div class="stat-card"><div class="stat-num" id="nouveaux">0</div><div class="stat-label">Nouveau</div></div>
|
||||
<div class="stat-card"><div class="stat-num" id="qualifies">0</div><div class="stat-label">Qualifies</div></div>
|
||||
<div class="stat-card"><div class="stat-num" id="gagnes">0</div><div class="stat-label">Gagnes</div></div>
|
||||
</div>
|
||||
<div class="filter-bar">
|
||||
<button class="filter-btn active" onclick="filter('tous')">Tous</button>
|
||||
<button class="filter-btn" onclick="filter('nouveau')">Nouveau</button>
|
||||
<button class="filter-btn" onclick="filter('contacte')">Contacte</button>
|
||||
<button class="filter-btn" onclick="filter('rdv')">RDV</button>
|
||||
<button class="filter-btn" onclick="filter('proposition')">Proposition</button>
|
||||
<button class="filter-btn" onclick="filter('gagne')">Gagne</button>
|
||||
<button class="filter-btn" onclick="filter('perdu')">Perdu</button>
|
||||
<select id="catFilter" onchange="render()">
|
||||
<option value="all">Toutes categories</option>
|
||||
<option value="Restaurant">Restaurants</option>
|
||||
<option value="Boulangerie">Boulangeries</option>
|
||||
<option value="Garage">Garages</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="prospects-grid" id="grid"></div>
|
||||
<div class="modal" id="modal">
|
||||
<div class="modal-content">
|
||||
<h2>Modifier le Prospect</h2>
|
||||
<input type="hidden" id="eid">
|
||||
<div class="form-group"><label>Nom</label><input type="text" id="enom"></div>
|
||||
<div class="form-group"><label>Entreprise</label><input type="text" id="eentreprise"></div>
|
||||
<div class="form-group"><label>Telephone</label><input type="tel" id="etel"></div>
|
||||
<div class="form-group"><label>Statut</label><select id="estatut">
|
||||
<option value="nouveau">Nouveau</option>
|
||||
<option value="contacte">Contacte</option>
|
||||
<option value="rdv">RDV</option>
|
||||
<option value="proposition">Proposition</option>
|
||||
<option value="gagne">Gagne</option>
|
||||
<option value="perdu">Perdu</option>
|
||||
</select></div>
|
||||
<div class="form-group"><label>Date RDV</label><input type="date" id="erdv"></div>
|
||||
<div class="form-group"><label>Commentaires</label><textarea id="enotes"></textarea></div>
|
||||
<div class="modal-buttons">
|
||||
<button class="btn-save" onclick="save()">Enregistrer</button>
|
||||
<button class="btn-cancel" onclick="closeModal()">Annuler</button>
|
||||
<button class="btn-delete-modal" onclick="delFromModal()">Supprimer</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script>
|
||||
var prospects = [];
|
||||
var currentFilter = 'tous';
|
||||
var currentCat = 'all';
|
||||
|
||||
fetch('api/prospects').then(r=>r.json()).then(function(data){
|
||||
prospects = data.prospects;
|
||||
document.getElementById('title').textContent = 'CRM H3R7 - ' + prospects.length + ' Prospects';
|
||||
render();
|
||||
});
|
||||
|
||||
function filter(f) {
|
||||
currentFilter = f;
|
||||
document.querySelectorAll('.filter-btn').forEach(function(b){b.classList.remove('active');});
|
||||
event.target.classList.add('active');
|
||||
render();
|
||||
}
|
||||
|
||||
function render() {
|
||||
currentCat = document.getElementById('catFilter').value;
|
||||
var filtered = prospects;
|
||||
if (currentCat !== 'all') {
|
||||
filtered = filtered.filter(function(p){return p.categorie===currentCat || p.secteur===currentCat || p.entreprise===currentCat;});
|
||||
}
|
||||
if (currentFilter !== 'tous') {
|
||||
filtered = filtered.filter(function(p){return p.statut===currentFilter;});
|
||||
}
|
||||
var grid = document.getElementById('grid');
|
||||
if (!filtered.length) {
|
||||
grid.innerHTML = '<div style="grid-column:1/-1;text-align:center;color:#666;padding:40px;">Aucun prospect</div>';
|
||||
return;
|
||||
}
|
||||
grid.innerHTML = filtered.map(function(p) {
|
||||
var rdv = p.rdv ? '<span style="background:#ff6b6b;color:#fff;padding:3px 8px;border-radius:10px;font-size:11px;margin-left:5px;">RDV: '+p.rdv+'</span>' : '';
|
||||
var notes = p.notes ? '<div class="prospect-info">'+p.notes.substring(0,30)+'</div>' : '';
|
||||
return '<div class="prospect-card '+(p.statut||'nouveau')+'">' +
|
||||
'<div class="prospect-name">'+(p.nom||'')+'</div>' +
|
||||
'<div class="prospect-entreprise">'+(p.entreprise||'')+'</div>' +
|
||||
'<div class="prospect-info">'+(p.adresse||'-')+'</div>' +
|
||||
'<div class="prospect-info">'+(p.tel||'-')+'</div>' +
|
||||
'<div class="prospect-info">'+(p.score||0)+' ('+(p.categorie||'-')+')</div>' +
|
||||
notes + rdv +
|
||||
'<div class="actions">' +
|
||||
'<button class="btn-edit" onclick="edit(\''+p.id+'\')">Modifier</button>' +
|
||||
'<button class="btn-delete" onclick="del(\''+p.id+'\')">Supprimer</button>' +
|
||||
'</div></div>';
|
||||
}).join('');
|
||||
updateStats();
|
||||
}
|
||||
|
||||
function updateStats() {
|
||||
document.getElementById('total').textContent = prospects.length;
|
||||
document.getElementById('nouveaux').textContent = prospects.filter(function(p){return p.statut==='nouveau'}).length;
|
||||
document.getElementById('qualifies').textContent = prospects.filter(function(p){return p.statut==='contacte' || p.statut==='rdv' || p.statut==='proposition'}).length;
|
||||
document.getElementById('gagnes').textContent = prospects.filter(function(p){return p.statut==='gagne'}).length;
|
||||
}
|
||||
|
||||
function edit(id) {
|
||||
var p = prospects.find(function(x){return x.id===id;});
|
||||
if (!p) return;
|
||||
document.getElementById('eid').value = id;
|
||||
document.getElementById('enom').value = p.nom || '';
|
||||
document.getElementById('eentreprise').value = p.entreprise || '';
|
||||
document.getElementById('etel').value = p.tel || '';
|
||||
document.getElementById('estatut').value = p.statut || 'nouveau';
|
||||
document.getElementById('erdv').value = p.rdv || '';
|
||||
document.getElementById('enotes').value = p.notes || '';
|
||||
document.getElementById('modal').classList.add('show');
|
||||
}
|
||||
|
||||
function closeModal() {
|
||||
document.getElementById('modal').classList.remove('show');
|
||||
}
|
||||
|
||||
function save() {
|
||||
var id = document.getElementById('eid').value;
|
||||
var p = prospects.find(function(x){return x.id===id;});
|
||||
if (!p) return;
|
||||
p.nom = document.getElementById('enom').value;
|
||||
p.entreprise = document.getElementById('eentreprise').value;
|
||||
p.tel = document.getElementById('etel').value;
|
||||
p.statut = document.getElementById('estatut').value;
|
||||
p.rdv = document.getElementById('erdv').value;
|
||||
p.notes = document.getElementById('enotes').value;
|
||||
|
||||
fetch('api/prospect/'+id, {
|
||||
method: 'PUT',
|
||||
headers: {'Content-Type': 'application/json'},
|
||||
body: JSON.stringify(p)
|
||||
}).then(function(){closeModal(); render();});
|
||||
}
|
||||
|
||||
function del(id) {
|
||||
if (!confirm('Supprimer ce prospect?')) return;
|
||||
fetch('api/prospect/'+id, {method: 'DELETE'}).then(function(){
|
||||
prospects = prospects.filter(function(p){return p.id!==id;});
|
||||
render();
|
||||
});
|
||||
}
|
||||
|
||||
function delFromModal() {
|
||||
var id = document.getElementById('eid').value;
|
||||
del(id);
|
||||
closeModal();
|
||||
}
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user