first
This commit is contained in:
@@ -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 · 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">© 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>
|
||||
Reference in New Issue
Block a user