feat: update intranet.astro

This commit is contained in:
Clément SAILLANT
2026-03-20 00:12:04 +01:00
parent bada31c775
commit 6ed434c44d
+140
View File
@@ -0,0 +1,140 @@
---
import BaseLayout from '@/layouts/BaseLayout.astro';
import '@/styles/global.css';
---
<BaseLayout title="Intranet — L'Electron Rare" description="Dashboard interne des services.">
<main class="intranet">
<h1 class="intranet-title">Intranet <span class="electric">L'Electron Rare</span></h1>
<p class="intranet-sub">Accès rapide à tous les services internes</p>
<div class="grid">
<a href="https://tower.saillant.cc/app/crm" class="card" target="_blank" rel="noopener">
<div class="card-icon">📊</div>
<h2>Frappe CRM</h2>
<p>Leads, deals, pipeline commercial</p>
<span class="card-url">tower.saillant.cc</span>
</a>
<a href="https://tower.saillant.cc/app/lms" class="card" target="_blank" rel="noopener">
<div class="card-icon">🎓</div>
<h2>Frappe LMS</h2>
<p>Formations KiCad, Debug, Dispositifs</p>
<span class="card-url">tower.saillant.cc/app/lms</span>
</a>
<a href="https://mail.saillant.cc" class="card" target="_blank" rel="noopener">
<div class="card-icon">📧</div>
<h2>Listmonk</h2>
<p>Newsletter, campagnes, subscribers</p>
<span class="card-url">mail.saillant.cc</span>
</a>
<a href="https://n8n.saillant.cc" class="card" target="_blank" rel="noopener">
<div class="card-icon">⚡</div>
<h2>n8n</h2>
<p>Workflows automation</p>
<span class="card-url">n8n.saillant.cc</span>
</a>
<a href="https://auth.saillant.cc" class="card" target="_blank" rel="noopener">
<div class="card-icon">🔐</div>
<h2>Authentik</h2>
<p>SSO, utilisateurs, permissions</p>
<span class="card-url">auth.saillant.cc</span>
</a>
<a href="https://kpi.saillant.cc" class="card" target="_blank" rel="noopener">
<div class="card-icon">📈</div>
<h2>Metabase</h2>
<p>Dashboards KPI, analytics</p>
<span class="card-url">kpi.saillant.cc</span>
</a>
<a href="https://rdv.saillant.cc" class="card" target="_blank" rel="noopener">
<div class="card-icon">📅</div>
<h2>Cal.com</h2>
<p>Prise de rendez-vous</p>
<span class="card-url">rdv.saillant.cc</span>
</a>
<a href="https://api.lelectronrare.fr/health" class="card" target="_blank" rel="noopener">
<div class="card-icon">🔌</div>
<h2>API Proxy</h2>
<p>Health check, uptime</p>
<span class="card-url">api.lelectronrare.fr</span>
</a>
</div>
<div class="section">
<h2 class="section-title">Status des services</h2>
<div id="status-grid" class="status-grid"></div>
</div>
<div class="section">
<h2 class="section-title">Liens rapides</h2>
<div class="links">
<a href="https://www.lelectronrare.fr/preview" target="_blank">Site preview</a>
<a href="https://www.lelectronrare.fr/portfolio" target="_blank">Portfolio KiCanvas</a>
<a href="https://www.lelectronrare.fr/formation" target="_blank">Page formation</a>
<a href="https://github.com/electron-rare" target="_blank">GitHub</a>
<a href="https://fr.linkedin.com/in/electron-rare" target="_blank">LinkedIn</a>
</div>
</div>
</main>
</BaseLayout>
<script>
const services = [
{ name: 'Site', url: 'https://www.lelectronrare.fr/' },
{ name: 'API CRM', url: 'https://api.lelectronrare.fr/health' },
{ name: 'Frappe CRM', url: 'https://tower.saillant.cc/' },
{ name: 'Listmonk', url: 'https://mail.saillant.cc/' },
{ name: 'n8n', url: 'https://n8n.saillant.cc/' },
{ name: 'Authentik', url: 'https://auth.saillant.cc/' },
];
const grid = document.getElementById('status-grid');
if (grid) {
services.forEach(s => {
const el = document.createElement('div');
el.className = 'status-item';
el.innerHTML = `<span class="status-dot status-checking"></span><span class="status-name">${s.name}</span>`;
grid.appendChild(el);
fetch(s.url, { mode: 'no-cors', cache: 'no-store' })
.then(() => {
el.querySelector('.status-dot')?.classList.replace('status-checking', 'status-up');
})
.catch(() => {
el.querySelector('.status-dot')?.classList.replace('status-checking', 'status-down');
});
});
}
</script>
<style>
.intranet { max-width:1000px; margin:0 auto; padding:48px 24px; min-height:100vh; }
.intranet-title { font-family:'Fraunces',serif; font-size:clamp(24px,4vw,36px); color:var(--text,#f4eee3); margin:0 0 8px; }
.electric { color:var(--electric,#5bd1d8); }
.intranet-sub { font-family:'IBM Plex Mono',monospace; font-size:13px; color:var(--text-dim,#b6a894); margin:0 0 32px; }
.grid { display:grid; grid-template-columns:repeat(auto-fill,minmax(220px,1fr)); gap:16px; margin-bottom:40px; }
.card { background:var(--surface,#1a1510); border:1px solid var(--line,#3a2f24); border-radius:8px; padding:20px; text-decoration:none; transition:all .2s; display:block; }
.card:hover { border-color:var(--electric,#5bd1d8); box-shadow:0 0 16px rgba(91,209,216,.15); transform:translateY(-2px); }
.card-icon { font-size:28px; margin-bottom:8px; }
.card h2 { font-family:'Fraunces',serif; font-size:16px; color:var(--text,#f4eee3); margin:0 0 4px; }
.card p { font-size:13px; color:var(--text-muted,#d6cbb9); margin:0 0 8px; line-height:1.4; }
.card-url { font-family:'IBM Plex Mono',monospace; font-size:11px; color:var(--text-dim,#b6a894); opacity:.6; }
.section { margin-bottom:32px; }
.section-title { font-family:'Fraunces',serif; font-size:18px; color:var(--accent,#f1c27a); margin:0 0 16px; }
.status-grid { display:flex; flex-wrap:wrap; gap:12px; }
.status-item { display:flex; align-items:center; gap:8px; font-family:'IBM Plex Mono',monospace; font-size:13px; color:var(--text-muted,#d6cbb9); }
.status-dot { width:8px; height:8px; border-radius:50%; }
.status-checking { background:#f1c27a; animation:blink 1s infinite; }
.status-up { background:#4ade80; }
.status-down { background:#ef4444; }
@keyframes blink { 50% { opacity:.3; } }
.links { display:flex; flex-wrap:wrap; gap:12px; }
.links a { font-family:'IBM Plex Mono',monospace; font-size:13px; color:var(--electric,#5bd1d8); text-decoration:none; padding:6px 12px; border:1px solid var(--line,#3a2f24); border-radius:4px; transition:all .2s; }
.links a:hover { border-color:var(--electric,#5bd1d8); background:rgba(91,209,216,.1); }
</style>