This commit is contained in:
zipfriis
2026-03-16 13:08:54 +01:00
commit 9ed735c133
12 changed files with 3218 additions and 0 deletions
+188
View File
@@ -0,0 +1,188 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<title>Git — Samantha Friis</title>
<link href="https://fonts.googleapis.com/css2?family=DM+Mono:wght@300;400;500&family=Syne:wght@400;700;800&display=swap" rel="stylesheet"/>
<link rel="stylesheet" href="styles.css"/>
</head>
<body>
<div class="container">
<header>
<a href="/" class="back">← back</a>
<p class="tag">// git</p>
<h1>Code &<br/><span>Repositories</span></h1>
<p class="header-sub">Personal projects &nbsp;·&nbsp; Private & public</p>
</header>
<main class="two-col">
<!-- ── LEFT: Login / Private Dashboard ── -->
<div>
<p class="section-label">// private access</p>
<div class="login-panel" id="login-panel">
<h2>Sign In</h2>
<p class="desc">Access to private repositories and personal workspace. Requires credentials and 2FA.</p>
<div class="form-group">
<label for="username">Username</label>
<input type="text" id="username" placeholder="samantha" autocomplete="username" />
</div>
<div class="form-group">
<label for="password">Password</label>
<input type="password" id="password" placeholder="••••••••••••" autocomplete="current-password" />
</div>
<div class="twofa-group" id="twofa-group">
<label for="twofa">Authenticator Code</label>
<input type="text" id="twofa" placeholder="000 000" maxlength="7" autocomplete="one-time-code" />
<p class="twofa-hint">Enter the 6-digit code from your authenticator app.</p>
</div>
<button class="btn-login" id="login-btn" onclick="handleLogin()">Continue →</button>
<p class="login-error" id="login-error">Invalid credentials. Please try again.</p>
</div>
<!-- Private dashboard (shown after login) -->
<div id="private-dashboard">
<div class="repo-list">
<a href="#" class="repo-item">
<div>
<p class="repo-name">samantha-site</p>
<p class="repo-desc">Personal website and Go backend server</p>
</div>
<span class="repo-badge private">private</span>
</a>
<a href="#" class="repo-item">
<div>
<p class="repo-name">equity-tools</p>
<p class="repo-desc">Python scripts for SEC filing analysis and financial modeling</p>
</div>
<span class="repo-badge active">active</span>
</a>
<a href="#" class="repo-item">
<div>
<p class="repo-name">infra-config</p>
<p class="repo-desc">Dotfiles, server configs, and deployment scripts</p>
</div>
<span class="repo-badge private">private</span>
</a>
<a href="#" class="repo-item">
<div>
<p class="repo-name">typst-templates</p>
<p class="repo-desc">Custom Typst document templates for reports and analysis</p>
</div>
<span class="repo-badge active">active</span>
</a>
</div>
<button class="logout-btn" onclick="handleLogout()">← sign out</button>
</div>
</div>
<!-- ── RIGHT: Public section ── -->
<div>
<div class="repo-list">
<a href="/gitpage/TicTacToe" class="repo-item">
<div>
<p class="repo-name">TicTacToe</p>
<p class="repo-desc">Python learning tic tac toe game in terminal</p>
</div>
<span class="repo-badge private">private</span>
</a>
<a href="/gitpage/infra-config" class="repo-item">
<div>
<p class="repo-name">infra-config</p>
<p class="repo-desc">Dotfiles, server configs, and deployment scripts</p>
</div>
<span class="repo-badge private">private</span>
</a>
<a href="/gitpage/typst-templates" class="repo-item">
<div>
<p class="repo-name">typst-templates</p>
<p class="repo-desc">Custom Typst document templates for reports and analysis</p>
</div>
<span class="repo-badge active">active</span>
</a>
</div>
<button class="logout-btn" onclick="handleLogout()">← sign out</button>
</div>
</div>
</main>
<footer>
<a href="mailto:contact@samantha42.xyz">contact@samantha42.xyz</a>
<p class="footer-copy">&copy; 2026 — All rights reserved</p>
</footer>
</div>
<script>
let step = 1;
function handleLogin() {
const username = document.getElementById('username').value.trim();
const password = document.getElementById('password').value.trim();
const twofa = document.getElementById('twofa').value.trim();
const tfGroup = document.getElementById('twofa-group');
document.getElementById('login-error').classList.remove('visible');
if (step === 1) {
if (!username || !password) { showError('Please enter your username and password.'); return; }
step = 2;
tfGroup.classList.add('visible');
document.getElementById('login-btn').textContent = 'Verify →';
document.getElementById('twofa').focus();
} else {
if (!twofa || twofa.replace(/\s/g, '').length < 6) { showError('Enter the 6-digit code from your authenticator app.'); return; }
if (twofa.replace(/\s/g, '').match(/^\d{6}$/)) {
showDashboard();
} else {
showError('Invalid authenticator code.');
}
}
}
function showError(msg) {
const error = document.getElementById('login-error');
const panel = document.getElementById('login-panel');
error.textContent = msg;
error.classList.add('visible');
panel.classList.add('shake');
setTimeout(() => panel.classList.remove('shake'), 500);
}
function showDashboard() {
document.getElementById('login-panel').style.display = 'none';
document.getElementById('private-dashboard').classList.add('visible');
}
function handleLogout() {
step = 1;
document.getElementById('login-panel').style.display = '';
document.getElementById('private-dashboard').classList.remove('visible');
document.getElementById('username').value = '';
document.getElementById('password').value = '';
document.getElementById('twofa').value = '';
document.getElementById('twofa-group').classList.remove('visible');
document.getElementById('login-btn').textContent = 'Continue →';
document.getElementById('login-error').classList.remove('visible');
}
document.addEventListener('keydown', (e) => { if (e.key === 'Enter') handleLogin(); });
document.getElementById('twofa').addEventListener('input', (e) => {
let val = e.target.value.replace(/\D/g, '').slice(0, 6);
if (val.length > 3) val = val.slice(0, 3) + ' ' + val.slice(3);
e.target.value = val;
});
</script>
</body>
</html>