port-calc/index.html

134 lines
5.5 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Калькулятор кассет и портов</title>
<style>
*{box-sizing:border-box;margin:0;padding:0}
body{font:17px/1.5 -apple-system,BlinkMacSystemFont,"Segoe UI",Inter,system-ui,sans-serif;background:#f0f2f5;color:#0F1218;min-height:100vh;display:flex;flex-direction:column;align-items:center;justify-content:center;padding:24px}
.card{background:#fff;border-radius:20px;padding:48px;max-width:520px;width:100%;box-shadow:0 4px 24px rgba(0,0,0,.06)}
h1{font-size:28px;font-weight:800;margin-bottom:8px}
.sub{color:#5B6573;font-size:15px;margin-bottom:32px}
label{display:block;font-weight:600;font-size:15px;margin-bottom:8px}
input[type=number]{width:100%;padding:16px 20px;font-size:24px;font-weight:700;border:2px solid #d0d5dd;border-radius:12px;outline:none;transition:.15s;text-align:center}
input:focus{border-color:#0F1218}
input::placeholder{font-weight:400;color:#9aa3b2;font-size:17px}
button{width:100%;padding:16px;background:#0F1218;color:#fff;border:none;border-radius:12px;font-size:18px;font-weight:700;cursor:pointer;margin-top:16px;transition:.15s}
button:hover{background:#2a2f3a}
button:active{transform:scale(.98)}
.result{padding:24px;background:#f0f2f5;border-radius:12px;margin-top:24px;text-align:center;display:none}
.result.show{display:block}
.result .big{font-size:36px;font-weight:800;color:#0F1218}
.result .big span{color:#0088cc}
.result .detail{font-size:14px;color:#5B6573;margin-top:8px}
.error{color:#e74c3c;font-size:14px;margin-top:8px;display:none}
.error.show{display:block}
.history{margin-top:32px;padding-top:24px;border-top:2px solid #e8eaed;display:none}
.history.show{display:block}
.history h3{font-size:15px;color:#5B6573;font-weight:600;margin-bottom:12px}
.history-item{display:flex;justify-content:space-between;align-items:center;padding:10px 14px;border-radius:8px;cursor:pointer;transition:.1s;font-size:15px}
.history-item:hover{background:#f0f2f5}
.history-item .h-port{font-weight:700}
.history-item .h-result{color:#0088cc;font-weight:600}
.history-item .h-copy{color:#9aa3b2;font-size:13px;cursor:pointer;padding:4px 8px;border-radius:4px}
.history-item .h-copy:hover{background:#d0d5dd;color:#0F1218}
@media(max-width:480px){.card{padding:24px}h1{font-size:24px}input[type=number]{font-size:20px}}
</style>
</head>
<body>
<div class="card">
<h1>🔢 Кассеты и порты</h1>
<p class="sub">84 кассеты × 16 портов = 11344</p>
<label for="port">Введи номер порта</label>
<input type="number" id="port" min="1" max="1344" placeholder="например, 699" autofocus>
<div class="error" id="error">Введи число от 1 до 1344</div>
<button onclick="calc()">Рассчитать</button>
<div class="result" id="result">
<div class="big" id="output"></div>
<div class="detail" id="detail"></div>
</div>
<div class="history" id="history">
<h3>📋 История расчётов</h3>
<div id="historyList"></div>
</div>
</div>
<script>
const PORTS_PER_CASSETTE = 16;
const TOTAL_CASSETTES = 84;
const TOTAL_PORTS = TOTAL_CASSETTES * PORTS_PER_CASSETTE;
const MAX_HISTORY = 50;
let history = JSON.parse(localStorage.getItem('portHistory')||'[]');
function calc(){
const input=document.getElementById('port');
const error=document.getElementById('error');
const result=document.getElementById('result');
const output=document.getElementById('output');
const detail=document.getElementById('detail');
const val=parseInt(input.value);
error.classList.remove('show');
result.classList.remove('show');
if(!val||val<1||val>TOTAL_PORTS){
error.classList.add('show');
return;
}
const cassette=Math.floor((val-1)/PORTS_PER_CASSETTE)+1;
const port=((val-1)%PORTS_PER_CASSETTE)+1;
const firstPort=(cassette-1)*PORTS_PER_CASSETTE+1;
const lastPort=cassette*PORTS_PER_CASSETTE;
output.innerHTML=`${cassette} <span>кассета</span> — ${port} <span>порт</span>`;
detail.textContent=`Кассета ${cassette}: порты ${firstPort}${lastPort}`;
result.classList.add('show');
addHistory(val,cassette,port,firstPort,lastPort);
}
function addHistory(portNum,cassette,port,firstPort,lastPort){
const entry={portNum,cassette,port,firstPort,lastPort,time:Date.now()};
history.unshift(entry);
if(history.length>MAX_HISTORY)history=history.slice(0,MAX_HISTORY);
localStorage.setItem('portHistory',JSON.stringify(history));
renderHistory();
}
function renderHistory(){
const el=document.getElementById('history');
const list=document.getElementById('historyList');
if(!history.length){el.classList.remove('show');return}
el.classList.add('show');
list.innerHTML=history.map((h,i)=>`
<div class="history-item" onclick="useHistory(${i})" title="Нажми чтобы вставить номер">
<span class="h-port">${h.portNum}</span>
<span class="h-result">${h.cassette} к — ${h.port} п</span>
<span class="h-copy" onclick="event.stopPropagation();copyResult(${i})" title="Копировать">📋</span>
</div>
`).join('');
}
function useHistory(i){
document.getElementById('port').value=history[i].portNum;
calc();
}
function copyResult(i){
const h=history[i];
const text=`${h.portNum}${h.cassette} кассета — ${h.port} порт`;
navigator.clipboard.writeText(text).catch(()=>{});
}
document.getElementById('port').addEventListener('keydown',e=>{if(e.key==='Enter')calc()});
renderHistory();
</script>
</body>
</html>