streaming / reset.html
jaynesmax's picture
Rename reset (1).html to reset.html
aee0e48 verified
Raw History Blame Contribute Delete
6.95 kB
<!DOCTYPE html>
<html lang="sw">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
<meta name="theme-color" content="#0e1116">
<meta name="robots" content="noindex">
<title>Weka Nenosiri Jipya — JAYNES MAX</title>
<style>
:root{--bg:#0e1116;--card:#161a21;--text:#f5f6f8;--muted:#9aa3af;--accent:#e50914;--accent2:#c7b8ff;--border:#242a33;}
*{box-sizing:border-box;margin:0;padding:0;}
html,body{height:100%;}
body{background:var(--bg);color:var(--text);font-family:-apple-system,Roboto,Segoe UI,Helvetica,Arial,sans-serif;
display:flex;align-items:center;justify-content:center;padding:20px;}
.card{width:100%;max-width:400px;background:var(--card);border:1px solid var(--border);border-radius:18px;padding:26px 22px;}
.brand{font-weight:800;font-size:18px;text-align:center;margin-bottom:6px;}
.brand span{color:var(--accent);}
h1{font-size:19px;text-align:center;margin-bottom:6px;}
.sub{font-size:13px;color:var(--muted);text-align:center;margin-bottom:20px;line-height:1.45;}
label{display:block;font-size:12px;color:var(--muted);margin:0 0 6px 2px;}
.field{position:relative;margin-bottom:14px;}
input{width:100%;padding:13px 44px 13px 14px;border-radius:12px;border:1px solid var(--border);
background:var(--bg);color:var(--text);font-size:15px;outline:none;}
input:focus{border-color:var(--accent2);}
.eye{position:absolute;right:6px;bottom:6px;width:36px;height:36px;border:none;background:none;color:var(--muted);font-size:17px;cursor:pointer;}
.track{height:4px;border-radius:999px;background:rgba(255,255,255,.08);overflow:hidden;margin:-6px 0 4px;}
.fill{height:100%;width:0;border-radius:999px;background:#ff5252;transition:width .25s,background .25s;}
.strength{font-size:11px;color:var(--muted);text-align:right;min-height:1.3em;margin-bottom:12px;}
.btn{width:100%;padding:13px;border:none;border-radius:999px;background:var(--accent2);color:#1b1230;
font-weight:700;font-size:15px;cursor:pointer;display:block;text-align:center;text-decoration:none;}
.btn:disabled{opacity:.55;cursor:default;}
.msg{font-size:13px;text-align:center;margin-top:14px;min-height:1.3em;line-height:1.4;}
.err{color:#ff8a80;} .ok{color:#5ee6a0;}
.big{font-size:44px;text-align:center;margin-bottom:10px;}
.hide{display:none;}
</style>
</head>
<body>
<div class="card">
<div class="brand">JAYNES <span>MAX</span></div>
<!-- Hali: kiungo kibaya / kimeisha muda -->
<div id="bad" class="hide">
<div class="big">⚠️</div>
<h1>Kiungo hakifanyi kazi</h1>
<p class="sub" id="badText">Kiungo hiki si sahihi au kimeisha muda. Omba kingine kupitia "Umesahau nenosiri?" kwenye app.</p>
<a class="btn" href="index.html">Rudi kwenye app</a>
</div>
<!-- Fomu -->
<div id="form" class="hide">
<h1>Weka nenosiri jipya</h1>
<p class="sub">Andika nenosiri jipya la akaunti yako.</p>
<div class="field">
<label for="p1">Nenosiri jipya</label>
<input id="p1" type="password" autocomplete="new-password" placeholder="Angalau herufi 8">
<button class="eye" type="button" data-for="p1" aria-label="Onyesha nenosiri">👁</button>
</div>
<div class="track"><div class="fill" id="fill"></div></div>
<div class="strength" id="strength"></div>
<div class="field">
<label for="p2">Rudia nenosiri</label>
<input id="p2" type="password" autocomplete="new-password" placeholder="Rudia nenosiri">
<button class="eye" type="button" data-for="p2" aria-label="Onyesha nenosiri">👁</button>
</div>
<button class="btn" id="save">Badilisha nenosiri</button>
<div class="msg" id="msg"></div>
</div>
<!-- Imefanikiwa -->
<div id="done" class="hide">
<div class="big">✅</div>
<h1>Nenosiri limebadilishwa</h1>
<p class="sub">Sasa unaweza kuingia kwa nenosiri lako jipya.</p>
<a class="btn" href="index.html">Ingia kwenye JAYNES MAX</a>
</div>
</div>
<script src="config.js"></script>
<script>
(function(){
const $ = id => document.getElementById(id);
const AUTH = JM_CONFIG.PROFILE_URL + '/auth/v1';
const KEY = JM_CONFIG.PROFILE_KEY;
const show = id => { ['bad','form','done'].forEach(x => $(x).classList.toggle('hide', x !== id)); };
// Supabase huweka token kwenye hash ya kiungo: #access_token=...&type=recovery
const params = new URLSearchParams(location.hash.replace(/^#/, ''));
const token = params.get('access_token');
const type = params.get('type');
const errCode = params.get('error_code');
try { history.replaceState(null, '', location.pathname); } catch (_) {} // ficha token kwenye URL
if (errCode === 'otp_expired') {
$('badText').textContent = 'Kiungo kimeisha muda au kimeshatumika. Omba kingine kupitia "Umesahau nenosiri?" kwenye app.';
show('bad');
} else if (!token || type !== 'recovery') {
show('bad');
} else {
show('form');
}
document.querySelectorAll('.eye').forEach(b => b.onclick = () => {
const i = $(b.dataset.for); i.type = i.type === 'password' ? 'text' : 'password';
});
$('p1').addEventListener('input', () => {
const v = $('p1').value;
let s = 0;
if (v.length >= 8) s++;
if (v.length >= 12) s++;
if (/[a-z]/.test(v) && /[A-Z]/.test(v)) s++;
if (/\d/.test(v)) s++;
if (/[^A-Za-z0-9]/.test(v)) s++;
if (!v) s = 0;
const lv = [
['0%', '#ff5252', ''], ['25%', '#ff5252', 'Dhaifu'], ['45%', '#ffb74d', 'Wastani'],
['70%', '#ffd54f', 'Nzuri'], ['90%', '#9ccc65', 'Imara'], ['100%', '#5ee6a0', 'Imara sana']
][s];
$('fill').style.width = lv[0]; $('fill').style.background = lv[1]; $('strength').textContent = lv[2];
});
const msg = (t, cls) => { $('msg').textContent = t; $('msg').className = 'msg ' + (cls || ''); };
$('save').onclick = async () => {
const a = $('p1').value, b = $('p2').value;
if (a.length < 8) return msg('Nenosiri liwe angalau herufi 8.', 'err');
if (a !== b) return msg('Manenosiri hayalingani.', 'err');
$('save').disabled = true; msg('Subiri…');
try {
const res = await fetch(AUTH + '/user', {
method: 'PUT',
headers: { 'Content-Type': 'application/json', 'apikey': KEY, 'Authorization': 'Bearer ' + token },
body: JSON.stringify({ password: a })
});
const d = await res.json().catch(() => ({}));
if (!res.ok) throw new Error(d.msg || d.error_description || d.error_code || 'Imeshindikana');
show('done');
} catch (e) {
const m = String(e.message || '');
msg(/same|different/i.test(m) ? 'Nenosiri jipya lazima lisiwe sawa na la zamani.'
: /expired|invalid|jwt/i.test(m) ? 'Kiungo kimeisha muda. Omba kingine kwenye app.'
: 'Imeshindikana: ' + m, 'err');
$('save').disabled = false;
}
};
[$('p1'), $('p2')].forEach(i => i.addEventListener('keydown', e => { if (e.key === 'Enter') $('save').click(); }));
})();
</script>
</body>
</html>